Compare commits

...

18 Commits

Author SHA1 Message Date
Slava Monich
5ec6b8e7ec [test] Improve sailfish_manager.c test coverage 2018-01-04 12:09:34 +02:00
Slava Monich
f94681f6f6 Merge branch 'iccid_watch' into 'master'
Properly reset cached SIM info after removal

See merge request !162
2018-01-04 10:08:35 +00:00
Slava Monich
de8edc84fa [ofono] Properly reset cached SIM info after removal. Fixes JB#39810
sailfish_watch expected to be notified by ofono of every ICCID or IMSI
change, however it wasn't happening when SIM card was getting removed.
That messed things up.
2018-01-03 16:45:39 +02:00
Slava Monich
90faf1b3a5 Merge branch 'fac_timeout' into 'master'
Make sure SIM_IO and QUERY_FACILITY_LOCK requests get completed

See merge request !161
2018-01-02 09:40:11 +00:00
Slava Monich
2b139b6974 [ril] Make sure SIM_IO and QUERY_FACILITY_LOCK get completed
ofono becomes very unhappy if they don't. Also, completion
is required in order to eventually reset SIM I/O active flag.
If doesn't make sense to keep it on forever.
2017-12-25 18:23:57 +02:00
Slava Monich
168f193efb Merge branch 'refresh' into 'master'
Handle SIM reset

See merge request !160
2017-12-08 21:09:15 +00:00
Slava Monich
32d8b5ccfc sim: Don't submit parallel EFpl reads
In addition to not doing unnecessary SIM I/O, this fixes memory leaks
like this one:

==10096== 74 (56 direct, 18 indirect) bytes in 2 blocks are definitely lost in loss record 1,252 of 1,342
==10096==    at 0x4841BF0: calloc (vg_replace_malloc.c)
==10096==    by 0x4B03117: g_malloc0 (gmem.c)
==10096==    by 0xF83DF: concat_lang_prefs (sim.c)
==10096==    by 0xF8697: sim_efpl_read_cb (sim.c)
==10096==    by 0x12CBF7: sim_fs_op_read_block_cb (simfs.c)
2017-12-09 00:06:26 +03:00
Slava Monich
f400ceff80 Merge branch 'sms-filter-api-version' into 'master'
sms-filter: Add api_version field

See merge request !159
2017-12-08 12:37:05 +00:00
Slava Monich
2186c60630 [ril] Handle SIM reset. Fixes JB#40010
This happens when we receive a proactive Refresh command from SIM Tookit
which is generated by some SIMs when people are moving between home and
roaming networks.
2017-12-08 15:26:44 +03:00
Slava Monich
d5fb195e2f [ofono] sms-filter: Added api_version field. JB#37478
This makes it possible to keep using old plugins even if
struct ofono_sms_filter gets extended with new callbacks.
2017-12-08 15:22:16 +03:00
Slava Monich
cbb08079d2 [ril] Housekeeping
Removed some unused stuff
2017-12-07 17:23:22 +03:00
Slava Monich
0583a831fb Merge branch 'sfos_bt_crash' into 'master'
Handle multiple EMULATOR_HFP atoms

See merge request !158
2017-12-01 15:02:32 +00:00
Slava Monich
a8a0758e90 [sailfish_bt] Handle multiple EMULATOR_HFP atoms. Fixes JB#40530
It appears that in some rare cases a new (second) instance can be
created before the old one is destroyed. This was causing a crash.
2017-12-01 16:44:57 +02:00
Slava Monich
9e267487f4 Merge branch 'devel' into 'master'
Add more stuff to ofono devel package

See merge request !157
2017-11-27 20:15:16 +00:00
Slava Monich
c8a774dfee [ofono] Add gdbus.h to the devel package. JB#37478
External (dynamically loadable) plugins need it.
2017-11-27 21:53:25 +02:00
Slava Monich
b88518d0f3 [ofono] Adapt Sailfish OS plugins to newly introduced <ofono/storage.h> 2017-11-27 21:53:25 +02:00
Slava Monich
b223ccc675 storage: Implement ofono_config_dir and ofono_storage_dir 2017-11-27 21:53:25 +02:00
Slava Monich
947a41a5fc include: Add storage.h
To expose ofono directories to dynamically loadable plugins.

Conflicts:
	ofono/Makefile.am
2017-11-27 21:53:25 +02:00
15 changed files with 343 additions and 141 deletions

View File

@@ -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
@@ -1163,6 +1165,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) $< $@

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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);

View File

@@ -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
View 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 */

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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,

View File

@@ -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. */

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 ^ */