forked from sailfishos/ofono
Compare commits
15 Commits
mer/1.23+g
...
mer/1.23+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c0f5094a6 | ||
|
|
4208b6d9ea | ||
|
|
59e304d474 | ||
|
|
30a2424507 | ||
|
|
e4f3ec6322 | ||
|
|
95fd4efc37 | ||
|
|
ef5ee98508 | ||
|
|
4220e7d5e8 | ||
|
|
33c067a75f | ||
|
|
29616c04d0 | ||
|
|
beb997d914 | ||
|
|
3d147843c4 | ||
|
|
c01dc63cbc | ||
|
|
297926ed24 | ||
|
|
6ef1174ea8 |
1
ofono/.gitignore
vendored
1
ofono/.gitignore
vendored
@@ -45,6 +45,7 @@ unit/test-caif
|
||||
unit/test-stkutil
|
||||
unit/test-cdmasms
|
||||
unit/test-dbus-access
|
||||
unit/test-dbus-clients
|
||||
unit/test-dbus-queue
|
||||
unit/test-gprs-filter
|
||||
unit/test-ril_config
|
||||
|
||||
@@ -26,7 +26,7 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
|
||||
include/sms-filter.h include/gprs-filter.h \
|
||||
include/voicecall-filter.h include/dbus-access.h \
|
||||
include/ril-constants.h include/ril-transport.h \
|
||||
include/watch.h gdbus/gdbus.h \
|
||||
include/watch.h gdbus/gdbus.h include/dbus-clients.h \
|
||||
include/netmon.h include/lte.h include/ims.h \
|
||||
include/storage.h
|
||||
|
||||
@@ -775,7 +775,8 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
|
||||
src/handsfree-audio.c src/bluetooth.h \
|
||||
src/sim-mnclength.c src/voicecallagent.c \
|
||||
src/sms-filter.c src/gprs-filter.c \
|
||||
src/dbus-queue.c src/dbus-access.c src/config.c \
|
||||
src/dbus-clients.c src/dbus-queue.c \
|
||||
src/dbus-access.c src/config.c \
|
||||
src/voicecall-filter.c src/ril-transport.c \
|
||||
src/hfp.h src/siri.c src/watchlist.c \
|
||||
src/netmon.c src/lte.c src/ims.c \
|
||||
@@ -981,7 +982,7 @@ unit_test_sailfish_cell_info_dbus_SOURCES = unit/test-dbus.c \
|
||||
unit/fake_sailfish_cell_info.c \
|
||||
plugins/sailfish_manager/sailfish_cell_info.c \
|
||||
plugins/sailfish_manager/sailfish_cell_info_dbus.c \
|
||||
gdbus/object.c \
|
||||
gdbus/object.c src/dbus-clients.c \
|
||||
src/dbus.c src/log.c
|
||||
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||
@DBUS_GLIB_CFLAGS@
|
||||
@@ -1164,6 +1165,14 @@ unit_test_caif_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
||||
unit_test_caif_LDADD = @GLIB_LIBS@
|
||||
unit_objects += $(unit_test_caif_OBJECTS)
|
||||
|
||||
unit_test_dbus_clients_SOURCES = unit/test-dbus-clients.c unit/test-dbus.c \
|
||||
src/dbus-clients.c gdbus/object.c \
|
||||
src/dbus.c src/log.c
|
||||
unit_test_dbus_clients_CFLAGS = @DBUS_GLIB_CFLAGS@ $(COVERAGE_OPT) $(AM_CFLAGS)
|
||||
unit_test_dbus_clients_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_dbus_clients_OBJECTS)
|
||||
unit_tests += unit/test-dbus-clients
|
||||
|
||||
unit_test_dbus_queue_SOURCES = unit/test-dbus-queue.c unit/test-dbus.c \
|
||||
src/dbus-queue.c gdbus/object.c \
|
||||
src/dbus.c src/log.c
|
||||
|
||||
@@ -47,6 +47,7 @@ struct ril_cell_info {
|
||||
gulong event_id;
|
||||
guint query_id;
|
||||
guint set_rate_id;
|
||||
gboolean enabled;
|
||||
};
|
||||
|
||||
enum ril_cell_info_signal {
|
||||
@@ -331,7 +332,8 @@ static void ril_cell_info_list_cb(GRilIoChannel *io, int status,
|
||||
DBG_(self, "");
|
||||
GASSERT(self->query_id);
|
||||
self->query_id = 0;
|
||||
ril_cell_info_update_cells(self, (status == RIL_E_SUCCESS) ?
|
||||
ril_cell_info_update_cells(self,
|
||||
(status == RIL_E_SUCCESS && self->enabled) ?
|
||||
ril_cell_info_parse_list(io->ril_version, data, len) : NULL);
|
||||
}
|
||||
|
||||
@@ -348,12 +350,14 @@ static void ril_cell_info_set_rate_cb(GRilIoChannel *io, int status,
|
||||
static gboolean ril_cell_info_retry(GRilIoRequest* request, int ril_status,
|
||||
const void* response_data, guint response_len, void* user_data)
|
||||
{
|
||||
struct ril_cell_info *self = RIL_CELL_INFO(user_data);
|
||||
|
||||
switch (ril_status) {
|
||||
case RIL_E_SUCCESS:
|
||||
case RIL_E_RADIO_NOT_AVAILABLE:
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
return self->enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +377,8 @@ static void ril_cell_info_query(struct ril_cell_info *self)
|
||||
static void ril_cell_info_set_rate(struct ril_cell_info *self)
|
||||
{
|
||||
GRilIoRequest *req = grilio_request_array_int32_new(1,
|
||||
(self->update_rate_ms >= 0) ? self->update_rate_ms : INT_MAX);
|
||||
(self->update_rate_ms >= 0 && self->enabled) ?
|
||||
self->update_rate_ms : INT_MAX);
|
||||
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
|
||||
grilio_request_set_retry_func(req, ril_cell_info_retry);
|
||||
@@ -387,7 +392,8 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self)
|
||||
static void ril_cell_info_refresh(struct ril_cell_info *self)
|
||||
{
|
||||
/* RIL_REQUEST_GET_CELL_INFO_LIST fails without SIM card */
|
||||
if (self->radio->state == RADIO_STATE_ON && self->sim_card_ready) {
|
||||
if (self->enabled && self->radio->state == RADIO_STATE_ON &&
|
||||
self->sim_card_ready) {
|
||||
ril_cell_info_query(self);
|
||||
} else {
|
||||
ril_cell_info_update_cells(self, NULL);
|
||||
@@ -482,6 +488,21 @@ static void ril_cell_info_set_update_interval_proc
|
||||
if (self->update_rate_ms != ms) {
|
||||
self->update_rate_ms = ms;
|
||||
DBG_(self, "%d ms", ms);
|
||||
if (self->enabled && self->sim_card_ready) {
|
||||
ril_cell_info_set_rate(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ril_cell_info_set_enabled_proc(struct sailfish_cell_info *info,
|
||||
gboolean enabled)
|
||||
{
|
||||
struct ril_cell_info *self = ril_cell_info_cast(info);
|
||||
|
||||
if (self->enabled != enabled) {
|
||||
self->enabled = enabled;
|
||||
DBG_(self, "%d", enabled);
|
||||
ril_cell_info_refresh(self);
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_set_rate(self);
|
||||
}
|
||||
@@ -497,7 +518,8 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
||||
ril_cell_info_unref_proc,
|
||||
ril_cell_info_add_cells_changed_handler_proc,
|
||||
ril_cell_info_remove_handler_proc,
|
||||
ril_cell_info_set_update_interval_proc
|
||||
ril_cell_info_set_update_interval_proc,
|
||||
ril_cell_info_set_enabled_proc
|
||||
};
|
||||
|
||||
struct ril_cell_info *self = g_object_new(RIL_CELL_INFO_TYPE, 0);
|
||||
@@ -519,6 +541,9 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
||||
ril_cell_info_sim_status_cb, self);
|
||||
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
||||
ril_cell_info_refresh(self);
|
||||
|
||||
/* Disable updates by default */
|
||||
self->enabled = FALSE;
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_set_rate(self);
|
||||
}
|
||||
|
||||
55
ofono/include/dbus-clients.h
Normal file
55
ofono/include/dbus-clients.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Open Mobile Platform LLC.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OFONO_DBUS_CLIENTS_H
|
||||
#define OFONO_DBUS_CLIENTS_H
|
||||
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/dbus.h>
|
||||
|
||||
/* Since mer/1.23+git31 */
|
||||
|
||||
struct ofono_dbus_clients;
|
||||
|
||||
typedef void (*ofono_dbus_clients_notify_func)(const char *name,
|
||||
void *user_data);
|
||||
|
||||
struct ofono_dbus_clients *ofono_dbus_clients_new(DBusConnection *conn,
|
||||
ofono_dbus_clients_notify_func notify, void *user_data);
|
||||
void ofono_dbus_clients_free(struct ofono_dbus_clients *clients);
|
||||
|
||||
unsigned int ofono_dbus_clients_count(struct ofono_dbus_clients *clients);
|
||||
|
||||
ofono_bool_t ofono_dbus_clients_add(struct ofono_dbus_clients *clients,
|
||||
const char *name);
|
||||
ofono_bool_t ofono_dbus_clients_remove(struct ofono_dbus_clients *clients,
|
||||
const char *name);
|
||||
|
||||
void ofono_dbus_clients_signal(struct ofono_dbus_clients *clients,
|
||||
DBusMessage *signal);
|
||||
void ofono_dbus_clients_signal_property_changed(struct ofono_dbus_clients *dc,
|
||||
const char *path, const char *interface, const char *name,
|
||||
int type, const void *value);
|
||||
|
||||
#endif /* OFONO_DBUS_CLIENTS_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -3,7 +3,7 @@
|
||||
* oFono - Open Telephony stack for Linux
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013-2016 Jolla Ltd.
|
||||
* Copyright (C) 2013-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -14,10 +14,6 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OFONO_DBUS_H
|
||||
@@ -83,6 +79,8 @@ extern "C" {
|
||||
DBUS_TYPE_VARIANT_AS_STRING \
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||
|
||||
#define OFONO_ERROR_INTERFACE "org.ofono.Error"
|
||||
|
||||
DBusConnection *ofono_dbus_get_connection(void);
|
||||
|
||||
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
||||
@@ -110,6 +108,11 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||
const char *name, int type,
|
||||
const void *value);
|
||||
|
||||
/* Since mer/1.23+git31 */
|
||||
DBusMessage *ofono_dbus_signal_new_property_changed(const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -128,6 +128,14 @@ void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
|
||||
}
|
||||
}
|
||||
|
||||
void sailfish_cell_info_set_enabled(struct sailfish_cell_info *info,
|
||||
gboolean enabled)
|
||||
{
|
||||
if (info && info->proc->set_enabled) {
|
||||
info->proc->set_enabled(info, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
|
||||
@@ -89,6 +89,7 @@ struct sailfish_cell_info_proc {
|
||||
sailfish_cell_info_cb_t cb, void *arg);
|
||||
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
|
||||
void (*set_update_interval)(struct sailfish_cell_info *info, int ms);
|
||||
void (*set_enabled)(struct sailfish_cell_info *info, gboolean enabled);
|
||||
};
|
||||
|
||||
/* Utilities */
|
||||
@@ -107,6 +108,8 @@ void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
|
||||
gulong id);
|
||||
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
|
||||
int ms);
|
||||
void sailfish_cell_info_set_enabled(struct sailfish_cell_info *info,
|
||||
gboolean enabled);
|
||||
|
||||
#endif /* SAILFISH_CELINFO_H */
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2016-2018 Jolla Ltd.
|
||||
* Copyright (C) 2016-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/dbus.h>
|
||||
#include <ofono/dbus-clients.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include <gdbus.h>
|
||||
@@ -35,11 +36,13 @@ struct sailfish_cell_info_dbus {
|
||||
gulong handler_id;
|
||||
guint next_cell_id;
|
||||
GSList *entries;
|
||||
struct ofono_dbus_clients *clients;
|
||||
};
|
||||
|
||||
#define CELL_INFO_DBUS_INTERFACE "org.nemomobile.ofono.CellInfo"
|
||||
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
||||
#define CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL "CellsRemoved"
|
||||
#define CELL_INFO_DBUS_UNSUBSCRIBED_SIGNAL "Unsubscribed"
|
||||
|
||||
#define CELL_DBUS_INTERFACE_VERSION (1)
|
||||
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
||||
@@ -322,21 +325,24 @@ static void sailfish_cell_info_dbus_emit_path_list
|
||||
(struct sailfish_cell_info_dbus *dbus, const char *name,
|
||||
GPtrArray *list)
|
||||
{
|
||||
guint i;
|
||||
DBusMessageIter it, array;
|
||||
DBusMessage *signal = dbus_message_new_signal(dbus->path,
|
||||
if (ofono_dbus_clients_count(dbus->clients)) {
|
||||
guint i;
|
||||
DBusMessageIter it, a;
|
||||
DBusMessage *signal = dbus_message_new_signal(dbus->path,
|
||||
CELL_INFO_DBUS_INTERFACE, name);
|
||||
|
||||
dbus_message_iter_init_append(signal, &it);
|
||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &array);
|
||||
for (i = 0; i < list->len; i++) {
|
||||
const char* path = list->pdata[i];
|
||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
|
||||
&path);
|
||||
}
|
||||
dbus_message_iter_close_container(&it, &array);
|
||||
dbus_message_iter_init_append(signal, &it);
|
||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &a);
|
||||
for (i = 0; i < list->len; i++) {
|
||||
const char* path = list->pdata[i];
|
||||
|
||||
g_dbus_send_message(dbus->conn, signal);
|
||||
dbus_message_iter_append_basic(&a,
|
||||
DBUS_TYPE_OBJECT_PATH, &path);
|
||||
}
|
||||
dbus_message_iter_close_container(&it, &a);
|
||||
ofono_dbus_clients_signal(dbus->clients, signal);
|
||||
dbus_message_unref(signal);
|
||||
}
|
||||
}
|
||||
|
||||
static int sailfish_cell_info_dbus_compare(const struct sailfish_cell *c1,
|
||||
@@ -366,6 +372,23 @@ static int sailfish_cell_info_dbus_compare(const struct sailfish_cell *c1,
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_cell_info_dbus_emit_signal
|
||||
(struct sailfish_cell_info_dbus *dbus,
|
||||
const char *path, const char *intf,
|
||||
const char *name, int type, ...)
|
||||
{
|
||||
if (ofono_dbus_clients_count(dbus->clients)) {
|
||||
va_list args;
|
||||
DBusMessage *signal = dbus_message_new_signal(path, intf, name);
|
||||
|
||||
va_start(args, type);
|
||||
dbus_message_append_args_valist(signal, type, args);
|
||||
ofono_dbus_clients_signal(dbus->clients, signal);
|
||||
dbus_message_unref(signal);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_cell_info_dbus_property_changed
|
||||
(struct sailfish_cell_info_dbus *dbus,
|
||||
const struct sailfish_cell_entry *entry, int mask)
|
||||
@@ -377,7 +400,8 @@ static void sailfish_cell_info_dbus_property_changed
|
||||
|
||||
if (mask & SAILFISH_CELL_PROPERTY_REGISTERED) {
|
||||
const dbus_bool_t registered = (cell->registered != FALSE);
|
||||
g_dbus_emit_signal(dbus->conn, entry->path,
|
||||
|
||||
sailfish_cell_info_dbus_emit_signal(dbus, entry->path,
|
||||
CELL_DBUS_INTERFACE,
|
||||
CELL_DBUS_REGISTERED_CHANGED_SIGNAL,
|
||||
DBUS_TYPE_BOOLEAN, ®istered, DBUS_TYPE_INVALID);
|
||||
@@ -386,9 +410,10 @@ static void sailfish_cell_info_dbus_property_changed
|
||||
|
||||
for (i = 0; i < n && mask; i++) {
|
||||
if (mask & prop[i].flag) {
|
||||
ofono_dbus_signal_property_changed(dbus->conn,
|
||||
entry->path, CELL_DBUS_INTERFACE,
|
||||
prop[i].name, DBUS_TYPE_INT32,
|
||||
ofono_dbus_clients_signal_property_changed(
|
||||
dbus->clients, entry->path,
|
||||
CELL_DBUS_INTERFACE, prop[i].name,
|
||||
DBUS_TYPE_INT32,
|
||||
G_STRUCT_MEMBER_P(&cell->info, prop[i].off));
|
||||
mask &= ~prop[i].flag;
|
||||
}
|
||||
@@ -411,7 +436,7 @@ static void sailfish_cell_info_dbus_update_entries
|
||||
sailfish_cell_compare_func)) {
|
||||
DBG("%s removed", entry->path);
|
||||
dbus->entries = g_slist_delete_link(dbus->entries, l);
|
||||
g_dbus_emit_signal(dbus->conn, entry->path,
|
||||
sailfish_cell_info_dbus_emit_signal(dbus, entry->path,
|
||||
CELL_DBUS_INTERFACE,
|
||||
CELL_DBUS_REMOVED_SIGNAL,
|
||||
DBUS_TYPE_INVALID);
|
||||
@@ -492,29 +517,67 @@ static void sailfish_cell_info_dbus_cells_changed_cb
|
||||
((struct sailfish_cell_info_dbus *)arg, TRUE);
|
||||
}
|
||||
|
||||
static DBusMessage *sailfish_cell_info_dbus_error_failed(DBusMessage *msg,
|
||||
const char *explanation)
|
||||
{
|
||||
return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE ".Failed", "%s",
|
||||
explanation);
|
||||
}
|
||||
|
||||
static DBusMessage *sailfish_cell_info_dbus_get_cells(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct sailfish_cell_info_dbus *dbus = data;
|
||||
DBusMessage *reply = dbus_message_new_method_return(msg);
|
||||
DBusMessageIter it, array;
|
||||
GSList *l;
|
||||
const char *sender = dbus_message_get_sender(msg);
|
||||
|
||||
dbus_message_iter_init_append(reply, &it);
|
||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &array);
|
||||
for (l = dbus->entries; l; l = l->next) {
|
||||
const struct sailfish_cell_entry *entry = l->data;
|
||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
|
||||
&entry->path);
|
||||
if (ofono_dbus_clients_add(dbus->clients, sender)) {
|
||||
DBusMessage *reply = dbus_message_new_method_return(msg);
|
||||
DBusMessageIter it, a;
|
||||
GSList *l;
|
||||
|
||||
sailfish_cell_info_set_enabled(dbus->info, TRUE);
|
||||
dbus_message_iter_init_append(reply, &it);
|
||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &a);
|
||||
for (l = dbus->entries; l; l = l->next) {
|
||||
const struct sailfish_cell_entry *entry = l->data;
|
||||
|
||||
dbus_message_iter_append_basic(&a,
|
||||
DBUS_TYPE_OBJECT_PATH, &entry->path);
|
||||
}
|
||||
dbus_message_iter_close_container(&it, &a);
|
||||
return reply;
|
||||
}
|
||||
dbus_message_iter_close_container(&it, &array);
|
||||
return reply;
|
||||
return sailfish_cell_info_dbus_error_failed(msg, "Operation failed");
|
||||
}
|
||||
|
||||
static DBusMessage *sailfish_cell_info_dbus_unsubscribe(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct sailfish_cell_info_dbus *dbus = data;
|
||||
const char *sender = dbus_message_get_sender(msg);
|
||||
|
||||
DBG("%s", sender);
|
||||
if (ofono_dbus_clients_remove(dbus->clients, sender)) {
|
||||
DBusMessage *signal = dbus_message_new_signal(dbus->path,
|
||||
CELL_INFO_DBUS_INTERFACE,
|
||||
CELL_INFO_DBUS_UNSUBSCRIBED_SIGNAL);
|
||||
|
||||
if (!ofono_dbus_clients_count(dbus->clients)) {
|
||||
sailfish_cell_info_set_enabled(dbus->info, FALSE);
|
||||
}
|
||||
dbus_message_set_destination(signal, sender);
|
||||
g_dbus_send_message(dbus->conn, signal);
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
return sailfish_cell_info_dbus_error_failed(msg, "Not subscribed");
|
||||
}
|
||||
|
||||
static const GDBusMethodTable sailfish_cell_info_dbus_methods[] = {
|
||||
{ GDBUS_METHOD("GetCells", NULL,
|
||||
GDBUS_ARGS({ "paths", "ao" }),
|
||||
sailfish_cell_info_dbus_get_cells) },
|
||||
{ GDBUS_METHOD("Unsubscribe", NULL, NULL,
|
||||
sailfish_cell_info_dbus_unsubscribe) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -523,9 +586,20 @@ static const GDBusSignalTable sailfish_cell_info_dbus_signals[] = {
|
||||
GDBUS_ARGS({ "paths", "ao" })) },
|
||||
{ GDBUS_SIGNAL(CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL,
|
||||
GDBUS_ARGS({ "paths", "ao" })) },
|
||||
{ GDBUS_SIGNAL(CELL_INFO_DBUS_UNSUBSCRIBED_SIGNAL,
|
||||
GDBUS_ARGS({})) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static void sailfish_cell_info_dbus_disconnect_cb(const char *name, void *data)
|
||||
{
|
||||
struct sailfish_cell_info_dbus *dbus = data;
|
||||
|
||||
if (!ofono_dbus_clients_count(dbus->clients)) {
|
||||
sailfish_cell_info_set_enabled(dbus->info, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
struct sailfish_cell_info_dbus *sailfish_cell_info_dbus_new
|
||||
(struct ofono_modem *modem, struct sailfish_cell_info *info)
|
||||
{
|
||||
@@ -550,6 +624,8 @@ struct sailfish_cell_info_dbus *sailfish_cell_info_dbus_new
|
||||
ofono_modem_add_interface(modem,
|
||||
CELL_INFO_DBUS_INTERFACE);
|
||||
sailfish_cell_info_dbus_update_entries(dbus, FALSE);
|
||||
dbus->clients = ofono_dbus_clients_new(dbus->conn,
|
||||
sailfish_cell_info_dbus_disconnect_cb, dbus);
|
||||
return dbus;
|
||||
} else {
|
||||
ofono_error("CellInfo D-Bus register failed");
|
||||
@@ -565,6 +641,7 @@ void sailfish_cell_info_dbus_free(struct sailfish_cell_info_dbus *dbus)
|
||||
GSList *l;
|
||||
|
||||
DBG("%s", dbus->path);
|
||||
ofono_dbus_clients_free(dbus->clients);
|
||||
g_dbus_unregister_interface(dbus->conn, dbus->path,
|
||||
CELL_INFO_DBUS_INTERFACE);
|
||||
|
||||
|
||||
182
ofono/src/dbus-clients.c
Normal file
182
ofono/src/dbus-clients.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017-2018 Jolla Ltd.
|
||||
* Copyright (C) 2020 Open Mobile Platform LLC.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <ofono/dbus-clients.h>
|
||||
#include <ofono/gdbus.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
struct ofono_dbus_client {
|
||||
struct ofono_dbus_clients *clients;
|
||||
char *name;
|
||||
unsigned int watch_id;
|
||||
};
|
||||
|
||||
struct ofono_dbus_clients {
|
||||
DBusConnection* conn;
|
||||
GHashTable* table;
|
||||
ofono_dbus_clients_notify_func notify;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
/* Compatible with GDestroyNotify */
|
||||
static void ofono_dbus_client_free(struct ofono_dbus_client *client)
|
||||
{
|
||||
struct ofono_dbus_clients *clients = client->clients;
|
||||
|
||||
/* Callers make sure that client parameter is not NULL */
|
||||
if (client->watch_id) {
|
||||
g_dbus_remove_watch(clients->conn, client->watch_id);
|
||||
}
|
||||
g_free(client->name);
|
||||
g_slice_free(struct ofono_dbus_client, client);
|
||||
}
|
||||
|
||||
static void ofono_dbus_clients_disconnect_notify(DBusConnection *connection,
|
||||
void *user_data)
|
||||
{
|
||||
struct ofono_dbus_client *client = user_data;
|
||||
struct ofono_dbus_clients *self = client->clients;
|
||||
char *name = client->name;
|
||||
|
||||
/*
|
||||
* Steal the name so that it doesn't get freed by
|
||||
* ofono_dbus_client_free(). We want to pass it to
|
||||
* the callback but first we need to delete client's
|
||||
* entry from the hashtable.
|
||||
*/
|
||||
client->name = NULL;
|
||||
DBG("%s is gone", name);
|
||||
g_hash_table_remove(self->table, name);
|
||||
if (self->notify) {
|
||||
self->notify(name, self->user_data);
|
||||
}
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
struct ofono_dbus_clients *ofono_dbus_clients_new(DBusConnection *conn,
|
||||
ofono_dbus_clients_notify_func notify, void *user_data)
|
||||
{
|
||||
if (conn) {
|
||||
struct ofono_dbus_clients *self =
|
||||
g_slice_new0(struct ofono_dbus_clients);
|
||||
|
||||
self->conn = dbus_connection_ref(conn);
|
||||
self->table = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) ofono_dbus_client_free);
|
||||
self->notify = notify;
|
||||
self->user_data = user_data;
|
||||
return self;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ofono_dbus_clients_free(struct ofono_dbus_clients *self)
|
||||
{
|
||||
if (self) {
|
||||
g_hash_table_destroy(self->table);
|
||||
dbus_connection_unref(self->conn);
|
||||
g_slice_free(struct ofono_dbus_clients, self);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ofono_dbus_clients_count(struct ofono_dbus_clients *self)
|
||||
{
|
||||
return self ? g_hash_table_size(self->table) : 0;
|
||||
}
|
||||
|
||||
ofono_bool_t ofono_dbus_clients_add(struct ofono_dbus_clients *self,
|
||||
const char *name)
|
||||
{
|
||||
if (self && name) {
|
||||
struct ofono_dbus_client *client =
|
||||
g_slice_new0(struct ofono_dbus_client);
|
||||
|
||||
client->clients = self;
|
||||
client->name = g_strdup(name);
|
||||
client->watch_id = g_dbus_add_disconnect_watch(self->conn,
|
||||
client->name, ofono_dbus_clients_disconnect_notify,
|
||||
client, NULL);
|
||||
|
||||
if (client->watch_id) {
|
||||
DBG("%s is registered", client->name);
|
||||
g_hash_table_replace(self->table, (gpointer)
|
||||
client->name, client);
|
||||
return TRUE;
|
||||
} else {
|
||||
DBG("failed to register %s", client->name);
|
||||
ofono_dbus_client_free(client);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ofono_bool_t ofono_dbus_clients_remove(struct ofono_dbus_clients *self,
|
||||
const char *name)
|
||||
{
|
||||
return self && name && g_hash_table_remove(self->table, name);
|
||||
}
|
||||
|
||||
void ofono_dbus_clients_signal(struct ofono_dbus_clients *self,
|
||||
DBusMessage *signal)
|
||||
{
|
||||
if (self && signal && g_hash_table_size(self->table)) {
|
||||
GHashTableIter it;
|
||||
gpointer key;
|
||||
const char *last_name = NULL;
|
||||
|
||||
g_hash_table_iter_init(&it, self->table);
|
||||
g_hash_table_iter_next(&it, &key, NULL);
|
||||
last_name = key;
|
||||
|
||||
while (g_hash_table_iter_next(&it, &key, NULL)) {
|
||||
DBusMessage *copy = dbus_message_copy(signal);
|
||||
|
||||
dbus_message_set_destination(copy, key);
|
||||
g_dbus_send_message(self->conn, copy);
|
||||
}
|
||||
|
||||
/*
|
||||
* The last one. Note that g_dbus_send_message() unrefs
|
||||
* the message, we need compensate for that by adding a
|
||||
* reference. The caller still owns the message when this
|
||||
* function returns.
|
||||
*/
|
||||
dbus_message_ref(signal);
|
||||
dbus_message_set_destination(signal, last_name);
|
||||
g_dbus_send_message(self->conn, signal);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_dbus_clients_signal_property_changed(struct ofono_dbus_clients *self,
|
||||
const char *path, const char *interface, const char *name,
|
||||
int type, const void *value)
|
||||
{
|
||||
if (self && g_hash_table_size(self->table)) {
|
||||
DBusMessage *sig = ofono_dbus_signal_new_property_changed(path,
|
||||
interface, name, type, value);
|
||||
|
||||
ofono_dbus_clients_signal(self, sig);
|
||||
dbus_message_unref(sig);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -3,6 +3,7 @@
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -13,10 +14,6 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@@ -29,8 +26,6 @@
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
#define OFONO_ERROR_INTERFACE "org.ofono.Error"
|
||||
|
||||
static DBusConnection *g_connection;
|
||||
|
||||
struct error_mapping_entry {
|
||||
@@ -209,8 +204,8 @@ void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||
dbus_message_iter_close_container(dict, &entry);
|
||||
}
|
||||
|
||||
int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
/* Since mer/1.23+git31 */
|
||||
DBusMessage *ofono_dbus_signal_new_property_changed(const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value)
|
||||
@@ -219,11 +214,8 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
DBusMessageIter iter;
|
||||
|
||||
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
|
||||
if (signal == NULL) {
|
||||
ofono_error("Unable to allocate new %s.PropertyChanged signal",
|
||||
interface);
|
||||
return -1;
|
||||
}
|
||||
if (signal == NULL)
|
||||
return NULL;
|
||||
|
||||
dbus_message_iter_init_append(signal, &iter);
|
||||
|
||||
@@ -231,6 +223,24 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
|
||||
append_variant(&iter, type, value);
|
||||
|
||||
return signal;
|
||||
}
|
||||
|
||||
int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, const void *value)
|
||||
{
|
||||
DBusMessage *signal = ofono_dbus_signal_new_property_changed(path,
|
||||
interface, name, type, value);
|
||||
|
||||
if (signal == NULL) {
|
||||
ofono_error("Unable to allocate new %s.PropertyChanged signal",
|
||||
interface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return g_dbus_send_message(conn, signal);
|
||||
}
|
||||
|
||||
|
||||
@@ -994,18 +994,17 @@ static void bac_cb(GAtServer *server, GAtServerRequestType type,
|
||||
/*
|
||||
* CVSD codec is mandatory and must come first.
|
||||
* See HFP v1.6 4.34.1
|
||||
* However, some headsets send the list in wrong order,
|
||||
* but function fine otherwise, so to get those working
|
||||
* let's not be pedantic about the codec order.
|
||||
*/
|
||||
if (g_at_result_iter_next_number(&iter, &val) == FALSE ||
|
||||
val != HFP_CODEC_CVSD)
|
||||
goto fail;
|
||||
|
||||
em->bac_received = TRUE;
|
||||
|
||||
em->negotiated_codec = 0;
|
||||
em->r_codecs[CVSD_OFFSET].supported = TRUE;
|
||||
|
||||
while (g_at_result_iter_next_number(&iter, &val)) {
|
||||
switch (val) {
|
||||
case HFP_CODEC_CVSD:
|
||||
em->bac_received = TRUE;
|
||||
em->negotiated_codec = 0;
|
||||
em->r_codecs[CVSD_OFFSET].supported = TRUE;
|
||||
break;
|
||||
case HFP_CODEC_MSBC:
|
||||
em->r_codecs[MSBC_OFFSET].supported = TRUE;
|
||||
break;
|
||||
@@ -1015,6 +1014,11 @@ static void bac_cb(GAtServer *server, GAtServerRequestType type,
|
||||
}
|
||||
}
|
||||
|
||||
if (!em->bac_received) {
|
||||
DBG("Mandatory codec %d not received.", HFP_CODEC_CVSD);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
|
||||
|
||||
/*
|
||||
|
||||
@@ -405,18 +405,18 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error,
|
||||
}
|
||||
|
||||
start_block = op->offset / 256;
|
||||
end_block = (op->offset + (op->num_bytes - 1)) / 256;
|
||||
end_block = op->num_bytes ? (op->offset + op->num_bytes - 1) / 256 :
|
||||
start_block;
|
||||
|
||||
if (op->current == start_block) {
|
||||
bufoff = 0;
|
||||
dataoff = op->offset % 256;
|
||||
tocopy = MIN(256 - op->offset % 256,
|
||||
op->num_bytes - op->current * 256);
|
||||
tocopy = MIN(256 - dataoff, op->num_bytes);
|
||||
} else {
|
||||
bufoff = (op->current - start_block - 1) * 256 +
|
||||
bufoff = (op->current - start_block) * 256 -
|
||||
op->offset % 256;
|
||||
dataoff = 0;
|
||||
tocopy = MIN(256, op->num_bytes - op->current * 256);
|
||||
tocopy = MIN(256, op->num_bytes - bufoff);
|
||||
}
|
||||
|
||||
DBG("bufoff: %d, dataoff: %d, tocopy: %d",
|
||||
@@ -485,13 +485,12 @@ static gboolean sim_fs_op_read_block(gpointer user_data)
|
||||
bufoff = 0;
|
||||
seekoff = SIM_CACHE_HEADER_SIZE + op->current * 256 +
|
||||
op->offset % 256;
|
||||
toread = MIN(256 - op->offset % 256,
|
||||
op->num_bytes - op->current * 256);
|
||||
toread = MIN(256 - op->offset % 256, op->num_bytes);
|
||||
} else {
|
||||
bufoff = (op->current - start_block - 1) * 256 +
|
||||
bufoff = (op->current - start_block) * 256 -
|
||||
op->offset % 256;
|
||||
seekoff = SIM_CACHE_HEADER_SIZE + op->current * 256;
|
||||
toread = MIN(256, op->num_bytes - op->current * 256);
|
||||
toread = MIN(256, op->num_bytes - bufoff);
|
||||
}
|
||||
|
||||
DBG("bufoff: %d, seekoff: %d, toread: %d",
|
||||
|
||||
@@ -18,6 +18,7 @@ TESTS="\
|
||||
test-caif \
|
||||
test-dbus-queue \
|
||||
test-dbus-access \
|
||||
test-dbus-clients \
|
||||
test-gprs-filter \
|
||||
test-provision \
|
||||
test-config \
|
||||
|
||||
280
ofono/unit/test-dbus-clients.c
Normal file
280
ofono/unit/test-dbus-clients.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2021 Jolla Ltd. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "test-dbus.h"
|
||||
|
||||
#include <ofono/dbus-clients.h>
|
||||
#include <ofono/dbus.h>
|
||||
#include <ofono/log.h>
|
||||
#include "ofono.h"
|
||||
|
||||
#include <gutil_log.h>
|
||||
#include <gutil_macros.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define TEST_TIMEOUT (10) /* seconds */
|
||||
#define TEST_SENDER ":1.0"
|
||||
#define TEST_SENDER_1 ":1.1"
|
||||
|
||||
#define TEST_DBUS_PATH "/test"
|
||||
#define TEST_DBUS_INTERFACE "test.interface"
|
||||
#define TEST_PROPERTY_CHANGED_SIGNAL "PropertyChanged"
|
||||
#define TEST_PROPERTY_NAME "Test"
|
||||
#define TEST_PROPERTY_VALUE "test"
|
||||
|
||||
struct test_data {
|
||||
struct test_dbus_context dbus;
|
||||
struct ofono_dbus_clients *clients;
|
||||
int count;
|
||||
};
|
||||
|
||||
static gboolean test_debug;
|
||||
|
||||
/* ==== dummy interface ==== */
|
||||
|
||||
#define test_register_interface(methods,signals,data) \
|
||||
g_assert(g_dbus_register_interface(ofono_dbus_get_connection(), \
|
||||
TEST_DBUS_PATH, TEST_DBUS_INTERFACE, \
|
||||
methods, signals, NULL, data, NULL))
|
||||
|
||||
#define test_register_dummy_interface() \
|
||||
test_register_interface(test_dummy_methods, \
|
||||
test_property_change_signal, NULL)
|
||||
|
||||
static DBusMessage *test_dummy_handler(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const GDBusMethodTable test_dummy_methods[] = {
|
||||
{ GDBUS_ASYNC_METHOD("Dummy", NULL, NULL, test_dummy_handler) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const GDBusSignalTable test_property_change_signal[] = {
|
||||
{ GDBUS_SIGNAL("PropertyChanged",
|
||||
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
|
||||
{ }
|
||||
};
|
||||
|
||||
/* ==== common ==== */
|
||||
|
||||
static gboolean test_timeout(gpointer param)
|
||||
{
|
||||
g_assert(!"TIMEOUT");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static guint test_setup_timeout(void)
|
||||
{
|
||||
if (test_debug) {
|
||||
return 0;
|
||||
} else {
|
||||
return g_timeout_add_seconds(TEST_TIMEOUT, test_timeout, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean test_loop_quit(gpointer data)
|
||||
{
|
||||
g_main_loop_quit(data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void test_loop_quit_later(GMainLoop *loop)
|
||||
{
|
||||
g_idle_add(test_loop_quit, loop);
|
||||
}
|
||||
|
||||
/* ==== null ==== */
|
||||
|
||||
static void test_null(void)
|
||||
{
|
||||
/* We are NULL tolerant: */
|
||||
ofono_dbus_clients_free(NULL);
|
||||
ofono_dbus_clients_signal(NULL, NULL);
|
||||
ofono_dbus_clients_signal_property_changed(NULL,NULL,NULL,NULL,0,NULL);
|
||||
g_assert(!ofono_dbus_clients_new(NULL, NULL, NULL));
|
||||
g_assert(!ofono_dbus_clients_count(NULL));
|
||||
g_assert(!ofono_dbus_clients_add(NULL, NULL));
|
||||
g_assert(!ofono_dbus_clients_remove(NULL, NULL));
|
||||
}
|
||||
|
||||
/* ==== basic ==== */
|
||||
|
||||
static void test_basic_notify_func(const char *name, void *loop)
|
||||
{
|
||||
g_assert_cmpstr(name, == ,TEST_SENDER);
|
||||
g_main_loop_quit(loop);
|
||||
}
|
||||
|
||||
static void test_basic_start(struct test_dbus_context *dbus)
|
||||
{
|
||||
struct test_data *test = G_CAST(dbus, struct test_data, dbus);
|
||||
const char *value = TEST_PROPERTY_VALUE;
|
||||
DBusMessage *signal =
|
||||
ofono_dbus_signal_new_property_changed(TEST_DBUS_PATH,
|
||||
TEST_DBUS_INTERFACE, TEST_PROPERTY_NAME,
|
||||
DBUS_TYPE_STRING, &value);
|
||||
|
||||
test->clients = ofono_dbus_clients_new(ofono_dbus_get_connection(),
|
||||
test_basic_notify_func, test->dbus.loop);
|
||||
|
||||
g_assert(!ofono_dbus_clients_add(test->clients, NULL));
|
||||
g_assert(ofono_dbus_clients_add(test->clients, TEST_SENDER));
|
||||
g_assert(ofono_dbus_clients_remove(test->clients, TEST_SENDER));
|
||||
g_assert(!ofono_dbus_clients_remove(test->clients, TEST_SENDER));
|
||||
|
||||
/* OK to add the same thing twice */
|
||||
g_assert(ofono_dbus_clients_add(test->clients, TEST_SENDER));
|
||||
g_assert(ofono_dbus_clients_add(test->clients, TEST_SENDER));
|
||||
g_assert_cmpuint(ofono_dbus_clients_count(test->clients), == ,1);
|
||||
test_dbus_watch_disconnect_all();
|
||||
g_assert_cmpuint(ofono_dbus_clients_count(test->clients), == ,0);
|
||||
|
||||
/* There's nothing to remove */
|
||||
g_assert(!ofono_dbus_clients_remove(test->clients, TEST_SENDER));
|
||||
g_assert(!ofono_dbus_clients_remove(test->clients, NULL));
|
||||
|
||||
/* These have no effect because client list is empty: */
|
||||
ofono_dbus_clients_signal(test->clients, NULL);
|
||||
ofono_dbus_clients_signal(test->clients, signal);
|
||||
ofono_dbus_clients_signal_property_changed(test->clients, NULL, NULL,
|
||||
NULL, 0, NULL);
|
||||
ofono_dbus_clients_signal_property_changed(test->clients,
|
||||
TEST_DBUS_PATH, TEST_DBUS_INTERFACE,
|
||||
TEST_PROPERTY_NAME, DBUS_TYPE_STRING, &value);
|
||||
|
||||
/* test_basic_notify_func() has called test_loop_quit_later() */
|
||||
dbus_message_unref(signal);
|
||||
}
|
||||
|
||||
static void test_basic(void)
|
||||
{
|
||||
struct test_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test_dbus_setup(&test.dbus);
|
||||
test.dbus.start = test_basic_start;
|
||||
|
||||
g_main_loop_run(test.dbus.loop);
|
||||
|
||||
g_assert(test.clients);
|
||||
ofono_dbus_clients_free(test.clients);
|
||||
test_dbus_shutdown(&test.dbus);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== signal ==== */
|
||||
|
||||
static void test_signal_handle(struct test_dbus_context *dbus, DBusMessage *msg)
|
||||
{
|
||||
struct test_data *test = G_CAST(dbus, struct test_data, dbus);
|
||||
|
||||
g_assert_cmpstr(dbus_message_get_path(msg), == ,TEST_DBUS_PATH);
|
||||
g_assert_cmpstr(dbus_message_get_interface(msg), == ,
|
||||
TEST_DBUS_INTERFACE);
|
||||
g_assert_cmpstr(dbus_message_get_member(msg), == ,
|
||||
TEST_PROPERTY_CHANGED_SIGNAL);
|
||||
test->count++;
|
||||
if (test->count == 2) {
|
||||
test_loop_quit_later(dbus->loop);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_signal_start(struct test_dbus_context *dbus)
|
||||
{
|
||||
struct test_data *test = G_CAST(dbus, struct test_data, dbus);
|
||||
const char *value = TEST_PROPERTY_VALUE;
|
||||
|
||||
test_register_dummy_interface();
|
||||
test->clients = ofono_dbus_clients_new(ofono_dbus_get_connection(),
|
||||
NULL, NULL);
|
||||
|
||||
g_assert(ofono_dbus_clients_add(test->clients, TEST_SENDER));
|
||||
g_assert(ofono_dbus_clients_add(test->clients, TEST_SENDER_1));
|
||||
g_assert_cmpuint(ofono_dbus_clients_count(test->clients), == ,2);
|
||||
|
||||
ofono_dbus_clients_signal_property_changed(test->clients,
|
||||
TEST_DBUS_PATH, TEST_DBUS_INTERFACE,
|
||||
TEST_PROPERTY_NAME, DBUS_TYPE_STRING, &value);
|
||||
/* And wait for 2 signals to arrive */
|
||||
}
|
||||
|
||||
static void test_signal(void)
|
||||
{
|
||||
struct test_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test_dbus_setup(&test.dbus);
|
||||
test.dbus.start = test_signal_start;
|
||||
test.dbus.handle_signal = test_signal_handle;
|
||||
|
||||
g_main_loop_run(test.dbus.loop);
|
||||
|
||||
g_assert_cmpuint(ofono_dbus_clients_count(test.clients), == ,2);
|
||||
test_dbus_watch_disconnect_all();
|
||||
g_assert_cmpuint(ofono_dbus_clients_count(test.clients), == ,0);
|
||||
ofono_dbus_clients_free(test.clients);
|
||||
|
||||
test_dbus_shutdown(&test.dbus);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_(name) "/dbus-clients/" name
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "-d") || !strcmp(arg, "--debug")) {
|
||||
test_debug = TRUE;
|
||||
} else {
|
||||
GWARN("Unsupported command line option %s", arg);
|
||||
}
|
||||
}
|
||||
|
||||
gutil_log_timestamp = FALSE;
|
||||
gutil_log_default.level = g_test_verbose() ?
|
||||
GLOG_LEVEL_VERBOSE : GLOG_LEVEL_NONE;
|
||||
__ofono_log_init("test-dbus-clients",
|
||||
g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("null"), test_null);
|
||||
g_test_add_func(TEST_("basic"), test_basic);
|
||||
g_test_add_func(TEST_("signal"), test_signal);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018-2019 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -133,6 +133,13 @@ guint g_dbus_add_signal_watch(DBusConnection *connection, const char *sender,
|
||||
return test_dbus_add_watch(connection, NULL, destroy, user_data);
|
||||
}
|
||||
|
||||
guint g_dbus_add_disconnect_watch(DBusConnection *connection, const char *name,
|
||||
GDBusWatchFunction func, void *user_data,
|
||||
GDBusDestroyFunction destroy)
|
||||
{
|
||||
return test_dbus_add_watch(connection, func, destroy, user_data);
|
||||
}
|
||||
|
||||
gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
|
||||
{
|
||||
struct test_dbus_watch *prev = NULL;
|
||||
@@ -303,6 +310,9 @@ static DBusHandlerResult test_dbus_client_message_cb(DBusConnection *conn,
|
||||
dbus_message_get_path(msg));
|
||||
test->client_signals = g_slist_append(test->client_signals,
|
||||
dbus_message_ref(msg));
|
||||
if (test->handle_signal) {
|
||||
test->handle_signal(test, msg);
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
} else {
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -25,6 +25,7 @@ struct test_dbus_context {
|
||||
DBusConnection *client_connection;
|
||||
GSList* client_signals;
|
||||
void (*start)(struct test_dbus_context *test);
|
||||
void (*handle_signal)(struct test_dbus_context *test, DBusMessage *msg);
|
||||
guint timeout_id;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -31,6 +31,7 @@
|
||||
#define CELL_INFO_DBUS_INTERFACE "org.nemomobile.ofono.CellInfo"
|
||||
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
||||
#define CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL "CellsRemoved"
|
||||
#define CELL_INFO_DBUS_UNSUBSCRIBED_SIGNAL "Unsubscribed"
|
||||
|
||||
#define CELL_DBUS_INTERFACE_VERSION (1)
|
||||
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
||||
@@ -66,7 +67,7 @@ static gboolean test_timeout(gpointer param)
|
||||
|
||||
static guint test_setup_timeout(void)
|
||||
{
|
||||
if (!test_debug) {
|
||||
if (test_debug) {
|
||||
return 0;
|
||||
} else {
|
||||
return g_timeout_add_seconds(TEST_TIMEOUT, test_timeout, NULL);
|
||||
@@ -102,6 +103,19 @@ static DBusMessage *test_new_cell_call(const char *path, const char *method)
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void test_submit_cell_info_call(DBusConnection* connection,
|
||||
const char *method, DBusPendingCallNotifyFunction notify,
|
||||
void *data)
|
||||
{
|
||||
DBusMessage *msg = test_new_cell_info_call(method);
|
||||
DBusPendingCall* call;
|
||||
|
||||
g_assert(dbus_connection_send_with_reply(connection, msg, &call,
|
||||
DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, notify, data, NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void test_submit_get_all_call(DBusConnection* connection,
|
||||
const char *cell_path, DBusPendingCallNotifyFunction notify,
|
||||
void *data)
|
||||
@@ -186,6 +200,26 @@ static void test_check_get_all_reply(DBusPendingCall *call,
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static void test_check_empty_reply(DBusPendingCall *call)
|
||||
{
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
dbus_message_iter_init(reply, &it);
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static void test_check_error(DBusPendingCall *call, const char* name)
|
||||
{
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
|
||||
g_assert(dbus_message_is_error(reply, name));
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static struct sailfish_cell *test_cell_init_gsm1(struct sailfish_cell *cell)
|
||||
{
|
||||
struct sailfish_cell_info_gsm *gsm = &cell->info.gsm;
|
||||
@@ -311,19 +345,13 @@ struct test_get_cells_data {
|
||||
static void test_get_cells_call(struct test_get_cells_data *test,
|
||||
DBusPendingCallNotifyFunction notify)
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
DBusConnection *connection = test->context.client_connection;
|
||||
DBusMessage *msg = test_new_cell_info_call("GetCells");
|
||||
|
||||
g_assert(dbus_connection_send_with_reply(connection, msg, &call,
|
||||
DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, notify, test, NULL);
|
||||
dbus_message_unref(msg);
|
||||
test_submit_cell_info_call(test->context.client_connection, "GetCells",
|
||||
notify, test);
|
||||
}
|
||||
|
||||
static void test_get_cells_start_reply3(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_cells_data *test = data;
|
||||
struct test_get_cells_data *test = data;
|
||||
DBusMessageIter it;
|
||||
DBusMessage *signal = test_dbus_take_signal(&test->context,
|
||||
test->modem.path, CELL_INFO_DBUS_INTERFACE,
|
||||
@@ -344,7 +372,7 @@ static void test_get_cells_start_reply3(DBusPendingCall *call, void *data)
|
||||
|
||||
static void test_get_cells_start_reply2(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_cells_data *test = data;
|
||||
struct test_get_cells_data *test = data;
|
||||
const char *cell_added = "/test/cell_1";
|
||||
struct sailfish_cell cell;
|
||||
DBusMessageIter it;
|
||||
@@ -371,7 +399,7 @@ static void test_get_cells_start_reply2(DBusPendingCall *call, void *data)
|
||||
|
||||
static void test_get_cells_start_reply1(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_cells_data *test = data;
|
||||
struct test_get_cells_data *test = data;
|
||||
struct sailfish_cell cell;
|
||||
|
||||
DBG("");
|
||||
@@ -432,7 +460,7 @@ struct test_get_all_data {
|
||||
|
||||
static void test_get_all_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_all_data *test = data;
|
||||
struct test_get_all_data *test = data;
|
||||
|
||||
DBG("");
|
||||
test_check_get_all_reply(call, &test->cell, test->type);
|
||||
@@ -519,7 +547,7 @@ struct test_get_version_data {
|
||||
|
||||
static void test_get_version_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_version_data *test = data;
|
||||
struct test_get_version_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
dbus_int32_t version;
|
||||
|
||||
@@ -588,7 +616,7 @@ struct test_get_type_data {
|
||||
|
||||
static void test_get_type_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_type_data *test = data;
|
||||
struct test_get_type_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
@@ -656,7 +684,7 @@ struct test_get_registered_data {
|
||||
|
||||
static void test_get_registered_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_registered_data *test = data;
|
||||
struct test_get_registered_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
@@ -725,7 +753,7 @@ struct test_get_properties_data {
|
||||
|
||||
static void test_get_properties_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_properties_data *test = data;
|
||||
struct test_get_properties_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it, array;
|
||||
|
||||
@@ -799,9 +827,9 @@ struct test_registered_changed_data {
|
||||
const char *cell_path;
|
||||
};
|
||||
|
||||
static void test_registered_changed_reply(DBusPendingCall *call, void *data)
|
||||
static void test_registered_changed_reply2(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_registered_changed_data *test = data;
|
||||
struct test_registered_changed_data *test = data;
|
||||
|
||||
DBG("");
|
||||
test_check_get_all_reply(call, &test->cell, test->type);
|
||||
@@ -810,17 +838,14 @@ static void test_registered_changed_reply(DBusPendingCall *call, void *data)
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_registered_changed_start(struct test_dbus_context *context)
|
||||
static void test_registered_changed_reply1(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_registered_changed_data *test =
|
||||
G_CAST(context, struct test_registered_changed_data, context);
|
||||
struct test_registered_changed_data *test = data;
|
||||
struct sailfish_cell *first_cell;
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
test_check_get_cells_reply(call, test->cell_path, NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Trigger "RegisteredChanged" signal */
|
||||
first_cell = test->info->cells->data;
|
||||
@@ -828,8 +853,24 @@ static void test_registered_changed_start(struct test_dbus_context *context)
|
||||
first_cell->registered = !first_cell->registered;
|
||||
fake_cell_info_cells_changed(test->info);
|
||||
|
||||
test_submit_get_all_call(context->client_connection, test->cell_path,
|
||||
test_registered_changed_reply, test);
|
||||
test_submit_get_all_call(test->context.client_connection,
|
||||
test->cell_path, test_registered_changed_reply2, test);
|
||||
}
|
||||
|
||||
static void test_registered_changed_start(struct test_dbus_context *context)
|
||||
{
|
||||
struct test_registered_changed_data *test =
|
||||
G_CAST(context, struct test_registered_changed_data, context);
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
|
||||
/* Submit GetCells to enable "RegisteredChanged" signals */
|
||||
test_submit_cell_info_call(test->context.client_connection, "GetCells",
|
||||
test_registered_changed_reply1, test);
|
||||
}
|
||||
|
||||
static void test_registered_changed(void)
|
||||
@@ -871,28 +912,26 @@ struct test_property_changed_data {
|
||||
const char *cell_path;
|
||||
};
|
||||
|
||||
static void test_property_changed_reply1(DBusPendingCall *call, void *data)
|
||||
static void test_property_changed_reply2(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_property_changed_data *test = data;
|
||||
struct test_property_changed_data *test = data;
|
||||
|
||||
DBG("");
|
||||
test_check_get_all_reply(call, &test->cell, test->type);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
test_dbus_watch_disconnect_all();
|
||||
}
|
||||
|
||||
static void test_property_changed_start(struct test_dbus_context *context)
|
||||
static void test_property_changed_reply1(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_property_changed_data *test =
|
||||
G_CAST(context, struct test_property_changed_data, context);
|
||||
struct test_property_changed_data *test = data;
|
||||
struct sailfish_cell *first_cell;
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
test_check_get_cells_reply(call, test->cell_path, NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Trigger "PropertyChanged" signal */
|
||||
first_cell = test->info->cells->data;
|
||||
@@ -900,8 +939,24 @@ static void test_property_changed_start(struct test_dbus_context *context)
|
||||
(++(first_cell->info.gsm.signalStrength));
|
||||
fake_cell_info_cells_changed(test->info);
|
||||
|
||||
test_submit_get_all_call(context->client_connection, test->cell_path,
|
||||
test_property_changed_reply1, test);
|
||||
test_submit_get_all_call(test->context.client_connection,
|
||||
test->cell_path, test_property_changed_reply2, test);
|
||||
}
|
||||
|
||||
static void test_property_changed_start(struct test_dbus_context *context)
|
||||
{
|
||||
struct test_property_changed_data *test =
|
||||
G_CAST(context, struct test_property_changed_data, context);
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
|
||||
/* Submit GetCells to enable "PropertyChanged" signals */
|
||||
test_submit_cell_info_call(test->context.client_connection, "GetCells",
|
||||
test_property_changed_reply1, test);
|
||||
}
|
||||
|
||||
static void test_property_changed(void)
|
||||
@@ -931,6 +986,106 @@ static void test_property_changed(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== Unsubscribe ==== */
|
||||
|
||||
struct test_unsubscribe_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info *info;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
struct sailfish_cell cell;
|
||||
const char *type;
|
||||
const char *cell_path;
|
||||
};
|
||||
|
||||
static void test_unsubscribe_reply3(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_unsubscribe_data *test = data;
|
||||
|
||||
DBG("");
|
||||
test_check_error(call, OFONO_ERROR_INTERFACE ".Failed");
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
test_dbus_watch_disconnect_all();
|
||||
}
|
||||
|
||||
static void test_unsubscribe_reply2(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_unsubscribe_data *test = data;
|
||||
struct sailfish_cell *first_cell;
|
||||
|
||||
DBG("");
|
||||
test_check_empty_reply(call);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* No "PropertyChanged" signal is expected because it's disabled */
|
||||
first_cell = test->info->cells->data;
|
||||
test->cell.info.gsm.signalStrength =
|
||||
(++(first_cell->info.gsm.signalStrength));
|
||||
fake_cell_info_cells_changed(test->info);
|
||||
|
||||
/* Submit Unsubscribe and expect and error */
|
||||
test_submit_cell_info_call(test->context.client_connection,
|
||||
"Unsubscribe", test_unsubscribe_reply3, test);
|
||||
}
|
||||
|
||||
static void test_unsubscribe_reply1(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_unsubscribe_data *test = data;
|
||||
|
||||
DBG("");
|
||||
test_check_get_cells_reply(call, test->cell_path, NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Submit Unsubscribe to disable "PropertyChanged" signals */
|
||||
test_submit_cell_info_call(test->context.client_connection,
|
||||
"Unsubscribe", test_unsubscribe_reply2, test);
|
||||
}
|
||||
|
||||
static void test_unsubscribe_start(struct test_dbus_context *context)
|
||||
{
|
||||
struct test_unsubscribe_data *test =
|
||||
G_CAST(context, struct test_unsubscribe_data, context);
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
|
||||
/* Submit GetCells to enable "PropertyChanged" signals */
|
||||
test_submit_cell_info_call(test->context.client_connection, "GetCells",
|
||||
test_unsubscribe_reply1, test);
|
||||
}
|
||||
|
||||
static void test_unsubscribe(void)
|
||||
{
|
||||
struct test_unsubscribe_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_unsubscribe_start;
|
||||
test_cell_init_gsm1(&test.cell);
|
||||
test.type = "gsm";
|
||||
test.cell_path = "/test/cell_0";
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
/* We must have received "Unsubscribed" signal */
|
||||
g_assert(test_dbus_find_signal(&test.context, test.modem.path,
|
||||
CELL_INFO_DBUS_INTERFACE, CELL_INFO_DBUS_UNSUBSCRIBED_SIGNAL));
|
||||
|
||||
sailfish_cell_info_unref(test.info);
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_(name) "/sailfish_cell_info_dbus/" name
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -966,6 +1121,7 @@ int main(int argc, char *argv[])
|
||||
g_test_add_func(TEST_("GetProperties"), test_get_properties);
|
||||
g_test_add_func(TEST_("RegisteredChanged"), test_registered_changed);
|
||||
g_test_add_func(TEST_("PropertyChanged"), test_property_changed);
|
||||
g_test_add_func(TEST_("Unsubscribe"), test_unsubscribe);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
@@ -130,6 +130,9 @@ systemctl daemon-reload ||:
|
||||
%postun
|
||||
systemctl daemon-reload ||:
|
||||
|
||||
%transfiletriggerin -- %{_libdir}/ofono/plugins
|
||||
systemctl try-restart ofono.service ||:
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%license COPYING
|
||||
|
||||
Reference in New Issue
Block a user