mirror of
https://github.com/sailfishos/ofono
synced 2025-11-27 21:12:35 +08:00
Compare commits
22 Commits
mer/1.20+g
...
mer/1.20+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ec6fc749d | ||
|
|
0a3bdd20f4 | ||
|
|
284919e76a | ||
|
|
ddcbb89fa1 | ||
|
|
5ec6b8e7ec | ||
|
|
f94681f6f6 | ||
|
|
de8edc84fa | ||
|
|
90faf1b3a5 | ||
|
|
2b139b6974 | ||
|
|
168f193efb | ||
|
|
32d8b5ccfc | ||
|
|
f400ceff80 | ||
|
|
2186c60630 | ||
|
|
d5fb195e2f | ||
|
|
cbb08079d2 | ||
|
|
0583a831fb | ||
|
|
a8a0758e90 | ||
|
|
9e267487f4 | ||
|
|
c8a774dfee | ||
|
|
b88518d0f3 | ||
|
|
b223ccc675 | ||
|
|
947a41a5fc |
1
ofono/.gitignore
vendored
1
ofono/.gitignore
vendored
@@ -48,6 +48,7 @@ unit/test-rilmodem-cs
|
||||
unit/test-rilmodem-gprs
|
||||
unit/test-rilmodem-sms
|
||||
unit/test-sailfish_cell_info
|
||||
unit/test-sailfish_cell_info_dbus
|
||||
unit/test-sailfish_manager
|
||||
unit/test-sailfish_sim_info
|
||||
unit/test-sms-filter
|
||||
|
||||
@@ -24,7 +24,9 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
|
||||
include/sim-mnclength.h \
|
||||
include/handsfree-audio.h include/siri.h \
|
||||
include/sms-filter.h \
|
||||
include/netmon.h include/lte.h
|
||||
include/netmon.h include/lte.h \
|
||||
include/storage.h \
|
||||
gdbus/gdbus.h
|
||||
|
||||
nodist_pkginclude_HEADERS = include/version.h
|
||||
|
||||
@@ -910,11 +912,24 @@ if SAILFISH_MANAGER
|
||||
unit_test_sailfish_cell_info_SOURCES = unit/test-sailfish_cell_info.c \
|
||||
plugins/sailfish_manager/sailfish_cell_info.c
|
||||
unit_test_sailfish_cell_info_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||
-Iplugins/sailfish_cell_info
|
||||
-Iplugins/sailfish_manager
|
||||
unit_test_sailfish_cell_info_LDADD = @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_sailfish_cell_info_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_cell_info
|
||||
|
||||
unit_test_sailfish_cell_info_dbus_SOURCES = unit/test-dbus.c \
|
||||
unit/test-sailfish_cell_info_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 \
|
||||
src/dbus.c src/log.c
|
||||
unit_test_sailfish_cell_info_dbus_CFLAGS = $(AM_CFLAGS) $(COVERAGE_OPT) \
|
||||
@DBUS_GLIB_CFLAGS@ -Iplugins/sailfish_manager
|
||||
unit_test_sailfish_cell_info_dbus_LDADD = @DBUS_GLIB_LIBS@ @GLIB_LIBS@ -ldl
|
||||
unit_objects += $(unit_test_sailfish_cell_info_dbus_OBJECTS)
|
||||
unit_tests += unit/test-sailfish_cell_info_dbus
|
||||
|
||||
unit_test_sailfish_sim_info_SOURCES = unit/test-sailfish_sim_info.c \
|
||||
unit/fake_sailfish_watch.c \
|
||||
plugins/sailfish_manager/sailfish_sim_info.c \
|
||||
@@ -1163,6 +1178,10 @@ include/ofono/version.h: include/version.h
|
||||
$(AM_V_at)$(MKDIR_P) include/ofono
|
||||
$(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@
|
||||
|
||||
include/ofono/gdbus.h: $(abs_top_srcdir)/gdbus/gdbus.h
|
||||
$(AM_V_at)$(MKDIR_P) include/ofono
|
||||
$(AM_V_GEN)$(LN_S) $< $@
|
||||
|
||||
include/ofono/%.h: $(abs_top_srcdir)/include/%.h
|
||||
$(AM_V_at)$(MKDIR_P) include/ofono
|
||||
$(AM_V_GEN)$(LN_S) $< $@
|
||||
|
||||
@@ -202,6 +202,13 @@ AC_ARG_ENABLE(sailfish-manager,
|
||||
[enable_sailfish_manager=${enableval}])
|
||||
AM_CONDITIONAL(SAILFISH_MANAGER, test "${enable_sailfish_manager}" = "yes")
|
||||
|
||||
if (test "${enable_sailfish_manager}" = "yes"); then
|
||||
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, dummy=yes,
|
||||
AC_MSG_ERROR(dbus-glib is required by unit tests))
|
||||
AC_SUBST(DBUS_GLIB_CFLAGS)
|
||||
AC_SUBST(DBUS_GLIB_LIBS)
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(add-remove-context, AC_HELP_STRING([--disable-add-remove-context],
|
||||
[don't allow to add or remove connection context over D-Bus]), [
|
||||
if (test "${enableval}" = "no"); then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2016-2017 Jolla Ltd.
|
||||
* Copyright (C) 2016-2018 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
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#define DISPLAY_ON_UPDATE_RATE (1000) /* 1 sec */
|
||||
#define DISPLAY_OFF_UPDATE_RATE (60000) /* 1 min */
|
||||
#define MAX_RETRIES (5)
|
||||
|
||||
typedef GObjectClass RilCellInfoClass;
|
||||
typedef struct ril_cell_info RilCellInfo;
|
||||
@@ -296,8 +297,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, ril_cell_info_parse_list
|
||||
(io->ril_version, data, len));
|
||||
ril_cell_info_update_cells(self, (status == RIL_E_SUCCESS) ?
|
||||
ril_cell_info_parse_list(io->ril_version, data, len) : NULL);
|
||||
}
|
||||
|
||||
static void ril_cell_info_set_rate_cb(GRilIoChannel *io, int status,
|
||||
@@ -314,7 +315,7 @@ static void ril_cell_info_query(struct ril_cell_info *self)
|
||||
{
|
||||
GRilIoRequest *req = grilio_request_new();
|
||||
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, -1);
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
|
||||
grilio_channel_cancel_request(self->io, self->query_id, FALSE);
|
||||
self->query_id = grilio_channel_send_request_full(self->io, req,
|
||||
RIL_REQUEST_GET_CELL_INFO_LIST, ril_cell_info_list_cb,
|
||||
@@ -328,7 +329,7 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self, int ms)
|
||||
|
||||
grilio_request_append_int32(req, 1);
|
||||
grilio_request_append_int32(req, ms);
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, -1);
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, MAX_RETRIES);
|
||||
grilio_channel_cancel_request(self->io, self->set_rate_id, FALSE);
|
||||
self->set_rate_id = grilio_channel_send_request_full(self->io, req,
|
||||
RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE,
|
||||
@@ -338,18 +339,16 @@ static void ril_cell_info_set_rate(struct ril_cell_info *self, int ms)
|
||||
|
||||
static void ril_cell_info_update_rate(struct ril_cell_info *self)
|
||||
{
|
||||
ril_cell_info_set_rate(self,
|
||||
(self->display->state == MCE_DISPLAY_STATE_OFF) ?
|
||||
DISPLAY_OFF_UPDATE_RATE : DISPLAY_ON_UPDATE_RATE);
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_set_rate(self,
|
||||
(self->display->state == MCE_DISPLAY_STATE_OFF) ?
|
||||
DISPLAY_OFF_UPDATE_RATE : DISPLAY_ON_UPDATE_RATE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_cell_info_display_state_cb(MceDisplay *display, void *arg)
|
||||
{
|
||||
struct ril_cell_info *self = RIL_CELL_INFO(arg);
|
||||
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_update_rate(self);
|
||||
}
|
||||
ril_cell_info_update_rate(RIL_CELL_INFO(arg));
|
||||
}
|
||||
|
||||
static void ril_cell_info_refresh(struct ril_cell_info *self)
|
||||
@@ -373,16 +372,11 @@ static void ril_cell_info_radio_state_cb(struct ril_radio *radio, void *arg)
|
||||
static void ril_cell_info_sim_status_cb(struct ril_sim_card *sim, void *arg)
|
||||
{
|
||||
struct ril_cell_info *self = RIL_CELL_INFO(arg);
|
||||
const gboolean sim_card_was_ready = self->sim_card_ready;
|
||||
|
||||
DBG_(self, "%sready", ril_sim_card_ready(sim) ? "" : "not ");
|
||||
self->sim_card_ready = ril_sim_card_ready(sim);
|
||||
if (self->sim_card_ready != sim_card_was_ready) {
|
||||
ril_cell_info_refresh(self);
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_update_rate(self);
|
||||
}
|
||||
}
|
||||
DBG_(self, "%sready", self->sim_card_ready ? "" : "not ");
|
||||
ril_cell_info_refresh(self);
|
||||
ril_cell_info_update_rate(self);
|
||||
}
|
||||
|
||||
/* sailfish_cell_info interface callbacks */
|
||||
@@ -483,10 +477,8 @@ struct sailfish_cell_info *ril_cell_info_new(GRilIoChannel *io,
|
||||
ril_sim_card_add_status_changed_handler(self->sim_card,
|
||||
ril_cell_info_sim_status_cb, self);
|
||||
self->sim_card_ready = ril_sim_card_ready(sim_card);
|
||||
if (self->sim_card_ready) {
|
||||
ril_cell_info_query(self);
|
||||
ril_cell_info_update_rate(self);
|
||||
}
|
||||
ril_cell_info_refresh(self);
|
||||
ril_cell_info_update_rate(self);
|
||||
return &self->info;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,8 +58,6 @@ struct ril_modem_data {
|
||||
char *imeisv;
|
||||
char *imei;
|
||||
char *ecclist_file;
|
||||
gboolean pre_sim_done;
|
||||
gboolean allow_data;
|
||||
gulong imsi_event_id;
|
||||
|
||||
guint online_check_id;
|
||||
@@ -249,7 +247,6 @@ static void ril_modem_pre_sim(struct ofono_modem *modem)
|
||||
struct ril_modem_data *md = ril_modem_data_from_ofono(modem);
|
||||
|
||||
DBG("%s", ofono_modem_get_path(modem));
|
||||
md->pre_sim_done = TRUE;
|
||||
ofono_devinfo_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
ofono_sim_create(modem, 0, RILMODEM_DRIVER, md);
|
||||
if (md->modem.config.enable_voicecall) {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include "storage.h"
|
||||
#include <ofono/storage.h>
|
||||
|
||||
#define OFONO_RADIO_ACCESS_MODE_ALL (OFONO_RADIO_ACCESS_MODE_GSM |\
|
||||
OFONO_RADIO_ACCESS_MODE_UMTS |\
|
||||
@@ -1664,7 +1664,7 @@ static void ril_plugin_set_storage_perm(const char *path,
|
||||
|
||||
static void ril_plugin_switch_identity(const struct ril_plugin_identity *id)
|
||||
{
|
||||
ril_plugin_set_storage_perm(STORAGEDIR, id);
|
||||
ril_plugin_set_storage_perm(ofono_storage_dir(), id);
|
||||
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
|
||||
ofono_error("prctl(PR_SET_KEEPCAPS) failed: %s",
|
||||
strerror(errno));
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
#include "ril_util.h"
|
||||
#include "ril_log.h"
|
||||
|
||||
#include "sailfish_watch.h"
|
||||
#include "simutil.h"
|
||||
#include "util.h"
|
||||
#include "ofono.h"
|
||||
|
||||
#define SIM_STATE_CHANGE_TIMEOUT_SECS (5)
|
||||
#define FAC_LOCK_QUERY_TIMEOUT_SECS (10)
|
||||
#define FAC_LOCK_QUERY_RETRIES (1)
|
||||
#define SIM_IO_TIMEOUT_SECS (20)
|
||||
|
||||
#define EF_STATUS_INVALIDATED 0
|
||||
#define EF_STATUS_VALID 1
|
||||
@@ -75,13 +79,16 @@ struct ril_sim {
|
||||
int retries[OFONO_SIM_PASSWORD_INVALID];
|
||||
gboolean empty_pin_query_allowed;
|
||||
gboolean inserted;
|
||||
guint idle_id;
|
||||
guint idle_id; /* Used by register and SIM reset callbacks */
|
||||
gulong card_event_id[SIM_CARD_EVENT_COUNT];
|
||||
guint query_pin_retries_id;
|
||||
|
||||
const char *log_prefix;
|
||||
char *allocated_log_prefix;
|
||||
|
||||
struct sailfish_watch *watch;
|
||||
gulong sim_state_watch_id;
|
||||
|
||||
/* query_passwd_state context */
|
||||
ofono_sim_passwd_cb_t query_passwd_state_cb;
|
||||
void *query_passwd_state_cb_data;
|
||||
@@ -485,6 +492,7 @@ static void ril_sim_request_io(struct ril_sim *sd, guint cmd, int fileid,
|
||||
grilio_request_append_utf8(req, ril_sim_app_id(sd));
|
||||
|
||||
grilio_request_set_blocking(req, TRUE);
|
||||
grilio_request_set_timeout(req, SIM_IO_TIMEOUT_SECS * 1000);
|
||||
cbd->req_id = grilio_queue_send_request_full(sd->q, req,
|
||||
RIL_REQUEST_SIM_IO, cb, ril_sim_cbd_free, cbd);
|
||||
ril_sim_card_sim_io_started(sd->card, cbd->req_id);
|
||||
@@ -850,6 +858,34 @@ static void ril_sim_status_changed_cb(struct ril_sim_card *sc, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ril_sim_reinsert_cb(gpointer data)
|
||||
{
|
||||
struct ril_sim *sd = data;
|
||||
const enum ofono_sim_state state = ofono_sim_get_state(sd->watch->sim);
|
||||
|
||||
GASSERT(sd->idle_id);
|
||||
sd->idle_id = 0;
|
||||
|
||||
if (state == OFONO_SIM_STATE_RESETTING && sd->inserted) {
|
||||
DBG_(sd, "reinserting SIM");
|
||||
ofono_sim_inserted_notify(sd->sim, TRUE);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void ril_sim_state_changed_cb(struct sailfish_watch *watch, void *data)
|
||||
{
|
||||
struct ril_sim *sd = data;
|
||||
const enum ofono_sim_state state = ofono_sim_get_state(watch->sim);
|
||||
|
||||
DBG_(sd, "%d %d", state, sd->inserted);
|
||||
if (state == OFONO_SIM_STATE_RESETTING && sd->inserted &&
|
||||
!sd->idle_id) {
|
||||
sd->idle_id = g_idle_add(ril_sim_reinsert_cb, sd);
|
||||
}
|
||||
}
|
||||
|
||||
static int ril_sim_parse_retry_count(const void *data, guint len)
|
||||
{
|
||||
int retry_count = -1;
|
||||
@@ -1356,6 +1392,13 @@ static void ril_sim_query_facility_lock_cb(GRilIoChannel *io, int status,
|
||||
cb(ril_error_failure(&error), FALSE, cbd->data);
|
||||
}
|
||||
|
||||
static gboolean ril_sim_query_facility_lock_retry(GRilIoRequest* req,
|
||||
int ril_status, const void* response_data,
|
||||
guint response_len, void* user_data)
|
||||
{
|
||||
return (ril_status == GRILIO_STATUS_TIMEOUT);
|
||||
}
|
||||
|
||||
static void ril_sim_query_facility_lock(struct ofono_sim *sim,
|
||||
enum ofono_sim_password_type type,
|
||||
ofono_query_facility_lock_cb_t cb, void *data)
|
||||
@@ -1366,6 +1409,11 @@ static void ril_sim_query_facility_lock(struct ofono_sim *sim,
|
||||
GRilIoRequest *req = grilio_request_array_utf8_new(4,
|
||||
type_str, "", "0" /* class */, ril_sim_app_id(sd));
|
||||
|
||||
/* Make sure that this request gets completed sooner or later */
|
||||
grilio_request_set_timeout(req, FAC_LOCK_QUERY_TIMEOUT_SECS * 1000);
|
||||
grilio_request_set_retry(req, RIL_RETRY_MS, FAC_LOCK_QUERY_RETRIES);
|
||||
grilio_request_set_retry_func(req, ril_sim_query_facility_lock_retry);
|
||||
|
||||
DBG_(sd, "%s", type_str);
|
||||
cbd->req_id = grilio_queue_send_request_full(sd->q, req,
|
||||
RIL_REQUEST_QUERY_FACILITY_LOCK, ril_sim_query_facility_lock_cb,
|
||||
@@ -1391,6 +1439,9 @@ static gboolean ril_sim_register(gpointer user)
|
||||
sd->card_event_id[SIM_CARD_APP_EVENT] =
|
||||
ril_sim_card_add_app_changed_handler(sd->card,
|
||||
ril_sim_app_changed_cb, sd);
|
||||
sd->sim_state_watch_id =
|
||||
sailfish_watch_add_sim_state_changed_handler(sd->watch,
|
||||
ril_sim_state_changed_cb, sd);
|
||||
|
||||
/* Check the current state */
|
||||
ril_sim_status_changed_cb(sd->card, sd);
|
||||
@@ -1409,6 +1460,7 @@ static int ril_sim_probe(struct ofono_sim *sim, unsigned int vendor,
|
||||
sd->io = grilio_channel_ref(ril_modem_io(modem));
|
||||
sd->card = ril_sim_card_ref(modem->sim_card);
|
||||
sd->q = grilio_queue_new(sd->io);
|
||||
sd->watch = sailfish_watch_new(ril_modem_get_path(modem));
|
||||
|
||||
if (modem->log_prefix && modem->log_prefix[0]) {
|
||||
sd->log_prefix = sd->allocated_log_prefix =
|
||||
@@ -1445,6 +1497,9 @@ static void ril_sim_remove(struct ofono_sim *sim)
|
||||
sd->query_passwd_state_sim_status_refresh_id);
|
||||
}
|
||||
|
||||
sailfish_watch_remove_handler(sd->watch, sd->sim_state_watch_id);
|
||||
sailfish_watch_unref(sd->watch);
|
||||
|
||||
ril_sim_card_remove_handlers(sd->card, sd->card_event_id,
|
||||
G_N_ELEMENTS(sd->card_event_id));
|
||||
ril_sim_card_unref(sd->card);
|
||||
|
||||
@@ -119,6 +119,13 @@ typedef void (*ofono_sms_filter_recv_datagram_cb_t)
|
||||
#define OFONO_SMS_FILTER_PRIORITY_DEFAULT (0)
|
||||
#define OFONO_SMS_FILTER_PRIORITY_HIGH (100)
|
||||
|
||||
/*
|
||||
* The api_version field makes it possible to keep using old plugins
|
||||
* even if struct ofono_sms_filter gets extended with new callbacks.
|
||||
*/
|
||||
|
||||
#define OFONO_SMS_FILTER_API_VERSION (0)
|
||||
|
||||
/*
|
||||
* The filter callbacks either invoke the completion callback directly
|
||||
* or return the id of the cancellable asynchronous operation (but never
|
||||
@@ -135,6 +142,7 @@ typedef void (*ofono_sms_filter_recv_datagram_cb_t)
|
||||
*/
|
||||
struct ofono_sms_filter {
|
||||
const char *name;
|
||||
int api_version; /* OFONO_SMS_FILTER_API_VERSION */
|
||||
int priority;
|
||||
unsigned int (*filter_send_text)(struct ofono_modem *modem,
|
||||
const struct ofono_sms_address *addr,
|
||||
|
||||
32
ofono/include/storage.h
Normal file
32
ofono/include/storage.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Telephony stack for Linux
|
||||
*
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OFONO_STORAGE_H
|
||||
#define __OFONO_STORAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char *ofono_config_dir(void);
|
||||
const char *ofono_storage_dir(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OFONO_STORAGE_H */
|
||||
@@ -35,7 +35,7 @@
|
||||
struct sfos_bt {
|
||||
unsigned int emu_watch;
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_emulator *em;
|
||||
GSList* ems;
|
||||
unsigned char speaker_volume;
|
||||
unsigned char microphone_volume;
|
||||
};
|
||||
@@ -43,22 +43,39 @@ struct sfos_bt {
|
||||
static GSList *modems;
|
||||
static guint modemwatch_id;
|
||||
|
||||
static void sfos_bt_send_unsolicited(struct sfos_bt *bt,
|
||||
const char *format, ...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
static void sfos_bt_send_unsolicited(struct sfos_bt *bt,
|
||||
const char *format, ...)
|
||||
{
|
||||
if (bt->ems) {
|
||||
GSList *l;
|
||||
GString* buf = g_string_sized_new(15);
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
g_string_vprintf(buf, format, va);
|
||||
va_end(va);
|
||||
|
||||
for (l = bt->ems; l; l = l->next) {
|
||||
ofono_emulator_send_unsolicited(l->data, buf->str);
|
||||
}
|
||||
|
||||
g_string_free(buf, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_hfp_microphone_volume(struct sfos_bt *sfos_bt,
|
||||
unsigned char gain)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "+VGM:%d", (int) gain);
|
||||
ofono_emulator_send_unsolicited(sfos_bt->em, buf);
|
||||
sfos_bt_send_unsolicited(sfos_bt, "+VGM:%d", (int) gain);
|
||||
}
|
||||
|
||||
static void set_hfp_speaker_volume(struct sfos_bt *sfos_bt,
|
||||
unsigned char gain)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "+VGS:%d", (int) gain);
|
||||
ofono_emulator_send_unsolicited(sfos_bt->em, buf);
|
||||
sfos_bt_send_unsolicited(sfos_bt, "+VGS:%d", (int) gain);
|
||||
}
|
||||
|
||||
static DBusMessage *cv_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||
@@ -165,8 +182,8 @@ static const GDBusSignalTable cv_signals[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
int sfos_bt_call_volume_set(struct ofono_modem *modem, unsigned char volume,
|
||||
const char *gain)
|
||||
static int sfos_bt_call_volume_set(struct ofono_modem *modem,
|
||||
unsigned char volume, const char *gain)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
const char *path = ofono_modem_get_path(modem);
|
||||
@@ -233,7 +250,7 @@ static void sfos_bt_vgs_cb(struct ofono_emulator *em,
|
||||
set_gain(em, req, userdata, gain);
|
||||
}
|
||||
|
||||
void sfos_bt_cv_dbus_new(struct sfos_bt *sfos_bt)
|
||||
static void sfos_bt_cv_dbus_new(struct sfos_bt *sfos_bt)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
struct ofono_modem *modem = sfos_bt->modem;
|
||||
@@ -255,7 +272,7 @@ static void sfos_bt_remove_handler(struct ofono_emulator *em)
|
||||
ofono_emulator_remove_handler(em, "+VGM");
|
||||
}
|
||||
|
||||
void sfos_bt_cv_dbus_free(struct sfos_bt *sfos_bt)
|
||||
static void sfos_bt_cv_dbus_free(struct sfos_bt *sfos_bt)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
struct ofono_modem *modem = sfos_bt->modem;
|
||||
@@ -269,19 +286,24 @@ static void sfos_bt_emu_watch_cb(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond,
|
||||
void *data)
|
||||
{
|
||||
struct sfos_bt *sfos_bt = data;
|
||||
struct sfos_bt *bt = data;
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED){
|
||||
sfos_bt->em = __ofono_atom_get_data(atom);
|
||||
sfos_bt_cv_dbus_new(sfos_bt);
|
||||
ofono_emulator_add_handler(sfos_bt->em, "+VGS",
|
||||
sfos_bt_vgs_cb, sfos_bt, NULL);
|
||||
ofono_emulator_add_handler(sfos_bt->em, "+VGM",
|
||||
sfos_bt_vgm_cb, sfos_bt, NULL);
|
||||
if (!bt->ems)
|
||||
sfos_bt_cv_dbus_new(bt);
|
||||
|
||||
bt->ems = g_slist_append(bt->ems, em);
|
||||
ofono_emulator_add_handler(em, "+VGS", sfos_bt_vgs_cb, bt,
|
||||
NULL);
|
||||
ofono_emulator_add_handler(em, "+VGM", sfos_bt_vgm_cb, bt,
|
||||
NULL);
|
||||
} else {
|
||||
sfos_bt_cv_dbus_free(sfos_bt);
|
||||
sfos_bt_remove_handler(sfos_bt->em);
|
||||
sfos_bt->em = NULL;
|
||||
sfos_bt_remove_handler(em);
|
||||
bt->ems = g_slist_remove(bt->ems, em);
|
||||
|
||||
if (!bt->ems)
|
||||
sfos_bt_cv_dbus_free(bt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,20 +314,25 @@ static void sfos_bt_emu_watch_destroy(void *data)
|
||||
sfos_bt->emu_watch = 0;
|
||||
}
|
||||
|
||||
static void sfos_bt_free_em(gpointer data)
|
||||
{
|
||||
sfos_bt_remove_handler((struct ofono_emulator*)data);
|
||||
}
|
||||
|
||||
static void sfos_bt_free(void *data)
|
||||
{
|
||||
struct sfos_bt *sfos_bt = data;
|
||||
struct sfos_bt *bt = data;
|
||||
|
||||
if (sfos_bt->emu_watch)
|
||||
__ofono_modem_remove_atom_watch(sfos_bt->modem,
|
||||
sfos_bt->emu_watch);
|
||||
if (bt->emu_watch)
|
||||
__ofono_modem_remove_atom_watch(bt->modem, bt->emu_watch);
|
||||
|
||||
if (sfos_bt->em) {
|
||||
sfos_bt_cv_dbus_free(sfos_bt);
|
||||
sfos_bt_remove_handler(sfos_bt->em);
|
||||
if (bt->ems) {
|
||||
sfos_bt_cv_dbus_free(bt);
|
||||
g_slist_free_full(bt->ems, sfos_bt_free_em);
|
||||
bt->ems = NULL;
|
||||
}
|
||||
|
||||
g_free(sfos_bt);
|
||||
g_free(bt);
|
||||
}
|
||||
|
||||
static gint sfos_bt_find_modem(gconstpointer listdata, gconstpointer modem)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2016-2017 Jolla Ltd.
|
||||
* Copyright (C) 2016-2018 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
|
||||
@@ -178,7 +178,7 @@ static void sailfish_cell_info_dbus_append_type(DBusMessageIter *it,
|
||||
static void sailfish_cell_info_dbus_append_registered(DBusMessageIter *it,
|
||||
const struct sailfish_cell_entry *entry)
|
||||
{
|
||||
dbus_bool_t registered = entry->cell.registered;
|
||||
const dbus_bool_t registered = (entry->cell.registered != FALSE);
|
||||
|
||||
dbus_message_iter_append_basic(it, DBUS_TYPE_BOOLEAN, ®istered);
|
||||
}
|
||||
@@ -279,8 +279,8 @@ static const GDBusSignalTable sailfish_cell_info_dbus_cell_signals[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct sailfish_cell_entry *sailfish_cell_info_dbus_find_id(
|
||||
struct sailfish_cell_info_dbus *dbus, guint id)
|
||||
static struct sailfish_cell_entry *sailfish_cell_info_dbus_find_id
|
||||
(struct sailfish_cell_info_dbus *dbus, guint id)
|
||||
{
|
||||
GSList *l;
|
||||
for (l = dbus->entries; l; l = l->next) {
|
||||
@@ -376,7 +376,7 @@ static void sailfish_cell_info_dbus_property_changed
|
||||
sailfish_cell_info_dbus_cell_properties(cell->type, &n);
|
||||
|
||||
if (mask & SAILFISH_CELL_PROPERTY_REGISTERED) {
|
||||
dbus_bool_t registered = cell->registered;
|
||||
const dbus_bool_t registered = (cell->registered != FALSE);
|
||||
g_dbus_emit_signal(dbus->conn, entry->path,
|
||||
CELL_DBUS_INTERFACE,
|
||||
CELL_DBUS_REGISTERED_CHANGED_SIGNAL,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -22,9 +22,8 @@
|
||||
#include <gutil_macros.h>
|
||||
#include <string.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include "ofono.h"
|
||||
#include "storage.h"
|
||||
#include "src/ofono.h"
|
||||
#include "src/storage.h"
|
||||
|
||||
#include <sailfish_manager.h>
|
||||
#include <sailfish_cell_info.h>
|
||||
@@ -796,9 +795,6 @@ void sailfish_manager_set_sim_state(struct sailfish_slot *s,
|
||||
slot->pub.sim_present = present;
|
||||
sailfish_manager_dbus_signal_sim(p->dbus,
|
||||
slot->index, present);
|
||||
if (!present) {
|
||||
sailfish_sim_info_invalidate(slot->siminfo);
|
||||
}
|
||||
sailfish_manager_update_modem_paths_full(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -23,9 +23,9 @@
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_log.h>
|
||||
|
||||
#include "ofono.h"
|
||||
#include "common.h"
|
||||
#include "storage.h"
|
||||
#include "src/ofono.h"
|
||||
#include "src/common.h"
|
||||
#include "src/storage.h"
|
||||
|
||||
#define SAILFISH_SIM_INFO_STORE "cache"
|
||||
#define SAILFISH_SIM_INFO_STORE_GROUP "sim"
|
||||
@@ -65,6 +65,7 @@ struct sailfish_sim_info_priv {
|
||||
guint netreg_status_watch_id;
|
||||
gboolean update_imsi_cache;
|
||||
gboolean update_iccid_map;
|
||||
int queued_signals;
|
||||
};
|
||||
|
||||
enum sailfish_sim_info_signal {
|
||||
@@ -94,12 +95,37 @@ G_DEFINE_TYPE(SailfishSimInfo, sailfish_sim_info, G_TYPE_OBJECT)
|
||||
/* Skip the leading slash from the modem path: */
|
||||
#define DBG_(obj,fmt,args...) DBG("%s " fmt, (obj)->path+1, ##args)
|
||||
|
||||
static int sailfish_sim_info_signal_bit(enum sailfish_sim_info_signal id)
|
||||
{
|
||||
return (1 << id);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_signal_emit(struct sailfish_sim_info *self,
|
||||
enum sailfish_sim_info_signal id)
|
||||
{
|
||||
self->priv->queued_signals &= ~sailfish_sim_info_signal_bit(id);
|
||||
g_signal_emit(self, sailfish_sim_info_signals[id], 0);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_signal_queue(struct sailfish_sim_info *self,
|
||||
enum sailfish_sim_info_signal id)
|
||||
{
|
||||
self->priv->queued_signals |= sailfish_sim_info_signal_bit(id);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_emit_queued_signals
|
||||
(struct sailfish_sim_info *self)
|
||||
{
|
||||
struct sailfish_sim_info_priv *priv = self->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; priv->queued_signals && i < SIGNAL_COUNT; i++) {
|
||||
if (priv->queued_signals & sailfish_sim_info_signal_bit(i)) {
|
||||
sailfish_sim_info_signal_emit(self, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_update_imsi_cache(struct sailfish_sim_info *self)
|
||||
{
|
||||
struct sailfish_sim_info_priv *priv = self->priv;
|
||||
@@ -178,8 +204,15 @@ static void sailfish_sim_info_update_public_spn(struct sailfish_sim_info *self)
|
||||
|
||||
if (g_strcmp0(priv->public_spn, spn)) {
|
||||
g_free(priv->public_spn);
|
||||
self->spn = priv->public_spn = g_strdup(spn);
|
||||
sailfish_sim_info_signal_emit(self, SIGNAL_SPN_CHANGED);
|
||||
if (spn && spn[0]) {
|
||||
DBG_(self, "public spn \"%s\"", spn);
|
||||
priv->public_spn = g_strdup(spn);
|
||||
} else {
|
||||
DBG_(self, "no public spn");
|
||||
priv->public_spn = NULL;
|
||||
}
|
||||
self->spn = priv->public_spn;
|
||||
sailfish_sim_info_signal_queue(self, SIGNAL_SPN_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,29 +287,25 @@ static void sailfish_sim_info_update_default_spn(struct sailfish_sim_info *self)
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_set_imsi(struct sailfish_sim_info *self,
|
||||
const char *imsi)
|
||||
{
|
||||
struct sailfish_sim_info_priv *priv = self->priv;
|
||||
|
||||
if (g_strcmp0(priv->imsi, imsi)) {
|
||||
DBG_(self, "%s", imsi);
|
||||
g_free(priv->imsi);
|
||||
self->imsi = priv->imsi = g_strdup(imsi);
|
||||
priv->update_iccid_map = TRUE;
|
||||
sailfish_sim_info_update_iccid_map(self);
|
||||
sailfish_sim_info_update_imsi_cache(self);
|
||||
sailfish_sim_info_signal_emit(self, SIGNAL_IMSI_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_update_imsi(struct sailfish_sim_info *self)
|
||||
{
|
||||
struct sailfish_watch *watch = self->priv->watch;
|
||||
struct sailfish_sim_info_priv *priv = self->priv;
|
||||
const char *imsi = priv->watch->imsi;
|
||||
|
||||
if (watch->imsi && watch->imsi[0]) {
|
||||
sailfish_sim_info_set_imsi(self, watch->imsi);
|
||||
if (g_strcmp0(priv->imsi, imsi)) {
|
||||
g_free(priv->imsi);
|
||||
self->imsi = priv->imsi = g_strdup(imsi);
|
||||
if (imsi && imsi[0]) {
|
||||
DBG_(self, "%s", imsi);
|
||||
priv->update_iccid_map = TRUE;
|
||||
sailfish_sim_info_update_iccid_map(self);
|
||||
sailfish_sim_info_update_imsi_cache(self);
|
||||
}
|
||||
sailfish_sim_info_signal_queue(self, SIGNAL_IMSI_CHANGED);
|
||||
}
|
||||
|
||||
/* Check if MCC/MNC have changed */
|
||||
sailfish_sim_info_update_default_spn(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_network_check(struct sailfish_sim_info *self)
|
||||
@@ -333,7 +362,8 @@ static void sailfish_sim_info_load_cache(struct sailfish_sim_info *self)
|
||||
self->imsi = priv->imsi = imsi;
|
||||
DBG_(self, "imsi[%s] = %s", priv->iccid, imsi);
|
||||
sailfish_sim_info_update_iccid_map(self);
|
||||
sailfish_sim_info_signal_emit(self,
|
||||
sailfish_sim_info_update_default_spn(self);
|
||||
sailfish_sim_info_signal_queue(self,
|
||||
SIGNAL_IMSI_CHANGED);
|
||||
} else if (imsi) {
|
||||
g_free(imsi);
|
||||
@@ -378,14 +408,15 @@ static void sailfish_sim_info_set_iccid(struct sailfish_sim_info *self,
|
||||
if (g_strcmp0(priv->iccid, iccid)) {
|
||||
g_free(priv->iccid);
|
||||
self->iccid = priv->iccid = g_strdup(iccid);
|
||||
sailfish_sim_info_signal_emit(self, SIGNAL_ICCID_CHANGED);
|
||||
sailfish_sim_info_signal_queue(self, SIGNAL_ICCID_CHANGED);
|
||||
if (iccid) {
|
||||
sailfish_sim_info_load_cache(self);
|
||||
} else {
|
||||
DBG_(self, "no more iccid");
|
||||
if (priv->imsi) {
|
||||
g_free(priv->imsi);
|
||||
self->imsi = priv->imsi = NULL;
|
||||
sailfish_sim_info_signal_emit(self,
|
||||
sailfish_sim_info_signal_queue(self,
|
||||
SIGNAL_IMSI_CHANGED);
|
||||
}
|
||||
if (priv->sim_spn) {
|
||||
@@ -393,23 +424,13 @@ static void sailfish_sim_info_set_iccid(struct sailfish_sim_info *self,
|
||||
priv->sim_spn = NULL;
|
||||
sailfish_sim_info_set_cached_spn(self, NULL);
|
||||
}
|
||||
/* No more default SPN too */
|
||||
priv->default_spn[0] = 0;
|
||||
sailfish_sim_info_update_public_spn(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_sim_watch_cb(struct sailfish_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
struct ofono_sim *sim = self->priv->watch->sim;
|
||||
|
||||
sailfish_sim_info_update_default_spn(self);
|
||||
if (ofono_sim_get_state(sim) == OFONO_SIM_STATE_NOT_PRESENT) {
|
||||
sailfish_sim_info_set_iccid(self, NULL);
|
||||
}
|
||||
sailfish_sim_info_network_check(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_iccid_watch_cb(struct sailfish_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
@@ -417,24 +438,34 @@ static void sailfish_sim_info_iccid_watch_cb(struct sailfish_watch *watch,
|
||||
|
||||
DBG_(self, "%s", watch->iccid);
|
||||
sailfish_sim_info_set_iccid(self, watch->iccid);
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_imsi_watch_cb(struct sailfish_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
sailfish_sim_info_update_imsi(SAILFISH_SIMINFO(data));
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
|
||||
sailfish_sim_info_update_imsi(self);
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_spn_watch_cb(struct sailfish_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
sailfish_sim_info_update_spn(SAILFISH_SIMINFO(data));
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
|
||||
sailfish_sim_info_update_spn(self);
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_netreg_watch(int status, int lac, int ci,
|
||||
int tech, const char *mcc, const char *mnc, void *data)
|
||||
{
|
||||
sailfish_sim_info_network_check(SAILFISH_SIMINFO(data));
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
|
||||
sailfish_sim_info_network_check(self);
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_sim_info_netreg_watch_done(void *data)
|
||||
@@ -475,7 +506,10 @@ static void sailfish_sim_info_set_netreg(struct sailfish_sim_info *self,
|
||||
static void sailfish_sim_info_netreg_changed(struct sailfish_watch *watch,
|
||||
void *data)
|
||||
{
|
||||
sailfish_sim_info_set_netreg(SAILFISH_SIMINFO(data), watch->netreg);
|
||||
struct sailfish_sim_info *self = SAILFISH_SIMINFO(data);
|
||||
|
||||
sailfish_sim_info_set_netreg(self, watch->netreg);
|
||||
sailfish_sim_info_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
struct sailfish_sim_info *sailfish_sim_info_new(const char *path)
|
||||
@@ -490,12 +524,6 @@ struct sailfish_sim_info *sailfish_sim_info_new(const char *path)
|
||||
priv = self->priv;
|
||||
priv->watch = watch;
|
||||
self->path = watch->path;
|
||||
priv->watch_event_id[WATCH_EVENT_SIM] =
|
||||
sailfish_watch_add_sim_changed_handler(watch,
|
||||
sailfish_sim_info_sim_watch_cb, self);
|
||||
priv->watch_event_id[WATCH_EVENT_SIM_STATE] =
|
||||
sailfish_watch_add_sim_state_changed_handler(watch,
|
||||
sailfish_sim_info_sim_watch_cb, self);
|
||||
priv->watch_event_id[WATCH_EVENT_ICCID] =
|
||||
sailfish_watch_add_iccid_changed_handler(watch,
|
||||
sailfish_sim_info_iccid_watch_cb, self);
|
||||
@@ -513,6 +541,9 @@ struct sailfish_sim_info *sailfish_sim_info_new(const char *path)
|
||||
sailfish_sim_info_update_imsi(self);
|
||||
sailfish_sim_info_update_spn(self);
|
||||
sailfish_sim_info_network_check(self);
|
||||
|
||||
/* Clear queued events, if any */
|
||||
priv->queued_signals = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -534,13 +565,6 @@ void sailfish_sim_info_unref(struct sailfish_sim_info *self)
|
||||
}
|
||||
}
|
||||
|
||||
void sailfish_sim_info_invalidate(struct sailfish_sim_info *self)
|
||||
{
|
||||
if (self) {
|
||||
sailfish_sim_info_set_iccid(self, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gulong sailfish_sim_info_add_iccid_changed_handler(struct sailfish_sim_info *s,
|
||||
sailfish_sim_info_cb_t cb, void *arg)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -48,7 +48,6 @@ typedef void (*sailfish_sim_info_cb_t)(struct sailfish_sim_info *si,
|
||||
struct sailfish_sim_info *sailfish_sim_info_new(const char *path);
|
||||
struct sailfish_sim_info *sailfish_sim_info_ref(struct sailfish_sim_info *si);
|
||||
void sailfish_sim_info_unref(struct sailfish_sim_info *si);
|
||||
void sailfish_sim_info_invalidate(struct sailfish_sim_info *si);
|
||||
gulong sailfish_sim_info_add_iccid_changed_handler(struct sailfish_sim_info *si,
|
||||
sailfish_sim_info_cb_t cb, void *user_data);
|
||||
gulong sailfish_sim_info_add_imsi_changed_handler(struct sailfish_sim_info *si,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -126,24 +126,6 @@ static inline void sailfish_watch_resume_signals(struct sailfish_watch *self)
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_notify(enum ofono_sim_state new_state,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SIM_STATE_CHANGED);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->sim_state_watch_id);
|
||||
priv->sim_state_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_iccid_update(struct sailfish_watch *self,
|
||||
const char *iccid)
|
||||
{
|
||||
@@ -238,6 +220,35 @@ static void sailfish_watch_imsi_destroy(void *user_data)
|
||||
priv->imsi_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_notify(enum ofono_sim_state new_state,
|
||||
void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
|
||||
/*
|
||||
* ofono core doesn't notify SIM watches when SIM card gets removed.
|
||||
* So we have to reset things here based on the SIM state.
|
||||
*/
|
||||
if (new_state == OFONO_SIM_STATE_NOT_PRESENT) {
|
||||
sailfish_watch_iccid_update(self, NULL);
|
||||
}
|
||||
if (new_state != OFONO_SIM_STATE_READY) {
|
||||
sailfish_watch_imsi_update(self, NULL);
|
||||
sailfish_watch_spn_update(self, NULL);
|
||||
}
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SIM_STATE_CHANGED);
|
||||
sailfish_watch_emit_queued_signals(self);
|
||||
}
|
||||
|
||||
static void sailfish_watch_sim_state_destroy(void *user_data)
|
||||
{
|
||||
struct sailfish_watch *self = SAILFISH_WATCH(user_data);
|
||||
struct sailfish_watch_priv *priv = self->priv;
|
||||
|
||||
GASSERT(priv->sim_state_watch_id);
|
||||
priv->sim_state_watch_id = 0;
|
||||
}
|
||||
|
||||
static void sailfish_watch_set_sim(struct sailfish_watch *self,
|
||||
struct ofono_sim *sim)
|
||||
{
|
||||
@@ -271,6 +282,11 @@ static void sailfish_watch_set_sim(struct sailfish_watch *self,
|
||||
self->sim = sim;
|
||||
sailfish_watch_signal_queue(self, SIGNAL_SIM_CHANGED);
|
||||
sailfish_watch_suspend_signals(self);
|
||||
|
||||
/* Reset the current state */
|
||||
sailfish_watch_iccid_update(self, NULL);
|
||||
sailfish_watch_imsi_update(self, NULL);
|
||||
sailfish_watch_spn_update(self, NULL);
|
||||
if (sim) {
|
||||
priv->sim_state_watch_id =
|
||||
ofono_sim_add_state_watch(sim,
|
||||
@@ -293,12 +309,6 @@ static void sailfish_watch_set_sim(struct sailfish_watch *self,
|
||||
ofono_sim_add_imsi_watch(self->sim,
|
||||
sailfish_watch_imsi_notify, self,
|
||||
sailfish_watch_imsi_destroy);
|
||||
} else {
|
||||
/* And these will just queue the signals
|
||||
* if necessary */
|
||||
sailfish_watch_iccid_update(self, NULL);
|
||||
sailfish_watch_imsi_update(self, NULL);
|
||||
sailfish_watch_spn_update(self, NULL);
|
||||
}
|
||||
|
||||
/* Emit the pending signals. */
|
||||
|
||||
@@ -2207,6 +2207,9 @@ static void sim_efli_efpl_changed(int id, void *userdata)
|
||||
if (sim->efli != NULL) /* This shouldn't happen */
|
||||
return;
|
||||
|
||||
if (sim->language_prefs_update)
|
||||
return;
|
||||
|
||||
if (sim->language_prefs) {
|
||||
g_strfreev(sim->language_prefs);
|
||||
sim->language_prefs = NULL;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ofono/storage.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@@ -35,6 +37,16 @@
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
const char *ofono_config_dir(void)
|
||||
{
|
||||
return CONFIGDIR;
|
||||
}
|
||||
|
||||
const char *ofono_storage_dir(void)
|
||||
{
|
||||
return STORAGEDIR;
|
||||
}
|
||||
|
||||
int create_dirs(const char *filename, const mode_t mode)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@@ -20,6 +20,7 @@ TESTS="\
|
||||
test-ril_util \
|
||||
test-sms-filter \
|
||||
test-sailfish_cell_info \
|
||||
test-sailfish_cell_info_dbus \
|
||||
test-sailfish_manager \
|
||||
test-sailfish_sim_info"
|
||||
|
||||
|
||||
181
ofono/unit/fake_sailfish_cell_info.c
Normal file
181
ofono/unit/fake_sailfish_cell_info.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 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
|
||||
* 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 "fake_sailfish_cell_info.h"
|
||||
|
||||
#include <gutil_macros.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
typedef GObjectClass FakeCellInfoClass;
|
||||
typedef struct fake_cell_info {
|
||||
GObject object;
|
||||
struct sailfish_cell_info info;
|
||||
} FakeCellInfo;
|
||||
|
||||
typedef struct fake_cell_info_signal_data {
|
||||
sailfish_cell_info_cb_t cb;
|
||||
void *arg;
|
||||
} FakeCellInfoSignalData;
|
||||
|
||||
enum fake_cell_info_signal {
|
||||
SIGNAL_CELLS_CHANGED,
|
||||
SIGNAL_COUNT
|
||||
};
|
||||
|
||||
static guint fake_cell_info_signals[SIGNAL_COUNT] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE(FakeCellInfo, fake_cell_info, G_TYPE_OBJECT)
|
||||
#define FAKE_CELL_INFO_TYPE (fake_cell_info_get_type())
|
||||
#define FAKE_CELL_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||
FAKE_CELL_INFO_TYPE, FakeCellInfo))
|
||||
|
||||
#define SIGNAL_CELLS_CHANGED_NAME "fake-cell-info-cells-changed"
|
||||
|
||||
static FakeCellInfo *fake_cell_info_cast(struct sailfish_cell_info *info)
|
||||
{
|
||||
return G_CAST(info, FakeCellInfo, info);
|
||||
}
|
||||
|
||||
static void fake_cell_info_ref_proc(struct sailfish_cell_info *info)
|
||||
{
|
||||
g_object_ref(fake_cell_info_cast(info));
|
||||
}
|
||||
|
||||
static void fake_cell_info_unref_proc(struct sailfish_cell_info *info)
|
||||
{
|
||||
g_object_unref(fake_cell_info_cast(info));
|
||||
}
|
||||
|
||||
static void fake_cell_info_cells_changed_cb(FakeCellInfo *self, void *data)
|
||||
{
|
||||
FakeCellInfoSignalData *signal_data = data;
|
||||
|
||||
signal_data->cb(&self->info, signal_data->arg);
|
||||
}
|
||||
|
||||
static void fake_cell_info_cells_disconnect_notify(gpointer data,
|
||||
GClosure *closure)
|
||||
{
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static gulong fake_cell_info_add_cells_changed_handler_proc
|
||||
(struct sailfish_cell_info *info,
|
||||
sailfish_cell_info_cb_t cb, void *arg)
|
||||
{
|
||||
if (cb) {
|
||||
FakeCellInfoSignalData *data =
|
||||
g_new0(FakeCellInfoSignalData, 1);
|
||||
|
||||
data->cb = cb;
|
||||
data->arg = arg;
|
||||
return g_signal_connect_data(fake_cell_info_cast(info),
|
||||
SIGNAL_CELLS_CHANGED_NAME,
|
||||
G_CALLBACK(fake_cell_info_cells_changed_cb),
|
||||
data, fake_cell_info_cells_disconnect_notify,
|
||||
G_CONNECT_AFTER);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_cell_info_remove_handler_proc(struct sailfish_cell_info *info,
|
||||
gulong id)
|
||||
{
|
||||
if (id) {
|
||||
g_signal_handler_disconnect(fake_cell_info_cast(info), id);
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_cell_info_init(FakeCellInfo *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void fake_cell_info_finalize(GObject *object)
|
||||
{
|
||||
FakeCellInfo *self = FAKE_CELL_INFO(object);
|
||||
|
||||
fake_cell_info_remove_all_cells(&self->info);
|
||||
G_OBJECT_CLASS(fake_cell_info_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void fake_cell_info_class_init(FakeCellInfoClass *klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = fake_cell_info_finalize;
|
||||
fake_cell_info_signals[SIGNAL_CELLS_CHANGED] =
|
||||
g_signal_new(SIGNAL_CELLS_CHANGED_NAME,
|
||||
G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
struct sailfish_cell_info *fake_cell_info_new()
|
||||
{
|
||||
static const struct sailfish_cell_info_proc fake_cell_info_proc = {
|
||||
fake_cell_info_ref_proc,
|
||||
fake_cell_info_unref_proc,
|
||||
fake_cell_info_add_cells_changed_handler_proc,
|
||||
fake_cell_info_remove_handler_proc
|
||||
};
|
||||
|
||||
FakeCellInfo *self = g_object_new(FAKE_CELL_INFO_TYPE, 0);
|
||||
|
||||
self->info.proc = &fake_cell_info_proc;
|
||||
return &self->info;
|
||||
}
|
||||
|
||||
void fake_cell_info_add_cell(struct sailfish_cell_info *info,
|
||||
const struct sailfish_cell* cell)
|
||||
{
|
||||
info->cells = g_slist_append(info->cells,
|
||||
g_memdup(cell, sizeof(*cell)));
|
||||
}
|
||||
|
||||
gboolean fake_cell_info_remove_cell(struct sailfish_cell_info *info,
|
||||
const struct sailfish_cell* cell)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = info->cells; l; l = l->next) {
|
||||
struct sailfish_cell *known_cell = l->data;
|
||||
|
||||
if (!memcmp(cell, known_cell, sizeof(*cell))) {
|
||||
info->cells = g_slist_remove(info->cells, known_cell);
|
||||
g_free(known_cell);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void fake_cell_info_remove_all_cells(struct sailfish_cell_info *info)
|
||||
{
|
||||
g_slist_free_full(info->cells, g_free);
|
||||
info->cells = NULL;
|
||||
}
|
||||
|
||||
void fake_cell_info_cells_changed(struct sailfish_cell_info *info)
|
||||
{
|
||||
g_signal_emit(fake_cell_info_cast(info), fake_cell_info_signals
|
||||
[SIGNAL_CELLS_CHANGED], 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
37
ofono/unit/fake_sailfish_cell_info.h
Normal file
37
ofono/unit/fake_sailfish_cell_info.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 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
|
||||
* 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 SAILFISH_FAKE_CELL_INFO_H
|
||||
#define SAILFISH_FAKE_CELL_INFO_H
|
||||
|
||||
#include "sailfish_cell_info.h"
|
||||
|
||||
struct sailfish_cell_info *fake_cell_info_new(void);
|
||||
void fake_cell_info_add_cell(struct sailfish_cell_info *info,
|
||||
const struct sailfish_cell* cell);
|
||||
gboolean fake_cell_info_remove_cell(struct sailfish_cell_info *info,
|
||||
const struct sailfish_cell* cell);
|
||||
void fake_cell_info_remove_all_cells(struct sailfish_cell_info *info);
|
||||
void fake_cell_info_cells_changed(struct sailfish_cell_info *info);
|
||||
|
||||
#endif /* FAKE_SAILFISH_CELL_INFO_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
341
ofono/unit/test-dbus.c
Normal file
341
ofono/unit/test-dbus.c
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 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
|
||||
* 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.h"
|
||||
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
struct test_polkit_auth_check {
|
||||
void (*function)(dbus_bool_t authorized, void *user_data);
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
struct test_dbus_watch {
|
||||
struct test_dbus_watch *next;
|
||||
guint id;
|
||||
DBusConnection *connection;
|
||||
GDBusWatchFunction disconnect;
|
||||
GDBusDestroyFunction destroy;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
struct test_dbus_watch *test_dbus_watch_list;
|
||||
static unsigned int test_last_id;
|
||||
|
||||
static gboolean polkit_check_authorization_cb(gpointer data)
|
||||
{
|
||||
struct test_polkit_auth_check *check = data;
|
||||
|
||||
check->function(TRUE, check->user_data);
|
||||
g_free(check);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
int polkit_check_authorization(DBusConnection *conn,
|
||||
const char *action, gboolean interaction,
|
||||
void (*function)(dbus_bool_t authorized, void *user_data),
|
||||
void *user_data, int timeout)
|
||||
{
|
||||
struct test_polkit_auth_check *check =
|
||||
g_new(struct test_polkit_auth_check, 1);
|
||||
|
||||
check->function = function;
|
||||
check->user_data = user_data;
|
||||
g_idle_add(polkit_check_authorization_cb, check);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint test_dbus_add_watch(DBusConnection *connection,
|
||||
GDBusWatchFunction disconnect, GDBusDestroyFunction destroy,
|
||||
void *user_data)
|
||||
{
|
||||
struct test_dbus_watch *watch = g_new0(struct test_dbus_watch, 1);
|
||||
|
||||
test_last_id++;
|
||||
watch->id = test_last_id;
|
||||
watch->connection = dbus_connection_ref(connection);
|
||||
watch->disconnect = disconnect;
|
||||
watch->destroy = destroy;
|
||||
watch->user_data = user_data;
|
||||
watch->next = test_dbus_watch_list;
|
||||
test_dbus_watch_list = watch;
|
||||
return test_last_id;
|
||||
}
|
||||
|
||||
static gboolean test_dbus_watch_disconnect_one(void)
|
||||
{
|
||||
struct test_dbus_watch *watch = test_dbus_watch_list;
|
||||
|
||||
while (watch) {
|
||||
if (watch->disconnect) {
|
||||
GDBusWatchFunction disconnect = watch->disconnect;
|
||||
|
||||
watch->disconnect = NULL;
|
||||
disconnect(watch->connection, watch->user_data);
|
||||
return TRUE;
|
||||
}
|
||||
watch = watch->next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void test_dbus_watch_disconnect_all(void)
|
||||
{
|
||||
while (test_dbus_watch_disconnect_one());
|
||||
}
|
||||
|
||||
static void test_dbus_watch_free(struct test_dbus_watch *watch)
|
||||
{
|
||||
if (watch->destroy) {
|
||||
watch->destroy(watch->user_data);
|
||||
}
|
||||
dbus_connection_unref(watch->connection);
|
||||
g_free(watch);
|
||||
}
|
||||
|
||||
static gboolean test_dbus_watch_remove_one(void)
|
||||
{
|
||||
struct test_dbus_watch *watch = test_dbus_watch_list;
|
||||
|
||||
if (watch) {
|
||||
test_dbus_watch_list = watch->next;
|
||||
test_dbus_watch_free(watch);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void test_dbus_watch_remove_all(void)
|
||||
{
|
||||
while (test_dbus_watch_remove_one());
|
||||
}
|
||||
|
||||
guint g_dbus_add_signal_watch(DBusConnection *connection, const char *sender,
|
||||
const char *path, const char *interface, const char *member,
|
||||
GDBusSignalFunction function, void *user_data,
|
||||
GDBusDestroyFunction destroy)
|
||||
{
|
||||
return test_dbus_add_watch(connection, NULL, destroy, user_data);
|
||||
}
|
||||
|
||||
gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
|
||||
{
|
||||
struct test_dbus_watch *prev = NULL;
|
||||
struct test_dbus_watch *watch = test_dbus_watch_list;
|
||||
|
||||
while (watch) {
|
||||
if (watch->id == id) {
|
||||
if (prev) {
|
||||
prev->next = watch->next;
|
||||
} else {
|
||||
test_dbus_watch_list = watch->next;
|
||||
}
|
||||
test_dbus_watch_free(watch);
|
||||
return TRUE;
|
||||
}
|
||||
prev = watch;
|
||||
watch = watch->next;
|
||||
}
|
||||
ofono_warn("Unexpected id %u", id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean test_dbus_loop_quit(gpointer data)
|
||||
{
|
||||
g_main_loop_quit(data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void test_dbus_loop_quit_later(GMainLoop *loop)
|
||||
{
|
||||
g_idle_add(test_dbus_loop_quit, loop);
|
||||
}
|
||||
|
||||
DBusMessage *test_dbus_find_signal(struct test_dbus_context *test,
|
||||
const char *path, const char *iface, const char *member)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = test->client_signals; l; l = l->next) {
|
||||
DBusMessage *msg = l->data;
|
||||
|
||||
if (!g_strcmp0(dbus_message_get_interface(msg), iface) &&
|
||||
!g_strcmp0(dbus_message_get_member(msg), member) &&
|
||||
!g_strcmp0(dbus_message_get_path(msg), path)) {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBusMessage *test_dbus_take_signal(struct test_dbus_context *test,
|
||||
const char *path, const char *iface, const char *member)
|
||||
{
|
||||
DBusMessage *m = test_dbus_find_signal(test, path, iface, member);
|
||||
|
||||
if (m) {
|
||||
test->client_signals = g_slist_remove(test->client_signals, m);
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int test_dbus_get_int32(DBusMessageIter *it)
|
||||
{
|
||||
dbus_uint32_t value;
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_INT32);
|
||||
dbus_message_iter_get_basic(it, &value);
|
||||
dbus_message_iter_next(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
gboolean test_dbus_get_bool(DBusMessageIter *it)
|
||||
{
|
||||
dbus_bool_t value;
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_BOOLEAN);
|
||||
dbus_message_iter_get_basic(it, &value);
|
||||
dbus_message_iter_next(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
const char *test_dbus_get_string(DBusMessageIter *it)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_STRING);
|
||||
dbus_message_iter_get_basic(it, &value);
|
||||
dbus_message_iter_next(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
const char *test_dbus_get_object_path(DBusMessageIter *it)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_OBJECT_PATH);
|
||||
dbus_message_iter_get_basic(it, &value);
|
||||
dbus_message_iter_next(it);
|
||||
return value;
|
||||
}
|
||||
|
||||
void test_dbus_expect_empty_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_dbus_context *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
DBG("");
|
||||
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);
|
||||
dbus_pending_call_unref(call);
|
||||
test_dbus_loop_quit_later(test->loop);
|
||||
}
|
||||
|
||||
void test_dbus_message_unref(gpointer data)
|
||||
{
|
||||
dbus_message_unref(data);
|
||||
}
|
||||
|
||||
static DBusHandlerResult test_dbus_client_message_cb(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct test_dbus_context *test = data;
|
||||
|
||||
if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_SIGNAL) {
|
||||
DBG("signal %s.%s \"%s\"", dbus_message_get_interface(msg),
|
||||
dbus_message_get_member(msg),
|
||||
dbus_message_get_path(msg));
|
||||
test->client_signals = g_slist_append(test->client_signals,
|
||||
dbus_message_ref(msg));
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
} else {
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_dbus_connection_cb(DBusServer *server, DBusConnection *conn,
|
||||
void *data)
|
||||
{
|
||||
struct test_dbus_context *test = data;
|
||||
|
||||
DBG("");
|
||||
g_assert(!test->server_connection);
|
||||
test->server_connection = dbus_connection_ref(conn);
|
||||
dbus_connection_setup_with_g_main(test->server_connection,
|
||||
g_main_loop_get_context(test->loop));
|
||||
|
||||
/* Start the test */
|
||||
__ofono_dbus_init(test->server_connection);
|
||||
test->start(test);
|
||||
}
|
||||
|
||||
void test_dbus_setup(struct test_dbus_context *test)
|
||||
{
|
||||
char *address;
|
||||
GMainContext *context;
|
||||
|
||||
test->loop = g_main_loop_new(NULL, TRUE);
|
||||
context = g_main_loop_get_context(test->loop);
|
||||
test->server = dbus_server_listen("unix:runtime=yes;unix:tmpdir=/tmp",
|
||||
NULL);
|
||||
g_assert(test->server);
|
||||
address = dbus_server_get_address(test->server);
|
||||
DBG("listening on %s", address);
|
||||
|
||||
dbus_server_setup_with_g_main(test->server, context);
|
||||
dbus_server_set_new_connection_function(test->server,
|
||||
test_dbus_connection_cb, test, NULL);
|
||||
|
||||
test->client_connection = dbus_connection_open_private(address, NULL);
|
||||
g_assert(test->client_connection);
|
||||
dbus_connection_setup_with_g_main(test->client_connection, context);
|
||||
g_assert(dbus_connection_add_filter(test->client_connection,
|
||||
test_dbus_client_message_cb, test, NULL));
|
||||
DBG("connected on %s", address);
|
||||
dbus_free(address);
|
||||
}
|
||||
|
||||
void test_dbus_shutdown(struct test_dbus_context *test)
|
||||
{
|
||||
test_dbus_watch_disconnect_all();
|
||||
test_dbus_watch_remove_all();
|
||||
__ofono_dbus_cleanup();
|
||||
if (test->server_connection) {
|
||||
dbus_connection_close(test->server_connection);
|
||||
dbus_connection_unref(test->server_connection);
|
||||
}
|
||||
dbus_connection_close(test->client_connection);
|
||||
dbus_connection_unref(test->client_connection);
|
||||
dbus_server_disconnect(test->server);
|
||||
dbus_server_unref(test->server);
|
||||
g_main_loop_unref(test->loop);
|
||||
g_slist_free_full(test->client_signals, test_dbus_message_unref);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
55
ofono/unit/test-dbus.h
Normal file
55
ofono/unit/test-dbus.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 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
|
||||
* 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 TEST_DBUS_H
|
||||
#define TEST_DBUS_H
|
||||
|
||||
#include <ofono/gdbus.h>
|
||||
|
||||
struct test_dbus_context {
|
||||
GMainLoop *loop;
|
||||
DBusServer *server;
|
||||
DBusConnection *server_connection;
|
||||
DBusConnection *client_connection;
|
||||
GSList* client_signals;
|
||||
void (*start)(struct test_dbus_context *test);
|
||||
guint timeout_id;
|
||||
};
|
||||
|
||||
void test_dbus_setup(struct test_dbus_context *context);
|
||||
void test_dbus_shutdown(struct test_dbus_context *context);
|
||||
|
||||
void test_dbus_watch_disconnect_all(void);
|
||||
void test_dbus_watch_remove_all(void);
|
||||
|
||||
int test_dbus_get_int32(DBusMessageIter *it);
|
||||
gboolean test_dbus_get_bool(DBusMessageIter *it);
|
||||
const char *test_dbus_get_string(DBusMessageIter *it);
|
||||
const char *test_dbus_get_object_path(DBusMessageIter *it);
|
||||
|
||||
DBusMessage *test_dbus_find_signal(struct test_dbus_context *test,
|
||||
const char *path, const char *iface, const char *member);
|
||||
DBusMessage *test_dbus_take_signal(struct test_dbus_context *test,
|
||||
const char *path, const char *iface, const char *member);
|
||||
|
||||
#endif /* TEST_DBUS_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
979
ofono/unit/test-sailfish_cell_info_dbus.c
Normal file
979
ofono/unit/test-sailfish_cell_info_dbus.c
Normal file
@@ -0,0 +1,979 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2018 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
|
||||
* 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 "sailfish_cell_info.h"
|
||||
#include "sailfish_cell_info_dbus.h"
|
||||
#include "fake_sailfish_cell_info.h"
|
||||
|
||||
#include <gutil_log.h>
|
||||
#include <gutil_macros.h>
|
||||
|
||||
#include "ofono.h"
|
||||
|
||||
#define TEST_TIMEOUT (10) /* seconds */
|
||||
#define TEST_MODEM_PATH "/test"
|
||||
#define TEST_SENDER ":1.0"
|
||||
|
||||
#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_DBUS_INTERFACE_VERSION (1)
|
||||
#define CELL_DBUS_INTERFACE "org.nemomobile.ofono.Cell"
|
||||
#define CELL_DBUS_REGISTERED_CHANGED_SIGNAL "RegisteredChanged"
|
||||
#define CELL_DBUS_PROPERTY_CHANGED_SIGNAL "PropertyChanged"
|
||||
#define CELL_DBUS_REMOVED_SIGNAL "Removed"
|
||||
|
||||
static gboolean test_debug;
|
||||
|
||||
/* Stubs (ofono) */
|
||||
|
||||
struct ofono_modem {
|
||||
const char *path;
|
||||
};
|
||||
|
||||
const char *ofono_modem_get_path(struct ofono_modem *modem)
|
||||
{
|
||||
return modem->path;
|
||||
}
|
||||
|
||||
void ofono_modem_add_interface(struct ofono_modem *modem, const char *iface)
|
||||
{
|
||||
DBG("%s %s", modem->path, iface);
|
||||
}
|
||||
|
||||
/* ==== 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);
|
||||
}
|
||||
|
||||
static DBusMessage *test_new_cell_info_call(const char *method)
|
||||
{
|
||||
DBusMessage *msg = dbus_message_new_method_call(NULL, TEST_MODEM_PATH,
|
||||
CELL_INFO_DBUS_INTERFACE, method);
|
||||
|
||||
g_assert(dbus_message_set_sender(msg, TEST_SENDER));
|
||||
return msg;
|
||||
}
|
||||
|
||||
static DBusMessage *test_new_cell_call(const char *path, const char *method)
|
||||
{
|
||||
DBusMessage *msg = dbus_message_new_method_call(NULL, path,
|
||||
CELL_DBUS_INTERFACE, method);
|
||||
|
||||
g_assert(dbus_message_set_sender(msg, TEST_SENDER));
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void test_submit_get_all_call(DBusConnection* connection,
|
||||
const char *cell_path, DBusPendingCallNotifyFunction notify,
|
||||
void *data)
|
||||
{
|
||||
DBusMessage *msg;
|
||||
DBusPendingCall* call;
|
||||
|
||||
msg = test_new_cell_call(cell_path, "GetAll");
|
||||
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_check_object_path_array_va(DBusMessageIter *it,
|
||||
const char *path1, va_list va)
|
||||
{
|
||||
DBusMessageIter array;
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_ARRAY);
|
||||
dbus_message_iter_recurse(it, &array);
|
||||
dbus_message_iter_next(it);
|
||||
|
||||
if (path1) {
|
||||
const char *path;
|
||||
|
||||
g_assert(!g_strcmp0(test_dbus_get_object_path(&array), path1));
|
||||
while ((path = va_arg(va, char*)) != NULL) {
|
||||
g_assert(!g_strcmp0(test_dbus_get_object_path(&array),
|
||||
path));
|
||||
}
|
||||
}
|
||||
|
||||
g_assert(dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_INVALID);
|
||||
g_assert(dbus_message_iter_get_arg_type(it) == DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
static void test_check_object_path_array(DBusMessageIter *it,
|
||||
const char *path1, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, path1);
|
||||
test_check_object_path_array_va(it, path1, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static void test_check_get_cells_reply(DBusPendingCall *call,
|
||||
const char *path1, ...)
|
||||
{
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
va_list va;
|
||||
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
dbus_message_iter_init(reply, &it);
|
||||
va_start(va, path1);
|
||||
test_check_object_path_array_va(&it, path1, va);
|
||||
va_end(va);
|
||||
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static void test_check_get_all_reply(DBusPendingCall *call,
|
||||
const struct sailfish_cell *cell, const char *type)
|
||||
{
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it, array;
|
||||
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
dbus_message_iter_init(reply, &it);
|
||||
g_assert(test_dbus_get_int32(&it) == CELL_DBUS_INTERFACE_VERSION);
|
||||
g_assert(!g_strcmp0(test_dbus_get_string(&it), type));
|
||||
g_assert(test_dbus_get_bool(&it) == (cell->registered != FALSE));
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_ARRAY);
|
||||
dbus_message_iter_recurse(&it, &array);
|
||||
dbus_message_iter_next(&it);
|
||||
/* Validate the properties? */
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_INVALID);
|
||||
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;
|
||||
|
||||
memset(cell, 0, sizeof(*cell));
|
||||
cell->type = SAILFISH_CELL_TYPE_GSM;
|
||||
cell->registered = TRUE;
|
||||
gsm->mcc = 244;
|
||||
gsm->mnc = 5;
|
||||
gsm->lac = 9007;
|
||||
gsm->cid = 42335;
|
||||
gsm->arfcn = INT_MAX;
|
||||
gsm->bsic = INT_MAX;
|
||||
gsm->signalStrength = 26;
|
||||
gsm->bitErrorRate = 99;
|
||||
gsm->timingAdvance = INT_MAX;
|
||||
return cell;
|
||||
}
|
||||
|
||||
static struct sailfish_cell *test_cell_init_gsm2(struct sailfish_cell *cell)
|
||||
{
|
||||
struct sailfish_cell_info_gsm *gsm = &cell->info.gsm;
|
||||
|
||||
memset(cell, 0, sizeof(*cell));
|
||||
cell->type = SAILFISH_CELL_TYPE_GSM;
|
||||
cell->registered = FALSE;
|
||||
gsm->mcc = 244;
|
||||
gsm->mnc = 5;
|
||||
gsm->lac = 9007;
|
||||
gsm->cid = 35600;
|
||||
gsm->arfcn = INT_MAX;
|
||||
gsm->bsic = INT_MAX;
|
||||
gsm->signalStrength = 8;
|
||||
gsm->bitErrorRate = 99;
|
||||
gsm->timingAdvance = INT_MAX;
|
||||
return cell;
|
||||
}
|
||||
|
||||
static struct sailfish_cell *test_cell_init_wcdma1(struct sailfish_cell *cell)
|
||||
{
|
||||
struct sailfish_cell_info_wcdma *wcdma = &cell->info.wcdma;
|
||||
|
||||
memset(cell, 0, sizeof(*cell));
|
||||
cell->type = SAILFISH_CELL_TYPE_WCDMA;
|
||||
cell->registered = TRUE;
|
||||
wcdma->mcc = 250;
|
||||
wcdma->mnc = 99;
|
||||
wcdma->lac = 14760;
|
||||
wcdma->cid = 149331616;
|
||||
wcdma->psc = 371;
|
||||
wcdma->uarfcn = INT_MAX;
|
||||
wcdma->signalStrength = 4;
|
||||
wcdma->bitErrorRate = 99;
|
||||
return cell;
|
||||
}
|
||||
|
||||
static struct sailfish_cell *test_cell_init_wcdma2(struct sailfish_cell *cell)
|
||||
{
|
||||
struct sailfish_cell_info_wcdma *wcdma = &cell->info.wcdma;
|
||||
|
||||
memset(cell, 0, sizeof(*cell));
|
||||
cell->type = SAILFISH_CELL_TYPE_WCDMA;
|
||||
cell->registered = FALSE;
|
||||
wcdma->mcc = INT_MAX;
|
||||
wcdma->mnc = INT_MAX;
|
||||
wcdma->lac = INT_MAX;
|
||||
wcdma->cid = INT_MAX;
|
||||
wcdma->psc = INT_MAX;
|
||||
wcdma->uarfcn = INT_MAX;
|
||||
wcdma->signalStrength = 5;
|
||||
wcdma->bitErrorRate = 99;
|
||||
return cell;
|
||||
}
|
||||
|
||||
static struct sailfish_cell *test_cell_init_lte(struct sailfish_cell *cell)
|
||||
{
|
||||
struct sailfish_cell_info_lte *lte = &cell->info.lte;
|
||||
|
||||
memset(cell, 0, sizeof(*cell));
|
||||
cell->type = SAILFISH_CELL_TYPE_LTE;
|
||||
cell->registered = TRUE;
|
||||
lte->mcc = 244;
|
||||
lte->mnc = 91;
|
||||
lte->ci = 36591883;
|
||||
lte->pci = 309;
|
||||
lte->tac = 4030;
|
||||
lte->earfcn = INT_MAX;
|
||||
lte->signalStrength = 17;
|
||||
lte->rsrp = 106;
|
||||
lte->rsrq = 6;
|
||||
lte->rssnr = INT_MAX;
|
||||
lte->cqi = INT_MAX;
|
||||
lte->timingAdvance = INT_MAX;
|
||||
return cell;
|
||||
}
|
||||
|
||||
/* ==== Misc ==== */
|
||||
|
||||
static void test_misc(void)
|
||||
{
|
||||
struct ofono_modem modem;
|
||||
|
||||
modem.path = TEST_MODEM_PATH;
|
||||
|
||||
/* NULL resistance */
|
||||
g_assert(!sailfish_cell_info_dbus_new(NULL, NULL));
|
||||
g_assert(!sailfish_cell_info_dbus_new(&modem, NULL));
|
||||
sailfish_cell_info_dbus_free(NULL);
|
||||
|
||||
/* Calling __ofono_dbus_cleanup() without __ofono_dbus_init() is ok */
|
||||
__ofono_dbus_cleanup();
|
||||
}
|
||||
|
||||
/* ==== GetCells ==== */
|
||||
|
||||
struct test_get_cells_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info *info;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void test_get_cells_start_reply3(DBusPendingCall *call, void *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,
|
||||
CELL_INFO_DBUS_CELLS_REMOVED_SIGNAL);
|
||||
|
||||
DBG("");
|
||||
test_check_get_cells_reply(call, "/test/cell_1", NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Validate the signal */
|
||||
g_assert(signal);
|
||||
dbus_message_iter_init(signal, &it);
|
||||
test_check_object_path_array(&it, "/test/cell_0", NULL);
|
||||
dbus_message_unref(signal);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_get_cells_start_reply2(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_cells_data *test = data;
|
||||
const char *cell_added = "/test/cell_1";
|
||||
struct sailfish_cell cell;
|
||||
DBusMessageIter it;
|
||||
DBusMessage *signal = test_dbus_take_signal(&test->context,
|
||||
test->modem.path, CELL_INFO_DBUS_INTERFACE,
|
||||
CELL_INFO_DBUS_CELLS_ADDED_SIGNAL);
|
||||
|
||||
DBG("");
|
||||
test_check_get_cells_reply(call, "/test/cell_0", cell_added, NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Validate the signal */
|
||||
g_assert(signal);
|
||||
dbus_message_iter_init(signal, &it);
|
||||
test_check_object_path_array(&it, cell_added, NULL);
|
||||
dbus_message_unref(signal);
|
||||
|
||||
/* Remove "/test/cell_0" */
|
||||
g_assert(fake_cell_info_remove_cell(test->info,
|
||||
test_cell_init_gsm1(&cell)));
|
||||
fake_cell_info_cells_changed(test->info);
|
||||
test_get_cells_call(test, test_get_cells_start_reply3);
|
||||
}
|
||||
|
||||
static void test_get_cells_start_reply1(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_cells_data *test = data;
|
||||
struct sailfish_cell cell;
|
||||
|
||||
DBG("");
|
||||
test_check_get_cells_reply(call, "/test/cell_0", NULL);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
/* Add "/test/cell_1" */
|
||||
fake_cell_info_add_cell(test->info, test_cell_init_gsm2(&cell));
|
||||
fake_cell_info_cells_changed(test->info);
|
||||
test_get_cells_call(test, test_get_cells_start_reply2);
|
||||
}
|
||||
|
||||
static void test_get_cells_start(struct test_dbus_context *context)
|
||||
{
|
||||
struct sailfish_cell cell;
|
||||
struct test_get_cells_data *test =
|
||||
G_CAST(context, struct test_get_cells_data, context);
|
||||
|
||||
DBG("");
|
||||
test->info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(test->info, test_cell_init_gsm1(&cell));
|
||||
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, test->info);
|
||||
g_assert(test->dbus);
|
||||
|
||||
test_get_cells_call(test, test_get_cells_start_reply1);
|
||||
}
|
||||
|
||||
static void test_get_cells(void)
|
||||
{
|
||||
struct test_get_cells_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_cells_start;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_unref(test.info);
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== GetAll ==== */
|
||||
|
||||
struct test_get_all_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
struct sailfish_cell cell;
|
||||
const char *type;
|
||||
};
|
||||
|
||||
static void test_get_all_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_all_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);
|
||||
}
|
||||
|
||||
static void test_get_all_start(struct test_dbus_context *context)
|
||||
{
|
||||
struct sailfish_cell_info *info;
|
||||
struct test_get_all_data *test =
|
||||
G_CAST(context, struct test_get_all_data, context);
|
||||
|
||||
DBG("");
|
||||
info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(info, &test->cell);
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, info);
|
||||
g_assert(test->dbus);
|
||||
sailfish_cell_info_unref(info);
|
||||
|
||||
test_submit_get_all_call(context->client_connection, "/test/cell_0",
|
||||
test_get_all_reply, test);
|
||||
}
|
||||
|
||||
static void test_get_all(const struct sailfish_cell *cell, const char *type)
|
||||
{
|
||||
struct test_get_all_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_all_start;
|
||||
test.cell = *cell;
|
||||
test.type = type;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_get_all1(void)
|
||||
{
|
||||
struct sailfish_cell cell;
|
||||
|
||||
test_get_all(test_cell_init_gsm1(&cell), "gsm");
|
||||
}
|
||||
|
||||
static void test_get_all2(void)
|
||||
{
|
||||
struct sailfish_cell cell;
|
||||
|
||||
test_get_all(test_cell_init_wcdma2(&cell), "wcdma");
|
||||
}
|
||||
|
||||
static void test_get_all3(void)
|
||||
{
|
||||
struct sailfish_cell cell;
|
||||
|
||||
test_get_all(test_cell_init_lte(&cell), "lte");
|
||||
}
|
||||
|
||||
static void test_get_all4(void)
|
||||
{
|
||||
struct sailfish_cell cell;
|
||||
|
||||
/* Invalid cell */
|
||||
memset(&cell, 0xff, sizeof(cell));
|
||||
test_get_all(&cell, "unknown");
|
||||
}
|
||||
|
||||
/* ==== GetInterfaceVersion ==== */
|
||||
|
||||
struct test_get_version_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
};
|
||||
|
||||
static void test_get_version_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_version_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
dbus_int32_t version;
|
||||
|
||||
DBG("");
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
g_assert(dbus_message_get_args(reply, NULL,
|
||||
DBUS_TYPE_INT32, &version,
|
||||
DBUS_TYPE_INVALID));
|
||||
g_assert(version == CELL_DBUS_INTERFACE_VERSION);
|
||||
dbus_message_unref(reply);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_get_version_start(struct test_dbus_context *context)
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
DBusMessage *msg;
|
||||
struct sailfish_cell cell;
|
||||
struct sailfish_cell_info *info;
|
||||
struct test_get_version_data *test =
|
||||
G_CAST(context, struct test_get_version_data, context);
|
||||
|
||||
DBG("");
|
||||
info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(info, test_cell_init_gsm1(&cell));
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, info);
|
||||
g_assert(test->dbus);
|
||||
sailfish_cell_info_unref(info);
|
||||
|
||||
msg = test_new_cell_call("/test/cell_0", "GetInterfaceVersion");
|
||||
g_assert(dbus_connection_send_with_reply(context->client_connection,
|
||||
msg, &call, DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, test_get_version_reply, test, NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void test_get_version(void)
|
||||
{
|
||||
struct test_get_version_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_version_start;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== GetType ==== */
|
||||
|
||||
struct test_get_type_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
};
|
||||
|
||||
static void test_get_type_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_type_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
DBG("");
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
dbus_message_iter_init(reply, &it);
|
||||
g_assert(!g_strcmp0(test_dbus_get_string(&it), "wcdma"));
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(reply);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_get_type_start(struct test_dbus_context *context)
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
DBusMessage *msg;
|
||||
struct sailfish_cell cell;
|
||||
struct sailfish_cell_info *info;
|
||||
struct test_get_type_data *test =
|
||||
G_CAST(context, struct test_get_type_data, context);
|
||||
|
||||
DBG("");
|
||||
info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(info, test_cell_init_wcdma1(&cell));
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, info);
|
||||
g_assert(test->dbus);
|
||||
sailfish_cell_info_unref(info);
|
||||
|
||||
msg = test_new_cell_call("/test/cell_0", "GetType");
|
||||
g_assert(dbus_connection_send_with_reply(context->client_connection,
|
||||
msg, &call, DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, test_get_type_reply, test, NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void test_get_type(void)
|
||||
{
|
||||
struct test_get_type_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_type_start;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== GetRegistered ==== */
|
||||
|
||||
struct test_get_registered_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
};
|
||||
|
||||
static void test_get_registered_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_registered_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it;
|
||||
|
||||
DBG("");
|
||||
g_assert(dbus_message_get_type(reply) ==
|
||||
DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
dbus_message_iter_init(reply, &it);
|
||||
g_assert(test_dbus_get_bool(&it) == TRUE);
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(reply);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_get_registered_start(struct test_dbus_context *context)
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
DBusMessage *msg;
|
||||
struct sailfish_cell cell;
|
||||
struct sailfish_cell_info *info;
|
||||
struct test_get_registered_data *test =
|
||||
G_CAST(context, struct test_get_registered_data, context);
|
||||
|
||||
DBG("");
|
||||
info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(info, test_cell_init_wcdma1(&cell));
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, info);
|
||||
g_assert(test->dbus);
|
||||
sailfish_cell_info_unref(info);
|
||||
|
||||
msg = test_new_cell_call("/test/cell_0", "GetRegistered");
|
||||
g_assert(dbus_connection_send_with_reply(context->client_connection,
|
||||
msg, &call, DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, test_get_registered_reply, test,
|
||||
NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void test_get_registered(void)
|
||||
{
|
||||
struct test_get_registered_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_registered_start;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== GetProperties ==== */
|
||||
|
||||
struct test_get_properties_data {
|
||||
struct ofono_modem modem;
|
||||
struct test_dbus_context context;
|
||||
struct sailfish_cell_info_dbus *dbus;
|
||||
};
|
||||
|
||||
static void test_get_properties_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_get_properties_data *test = data;
|
||||
DBusMessage *reply = dbus_pending_call_steal_reply(call);
|
||||
DBusMessageIter it, array;
|
||||
|
||||
DBG("");
|
||||
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_ARRAY);
|
||||
dbus_message_iter_recurse(&it, &array);
|
||||
dbus_message_iter_next(&it);
|
||||
/* Validate the properties? */
|
||||
g_assert(dbus_message_iter_get_arg_type(&it) == DBUS_TYPE_INVALID);
|
||||
dbus_message_unref(reply);
|
||||
dbus_pending_call_unref(call);
|
||||
|
||||
test_loop_quit_later(test->context.loop);
|
||||
}
|
||||
|
||||
static void test_get_properties_start(struct test_dbus_context *context)
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
DBusMessage *msg;
|
||||
struct sailfish_cell cell;
|
||||
struct sailfish_cell_info *info;
|
||||
struct test_get_properties_data *test =
|
||||
G_CAST(context, struct test_get_properties_data, context);
|
||||
|
||||
DBG("");
|
||||
info = fake_cell_info_new();
|
||||
fake_cell_info_add_cell(info, test_cell_init_wcdma2(&cell));
|
||||
test->dbus = sailfish_cell_info_dbus_new(&test->modem, info);
|
||||
g_assert(test->dbus);
|
||||
sailfish_cell_info_unref(info);
|
||||
|
||||
msg = test_new_cell_call("/test/cell_0", "GetProperties");
|
||||
g_assert(dbus_connection_send_with_reply(context->client_connection,
|
||||
msg, &call, DBUS_TIMEOUT_INFINITE));
|
||||
dbus_pending_call_set_notify(call, test_get_properties_reply, test,
|
||||
NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static void test_get_properties(void)
|
||||
{
|
||||
struct test_get_properties_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_get_properties_start;
|
||||
test_dbus_setup(&test.context);
|
||||
|
||||
g_main_loop_run(test.context.loop);
|
||||
|
||||
sailfish_cell_info_dbus_free(test.dbus);
|
||||
test_dbus_shutdown(&test.context);
|
||||
if (timeout) {
|
||||
g_source_remove(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== RegisteredChanged ==== */
|
||||
|
||||
struct test_registered_changed_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_registered_changed_reply(DBusPendingCall *call, void *data)
|
||||
{
|
||||
struct test_registered_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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
/* Trigger "RegisteredChanged" signal */
|
||||
first_cell = test->info->cells->data;
|
||||
test->cell.registered =
|
||||
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);
|
||||
}
|
||||
|
||||
static void test_registered_changed(void)
|
||||
{
|
||||
struct test_registered_changed_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_registered_changed_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 "RegisteredChanged" signal */
|
||||
g_assert(test_dbus_find_signal(&test.context, test.cell_path,
|
||||
CELL_DBUS_INTERFACE, CELL_DBUS_REGISTERED_CHANGED_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);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== PropertyChanged ==== */
|
||||
|
||||
struct test_property_changed_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_property_changed_reply1(DBusPendingCall *call, void *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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
/* Trigger "PropertyChanged" signal */
|
||||
first_cell = test->info->cells->data;
|
||||
test->cell.info.gsm.signalStrength =
|
||||
(++(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);
|
||||
}
|
||||
|
||||
static void test_property_changed(void)
|
||||
{
|
||||
struct test_property_changed_data test;
|
||||
guint timeout = test_setup_timeout();
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
test.modem.path = TEST_MODEM_PATH;
|
||||
test.context.start = test_property_changed_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 "PropertyChanged" signal */
|
||||
g_assert(test_dbus_find_signal(&test.context, test.cell_path,
|
||||
CELL_DBUS_INTERFACE, CELL_DBUS_PROPERTY_CHANGED_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[])
|
||||
{
|
||||
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-sailfish_cell_info_dbus",
|
||||
g_test_verbose() ? "*" : NULL,
|
||||
FALSE, FALSE);
|
||||
|
||||
g_test_add_func(TEST_("Misc"), test_misc);
|
||||
g_test_add_func(TEST_("GetCells"), test_get_cells);
|
||||
g_test_add_func(TEST_("GetAll1"), test_get_all1);
|
||||
g_test_add_func(TEST_("GetAll2"), test_get_all2);
|
||||
g_test_add_func(TEST_("GetAll3"), test_get_all3);
|
||||
g_test_add_func(TEST_("GetAll4"), test_get_all4);
|
||||
g_test_add_func(TEST_("GetInterfaceVersion"), test_get_version);
|
||||
g_test_add_func(TEST_("GetType"), test_get_type);
|
||||
g_test_add_func(TEST_("GetRegistered"), test_get_registered);
|
||||
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);
|
||||
|
||||
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) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -919,9 +919,11 @@ static gboolean test_voice_sim_done(gpointer user_data)
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
|
||||
/* Remove the SIM */
|
||||
fake_sailfish_watch_set_ofono_sim(w, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(w, NULL);
|
||||
sailfish_manager_set_sim_state(s->handle, SAILFISH_SIM_STATE_ABSENT);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
g_assert(!m->slots[0]->sim_present);
|
||||
g_assert(!g_strcmp0(m->default_voice_imsi, TEST_IMSI));
|
||||
g_assert(!m->default_voice_path);
|
||||
@@ -1240,6 +1242,24 @@ static gboolean test_multisim_done(gpointer user_data)
|
||||
g_assert(!m->default_data_imsi);
|
||||
g_assert(!m->default_data_path);
|
||||
|
||||
/* But there is automatic voice SIM selection */
|
||||
g_assert(!m->default_voice_imsi);
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
|
||||
/* Switch the voice SIM back and forth */
|
||||
fake_sailfish_manager_dbus.cb.set_default_voice_imsi(m, TEST_IMSI);
|
||||
g_assert(!g_strcmp0(m->default_voice_imsi, TEST_IMSI));
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH));
|
||||
|
||||
fake_sailfish_manager_dbus.cb.set_default_voice_imsi(m, TEST_IMSI_1);
|
||||
g_assert(!g_strcmp0(m->default_voice_imsi, TEST_IMSI_1));
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH_1));
|
||||
|
||||
/* test_1 remains the current voice slot */
|
||||
fake_sailfish_manager_dbus.cb.set_default_voice_imsi(m, NULL);
|
||||
g_assert(!m->default_voice_imsi);
|
||||
g_assert(!g_strcmp0(m->default_voice_path, TEST_PATH_1));
|
||||
|
||||
/* Reserve the first slot for data */
|
||||
fake_sailfish_manager_dbus.cb.set_default_data_imsi(m, TEST_IMSI);
|
||||
g_assert(s->data_role == SAILFISH_DATA_ROLE_INTERNET);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2017 Jolla Ltd.
|
||||
* Copyright (C) 2017-2018 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
|
||||
@@ -182,7 +182,6 @@ static void test_basic(void)
|
||||
g_assert(!sailfish_sim_info_new(NULL));
|
||||
g_assert(!sailfish_sim_info_ref(NULL));
|
||||
sailfish_sim_info_unref(NULL);
|
||||
sailfish_sim_info_invalidate(NULL);
|
||||
g_assert(!sailfish_sim_info_add_iccid_changed_handler(NULL,NULL,NULL));
|
||||
g_assert(!sailfish_sim_info_add_imsi_changed_handler(NULL,NULL,NULL));
|
||||
g_assert(!sailfish_sim_info_add_spn_changed_handler(NULL,NULL,NULL));
|
||||
@@ -192,7 +191,6 @@ static void test_basic(void)
|
||||
/* Very basic things (mostly to improve code coverage) */
|
||||
si = sailfish_sim_info_new("/test");
|
||||
g_assert(si);
|
||||
sailfish_sim_info_invalidate(si);
|
||||
g_assert(!sailfish_sim_info_add_iccid_changed_handler(si,NULL,NULL));
|
||||
g_assert(!sailfish_sim_info_add_imsi_changed_handler(si,NULL,NULL));
|
||||
g_assert(!sailfish_sim_info_add_spn_changed_handler(si,NULL,NULL));
|
||||
@@ -241,6 +239,9 @@ static void test_cache(void)
|
||||
g_assert(!count[SIM_INFO_SIGNAL_ICCID_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_IMSI_CHANGED]);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
g_assert(!si->iccid);
|
||||
g_assert(!si->imsi);
|
||||
g_assert(!si->spn);
|
||||
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
@@ -258,7 +259,7 @@ static void test_cache(void)
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
g_assert(count[SIM_INFO_SIGNAL_IMSI_CHANGED] == 1);
|
||||
count[SIM_INFO_SIGNAL_IMSI_CHANGED] = 0;
|
||||
/* ICCID mape appears */
|
||||
/* ICCID map appears */
|
||||
g_assert(stat(ICCID_MAP, &st) == 0);
|
||||
g_assert(S_ISREG(st.st_mode));
|
||||
/* But no cache yet */
|
||||
@@ -268,6 +269,7 @@ static void test_cache(void)
|
||||
sim.mcc = TEST_MCC;
|
||||
sim.mnc = TEST_MNC;
|
||||
sim.state = OFONO_SIM_STATE_READY;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
g_assert(!g_strcmp0(si->spn, TEST_DEFAULT_SPN));
|
||||
@@ -290,6 +292,7 @@ static void test_cache(void)
|
||||
sim.mcc = NULL;
|
||||
sim.mnc = NULL;
|
||||
sim.state = OFONO_SIM_STATE_NOT_PRESENT;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, NULL);
|
||||
@@ -298,12 +301,16 @@ static void test_cache(void)
|
||||
g_assert(count[SIM_INFO_SIGNAL_ICCID_CHANGED] == 1);
|
||||
g_assert(count[SIM_INFO_SIGNAL_IMSI_CHANGED] == 1);
|
||||
g_assert(count[SIM_INFO_SIGNAL_SPN_CHANGED] == 1);
|
||||
g_assert(!si->iccid);
|
||||
g_assert(!si->imsi);
|
||||
g_assert(!si->spn);
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
/* Set ICCID again, that will load the cached information */
|
||||
sim.mcc = NULL;
|
||||
sim.mnc = NULL;
|
||||
sim.state = OFONO_SIM_STATE_INSERTED;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_ICCID_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, TEST_ICCID);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
@@ -315,12 +322,18 @@ static void test_cache(void)
|
||||
g_assert(count[SIM_INFO_SIGNAL_SPN_CHANGED] == 1);
|
||||
memset(count, 0, sizeof(count));
|
||||
|
||||
/* Make sure that removed handler doesn't get invoked */
|
||||
sailfish_sim_info_remove_handler(si, id[SIM_INFO_SIGNAL_SPN_CHANGED]);
|
||||
id[SIM_INFO_SIGNAL_SPN_CHANGED] = 0;
|
||||
sailfish_sim_info_invalidate(si);
|
||||
g_assert(!si->iccid);
|
||||
g_assert(!si->imsi);
|
||||
g_assert(!si->iccid);
|
||||
sim.mcc = NULL;
|
||||
sim.mnc = NULL;
|
||||
sim.state = OFONO_SIM_STATE_NOT_PRESENT;
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_IMSI_CHANGED);
|
||||
fake_sailfish_watch_signal_queue(w, WATCH_SIGNAL_SIM_STATE_CHANGED);
|
||||
fake_sailfish_watch_set_ofono_iccid(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_imsi(w, NULL);
|
||||
fake_sailfish_watch_set_ofono_spn(w, NULL);
|
||||
fake_sailfish_watch_emit_queued_signals(w);
|
||||
g_assert(count[SIM_INFO_SIGNAL_ICCID_CHANGED] == 1);
|
||||
g_assert(count[SIM_INFO_SIGNAL_IMSI_CHANGED] == 1);
|
||||
g_assert(!count[SIM_INFO_SIGNAL_SPN_CHANGED]); /* removed ^ */
|
||||
|
||||
@@ -17,6 +17,7 @@ Requires(preun): systemd
|
||||
Requires(post): systemd
|
||||
Requires(postun): systemd
|
||||
BuildRequires: pkgconfig(dbus-1)
|
||||
BuildRequires: pkgconfig(dbus-glib-1)
|
||||
BuildRequires: pkgconfig(glib-2.0)
|
||||
BuildRequires: pkgconfig(libudev) >= 145
|
||||
BuildRequires: pkgconfig(libwspcodec) >= 2.0
|
||||
|
||||
Reference in New Issue
Block a user