Maintain connection status when wifi roaming 36/280036/1 submit/tizen/20220829.114301 submit/tizen/20220902.085939
authorJaehyun Kim <jeik01.kim@samsung.com>
Mon, 22 Aug 2022 17:15:07 +0000 (02:15 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Mon, 22 Aug 2022 17:15:07 +0000 (02:15 +0900)
When wifi roaming, the current connection status is maintained.
If the network is changed, the connection status is reset.

Change-Id: I2680030c849c712b7d7dc68f70397514484a7fc3
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
include/network.h
include/service.h
packaging/connman.spec
plugins/wifi.c
src/dhcp.c
src/network.c
src/service.c

index ed07c1f..884c92e 100755 (executable)
@@ -281,6 +281,10 @@ struct _GSupplicantP2PServiceParams {
 typedef struct _GSupplicantP2PServiceParams GSupplicantP2PServiceParams;
 
 #if defined TIZEN_EXT
+#define WIFI_BSSID_STR_LEN 18
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
 #define WIFI_BSSID_LEN_MAX 6
 
 struct g_connman_bssids {
@@ -530,9 +534,10 @@ dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network
 const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network);
 const void *g_supplicant_network_get_transition_mode_ssid(GSupplicantNetwork *network,
                                                        unsigned int *transition_mode_ssid_len);
+void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal);
+void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network,
+               int signal, int snr);
 
-#endif
-#if defined TIZEN_EXT
 void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid);
 const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network);
 void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface,
index 4bc5276..e457fef 100755 (executable)
@@ -1601,6 +1601,32 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network)
        return network->signal;
 }
 
