*
*/
+#include <stdio.h>
+
#include "log.h"
#include "util.h"
#include "neterror.h"
#include "wifi-ssid-scan.h"
#include "wifi-background-scan.h"
-enum netconfig_wifi_security {
- WIFI_SECURITY_UNKNOWN = 0x00,
- WIFI_SECURITY_NONE = 0x01,
- WIFI_SECURITY_WEP = 0x02,
- WIFI_SECURITY_PSK = 0x03,
- WIFI_SECURITY_IEEE8021X = 0x04,
+#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_KEYMGMT_NONE (1 << 0)
+#define WIFI_KEYMGMT_IEEE8021X (1 << 1)
+#define WIFI_KEYMGMT_WPA_NONE (1 << 2)
+#define WIFI_KEYMGMT_WPA_PSK (1 << 3)
+#define WIFI_KEYMGMT_WPA_PSK_256 (1 << 4)
+#define WIFI_KEYMGMT_WPA_FT_PSK (1 << 5)
+#define WIFI_KEYMGMT_WPA_FT_EAP (1 << 6)
+#define WIFI_KEYMGMT_WPA_EAP (1 << 7)
+#define WIFI_KEYMGMT_WPA_EAP_256 (1 << 8)
+#define WIFI_KEYMGMT_WPS (1 << 9)
+
+#define WIFI_PAIRWISE_NONE (1 << 0)
+#define WIFI_PAIRWISE_TKIP (1 << 1)
+#define WIFI_PAIRWISE_CCMP (1 << 2)
+
+typedef struct {
+ const char *str;
+ unsigned int val;
+} strval_s;
+
+static strval_s wifi_keymgmt[] = {
+ { "none", WIFI_KEYMGMT_NONE },
+ { "ieee8021x", WIFI_KEYMGMT_IEEE8021X },
+ { "wpa-none", WIFI_KEYMGMT_WPA_NONE },
+ { "wpa-psk", WIFI_KEYMGMT_WPA_PSK },
+ { "wpa-psk-sha256", WIFI_KEYMGMT_WPA_PSK_256 },
+ { "wpa-ft-psk", WIFI_KEYMGMT_WPA_FT_PSK },
+ { "wpa-ft-eap", WIFI_KEYMGMT_WPA_FT_EAP },
+ { "wpa-eap", WIFI_KEYMGMT_WPA_EAP },
+ { "wpa-eap-sha256", WIFI_KEYMGMT_WPA_EAP_256 },
+ { "wps", WIFI_KEYMGMT_WPS },
+ { }
};
-struct bss_info_t {
+static strval_s wifi_pairwise[] = {
+ { "none", WIFI_PAIRWISE_NONE },
+ { "tkip", WIFI_PAIRWISE_TKIP },
+ { "ccmp", WIFI_PAIRWISE_CCMP },
+ { }
+};
+
+typedef enum {
+ WIFI_SECURITY_UNKNOWN = 0x00,
+ WIFI_SECURITY_NONE,
+ WIFI_SECURITY_WEP,
+ WIFI_SECURITY_PSK,
+ WIFI_SECURITY_PSK2,
+ WIFI_SECURITY_IEEE8021X,
+} wifi_security_e;
+
+typedef struct {
unsigned char ssid[33];
- enum netconfig_wifi_security security;
+ unsigned char bssid[6];
+ wifi_security_e security;
+ unsigned int wpa_keymgmt;
+ unsigned int wpa_pairwise;
+ unsigned int rsn_keymgmt;
+ unsigned int rsn_pairwise;
+ gboolean rsn_selected;
gboolean privacy;
gboolean wps;
-};
+} bss_info_t;
-static gboolean wifi_ssid_scan_state = FALSE;
-static GSList *wifi_bss_info_list = NULL;
-static guint netconfig_wifi_ssid_scan_timer = 0;
+static gboolean g_ssid_scan_state = FALSE;
+static GSList *bss_info_list = NULL;
+static guint ssid_scan_timer = 0;
static char *g_ssid = NULL;
-static gboolean __netconfig_wifi_ssid_scan_timeout(gpointer data)
+static void __check_keymgmt(const char *str_keymgmt, unsigned int *key_info)
+{
+ int i;
+
+ for (i = 0; wifi_keymgmt[i].str; i++) {
+ if (g_strcmp0(str_keymgmt, wifi_keymgmt[i].str) == 0) {
+ INFO("keymgmt : %s", str_keymgmt);
+ *key_info |= wifi_keymgmt[i].val;
+ break;
+ }
+ }
+}
+
+static void __check_pairwise(const char *str_pairwise, unsigned int *pairwise_info)
+{
+ int i;
+
+ for (i = 0; wifi_pairwise[i].str; i++) {
+ if (g_strcmp0(str_pairwise, wifi_pairwise[i].str) == 0) {
+ INFO("pairwise : %s", str_pairwise);
+ *pairwise_info |= wifi_pairwise[i].val;
+ break;
+ }
+ }
+}
+
+static wifi_security_e __check_security(bss_info_t *bss_info)
{
- netconfig_wifi_notify_ssid_scan_done();
+ gboolean ieee8021x = FALSE;
+ gboolean psk = FALSE;
+ gboolean ft_ieee8021x = FALSE;
+ gboolean ft_psk = FALSE;
+ unsigned int keymgmt = bss_info->rsn_keymgmt | bss_info->wpa_keymgmt;
+
+ if (keymgmt & (WIFI_KEYMGMT_WPA_EAP | WIFI_KEYMGMT_WPA_EAP_256))
+ ieee8021x = TRUE;
+ else if (keymgmt & WIFI_KEYMGMT_WPA_FT_EAP)
+ ft_ieee8021x = TRUE;
+
+ if (keymgmt & (WIFI_KEYMGMT_WPA_PSK | WIFI_KEYMGMT_WPA_PSK_256))
+ psk = TRUE;
+ else if (keymgmt & WIFI_KEYMGMT_WPA_FT_PSK)
+ ft_psk = TRUE;
+
+ if (ieee8021x || ft_ieee8021x)
+ bss_info->security = WIFI_SECURITY_IEEE8021X;
+ else if (psk || ft_psk)
+ bss_info->security = WIFI_SECURITY_PSK;
+ else if (bss_info->privacy)
+ bss_info->security = WIFI_SECURITY_WEP;
+ else
+ bss_info->security = WIFI_SECURITY_NONE;
+
+ if (bss_info->rsn_selected) {
+ unsigned int pairwise = bss_info->rsn_pairwise | bss_info->wpa_pairwise;
+ if ((pairwise & WIFI_PAIRWISE_CCMP) ||
+ (pairwise & (WIFI_PAIRWISE_CCMP | WIFI_PAIRWISE_TKIP)))
+ bss_info->security = WIFI_SECURITY_PSK2;
+ }
+
+ return bss_info->security;
+}
+
+static gboolean __ssid_scan_timeout(gpointer data)
+{
+ wifi_ssid_scan_emit_scan_completed();
return FALSE;
}
-static void __netconfig_wifi_ssid_scan_started(void)
+static void _start_ssid_scan_timer(void)
{
INFO("Wi-Fi SSID scan started");
- wifi_ssid_scan_state = TRUE;
+ g_ssid_scan_state = TRUE;
- netconfig_start_timer_seconds(5,
- __netconfig_wifi_ssid_scan_timeout,
- NULL,
- &netconfig_wifi_ssid_scan_timer);
+ netconfig_start_timer_seconds(5, __ssid_scan_timeout, NULL, &ssid_scan_timer);
}
-static void __netconfig_wifi_ssid_scan_finished(void)
+static void _stop_ssid_scan_timer(void)
{
INFO("Wi-Fi SSID scan finished");
- wifi_ssid_scan_state = FALSE;
+ g_ssid_scan_state = FALSE;
+
+ netconfig_stop_timer(&ssid_scan_timer);
+}
+
+static void _parse_wpa_message(GVariant *param, bss_info_t *bss_info)
+{
+ GVariantIter *iter1;
+ GVariant *var;
+ gchar *key;
+
+ g_variant_get(param, "a{sv}", &iter1);
+ while (g_variant_iter_loop(iter1, "{sv}", &key, &var)) {
+ if (g_strcmp0(key, "KeyMgmt") == 0) {
+ GVariantIter *iter2;
+ g_variant_get(var, "as", &iter2);
+ char *str;
+ while (g_variant_iter_loop(iter2, "s", &str)) {
+ if (str == NULL)
+ break;
+ unsigned int key_info = 0;
+ __check_keymgmt(str, &key_info);
+ if (bss_info->rsn_selected)
+ bss_info->rsn_keymgmt = key_info;
+ else
+ bss_info->wpa_keymgmt = key_info;
+ }
+ g_variant_iter_free(iter2);
+ } else if (g_strcmp0(key, "Pairwise") == 0) {
+ GVariantIter *iter2;
+ g_variant_get(var, "as", &iter2);
+ char *str;
+ while (g_variant_iter_loop(iter2, "s", &str)) {
+ if (str == NULL)
+ break;
+ unsigned int pairwise_info = 0;
+ __check_pairwise(str, &pairwise_info);
+ if (bss_info->rsn_selected)
+ bss_info->rsn_pairwise = pairwise_info;
+ else
+ bss_info->wpa_pairwise = pairwise_info;
+ }
+ g_variant_iter_free(iter2);
+ }
+ }
+
+ g_variant_iter_free(iter1);
- netconfig_stop_timer(&netconfig_wifi_ssid_scan_timer);
+ return;
}
-static gboolean __netconfig_wifi_invoke_ssid_scan(
- const char *object_path, const char *ssid)
+static gboolean _request_ssid_scan(const char *object_path, const char *ssid)
{
/* TODO: Revise following code */
-#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
GDBusConnection *connection = NULL;
GVariant *reply = NULL;
GVariant *params = NULL;
const gchar *key2 = "SSIDs";
int i = 0;
- connection = netconfig_gdbus_get_connection();
+ connection = netdbus_get_connection();
if (connection == NULL) {
DBG("Failed to get GDBusconnection");
return FALSE;
}
- builder1 = g_variant_builder_new(G_VARIANT_TYPE ("a{sv}"));
+ builder1 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
g_variant_builder_add(builder1, "{sv}", key1, g_variant_new_string(val1));
- builder2 = g_variant_builder_new(G_VARIANT_TYPE ("aay"));
- builder3 = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+ builder2 = g_variant_builder_new(G_VARIANT_TYPE("aay"));
+ builder3 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
- for (i = 0; i < strlen(ssid); i++) {
- g_variant_builder_add (builder3, "y", ssid[i]);
- }
+ for (i = 0; i < strlen(ssid); i++)
+ g_variant_builder_add(builder3, "y", ssid[i]);
g_variant_builder_add(builder2, "@ay", g_variant_builder_end(builder3));
g_variant_builder_add(builder1, "{sv}", key2, g_variant_builder_end(builder2));
NULL,
G_DBUS_CALL_FLAGS_NONE,
NETCONFIG_DBUS_REPLY_TIMEOUT,
- netconfig_gdbus_get_gdbus_cancellable(),
+ netdbus_get_cancellable(),
&error);
if (reply == NULL) {
return FALSE;
}
- if (g_ssid != NULL) {
+ if (g_ssid != NULL)
g_free(g_ssid);
- }
g_ssid = g_strdup(ssid);
return TRUE;
}
-static void __netconfig_wifi_notify_ssid_scan_done(void)
+static void _emit_ssid_scan_completed(void)
{
GVariantBuilder *builder = NULL;
GSList* list = NULL;
const char *prop_ssid = "ssid";
+ const char *prop_bssid = "bssid";
+ char bssid_buf[18] = {0,};
+ char *bssid_str = bssid_buf;
const char *prop_security = "security";
const char *prop_wps = "wps";
- builder = g_variant_builder_new(G_VARIANT_TYPE ("a{sv}"));
- for (list = wifi_bss_info_list; list != NULL; list = list->next) {
- struct bss_info_t *bss_info = (struct bss_info_t *)list->data;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ for (list = bss_info_list; list != NULL; list = list->next) {
+ bss_info_t *bss_info = (bss_info_t *)list->data;
if (bss_info && g_strcmp0((char *)bss_info->ssid, g_ssid) == 0) {
const gchar *ssid = (char *)bss_info->ssid;
- enum netconfig_wifi_security security = bss_info->security;
+ const gchar *bssid = (gchar *)&bss_info->bssid[0];
+ wifi_security_e security = __check_security(bss_info);
gboolean wps = bss_info->wps;
DBG("BSS found; SSID:%s security:%d WPS:%d", ssid, security, wps);
- /* SSID */
- g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("(s)", ssid));
- /* Security */
+ if (bssid) {
+ snprintf(bssid_str, sizeof(bssid_buf), MACSTR, MAC2STR(bssid));
+ DBG("BSSID: %s", bssid_str);
+ }
+ g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new_string(ssid));
+ g_variant_builder_add(builder, "{sv}", prop_bssid,
+ g_variant_new_string(bssid));
g_variant_builder_add(builder, "{sv}", prop_security, g_variant_new_int32(security));
/* WPS */
g_variant_builder_add(builder, "{sv}", prop_wps, g_variant_new_boolean(wps));
}
}
- wifi_emit_specific_scan_completed((Wifi *)get_netconfig_wifi_object(),
- g_variant_builder_end(builder));
+ wifi_emit_specific_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
if (builder)
g_variant_builder_unref(builder);
- if (wifi_bss_info_list != NULL) {
- g_slist_free_full(wifi_bss_info_list, g_free);
- wifi_bss_info_list = NULL;
+ if (bss_info_list != NULL) {
+ g_slist_free_full(bss_info_list, g_free);
+ bss_info_list = NULL;
}
if (g_ssid != NULL) {
return;
}
-static void __netconfig_wifi_check_security(const char *str_keymgmt, struct bss_info_t *bss_data)
+gboolean wifi_ssid_scan(const char *ssid)
{
- INFO("keymgmt : %s", str_keymgmt);
-
- if (strcmp(str_keymgmt, "ieee8021x") == 0) {
- bss_data->security = WIFI_SECURITY_IEEE8021X;
- } else if (strcmp(str_keymgmt, "wpa-psk") == 0) {
- bss_data->security = WIFI_SECURITY_PSK;
- } else if (strcmp(str_keymgmt, "wpa-psk-sha256") == 0) {
- bss_data->security = WIFI_SECURITY_PSK;
- } else if (strcmp(str_keymgmt, "wpa-ft-psk") == 0) {
- bss_data->security = WIFI_SECURITY_PSK;
- } else if (strcmp(str_keymgmt, "wpa-ft-eap") == 0) {
- bss_data->security = WIFI_SECURITY_IEEE8021X;
- } else if (strcmp(str_keymgmt, "wpa-eap") == 0) {
- bss_data->security = WIFI_SECURITY_IEEE8021X;
- } else if (strcmp(str_keymgmt, "wpa-eap-sha256") == 0) {
- bss_data->security = WIFI_SECURITY_IEEE8021X;
- } else if (strcmp(str_keymgmt, "wps") == 0) {
- bss_data->wps = TRUE;
+ const char *if_path;
+ static char *scan_ssid = NULL;
+
+ netconfig_wifi_bgscan_stop();
+
+ if (ssid != NULL) {
+ if (scan_ssid != NULL)
+ g_free(scan_ssid);
+ scan_ssid = g_strdup(ssid);
}
-}
-static void __netconfig_wifi_parse_keymgmt_message(GVariant *param, struct bss_info_t *bss_data)
-{
- GVariantIter *iter1;
- GVariant *var;
- gchar *key;
+ if (scan_ssid == NULL)
+ goto error;
- g_variant_get(param, "a{sv}", &iter1);
- while (g_variant_iter_loop(iter1, "{sv}", &key, &var)) {
- if (g_strcmp0(key, "KeyMgmt") == 0) {//check this :iterate
- GVariantIter *iter2;
- g_variant_get(var, "as", &iter2);
- char *str;
- while (g_variant_iter_loop(iter2, "s", &str)) {
- if (str == NULL) {
- break;
- }
- __netconfig_wifi_check_security(str, bss_data);
- }
- g_variant_iter_free (iter2);
- }
+ if_path = netconfig_wifi_get_supplicant_interface();
+ if (if_path == NULL) {
+ DBG("Fail to get wpa_supplicant DBus path");
+ goto error;
+ }
+
+ if (netconfig_wifi_get_scanning() == TRUE) {
+ DBG("Wi-Fi scan in progress, %s scan will be delayed", scan_ssid);
+ return TRUE;
}
- g_variant_iter_free (iter1);
+ if (bss_info_list) {
+ g_slist_free_full(bss_info_list, g_free);
+ bss_info_list = NULL;
+ }
- return;
+ INFO("Start Wi-Fi scan with %s(%d)", scan_ssid, strlen(scan_ssid));
+ if (_request_ssid_scan(if_path, (const char *)scan_ssid) == TRUE) {
+ _start_ssid_scan_timer();
+ g_free(scan_ssid);
+ scan_ssid = NULL;
+ return TRUE;
+ }
+
+error:
+ if (scan_ssid != NULL) {
+ g_free(scan_ssid);
+ scan_ssid = NULL;
+ }
+
+ netconfig_wifi_bgscan_start(FALSE);
+
+ return FALSE;
}
-gboolean netconfig_wifi_get_ssid_scan_state(void)
+gboolean wifi_ssid_scan_get_state(void)
{
- return wifi_ssid_scan_state;
+ return g_ssid_scan_state;
}
-void netconfig_wifi_notify_ssid_scan_done(void)
+void wifi_ssid_scan_emit_scan_completed(void)
{
- if (netconfig_wifi_get_ssid_scan_state() != TRUE)
+ if (g_ssid_scan_state != TRUE)
return;
- __netconfig_wifi_ssid_scan_finished();
-
- __netconfig_wifi_notify_ssid_scan_done();
+ _stop_ssid_scan_timer();
+ _emit_ssid_scan_completed();
+ netconfig_wifi_bgscan_start(FALSE);
}
-void netconfig_wifi_bss_added(GVariant *message)
+void wifi_ssid_scan_add_bss(GVariant *message)
{
GVariantIter *iter;
GVariant *value;
- const gchar *path = NULL;
- const gchar *key;
- struct bss_info_t *bss_info;
+ gchar *path = NULL;
+ gchar *key;
+ bss_info_t *bss_info;
- if (netconfig_wifi_get_ssid_scan_state() != TRUE)
+ if (g_ssid_scan_state != TRUE)
return;
INFO("NEW BSS added");
return;
}
-
if (path != NULL)
- INFO("Object path of BSS added is %s",path);
+ INFO("Object path of BSS added is %s", path);
- bss_info = g_try_new0(struct bss_info_t, 1);
+ bss_info = g_try_new0(bss_info_t, 1);
if (bss_info == NULL)
return;
const guchar *ssid;
gsize ssid_len;
ssid = g_variant_get_fixed_array(value, &ssid_len, sizeof(guchar));
- if (ssid_len > 0 && ssid_len < 33)
+ if (ssid != NULL && ssid_len > 0 && ssid_len < 33)
memcpy(bss_info->ssid, ssid, ssid_len);
else
memset(bss_info->ssid, 0, sizeof(bss_info->ssid));
gboolean privacy = FALSE;
privacy = g_variant_get_boolean(value);
bss_info->privacy = privacy;
- } else if ((g_strcmp0(key, "RSN") == 0) || (g_strcmp0(key, "WPA") == 0)) {
- __netconfig_wifi_parse_keymgmt_message(value, bss_info);
+ } else if (g_strcmp0(key, "RSN") == 0) {
+ bss_info->rsn_selected = TRUE;
+ _parse_wpa_message(value, bss_info);
+ } else if (g_strcmp0(key, "WPA") == 0) {
+ bss_info->rsn_selected = FALSE;
+ _parse_wpa_message(value, bss_info);
} else if (g_strcmp0(key, "IEs") == 0) {
const guchar *ie;
gsize ie_len;
ie = g_variant_get_fixed_array(value, &ie_len, sizeof(guchar));
- DBG("The IE : %s",ie);
+ DBG("The IE : %s", ie);
+ } else if (g_strcmp0(key, "BSSID") == 0) {
+ const guchar *bssid;
+ gsize bssid_len;
+
+ bssid = g_variant_get_fixed_array(value, &bssid_len, sizeof(guchar));
+ if (bssid != NULL && bssid_len == 6)
+ memcpy(bss_info->bssid, bssid, bssid_len);
}
}
g_variant_iter_free(iter);
+ if (path)
+ g_free(path);
if (bss_info->ssid[0] == '\0') {
g_free(bss_info);
bss_info->security = WIFI_SECURITY_NONE;
}
- wifi_bss_info_list = g_slist_append(wifi_bss_info_list, bss_info);
-}
-
-gboolean netconfig_wifi_ssid_scan(const char *ssid)
-{
- const char *if_path;
- static char *scan_ssid = NULL;
-
- netconfig_wifi_bgscan_stop();
-
- if (ssid != NULL) {
- g_free(scan_ssid);
- scan_ssid = g_strdup(ssid);
- }
-
- if (scan_ssid == NULL)
- goto error;
-
- if_path = netconfig_wifi_get_supplicant_interface();
- if (if_path == NULL) {
- DBG("Fail to get wpa_supplicant DBus path");
- goto error;
- }
-
- if (netconfig_wifi_get_scanning() == TRUE) {
- DBG("Wi-Fi scan in progress, %s scan will be delayed", scan_ssid);
- g_free(scan_ssid);
- return TRUE;
- }
-
- if (wifi_bss_info_list) {
- g_slist_free_full(wifi_bss_info_list, g_free);
- wifi_bss_info_list = NULL;
- }
-
- INFO("Start Wi-Fi scan with %s(%d)", scan_ssid, strlen(scan_ssid));
- if (__netconfig_wifi_invoke_ssid_scan(if_path,
- (const char *)scan_ssid) == TRUE) {
- __netconfig_wifi_ssid_scan_started();
-
- g_free(scan_ssid);
- scan_ssid = NULL;
-
- return TRUE;
- }
-
-error:
- if (scan_ssid != NULL) {
- g_free(scan_ssid);
- scan_ssid = NULL;
- }
-
- netconfig_wifi_bgscan_start(FALSE);
-
- return FALSE;
+ bss_info_list = g_slist_append(bss_info_list, bss_info);
}
gboolean handle_request_specific_scan(Wifi *wifi,
g_return_val_if_fail(wifi != NULL, FALSE);
g_return_val_if_fail(ssid != NULL, FALSE);
- result = netconfig_wifi_ssid_scan((const char *)ssid);
+ result = wifi_ssid_scan((const char *)ssid);
- if (result != TRUE) {
+ if (result != TRUE)
netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSpecificScan");
- } else {
- wifi_complete_request_wps_scan(wifi, context);
- }
+ else
+ wifi_complete_request_specific_scan(wifi, context);
return result;
}