--- 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