diff options
author | Arron Wang <arron.wang@intel.com> | 2012-10-25 17:17:04 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2013-07-01 11:05:18 +0800 |
commit | 2d63b07b78a1880d70975765880c5dd62e467663 (patch) | |
tree | a4c09f7d522256e9849333e5a866e8b5253c0091 /src | |
parent | 9dabc5af5a19a7da74357afcf9f3301ada173e8e (diff) | |
download | connman-2d63b07b78a1880d70975765880c5dd62e467663.tar.gz connman-2d63b07b78a1880d70975765880c5dd62e467663.tar.bz2 connman-2d63b07b78a1880d70975765880c5dd62e467663.zip |
Tizen: Add refcount for cellular service connection
TIZEN implements system global connection management.
It's only for PDP (cellular) bearer. Wi-Fi is managed
by ConnMan automatically. Reference count can help to
manage open/close connection requests by each application.
Diffstat (limited to 'src')
-rw-r--r-- | src/network.c | 3 | ||||
-rw-r--r-- | src/service.c | 85 |
2 files changed, 88 insertions, 0 deletions
diff --git a/src/network.c b/src/network.c index aba9a014..5df3e123 100644 --- a/src/network.c +++ b/src/network.c @@ -1517,6 +1517,9 @@ int __connman_network_connect(struct connman_network *network) network->connecting = TRUE; +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif __connman_device_disconnect(network->device); err = network->driver->connect(network); diff --git a/src/service.c b/src/service.c index 893b4fce..3f6f12c9 100644 --- a/src/service.c +++ b/src/service.c @@ -127,6 +127,15 @@ struct connman_service { connman_bool_t hidden_service; char *config_file; char *config_entry; +#if defined TIZEN_EXT + /* + * Description: TIZEN implements system global connection management. + * It's only for PDP (cellular) bearer. Wi-Fi is managed + * by ConnMan automatically. Reference count can help to + * manage open/close connection requests by each application. + */ + int user_pdn_connection_refcount; +#endif }; static connman_bool_t allow_property_changed(struct connman_service *service); @@ -142,6 +151,40 @@ struct find_data { struct connman_service *service; }; +#if defined TIZEN_EXT +/* + * Public APIs to use user_pdn_connection_refcount + */ +void connman_service_user_pdn_connection_ref(struct connman_service *service) +{ + __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1); + DBG("User make a PDP connection with already refcount: %d", + service->user_pdn_connection_refcount); +} + +connman_bool_t connman_service_user_pdn_connection_unref_and_test( + struct connman_service *service) +{ + DBG("User disconnect PDP connection with already refcount: %d", + service->user_pdn_connection_refcount); + + if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) + > 0) + return FALSE; + + return TRUE; +} + +connman_bool_t connman_service_is_no_ref_user_pdn_connection( + struct connman_service *service) +{ + __sync_synchronize(); + if (service->user_pdn_connection_refcount == 0) + return TRUE; + + return FALSE; +} +#endif static void compare_path(gpointer value, gpointer user_data) { struct connman_service *service = value; @@ -3822,6 +3865,10 @@ static DBusMessage *connect_service(DBusConnection *conn, DBG("service %p", service); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + connman_service_user_pdn_connection_ref(service); +#endif if (service->pending != NULL) return __connman_error_in_progress(msg); @@ -3890,6 +3937,16 @@ static DBusMessage *disconnect_service(DBusConnection *conn, DBG("service %p", service); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) { + if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE) + return __connman_error_failed(msg, EISCONN); + + if (is_connected(service) == TRUE && + service == __connman_service_get_default()) + return __connman_error_failed(msg, EISCONN); + } +#endif reply_pending(service, ECONNABORTED); service->ignore = TRUE; @@ -4436,6 +4493,9 @@ static void service_initialize(struct connman_service *service) service->provider = NULL; service->wps = FALSE; +#if defined TIZEN_EXT + service->user_pdn_connection_refcount = 0; +#endif } /** @@ -5117,18 +5177,38 @@ static int service_update_preferred_order(struct connman_service *default_servic return -EALREADY; } +#if defined TIZEN_EXT +static connman_bool_t __connman_service_can_drop_cellular( + struct connman_service *cellular) +{ + if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR && + is_connected(cellular) == TRUE) + if (connman_service_is_no_ref_user_pdn_connection(cellular) + == TRUE) + return TRUE; + return FALSE; +} +#endif + static void single_connected_tech(struct connman_service *allowed) { GSList *services = NULL; GSequenceIter *iter; GSList *list; +#if defined TIZEN_EXT + if (allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR) + return; +#endif iter = g_sequence_get_begin_iter(service_list); while (g_sequence_iter_is_end(iter) == FALSE) { struct connman_service *service = g_sequence_get(iter); if (service != allowed && is_connected(service)) +#if defined TIZEN_EXT + if (__connman_service_can_drop_cellular(service) == TRUE) +#endif services = g_slist_prepend(services, service); iter = g_sequence_iter_next(iter); @@ -5561,6 +5641,11 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, if (ipconfig == NULL) return -EINVAL; +#if defined TIZEN_EXT + if (new_state == CONNMAN_SERVICE_STATE_FAILURE && + service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + service->user_pdn_connection_refcount = 0; +#endif /* Any change? */ if (old_state == new_state) return -EALREADY; |