+#if defined TIZEN_EXT
+void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal)
+{
+       if (!network)
+               return;
+
+       network->signal = (dbus_int16_t)signal;
+}
+
+void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network,
+               int signal, int snr)
+{
+       struct g_supplicant_bss *best_bss;
+
+       if (!network)
+               return;
+
+       best_bss = network->best_bss;
+       if (!best_bss)
+               return;
+
+       best_bss->signal = (dbus_int16_t)signal;
+       best_bss->snr = (dbus_int16_t)snr;
+}
+#endif
+
 dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network)
 {
        if (!network)
@@ -2631,7 +2657,7 @@ static bool update_best_bss(GSupplicantNetwork *network,
 #endif
 
        if (score_new > score_best) {
-               SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]",
+               SUPPLICANT_DBG("new[" MACSTR "][%d] : best[" MACSTR "][%d]",
                        MAC2STR(bss->bssid), score_new,
                        MAC2STR(network->best_bss->bssid), score_best);
 
@@ -3547,6 +3573,13 @@ static void interface_current_bss(GSupplicantInterface *interface,
        GSupplicantNetwork *network;
        struct g_supplicant_bss *bss;
        const char *path;
+#if defined TIZEN_EXT
+       char bssid_buff1[WIFI_BSSID_STR_LEN] = {0,};
+       char bssid_buff2[WIFI_BSSID_STR_LEN] = {0,};
+       char *bssid_str1 = bssid_buff1;
+       char *bssid_str2 = bssid_buff2;
+       gboolean update = FALSE;
+#endif
 
        dbus_message_iter_get_basic(iter, &path);
        if (g_strcmp0(path, "/") == 0) {
@@ -3566,7 +3599,16 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
        interface->current_network = network;
 #if defined TIZEN_EXT
-       SUPPLICANT_DBG("current network [%p]", interface->current_network);
+       snprintf(bssid_str1, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid));
+       snprintf(bssid_str2, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(network->best_bss->bssid));
+
+       SUPPLICANT_DBG("current network [%p], Passed bss %s, best bss %s",
+                       interface->current_network, bssid_str1, bssid_str2);
+
+       if (network->frequency != bss->frequency) {
+               network->frequency = bss->frequency;
+               update = TRUE;
+       }
 #endif
 
        if (bss != network->best_bss) {
@@ -3579,24 +3621,25 @@ static void interface_current_bss(GSupplicantInterface *interface,
 
                network->best_bss = bss;
 
-#if defined TIZEN_EXT
-               if (network->frequency != bss->frequency)
-                       network->frequency = bss->frequency;
-#endif
-
                if (network->signal != bss->signal) {
                        SUPPLICANT_DBG("New network signal %d dBm",
                                                bss->signal);
 
                        network->signal = bss->signal;
                        callback_network_changed(network, "Signal");
-               }
 #if defined TIZEN_EXT
-               else
-                       callback_network_changed(network, "");
+                       update = FALSE;
+               } else {
+                       update = TRUE;
 #endif
+               }
        }
 
+#if defined TIZEN_EXT
+       if (update)
+               callback_network_changed(network, "");
+#endif
+
        /*
         * wpa_s could notify about CurrentBSS in any state once
         * it got associated. It is not sure such notification will
index 4d09dff..d637579 100755 (executable)
@@ -235,7 +235,7 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network);
 int connman_network_set_bssid_list(struct connman_network *network,
                                        GSList *bssids);
 void *connman_network_get_bssid_list(struct connman_network *network);
-#if defined TIZEN_EXT
+unsigned int connman_network_get_max_bssid_count(struct connman_network *network);
 int connman_network_set_last_connected_bssid(struct connman_network *network,
                                const unsigned char *bssid);
 unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network);
@@ -247,13 +247,13 @@ void connman_network_set_roam_scan_time(struct connman_network *network,
                                                __time_t roam_scan_time);
 int connman_network_get_snr(struct connman_network *network);
 void connman_network_set_snr(struct connman_network *network, int snr);
-#endif
 int connman_network_set_phy_mode(struct connman_network *network,
                                ieee80211_modes_e mode);
 ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network);
 int connman_network_set_connection_mode(struct connman_network *network,
                                connection_mode_e mode);
 connection_mode_e connman_network_get_connection_mode(struct connman_network *network);
+int set_connected_dhcp(struct connman_network *network);
 #endif
 
 int connman_network_set_name(struct connman_network *network,
index 041949f..3f4c58c 100755 (executable)
@@ -209,7 +209,8 @@ int connman_service_set_proxy(struct connman_service *service,
                                        const char *proxy, gboolean active);
 
 void connman_service_set_disconnection_requested(struct connman_service *service,
-                                                bool disconnection_requested);
+                                               bool disconnection_requested);
+void connman_service_notify_reconnection(struct connman_service *service);
 #endif
 
 #if defined TIZEN_EXT
index 3f73b7b..ba2c24c 100644 (file)
@@ -6,7 +6,7 @@
 
 Name:           connman
 Version:        1.40
-Release:        1
+Release:        2
 License:        GPL-2.0+
 Summary:        Connection Manager
 Url:            http://connman.net
index 9bd11cb..4280c47 100755 (executable)
 #define RSSI_LEVEL_2_24G -75
 #define RSSI_LEVEL_3_5G  -68
 #define RSSI_LEVEL_3_24G -64
-#define WIFI_BSSID_STR_LEN 18
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 #define ROAM_SCAN_INTERVAL 60 /* 60 seconds */
 #endif
 
@@ -2177,6 +2174,59 @@ static void scan_callback_hidden(int result,
                        GSupplicantInterface *interface, void *user_data);
 
 static int network_disconnect(struct connman_network *network);
+
+static void start_roaming(struct wifi_data *wifi)
+{
+       bool roaming_ap_found = false;
+       GSList *bssid_list = NULL;
+
+       if (!wifi || !wifi->network)
+               return;
+
+       if (connman_setting_get_bool("WifiRoaming")) {
+               struct connman_network *network = wifi->network;
+               bssid_list = connman_network_get_bssid_list(network);
+
+               if (g_slist_length(bssid_list) <= 1)
+                       return;
+
+               if (!connman_network_get_connected(network))
+                       return;
+
+               if (connman_network_get_bool(network, "WiFi.Roaming"))
+                       return;
+
+               if (!need_bss_transition(
+                               connman_network_get_frequency(network),
+                               connman_network_get_snr(network),
+                               connman_network_get_strength(network)))
+                       return;
+
+               for (bssid_list; bssid_list; bssid_list = bssid_list->next) {
+                       struct g_connman_bssids *bssid = bssid_list->data;
+
+                       if (check_bss_condition(bssid->frequency,
+                                       bssid->score_snr, bssid->strength))
+                               roaming_ap_found = true;
+               }
+
+               if (roaming_ap_found) {
+                       char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+                       char *bssid_str = bssid_buff;
+                       unsigned char *bssid;
+
+                       bssid = connman_network_get_bssid(network);
+                       snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+                       connman_network_set_string(network,
+                                       "WiFi.RoamingCurBSSID", bssid_str);
+
+                       network_disconnect(network);
+                       wifi->pending_network = network;
+                       connman_network_set_bool(network, "WiFi.Roaming", true);
+               }
+       }
+}
+
 #endif
 
 static void scan_callback(int result, GSupplicantInterface *interface,
@@ -2186,10 +2236,7 @@ static void scan_callback(int result, GSupplicantInterface *interface,
        struct wifi_data *wifi = connman_device_get_data(device);
        bool scanning;
 #if defined TIZEN_EXT
-       bool roaming_needed = false;
-       bool roaming_ap_found = false;
        GSList *list = NULL;
-       GSList *bssid_list = NULL;
        bool favorite_exists = false;
        struct connman_network *network = NULL;
        struct connman_service *service = NULL;
@@ -2306,46 +2353,8 @@ static void scan_callback(int result, GSupplicantInterface *interface,
                network_connect(wifi->scan_pending_network);
                wifi->scan_pending_network = NULL;
                connman_network_set_connecting(wifi->network);
-       } else if (connman_setting_get_bool("WifiRoaming") && wifi->network) {
-               bssid_list = connman_network_get_bssid_list(wifi->network);
-
-               if (g_slist_length(bssid_list) <= 1)
-                       goto done;
-
-               if (!connman_network_get_connected(wifi->network))
-                       goto done;
-
-               if (connman_network_get_bool(wifi->network, "WiFi.Roaming"))
-                       goto done;
-
-               if (!need_bss_transition(
-                               connman_network_get_frequency(wifi->network),
-                               connman_network_get_snr(wifi->network),
-                               connman_network_get_strength(wifi->network)))
-                       goto done;
-
-               for (bssid_list; bssid_list; bssid_list = bssid_list->next) {
-                       struct g_connman_bssids *bssid = bssid_list->data;
-
-                       if (check_bss_condition(bssid->frequency,
-                                       bssid->score_snr, bssid->strength))
-                               roaming_ap_found = true;
-               }
-
-               if (roaming_ap_found) {
-                       char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
-                       char *bssid_str = bssid_buff;
-                       unsigned char *bssid;
-
-                       bssid = connman_network_get_bssid(wifi->network);
-                       snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
-                       connman_network_set_string(wifi->network,
-                                       "WiFi.RoamingCurBSSID", bssid_str);
-
-                       network_disconnect(wifi->network);
-                       wifi->pending_network = wifi->network;
-                       connman_network_set_bool(wifi->network, "WiFi.Roaming", true);
-               }
+       } else {
+               start_roaming(wifi);
        }
 
 done:
@@ -2957,7 +2966,7 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface,
        struct wifi_data *wifi = connman_device_get_data(device);
        bool scanning;
 
-       DBG("result %d wifi %p", result, wifi);
+       DBG("result %d device %p wifi %p", result, device, wifi);
 
        if (wifi && wifi->scan_params) {
                g_supplicant_free_scan_params(wifi->scan_params);
@@ -2971,6 +2980,8 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface,
                                CONNMAN_SERVICE_TYPE_WIFI, false);
                connman_device_unref(device);
        }
+
+       start_roaming(wifi);
 }
 
 static int wifi_specific_scan(enum connman_service_type type,
@@ -3917,7 +3928,7 @@ done:
                        connman_network_get_string(network, "WiFi.KeymgmtType"));
        ssid->phase1 = connman_network_get_string(network, "WiFi.Phase1");
 
-       if(g_strcmp0(ssid->eap, "fast") == 0)
+       if (g_strcmp0(ssid->eap, "fast") == 0)
                ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE);
 
        ssid->keymgmt = connman_network_get_keymgmt(network);
@@ -3993,6 +4004,12 @@ static void disconnect_callback(int result, GSupplicantInterface *interface,
                        goto found;
        }
 
+       if (connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+               connman_network_set_bool(wifi->network, "WiFi.Roaming", false);
+
+       if (network == wifi->pending_network)
+               wifi->pending_network = NULL;
+
        /* wifi_data may be invalid because wifi is already disabled */
        return;
 
@@ -4012,9 +4029,8 @@ found:
        }
 
 #if defined TIZEN_EXT
-       if (wifi->network &&
-                       (wifi->network != wifi->pending_network ||
-                       connman_network_get_bool(wifi->network, "WiFi.Roaming")))
+       if (g_slist_find(wifi->networks, network) &&
+                       wifi->network != wifi->pending_network)
 #else
        if (g_slist_find(wifi->networks, network))
 #endif
@@ -4184,7 +4200,10 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
        const char *interface = NULL;
        struct connman_device *device;
        struct connman_network *network = user_data;
+       GSupplicantNetwork *supplicant_network;
+       struct wifi_data *wifi;
        uint16_t freq = connman_network_get_frequency(network);
+       const char *group = connman_network_get_group(network);
 
        if (result != 0) {
                DBG("Failed to get maxspeed from signalpoll !");
@@ -4192,30 +4211,44 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
                return;
        }
 
+       device = connman_network_get_device(network);
+       if (device)
+               wifi = connman_device_get_data(device);
+
+       if (group) {
+               supplicant_network = g_supplicant_interface_get_network(wifi->interface, group);
+               if (supplicant_network) {
+                       g_supplicant_network_set_signal(supplicant_network, strength);
+                       g_supplicant_network_set_bss_signal(supplicant_network, strength, snr);
+               }
+       }
+
        strength += 120;
        if (strength > 100)
                strength = 100;
 
-       DBG("freq = %u, maxspeed = %d, strength = %d, snr = %d", freq, maxspeed, strength, snr);
+       bssid = connman_network_get_bssid(network);
+       snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+
+       DBG("network %p, bssid %s, freq %u, maxspeed %d, strength %d, snr %d",
+                       network, bssid_str, freq, maxspeed, strength, snr);
 
        connman_network_set_strength(network, (uint8_t)strength);
        connman_network_set_snr(network, snr);
        connman_network_set_maxspeed(network, maxspeed);
        set_connection_mode(network, maxspeed);
 
+       if (connman_network_get_max_bssid_count(network) <= 1)
+               goto done;
+
        clock_gettime(CLOCK_MONOTONIC, &curr_time);
        roam_scan_time = connman_network_get_roam_scan_time(network);
        if (curr_time.tv_sec <= roam_scan_time + ROAM_SCAN_INTERVAL)
                goto done;
 
-       if (need_bss_transition(freq, snr, strength)) {
-               device = connman_network_get_device(network);
-               if (!device)
-                       goto done;
+       if (device && need_bss_transition(freq, snr, strength)) {
 
                interface = connman_device_get_string(device, "Interface");
-               bssid = connman_network_get_bssid(network);
-               snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
                __connman_technology_notify_roaming_state(interface, "required", bssid_str, NULL);
 
                if (connman_setting_get_bool("WifiRoamingScan") == false)
@@ -4574,6 +4607,65 @@ static bool handle_wifi_assoc_retry(struct connman_network *network,
 
        return true;
 }
+
+static void handle_wifi_roaming_complete(struct connman_network *network)
+{
+       const char *cur_bssid;
+       const char *dst_bssid;
+       const char *ifname;
+       struct connman_device *device;
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig_ipv4;
+       enum connman_ipconfig_type type;
+       enum connman_ipconfig_method method;
+
+       if (!connman_setting_get_bool("WifiRoaming") ||
+                       !connman_network_get_bool(network, "WiFi.Roaming"))
+               return;
+
+       device = connman_network_get_device(network);
+       if (device) {
+               ifname = connman_device_get_string(device, "Interface");
+               cur_bssid = connman_network_get_string(network,
+                               "WiFi.RoamingCurBSSID");
+               dst_bssid = connman_network_get_string(network,
+                               "WiFi.RoamingDstBSSID");
+       }
+
+       if (device && ifname && cur_bssid && dst_bssid) {
+               __connman_technology_notify_roaming_state(ifname,
+                               "success", cur_bssid, dst_bssid);
+               connman_network_set_bool(network,
+                               "WiFi.Roaming", false);
+               connman_network_set_string(network,
+                               "WiFi.RoamingCurBSSID", NULL);
+               connman_network_set_string(network,
+                               "WiFi.RoamingDstBSSID", NULL);
+
+               service = connman_service_lookup_from_network(network);
+               if (!service)
+                       return;
+
+               ipconfig_ipv4 = __connman_service_get_ip4config(service);
+               if (!ipconfig_ipv4) {
+                       connman_error("Service has no IPv4 configuration");
+                       return;
+               }
+
+               type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
+               if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
+                       return;
+
+               method = __connman_ipconfig_get_method(ipconfig_ipv4);
+               if (method != CONNMAN_IPCONFIG_METHOD_DHCP)
+                       return;
+
+               connman_network_set_bool(network, "WiFi.RoamingDHCP", true);
+
+               if (set_connected_dhcp(network) != 0)
+                       connman_network_set_bool(network, "WiFi.RoamingDHCP", false);
+       }
+}
 #endif
 
 static void interface_state(GSupplicantInterface *interface)
@@ -4634,6 +4726,8 @@ static void interface_state(GSupplicantInterface *interface)
                        wifi->automaxspeed_timeout = 0;
                        DBG("Remove signalpoll timer!!");
                }
+
+               if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
 #endif
                if (wifi->connected)
                        connman_network_set_connected(network, false);
@@ -4647,7 +4741,9 @@ static void interface_state(GSupplicantInterface *interface)
 #else
                stop_autoscan(device);
 #endif
-
+#if defined TIZEN_EXT
+               if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+#endif
                if (!wifi->connected)
                        connman_network_set_associating(network, true);
 
@@ -4681,6 +4777,7 @@ static void interface_state(GSupplicantInterface *interface)
                }
 
                g_hash_table_remove_all(failed_bssids);
+               handle_wifi_roaming_complete(network);
 #else
                /* though it should be already stopped: */
                stop_autoscan(device);
@@ -4722,7 +4819,7 @@ static void interface_state(GSupplicantInterface *interface)
                        break;
 
 #if defined TIZEN_EXT
-               if (handle_assoc_status_code(interface, wifi)) {
+               if (!wifi->connected && handle_assoc_status_code(interface, wifi)) {
                        const char *group = connman_network_get_group(network);
                        GSupplicantNetwork *supplicant_network;
                        GSList *bssid_list = NULL;
@@ -4787,7 +4884,7 @@ static void interface_state(GSupplicantInterface *interface)
                        break;
                }
 
-               if(wifi->disconnect_code > 0){
+               if (wifi->disconnect_code > 0){
                        DBG("Set disconnect reason code(%d)", wifi->disconnect_code);
                        connman_network_set_disconnect_reason(network, wifi->disconnect_code);
                }
index 5cef038..7c446cf 100644 (file)
@@ -285,6 +285,14 @@ static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data)
                dhcp->ipv4ll_client);
 
 #if defined TIZEN_EXT
+       if (dhcp->network &&
+                       connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) {
+               connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false);
+               __connman_network_enable_ipconfig(dhcp->network, dhcp->ipconfig);
+
+               return;
+       }
+
        if (connman_setting_get_bool("EnableAutoIp") == false) {
                DBG("link-local address autoconfiguration is disabled.");
                if (dhcp->network)
@@ -563,6 +571,17 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
                        __connman_service_notify_ipv4_configuration(service);
        }
 
+#if defined TIZEN_EXT
+       if (connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) {
+
+               if (ip_change)
+                       connman_service_notify_reconnection(
+                               connman_service_lookup_from_network(dhcp->network));
+
+               connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false);
+       }
+#endif
+
        if (ip_change) {
                __connman_ipconfig_set_local(dhcp->ipconfig, address);
                __connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
@@ -829,9 +848,15 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
        dhcp->user_data = user_data;
 
 #if defined TIZEN_EXT
-       DBG("Start DHCP with DHCPDISCOVER request");
+       if (connman_network_get_bool(network, "WiFi.RoamingDHCP")) {
+               const char *last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
 
-       return g_dhcp_client_start(dhcp->dhcp_client, NULL);
+               DBG("Start DHCP with last address request");
+               return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
+       } else {
+               DBG("Start DHCP with DHCPDISCOVER request");
+               return g_dhcp_client_start(dhcp->dhcp_client, NULL);
+       }
 #else
        return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
 #endif
index 3bf6299..8eb8c1e 100755 (executable)
@@ -147,9 +147,11 @@ struct connman_network {
                int transition_mode_ssid_len;
                unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX];
                bool roaming_progress;
+               bool roaming_dhcp;
                char *roaming_cur_bssid;
                char *roaming_dst_bssid;
                __time_t roam_scan_time;
+               unsigned int max_bssid_count;
                int snr;
 #endif
        } wifi;
