mirror of
https://github.com/sailfishos/ofono
synced 2025-11-23 19:09:44 +08:00
Compare commits
15 Commits
mer/1.23+g
...
mer/1.23+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef5ee98508 | ||
|
|
4220e7d5e8 | ||
|
|
33c067a75f | ||
|
|
29616c04d0 | ||
|
|
beb997d914 | ||
|
|
cefc03e5ed | ||
|
|
85d99536ee | ||
|
|
ea36baa4c1 | ||
|
|
b95a089c00 | ||
|
|
c8dbf5494b | ||
|
|
cfb75f473d | ||
|
|
3d147843c4 | ||
|
|
c01dc63cbc | ||
|
|
297926ed24 | ||
|
|
6ef1174ea8 |
1
ofono/.gitignore
vendored
1
ofono/.gitignore
vendored
@@ -45,6 +45,7 @@ unit/test-caif
|
|||||||
unit/test-stkutil
|
unit/test-stkutil
|
||||||
unit/test-cdmasms
|
unit/test-cdmasms
|
||||||
unit/test-dbus-access
|
unit/test-dbus-access
|
||||||
|
unit/test-dbus-clients
|
||||||
unit/test-dbus-queue
|
unit/test-dbus-queue
|
||||||
unit/test-gprs-filter
|
unit/test-gprs-filter
|
||||||
unit/test-ril_config
|
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/sms-filter.h include/gprs-filter.h \
|
||||||
include/voicecall-filter.h include/dbus-access.h \
|
include/voicecall-filter.h include/dbus-access.h \
|
||||||
include/ril-constants.h include/ril-transport.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/netmon.h include/lte.h include/ims.h \
|
||||||
include/storage.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/handsfree-audio.c src/bluetooth.h \
|
||||||
src/sim-mnclength.c src/voicecallagent.c \
|
src/sim-mnclength.c src/voicecallagent.c \
|
||||||
src/sms-filter.c src/gprs-filter.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/voicecall-filter.c src/ril-transport.c \
|
||||||
src/hfp.h src/siri.c src/watchlist.c \
|
src/hfp.h src/siri.c src/watchlist.c \
|
||||||
src/netmon.c src/lte.c src/ims.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 \
|
unit/fake_sailfish_cell_info.c \
|
||||||
plugins/sailfish_manager/sailfish_cell_info.c \
|
plugins/sailfish_manager/sailfish_cell_info.c \
|
||||||
plugins/sailfish_manager/sailfish_cell_info_dbus.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
|
src/dbus.c src/log.c
|
||||||
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||||
@DBUS_GLIB_CFLAGS@
|
@DBUS_GLIB_CFLAGS@
|
||||||
@@ -1164,6 +1165,14 @@ unit_test_caif_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
|
|||||||
unit_test_caif_LDADD = @GLIB_LIBS@
|
unit_test_caif_LDADD = @GLIB_LIBS@
|
||||||
unit_objects += $(unit_test_caif_OBJECTS)
|
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 \
|
unit_test_dbus_queue_SOURCES = unit/test-dbus-queue.c unit/test-dbus.c \
|
||||||
src/dbus-queue.c gdbus/object.c \
|
src/dbus-queue.c gdbus/object.c \
|
||||||
src/dbus.c src/log.c
|
src/dbus.c src/log.c
|
||||||
|
|||||||
@@ -278,6 +278,13 @@ Properties boolean Active [readwrite]
|
|||||||
via this proxy. All other values are left
|
via this proxy. All other values are left
|
||||||
out in this case.
|
out in this case.
|
||||||
|
|
||||||
|
array{string} ProxyCSCF [readonly, optional]
|
||||||
|
|
||||||
|
Holds the list of P-CSCF (SIP proxy) for this
|
||||||
|
context. Only used by IMS connections.
|
||||||
|
|
||||||
|
This is a Sailfish OS specific extension.
|
||||||
|
|
||||||
dict IPv6.Settings [readonly, optional]
|
dict IPv6.Settings [readonly, optional]
|
||||||
|
|
||||||
Holds all the IPv6 network settings
|
Holds all the IPv6 network settings
|
||||||
@@ -304,6 +311,13 @@ Properties boolean Active [readwrite]
|
|||||||
|
|
||||||
Holds the gateway IP for this connection.
|
Holds the gateway IP for this connection.
|
||||||
|
|
||||||
|
array{string} ProxyCSCF [readonly, optional]
|
||||||
|
|
||||||
|
Holds the list of P-CSCF (SIP proxy) for this
|
||||||
|
context. Only used by IMS connections.
|
||||||
|
|
||||||
|
This is a Sailfish OS specific extension.
|
||||||
|
|
||||||
string MessageProxy [readwrite, MMS only]
|
string MessageProxy [readwrite, MMS only]
|
||||||
|
|
||||||
Holds the MMS Proxy setting.
|
Holds the MMS Proxy setting.
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ struct ril_cell_info {
|
|||||||
gulong event_id;
|
gulong event_id;
|
||||||
guint query_id;
|
guint query_id;
|
||||||
guint set_rate_id;
|
guint set_rate_id;
|
||||||
|
gboolean enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ril_cell_info_signal {
|
enum ril_cell_info_signal {
|
||||||
@@ -331,7 +332,8 @@ static void ril_cell_info_list_cb(GRilIoChannel *io, int status,
|
|||||||
DBG_(self, "");
|
DBG_(self, "");
|
||||||
GASSERT(self->query_id);
|
GASSERT(self->query_id);
|
||||||
self->query_id = 0;
|
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);
|
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,
|
static gboolean ril_cell_info_retry(GRilIoRequest* request, int ril_status,
|
||||||
const void* response_data, guint response_len, void* user_data)
|
const void* response_data, guint response_len, void* user_data)
|
||||||
{
|
{
|
||||||
|
struct ril_cell_info *self = RIL_CELL_INFO(user_data);
|
||||||
|
|
||||||
switch (ril_status) {
|
switch (ril_status) {
|
||||||
case RIL_E_SUCCESS:
|
case RIL_E_SUCCESS:
|
||||||
case RIL_E_RADIO_NOT_AVAILABLE:
|
case RIL_E_RADIO_NOT_AVAILABLE:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
default:
|
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)
|
static void ril_cell_info_set_rate(struct ril_cell_info *self)
|
||||||
{
|
{
|
||||||
GRilIoRequest *req = grilio_request_array_int32_new(1,
|
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(req, RIL_RETRY_MS, MAX_RETRIES);
|
||||||
grilio_request_set_retry_func(req, ril_cell_info_retry);
|
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)
|
static void ril_cell_info_refresh(struct ril_cell_info *self)
|
||||||
{
|
{
|
||||||
/* RIL_REQUEST_GET_CELL_INFO_LIST fails without SIM card */
|
/* 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);
|
ril_cell_info_query(self);
|
||||||
} else {
|
} else {
|
||||||
ril_cell_info_update_cells(self, NULL);
|
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) {
|
if (self->update_rate_ms != ms) {
|
||||||
self->update_rate_ms = ms;
|
self->update_rate_ms = ms;
|
||||||
DBG_(self, "%d 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) {
|
if (self->sim_card_ready) {
|
||||||
ril_cell_info_set_rate(self);
|
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_unref_proc,
|
||||||
ril_cell_info_add_cells_changed_handler_proc,
|
ril_cell_info_add_cells_changed_handler_proc,
|
||||||
ril_cell_info_remove_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);
|
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);
|
ril_cell_info_sim_status_cb, self);
|
||||||
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
||||||
ril_cell_info_refresh(self);
|
ril_cell_info_refresh(self);
|
||||||
|
|
||||||
|
/* Disable updates by default */
|
||||||
|
self->enabled = FALSE;
|
||||||
if (self->sim_card_ready) {
|
if (self->sim_card_ready) {
|
||||||
ril_cell_info_set_rate(self);
|
ril_cell_info_set_rate(self);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* oFono - Open Source Telephony - RIL-based devices
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2019 Jolla Ltd.
|
* Copyright (C) 2015-2021 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define CTX_ID_NONE ((unsigned int)(-1))
|
#define CTX_ID_NONE ((unsigned int)(-1))
|
||||||
|
|
||||||
#define MAX_MTU 1280
|
#define MAX_MMS_MTU 1280
|
||||||
|
|
||||||
struct ril_gprs_context_call {
|
struct ril_gprs_context_call {
|
||||||
struct ril_data_request *req;
|
struct ril_data_request *req;
|
||||||
@@ -108,8 +108,15 @@ static void ril_gprs_context_set_active_call(struct ril_gprs_context *gcd,
|
|||||||
if (call) {
|
if (call) {
|
||||||
ril_data_call_free(gcd->active_call);
|
ril_data_call_free(gcd->active_call);
|
||||||
gcd->active_call = ril_data_call_dup(call);
|
gcd->active_call = ril_data_call_dup(call);
|
||||||
if (!gcd->mtu_watch) {
|
if (ofono_gprs_context_get_type(gcd->gc) ==
|
||||||
gcd->mtu_watch = mtu_watch_new(MAX_MTU);
|
OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||||
|
/*
|
||||||
|
* Some MMS providers have a problem with MTU
|
||||||
|
* greater than 1280. Let's be safe.
|
||||||
|
*/
|
||||||
|
if (!gcd->mtu_watch) {
|
||||||
|
gcd->mtu_watch = mtu_watch_new(MAX_MMS_MTU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mtu_watch_set_ifname(gcd->mtu_watch, call->ifname);
|
mtu_watch_set_ifname(gcd->mtu_watch, call->ifname);
|
||||||
ril_data_call_grab(gcd->data, call->cid, gcd);
|
ril_data_call_grab(gcd->data, call->cid, gcd);
|
||||||
@@ -247,34 +254,59 @@ static void ril_gprs_context_set_gateway(struct ofono_gprs_context *gc,
|
|||||||
ofono_gprs_context_set_ipv6_gateway(gc, ipv6_gw);
|
ofono_gprs_context_set_ipv6_gateway(gc, ipv6_gw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ril_gprs_context_set_dns_servers(struct ofono_gprs_context *gc,
|
typedef void (*ofono_gprs_context_list_setter_t)(struct ofono_gprs_context *gc,
|
||||||
const struct ril_data_call *call)
|
const char **list);
|
||||||
|
|
||||||
|
static void ril_gprs_context_set_servers(struct ofono_gprs_context *gc,
|
||||||
|
char * const *list, ofono_gprs_context_list_setter_t set_ipv4,
|
||||||
|
ofono_gprs_context_list_setter_t set_ipv6)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char * const *list = call->dnses;
|
const char **ip_list = NULL, **ip_ptr = NULL;
|
||||||
|
const char **ipv6_list = NULL, **ipv6_ptr = NULL;
|
||||||
const int n = gutil_strv_length(list);
|
const int n = gutil_strv_length(list);
|
||||||
const char **ip_dns = g_new0(const char *, n+1);
|
|
||||||
const char **ipv6_dns = g_new0(const char *, n+1);
|
|
||||||
const char **ip_ptr = ip_dns;
|
|
||||||
const char **ipv6_ptr = ipv6_dns;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
const char *addr = list[i];
|
const char *addr = list[i];
|
||||||
switch (ril_gprs_context_address_family(addr)) {
|
switch (ril_gprs_context_address_family(addr)) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
if (!ip_ptr) {
|
||||||
|
ip_list = g_new0(const char *, n - i + 1);
|
||||||
|
ip_ptr = ip_list;
|
||||||
|
}
|
||||||
*ip_ptr++ = addr;
|
*ip_ptr++ = addr;
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
if (!ipv6_ptr) {
|
||||||
|
ipv6_list = g_new0(const char *, n - i + 1);
|
||||||
|
ipv6_ptr = ipv6_list;
|
||||||
|
}
|
||||||
*ipv6_ptr++ = addr;
|
*ipv6_ptr++ = addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ofono_gprs_context_set_ipv4_dns_servers(gc, ip_dns);
|
set_ipv4(gc, ip_list);
|
||||||
ofono_gprs_context_set_ipv6_dns_servers(gc, ipv6_dns);
|
set_ipv6(gc, ipv6_list);
|
||||||
|
|
||||||
g_free(ip_dns);
|
g_free(ip_list);
|
||||||
g_free(ipv6_dns);
|
g_free(ipv6_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_gprs_context_set_dns_servers(struct ofono_gprs_context *gc,
|
||||||
|
const struct ril_data_call *call)
|
||||||
|
{
|
||||||
|
ril_gprs_context_set_servers(gc, call->dnses,
|
||||||
|
ofono_gprs_context_set_ipv4_dns_servers,
|
||||||
|
ofono_gprs_context_set_ipv6_dns_servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ril_gprs_context_set_proxy_cscf(struct ofono_gprs_context *gc,
|
||||||
|
const struct ril_data_call *call)
|
||||||
|
{
|
||||||
|
ril_gprs_context_set_servers(gc, call->pcscf,
|
||||||
|
ofono_gprs_context_set_ipv4_proxy_cscf,
|
||||||
|
ofono_gprs_context_set_ipv6_proxy_cscf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only compares the stuff that's important to us */
|
/* Only compares the stuff that's important to us */
|
||||||
@@ -282,7 +314,8 @@ static void ril_gprs_context_set_dns_servers(struct ofono_gprs_context *gc,
|
|||||||
#define DATA_CALL_ADDRESS_CHANGED (0x02)
|
#define DATA_CALL_ADDRESS_CHANGED (0x02)
|
||||||
#define DATA_CALL_GATEWAY_CHANGED (0x04)
|
#define DATA_CALL_GATEWAY_CHANGED (0x04)
|
||||||
#define DATA_CALL_DNS_CHANGED (0x08)
|
#define DATA_CALL_DNS_CHANGED (0x08)
|
||||||
#define DATA_CALL_ALL_CHANGED (0x0f)
|
#define DATA_CALL_PCSCF_CHANGED (0x10)
|
||||||
|
#define DATA_CALL_ALL_CHANGED (0x1f)
|
||||||
static int ril_gprs_context_data_call_change(
|
static int ril_gprs_context_data_call_change(
|
||||||
const struct ril_data_call *c1,
|
const struct ril_data_call *c1,
|
||||||
const struct ril_data_call *c2)
|
const struct ril_data_call *c2)
|
||||||
@@ -308,6 +341,10 @@ static int ril_gprs_context_data_call_change(
|
|||||||
changes |= DATA_CALL_DNS_CHANGED;
|
changes |= DATA_CALL_DNS_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gutil_strv_equal(c1->pcscf, c2->pcscf)) {
|
||||||
|
changes |= DATA_CALL_PCSCF_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
} else {
|
} else {
|
||||||
return DATA_CALL_ALL_CHANGED;
|
return DATA_CALL_ALL_CHANGED;
|
||||||
@@ -380,6 +417,11 @@ static void ril_gprs_context_call_list_changed(struct ril_data *data, void *arg)
|
|||||||
ril_gprs_context_set_dns_servers(gc, call);
|
ril_gprs_context_set_dns_servers(gc, call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (change & DATA_CALL_PCSCF_CHANGED) {
|
||||||
|
DBG("P-CSCF changed");
|
||||||
|
ril_gprs_context_set_proxy_cscf(gc, call);
|
||||||
|
}
|
||||||
|
|
||||||
ofono_gprs_context_signal_change(gc, gcd->active_ctx_cid);
|
ofono_gprs_context_signal_change(gc, gcd->active_ctx_cid);
|
||||||
ril_data_call_free(prev_call);
|
ril_data_call_free(prev_call);
|
||||||
}
|
}
|
||||||
@@ -421,6 +463,7 @@ static void ril_gprs_context_activate_primary_cb(struct ril_data *data,
|
|||||||
ril_gprs_context_set_address(gc, call);
|
ril_gprs_context_set_address(gc, call);
|
||||||
ril_gprs_context_set_gateway(gc, call);
|
ril_gprs_context_set_gateway(gc, call);
|
||||||
ril_gprs_context_set_dns_servers(gc, call);
|
ril_gprs_context_set_dns_servers(gc, call);
|
||||||
|
ril_gprs_context_set_proxy_cscf(gc, call);
|
||||||
ril_error_init_ok(&error);
|
ril_error_init_ok(&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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
|
* oFono - Open Telephony stack for Linux
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* 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
|
* 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
|
* 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
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* 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
|
#ifndef __OFONO_DBUS_H
|
||||||
@@ -83,6 +79,8 @@ extern "C" {
|
|||||||
DBUS_TYPE_VARIANT_AS_STRING \
|
DBUS_TYPE_VARIANT_AS_STRING \
|
||||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
|
||||||
|
|
||||||
|
#define OFONO_ERROR_INTERFACE "org.ofono.Error"
|
||||||
|
|
||||||
DBusConnection *ofono_dbus_get_connection(void);
|
DBusConnection *ofono_dbus_get_connection(void);
|
||||||
|
|
||||||
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
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 char *name, int type,
|
||||||
const void *value);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
|
* Copyright (C) 2015-2021 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -128,6 +129,8 @@ void ofono_gprs_context_set_ipv4_gateway(struct ofono_gprs_context *gc,
|
|||||||
const char *gateway);
|
const char *gateway);
|
||||||
void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
|
||||||
const char **dns);
|
const char **dns);
|
||||||
|
void ofono_gprs_context_set_ipv4_proxy_cscf(struct ofono_gprs_context *gc,
|
||||||
|
const char **pcscf); /* Since mer/1.23+git30 */
|
||||||
|
|
||||||
void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
|
||||||
const char *address);
|
const char *address);
|
||||||
@@ -137,6 +140,8 @@ void ofono_gprs_context_set_ipv6_gateway(struct ofono_gprs_context *gc,
|
|||||||
const char *gateway);
|
const char *gateway);
|
||||||
void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
||||||
const char **dns);
|
const char **dns);
|
||||||
|
void ofono_gprs_context_set_ipv6_proxy_cscf(struct ofono_gprs_context *gc,
|
||||||
|
const char **pcscf); /* Since mer/1.23+git30 */
|
||||||
|
|
||||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||||
unsigned int cid);
|
unsigned int cid);
|
||||||
|
|||||||
@@ -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:
|
* Local Variables:
|
||||||
* mode: C
|
* mode: C
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ struct sailfish_cell_info_proc {
|
|||||||
sailfish_cell_info_cb_t cb, void *arg);
|
sailfish_cell_info_cb_t cb, void *arg);
|
||||||
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
|
void (*remove_handler)(struct sailfish_cell_info *info, gulong id);
|
||||||
void (*set_update_interval)(struct sailfish_cell_info *info, int ms);
|
void (*set_update_interval)(struct sailfish_cell_info *info, int ms);
|
||||||
|
void (*set_enabled)(struct sailfish_cell_info *info, gboolean enabled);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
@@ -107,6 +108,8 @@ void sailfish_cell_info_remove_handler(struct sailfish_cell_info *info,
|
|||||||
gulong id);
|
gulong id);
|
||||||
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
|
void sailfish_cell_info_set_update_interval(struct sailfish_cell_info *info,
|
||||||
int ms);
|
int ms);
|
||||||
|
void sailfish_cell_info_set_enabled(struct sailfish_cell_info *info,
|
||||||
|
gboolean enabled);
|
||||||
|
|
||||||
#endif /* SAILFISH_CELINFO_H */
|
#endif /* SAILFISH_CELINFO_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony - RIL-based devices
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <ofono/modem.h>
|
#include <ofono/modem.h>
|
||||||
#include <ofono/dbus.h>
|
#include <ofono/dbus.h>
|
||||||
|
#include <ofono/dbus-clients.h>
|
||||||
#include <ofono/log.h>
|
#include <ofono/log.h>
|
||||||
|
|
||||||
#include <gdbus.h>
|
#include <gdbus.h>
|
||||||
@@ -35,11 +36,13 @@ struct sailfish_cell_info_dbus {
|
|||||||
gulong handler_id;
|
gulong handler_id;
|
||||||
guint next_cell_id;
|
guint next_cell_id;
|
||||||
GSList *entries;
|
GSList *entries;
|
||||||
|
struct ofono_dbus_clients *clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CELL_INFO_DBUS_INTERFACE "org.nemomobile.ofono.CellInfo"
|
#define CELL_INFO_DBUS_INTERFACE "org.nemomobile.ofono.CellInfo"
|
||||||
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
||||||
#define CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL "CellsRemoved"
|
#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_VERSION (1)
|
||||||
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
#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,
|
(struct sailfish_cell_info_dbus *dbus, const char *name,
|
||||||
GPtrArray *list)
|
GPtrArray *list)
|
||||||
{
|
{
|
||||||
guint i;
|
if (ofono_dbus_clients_count(dbus->clients)) {
|
||||||
DBusMessageIter it, array;
|
guint i;
|
||||||
DBusMessage *signal = dbus_message_new_signal(dbus->path,
|
DBusMessageIter it, a;
|
||||||
|
DBusMessage *signal = dbus_message_new_signal(dbus->path,
|
||||||
CELL_INFO_DBUS_INTERFACE, name);
|
CELL_INFO_DBUS_INTERFACE, name);
|
||||||
|
|
||||||
dbus_message_iter_init_append(signal, &it);
|
dbus_message_iter_init_append(signal, &it);
|
||||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &array);
|
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &a);
|
||||||
for (i = 0; i < list->len; i++) {
|
for (i = 0; i < list->len; i++) {
|
||||||
const char* path = list->pdata[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);
|
|
||||||
|
|
||||||
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,
|
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
|
static void sailfish_cell_info_dbus_property_changed
|
||||||
(struct sailfish_cell_info_dbus *dbus,
|
(struct sailfish_cell_info_dbus *dbus,
|
||||||
const struct sailfish_cell_entry *entry, int mask)
|
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) {
|
if (mask & SAILFISH_CELL_PROPERTY_REGISTERED) {
|
||||||
const dbus_bool_t registered = (cell->registered != FALSE);
|
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_INTERFACE,
|
||||||
CELL_DBUS_REGISTERED_CHANGED_SIGNAL,
|
CELL_DBUS_REGISTERED_CHANGED_SIGNAL,
|
||||||
DBUS_TYPE_BOOLEAN, ®istered, DBUS_TYPE_INVALID);
|
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++) {
|
for (i = 0; i < n && mask; i++) {
|
||||||
if (mask & prop[i].flag) {
|
if (mask & prop[i].flag) {
|
||||||
ofono_dbus_signal_property_changed(dbus->conn,
|
ofono_dbus_clients_signal_property_changed(
|
||||||
entry->path, CELL_DBUS_INTERFACE,
|
dbus->clients, entry->path,
|
||||||
prop[i].name, DBUS_TYPE_INT32,
|
CELL_DBUS_INTERFACE, prop[i].name,
|
||||||
|
DBUS_TYPE_INT32,
|
||||||
G_STRUCT_MEMBER_P(&cell->info, prop[i].off));
|
G_STRUCT_MEMBER_P(&cell->info, prop[i].off));
|
||||||
mask &= ~prop[i].flag;
|
mask &= ~prop[i].flag;
|
||||||
}
|
}
|
||||||
@@ -411,7 +436,7 @@ static void sailfish_cell_info_dbus_update_entries
|
|||||||
sailfish_cell_compare_func)) {
|
sailfish_cell_compare_func)) {
|
||||||
DBG("%s removed", entry->path);
|
DBG("%s removed", entry->path);
|
||||||
dbus->entries = g_slist_delete_link(dbus->entries, l);
|
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_INTERFACE,
|
||||||
CELL_DBUS_REMOVED_SIGNAL,
|
CELL_DBUS_REMOVED_SIGNAL,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
@@ -492,29 +517,67 @@ static void sailfish_cell_info_dbus_cells_changed_cb
|
|||||||
((struct sailfish_cell_info_dbus *)arg, TRUE);
|
((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,
|
static DBusMessage *sailfish_cell_info_dbus_get_cells(DBusConnection *conn,
|
||||||
DBusMessage *msg, void *data)
|
DBusMessage *msg, void *data)
|
||||||
{
|
{
|
||||||
struct sailfish_cell_info_dbus *dbus = data;
|
struct sailfish_cell_info_dbus *dbus = data;
|
||||||
DBusMessage *reply = dbus_message_new_method_return(msg);
|
const char *sender = dbus_message_get_sender(msg);
|
||||||
DBusMessageIter it, array;
|
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
dbus_message_iter_init_append(reply, &it);
|
if (ofono_dbus_clients_add(dbus->clients, sender)) {
|
||||||
dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "o", &array);
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
||||||
for (l = dbus->entries; l; l = l->next) {
|
DBusMessageIter it, a;
|
||||||
const struct sailfish_cell_entry *entry = l->data;
|
GSList *l;
|
||||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
|
|
||||||
&entry->path);
|
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 sailfish_cell_info_dbus_error_failed(msg, "Operation failed");
|
||||||
return reply;
|
}
|
||||||
|
|
||||||
|
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[] = {
|
static const GDBusMethodTable sailfish_cell_info_dbus_methods[] = {
|
||||||
{ GDBUS_METHOD("GetCells", NULL,
|
{ GDBUS_METHOD("GetCells", NULL,
|
||||||
GDBUS_ARGS({ "paths", "ao" }),
|
GDBUS_ARGS({ "paths", "ao" }),
|
||||||
sailfish_cell_info_dbus_get_cells) },
|
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_ARGS({ "paths", "ao" })) },
|
||||||
{ GDBUS_SIGNAL(CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL,
|
{ GDBUS_SIGNAL(CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL,
|
||||||
GDBUS_ARGS({ "paths", "ao" })) },
|
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 sailfish_cell_info_dbus *sailfish_cell_info_dbus_new
|
||||||
(struct ofono_modem *modem, struct sailfish_cell_info *info)
|
(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,
|
ofono_modem_add_interface(modem,
|
||||||
CELL_INFO_DBUS_INTERFACE);
|
CELL_INFO_DBUS_INTERFACE);
|
||||||
sailfish_cell_info_dbus_update_entries(dbus, FALSE);
|
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;
|
return dbus;
|
||||||
} else {
|
} else {
|
||||||
ofono_error("CellInfo D-Bus register failed");
|
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;
|
GSList *l;
|
||||||
|
|
||||||
DBG("%s", dbus->path);
|
DBG("%s", dbus->path);
|
||||||
|
ofono_dbus_clients_free(dbus->clients);
|
||||||
g_dbus_unregister_interface(dbus->conn, dbus->path,
|
g_dbus_unregister_interface(dbus->conn, dbus->path,
|
||||||
CELL_INFO_DBUS_INTERFACE);
|
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
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* 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
|
* 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
|
* 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
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* 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
|
#ifdef HAVE_CONFIG_H
|
||||||
@@ -29,8 +26,6 @@
|
|||||||
|
|
||||||
#include "ofono.h"
|
#include "ofono.h"
|
||||||
|
|
||||||
#define OFONO_ERROR_INTERFACE "org.ofono.Error"
|
|
||||||
|
|
||||||
static DBusConnection *g_connection;
|
static DBusConnection *g_connection;
|
||||||
|
|
||||||
struct error_mapping_entry {
|
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);
|
dbus_message_iter_close_container(dict, &entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
/* Since mer/1.23+git31 */
|
||||||
const char *path,
|
DBusMessage *ofono_dbus_signal_new_property_changed(const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *name,
|
const char *name,
|
||||||
int type, const void *value)
|
int type, const void *value)
|
||||||
@@ -219,11 +214,8 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
|||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
|
|
||||||
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
|
signal = dbus_message_new_signal(path, interface, "PropertyChanged");
|
||||||
if (signal == NULL) {
|
if (signal == NULL)
|
||||||
ofono_error("Unable to allocate new %s.PropertyChanged signal",
|
return NULL;
|
||||||
interface);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_message_iter_init_append(signal, &iter);
|
dbus_message_iter_init_append(signal, &iter);
|
||||||
|
|
||||||
@@ -231,6 +223,24 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
|||||||
|
|
||||||
append_variant(&iter, type, value);
|
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);
|
return g_dbus_send_message(conn, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* oFono - Open Source Telephony
|
* oFono - Open Source Telephony
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||||
* Copyright (C) 2015-2020 Jolla Ltd.
|
* Copyright (C) 2015-2021 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -97,6 +97,7 @@ struct ipv4_settings {
|
|||||||
char *netmask;
|
char *netmask;
|
||||||
char *gateway;
|
char *gateway;
|
||||||
char **dns;
|
char **dns;
|
||||||
|
char **pcscf;
|
||||||
char *proxy;
|
char *proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,6 +106,7 @@ struct ipv6_settings {
|
|||||||
unsigned char prefix_len;
|
unsigned char prefix_len;
|
||||||
char *gateway;
|
char *gateway;
|
||||||
char **dns;
|
char **dns;
|
||||||
|
char **pcscf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct context_settings {
|
struct context_settings {
|
||||||
@@ -410,6 +412,7 @@ static void context_settings_free(struct context_settings *settings)
|
|||||||
g_free(settings->ipv4->netmask);
|
g_free(settings->ipv4->netmask);
|
||||||
g_free(settings->ipv4->gateway);
|
g_free(settings->ipv4->gateway);
|
||||||
g_strfreev(settings->ipv4->dns);
|
g_strfreev(settings->ipv4->dns);
|
||||||
|
g_strfreev(settings->ipv4->pcscf);
|
||||||
g_free(settings->ipv4->proxy);
|
g_free(settings->ipv4->proxy);
|
||||||
|
|
||||||
g_free(settings->ipv4);
|
g_free(settings->ipv4);
|
||||||
@@ -420,6 +423,7 @@ static void context_settings_free(struct context_settings *settings)
|
|||||||
g_free(settings->ipv6->ip);
|
g_free(settings->ipv6->ip);
|
||||||
g_free(settings->ipv6->gateway);
|
g_free(settings->ipv6->gateway);
|
||||||
g_strfreev(settings->ipv6->dns);
|
g_strfreev(settings->ipv6->dns);
|
||||||
|
g_strfreev(settings->ipv6->pcscf);
|
||||||
|
|
||||||
g_free(settings->ipv6);
|
g_free(settings->ipv6);
|
||||||
settings->ipv6 = NULL;
|
settings->ipv6 = NULL;
|
||||||
@@ -484,6 +488,11 @@ static void context_settings_append_ipv4(struct context_settings *settings,
|
|||||||
DBUS_TYPE_STRING,
|
DBUS_TYPE_STRING,
|
||||||
&settings->ipv4->dns);
|
&settings->ipv4->dns);
|
||||||
|
|
||||||
|
if (settings->ipv4->pcscf)
|
||||||
|
ofono_dbus_dict_append_array(&array, "ProxyCSCF",
|
||||||
|
DBUS_TYPE_STRING,
|
||||||
|
&settings->ipv4->pcscf);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dbus_message_iter_close_container(&variant, &array);
|
dbus_message_iter_close_container(&variant, &array);
|
||||||
|
|
||||||
@@ -549,6 +558,11 @@ static void context_settings_append_ipv6(struct context_settings *settings,
|
|||||||
DBUS_TYPE_STRING,
|
DBUS_TYPE_STRING,
|
||||||
&settings->ipv6->dns);
|
&settings->ipv6->dns);
|
||||||
|
|
||||||
|
if (settings->ipv6->pcscf)
|
||||||
|
ofono_dbus_dict_append_array(&array, "ProxyCSCF",
|
||||||
|
DBUS_TYPE_STRING,
|
||||||
|
&settings->ipv6->pcscf);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dbus_message_iter_close_container(&variant, &array);
|
dbus_message_iter_close_container(&variant, &array);
|
||||||
|
|
||||||
@@ -3417,6 +3431,18 @@ void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
|
|||||||
settings->ipv4->dns = g_strdupv((char **) dns);
|
settings->ipv4->dns = g_strdupv((char **) dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ofono_gprs_context_set_ipv4_proxy_cscf(struct ofono_gprs_context *gc,
|
||||||
|
const char **pcscf)
|
||||||
|
{
|
||||||
|
struct context_settings *settings = gc->settings;
|
||||||
|
|
||||||
|
if (settings->ipv4 == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_strfreev(settings->ipv4->pcscf);
|
||||||
|
settings->ipv4->pcscf = g_strdupv((char **) pcscf);
|
||||||
|
}
|
||||||
|
|
||||||
void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
|
||||||
const char *address)
|
const char *address)
|
||||||
{
|
{
|
||||||
@@ -3464,6 +3490,18 @@ void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
|||||||
settings->ipv6->dns = g_strdupv((char **) dns);
|
settings->ipv6->dns = g_strdupv((char **) dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ofono_gprs_context_set_ipv6_proxy_cscf(struct ofono_gprs_context *gc,
|
||||||
|
const char **pcscf)
|
||||||
|
{
|
||||||
|
struct context_settings *settings = gc->settings;
|
||||||
|
|
||||||
|
if (settings->ipv6 == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_strfreev(settings->ipv6->pcscf);
|
||||||
|
settings->ipv6->pcscf = g_strdupv((char **) pcscf);
|
||||||
|
}
|
||||||
|
|
||||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||||
unsigned int cid)
|
unsigned int cid)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3823,7 +3823,7 @@ struct ofono_sim_aid_session *__ofono_sim_get_session_by_aid(
|
|||||||
struct ofono_sim_aid_session *session = iter->data;
|
struct ofono_sim_aid_session *session = iter->data;
|
||||||
|
|
||||||
if (session->record->aid.len == aid->len &&
|
if (session->record->aid.len == aid->len &&
|
||||||
!memcmp(session->record->aid.aid, aid, aid->len))
|
!memcmp(session->record->aid.aid, aid->aid, aid->len))
|
||||||
return session;
|
return session;
|
||||||
|
|
||||||
iter = g_slist_next(iter);
|
iter = g_slist_next(iter);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ TESTS="\
|
|||||||
test-caif \
|
test-caif \
|
||||||
test-dbus-queue \
|
test-dbus-queue \
|
||||||
test-dbus-access \
|
test-dbus-access \
|
||||||
|
test-dbus-clients \
|
||||||
test-gprs-filter \
|
test-gprs-filter \
|
||||||
test-provision \
|
test-provision \
|
||||||
test-config \
|
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
|
* 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
|
* 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
|
* 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);
|
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)
|
gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
|
||||||
{
|
{
|
||||||
struct test_dbus_watch *prev = NULL;
|
struct test_dbus_watch *prev = NULL;
|
||||||
@@ -303,6 +310,9 @@ static DBusHandlerResult test_dbus_client_message_cb(DBusConnection *conn,
|
|||||||
dbus_message_get_path(msg));
|
dbus_message_get_path(msg));
|
||||||
test->client_signals = g_slist_append(test->client_signals,
|
test->client_signals = g_slist_append(test->client_signals,
|
||||||
dbus_message_ref(msg));
|
dbus_message_ref(msg));
|
||||||
|
if (test->handle_signal) {
|
||||||
|
test->handle_signal(test, msg);
|
||||||
|
}
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
} else {
|
} else {
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@@ -25,6 +25,7 @@ struct test_dbus_context {
|
|||||||
DBusConnection *client_connection;
|
DBusConnection *client_connection;
|
||||||
GSList* client_signals;
|
GSList* client_signals;
|
||||||
void (*start)(struct test_dbus_context *test);
|
void (*start)(struct test_dbus_context *test);
|
||||||
|
void (*handle_signal)(struct test_dbus_context *test, DBusMessage *msg);
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* oFono - Open Source Telephony
|
* 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
|
* 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
|
* 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_INTERFACE "org.nemomobile.ofono.CellInfo"
|
||||||
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
#define CELL_INFO_DBUS_CELLS_ADDED_SIGNAL "CellsAdded"
|
||||||
#define CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL "CellsRemoved"
|
#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_VERSION (1)
|
||||||
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
||||||
@@ -66,7 +67,7 @@ static gboolean test_timeout(gpointer param)
|
|||||||
|
|
||||||
static guint test_setup_timeout(void)
|
static guint test_setup_timeout(void)
|
||||||
{
|
{
|
||||||
if (!test_debug) {
|
if (test_debug) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return g_timeout_add_seconds(TEST_TIMEOUT, test_timeout, NULL);
|
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;
|
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,
|
static void test_submit_get_all_call(DBusConnection* connection,
|
||||||
const char *cell_path, DBusPendingCallNotifyFunction notify,
|
const char *cell_path, DBusPendingCallNotifyFunction notify,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -186,6 +200,26 @@ static void test_check_get_all_reply(DBusPendingCall *call,
|
|||||||
dbus_message_unref(reply);
|
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)
|
static struct sailfish_cell *test_cell_init_gsm1(struct sailfish_cell *cell)
|
||||||
{
|
{
|
||||||
struct sailfish_cell_info_gsm *gsm = &cell->info.gsm;
|
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,
|
static void test_get_cells_call(struct test_get_cells_data *test,
|
||||||
DBusPendingCallNotifyFunction notify)
|
DBusPendingCallNotifyFunction notify)
|
||||||
{
|
{
|
||||||
DBusPendingCall *call;
|
test_submit_cell_info_call(test->context.client_connection, "GetCells",
|
||||||
DBusConnection *connection = test->context.client_connection;
|
notify, test);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_get_cells_start_reply3(DBusPendingCall *call, void *data)
|
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;
|
DBusMessageIter it;
|
||||||
DBusMessage *signal = test_dbus_take_signal(&test->context,
|
DBusMessage *signal = test_dbus_take_signal(&test->context,
|
||||||
test->modem.path, CELL_INFO_DBUS_INTERFACE,
|
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)
|
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";
|
const char *cell_added = "/test/cell_1";
|
||||||
struct sailfish_cell cell;
|
struct sailfish_cell cell;
|
||||||
DBusMessageIter it;
|
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)
|
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;
|
struct sailfish_cell cell;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
@@ -432,7 +460,7 @@ struct test_get_all_data {
|
|||||||
|
|
||||||
static void test_get_all_reply(DBusPendingCall *call, void *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("");
|
DBG("");
|
||||||
test_check_get_all_reply(call, &test->cell, test->type);
|
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)
|
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);
|
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||||
dbus_int32_t version;
|
dbus_int32_t version;
|
||||||
|
|
||||||
@@ -588,7 +616,7 @@ struct test_get_type_data {
|
|||||||
|
|
||||||
static void test_get_type_reply(DBusPendingCall *call, void *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);
|
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||||
DBusMessageIter it;
|
DBusMessageIter it;
|
||||||
|
|
||||||
@@ -656,7 +684,7 @@ struct test_get_registered_data {
|
|||||||
|
|
||||||
static void test_get_registered_reply(DBusPendingCall *call, void *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);
|
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||||
DBusMessageIter it;
|
DBusMessageIter it;
|
||||||
|
|
||||||
@@ -725,7 +753,7 @@ struct test_get_properties_data {
|
|||||||
|
|
||||||
static void test_get_properties_reply(DBusPendingCall *call, void *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);
|
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||||
DBusMessageIter it, array;
|
DBusMessageIter it, array;
|
||||||
|
|
||||||
@@ -799,9 +827,9 @@ struct test_registered_changed_data {
|
|||||||
const char *cell_path;
|
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("");
|
DBG("");
|
||||||
test_check_get_all_reply(call, &test->cell, test->type);
|
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);
|
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 =
|
struct test_registered_changed_data *test = data;
|
||||||
G_CAST(context, struct test_registered_changed_data, context);
|
|
||||||
struct sailfish_cell *first_cell;
|
struct sailfish_cell *first_cell;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
test->info = fake_cell_info_new();
|
test_check_get_cells_reply(call, test->cell_path, NULL);
|
||||||
fake_cell_info_add_cell(test->info, &test->cell);
|
dbus_pending_call_unref(call);
|
||||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
|
||||||
g_assert(test->dbus);
|
|
||||||
|
|
||||||
/* Trigger "RegisteredChanged" signal */
|
/* Trigger "RegisteredChanged" signal */
|
||||||
first_cell = test->info->cells->data;
|
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;
|
first_cell->registered = !first_cell->registered;
|
||||||
fake_cell_info_cells_changed(test->info);
|
fake_cell_info_cells_changed(test->info);
|
||||||
|
|
||||||
test_submit_get_all_call(context->client_connection, test->cell_path,
|
test_submit_get_all_call(test->context.client_connection,
|
||||||
test_registered_changed_reply, test);
|
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)
|
static void test_registered_changed(void)
|
||||||
@@ -871,28 +912,26 @@ struct test_property_changed_data {
|
|||||||
const char *cell_path;
|
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("");
|
DBG("");
|
||||||
test_check_get_all_reply(call, &test->cell, test->type);
|
test_check_get_all_reply(call, &test->cell, test->type);
|
||||||
dbus_pending_call_unref(call);
|
dbus_pending_call_unref(call);
|
||||||
|
|
||||||
test_loop_quit_later(test->context.loop);
|
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 =
|
struct test_property_changed_data *test = data;
|
||||||
G_CAST(context, struct test_property_changed_data, context);
|
|
||||||
struct sailfish_cell *first_cell;
|
struct sailfish_cell *first_cell;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
test->info = fake_cell_info_new();
|
test_check_get_cells_reply(call, test->cell_path, NULL);
|
||||||
fake_cell_info_add_cell(test->info, &test->cell);
|
dbus_pending_call_unref(call);
|
||||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
|
||||||
g_assert(test->dbus);
|
|
||||||
|
|
||||||
/* Trigger "PropertyChanged" signal */
|
/* Trigger "PropertyChanged" signal */
|
||||||
first_cell = test->info->cells->data;
|
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));
|
(++(first_cell->info.gsm.signalStrength));
|
||||||
fake_cell_info_cells_changed(test->info);
|
fake_cell_info_cells_changed(test->info);
|
||||||
|
|
||||||
test_submit_get_all_call(context->client_connection, test->cell_path,
|
test_submit_get_all_call(test->context.client_connection,
|
||||||
test_property_changed_reply1, test);
|
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)
|
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
|
#define TEST_(name) "/sailfish_cell_info_dbus/" name
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
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_("GetProperties"), test_get_properties);
|
||||||
g_test_add_func(TEST_("RegisteredChanged"), test_registered_changed);
|
g_test_add_func(TEST_("RegisteredChanged"), test_registered_changed);
|
||||||
g_test_add_func(TEST_("PropertyChanged"), test_property_changed);
|
g_test_add_func(TEST_("PropertyChanged"), test_property_changed);
|
||||||
|
g_test_add_func(TEST_("Unsubscribe"), test_unsubscribe);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user