From: Pekka Pessi <[email protected]>
Try to get IMSI immediately after SimManager interface is available.
Listen to SIM events in Ofono plugin, add device when IMSI
(SubscriberIdentity) becomes available, remove device if SIM is removed.
---
plugins/ofono.c | 137 ++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 101 insertions(+), 36 deletions(-)
diff --git a/plugins/ofono.c b/plugins/ofono.c
index faf82b9..1a4b8e6 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -195,10 +195,35 @@ static struct connman_device_driver modem_driver = {
.disable = modem_disable,
};
+static void modem_remove_device(struct modem_data *modem)
+{
+ if (modem->device == NULL)
+ return;
+
+ connman_device_unregister(modem->device);
+ connman_device_unref(modem->device);
+
+ modem->device = NULL;
+}
+
+static void remove_modem(gpointer data)
+{
+ struct modem_data *modem = data;
+
+ g_free(modem->path);
+
+ modem_remove_device(modem);
+
+ g_free(modem);
+}
+
static char *get_ident(const char *path)
{
char *pos;
+ if (path == NULL)
+ return NULL;
+
if (*path != '/')
return NULL;
@@ -880,7 +905,7 @@ static void add_device(const char *path, const char *imsi,
struct modem_data *modem;
struct connman_device *device;
- DBG("path %s imsi %s", path, imsi);
+ DBG("path %s imsi %s", path, imsi ? imsi : "<missing>");
if (path == NULL)
return;
@@ -892,6 +917,16 @@ static void add_device(const char *path, const char *imsi,
if (modem == NULL)
return;
+ if (modem->device) {
+ char const *ident;
+
+ ident = connman_device_get_string(modem->device, "IMSI");
+ if (g_str_equal(ident, imsi))
+ return;
+
+ modem_remove_device(modem);
+ }
+
device = connman_device_create(imsi, CONNMAN_DEVICE_TYPE_CELLULAR);
if (device == NULL)
return;
@@ -901,6 +936,7 @@ static void add_device(const char *path, const char *imsi,
connman_device_set_mode(device, CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE);
connman_device_set_string(device, "Path", path);
+ connman_device_set_string(device, "IMSI", imsi); /* XXX */
if (mcc != NULL)
connman_device_set_string(device, "MCC", mcc);
if (mnc != NULL)
@@ -919,7 +955,7 @@ static void add_device(const char *path, const char *imsi,
static void sim_properties_reply(DBusPendingCall *call, void *user_data)
{
const char *path = user_data;
- const char *imsi;
+ const char *imsi = NULL;
char *mcc = NULL;
char *mnc = NULL;
/* If MobileNetworkCodeLength is not provided, mnc_length is 0 */
@@ -1049,7 +1085,7 @@ static struct modem_data *add_modem(const char *path)
return modem;
}
-static gboolean modem_has_gprs(DBusMessageIter *array)
+static gboolean modem_has_sim(DBusMessageIter *array)
{
DBusMessageIter entry;
@@ -1060,7 +1096,7 @@ static gboolean modem_has_gprs(DBusMessageIter *array)
dbus_message_iter_get_basic(&entry, &interface);
- if (g_strcmp0(OFONO_GPRS_INTERFACE, interface) == 0)
+ if (g_strcmp0(OFONO_SIM_INTERFACE, interface) == 0)
return TRUE;
dbus_message_iter_next(&entry);
@@ -1076,7 +1112,7 @@ static void modem_properties_reply(DBusPendingCall *call,
void *user_data)
DBusMessageIter array, dict;
const char *path = user_data;
dbus_bool_t powered = FALSE;
- gboolean has_gprs = FALSE;
+ gboolean has_sim = FALSE;
struct modem_data *new_modem;
DBG("path %s", path);
@@ -1114,7 +1150,7 @@ static void modem_properties_reply(DBusPendingCall *call,
void *user_data)
if (g_str_equal(key, "Powered") == TRUE)
dbus_message_iter_get_basic(&value, &powered);
else if (g_str_equal(key, "Interfaces") == TRUE)
- has_gprs = modem_has_gprs(&value);
+ has_sim = modem_has_sim(&value);
dbus_message_iter_next(&dict);
}
@@ -1126,7 +1162,7 @@ static void modem_properties_reply(DBusPendingCall *call,
void *user_data)
if (!powered)
modem_change_powered(path, TRUE);
- if (has_gprs)
+ if (has_sim)
get_imsi(path);
done:
@@ -1277,28 +1313,6 @@ done:
dbus_pending_call_unref(call);
}
-static void modem_remove_device(struct modem_data *modem)
-{
- if (modem->device == NULL)
- return;
-
- connman_device_unregister(modem->device);
- connman_device_unref(modem->device);
-
- modem->device = NULL;
-}
-
-static void remove_modem(gpointer data)
-{
- struct modem_data *modem = data;
-
- g_free(modem->path);
-
- modem_remove_device(modem);
-
- g_free(modem);
-}
-
static void ofono_connect(DBusConnection *connection, void *user_data)
{
DBusMessage *message;
@@ -1373,15 +1387,56 @@ static gboolean modem_changed(DBusConnection
*connection, DBusMessage *message,
dbus_bool_t powered;
dbus_message_iter_get_basic(&value, &powered);
- if (powered == TRUE)
- return TRUE;
-
- modem_remove_device(modem);
+ if (powered == FALSE)
+ modem_remove_device(modem);
} else if (g_str_equal(key, "Interfaces") == TRUE) {
- if (modem_has_gprs(&value) == TRUE) {
+ if (modem_has_sim(&value)) {
if (modem->device == NULL)
- get_imsi(modem->path);
- } else if (modem->device != NULL)
+ get_imsi(path);
+ } else {
+ if (modem->device != NULL)
+ modem_remove_device(modem);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean sim_changed(DBusConnection *connection, DBusMessage *message,
+ void *user_data)
+{
+ const char *path = dbus_message_get_path(message);
+ struct modem_data *modem;
+ DBusMessageIter iter, value;
+ const char *key;
+
+ DBG("path %s", path);
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL)
+ return TRUE;
+
+ if (dbus_message_iter_init(message, &iter) == FALSE)
+ return TRUE;
+
+ dbus_message_iter_get_basic(&iter, &key);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &value);
+
+ if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
+ char *imsi;
+
+ dbus_message_iter_get_basic(&value, &imsi);
+
+ if (strlen(imsi) > 0)
+ add_device(path, imsi, NULL, NULL);
+ } else if (g_str_equal(key, "Present") == TRUE) {
+ dbus_bool_t present;
+
+ dbus_message_iter_get_basic(&value, &present);
+
+ if (!present && modem->device != NULL)
modem_remove_device(modem);
}
@@ -1676,6 +1731,7 @@ static gboolean pri_context_changed(DBusConnection
*connection,
}
static guint watch;
+static guint sim_watch;
static guint gprs_watch;
static guint modem_watch;
static guint manager_watch;
@@ -1710,6 +1766,12 @@ static int ofono_init(void)
manager_changed,
NULL, NULL);
+ sim_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ OFONO_SIM_INTERFACE,
+ PROPERTY_CHANGED,
+ sim_changed,
+ NULL, NULL);
+
context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_PRI_CONTEXT_INTERFACE,
PROPERTY_CHANGED,
@@ -1717,6 +1779,7 @@ static int ofono_init(void)
NULL, NULL);
if (watch == 0 || gprs_watch == 0 || modem_watch == 0 ||
+ sim_watch == 0 ||
manager_watch == 0 || context_watch == 0) {
err = -EIO;
goto remove;
@@ -1736,6 +1799,7 @@ static int ofono_init(void)
remove:
g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, sim_watch);
g_dbus_remove_watch(connection, gprs_watch);
g_dbus_remove_watch(connection, modem_watch);
g_dbus_remove_watch(connection, manager_watch);
@@ -1749,6 +1813,7 @@ remove:
static void ofono_exit(void)
{
g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, sim_watch);
g_dbus_remove_watch(connection, gprs_watch);
g_dbus_remove_watch(connection, modem_watch);
g_dbus_remove_watch(connection, manager_watch);
--
1.7.0.4
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman