--- Change log from v2 and v3: - format patch into master - remove CDMA network when CDMA interface is removed - use unique name for CDMA networks - remove CDMA specific functions
plugins/ofono.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 180 insertions(+), 9 deletions(-) diff --git a/plugins/ofono.c b/plugins/ofono.c index 8650bfc..44074a5 100644 --- a/plugins/ofono.c +++ b/plugins/ofono.c @@ -50,6 +50,7 @@ #define OFONO_CONTEXT_INTERFACE OFONO_SERVICE ".ConnectionContext" #define OFONO_SIM_INTERFACE OFONO_SERVICE ".SimManager" #define OFONO_REGISTRATION_INTERFACE OFONO_SERVICE ".NetworkRegistration" +#define OFONO_CDMA_INTERFACE OFONO_SERVICE ".cdma.ConnectionManager" #define PROPERTY_CHANGED "PropertyChanged" #define GET_PROPERTIES "GetProperties" @@ -70,12 +71,15 @@ static GHashTable *modem_hash = NULL; static GHashTable *network_hash; +static int cdma_count; + struct modem_data { char *path; struct connman_device *device; gboolean has_sim; gboolean has_reg; gboolean has_gprs; + gboolean is_cdma; gboolean available; gboolean pending_online; dbus_bool_t requested_online; @@ -337,6 +341,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 +367,12 @@ static void remove_device_networks(struct connman_device *device) connman_device_remove_network(device, info->network); } + if (modem->is_cdma == TRUE) { + g_hash_table_remove(network_hash, "/context1"); + modem->is_cdma = FALSE; + cdma_count--; + } + g_slist_free(info_list); } @@ -541,25 +552,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->is_cdma == TRUE) + return set_property(modem->path, OFONO_CDMA_INTERFACE, + "Powered", DBUS_TYPE_BOOLEAN, &value, + set_active_reply, g_strdup(modem->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->is_cdma == TRUE) + err = set_property(modem->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); @@ -584,6 +627,9 @@ static int network_connect(struct connman_network *network) if (modem == NULL) return -ENODEV; + if (modem->is_cdma == TRUE) + return set_network_active(network); + if (modem->registered == FALSE) return -ENOLINK; @@ -598,8 +644,19 @@ static int network_connect(struct connman_network *network) static int network_disconnect(struct connman_network *network) { + struct connman_device *device; + struct modem_data *modem; + DBG("network %p", network); + device = connman_network_get_device(network); + if (device == NULL) + return -ENODEV; + + modem = connman_device_get_data(device); + if (modem == NULL) + return -ENODEV; + if (connman_network_get_index(network) < 0) return -ENOTCONN; @@ -887,16 +944,31 @@ static int add_network(struct connman_device *device, connman_network_set_available(network, TRUE); connman_network_set_index(network, -1); - if (modem->operator) - connman_network_set_name(network, modem->operator); - else - connman_network_set_name(network, ""); + if (modem->is_cdma == TRUE) { + char *name = g_strdup_printf("CDMA network %d", cdma_count++); + if (name == NULL) { + g_hash_table_remove(network_hash, info); + return -ENOMEM; + } + + connman_network_set_name(network, name); + + g_free(name); + } else { + if (modem->operator) + connman_network_set_name(network, modem->operator); + else + connman_network_set_name(network, ""); + } if (modem->has_strength) connman_network_set_strength(network, modem->strength); connman_network_set_roaming(network, modem->roaming); + if (dict == NULL) + goto done; + while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; const char *key; @@ -926,6 +998,7 @@ static int add_network(struct connman_device *device, dbus_message_iter_next(dict); } +done: if (connman_device_add_network(device, network) != 0) { g_hash_table_remove(network_hash, path); return -EIO; @@ -1464,6 +1537,12 @@ static gboolean modem_has_gprs(DBusMessageIter *array) return modem_has_interface(array, OFONO_GPRS_INTERFACE); } +static gboolean modem_is_cdma(DBusMessageIter *array) +{ + return modem_has_interface(array, + OFONO_CDMA_INTERFACE); +} + static void add_modem(const char *path, DBusMessageIter *prop) { struct modem_data *modem; @@ -1473,6 +1552,7 @@ static void add_modem(const char *path, DBusMessageIter *prop) gboolean has_sim = FALSE; gboolean has_reg = FALSE; gboolean has_gprs = FALSE; + gboolean is_cdma = FALSE; modem = g_hash_table_lookup(modem_hash, path); @@ -1507,6 +1587,7 @@ 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); + is_cdma = modem_is_cdma(&value); } dbus_message_iter_next(prop); @@ -1521,6 +1602,7 @@ 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->is_cdma = is_cdma; update_modem_online(modem, online); @@ -1658,10 +1740,27 @@ 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 is_cdma = modem_is_cdma(&value); + gboolean was_cdma = modem->is_cdma; modem->has_sim = has_sim; modem->has_reg = has_reg; modem->has_gprs = has_gprs; + modem->is_cdma = is_cdma; + + if (is_cdma) { + if (modem->device == NULL) + return TRUE; + + add_network(modem->device, "/context1", NULL); + + return TRUE; + } else { + if (is_cdma == FALSE && was_cdma == TRUE) { + modem->is_cdma = was_cdma; + modem_remove_device(modem); + } + } if (modem->device == NULL) { if (has_sim) @@ -1679,6 +1778,21 @@ 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); + + if (g_str_has_prefix(hw_serial, "+GSN:") == TRUE) + hw_serial = hw_serial + 5; + + if (g_str_has_prefix(hw_serial, "+CGSN:") == TRUE) + hw_serial = hw_serial + 6; + + add_device(modem->path, hw_serial); + + if (modem->is_cdma == TRUE) + add_network(modem->device, "/context1", NULL); } return TRUE; @@ -1888,6 +2002,55 @@ static gboolean context_changed(DBusConnection *connection, return TRUE; } +static gboolean cdma_changed(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct network_info *info; + DBusMessageIter iter, value; + const char *key; + + DBG(""); + + info = g_hash_table_lookup(network_hash, "/context1"); + if (info == NULL) + return TRUE; + + if (!pending_network_is_available(info->network)) { + g_hash_table_remove(network_hash, "/context1"); + 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); + + /* Connect only if requested to do so */ + if (active == TRUE && + connman_network_get_connecting(info->network) == TRUE) + set_connected(info, active); + } + + return TRUE; +} + static guint watch; static guint reg_watch; static guint sim_watch; @@ -1898,6 +2061,7 @@ static guint modem_watch; static guint modem_added_watch; static guint modem_removed_watch; static guint context_watch; +static guint cdma_watch; static int ofono_init(void) { @@ -1964,11 +2128,17 @@ 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); + 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) { err = -EIO; goto remove; } @@ -1996,6 +2166,7 @@ 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); dbus_connection_unref(connection); -- 1.7.1 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman