]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Use AP Channel attribute in credential to speed up scan
authorJouni Malinen <j@w1.fi>
Sun, 28 Oct 2012 16:02:04 +0000 (18:02 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 28 Oct 2012 16:02:04 +0000 (18:02 +0200)
When WPS is used with NFC connection handover, the AP may indicate its
operating channel within the credential information. Use this
informatiom, if present, to speed up the scan process.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/wps/wps.h
src/wps/wps_attr_parse.c
src/wps/wps_attr_parse.h
src/wps/wps_attr_process.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wps_supplicant.c

index 17ee620c943f29faf6c1d1ca409785a5e0925bb6..74304dc23ff100e1fdbf14abf0b965a5479b7632 100644 (file)
@@ -42,6 +42,7 @@ struct wps_parse_attr;
  * @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
  *     this may be %NULL, if not used
  * @cred_attr_len: Length of cred_attr in octets
+ * @ap_channel: AP channel
  */
 struct wps_credential {
        u8 ssid[32];
@@ -54,6 +55,7 @@ struct wps_credential {
        u8 mac_addr[ETH_ALEN];
        const u8 *cred_attr;
        size_t cred_attr_len;
+       u16 ap_channel;
 };
 
 #define WPS_DEV_TYPE_LEN 8
index 5aa9b004f5c15244ba876c8c407e47f267a3a71e..3999b1b88108d64dce872ef17b22d803011eda14 100644 (file)
@@ -542,6 +542,14 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
                if (wps_parse_vendor_ext(attr, pos, len) < 0)
                        return -1;
                break;
+       case ATTR_AP_CHANNEL:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid AP Channel "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->ap_channel = pos;
+               break;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
                           "len=%u", type, len);
index 332e966a4d4f57c70e0d4921a95be9327fdaabae..88e51a4494455d1018b4e1bb1612690cccb0833f 100644 (file)
@@ -56,6 +56,7 @@ struct wps_parse_attr {
        const u8 *settings_delay_time; /* 1 octet */
        const u8 *network_key_shareable; /* 1 octet (Bool) */
        const u8 *request_to_enroll; /* 1 octet (Bool) */
+       const u8 *ap_channel; /* 2 octets */
 
        /* variable length fields */
        const u8 *manufacturer;
index d4c6e883b5a8a39ac5f3ff9b4c7802d0ab31d5e0..b81f106e7710d2afed8bf5aca1c4dc5dbe9008f7 100644 (file)
@@ -258,6 +258,19 @@ static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
 }
 
 
+static int wps_process_cred_ap_channel(struct wps_credential *cred,
+                                      const u8 *ap_channel)
+{
+       if (ap_channel == NULL)
+               return 0; /* optional attribute */
+
+       cred->ap_channel = WPA_GET_BE16(ap_channel);
+       wpa_printf(MSG_DEBUG, "WPS: AP Channel: %u", cred->ap_channel);
+
+       return 0;
+}
+
+
 static int wps_workaround_cred_key(struct wps_credential *cred)
 {
        if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
@@ -303,7 +316,8 @@ int wps_process_cred(struct wps_parse_attr *attr,
            wps_process_cred_eap_identity(cred, attr->eap_identity,
                                          attr->eap_identity_len) ||
            wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
-           wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled))
+           wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled) ||
+           wps_process_cred_ap_channel(cred, attr->ap_channel))
                return -1;
 
        return wps_workaround_cred_key(cred);
index 43e98830d674dc1e63dd5baa34e6bc6606b28799..3761fbf66d44631b04e73279bd438817d9190b39 100644 (file)
@@ -589,6 +589,7 @@ struct wpa_supplicant {
        int after_wps;
        int known_wps_freq;
        unsigned int wps_freq;
+       u16 wps_ap_channel;
        int wps_fragment_size;
        int auto_reconnect_disabled;
 
index 06551567fe81b3654d6bf63fcdea4986b3b3aa26..5977e1a1a7e9ceb60836722f6b7455d5298cd1f0 100644 (file)
@@ -403,6 +403,9 @@ static int wpa_supplicant_wps_cred(void *ctx,
 
        wpas_wps_security_workaround(wpa_s, ssid, cred);
 
+       if (cred->ap_channel)
+               wpa_s->wps_ap_channel = cred->ap_channel;
+
 #ifndef CONFIG_NO_CONFIG_WRITE
        if (wpa_s->conf->update_config &&
            wpa_config_write(wpa_s->confname, wpa_s->conf)) {
@@ -1896,6 +1899,8 @@ int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid)
 static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
                             struct wps_parse_attr *attr)
 {
+       wpa_s->wps_ap_channel = 0;
+
        if (wps_oob_use_cred(wpa_s->wps, attr) < 0)
                return -1;
 
@@ -1906,6 +1911,24 @@ static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
                   "based on the received credential added");
        wpa_s->normal_scans = 0;
        wpa_supplicant_reinit_autoscan(wpa_s);
+       if (wpa_s->wps_ap_channel) {
+               u16 chan = wpa_s->wps_ap_channel;
+               int freq = 0;
+
+               if (chan >= 1 && chan <= 13)
+                       freq = 2407 + 5 * chan;
+               else if (chan == 14)
+                       freq = 2484;
+               else if (chan >= 30)
+                       freq = 5000 + 5 * chan;
+
+               if (freq) {
+                       wpa_printf(MSG_DEBUG, "WPS: Credential indicated "
+                                  "AP channel %u -> %u MHz", chan, freq);
+                       wpa_s->after_wps = 5;
+                       wpa_s->wps_freq = freq;
+               }
+       }
        wpa_s->disconnected = 0;
        wpa_s->reassociate = 1;
        wpa_supplicant_req_scan(wpa_s, 0, 0);