@@ -600,7 +602,11 @@ static void remove_dhcp_timeout(struct connman_network *network)
        }
 }
 
+#if defined TIZEN_EXT
+int set_connected_dhcp(struct connman_network *network)
+#else
 static int set_connected_dhcp(struct connman_network *network)
+#endif
 {
        struct connman_service *service;
        struct connman_ipconfig *ipconfig_ipv4;
@@ -1415,6 +1421,9 @@ struct connman_network *
 connman_network_ref_debug(struct connman_network *network,
                        const char *file, int line, const char *caller)
 {
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
                network->refcount + 1, file, line, caller);
 
@@ -1432,6 +1441,9 @@ connman_network_ref_debug(struct connman_network *network,
 void connman_network_unref_debug(struct connman_network *network,
                                const char *file, int line, const char *caller)
 {
+#if defined TIZEN_EXT
+       if (!simplified_log)
+#endif
        DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
                network->refcount - 1, file, line, caller);
 
@@ -2380,9 +2392,6 @@ int connman_network_set_bssid(struct connman_network *network,
        if (bssid == NULL)
                return -EINVAL;
 
-       if (network->connected)
-               return -EPERM;
-
        if (!simplified_log)
                DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
                                bssid[0], bssid[1], bssid[2],
@@ -2601,9 +2610,15 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network)
 int connman_network_set_bssid_list(struct connman_network *network,
                                        GSList *bssids)
 {
+       unsigned int max_bssid_count;
+
        g_slist_free_full(network->wifi.bssid_list, g_free);
        network->wifi.bssid_list = bssids;
 
+       max_bssid_count = g_slist_length(bssids);
+       if (network->wifi.max_bssid_count < max_bssid_count)
+               network->wifi.max_bssid_count = max_bssid_count;
+
        return 0;
 }
 
@@ -2641,6 +2656,11 @@ void *connman_network_get_bssid_list(struct connman_network *network)
        return network->wifi.bssid_list;
 }
 
+unsigned int connman_network_get_max_bssid_count(struct connman_network *network)
+{
+       return network->wifi.max_bssid_count;
+}
+
 int connman_network_set_last_connected_bssid(struct connman_network *network,
                                const unsigned char *bssid)
 {
@@ -3034,6 +3054,8 @@ int connman_network_set_bool(struct connman_network *network,
                network->wifi.owe_transition_mode = value;
        else if (g_strcmp0(key, "WiFi.Roaming") == 0)
                network->wifi.roaming_progress = value;
+       else if (g_strcmp0(key, "WiFi.RoamingDHCP") == 0)
+               network->wifi.roaming_dhcp = value;
        else if (g_strcmp0(key, "WiFi.PMFRequired") == 0)
                network->wifi.pmf_required = value;
 #endif
@@ -3068,6 +3090,8 @@ bool connman_network_get_bool(struct connman_network *network,
                return network->wifi.owe_transition_mode;
        else if (g_str_equal(key, "WiFi.Roaming"))
                return network->wifi.roaming_progress;
+       else if (g_str_equal(key, "WiFi.RoamingDHCP"))
+               return network->wifi.roaming_dhcp;
        else if (g_str_equal(key, "WiFi.PMFRequired"))
                return network->wifi.pmf_required;
 #endif
index 794555e..356a218 100755 (executable)
@@ -3196,7 +3196,7 @@ static void disconnection_requested_changed(struct connman_service *service)
 }
 
 void connman_service_set_disconnection_requested(struct connman_service *service,
-                                                bool disconnection_requested)
+                                               bool disconnection_requested)
 {
        if (service == NULL)
                return;
@@ -3204,6 +3204,47 @@ void connman_service_set_disconnection_requested(struct connman_service *service
        service->disconnection_requested = disconnection_requested;
        disconnection_requested_changed(service);
 }
+
+static void connman_service_emit_state(struct connman_service *service,
+                                               enum connman_service_state state)
+{
+       const char *str;
+       enum connman_service_state cur_state = service->state;
+
+       if (service->state != state)
+               service->state = state;
+
+       str = state2string(service->state);
+       if (!str) {
+               service->state = cur_state;
+               return;
+       }
+
+       DBG(" %s, %s", str, service->path);
+
+       connman_dbus_property_changed_basic(service->path,
+                               CONNMAN_SERVICE_INTERFACE, "State",
+                                               DBUS_TYPE_STRING, &str);
+
+       emit_state_changed_with_properties(service);
+       service->state = cur_state;
+}
+
+void connman_service_notify_reconnection(struct connman_service *service)
+{
+       if (!service)
+               return;
+
+       if (service->state != CONNMAN_SERVICE_STATE_READY &&
+                       service->state != CONNMAN_SERVICE_STATE_ONLINE)
+               return;
+
+       connman_service_emit_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION);
+       connman_service_emit_state(service, CONNMAN_SERVICE_STATE_READY);
+
+       if (service->state == CONNMAN_SERVICE_STATE_ONLINE)
+               connman_service_emit_state(service, CONNMAN_SERVICE_STATE_ONLINE);
+}
 #endif
 
 static void strength_changed(struct connman_service *service)
@@ -9147,6 +9188,50 @@ static void set_priority_connected_service(void)
 #endif
        }
 }
