Hi Marcel:
The patch can fix the issue, please review it.
When connect to new service, the patch will find the ready service on the same
device. If found, disconnect it firstly.
I have verified the patch, it can work fine.
diff --git a/src/service.c b/src/service.c
index aa89d5d..e7ad577 100644
--- a/src/service.c
+++ b/src/service.c
@@ -372,9 +372,40 @@ static gboolean connect_timeout(gpointer user_data)
return FALSE;
}
+struct find_data_device {
+ struct connman_device *device;
+ struct connman_service *service;
+};
+
+static void compare_device(gpointer value, gpointer user_data)
+{
+ struct connman_service *service = value;
+ struct find_data_device *data = user_data;
+
+ if (data->service != NULL)
+ return;
+
+ if (service->device == data->device &&
+ service->state == CONNMAN_SERVICE_STATE_READY)
+ data->service = service;
+}
+
+static struct connman_service *get_ready_service_from_device(
+ struct
connman_device *device)
+{
+ struct find_data_device data = { .device = device, .service = NULL };
+
+ DBG("device 0x%p", device);
+
+ g_sequence_foreach(service_list, compare_device, &data);
+
+ return data.service;
+}
+
static DBusMessage *connect_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
+ struct connman_service *ready_service = NULL;
struct connman_service *service = user_data;
DBG("service %p", service);
@@ -385,6 +416,8 @@ static DBusMessage *connect_service(DBusConnection *conn,
if (service->state == CONNMAN_SERVICE_STATE_READY)
return __connman_error_already_connected(msg);
+ ready_service = get_ready_service_from_device(service->device);
+
if (service->network != NULL) {
int err;
@@ -394,6 +427,10 @@ static DBusMessage *connect_service(DBusConnection *conn,
connman_network_set_string(service->network,
"WiFi.Passphrase", service->passphrase);
+ if (ready_service != NULL)
+ if (ready_service->network != NULL)
+ __connman_network_disconnect(service->network);
+
err = __connman_network_connect(service->network);
if (err < 0 && err != -EINPROGRESS)
return __connman_error_failed(msg, -err);
@@ -408,6 +445,10 @@ static DBusMessage *connect_service(DBusConnection *conn,
if (service->favorite == FALSE)
return __connman_error_no_carrier(msg);
+ if (ready_service != NULL)
+ if (ready_service->device != NULL)
+ __connman_device_disconnect(service->device);
+
if (__connman_device_connect(service->device) < 0)
return __connman_error_failed(msg, EINVAL);
@@ -1207,6 +1248,8 @@ struct connman_service
*__connman_service_create_from_network(struct connman_net
update_from_network(service, network);
+ service->device = connman_network_get_device(network);
+
service_register(service);
done:
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf
Of Marcel Holtmann
Sent: 2009年6月1日 22:34
To: [email protected]
Cc: Liu, Bing Wei
Subject: Re: [connman] old IP and Route should be cleared when new service
connection failed
Hi Martin,
> I found that when you connect new service(wifi service), if the association
> failed, the IP address and route table may mess up. The failed association
> may broken the original association, but not clear the original IP and Route
> table. So the original IP/Route is still there. Consequently, Carrick will
> show strange network states.
> I think we can disconnect the original service before connect to new one to
> resolve the issue. Or to clear the original connection and route after new
> connection failed.
> The related Carrick bug is: #2737
this makes sense and is similar to previous DHCP element registration
issues I have seen, but never was able to pin-point them. I will be
earliest looking into this next week. So feel free to sent patches.
Regards
Marcel
_______________________________________________
connman mailing list
[email protected]
https://lists.moblin.org/mailman/listinfo/connman
_______________________________________________
connman mailing list
[email protected]
https://lists.moblin.org/mailman/listinfo/connman