---
Change log from v4:
        - manage CDMA network registration, netwok is retrieved like GSM case
        - modem path is used as network hash_table key
        - create CDMA_SERVICE macro to avoid over 80 characters lines

 plugins/ofono.c |  193 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 184 insertions(+), 9 deletions(-)

diff --git a/plugins/ofono.c b/plugins/ofono.c
index 060cd8e..adb715d 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -51,6 +51,11 @@
 #define OFONO_SIM_INTERFACE            OFONO_SERVICE ".SimManager"
 #define OFONO_REGISTRATION_INTERFACE   OFONO_SERVICE ".NetworkRegistration"
 
+#define CDMA_SERVICE                   OFONO_SERVICE ".cdma"
+
+#define OFONO_CDMA_INTERFACE           CDMA_SERVICE ".ConnectionManager"
+#define OFONO_CDMA_NETREG_INTERFACE    CDMA_SERVICE ".NetworkRegistration"
+
 #define PROPERTY_CHANGED               "PropertyChanged"
 #define GET_PROPERTIES                 "GetProperties"
 #define SET_PROPERTY                   "SetProperty"
@@ -76,6 +81,8 @@ struct modem_data {
        gboolean has_sim;
        gboolean has_reg;
        gboolean has_gprs;
+       gboolean has_cdma;
+       gboolean has_cdma_reg;
        gboolean available;
        gboolean pending_online;
        dbus_bool_t requested_online;
@@ -90,6 +97,7 @@ struct modem_data {
        connman_bool_t roaming;
        uint8_t strength, has_strength;
        char *operator;
+       char *serial;
 };
 
 struct network_info {
@@ -337,6 +345,7 @@ static struct connman_device_driver modem_driver = {
 
 static void remove_device_networks(struct connman_device *device)
 {
+       struct modem_data *modem = connman_device_get_data(device);
        GHashTableIter iter;
        gpointer key, value;
        GSList *info_list = NULL;
@@ -362,6 +371,11 @@ static void remove_device_networks(struct connman_device 
*device)
                connman_device_remove_network(device, info->network);
        }
 
+       if (modem->has_cdma == TRUE) {
+               g_hash_table_remove(network_hash, modem->path);
+               modem->has_cdma = FALSE;
+       }
+
        g_slist_free(info_list);
 }
 
@@ -388,6 +402,7 @@ static void remove_modem(gpointer data)
 
        g_free(modem->path);
        g_free(modem->operator);
+       g_free(modem->serial);
 
        g_free(modem);
 }
@@ -541,25 +556,57 @@ done:
 
 static int set_network_active(struct connman_network *network)
 {
+       struct connman_device *device;
+       struct modem_data *modem;
        dbus_bool_t value = TRUE;
        const char *path = connman_network_get_string(network, "Path");
 
        DBG("network %p, path %s", network, path);
 
-       return set_property(path, OFONO_CONTEXT_INTERFACE,
-                               "Active", DBUS_TYPE_BOOLEAN, &value,
-                               set_active_reply, g_strdup(path), g_free);
+       device = connman_network_get_device(network);
+       if (device == NULL)
+               return -ENODEV;
+
+       modem = connman_device_get_data(device);
+       if (modem == NULL)
+               return -ENODEV;
+
+       if (modem->has_cdma == TRUE)
+               return set_property(path, OFONO_CDMA_INTERFACE,
+                                       "Powered", DBUS_TYPE_BOOLEAN, &value,
+                                       set_active_reply, g_strdup(path),
+                                       g_free);
+       else
+               return set_property(path, OFONO_CONTEXT_INTERFACE,
+                                       "Active", DBUS_TYPE_BOOLEAN, &value,
+                                       set_active_reply,
+                                       g_strdup(path), g_free);
 }
 
 static int set_network_inactive(struct connman_network *network)
 {
+       struct connman_device *device;
+       struct modem_data *modem;
        int err;
        dbus_bool_t value = FALSE;
        const char *path = connman_network_get_string(network, "Path");
 
        DBG("network %p, path %s", network, path);
 
-       err = set_property(path, OFONO_CONTEXT_INTERFACE,
+       device = connman_network_get_device(network);
+       if (device == NULL)
+               return -ENODEV;
+
+       modem = connman_device_get_data(device);
+       if (modem == NULL)
+               return -ENODEV;
+
+       if (modem->has_cdma == TRUE)
+               err = set_property(path, OFONO_CDMA_INTERFACE,
+                                       "Powered", DBUS_TYPE_BOOLEAN, &value,
+                                       NULL, NULL, NULL);
+       else
+               err = set_property(path, OFONO_CONTEXT_INTERFACE,
                                "Active", DBUS_TYPE_BOOLEAN, &value,
                                NULL, NULL, NULL);
 
@@ -587,7 +634,7 @@ static int network_connect(struct connman_network *network)
        if (modem->registered == FALSE)
                return -ENOLINK;
 
-       if (modem->powered == FALSE)
+       if (modem->powered == FALSE && modem->has_cdma == FALSE)
                return -ENOLINK;
 
        if (modem->roaming_allowed == FALSE && modem->roaming == TRUE)
@@ -1213,9 +1260,14 @@ static void check_registration(struct modem_data *modem)
 
        DBG("modem %p path %s", modem, path);
 
-       call_ofono(path, OFONO_REGISTRATION_INTERFACE, GET_PROPERTIES,
-                       check_registration_reply, g_strdup(path), g_free,
-                       DBUS_TYPE_INVALID);
+       if (modem->has_cdma)
+               call_ofono(path, OFONO_CDMA_NETREG_INTERFACE, GET_PROPERTIES,
+                               check_registration_reply, g_strdup(path),
+                               g_free, DBUS_TYPE_INVALID);
+       else
+               call_ofono(path, OFONO_REGISTRATION_INTERFACE, GET_PROPERTIES,
+                               check_registration_reply, g_strdup(path),
+                               g_free, DBUS_TYPE_INVALID);
 }
 
 static void modem_gprs_changed(struct modem_data *modem,
@@ -1355,6 +1407,9 @@ static void add_device(const char *path, const char *imsi)
 
        if (modem->has_gprs)
                check_gprs(modem);
+
+       if (modem->has_cdma)
+               add_network(modem->device, modem->path, NULL);
 }
 
 static void sim_properties_reply(DBusPendingCall *call, void *user_data)
@@ -1464,6 +1519,17 @@ static gboolean modem_has_gprs(DBusMessageIter *array)
        return modem_has_interface(array, OFONO_GPRS_INTERFACE);
 }
 
+static gboolean modem_has_cdma(DBusMessageIter *array)
+{
+       return modem_has_interface(array,
+                               OFONO_CDMA_INTERFACE);
+}
+
+static gboolean modem_has_cdma_reg(DBusMessageIter *array)
+{
+       return modem_has_interface(array, OFONO_CDMA_NETREG_INTERFACE);
+}
+
 static void add_modem(const char *path, DBusMessageIter *prop)
 {
        struct modem_data *modem;
@@ -1473,6 +1539,8 @@ static void add_modem(const char *path, DBusMessageIter 
*prop)
        gboolean has_sim = FALSE;
        gboolean has_reg = FALSE;
        gboolean has_gprs = FALSE;
+       gboolean has_cdma = FALSE;
+       gboolean has_cdma_reg = FALSE;
 
        modem = g_hash_table_lookup(modem_hash, path);
 
@@ -1486,6 +1554,8 @@ static void add_modem(const char *path, DBusMessageIter 
*prop)
        modem->path = g_strdup(path);
        modem->device = NULL;
        modem->available = TRUE;
+       modem->operator = NULL;
+       modem->serial = NULL;
 
        g_hash_table_insert(modem_hash, g_strdup(path), modem);
 
@@ -1507,6 +1577,8 @@ static void add_modem(const char *path, DBusMessageIter 
*prop)
                        has_sim = modem_has_sim(&value);
                        has_reg = modem_has_reg(&value);
                        has_gprs = modem_has_gprs(&value);
+                       has_cdma = modem_has_cdma(&value);
+                       has_cdma_reg = modem_has_cdma_reg(&value);
                }
 
                dbus_message_iter_next(prop);
@@ -1521,6 +1593,8 @@ static void add_modem(const char *path, DBusMessageIter 
*prop)
        modem->has_sim = has_sim;
        modem->has_reg = has_reg;
        modem->has_gprs = has_gprs;
+       modem->has_cdma = has_cdma;
+       modem->has_cdma_reg = has_cdma_reg;
 
        update_modem_online(modem, online);
 
@@ -1639,6 +1713,7 @@ static gboolean modem_changed(DBusConnection *connection, 
DBusMessage *message,
                modem->has_sim = FALSE;
                modem->has_reg = FALSE;
                modem->has_gprs = FALSE;
+               modem->has_cdma_reg = FALSE;
 
                modem_remove_device(modem);
        } else if (g_str_equal(key, "Online") == TRUE) {
@@ -1661,10 +1736,34 @@ static gboolean modem_changed(DBusConnection 
*connection, DBusMessage *message,
                gboolean had_reg = modem->has_reg;
                gboolean has_gprs = modem_has_gprs(&value);
                gboolean had_gprs = modem->has_gprs;
+               gboolean has_cdma = modem_has_cdma(&value);
+               gboolean had_cdma = modem->has_cdma;
+               gboolean has_cdma_reg = modem_has_cdma_reg(&value);
+               gboolean had_cdma_reg = modem->has_cdma_reg;
 
                modem->has_sim = has_sim;
                modem->has_reg = has_reg;
                modem->has_gprs = has_gprs;
+               modem->has_cdma = has_cdma;
+               modem->has_cdma_reg = has_cdma_reg;
+
+               if (modem->has_cdma == TRUE) {
+                       if (modem->has_cdma_reg)
+                               check_registration(modem);
+                       else if (had_cdma_reg)
+                               modem_registration_removed(modem);
+
+                       if (modem->device == NULL)
+                               add_device(modem->path, modem->serial);
+
+                       return TRUE;
+               } else if (had_cdma == TRUE) {
+                       modem->has_cdma = had_cdma;
+                       modem_remove_device(modem);
+
+                       if (had_cdma_reg && !has_cdma_reg)
+                               modem_registration_removed(modem);
+               }
 
                if (modem->device == NULL) {
                        if (has_sim)
@@ -1682,6 +1781,15 @@ static gboolean modem_changed(DBusConnection 
*connection, DBusMessage *message,
                                check_gprs(modem);
                        }
                }
+       } else if (g_str_equal(key, "Serial") == TRUE) {
+               const char *hw_serial;
+
+               dbus_message_iter_get_basic(&value, &hw_serial);
+
+               modem->serial = g_strdup(hw_serial);
+
+               if (modem->has_cdma == TRUE)
+                       add_device(modem->path, hw_serial);
        }
 
        return TRUE;
@@ -1889,6 +1997,54 @@ static gboolean context_changed(DBusConnection 
*connection,
        return TRUE;
 }
 
+static gboolean cdma_changed(DBusConnection *connection,
+                                       DBusMessage *message, void *user_data)
+{
+       const char *path = dbus_message_get_path(message);
+       struct network_info *info;
+       DBusMessageIter iter, value;
+       const char *key;
+
+       DBG("");
+
+       info = g_hash_table_lookup(network_hash, path);
+       if (info == NULL)
+               return TRUE;
+
+       if (!pending_network_is_available(info->network)) {
+               g_hash_table_remove(network_hash, path);
+               return TRUE;
+       }
+
+       connman_network_set_associating(info->network, FALSE);
+
+       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);
+
+       DBG("key %s", key);
+
+       if (g_str_equal(key, "Settings") == TRUE)
+               update_ipv4_settings(&value, info);
+       else if (g_str_equal(key, "Powered") == TRUE) {
+               dbus_bool_t active;
+
+               dbus_message_iter_get_basic(&value, &active);
+
+               if (active == FALSE)
+                       set_connected(info, active);
+               else if (connman_network_get_connecting(info->network) == TRUE)
+                       /* Connect only if requested to do so */
+                       set_connected(info, active);
+       }
+
+       return TRUE;
+}
+
 static guint watch;
 static guint reg_watch;
 static guint sim_watch;
@@ -1899,6 +2055,8 @@ static guint modem_watch;
 static guint modem_added_watch;
 static guint modem_removed_watch;
 static guint context_watch;
+static guint cdma_watch;
+static guint cdma_reg_watch;
 
 static int ofono_init(void)
 {
@@ -1965,11 +2123,24 @@ static int ofono_init(void)
                                                context_changed,
                                                NULL, NULL);
 
+       cdma_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+                                               OFONO_CDMA_INTERFACE,
+                                               PROPERTY_CHANGED,
+                                               cdma_changed,
+                                               NULL, NULL);
+
+       cdma_reg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+                                               OFONO_CDMA_NETREG_INTERFACE,
+                                               PROPERTY_CHANGED,
+                                               reg_changed,
+                                               NULL, NULL);
+
        if (watch == 0 || gprs_watch == 0 || context_added_watch == 0 ||
                        context_removed_watch == 0 || modem_watch == 0 ||
                        reg_watch == 0 || sim_watch == 0 ||
                        modem_added_watch == 0 || modem_removed_watch == 0 ||
-                               context_watch == 0) {
+                       context_watch == 0 || cdma_watch == 0 ||
+                       cdma_reg_watch == 0) {
                err = -EIO;
                goto remove;
        }
@@ -1997,6 +2168,8 @@ remove:
        g_dbus_remove_watch(connection, modem_added_watch);
        g_dbus_remove_watch(connection, modem_removed_watch);
        g_dbus_remove_watch(connection, context_watch);
+       g_dbus_remove_watch(connection, cdma_watch);
+       g_dbus_remove_watch(connection, cdma_reg_watch);
 
        dbus_connection_unref(connection);
 
@@ -2015,6 +2188,8 @@ static void ofono_exit(void)
        g_dbus_remove_watch(connection, modem_added_watch);
        g_dbus_remove_watch(connection, modem_removed_watch);
        g_dbus_remove_watch(connection, context_watch);
+       g_dbus_remove_watch(connection, cdma_watch);
+       g_dbus_remove_watch(connection, cdma_reg_watch);
 
        ofono_disconnect(connection, NULL);
 
-- 
1.7.1

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to