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