+
+static void emit_wifi_roaming_failure(struct connman_service *service,
+                                       enum connman_service_state new_state)
+{
+       if (connman_setting_get_bool("WifiRoaming") &&
+                       connman_network_get_bool(service->network, "WiFi.Roaming")) {
+               const char *cur_bssid;
+               const char *dst_bssid;
+               const char *ifname;
+               struct connman_device *device;
+
+               device = connman_network_get_device(service->network);
+               if (device) {
+                       ifname = connman_device_get_string(device, "Interface");
+                       cur_bssid = connman_network_get_string(service->network,
+                                               "WiFi.RoamingCurBSSID");
+                       dst_bssid = connman_network_get_string(service->network,
+                                               "WiFi.RoamingDstBSSID");
+               }
+
+               if (device && ifname && cur_bssid && dst_bssid) {
+                       switch(new_state) {
+                       case CONNMAN_SERVICE_STATE_UNKNOWN:
+                       case CONNMAN_SERVICE_STATE_ASSOCIATION:
+                       case CONNMAN_SERVICE_STATE_CONFIGURATION:
+                       case CONNMAN_SERVICE_STATE_READY:
+                       case CONNMAN_SERVICE_STATE_ONLINE:
+                               break;
+                       case CONNMAN_SERVICE_STATE_DISCONNECT:
+                       case CONNMAN_SERVICE_STATE_FAILURE:
+                       case CONNMAN_SERVICE_STATE_IDLE:
+                               __connman_technology_notify_roaming_state(ifname,
+                                               "failure", cur_bssid, dst_bssid);
+                               connman_network_set_bool(service->network,
+                                               "WiFi.Roaming", false);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingCurBSSID", NULL);
+                               connman_network_set_string(service->network,
+                                               "WiFi.RoamingDstBSSID", NULL);
+                               break;
+                       }
+               }
+       }
+}
 #endif
 
 static const char *get_dbus_sender(struct connman_service *service)
