From: Martin Xu <martin...@intel.com>

When changing wifi from STA to AP the interface needs to be closed
and then opened. Only after the interface is opened and detected
carrier, the interface can be added to bridge.
---
 plugins/wifi.c |   38 ++++++++++++++++++++++++++++++++++----
 1 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/plugins/wifi.c b/plugins/wifi.c
index 78da6ac..33ce0f9 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -66,6 +66,8 @@ struct wifi_data {
        connman_bool_t connected;
        connman_bool_t disconnecting;
        connman_bool_t tethering;
+       connman_bool_t propose_add_bridge;
+       char *bridge;
        int index;
        unsigned flags;
        unsigned int watch;
@@ -112,6 +114,24 @@ static int get_bssid(struct connman_device *device,
        return 0;
 }
 
+static void handle_tethering(struct wifi_data *wifi)
+{
+       if (wifi->tethering == FALSE)
+               return;
+
+       if (wifi->bridge == NULL)
+               return;
+
+       if (wifi->propose_add_bridge == FALSE)
+               return;
+
+       DBG("index %d bridge %s", wifi->index, wifi->bridge);
+
+       connman_inet_add_to_bridge(wifi->index, wifi->bridge);
+
+       wifi->propose_add_bridge = FALSE;
+}
+
 static void wifi_newlink(unsigned flags, unsigned change, void *user_data)
 {
        struct connman_device *device = user_data;
@@ -130,9 +150,11 @@ static void wifi_newlink(unsigned flags, unsigned change, 
void *user_data)
        }
 
        if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
-               if (flags & IFF_LOWER_UP)
+               if (flags & IFF_LOWER_UP) {
                        DBG("carrier on");
-               else
+
+                       handle_tethering(wifi);
+               } else
                        DBG("carrier off");
        }
 
@@ -152,6 +174,8 @@ static int wifi_probe(struct connman_device *device)
        wifi->connected = FALSE;
        wifi->disconnecting = FALSE;
        wifi->tethering = FALSE;
+       wifi->propose_add_bridge = FALSE;
+       wifi->bridge = NULL;
        wifi->state = G_SUPPLICANT_STATE_INACTIVE;
 
        connman_device_set_data(device, wifi);
@@ -982,7 +1006,8 @@ static void sta_remove_callback(int result,
        info->wifi->interface = NULL;
 
        connman_technology_tethering_notify(info->technology, TRUE);
-       connman_inet_add_to_bridge(info->wifi->index, info->bridge);
+
+       info->wifi->propose_add_bridge = TRUE;
 
        g_supplicant_interface_create(info->ifname, driver, info->bridge,
                                                ap_create_callback,
@@ -1007,8 +1032,11 @@ static int tech_set_tethering(struct connman_technology 
*technology,
                for (list = iface_list; list; list = list->next) {
                        wifi = list->data;
 
-                       if (wifi->tethering == TRUE)
+                       if (wifi->tethering == TRUE) {
                                wifi->tethering = FALSE;
+                               wifi->propose_add_bridge = FALSE;
+                               g_free(wifi->bridge);
+                       }
                }
 
                connman_technology_tethering_notify(technology, FALSE);
@@ -1051,6 +1079,8 @@ static int tech_set_tethering(struct connman_technology 
*technology,
                }
 
                info->wifi->tethering = TRUE;
+               g_free(info->wifi->bridge);
+               info->wifi->bridge = g_strdup(bridge);
 
                err = g_supplicant_interface_remove(interface,
                                                sta_remove_callback,
-- 
1.6.1.3

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to