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

Reply via email to