@@ -9353,6 +9438,8 @@ static int service_indicate_state(struct connman_service *service)
                proxy_changed(service);
 #if defined TIZEN_EXT
                }
+
+               emit_wifi_roaming_failure(service, new_state);
 #endif
 
                /*
@@ -9393,55 +9480,7 @@ static int service_indicate_state(struct connman_service *service)
 #else
        __connman_service_connect_default(service);
 #endif
-       /* Update Wi-Fi Roaming result */
-       if (connman_setting_get_bool("WifiRoaming") &&
-                       connman_network_get_bool(service->network, "WiFi.Roaming")) {
-               const char *cur_bssid;
-               const char *dst_bssid;
-               const char *ifname;
-               struct connman_device *device;
-
-               device = connman_network_get_device(service->network);
-               if (device) {
-                       ifname = connman_device_get_string(device, "Interface");
-                       cur_bssid = connman_network_get_string(service->network,
-                                               "WiFi.RoamingCurBSSID");
-                       dst_bssid = connman_network_get_string(service->network,
-                                               "WiFi.RoamingDstBSSID");
-               }
-
-               if (device && ifname && cur_bssid && dst_bssid) {
-                       switch(new_state) {
-                       case CONNMAN_SERVICE_STATE_UNKNOWN:
-                       case CONNMAN_SERVICE_STATE_ASSOCIATION:
-                       case CONNMAN_SERVICE_STATE_CONFIGURATION:
-                               break;
-                       case CONNMAN_SERVICE_STATE_READY:
-                       case CONNMAN_SERVICE_STATE_ONLINE:
-                               __connman_technology_notify_roaming_state(ifname,
-                                               "success", cur_bssid, dst_bssid);
-                               connman_network_set_bool(service->network,
-                                               "WiFi.Roaming", false);
-                               connman_network_set_string(service->network,
-                                               "WiFi.RoamingCurBSSID", NULL);
-                               connman_network_set_string(service->network,
-                                               "WiFi.RoamingDstBSSID", NULL);
-                               break;
-                       case CONNMAN_SERVICE_STATE_DISCONNECT:
-                       case CONNMAN_SERVICE_STATE_FAILURE:
-                       case CONNMAN_SERVICE_STATE_IDLE:
-                               __connman_technology_notify_roaming_state(ifname,
-                                               "failure", cur_bssid, dst_bssid);
-                               connman_network_set_bool(service->network,
-                                               "WiFi.Roaming", false);
-                               connman_network_set_string(service->network,
-                                               "WiFi.RoamingCurBSSID", NULL);
-                               connman_network_set_string(service->network,
-                                               "WiFi.RoamingDstBSSID", NULL);
-                               break;
-                       }
-               }
-       }
+       emit_wifi_roaming_failure(service, new_state);
 #endif
 
        __connman_connection_update_gateway();