Compare commits

...

5 Commits

Author SHA1 Message Date
Slava Monich
a78b7818e9 [ril] Don't auto-select the data sim on a multisim phone. JB#38719
This kind of behavior is reserved for single sim phone (for now).
2017-05-31 11:04:49 +03:00
Slava Monich
d00b999cf6 [ril] Allow (some) DEVICE_IDENTITY requests to time out. Fixes JB#38632
If GET_SIM_STATUS succeeds but DEVICE_IDENTITY keeps on failing,
allow the latter to time out. Some RILs behave that way until the
modem has been properly initialized.

Conflicts:
	ofono/drivers/ril/ril_plugin.c
2017-05-13 00:22:50 +03:00
Slava Monich
476243be6a [ril] Use DEVICE_IDENTITY request instead of GET_IMEI. Contributes to JB#38632
RIL_REQUEST_GET_IMEI has been deprecated since 2009
2017-05-13 00:21:05 +03:00
Slava Monich
adca340f4b [simfs] Prevent a crash in sim_fs_notify_file_watches. Fixes JB#38656
If no file watchers have ever been added, context->file_watches
is NULL and sim_fs_notify_file_watches() should take that into
account.
2017-05-12 23:39:37 +03:00
Slava Monich
709bb7e596 [ril] Always refresh SIM status from query_passwd_state. Fixes JB#38257
After we have entered an invalid pin too many times, RIL signals
the SIM status change, we request the new status but ofono core
asks us for the new passwd state before our SIM status query has
completed. We need to wait for the query to complete before we can
report the new status to the core.

It also won't hurt if we request a fresh SIM status every time
when query_passwd_state callback is called, just in case if RIL
fails to notify us about the SIM status change.
2017-04-27 11:18:46 +03:00
9 changed files with 270 additions and 117 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* oFono - Open Source Telephony - RIL-based devices * oFono - Open Source Telephony - RIL-based devices
* *
* Copyright (C) 2015-2016 Jolla Ltd. * Copyright (C) 2015-2017 Jolla Ltd.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@@ -17,16 +17,24 @@
#include "ril_util.h" #include "ril_util.h"
#include "ril_log.h" #include "ril_log.h"
#include <gutil_idlequeue.h>
/* /*
* TODO: No public RIL api to query manufacturer or model. * TODO: No public RIL api to query manufacturer or model.
* Check where to get, could /system/build.prop be updated to have good values? * Check where to get, could /system/build.prop be updated to have good values?
*/ */
enum ril_devinfo_cb_tag {
DEVINFO_QUERY_SERIAL = 1,
DEVINFO_QUERY_SVN
};
struct ril_devinfo { struct ril_devinfo {
struct ofono_devinfo *info; struct ofono_devinfo *info;
GRilIoQueue *q; GRilIoQueue *q;
guint register_id; GUtilIdleQueue *iq;
guint imei_id; char *log_prefix;
char *imeisv;
char *imei; char *imei;
}; };
@@ -36,6 +44,7 @@ struct ril_devinfo_cbd {
gpointer data; gpointer data;
}; };
#define DBG_(self,fmt,args...) DBG("%s" fmt, (self)->log_prefix, ##args)
#define ril_devinfo_cbd_free g_free #define ril_devinfo_cbd_free g_free
static inline struct ril_devinfo *ril_devinfo_get_data( static inline struct ril_devinfo *ril_devinfo_get_data(
@@ -62,7 +71,7 @@ static void ril_devinfo_query_unsupported(struct ofono_devinfo *info,
cb(ril_error_failure(&error), "", data); cb(ril_error_failure(&error), "", data);
} }
static void ril_devinfo_query_cb(GRilIoChannel *io, int status, static void ril_devinfo_query_revision_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data) const void *data, guint len, void *user_data)
{ {
struct ofono_error error; struct ofono_error error;
@@ -73,7 +82,7 @@ static void ril_devinfo_query_cb(GRilIoChannel *io, int status,
GRilIoParser rilp; GRilIoParser rilp;
grilio_parser_init(&rilp, data, len); grilio_parser_init(&rilp, data, len);
res = grilio_parser_get_utf8(&rilp); res = grilio_parser_get_utf8(&rilp);
DBG("%s", res); DBG_(cbd->di, "%s", res);
cbd->cb(ril_error_ok(&error), res ? res : "", cbd->data); cbd->cb(ril_error_ok(&error), res ? res : "", cbd->data);
g_free(res); g_free(res);
} else { } else {
@@ -86,23 +95,46 @@ static void ril_devinfo_query_revision(struct ofono_devinfo *info,
{ {
struct ril_devinfo *di = ril_devinfo_get_data(info); struct ril_devinfo *di = ril_devinfo_get_data(info);
DBG(""); DBG_(di, "");
grilio_queue_send_request_full(di->q, NULL, RIL_REQUEST_BASEBAND_VERSION, grilio_queue_send_request_full(di->q, NULL,
ril_devinfo_query_cb, ril_devinfo_cbd_free, RIL_REQUEST_BASEBAND_VERSION,
ril_devinfo_query_revision_cb,
ril_devinfo_cbd_free,
ril_devinfo_cbd_new(di, cb, data)); ril_devinfo_cbd_new(di, cb, data));
} }
static gboolean ril_devinfo_query_serial_cb(void *user_data) static void ril_devinfo_query_serial_cb(gpointer user_data)
{ {
struct ril_devinfo_cbd *cbd = user_data; struct ril_devinfo_cbd *cbd = user_data;
struct ril_devinfo *di = cbd->di; struct ril_devinfo *di = cbd->di;
struct ofono_error error; struct ofono_error error;
GASSERT(di->imei_id); DBG_(di, "%s", di->imei);
di->imei_id = 0;
cbd->cb(ril_error_ok(&error), di->imei, cbd->data); cbd->cb(ril_error_ok(&error), di->imei, cbd->data);
return FALSE; }
static void ril_devinfo_query_svn_cb(gpointer user_data)
{
struct ril_devinfo_cbd *cbd = user_data;
struct ril_devinfo *di = cbd->di;
struct ofono_error error;
DBG_(di, "%s", di->imeisv);
if (di->imeisv && di->imeisv[0]) {
cbd->cb(ril_error_ok(&error), di->imeisv, cbd->data);
} else {
cbd->cb(ril_error_failure(&error), "", cbd->data);
}
}
static void ril_devinfo_query(struct ril_devinfo *di,
enum ril_devinfo_cb_tag tag, GUtilIdleFunc fn,
ofono_devinfo_query_cb_t cb, void *data)
{
GVERIFY_FALSE(gutil_idle_queue_cancel_tag(di->iq, tag));
gutil_idle_queue_add_tag_full(di->iq, tag, fn,
ril_devinfo_cbd_new(di, cb, data),
ril_devinfo_cbd_free);
} }
static void ril_devinfo_query_serial(struct ofono_devinfo *info, static void ril_devinfo_query_serial(struct ofono_devinfo *info,
@@ -111,29 +143,28 @@ static void ril_devinfo_query_serial(struct ofono_devinfo *info,
{ {
struct ril_devinfo *di = ril_devinfo_get_data(info); struct ril_devinfo *di = ril_devinfo_get_data(info);
GASSERT(!di->imei_id); DBG_(di, "");
if (di->imei_id) { ril_devinfo_query(di, DEVINFO_QUERY_SERIAL,
g_source_remove(di->imei_id); ril_devinfo_query_serial_cb, cb, data);
di->imei_id = 0;
}
DBG("%s", di->imei);
di->imei_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
ril_devinfo_query_serial_cb,
ril_devinfo_cbd_new(di, cb, data),
ril_devinfo_cbd_free);
} }
static gboolean ril_devinfo_register(gpointer user_data) static void ril_devinfo_query_svn(struct ofono_devinfo *info,
ofono_devinfo_query_cb_t cb,
void *data)
{
struct ril_devinfo *di = ril_devinfo_get_data(info);
DBG_(di, "");
ril_devinfo_query(di, DEVINFO_QUERY_SVN,
ril_devinfo_query_svn_cb, cb, data);
}
static void ril_devinfo_register(gpointer user_data)
{ {
struct ril_devinfo *di = user_data; struct ril_devinfo *di = user_data;
DBG(""); DBG_(di, "");
di->register_id = 0;
ofono_devinfo_register(di->info); ofono_devinfo_register(di->info);
/* This makes the timeout a single-shot */
return FALSE;
} }
static int ril_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor, static int ril_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor,
@@ -142,13 +173,18 @@ static int ril_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor,
struct ril_modem *modem = data; struct ril_modem *modem = data;
struct ril_devinfo *di = g_new0(struct ril_devinfo, 1); struct ril_devinfo *di = g_new0(struct ril_devinfo, 1);
DBG("%s %s %p", ril_modem_get_path(modem), modem->imei, di); di->log_prefix = (modem->log_prefix && modem->log_prefix[0]) ?
g_strconcat(modem->log_prefix, " ", NULL) : g_strdup("");
DBG_(di, "%s", modem->imei);
GASSERT(modem->imei); GASSERT(modem->imei);
di->q = grilio_queue_new(ril_modem_io(modem)); di->q = grilio_queue_new(ril_modem_io(modem));
di->info = info; di->info = info;
di->imeisv = g_strdup(modem->imeisv);
di->imei = g_strdup(modem->imei); di->imei = g_strdup(modem->imei);
di->iq = gutil_idle_queue_new();
di->register_id = g_idle_add(ril_devinfo_register, di); gutil_idle_queue_add(di->iq, ril_devinfo_register, di);
ofono_devinfo_set_data(info, di); ofono_devinfo_set_data(info, di);
return 0; return 0;
} }
@@ -157,19 +193,14 @@ static void ril_devinfo_remove(struct ofono_devinfo *info)
{ {
struct ril_devinfo *di = ril_devinfo_get_data(info); struct ril_devinfo *di = ril_devinfo_get_data(info);
DBG("%p", di); DBG_(di, "");
ofono_devinfo_set_data(info, NULL); ofono_devinfo_set_data(info, NULL);
gutil_idle_queue_cancel_all(di->iq);
if (di->register_id > 0) { gutil_idle_queue_unref(di->iq);
g_source_remove(di->register_id);
}
if (di->imei_id > 0) {
g_source_remove(di->imei_id);
}
grilio_queue_cancel_all(di->q, FALSE); grilio_queue_cancel_all(di->q, FALSE);
grilio_queue_unref(di->q); grilio_queue_unref(di->q);
g_free(di->log_prefix);
g_free(di->imeisv);
g_free(di->imei); g_free(di->imei);
g_free(di); g_free(di);
} }
@@ -178,10 +209,11 @@ const struct ofono_devinfo_driver ril_devinfo_driver = {
.name = RILMODEM_DRIVER, .name = RILMODEM_DRIVER,
.probe = ril_devinfo_probe, .probe = ril_devinfo_probe,
.remove = ril_devinfo_remove, .remove = ril_devinfo_remove,
.query_manufacturer = ril_devinfo_query_unsupported, /* query_revision won't be called if query_model is missing */
.query_model = ril_devinfo_query_unsupported, .query_model = ril_devinfo_query_unsupported,
.query_revision = ril_devinfo_query_revision, .query_revision = ril_devinfo_query_revision,
.query_serial = ril_devinfo_query_serial .query_serial = ril_devinfo_query_serial,
.query_svn = ril_devinfo_query_svn
}; };
/* /*

View File

@@ -1,7 +1,7 @@
/* /*
* oFono - Open Source Telephony - RIL-based devices * oFono - Open Source Telephony - RIL-based devices
* *
* Copyright (C) 2015-2016 Jolla Ltd. * Copyright (C) 2015-2017 Jolla Ltd.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@@ -52,6 +52,7 @@ struct ril_modem_data {
struct ril_modem modem; struct ril_modem modem;
GRilIoQueue *q; GRilIoQueue *q;
char *log_prefix; char *log_prefix;
char *imeisv;
char *imei; char *imei;
char *ecclist_file; char *ecclist_file;
gboolean pre_sim_done; gboolean pre_sim_done;
@@ -433,6 +434,7 @@ static void ril_modem_remove(struct ofono_modem *ofono)
grilio_queue_unref(md->q); grilio_queue_unref(md->q);
g_free(md->ecclist_file); g_free(md->ecclist_file);
g_free(md->log_prefix); g_free(md->log_prefix);
g_free(md->imeisv);
g_free(md->imei); g_free(md->imei);
g_free(md); g_free(md);
} }
@@ -460,6 +462,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
/* Copy config */ /* Copy config */
modem->config = *slot->config; modem->config = *slot->config;
modem->imei = md->imei = g_strdup(slot->imei); modem->imei = md->imei = g_strdup(slot->imei);
modem->imeisv = md->imeisv = g_strdup(slot->imeisv);
modem->log_prefix = log_prefix; modem->log_prefix = log_prefix;
modem->ecclist_file = modem->ecclist_file =
md->ecclist_file = g_strdup(slot->ecclist_file); md->ecclist_file = g_strdup(slot->ecclist_file);

View File

@@ -41,6 +41,8 @@
#include "ofono.h" #include "ofono.h"
#include "storage.h" #include "storage.h"
#define RIL_DEVICE_IDENTITY_RETRIES_LAST 2
#define RADIO_GID 1001 #define RADIO_GID 1001
#define RADIO_UID 1001 #define RADIO_UID 1001
#define RIL_SUB_SIZE 4 #define RIL_SUB_SIZE 4
@@ -130,6 +132,7 @@ struct ril_slot {
struct ril_slot_info pub; struct ril_slot_info pub;
char *path; char *path;
char *imei; char *imei;
char *imeisv;
char *name; char *name;
char *sockpath; char *sockpath;
char *sub; char *sub;
@@ -157,6 +160,7 @@ struct ril_slot {
gulong io_event_id[IO_EVENT_COUNT]; gulong io_event_id[IO_EVENT_COUNT];
gulong imei_req_id; gulong imei_req_id;
gulong sim_card_state_event_id; gulong sim_card_state_event_id;
gboolean received_sim_status;
guint trace_id; guint trace_id;
guint dump_id; guint dump_id;
guint retry_id; guint retry_id;
@@ -175,6 +179,7 @@ static void ril_debug_grilio_notify(struct ofono_debug_desc *desc);
static void ril_debug_mce_notify(struct ofono_debug_desc *desc); static void ril_debug_mce_notify(struct ofono_debug_desc *desc);
static void ril_plugin_debug_notify(struct ofono_debug_desc *desc); static void ril_plugin_debug_notify(struct ofono_debug_desc *desc);
static void ril_plugin_retry_init_io(struct ril_slot *slot); static void ril_plugin_retry_init_io(struct ril_slot *slot);
static void ril_plugin_check_modem(struct ril_slot *slot);
GLOG_MODULE_DEFINE("rilmodem"); GLOG_MODULE_DEFINE("rilmodem");
@@ -247,7 +252,7 @@ static void ril_plugin_foreach_slot(struct ril_plugin_priv *plugin,
static void ril_plugin_send_screen_state(struct ril_slot *slot) static void ril_plugin_send_screen_state(struct ril_slot *slot)
{ {
if (slot->io) { if (slot->io && slot->io->connected) {
GRilIoRequest *req = grilio_request_sized_new(8); GRilIoRequest *req = grilio_request_sized_new(8);
grilio_request_append_int32(req, 1); /* Number of params */ grilio_request_append_int32(req, 1); /* Number of params */
grilio_request_append_int32(req, slot->plugin->display_on); grilio_request_append_int32(req, slot->plugin->display_on);
@@ -353,6 +358,7 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
ril_sim_card_unref(slot->sim_card); ril_sim_card_unref(slot->sim_card);
slot->sim_card_state_event_id = 0; slot->sim_card_state_event_id = 0;
slot->sim_card = NULL; slot->sim_card = NULL;
slot->received_sim_status = FALSE;
} }
if (slot->io) { if (slot->io) {
@@ -484,14 +490,23 @@ static int ril_plugin_update_modem_paths(struct ril_plugin_priv *plugin)
if (plugin->default_data_imsi) { if (plugin->default_data_imsi) {
slot = ril_plugin_find_slot_imsi(plugin->slots, slot = ril_plugin_find_slot_imsi(plugin->slots,
plugin->default_data_imsi); plugin->default_data_imsi);
} else if (plugin->data_slot) { } else if (!ril_plugin_multisim(plugin)) {
/* Make sure that the slot is enabled and SIM is in */ if (plugin->data_slot) {
slot = ril_plugin_find_slot_imsi(plugin->slots, /* Make sure that the slot is enabled and SIM is in */
slot = ril_plugin_find_slot_imsi(plugin->slots,
plugin->data_slot->modem ? plugin->data_slot->modem ?
ofono_sim_get_imsi(plugin->data_slot->sim) : ofono_sim_get_imsi(plugin->data_slot->sim) :
NULL); NULL);
} else {
/* Check if anything is available */
slot = ril_plugin_find_slot_imsi(plugin->slots, NULL);
}
} else { } else {
slot = ril_plugin_find_slot_imsi(plugin->slots, NULL); /*
* Should we automatically select the default data sim
* on a multisim phone that has only one sim inserted?
*/
slot = NULL;
} }
if (slot && !slot->radio->online) { if (slot && !slot->radio->online) {
@@ -583,14 +598,79 @@ static void ril_plugin_update_ready(struct ril_plugin_priv *plugin)
} }
} }
static void ril_plugin_device_identity_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ril_slot *slot = user_data;
char *imei = NULL;
char *imeisv = NULL;
GASSERT(slot->imei_req_id);
slot->imei_req_id = 0;
if (status == RIL_E_SUCCESS) {
GRilIoParser rilp;
guint32 n;
/*
* RIL_REQUEST_DEVICE_IDENTITY
*
* "response" is const char **
* ((const char **)response)[0] is IMEI (for GSM)
* ((const char **)response)[1] is IMEISV (for GSM)
* ((const char **)response)[2] is ESN (for CDMA)
* ((const char **)response)[3] is MEID (for CDMA)
*/
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_uint32(&rilp, &n) && n >= 2) {
imei = grilio_parser_get_utf8(&rilp);
imeisv = grilio_parser_get_utf8(&rilp);
DBG("%s %s", imei, imeisv);
} else {
DBG("parsing failure!");
}
/*
* slot->imei should be either NULL (when we get connected
* to rild the very first time) or match the already known
* IMEI (if rild crashed and we have reconnected)
*/
if (slot->imei && imei && strcmp(slot->imei, imei)) {
ofono_warn("IMEI has changed \"%s\" -> \"%s\"",
slot->imei, imei);
}
} else {
ofono_error("Slot %u IMEI query error: %s", slot->config.slot,
ril_error_to_string(status));
}
if (slot->imei) {
/* We assume that IMEI never changes */
g_free(imei);
} else {
slot->pub.imei =
slot->imei = imei ? imei : g_strdup_printf("%d", slot->index);
}
if (slot->imeisv) {
g_free(imeisv);
} else {
slot->pub.imeisv =
slot->imeisv = (imeisv ? imeisv : g_strdup(""));
}
ril_plugin_check_modem(slot);
ril_plugin_update_ready(slot->plugin);
}
static void ril_plugin_sim_state_changed(struct ril_sim_card *card, void *data) static void ril_plugin_sim_state_changed(struct ril_sim_card *card, void *data)
{ {
struct ril_slot *slot = data; struct ril_slot *slot = data;
struct ril_plugin_priv *plugin = slot->plugin; struct ril_plugin_priv *plugin = slot->plugin;
const struct ril_sim_card_status *status = card->status;
gboolean present; gboolean present;
if (card && card->status && if (status && status->card_state == RIL_CARDSTATE_PRESENT) {
card->status->card_state == RIL_CARDSTATE_PRESENT) {
DBG("SIM found in slot %u", slot->config.slot); DBG("SIM found in slot %u", slot->config.slot);
present = TRUE; present = TRUE;
} else { } else {
@@ -598,6 +678,36 @@ static void ril_plugin_sim_state_changed(struct ril_sim_card *card, void *data)
present = FALSE; present = FALSE;
} }
if (status) {
if (!slot->received_sim_status && slot->imei_req_id) {
/*
* We have received the SIM status but haven't yet
* got IMEI from the modem. Some RILs behave this
* way if the modem doesn't have IMEI initialized
* yet. Cancel the current request (with unlimited
* number of retries) and give a few more tries
* (this time, limited number).
*
* Some RILs fail RIL_REQUEST_DEVICE_IDENTITY until
* the modem hasn't been properly initialized.
*/
GRilIoRequest* req = grilio_request_new();
DBG("Giving slot %u last chance", slot->config.slot);
grilio_request_set_retry(req, RIL_RETRY_MS,
RIL_DEVICE_IDENTITY_RETRIES_LAST);
grilio_channel_cancel_request(slot->io,
slot->imei_req_id, FALSE);
slot->imei_req_id =
grilio_channel_send_request_full(slot->io,
req, RIL_REQUEST_DEVICE_IDENTITY,
ril_plugin_device_identity_cb,
NULL, slot);
grilio_request_unref(req);
}
slot->received_sim_status = TRUE;
}
if (slot->pub.sim_present != present) { if (slot->pub.sim_present != present) {
slot->pub.sim_present = present; slot->pub.sim_present = present;
ril_plugin_dbus_signal_sim(plugin->dbus, slot->index, present); ril_plugin_dbus_signal_sim(plugin->dbus, slot->index, present);
@@ -912,42 +1022,6 @@ static void ril_plugin_check_modem(struct ril_slot *slot)
} }
} }
static void ril_plugin_imei_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ril_slot *slot = user_data;
char *imei = NULL;
GASSERT(slot->imei_req_id);
slot->imei_req_id = 0;
if (status == RIL_E_SUCCESS) {
GRilIoParser rilp;
grilio_parser_init(&rilp, data, len);
imei = grilio_parser_get_utf8(&rilp);
DBG("%s", imei);
/*
* slot->imei should be either NULL (when we get connected
* to rild the very first time) or match the already known
* IMEI (if rild crashed and we have reconnected)
*/
GASSERT(!slot->imei || !g_strcmp0(slot->imei, imei));
} else {
ofono_error("Slot %u IMEI query error: %s", slot->config.slot,
ril_error_to_string(status));
}
g_free(slot->imei);
slot->pub.imei = slot->imei = (imei ? imei : g_strdup("ERROR"));
ril_plugin_check_modem(slot);
ril_plugin_update_ready(slot->plugin);
}
/* /*
* It seems to be necessary to kick (with RIL_REQUEST_RADIO_POWER) the * It seems to be necessary to kick (with RIL_REQUEST_RADIO_POWER) the
* modems with power on after one of the modems has been powered off. * modems with power on after one of the modems has been powered off.
@@ -983,17 +1057,19 @@ static void ril_plugin_slot_connected(struct ril_slot *slot)
GASSERT(!slot->io_event_id[IO_EVENT_CONNECTED]); GASSERT(!slot->io_event_id[IO_EVENT_CONNECTED]);
/* /*
* Modem will be registered after RIL_REQUEST_GET_IMEI successfully * Modem will be registered after RIL_REQUEST_DEVICE_IDENTITY
* completes. By the time ofono starts, rild may not be completely * successfully completes. By the time ofono starts, rild may
* functional. Waiting until it responds to RIL_REQUEST_GET_IMEI * not be completely functional. Waiting until it responds to
* (and retrying the request on failure) gives rild time to finish * RIL_REQUEST_DEVICE_IDENTITY (and retrying the request on
* whatever it's doing during initialization. * failure) gives rild time to finish whatever it's doing during
* initialization.
*/ */
GASSERT(!slot->imei_req_id); GASSERT(!slot->imei_req_id);
req = grilio_request_new(); req = grilio_request_new();
grilio_request_set_retry(req, RIL_RETRY_MS, -1); grilio_request_set_retry(req, RIL_RETRY_MS, -1);
slot->imei_req_id = grilio_channel_send_request_full(slot->io, req, slot->imei_req_id = grilio_channel_send_request_full(slot->io,
RIL_REQUEST_GET_IMEI, ril_plugin_imei_cb, NULL, slot); req, RIL_REQUEST_DEVICE_IDENTITY,
ril_plugin_device_identity_cb, NULL, slot);
grilio_request_unref(req); grilio_request_unref(req);
GASSERT(!slot->radio); GASSERT(!slot->radio);
@@ -1010,6 +1086,10 @@ static void ril_plugin_slot_connected(struct ril_slot *slot)
slot->sim_flags); slot->sim_flags);
slot->sim_card_state_event_id = ril_sim_card_add_state_changed_handler( slot->sim_card_state_event_id = ril_sim_card_add_state_changed_handler(
slot->sim_card, ril_plugin_sim_state_changed, slot); slot->sim_card, ril_plugin_sim_state_changed, slot);
/* ril_sim_card is expected to perform RIL_REQUEST_GET_SIM_STATUS
* asynchronously and report back when request has completed: */
GASSERT(!slot->sim_card->status);
GASSERT(!slot->received_sim_status);
GASSERT(!slot->network); GASSERT(!slot->network);
slot->network = ril_network_new(slot->io, log_prefix, slot->radio, slot->network = ril_network_new(slot->io, log_prefix, slot->radio,
@@ -1318,6 +1398,7 @@ static void ril_plugin_delete_slot(struct ril_slot *slot)
g_hash_table_destroy(slot->pub.errors); g_hash_table_destroy(slot->pub.errors);
g_free(slot->path); g_free(slot->path);
g_free(slot->imei); g_free(slot->imei);
g_free(slot->imeisv);
g_free(slot->name); g_free(slot->name);
g_free(slot->sockpath); g_free(slot->sockpath);
g_free(slot->sub); g_free(slot->sub);

View File

@@ -48,6 +48,7 @@ typedef struct ril_slot_info const *ril_slot_info_ptr;
struct ril_slot_info { struct ril_slot_info {
const char *path; const char *path;
const char *imei; const char *imei;
const char *imeisv;
const char *ecclist_file; const char *ecclist_file;
gboolean enabled; gboolean enabled;
gboolean sim_present; gboolean sim_present;
@@ -69,6 +70,7 @@ struct ril_plugin {
struct ril_modem { struct ril_modem {
GRilIoChannel *io; GRilIoChannel *io;
const char *imei; const char *imei;
const char *imeisv;
const char *log_prefix; const char *log_prefix;
const char *ecclist_file; const char *ecclist_file;
struct ofono_modem *ofono; struct ofono_modem *ofono;

View File

@@ -1,7 +1,7 @@
/* /*
* oFono - Open Source Telephony - RIL-based devices * oFono - Open Source Telephony - RIL-based devices
* *
* Copyright (C) 2015-2016 Jolla Ltd. * Copyright (C) 2015-2017 Jolla Ltd.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@@ -85,6 +85,7 @@ struct ril_sim {
ofono_sim_passwd_cb_t query_passwd_state_cb; ofono_sim_passwd_cb_t query_passwd_state_cb;
void *query_passwd_state_cb_data; void *query_passwd_state_cb_data;
guint query_passwd_state_timeout_id; guint query_passwd_state_timeout_id;
gulong query_passwd_state_sim_status_refresh_id;
}; };
struct ril_sim_io_response { struct ril_sim_io_response {
@@ -691,6 +692,12 @@ static void ril_sim_finish_passwd_state_query(struct ril_sim *sd,
sd->query_passwd_state_timeout_id = 0; sd->query_passwd_state_timeout_id = 0;
} }
if (sd->query_passwd_state_sim_status_refresh_id) {
ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_sim_status_refresh_id);
sd->query_passwd_state_sim_status_refresh_id = 0;
}
if (sd->query_passwd_state_cb) { if (sd->query_passwd_state_cb) {
ofono_sim_passwd_cb_t cb = sd->query_passwd_state_cb; ofono_sim_passwd_cb_t cb = sd->query_passwd_state_cb;
void *data = sd->query_passwd_state_cb_data; void *data = sd->query_passwd_state_cb_data;
@@ -884,6 +891,15 @@ static void ril_sim_query_pin_retries(struct ofono_sim *sim,
cb(ril_error_ok(&error), sd->retries, data); cb(ril_error_ok(&error), sd->retries, data);
} }
static void ril_sim_query_passwd_state_complete_cb(struct ril_sim_card *sc,
void *user_data)
{
struct ril_sim *sd = user_data;
GASSERT(sd->query_passwd_state_sim_status_refresh_id);
ril_sim_finish_passwd_state_query(sd, ril_sim_passwd_state(sd));
}
static gboolean ril_sim_query_passwd_state_timeout_cb(gpointer user_data) static gboolean ril_sim_query_passwd_state_timeout_cb(gpointer user_data)
{ {
struct ril_sim *sd = user_data; struct ril_sim *sd = user_data;
@@ -899,29 +915,41 @@ static void ril_sim_query_passwd_state(struct ofono_sim *sim,
ofono_sim_passwd_cb_t cb, void *data) ofono_sim_passwd_cb_t cb, void *data)
{ {
struct ril_sim *sd = ril_sim_get_data(sim); struct ril_sim *sd = ril_sim_get_data(sim);
enum ofono_sim_password_type passwd_state = ril_sim_passwd_state(sd);
struct ofono_error error;
if (sd->query_passwd_state_timeout_id) { if (sd->query_passwd_state_timeout_id) {
g_source_remove(sd->query_passwd_state_timeout_id); g_source_remove(sd->query_passwd_state_timeout_id);
sd->query_passwd_state_timeout_id = 0; sd->query_passwd_state_timeout_id = 0;
} }
if (passwd_state != OFONO_SIM_PASSWORD_INVALID) { if (!sd->query_passwd_state_sim_status_refresh_id) {
DBG_(sd, "%d", passwd_state); ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_cb = NULL; sd->query_passwd_state_sim_status_refresh_id);
sd->query_passwd_state_cb_data = NULL; sd->query_passwd_state_sim_status_refresh_id = 0;
sd->ofono_passwd_state = passwd_state; }
cb(ril_error_ok(&error), passwd_state, data);
/* Always request fresh status, just in case. */
ril_sim_card_request_status(sd->card);
sd->query_passwd_state_cb = cb;
sd->query_passwd_state_cb_data = data;
if (ril_sim_passwd_state(sd) != OFONO_SIM_PASSWORD_INVALID) {
/* Just wait for GET_SIM_STATUS completion */
DBG_(sd, "waiting for SIM status query to complete");
sd->query_passwd_state_sim_status_refresh_id =
ril_sim_card_add_status_received_handler(sd->card,
ril_sim_query_passwd_state_complete_cb, sd);
} else { } else {
/* Wait for the state to change */ /* Wait for the state to change */
DBG_(sd, "waiting for the SIM state to change"); DBG_(sd, "waiting for the SIM state to change");
sd->query_passwd_state_cb = cb;
sd->query_passwd_state_cb_data = data;
sd->query_passwd_state_timeout_id =
g_timeout_add_seconds(SIM_STATE_CHANGE_TIMEOUT_SECS,
ril_sim_query_passwd_state_timeout_cb, sd);
} }
/*
* We still need to complete the request somehow, even if
* GET_STATUS never completes or SIM status never changes.
*/
sd->query_passwd_state_timeout_id =
g_timeout_add_seconds(SIM_STATE_CHANGE_TIMEOUT_SECS,
ril_sim_query_passwd_state_timeout_cb, sd);
} }
static gboolean ril_sim_pin_change_state_timeout_cb(gpointer user_data) static gboolean ril_sim_pin_change_state_timeout_cb(gpointer user_data)
@@ -1280,6 +1308,11 @@ static void ril_sim_remove(struct ofono_sim *sim)
g_source_remove(sd->query_passwd_state_timeout_id); g_source_remove(sd->query_passwd_state_timeout_id);
} }
if (sd->query_passwd_state_sim_status_refresh_id) {
ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_sim_status_refresh_id);
}
ril_sim_card_remove_handler(sd->card, sd->card_status_id); ril_sim_card_remove_handler(sd->card, sd->card_status_id);
ril_sim_card_unref(sd->card); ril_sim_card_unref(sd->card);

View File

@@ -1,7 +1,7 @@
/* /*
* oFono - Open Source Telephony - RIL-based devices * oFono - Open Source Telephony - RIL-based devices
* *
* Copyright (C) 2015-2016 Jolla Ltd. * Copyright (C) 2015-2017 Jolla Ltd.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@@ -64,8 +64,6 @@ G_DEFINE_TYPE(RilSimCard, ril_sim_card, G_TYPE_OBJECT)
#define RIL_SIMCARD_STATE_CHANGED (0x01) #define RIL_SIMCARD_STATE_CHANGED (0x01)
#define RIL_SIMCARD_STATUS_CHANGED (0x02) #define RIL_SIMCARD_STATUS_CHANGED (0x02)
static void ril_sim_card_request_status(struct ril_sim_card *self);
static gboolean ril_sim_card_app_equal(const struct ril_sim_card_app *a1, static gboolean ril_sim_card_app_equal(const struct ril_sim_card_app *a1,
const struct ril_sim_card_app *a2) const struct ril_sim_card_app *a2)
{ {
@@ -365,7 +363,7 @@ static void ril_sim_card_status_cb(GRilIoChannel *io, int ril_status,
} }
} }
static void ril_sim_card_request_status(struct ril_sim_card *self) void ril_sim_card_request_status(struct ril_sim_card *self)
{ {
struct ril_sim_card_priv *priv = self->priv; struct ril_sim_card_priv *priv = self->priv;

View File

@@ -1,7 +1,7 @@
/* /*
* oFono - Open Source Telephony - RIL-based devices * oFono - Open Source Telephony - RIL-based devices
* *
* Copyright (C) 2015-2016 Jolla Ltd. * Copyright (C) 2015-2017 Jolla Ltd.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@@ -55,6 +55,7 @@ typedef void (*ril_sim_card_cb_t)(struct ril_sim_card *sc, void *arg);
struct ril_sim_card *ril_sim_card_new(GRilIoChannel *io, guint slot, int flags); struct ril_sim_card *ril_sim_card_new(GRilIoChannel *io, guint slot, int flags);
struct ril_sim_card *ril_sim_card_ref(struct ril_sim_card *sc); struct ril_sim_card *ril_sim_card_ref(struct ril_sim_card *sc);
void ril_sim_card_unref(struct ril_sim_card *sc); void ril_sim_card_unref(struct ril_sim_card *sc);
void ril_sim_card_request_status(struct ril_sim_card *self);
gboolean ril_sim_card_ready(struct ril_sim_card *sc); gboolean ril_sim_card_ready(struct ril_sim_card *sc);
gulong ril_sim_card_add_status_received_handler(struct ril_sim_card *sc, gulong ril_sim_card_add_status_received_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg); ril_sim_card_cb_t cb, void *arg);

View File

@@ -226,6 +226,9 @@ void sim_fs_notify_file_watches(struct sim_fs *fs, int id)
struct ofono_sim_context *context = l->data; struct ofono_sim_context *context = l->data;
GSList *k; GSList *k;
if (context->file_watches == NULL)
continue;
for (k = context->file_watches->items; k; k = k->next) { for (k = context->file_watches->items; k; k = k->next) {
struct file_watch *w = k->data; struct file_watch *w = k->data;
ofono_sim_file_changed_cb_t notify = w->item.notify; ofono_sim_file_changed_cb_t notify = w->item.notify;

View File

@@ -11,7 +11,7 @@ Requires: dbus
Requires: systemd Requires: systemd
Requires: ofono-configs Requires: ofono-configs
Requires: libgrilio >= 1.0.10 Requires: libgrilio >= 1.0.10
Requires: libglibutil >= 1.0.19 Requires: libglibutil >= 1.0.22
Requires(preun): systemd Requires(preun): systemd
Requires(post): systemd Requires(post): systemd
Requires(postun): systemd Requires(postun): systemd
@@ -21,7 +21,7 @@ BuildRequires: pkgconfig(libudev) >= 145
BuildRequires: pkgconfig(mobile-broadband-provider-info) BuildRequires: pkgconfig(mobile-broadband-provider-info)
BuildRequires: pkgconfig(libwspcodec) >= 2.0 BuildRequires: pkgconfig(libwspcodec) >= 2.0
BuildRequires: pkgconfig(libgrilio) >= 1.0.10 BuildRequires: pkgconfig(libgrilio) >= 1.0.10
BuildRequires: pkgconfig(libglibutil) >= 1.0.19 BuildRequires: pkgconfig(libglibutil) >= 1.0.22
BuildRequires: pkgconfig(libdbuslogserver-dbus) BuildRequires: pkgconfig(libdbuslogserver-dbus)
BuildRequires: pkgconfig(libmce-glib) BuildRequires: pkgconfig(libmce-glib)
BuildRequires: libtool BuildRequires: libtool