diff options
author | Jaehyun Kim <jeik01.kim@samsung.com> | 2015-06-30 09:40:43 +0900 |
---|---|---|
committer | Seonah Moon <seonah1.moon@samsung.com> | 2015-07-08 16:27:34 +0900 |
commit | 87ae92a8fff91a11db13a615d9fdc1133f9e7b7a (patch) | |
tree | ab65ab6ac16d89ee4624b621049bba498717b5bd /plugins | |
parent | 569ccaa4728078c11bf7a4970a63bfd4ad840709 (diff) | |
download | connman-87ae92a8fff91a11db13a615d9fdc1133f9e7b7a.tar.gz connman-87ae92a8fff91a11db13a615d9fdc1133f9e7b7a.tar.bz2 connman-87ae92a8fff91a11db13a615d9fdc1133f9e7b7a.zip |
Fix MMS connection failure
Change-Id: Id3847d1d8233c2177cfbd65ba42ead8ff44a06a8
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/telephony.c | 1041 |
1 files changed, 594 insertions, 447 deletions
diff --git a/plugins/telephony.c b/plugins/telephony.c index 88703edf..459095db 100644 --- a/plugins/telephony.c +++ b/plugins/telephony.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,36 +19,34 @@ * */ - #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <errno.h> -#include <stdlib.h> - #include <gdbus.h> +#include <stdlib.h> #include <string.h> #define CONNMAN_API_SUBJECT_TO_CHANGE -#include <connman/plugin.h> -#include <connman/device.h> -#include <connman/network.h> -#include <connman/ipconfig.h> #include <connman/dbus.h> #include <connman/inet.h> +#include <connman/plugin.h> +#include <connman/network.h> +#include <connman/setting.h> #include <connman/technology.h> -#include <connman/log.h> + +#include <connman.h> #define PS_DBUS_SERVICE "com.tcore.ps" -#define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master" -#define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem" +#define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master" +#define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem" #define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service" #define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context" /* methods */ -#define GET_MODEMS "GetModems" +#define GET_MODEMS "GetModems" #define GET_SERVICES "GetServices" #define GET_CONTEXTS "GetContexts" #define ACTIVATE_CONTEXT "Activate" @@ -57,7 +55,7 @@ #define SET_PROPERTY "SetProperties" /* signals */ -#define MODEM_ADDED "ModemAdded" +#define MODEM_ADDED "ModemAdded" #define MODEM_REMOVED "ModemRemoved" #define SERVICE_ADDED "ServiceAdded" #define SERVICE_REMOVED "ServiceRemoved" @@ -65,9 +63,9 @@ #define CONTEXT_REMOVED "ContextRemoved" #define PROPERTY_CHANGED "PropertyChanged" -#define TIMEOUT 40000 +#define TIMEOUT 130000 -#define STRING2BOOL(a) ((g_str_equal(a, "TRUE")) ? (TRUE):(FALSE)) +#define STRING2BOOL(a) (!(g_strcmp0(a, "TRUE")) ? (TRUE):(FALSE)) static DBusConnection *connection; static GHashTable *modem_hash; @@ -99,6 +97,10 @@ struct telephony_modem { struct telephony_network { char *path; + int if_index; + gboolean routing_only; + gboolean ipv6_link_only; + struct connman_network *network; enum connman_ipconfig_method ipv4_method; @@ -108,6 +110,8 @@ struct telephony_network { struct connman_ipaddress *ipv6_address; }; +static int telephony_default_subscription_id = 0; + /* function prototype */ static void telephony_connect(DBusConnection *connection, void *user_data); static void telephony_disconnect(DBusConnection *connection, void *user_data); @@ -149,18 +153,8 @@ static void __add_service(struct telephony_modem *modem, static void __add_connman_device(const char *modem_path, const char *operator); static void __remove_connman_device(struct telephony_modem *modem); static void __remove_connman_networks(struct connman_device *device); -static void __set_device_powered(struct telephony_modem *modem, - gboolean powered); -static int __check_device_powered(const char *path, gboolean online); -static gboolean __check_network_available(struct connman_network *network); -static void __create_service(struct connman_network *network); static int __add_context(struct connman_device *device, const char *path, DBusMessageIter *prop); -static gboolean __set_network_ipconfig(struct telephony_network *network, - DBusMessageIter *dict); -static void __set_network_connected(struct telephony_network *network, - gboolean connected); -static char *__get_ident(const char *path); /* signal handler */ static gboolean __changed_modem(DBusConnection *connection, @@ -209,6 +203,7 @@ static int tech_probe(struct connman_technology *technology) static void tech_remove(struct connman_technology *technology) { + return; } static struct connman_technology_driver tech_driver = { @@ -228,8 +223,8 @@ static void telephony_connect(DBusConnection *connection, void *user_data) g_free, __remove_service); network_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_network); + __request_get_modems(); - return; } static void telephony_disconnect(DBusConnection *connection, void *user_data) @@ -245,8 +240,6 @@ static void telephony_disconnect(DBusConnection *connection, void *user_data) g_hash_table_destroy(network_hash); network_hash = NULL; } - - return; } static void __remove_modem(gpointer data) @@ -281,11 +274,37 @@ static void __remove_network(gpointer data) connman_network_unref(info->network); g_free(info->path); + connman_ipaddress_free(info->ipv4_address); connman_ipaddress_free(info->ipv6_address); + g_free(info); } +static void __set_device_powered(struct telephony_modem *modem, + gboolean powered) +{ + DBG("set modem(%s) powered(%d)", modem->path, powered); + + if (modem->device) + connman_device_set_powered(modem->device, powered); +} + +static int __check_device_powered(const char *path, gboolean powered) +{ + struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path); + + if (modem == NULL) + return -ENODEV; + + DBG("check modem (%s) powered (%d)", modem->path, modem->powered); + + if (modem->powered == powered) + return -EALREADY; + + return 0; +} + static int __modem_probe(struct connman_device *device) { DBG("device %p", device); @@ -321,30 +340,8 @@ static int __network_probe(struct connman_network *network) static int __network_connect(struct connman_network *network) { - struct connman_device *device; - struct telephony_modem *modem; - struct telephony_service *service; - 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; - - service = modem->s_service; - if (service == NULL) - return -ENOLINK; - - if (modem->powered == FALSE) - return -ENOLINK; - - if (modem->data_allowed == FALSE || service->ps_attached == FALSE) - return -ENOLINK; - return __request_network_activate(network); } @@ -352,8 +349,8 @@ static int __network_disconnect(struct connman_network *network) { DBG("network %p", network); - if (connman_network_get_index(network) < 0) - return -ENOTCONN; + if (connman_network_get_associating(network) == TRUE) + connman_network_clear_associating(network); connman_network_set_associating(network, FALSE); @@ -366,26 +363,24 @@ static void __network_remove(struct connman_network *network) DBG("network %p path %s", network, path); g_hash_table_remove(network_hash, path); - return; } static int __dbus_request(const char *path, const char *interface, - const char *method, - DBusPendingCallNotifyFunction notify, void *user_data, - DBusFreeFunction free_function, int type, ...) + const char *method, + DBusPendingCallNotifyFunction notify, void *user_data, + DBusFreeFunction free_function, int type, ...) { DBusMessage *message; DBusPendingCall *call; dbus_bool_t ok; va_list va; - DBG("Telephony request path %s %s.%s", path, interface, method); + DBG("path %s %s.%s", path, interface, method); if (path == NULL) return -EINVAL; - message = dbus_message_new_method_call(PS_DBUS_SERVICE, path, - interface, method); + message = dbus_message_new_method_call(PS_DBUS_SERVICE, path, interface, method); if (message == NULL) return -ENOMEM; @@ -451,6 +446,10 @@ static void __response_get_modems(DBusPendingCall *call, void *user_data) dbus_message_iter_recurse(&args, &dict); + /* DBG("message type (%d) dic(%d)", + * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY); + */ + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) { DBusMessageIter entry, property; const char *modem_path; @@ -470,15 +469,14 @@ static void __response_get_modems(DBusPendingCall *call, void *user_data) done: dbus_message_unref(reply); dbus_pending_call_unref(call); - return; } static int __request_get_services(const char *path) { DBG("request get service"); return __dbus_request(path, PS_MODEM_INTERFACE, GET_SERVICES, - __response_get_services, g_strdup(path), - g_free, DBUS_TYPE_INVALID); + __response_get_services, g_strdup(path), + g_free, DBUS_TYPE_INVALID); } static void __response_get_services(DBusPendingCall *call, void *user_data) @@ -515,6 +513,10 @@ static void __response_get_services(DBusPendingCall *call, void *user_data) dbus_message_iter_recurse(&args, &dict); + /* DBG("message type (%d) dic(%d)", + * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY); + */ + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) { DBusMessageIter entry, property; const char *service_path; @@ -534,16 +536,15 @@ static void __response_get_services(DBusPendingCall *call, void *user_data) done: dbus_message_unref(reply); dbus_pending_call_unref(call); - return; } static int __request_get_contexts(struct telephony_modem *modem) { DBG("request get contexts"); return __dbus_request(modem->s_service->path, - PS_SERVICE_INTERFACE, GET_CONTEXTS, - __response_get_contexts, g_strdup(modem->path), - g_free, DBUS_TYPE_INVALID); + PS_SERVICE_INTERFACE, GET_CONTEXTS, + __response_get_contexts, g_strdup(modem->path), + g_free, DBUS_TYPE_INVALID); } static void __response_get_contexts(DBusPendingCall *call, void *user_data) @@ -601,21 +602,43 @@ static void __response_get_contexts(DBusPendingCall *call, void *user_data) done: dbus_message_unref(reply); dbus_pending_call_unref(call); - return; } static int __request_network_activate(struct connman_network *network) { - DBG("request network activate"); + int n_modems; + const char *path = NULL; + struct telephony_modem *modem = NULL; - const char *path = connman_network_get_string(network, "Path"); - DBG("network %p, path %s", network, path); + n_modems = g_hash_table_size(modem_hash); + path = connman_network_get_string(network, "Path"); + modem = connman_device_get_data(connman_network_get_device(network)); + DBG("network %p, path %s, modem %s[%d]", network, path, modem->path, + telephony_default_subscription_id); + + if (modem && n_modems > 1 && g_str_has_suffix(path, "_1") == TRUE) { + char *subscribe_id = g_strdup_printf("%d", telephony_default_subscription_id); + + if (g_str_has_suffix(modem->path, subscribe_id) != TRUE) { + g_free(subscribe_id); + return -ENOLINK; + } + g_free(subscribe_id); + } return __dbus_request(path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT, __response_network_activate, g_strdup(path), NULL, DBUS_TYPE_INVALID); } +static gboolean __check_network_available(struct connman_network *network) +{ + if (network == NULL || connman_network_get_device(network) == NULL) + return FALSE; + + return TRUE; +} + static void __response_network_activate(DBusPendingCall *call, void *user_data) { DBG("network activation response"); @@ -632,7 +655,7 @@ static void __response_network_activate(DBusPendingCall *call, void *user_data) if (info == NULL) goto done; - if (!__check_network_available(info->network)) { + if (__check_network_available(info->network) == FALSE) { g_hash_table_remove(network_hash, path); goto done; } @@ -642,6 +665,14 @@ static void __response_network_activate(DBusPendingCall *call, void *user_data) connman_error("connection activate() %s %s", error.name, error.message); + if (connman_network_get_associating(info->network) == TRUE) + connman_network_set_error(info->network, + CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + + if (connman_network_get_connecting(info->network) == TRUE) + connman_network_set_error(info->network, + CONNMAN_NETWORK_ERROR_CONNECT_FAIL); + if (connman_network_get_index(info->network) < 0) connman_network_set_error(info->network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); @@ -653,18 +684,62 @@ static void __response_network_activate(DBusPendingCall *call, void *user_data) done: dbus_message_unref(reply); dbus_pending_call_unref(call); - return; } static int __request_network_deactivate(struct connman_network *network) { - DBG("request network deactivate"); - const char *path = connman_network_get_string(network, "Path"); DBG("network %p, path %s", network, path); return __dbus_request(path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT, - NULL, NULL, NULL, DBUS_TYPE_INVALID); + NULL, NULL, NULL, DBUS_TYPE_INVALID); +} + +static void __response_get_default_subscription_id(DBusPendingCall *call, + void *user_data) +{ + DBusMessage *reply; + DBusError error; + DBusMessageIter args; + + DBG(""); + + reply = dbus_pending_call_steal_reply(call); + + dbus_error_init(&error); + if (dbus_set_error_from_message(&error, reply)) { + connman_error("GetDefaultDataSubscription() %s %s", error.name, error.message); + dbus_error_free(&error); + goto done; + } + + DBG("message signature (%s)", dbus_message_get_signature(reply)); + + if (dbus_message_iter_init(reply, &args) == FALSE) + goto done; + + dbus_message_iter_get_basic(&args, &telephony_default_subscription_id); + DBG("default subscription: %d", telephony_default_subscription_id); + +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static int __request_get_default_subscription_id(const char *path) +{ + int ret; + char *telephony_modem_path = NULL; + + telephony_modem_path = g_strdup_printf("/org/tizen/telephony%s", path); + DBG("request get default subscription id %s", telephony_modem_path); + + ret = __dbus_request(telephony_modem_path, + "org.tizen.telephony.Network", "GetDefaultDataSubscription", + __response_get_default_subscription_id, NULL, NULL, DBUS_TYPE_INVALID); + + g_free(telephony_modem_path); + return ret; } static void __add_modem(const char *path, DBusMessageIter *prop) @@ -675,9 +750,9 @@ static void __add_modem(const char *path, DBusMessageIter *prop) if (modem != NULL) return; - modem = (struct telephony_modem *)malloc( - sizeof(struct telephony_modem)); - memset(modem, 0, sizeof(struct telephony_modem)); + modem = g_try_new0(struct telephony_modem, 1); + if (modem == NULL) + return; modem->path = g_strdup(path); modem->device = NULL; @@ -697,17 +772,17 @@ static void __add_modem(const char *path, DBusMessageIter *prop) DBG("key (%s) value(%s)", key, tmp); - if (g_str_equal(key, "powered") == TRUE) { + if (g_strcmp0(key, "powered") == 0) { modem->powered = STRING2BOOL(tmp); - } else if (g_str_equal(key, "operator") == TRUE) { + } else if (g_strcmp0(key, "operator") == 0) { modem->operator = g_strdup(tmp); - } else if (g_str_equal(key, "sim_init") == TRUE) { + } else if (g_strcmp0(key, "sim_init") == 0) { modem->sim_init = STRING2BOOL(tmp); - } else if (g_str_equal(key, "flight_mode") == TRUE) { + } else if (g_strcmp0(key, "flight_mode") == 0) { modem->flight_mode = STRING2BOOL(tmp); - } else if (g_str_equal(key, "roaming_allowed") == TRUE) { + } else if (g_strcmp0(key, "roaming_allowed") == 0) { modem->roaming_allowed = STRING2BOOL(tmp); - } else if (g_str_equal(key, "data_allowed") == TRUE) { + } else if (g_strcmp0(key, "data_allowed") == 0) { modem->data_allowed = STRING2BOOL(tmp); } dbus_message_iter_next(prop); @@ -716,14 +791,15 @@ static void __add_modem(const char *path, DBusMessageIter *prop) __add_connman_device(path, modem->operator); __set_device_powered(modem, modem->powered); + if (g_hash_table_size(modem_hash) > 1) + __request_get_default_subscription_id(modem->path); + if (modem->powered != TRUE) { DBG("modem is not powered"); return; } __request_get_services(modem->path); - - return; } static void __add_service(struct telephony_modem *modem, @@ -734,13 +810,10 @@ static void __add_service(struct telephony_modem *modem, if (modem->s_service != NULL) return; - service = (struct telephony_service *)g_try_malloc( - sizeof(struct telephony_service)); + service = g_try_new0(struct telephony_service, 1); if (service == NULL) return; - memset(service, 0, sizeof(struct telephony_service)); - service->path = g_strdup(service_path); service->p_modem = modem; g_hash_table_insert(service_hash, g_strdup(service_path), service); @@ -757,11 +830,11 @@ static void __add_service(struct telephony_modem *modem, DBG("key (%s) value(%s)", key, tmp); - if (g_str_equal(key, "roaming") == TRUE) { + if (g_strcmp0(key, "roaming") == 0) { service->roaming = STRING2BOOL(tmp); - } else if (g_str_equal(key, "act") == TRUE) { + } else if (g_strcmp0(key, "act") == 0) { service->act = g_strdup(tmp); - } else if (g_str_equal(key, "ps_attached") == TRUE) { + } else if (g_strcmp0(key, "ps_attached") == 0) { service->ps_attached = STRING2BOOL(tmp); } @@ -770,12 +843,25 @@ static void __add_service(struct telephony_modem *modem, modem->s_service = service; __request_get_contexts(modem); +} - return; +static char *__get_ident(const char *path) +{ + char *pos; + + if (*path != '/') + return NULL; + + pos = strrchr(path, '/'); + if (pos == NULL) + return NULL; + + return pos + 1; } static void __add_connman_device(const char *modem_path, const char *operator) { + char* ident = NULL; struct telephony_modem *modem; struct connman_device *device; @@ -806,7 +892,10 @@ static void __add_connman_device(const char *modem_path, const char *operator) if (device == NULL) return; - connman_device_set_ident(device, operator); + ident = g_strdup_printf("%s_%s", __get_ident(modem_path), operator); + connman_device_set_ident(device, ident); + g_free(ident); + connman_device_set_string(device, "Path", modem_path); connman_device_set_data(device, modem); @@ -817,8 +906,6 @@ static void __add_connman_device(const char *modem_path, const char *operator) } modem->device = device; - - return; } static void __remove_connman_device(struct telephony_modem *modem) @@ -834,8 +921,6 @@ static void __remove_connman_device(struct telephony_modem *modem) connman_device_unref(modem->device); modem->device = NULL; - - return; } static void __remove_connman_networks(struct connman_device *device) @@ -867,387 +952,409 @@ static void __remove_connman_networks(struct connman_device *device) g_slist_free(info_list); } -static void __set_device_powered(struct telephony_modem *modem, - gboolean powered) -{ - DBG("set modem(%s) powered(%d)", modem->path, powered); - - if (modem->device) - connman_device_set_powered(modem->device, powered); - - return; -} - -static int __check_device_powered(const char *path, gboolean powered) +static gboolean connman_ipaddress_updated(struct connman_ipaddress *ipaddress, + const char *address, const char *gateway) { - struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path); - - if (modem == NULL) - return -ENODEV; - - DBG("check modem (%s) powered (%d)", modem->path, modem->powered); - - if (modem->powered == powered) - return -EALREADY; + if (ipaddress == NULL || address == NULL) + return FALSE; - return 0; -} + if (g_strcmp0(ipaddress->local, address) != 0) + return TRUE; -static gboolean __check_network_available(struct connman_network *network) -{ - if (network == NULL || connman_network_get_device(network) == NULL) { - DBG("Modem or network was removed"); - return FALSE; - } + if (g_strcmp0(ipaddress->gateway, gateway) != 0) + return TRUE; - return TRUE; + return FALSE; } -static int __add_context(struct connman_device *device, const char *path, - DBusMessageIter *prop) +static void __set_network_connected(struct telephony_network *network, + gboolean connected) { - char *ident; - gboolean active = FALSE; - - struct telephony_modem *modem = connman_device_get_data(device); - struct connman_network *network; - struct telephony_network *info; - - DBG("modem %p device %p path %s", modem, device, path); - - ident = __get_ident(path); - - network = connman_device_get_network(device, ident); - if (network != NULL) - return -EALREADY; - - info = g_hash_table_lookup(network_hash, path); - if (info != NULL) { - DBG("path %p already exists with device %p", path, - connman_network_get_device(info->network)); - - if (connman_network_get_device(info->network)) - return -EALREADY; + gboolean setip = FALSE; - g_hash_table_remove(network_hash, path); - } + DBG("network %p connected %d", network, connected); - network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR); - if (network == NULL) - return -ENOMEM; + connman_network_set_index(network->network, network->if_index); + if (connman_network_get_connected(network->network) == connected) + return; - info = (struct telephony_network *)g_try_malloc( - sizeof(struct telephony_network)); - if (info == NULL) { - connman_network_unref(network); - return -ENOMEM; + switch (network->ipv4_method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_DHCP: + case CONNMAN_IPCONFIG_METHOD_AUTO: + case CONNMAN_IPCONFIG_METHOD_OFF: + connman_network_set_ipv4_method(network->network, + network->ipv4_method); + break; + case CONNMAN_IPCONFIG_METHOD_MANUAL: + case CONNMAN_IPCONFIG_METHOD_FIXED: + connman_network_set_ipv4_method(network->network, + network->ipv4_method); + connman_network_set_ipaddress(network->network, + network->ipv4_address); + setip = TRUE; + break; } - memset(info, 0, sizeof(struct telephony_network)); - - info->path = g_strdup(path); - - connman_ipaddress_clear(info->ipv4_address); - connman_ipaddress_clear(info->ipv6_address); - info->network = network; - - connman_network_set_string(network, "Path", path); - connman_network_set_name(network, path); - - __create_service(network); - - g_hash_table_insert(network_hash, g_strdup(path), info); - - connman_network_set_available(network, TRUE); - connman_network_set_index(network, -1); - connman_network_set_bool(network, "Roaming", modem->s_service->roaming); - - if (connman_device_add_network(device, network) != 0) { - g_hash_table_remove(network_hash, path); - return -EIO; + switch (network->ipv6_method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_DHCP: + break; + case CONNMAN_IPCONFIG_METHOD_AUTO: + connman_network_set_ipv6_method(network->network, + network->ipv6_method); + setip = TRUE; + break; + case CONNMAN_IPCONFIG_METHOD_MANUAL: + case CONNMAN_IPCONFIG_METHOD_FIXED: + connman_network_set_ipv6_method(network->network, + network->ipv6_method); + connman_network_set_ipaddress(network->network, + network->ipv6_address); + setip = TRUE; + break; } - active = __set_network_ipconfig(info, prop); - - if (active && (connman_network_get_connecting(network) || - connman_network_get_associating(network))) - __set_network_connected(info, active); - - return 0; -} - -static void __create_service(struct connman_network *network) -{ - const char *path; - char *group; - - DBG(""); - - path = connman_network_get_string(network, "Path"); - - group = __get_ident(path); - - connman_network_set_group(network, group); + if (setip == TRUE) + connman_network_set_connected(network->network, connected); } -static gboolean __set_network_ipconfig(struct telephony_network *network, - DBusMessageIter *dict) +static gboolean __set_network_context( + struct telephony_network *network, + DBusMessageIter *dict) { - DBG("set network info"); - + int index = 0; gboolean active = FALSE; - char *dev_name = NULL, *proxy_addr = NULL; + gboolean routing_only = FALSE; + gboolean ipv4_updated = FALSE; + gboolean ipv6_updated = FALSE; + gboolean ipv6_link_only = FALSE; + gboolean default_internet = FALSE; + gboolean active_proxy = FALSE; + char **proxies = NULL; + const char *dev_name = NULL; + const char *proxy_addr = NULL; char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL, *ipv4_dns1 = NULL, *ipv4_dns2 = NULL; char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL, *ipv6_dns1 = NULL, *ipv6_dns2 = NULL; - int index; - int dns_flag = 0; + struct connman_service *service; while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) { DBusMessageIter entry; - const char *key, *tmp; + const char *key, *value; dbus_message_iter_recurse(dict, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); - DBG("key (%s)", key); - - if (g_str_equal(key, "dev_name") == TRUE) { + if (g_strcmp0(key, "dev_name") == 0) { dbus_message_iter_get_basic(&entry, &dev_name); DBG("dev_name (%s)", dev_name); - } else if (g_str_equal(key, "proxy") == TRUE) { + } else if (g_strcmp0(key, "proxy") == 0) { dbus_message_iter_get_basic(&entry, &proxy_addr); - } else if (g_str_equal(key, "ipv4_address") == TRUE) { + DBG("proxy_addr (%s)", proxy_addr); + } else if (g_strcmp0(key, "ipv4_address") == 0) { dbus_message_iter_get_basic(&entry, &ipv4_addr); - DBG("ipv4 address (%s)", ipv4_addr); - } else if (g_str_equal(key, "ipv4_gateway") == TRUE) { + DBG("ipv4_addr (%s)", ipv4_addr); + } else if (g_strcmp0(key, "ipv4_gateway") == 0) { dbus_message_iter_get_basic(&entry, &ipv4_gw); - } else if (g_str_equal(key, "ipv4_netmask") == TRUE) { + DBG("ipv4_gw (%s)", ipv4_gw); + } else if (g_strcmp0(key, "ipv4_netmask") == 0) { dbus_message_iter_get_basic(&entry, &ipv4_netmask); - } else if (g_str_equal(key, "ipv4_dns1") == TRUE) { + DBG("ipv4_netmask (%s)", ipv4_netmask); + } else if (g_strcmp0(key, "ipv4_dns1") == 0) { dbus_message_iter_get_basic(&entry, &ipv4_dns1); - } else if (g_str_equal(key, "ipv4_dns2") == TRUE) { + DBG("ipv4_dns1 (%s)", ipv4_dns1); + } else if (g_strcmp0(key, "ipv4_dns2") == 0) { dbus_message_iter_get_basic(&entry, &ipv4_dns2); - } else if (g_str_equal(key, "ipv6_address") == TRUE) { + DBG("ipv4_dns2 (%s)", ipv4_dns2); + } else if (g_strcmp0(key, "ipv6_address") == 0) { dbus_message_iter_get_basic(&entry, &ipv6_addr); DBG("ipv6 address (%s)", ipv6_addr); - } else if (g_str_equal(key, "ipv6_gateway") == TRUE) { + } else if (g_strcmp0(key, "ipv6_gateway") == 0) { dbus_message_iter_get_basic(&entry, &ipv6_gw); - } else if (g_str_equal(key, "ipv6_netmask") == TRUE) { + DBG("ipv6_gw (%s)", ipv6_gw); + } else if (g_strcmp0(key, "ipv6_netmask") == 0) { dbus_message_iter_get_basic(&entry, &ipv6_netmask); - } else if (g_str_equal(key, "ipv6_dns1") == TRUE) { + DBG("ipv6_netmask (%s)", ipv6_netmask); + } else if (g_strcmp0(key, "ipv6_dns1") == 0) { dbus_message_iter_get_basic(&entry, &ipv6_dns1); - } else if (g_str_equal(key, "ipv6_dns2") == TRUE) { + DBG("ipv6_dns1 (%s)", ipv6_dns1); + } else if (g_strcmp0(key, "ipv6_dns2") == 0) { dbus_message_iter_get_basic(&entry, &ipv6_dns2); - } else if (g_str_equal(key, "active") == TRUE) { - dbus_message_iter_get_basic(&entry, &tmp); - DBG("active (%s)", tmp); - active = STRING2BOOL(tmp); + DBG("ipv6_dns2 (%s)", ipv6_dns2); + } else if (g_strcmp0(key, "active") == 0) { + dbus_message_iter_get_basic(&entry, &value); + DBG("active (%s)", value); + active = STRING2BOOL(value); + } else if (g_strcmp0(key, "routing_only") == 0) { + dbus_message_iter_get_basic(&entry, &value); + DBG("routing_only (%s)", value); + routing_only = STRING2BOOL(value); + network->routing_only = routing_only; + } else if (g_strcmp0(key, "ipv6_link_only") == 0) { + dbus_message_iter_get_basic(&entry, &value); + DBG("ipv6_link_only (%s)", value); + ipv6_link_only = STRING2BOOL(value); + network->ipv6_link_only = ipv6_link_only; + } + else if (g_strcmp0(key, "default_internet_conn") == 0) { + dbus_message_iter_get_basic(&entry, &value); + DBG("default_internet (%s)", value); + default_internet = STRING2BOOL(value); } dbus_message_iter_next(dict); } - /* interface index set */ - if (dev_name == NULL) - dev_name = ""; + if(routing_only){ + //context active does not effect the connman service status. + //it only for setting the routing path. + DBG("routing_only(%d), active(%d)", routing_only, active); + return active; + } + + if (g_strcmp0(proxy_addr, ":") == 0) + proxy_addr = NULL; + if (g_strcmp0(ipv4_addr, "0.0.0.0") == 0) + ipv4_addr = NULL; + if (g_strcmp0(ipv4_gw, "0.0.0.0") == 0) + ipv4_gw = NULL; + if (g_strcmp0(ipv4_netmask, "0.0.0.0") == 0) + ipv4_netmask = NULL; + if (g_strcmp0(ipv4_dns1, "0.0.0.0") == 0) + ipv4_dns1 = NULL; + if (g_strcmp0(ipv4_dns2, "0.0.0.0") == 0) + ipv4_dns2 = NULL; + if (g_strcmp0(ipv6_addr, "::") == 0) + ipv6_addr = NULL; + if (g_strcmp0(ipv6_gw, "::") == 0) + ipv6_gw = NULL; + if (g_strcmp0(ipv6_netmask, "::") == 0) + ipv6_netmask = NULL; + if (g_strcmp0(ipv6_dns1, "::") == 0) + ipv6_dns1 = NULL; + if (g_strcmp0(ipv6_dns2, "::") == 0) + ipv6_dns2 = NULL; + + connman_network_set_bool(network->network, "DefaultInternet", + (bool)default_internet); + + service = connman_service_lookup_from_network(network->network); + if (service == NULL) + return FALSE; + + if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) { + /* Wi-Fi technology is always a top priority */ + if (active == TRUE && + connman_service_is_no_ref_user_pdn_connection(service) == TRUE && + connman_service_get_type(connman_service_get_default_connection()) + == CONNMAN_SERVICE_TYPE_WIFI) { + __request_network_deactivate(network->network); + + return FALSE; + } + } - if (!g_str_equal(dev_name, "")) { + /* interface index set */ + if (dev_name != NULL) { index = connman_inet_ifindex(dev_name); - DBG("interface %s, index %d", dev_name, index); - connman_network_set_index(network->network, index); + network->if_index = index; + DBG("interface index %d", index); } /* proxy set */ - if (proxy_addr == NULL) - proxy_addr = ""; + if (active == TRUE && + connman_network_get_connected(network->network) == TRUE) + active_proxy = TRUE; - DBG("proxy (%s) is set", proxy_addr); - connman_network_set_proxy(network->network, proxy_addr); + proxies = connman_service_get_proxy_servers(service); + if (proxies != NULL) { + if (proxy_addr == NULL) + connman_service_set_proxy(service, proxy_addr, active_proxy); + else if (g_strcmp0(proxy_addr, proxies[0]) != 0) + connman_service_set_proxy(service, proxy_addr, active_proxy); + } else if (proxy_addr != NULL) + connman_service_set_proxy(service, proxy_addr, active_proxy); + + if (proxies != NULL) + g_strfreev(proxies); + + __connman_service_nameserver_clear(service); /* ipv4 set */ - if (ipv4_addr == NULL) - ipv4_addr = "0.0.0.0"; + if (network->ipv4_address == NULL) + network->ipv4_address = + connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4); + + if (network->ipv4_address == NULL) + return FALSE; - if (g_str_equal(ipv4_addr, "0.0.0.0")) { + if (ipv4_addr == NULL && active == TRUE) network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF; - } else { + else network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED; - network->ipv4_address = - connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4); - if (network->ipv4_address == NULL) - return FALSE; + connman_network_set_ipv4_method(network->network, network->ipv4_method); + + ipv4_updated = connman_ipaddress_updated(network->ipv4_address, + ipv4_addr, ipv4_gw); + if (ipv4_updated == TRUE) connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr, ipv4_netmask, ipv4_gw); - if (ipv4_dns1 == NULL) - ipv4_dns1 = "0.0.0.0"; - if (ipv4_dns2 == NULL) - ipv4_dns2 = "0.0.0.0"; - - if (g_str_equal(ipv4_dns1, "0.0.0.0")) - dns_flag += 1; - - if (g_str_equal(ipv4_dns2, "0.0.0.0")) - dns_flag += 2; - - gchar *nameservers = NULL; - - switch (dns_flag) { - case 0: - nameservers = g_strdup_printf("%s %s", ipv4_dns1, - ipv4_dns2); - break; - case 1: - nameservers = g_strdup_printf("%s", ipv4_dns2); - break; - case 2: - nameservers = g_strdup_printf("%s", ipv4_dns1); - } - - connman_network_set_nameservers(network->network, nameservers); - g_free(nameservers); - } + if (ipv4_dns1) + __connman_service_nameserver_append(service, ipv4_dns1, FALSE); + //if (ipv4_dns2) + if (ipv4_dns2 && !ipv4_dns1) + __connman_service_nameserver_append(service, ipv4_dns2, FALSE); /* ipv6 set */ - if (ipv6_addr == NULL) - ipv6_addr = "::"; + if (network->ipv6_address == NULL) + network->ipv6_address = + connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6); - if (g_str_equal(ipv6_addr, "::")) { - network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF; - } else { + if (network->ipv6_address == NULL) + return FALSE; + + if(ipv6_link_only) + network->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO; + else network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED; - unsigned char prefix_length = 64; - network->ipv6_address = - connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6); - if (network->ipv6_address == NULL) - return FALSE; - connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr, - prefix_length, ipv6_gw); + if (ipv6_addr == NULL) + network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF; - dns_flag = 0; + connman_network_set_ipv6_method(network->network, network->ipv6_method); - if (ipv6_dns1 == NULL) - ipv6_dns1 = "::"; - if (ipv6_dns2 == NULL) - ipv6_dns2 = "::"; + ipv6_updated = connman_ipaddress_updated(network->ipv6_address, + ipv6_addr, ipv6_gw); + if (ipv6_updated == TRUE) + connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr, + 64, ipv6_gw); - if (g_str_equal(ipv6_dns1, "::")) - dns_flag += 1; + if (ipv6_dns1) + __connman_service_nameserver_append(service, ipv6_dns1, FALSE); + //if (ipv6_dns2) + if (ipv6_dns2 && !ipv6_dns1) + __connman_service_nameserver_append(service, ipv6_dns2, FALSE); - if (g_str_equal(ipv6_dns2, "::")) - dns_flag += 2; + if (active == TRUE && + connman_network_get_connected(network->network) == TRUE) { + if (ipv4_updated == TRUE || ipv6_updated == TRUE) { + DBG("IPv4 updated %d, IPv6 updated %d", ipv4_updated, ipv6_updated); - gchar *nameservers = NULL; + __set_network_connected(network, FALSE); + } else { + DBG("Already connected"); - switch (dns_flag) { - case 0: - nameservers = g_strdup_printf("%s %s", ipv6_dns1, - ipv6_dns2); - break; - case 1: - nameservers = g_strdup_printf("%s", ipv6_dns2); - break; - case 2: - nameservers = g_strdup_printf("%s", ipv6_dns1); + return active; } - - connman_network_set_nameservers(network->network, nameservers); - g_free(nameservers); } - if (active) + if (active == TRUE) connman_network_set_associating(network->network, TRUE); return active; } -static void __set_network_connected(struct telephony_network *network, - gboolean connected) +static int __add_context(struct connman_device *device, const char *path, + DBusMessageIter *prop) { - gboolean setip = FALSE; + char *ident; + gboolean active = FALSE; - DBG("network %p connected %d", network, connected); + struct telephony_modem *modem = connman_device_get_data(device); + struct connman_network *network; + struct telephony_network *info; - switch (network->ipv4_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - case CONNMAN_IPCONFIG_METHOD_AUTO: - setip = TRUE; - break; + DBG("modem %p device %p path %s", modem, device, path); - case CONNMAN_IPCONFIG_METHOD_FIXED: - connman_network_set_ipv4_method(network->network, - network->ipv4_method); - connman_network_set_ipaddress(network->network, - network->ipv4_address); - setip = TRUE; - break; + ident = __get_ident(path); - case CONNMAN_IPCONFIG_METHOD_DHCP: - connman_network_set_ipv4_method(network->network, - network->ipv4_method); - setip = TRUE; - break; + network = connman_device_get_network(device, ident); + if (network != NULL) + return -EALREADY; + + info = g_hash_table_lookup(network_hash, path); + if (info != NULL) { + DBG("path %p already exists with device %p", path, + connman_network_get_device(info->network)); + + if (connman_network_get_device(info->network)) + return -EALREADY; + + g_hash_table_remove(network_hash, path); } - switch (network->ipv6_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - case CONNMAN_IPCONFIG_METHOD_DHCP: - break; - case CONNMAN_IPCONFIG_METHOD_AUTO: - connman_network_set_ipv6_method(network->network, - network->ipv6_method); - setip = TRUE; - break; + network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR); + if (network == NULL) + return -ENOMEM; - case CONNMAN_IPCONFIG_METHOD_FIXED: - connman_network_set_ipv6_method(network->network, - network->ipv6_method); - connman_network_set_ipaddress(network->network, - network->ipv6_address); - setip = TRUE; - break; + info = g_try_new0(struct telephony_network, 1); + if (info == NULL) { + connman_network_unref(network); + return -ENOMEM; } - if (setip == TRUE) - connman_network_set_connected(network->network, connected); + info->path = g_strdup(path); - return; -} + connman_ipaddress_clear(info->ipv4_address); + connman_ipaddress_clear(info->ipv6_address); -static char *__get_ident(const char *path) -{ - char *pos; + info->network = network; - if (*path != '/') - return NULL; + connman_network_set_string(network, "Path", path); + connman_network_set_name(network, path); - pos = strrchr(path, '/'); - if (pos == NULL) - return NULL; + connman_network_set_group(network, ident); - return pos + 1; + g_hash_table_insert(network_hash, g_strdup(path), info); + + connman_network_set_available(network, TRUE); + connman_network_set_bool(network, "Roaming", (bool)modem->s_service->roaming); + + if (connman_device_add_network(device, network) != 0) { + g_hash_table_remove(network_hash, path); + return -EIO; + } + + active = __set_network_context(info, prop); + if(info->routing_only){ + int err = 0; + struct connman_service *routing_service; + struct connman_ipconfig *routing_ipconfig; + + if(!active) + return TRUE; + + routing_service = connman_service_lookup_from_network(info->network); + routing_ipconfig = __connman_service_get_ip4config(routing_service); + err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service); + + DBG("set gateway rv(%d)", err); + return TRUE; + } + + if (active == TRUE && (connman_network_get_associating(network) == TRUE || + connman_network_get_connecting(network) == TRUE)) + __set_network_connected(info, active); + + return 0; } static gboolean __changed_modem(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("modem changed signal"); - + gboolean old_powered; DBusMessageIter args, dict; - const char *path = dbus_message_get_path(message); struct telephony_modem *modem; + const char *path = dbus_message_get_path(message); - DBG("modem path %s", path); + DBG("modem changed signal %s", path); modem = g_hash_table_lookup(modem_hash, path); if (modem == NULL) { @@ -1255,6 +1362,8 @@ static gboolean __changed_modem(DBusConnection *connection, return TRUE; } + old_powered = modem->powered; + DBG("message signature (%s)", dbus_message_get_signature(message)); if (dbus_message_iter_init(message, &args) == FALSE) { @@ -1276,17 +1385,17 @@ static gboolean __changed_modem(DBusConnection *connection, DBG("key(%s), value(%s)", key, tmp); - if (g_str_equal(key, "powered") == TRUE) { + if (g_strcmp0(key, "powered") == 0) { modem->powered = STRING2BOOL(tmp); - } else if (g_str_equal(key, "operator") == TRUE) { + } else if (g_strcmp0(key, "operator") == 0) { modem->operator = g_strdup(tmp); - } else if (g_str_equal(key, "sim_init") == TRUE) { + } else if (g_strcmp0(key, "sim_init") == 0) { modem->sim_init = STRING2BOOL(tmp); - } else if (g_str_equal(key, "flight_mode") == TRUE) { + } else if (g_strcmp0(key, "flight_mode") == 0) { modem->flight_mode = STRING2BOOL(tmp); - } else if (g_str_equal(key, "roaming_allowed") == TRUE) { + } else if (g_strcmp0(key, "roaming_allowed") == 0) { modem->roaming_allowed = STRING2BOOL(tmp); - } else if (g_str_equal(key, "data_allowed") == TRUE) { + } else if (g_strcmp0(key, "data_allowed") == 0) { modem->data_allowed = STRING2BOOL(tmp); } @@ -1296,23 +1405,21 @@ static gboolean __changed_modem(DBusConnection *connection, if (modem->device == NULL) __add_connman_device(path, modem->operator); - __set_device_powered(modem, modem->powered); + if (old_powered != modem->powered) + __set_device_powered(modem, modem->powered); if (modem->powered != TRUE) { DBG("modem is not powered"); return TRUE; } - if (!modem->s_service) { + if (modem->s_service == NULL) { __request_get_services(modem->path); return TRUE; } - if (modem->flight_mode || !modem->data_allowed) { - DBG("modem(%s) flight mode(%d) data allowed(%d)", + DBG("modem(%s) flight mode(%d) data allowed(%d)", modem->path, modem->flight_mode, modem->data_allowed); - return TRUE; - } return TRUE; } @@ -1320,12 +1427,11 @@ static gboolean __changed_modem(DBusConnection *connection, static gboolean __added_modem(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("modem added signal"); - const char *modem_path = NULL; DBusMessageIter args, dict, tmp; - DBG("message signature (%s)", dbus_message_get_signature(message)); + DBG("modem added signal (%s)", dbus_message_get_signature(message)); + if (dbus_message_iter_init(message, &args) == FALSE) { DBG("error to read message"); return TRUE; @@ -1346,7 +1452,7 @@ static gboolean __added_modem(DBusConnection *connection, DBG("key (%s) value(%s)", key, value); - if (g_str_equal(key, "path") == TRUE) + if (g_strcmp0(key, "path") == 0) modem_path = g_strdup(value); dbus_message_iter_next(&tmp); @@ -1361,11 +1467,11 @@ static gboolean __added_modem(DBusConnection *connection, static gboolean __removed_modem(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("modem removed signal"); - DBusMessageIter iter; const char *modem_path; + DBG("modem removed signal"); + if (dbus_message_iter_init(message, &iter) == FALSE) { DBG("error to read message"); return TRUE; @@ -1380,15 +1486,13 @@ static gboolean __removed_modem(DBusConnection *connection, static gboolean __changed_service(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("service changed signal"); - DBusMessageIter args, dict; - const char *service_path = dbus_message_get_path(message); struct telephony_modem *modem; - struct telephony_service *s_service; gboolean roaming_option = TRUE; + struct telephony_service *s_service; + const char *service_path = dbus_message_get_path(message); - DBG("service path %s", service_path); + DBG("service changed signal %s", service_path); s_service = g_hash_table_lookup(service_hash, service_path); if (s_service == NULL) { @@ -1423,11 +1527,11 @@ static gboolean __changed_service(DBusConnection *connection, DBG("key(%s), value(%s)", key, tmp); - if (g_str_equal(key, "roaming") == TRUE) { + if (g_strcmp0(key, "roaming") == 0) { s_service->roaming = STRING2BOOL(tmp); - } else if (g_str_equal(key, "act") == TRUE) { + } else if (g_strcmp0(key, "act") == 0) { s_service->act = g_strdup(tmp); - } else if (g_str_equal(key, "ps_attached") == TRUE) { + } else if (g_strcmp0(key, "ps_attached") == 0) { s_service->ps_attached = STRING2BOOL(tmp); } @@ -1440,16 +1544,15 @@ static gboolean __changed_service(DBusConnection *connection, return TRUE; } - static gboolean __added_service(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("service added signal"); - - const char *path = dbus_message_get_path(message); + struct telephony_modem *modem; const char *service_path = NULL; DBusMessageIter args, dict, tmp; - struct telephony_modem *modem; + const char *path = dbus_message_get_path(message); + + DBG("service added signal %s", path); modem = g_hash_table_lookup(modem_hash, path); if (modem == NULL || modem->device == NULL) @@ -1476,9 +1579,8 @@ static gboolean __added_service(DBusConnection *connection, DBG("key (%s) value(%s)", key, value); - if (g_str_equal(key, "path") == TRUE) { - service_path = g_strdup(value); - } + if (g_strcmp0(key, "path") == 0) + service_path = value; dbus_message_iter_next(&tmp); } @@ -1492,11 +1594,11 @@ static gboolean __added_service(DBusConnection *connection, static gboolean __removed_service(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("service removed signal"); - DBusMessageIter iter; const char *service_path; + DBG("service removed signal"); + if (dbus_message_iter_init(message, &iter) == FALSE) { DBG("error to read message"); return TRUE; @@ -1511,19 +1613,18 @@ static gboolean __removed_service(DBusConnection *connection, static gboolean __changed_context(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("network changed signal"); - gboolean active = FALSE; - const char *path = dbus_message_get_path(message); - struct telephony_network *info; DBusMessageIter args, dict; + struct telephony_network *info; + const char *path = dbus_message_get_path(message); + + DBG("network changed signal %s", path); - DBG("path %s", path); info = g_hash_table_lookup(network_hash, path); if (info == NULL) return TRUE; - if (!__check_network_available(info->network)) { + if (__check_network_available(info->network) == FALSE) { g_hash_table_remove(network_hash, path); return TRUE; } @@ -1535,13 +1636,28 @@ static gboolean __changed_context(DBusConnection *connection, dbus_message_iter_recurse(&args, &dict); - active = __set_network_ipconfig(info, &dict); + active = __set_network_context(info, &dict); + if(info->routing_only){ + int err = 0; + struct connman_service *routing_service; + struct connman_ipconfig *routing_ipconfig; - if (active == FALSE) - __set_network_connected(info, active); - else if ((connman_network_get_connecting(info->network) || - connman_network_get_associating(info->network))) - __set_network_connected(info, active); + if(!active) + return TRUE; + + routing_service = connman_service_lookup_from_network(info->network); + routing_ipconfig = __connman_service_get_ip4config(routing_service); + err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service); + + DBG("set gateway rv(%d)", err); + return TRUE; + } + + __set_network_connected(info, active); + + if (active == FALSE && + connman_network_get_connecting(info->network) == TRUE) + connman_network_set_connected(info->network, FALSE); return TRUE; } @@ -1549,13 +1665,13 @@ static gboolean __changed_context(DBusConnection *connection, static gboolean __added_context(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("network added signal"); - - DBusMessageIter args, dict, tmp; - const char *path = dbus_message_get_path(message); const char *network_path = NULL; - struct telephony_service *service = NULL; + DBusMessageIter args, dict, tmp; struct telephony_modem *modem = NULL; + struct telephony_service *service = NULL; + const char *path = dbus_message_get_path(message); + + DBG("network added signal %s", path); service = g_hash_table_lookup(service_hash, path); if (service == NULL || service->p_modem == NULL) @@ -1586,7 +1702,7 @@ static gboolean __added_context(DBusConnection *connection, DBG("key (%s) value(%s)", key, value); - if (g_str_equal(key, "path") == TRUE) + if (g_strcmp0(key, "path") == 0) network_path = g_strdup(value); dbus_message_iter_next(&tmp); @@ -1601,12 +1717,12 @@ static gboolean __added_context(DBusConnection *connection, static gboolean __removed_context(DBusConnection *connection, DBusMessage *message, void *user_data) { - DBG("network removed signal"); - DBusMessageIter iter; - const char *path = dbus_message_get_path(message); const char *network_path = NULL; struct telephony_service *service = NULL; + const char *path = dbus_message_get_path(message); + + DBG("network removed signal %s", path); service = g_hash_table_lookup(service_hash, path); if (service == NULL || service->p_modem == NULL) @@ -1623,23 +1739,40 @@ static gboolean __removed_context(DBusConnection *connection, return TRUE; } +static gboolean __changed_default_subscription(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + DBusMessageIter args; + + DBG("message signature (%s)", dbus_message_get_signature(message)); + if (dbus_message_iter_init(message, &args) == FALSE) + return TRUE; + + dbus_message_iter_get_basic(&args, &telephony_default_subscription_id); + DBG("default subscription: %d", telephony_default_subscription_id); + + return TRUE; +} + /* telephony initialization */ -static guint watch; -static guint modem_watch; -static guint modem_added_watch; -static guint modem_removed_watch; -static guint service_watch; -static guint service_added_watch; -static guint service_removed_watch; -static guint context_watch; -static guint context_added_watch; -static guint context_removed_watch; +static guint watch = 0; +static guint modem_watch = 0; +static guint modem_added_watch = 0; +static guint modem_removed_watch = 0; +static guint service_watch = 0; +static guint service_added_watch = 0; +static guint service_removed_watch = 0; +static guint context_watch = 0; +static guint context_added_watch = 0; +static guint context_removed_watch = 0; +static guint default_subscription_watch = 0; static int telephony_init(void) { - DBG("telephony plugin"); int err; + DBG("telephony plugin"); + connection = connman_dbus_get_connection(); if (connection == NULL) return -EIO; @@ -1652,16 +1785,19 @@ static int telephony_init(void) modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MODEM_INTERFACE, PROPERTY_CHANGED, - __changed_modem, NULL, NULL); + __changed_modem, + NULL, NULL); modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MASTER_INTERFACE, - MODEM_ADDED, __added_modem, + MODEM_ADDED, + __added_modem, NULL, NULL); modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MASTER_INTERFACE, - MODEM_REMOVED, __removed_modem, + MODEM_REMOVED, + __removed_modem, NULL, NULL); service_watch = g_dbus_add_signal_watch(connection, NULL, NULL, @@ -1672,7 +1808,8 @@ static int telephony_init(void) service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MODEM_INTERFACE, - SERVICE_ADDED, __added_service, + SERVICE_ADDED, + __added_service, NULL, NULL); service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, @@ -1689,7 +1826,8 @@ static int telephony_init(void) context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_SERVICE_INTERFACE, - CONTEXT_ADDED, __added_context, + CONTEXT_ADDED, + __added_context, NULL, NULL); context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, @@ -1698,12 +1836,19 @@ static int telephony_init(void) __removed_context, NULL, NULL); + default_subscription_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + "org.tizen.telephony.Network", + "DefaultDataSubscription", + __changed_default_subscription, + NULL, NULL); + if (watch == 0 || modem_watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0 || service_watch == 0 || service_added_watch == 0 || context_watch == 0 || service_removed_watch == 0 || context_added_watch == 0 - || context_removed_watch == 0) { + || context_removed_watch == 0 + || default_subscription_watch == 0) { err = -EIO; goto remove; } @@ -1738,6 +1883,7 @@ remove: g_dbus_remove_watch(connection, context_watch); g_dbus_remove_watch(connection, context_added_watch); g_dbus_remove_watch(connection, context_removed_watch); + g_dbus_remove_watch(connection, default_subscription_watch); dbus_connection_unref(connection); return err; @@ -1755,6 +1901,7 @@ static void telephony_exit(void) g_dbus_remove_watch(connection, context_watch); g_dbus_remove_watch(connection, context_added_watch); g_dbus_remove_watch(connection, context_removed_watch); + g_dbus_remove_watch(connection, default_subscription_watch); telephony_disconnect(connection, NULL); |