summaryrefslogtreecommitdiff
path: root/src/service.c
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2014-08-05 09:56:47 (GMT)
committerZhang zhengguang <zhengguang.zhang@intel.com>2014-08-07 01:31:06 (GMT)
commit9865f975d998d124cb89e0c3c56a5afe3c260d91 (patch)
tree3f14543bc7166976d80ddf84351cebe7c371c0d1 /src/service.c
parentaac83cdcf738fa577cf18f3eae19b95d957d13d8 (diff)
downloadconnman-9865f975d998d124cb89e0c3c56a5afe3c260d91.zip
connman-9865f975d998d124cb89e0c3c56a5afe3c260d91.tar.gz
connman-9865f975d998d124cb89e0c3c56a5afe3c260d91.tar.bz2
Upstream/service: Fix service disconnection when using the same index
When a service is to be connected, other service(s) using the same interface will be disconnected. Fix the already connected or connecting situation by ignoring the service in question when seen in the list. Simplify the index detection and signal a timeout other services are disconnected in order to indicate to the caller that the connect action needs to be redone. Thanks to Chengyi Zhao for finding the issue.
Diffstat (limited to 'src/service.c')
-rw-r--r--src/service.c45
1 files changed, 11 insertions, 34 deletions
diff --git a/src/service.c b/src/service.c
index b046514..b309f60 100644
--- a/src/service.c
+++ b/src/service.c
@@ -4048,34 +4048,11 @@ static gboolean connect_timeout(gpointer user_data)
return FALSE;
}
-static bool is_interface_available(struct connman_service *service,
- struct connman_service *other_service)
-{
- unsigned int index = 0, other_index = 0;
-
- if (service->ipconfig_ipv4)
- index = __connman_ipconfig_get_index(service->ipconfig_ipv4);
- else if (service->ipconfig_ipv6)
- index = __connman_ipconfig_get_index(service->ipconfig_ipv6);
-
- if (other_service->ipconfig_ipv4)
- other_index = __connman_ipconfig_get_index(
- other_service->ipconfig_ipv4);
- else if (other_service->ipconfig_ipv6)
- other_index = __connman_ipconfig_get_index(
- other_service->ipconfig_ipv6);
-
- if (index > 0 && other_index != index)
- return true;
-
- return false;
-}
-
static DBusMessage *connect_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct connman_service *service = user_data;
- int err = 0;
+ int index, err = 0;
GList *list;
DBG("service %p", service);
@@ -4083,27 +4060,27 @@ static DBusMessage *connect_service(DBusConnection *conn,
if (service->pending)
return __connman_error_in_progress(msg);
+ index = __connman_service_get_index(service);
+
for (list = service_list; list; list = list->next) {
struct connman_service *temp = list->data;
- /*
- * We should allow connection if there are available
- * interfaces for a given technology type (like having
- * more than one wifi card).
- */
if (!is_connecting(temp) && !is_connected(temp))
break;
+ if (service == temp)
+ continue;
+
if (service->type != temp->type)
continue;
- if(!is_interface_available(service, temp)) {
- if (__connman_service_disconnect(temp) == -EINPROGRESS)
- err = -EINPROGRESS;
- }
+ if (__connman_service_get_index(temp) == index &&
+ __connman_service_disconnect(temp) == -EINPROGRESS)
+ err = -EINPROGRESS;
+
}
if (err == -EINPROGRESS)
- return __connman_error_in_progress(msg);
+ return __connman_error_operation_timeout(msg);
service->ignore = false;