ofono: Retry autoconnect when gprs gets attached
authorPekka Pessi <Pekka.Pessi@nokia.com>
Wed, 26 Jan 2011 14:50:37 +0000 (16:50 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 27 Jan 2011 10:08:37 +0000 (11:08 +0100)
plugins/ofono.c

index 7abcf8d..90b579d 100644 (file)
@@ -81,6 +81,11 @@ struct modem_data {
        dbus_bool_t requested_online;
        dbus_bool_t online;
 
+       /* org.ofono.ConnectionManager properties */
+       dbus_bool_t powered;
+       dbus_bool_t attached;
+       dbus_bool_t roaming_allowed;
+
        uint8_t strength, has_strength;
 };
 
@@ -677,6 +682,25 @@ static void check_networks(struct modem_data *modem)
                        DBUS_TYPE_INVALID);
 }
 
+static void modem_clear_network_errors(struct modem_data *modem)
+{
+       struct connman_device *device = modem->device;
+       GHashTableIter i;
+       gpointer value;
+
+       if (device == NULL)
+               return;
+
+       g_hash_table_iter_init(&i, network_hash);
+
+       while (g_hash_table_iter_next(&i, NULL, &value)) {
+               struct connman_network *network = value;
+
+               if (connman_network_get_device(network) == device)
+                       connman_network_clear_error(network);
+       }
+}
+
 static void modem_operator_name_changed(struct modem_data *modem,
                                        char const *name)
 {
@@ -865,6 +889,94 @@ static void check_registration(struct modem_data *modem)
                        DBUS_TYPE_INVALID);
 }
 
+static void modem_gprs_changed(struct modem_data *modem,
+                                       DBusMessageIter *entry)
+{
+       DBusMessageIter iter;
+       const char *key;
+       int type;
+       dbus_bool_t value;
+
+       dbus_message_iter_get_basic(entry, &key);
+
+       DBG("key %s", key);
+
+       dbus_message_iter_next(entry);
+
+       dbus_message_iter_recurse(entry, &iter);
+
+       type = dbus_message_iter_get_arg_type(&iter);
+
+       if (type != DBUS_TYPE_BOOLEAN)
+               return;
+
+       dbus_message_iter_get_basic(&iter, &value);
+
+       if (g_str_equal(key, "Attached") == TRUE) {
+               DBG("Attached %d", value);
+
+               modem->attached = value;
+
+               if (value)
+                       modem_clear_network_errors(modem);
+       } else if (g_str_equal(key, "Powered") == TRUE) {
+               DBG("Powered %d", value);
+
+               modem->powered = value;
+       } else if (g_str_equal(key, "RoamingAllowed") == TRUE) {
+               DBG("RoamingAllowed %d", value);
+
+               modem->roaming_allowed = value;
+       }
+}
+
+static void check_gprs_reply(DBusPendingCall *call, void *user_data)
+{
+       char const *path = user_data;
+       struct modem_data *modem;
+       DBusMessage *reply;
+       DBusMessageIter array, dict, entry;
+
+       DBG("path %s", path);
+
+       modem = g_hash_table_lookup(modem_hash, path);
+       if (modem == NULL)
+               return;
+
+       reply = dbus_pending_call_steal_reply(call);
+
+       if (dbus_message_iter_init(reply, &array) == FALSE)
+               goto done;
+
+       if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
+               goto done;
+
+       dbus_message_iter_recurse(&array, &dict);
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               dbus_message_iter_recurse(&dict, &entry);
+               modem_gprs_changed(modem, &entry);
+               dbus_message_iter_next(&dict);
+       }
+
+done:
+       dbus_message_unref(reply);
+
+       dbus_pending_call_unref(call);
+
+       check_networks(modem);
+}
+
+static void check_gprs(struct modem_data *modem)
+{
+       char const *path = modem->path;
+
+       DBG("modem %p path %s", modem, path);
+
+       call_ofono(path, OFONO_GPRS_INTERFACE, GET_PROPERTIES,
+                       check_gprs_reply, g_strdup(path), g_free,
+                       DBUS_TYPE_INVALID);
+}
+
 static void add_device(const char *path, const char *imsi)
 {
        struct modem_data *modem;
@@ -911,8 +1023,9 @@ static void add_device(const char *path, const char *imsi)
 
        if (modem->has_reg)
                check_registration(modem);
+
        if (modem->has_gprs)
-               check_networks(modem);
+               check_gprs(modem);
 }
 
 static void sim_properties_reply(DBusPendingCall *call, void *user_data)
@@ -1233,8 +1346,11 @@ static gboolean modem_changed(DBusConnection *connection, DBusMessage *message,
                } else {
                        if (added_reg)
                                check_registration(modem);
-                       if (added_gprs)
+
+                       if (added_gprs) {
                                gprs_change_powered(modem->path, TRUE);
+                               check_gprs(modem);
+                       }
                }
        }
 
@@ -1292,8 +1408,7 @@ static gboolean gprs_changed(DBusConnection *connection, DBusMessage *message,
 {
        const char *path = dbus_message_get_path(message);
        struct modem_data *modem;
-       DBusMessageIter iter, value;
-       const char *key;
+       DBusMessageIter iter;
 
        DBG("path %s", path);
 
@@ -1301,27 +1416,8 @@ static gboolean gprs_changed(DBusConnection *connection, DBusMessage *message,
        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, "Attached") == TRUE) {
-               dbus_bool_t attached;
-
-               dbus_message_iter_get_basic(&value, &attached);
-
-               DBG("Attached %d", attached);
-
-               if (attached == TRUE)
-                       check_networks(modem);
-               else if (modem->device != NULL)
-                       connman_device_remove_all_networks(modem->device);
-
-       }
+       if (dbus_message_iter_init(message, &iter))
+               modem_gprs_changed(modem, &iter);
 
        return TRUE;
 }