Handle the case that best_bss is NULL
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index 759e165..36625d0 100755 (executable)
@@ -452,6 +452,10 @@ struct assoc_count_data {
 static unsigned int last_connected_bss_timeout = 0;
 #endif
 
+static void interface_get_params(DBusMessageIter *iter, void *user_data);
+static void interface_get_result(const char *error,
+                               DBusMessageIter *iter, void *user_data);
+
 static int network_remove(struct interface_data *data);
 
 #if defined TIZEN_EXT_WIFI_MESH
@@ -2455,16 +2459,30 @@ static char *create_group(struct g_supplicant_bss *bss)
        return g_string_free(str, FALSE);
 }
 
+static void update_network_with_best_bss(GSupplicantNetwork *network,
+               struct g_supplicant_bss *best_bss)
+{
+       network->signal = best_bss->signal;
+       network->frequency = best_bss->frequency;
+       network->best_bss = best_bss;
+}
+
 static bool update_best_bss(GSupplicantNetwork *network,
                struct g_supplicant_bss *bss, struct g_supplicant_bss *best_bss)
 {
        int score_new;
        int score_best;
 
+       if (network->best_bss == NULL) {
+               update_network_with_best_bss(network, bss);
+               return true;
+       }
+
        score_new = calculate_score(
                compare_bssid(bss->bssid, network->last_connected_bssid),
                get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid),
                bss->frequency, bss->signal);
+
        score_best = calculate_score(
                compare_bssid(network->best_bss->bssid, network->last_connected_bssid),
                get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid),
@@ -2475,9 +2493,7 @@ static bool update_best_bss(GSupplicantNetwork *network,
                        MAC2STR(bss->bssid), score_new,
                        MAC2STR(network->best_bss->bssid), score_best);
 
-               network->signal = bss->signal;
-               network->frequency = bss->frequency;
-               network->best_bss = bss;
+               update_network_with_best_bss(network, bss);
 
                SUPPLICANT_DBG("Update best BSS for %s", network->name);
 
@@ -5484,11 +5500,29 @@ static void interface_create_result(const char *error,
        struct interface_create_data *data = user_data;
        const char *path = NULL;
        int err;
+#if defined TIZEN_EXT
+       int ret;
+#endif
 
        SUPPLICANT_DBG("");
 
        if (error) {
                g_message("error %s", error);
+#if defined TIZEN_EXT
+               SUPPLICANT_DBG("error %s", error);
+               if (strcmp(error, "fi.w1.wpa_supplicant1.InterfaceExists") == 0) {
+                       SUPPLICANT_DBG("Send method: GetInterface");
+                       ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
+                                       SUPPLICANT_INTERFACE,
+                                       "GetInterface",
+                                       interface_get_params,
+                                       interface_get_result, user_data,
+                                       NULL);
+                       if (ret < 0)
+                               interface_create_data_free(data);
+                       return;
+               }
+#endif
                err = -EIO;
                goto done;
        }
@@ -5570,6 +5604,53 @@ static void interface_create_params(DBusMessageIter *iter, void *user_data)
        supplicant_dbus_dict_close(iter, &dict);
 }
 
+#if defined TIZEN_EXT
+static void interface_get_state(const char *key, DBusMessageIter *iter,
+               void *user_data)
+{
+       struct interface_create_data *data = user_data;
+       GSupplicantInterface *interface = NULL;
+       const char *str = NULL;
+
+       SUPPLICANT_DBG("key[%s]", key);
+
+       if (!data) {
+               SUPPLICANT_DBG("data is NULL");
+               return;
+       }
+
+       interface = data->interface;
+       if (!interface) {
+               SUPPLICANT_DBG("interface is NULL");
+               return;
+       }
+
+       if (iter)
+               dbus_message_iter_get_basic(iter, &str);
+
+       if (str) {
+               if (string2state(str) != interface->state)
+                       interface->state = string2state(str);
+       }
+
+       if (interface->state == G_SUPPLICANT_STATE_DISABLED)
+               interface->ready = FALSE;
+       else
+               interface->ready = TRUE;
+
+       SUPPLICANT_DBG("state %s (%d)", str, interface->state);
+
+       if (data->callback) {
+               data->callback(0, interface, data->user_data);
+#if defined TIZEN_EXT_WIFI_MESH
+               callback_mesh_support(interface);
+#endif
+       }
+
+       interface_create_data_free(data);
+}
+#endif
+
 static void interface_get_result(const char *error,
                                DBusMessageIter *iter, void *user_data)
 {
@@ -5597,6 +5678,16 @@ static void interface_get_result(const char *error,
                goto done;
        }
 
+#if defined TIZEN_EXT
+       data->interface = interface;
+       err = supplicant_dbus_property_get(path,
+                       SUPPLICANT_INTERFACE ".Interface",
+                       "State", interface_get_state, data, NULL);
+
+       if (err == 0)
+               return;
+#endif
+
        if (data->callback) {
                data->callback(0, interface, data->user_data);
 #if !defined TIZEN_EXT
@@ -5781,6 +5872,7 @@ int g_supplicant_interface_create(const char *ifname, const char *driver,
        data->callback = callback;
        data->user_data = user_data;
 
+#if !defined TIZEN_EXT
        ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
                                                SUPPLICANT_INTERFACE,
                                                "GetInterface",
@@ -5789,6 +5881,16 @@ int g_supplicant_interface_create(const char *ifname, const char *driver,
                                                NULL);
        if (ret < 0)
                interface_create_data_free(data);
+#else
+       ret = supplicant_dbus_method_call(SUPPLICANT_PATH,
+                                               SUPPLICANT_INTERFACE,
+                                               "CreateInterface",
+                                               interface_create_params,
+                                               interface_create_result, data,
+                                               NULL);
+       if (ret < 0)
+               interface_create_data_free(data);
+#endif
 
        return ret;
 }