summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-05-04 15:24:32 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-05-04 16:17:05 +0300
commit305a6cb8bc6aa464a7a5e2669d00ac4691f4a2a5 (patch)
tree91a9ae59b32cd9d932a0abf86447d8a96f776052
parent4cd19238f5499623391ebf74c74af03905a14ef8 (diff)
downloadconnman-305a6cb8bc6aa464a7a5e2669d00ac4691f4a2a5.tar.gz
connman-305a6cb8bc6aa464a7a5e2669d00ac4691f4a2a5.tar.bz2
connman-305a6cb8bc6aa464a7a5e2669d00ac4691f4a2a5.zip
wifi: Allow max number of scan entries
Do no limit the scan entries to 4 (G_SUPPLICANT_MAX_FAST_SCAN) but use the limit given by the driver. The limit is given by wpa_s. If the supplicant does not return the limit, then use 4 as a max value.
-rw-r--r--gsupplicant/gsupplicant.h31
-rw-r--r--gsupplicant/supplicant.c19
-rw-r--r--plugins/wifi.c59
3 files changed, 85 insertions, 24 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 883de7f4..5dc53642 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -73,8 +73,6 @@ extern "C" {
#define G_SUPPLICANT_PAIRWISE_TKIP (1 << 1)
#define G_SUPPLICANT_PAIRWISE_CCMP (1 << 2)
-#define G_SUPPLICANT_MAX_FAST_SCAN 4
-
#define G_SUPPLICANT_WPS_CONFIGURED (1 << 0)
#define G_SUPPLICANT_WPS_PBC (1 << 1)
#define G_SUPPLICANT_WPS_PIN (1 << 2)
@@ -139,15 +137,26 @@ struct _GSupplicantSSID {
typedef struct _GSupplicantSSID GSupplicantSSID;
+/*
+ * Max number of SSIDs that can be scanned.
+ * In wpa_s 0.7x the limit is 4.
+ * In wps_s 0.8 or later it is 16.
+ * The value is only used if wpa_supplicant does not return any max limit
+ * for number of scannable SSIDs.
+ */
+#define WPAS_MAX_SCAN_SSIDS 4
+
+struct scan_ssid {
+ unsigned char ssid[32];
+ uint8_t ssid_len;
+};
+
struct _GSupplicantScanParams {
- struct scan_ssid {
- unsigned char ssid[32];
- uint8_t ssid_len;
- } ssids[G_SUPPLICANT_MAX_FAST_SCAN];
+ GSList *ssids;
uint8_t num_ssids;
- uint16_t freqs[G_SUPPLICANT_MAX_FAST_SCAN];
+ uint16_t *freqs;
};
typedef struct _GSupplicantScanParams GSupplicantScanParams;
@@ -250,6 +259,14 @@ typedef struct _GSupplicantCallbacks GSupplicantCallbacks;
int g_supplicant_register(const GSupplicantCallbacks *callbacks);
void g_supplicant_unregister(const GSupplicantCallbacks *callbacks);
+static inline
+void g_supplicant_free_scan_params(GSupplicantScanParams *scan_params)
+{
+ g_slist_free_full(scan_params->ssids, g_free);
+ g_free(scan_params->freqs);
+ g_free(scan_params);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 58d40c13..867fa028 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -742,6 +742,9 @@ unsigned int g_supplicant_interface_get_max_scan_ssids(
if (interface == NULL)
return 0;
+ if (interface->max_scan_ssids == 0)
+ return WPAS_MAX_SCAN_SSIDS;
+
return interface->max_scan_ssids;
}
@@ -2618,7 +2621,7 @@ static void interface_scan_result(const char *error,
}
if (data != NULL && data->scan_params != NULL)
- g_free(data->scan_params);
+ g_supplicant_free_scan_params(data->scan_params);
dbus_free(data);
}
@@ -2643,7 +2646,7 @@ static void add_scan_frequencies(DBusMessageIter *iter,
unsigned int freq;
int i;
- for (i = 0; i < G_SUPPLICANT_MAX_FAST_SCAN; i++) {
+ for (i = 0; i < scan_data->num_ssids; i++) {
freq = scan_data->freqs[i];
if (!freq)
break;
@@ -2668,11 +2671,13 @@ static void append_ssid(DBusMessageIter *iter,
static void append_ssids(DBusMessageIter *iter, void *user_data)
{
GSupplicantScanParams *scan_data = user_data;
- int i;
+ GSList *list;
- for (i = 0; i < scan_data->num_ssids; i++)
- append_ssid(iter, scan_data->ssids[i].ssid,
- scan_data->ssids[i].ssid_len);
+ for (list = scan_data->ssids; list; list = list->next) {
+ struct scan_ssid *scan_ssid = list->data;
+
+ append_ssid(iter, scan_ssid->ssid, scan_ssid->ssid_len);
+ }
}
static void supplicant_add_scan_frequency(DBusMessageIter *dict,
@@ -2683,7 +2688,7 @@ static void supplicant_add_scan_frequency(DBusMessageIter *dict,
DBusMessageIter entry, value, array;
const char *key = "Channels";
- if (scan_params->freqs[0] != 0) {
+ if (scan_params->freqs && scan_params->freqs[0] != 0) {
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 6e6bbca7..2f1f7a66 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -495,6 +495,7 @@ static int add_scan_param(gchar *hex_ssid, int freq,
int driver_max_scan_ssids)
{
unsigned int i;
+ struct scan_ssid *scan_ssid;
if (driver_max_scan_ssids > scan_data->num_ssids && hex_ssid != NULL) {
gchar *ssid;
@@ -510,15 +511,44 @@ static int add_scan_param(gchar *hex_ssid, int freq,
ssid[j++] = hex;
}
- memcpy(scan_data->ssids[scan_data->num_ssids].ssid, ssid, j);
- scan_data->ssids[scan_data->num_ssids].ssid_len = j;
+ scan_ssid = g_try_new(struct scan_ssid, 1);
+ if (scan_ssid == NULL) {
+ g_free(ssid);
+ return -ENOMEM;
+ }
+
+ memcpy(scan_ssid->ssid, ssid, j);
+ scan_ssid->ssid_len = j;
+ scan_data->ssids = g_slist_prepend(scan_data->ssids,
+ scan_ssid);
+
scan_data->num_ssids++;
g_free(ssid);
+ } else
+ return -EINVAL;
+
+ scan_data->ssids = g_slist_reverse(scan_data->ssids);
+
+ if (scan_data->freqs == NULL) {
+ scan_data->freqs = g_try_malloc0(sizeof(uint16_t) *
+ scan_data->num_ssids);
+ if (scan_data->freqs == NULL) {
+ g_slist_free_full(scan_data->ssids, g_free);
+ return -ENOMEM;
+ }
+ } else {
+ scan_data->freqs = g_try_realloc(scan_data->freqs,
+ sizeof(uint16_t) * scan_data->num_ssids);
+ if (scan_data->freqs == NULL) {
+ g_slist_free_full(scan_data->ssids, g_free);
+ return -ENOMEM;
+ }
+ scan_data->freqs[scan_data->num_ssids - 1] = 0;
}
/* Don't add duplicate entries */
- for (i = 0; i < G_SUPPLICANT_MAX_FAST_SCAN; i++) {
+ for (i = 0; i < scan_data->num_ssids; i++) {
if (scan_data->freqs[i] == 0) {
scan_data->freqs[i] = freq;
break;
@@ -639,8 +669,7 @@ static int get_latest_connections(int max_ssids,
g_strfreev(services);
- num_ssids = num_ssids > G_SUPPLICANT_MAX_FAST_SCAN ?
- G_SUPPLICANT_MAX_FAST_SCAN : num_ssids;
+ num_ssids = num_ssids > max_ssids ? max_ssids : num_ssids;
iter = g_sequence_get_begin_iter(latest_list);
@@ -690,7 +719,7 @@ static int wifi_scan_fast(struct connman_device *device)
ret = get_latest_connections(driver_max_ssids, scan_params);
if (ret <= 0) {
- g_free(scan_params);
+ g_supplicant_free_scan_params(scan_params);
return wifi_scan(device);
}
@@ -702,7 +731,7 @@ static int wifi_scan_fast(struct connman_device *device)
if (ret == 0)
connman_device_set_scanning(device, TRUE);
else {
- g_free(scan_params);
+ g_supplicant_free_scan_params(scan_params);
connman_device_unref(device);
}
@@ -715,6 +744,7 @@ static int wifi_scan_hidden(struct connman_device *device,
{
struct wifi_data *wifi = connman_device_get_data(device);
GSupplicantScanParams *scan_params = NULL;
+ struct scan_ssid *scan_ssid;
struct hidden_params *hidden;
int ret;
@@ -729,8 +759,17 @@ static int wifi_scan_hidden(struct connman_device *device,
scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
if (scan_params == NULL)
return -ENOMEM;
- memcpy(scan_params->ssids[0].ssid, ssid, ssid_len);
- scan_params->ssids[0].ssid_len = ssid_len;
+
+ scan_ssid = g_try_new(struct scan_ssid, 1);
+ if (scan_ssid == NULL) {
+ g_free(scan_params);
+ return -ENOMEM;
+ }
+
+ memcpy(scan_ssid->ssid, ssid, ssid_len);
+ scan_ssid->ssid_len = ssid_len;
+ scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
+
scan_params->num_ssids = 1;
hidden = g_try_new0(struct hidden_params, 1);
@@ -753,7 +792,7 @@ static int wifi_scan_hidden(struct connman_device *device,
connman_device_set_scanning(device, TRUE);
else {
connman_device_unref(device);
- g_free(scan_params);
+ g_supplicant_free_scan_params(scan_params);
hidden_free(wifi->hidden);
wifi->hidden = NULL;
}