Add BSSID , signal strength and frequency list of the APs
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index 9b7a934..c154a0e 100644 (file)
 #define IEEE80211_CAP_IBSS     0x0002
 #define IEEE80211_CAP_PRIVACY  0x0010
 
+#if defined TIZEN_EXT
+#define COUNTRY_CODE_LENGTH    2
+#endif
+
 #define BSS_UNKNOWN_STRENGTH    -90
 
 static DBusConnection *connection;
@@ -223,6 +227,7 @@ struct g_supplicant_bss {
        dbus_bool_t ft_ieee8021x;
        GSList *vsie_list;
        dbus_bool_t hs20;
+       unsigned char country_code[COUNTRY_CODE_LENGTH];
 #endif
        unsigned int wps_capabilities;
 };
@@ -250,6 +255,7 @@ struct _GSupplicantNetwork {
        char *phase2;
        unsigned int keymgmt;
        GSList *vsie_list;
+       unsigned char country_code[COUNTRY_CODE_LENGTH];
 #endif
 };
 
@@ -315,6 +321,14 @@ struct interface_scan_data {
        void *user_data;
 };
 
+#if defined TIZEN_EXT
+struct g_connman_bssids {
+       char bssid[18];
+       uint16_t strength;
+       uint16_t frequency;
+};
+#endif
+
 static int network_remove(struct interface_data *data);
 
 static inline void debug(const char *format, ...)
@@ -1408,6 +1422,15 @@ unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network)
 
        return network->keymgmt;
 }
+
+const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
+                                                         *network)
+{
+       if (!network)
+               return NULL;
+
+       return network->country_code;
+}
 #endif
 
 const unsigned char *g_supplicant_peer_get_widi_ies(GSupplicantPeer *peer,
@@ -1580,6 +1603,46 @@ void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
 
        return vsie_list;
 }
+
+static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
+{
+       struct g_supplicant_bss *bss = value;
+       struct g_connman_bssids *bssids = NULL;
+       char buff[18];
+       GSList **list = (GSList **)user_data;
+
+       bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids));
+
+       if (bssids) {
+               g_snprintf(buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+                               bss->bssid[0], bss->bssid[1], bss->bssid[2], bss->bssid[3],
+                               bss->bssid[4], bss->bssid[5]);
+
+               memcpy(bssids->bssid, buff, 18);
+               bssids->bssid[17] = '\0';
+               bssids->strength = bss->signal;
+               bssids->strength += 120;
+
+               if (bssids->strength > 100)
+                       bssids->strength = 100;
+
+               bssids->frequency = bss->frequency;
+               *list = g_slist_append(*list, bssids);
+       } else
+               SUPPLICANT_DBG("Failed to allocate memory");
+}
+
+void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
+{
+       GSList *bssid_list = NULL;
+
+       if (g_hash_table_size(network->bss_table) < 1)
+               return NULL;
+
+       g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list);
+
+       return bssid_list;
+}
 #endif
 
 static void merge_network(GSupplicantNetwork *network)
@@ -1876,6 +1939,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
        }
 
        network->isHS20AP = bss->hs20;
+       memcpy(network->country_code, bss->country_code, COUNTRY_CODE_LENGTH);
 #endif
 
        SUPPLICANT_DBG("New network %s created", network->name);
@@ -2079,6 +2143,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 #define WPS_CONFIGURED    0x02
 #if defined TIZEN_EXT
 #define VENDOR_SPECIFIC_INFO 0xDD
+#define WLAN_EID_COUNTRY 7
 #endif
 
        dbus_message_iter_recurse(iter, &array);
@@ -2089,6 +2154,7 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 
        bss->wps_capabilities = 0;
        bss->keymgmt = 0;
+       memset(bss->country_code, 0, COUNTRY_CODE_LENGTH);
 
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
@@ -2108,6 +2174,11 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
                                SUPPLICANT_DBG("Failed to allocate memory");
                        continue;
                }
+
+               if(ie[0] == WLAN_EID_COUNTRY && ie[1] >= 2) {
+                       memcpy(bss->country_code, ie+2, COUNTRY_CODE_LENGTH);
+                       continue;
+               }
 #endif
                if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
                        memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
@@ -5131,6 +5202,33 @@ static void add_network_security_aka_sim(DBusMessageIter *dict,
                        DBUS_TYPE_STRING,
                        &ssid->passphrase);
 }
+
+static void add_network_security_fast(DBusMessageIter *dict,
+               GSupplicantSSID *ssid)
+{
+       /*
+        * For FAST, we at least need:
+        *              id / password
+        *              phase1 (provisiong information)
+        *              pac_file
+        */
+
+       /* Allow provisioing both authenticated and unauthenticated */
+       const char *phase1 = "fast_provisioning=2";
+       supplicant_dbus_dict_append_basic(dict, "phase1",
+                       DBUS_TYPE_STRING,
+                       &phase1);
+
+       SUPPLICANT_DBG("pac_file [%s]", ssid->pac_file);
+       if(ssid->pac_file)
+               supplicant_dbus_dict_append_basic(dict, "pac_file",
+                               DBUS_TYPE_STRING,
+                               &ssid->pac_file);
+
+       supplicant_dbus_dict_append_basic(dict, "password",
+                       DBUS_TYPE_STRING,
+                       &ssid->passphrase);
+}
 #endif
 
 static void add_network_security_eap(DBusMessageIter *dict,
@@ -5157,8 +5255,20 @@ static void add_network_security_eap(DBusMessageIter *dict,
 
 #if defined TIZEN_EXT
        } else if (g_strcmp0(ssid->eap, "sim") == 0 ||
-                       g_strcmp0(ssid->eap, "aka") == 0) {
+                       g_strcmp0(ssid->eap, "aka") == 0 ||
+                       g_strcmp0(ssid->eap, "aka'") == 0) {
                add_network_security_aka_sim(dict, ssid);
+       } else if (g_strcmp0(ssid->eap, "pwd") == 0) {
+               if(!ssid->passphrase)
+                       return;
+               supplicant_dbus_dict_append_basic(dict, "password",
+                               DBUS_TYPE_STRING,
+                               &ssid->passphrase);
+       } else if (g_strcmp0(ssid->eap, "fast") == 0){
+               if (!ssid->identity || !ssid->passphrase)
+                       return;
+
+               add_network_security_fast(dict, ssid);
 #endif
        } else
                return;
@@ -5738,7 +5848,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                        network_remove(intf_data);
                } else
 #if defined TIZEN_EXT
-                       if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
+                       if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0 && !ssid->eap) {
                                ret = send_decryption_request(ssid->passphrase, data);
                                if (ret < 0)
                                        SUPPLICANT_DBG("Decryption request failed %d", ret);