WPS: Set Request Type properly into WPS IE in ProbeReq/AssocReq
[wpasupplicant] / src / wps / wps.c
index 2b3751d..44cac3f 100644 (file)
@@ -17,6 +17,7 @@
 #include "common.h"
 #include "wps_i.h"
 #include "wps_dev_attr.h"
+#include "ieee802_11_defs.h"
 
 
 struct wps_data * wps_init(const struct wps_config *cfg)
@@ -60,6 +61,24 @@ struct wps_data * wps_init(const struct wps_config *cfg)
 
        data->state = data->registrar ? RECV_M1 : SEND_M1;
 
+       if (cfg->assoc_wps_ie) {
+               struct wps_parse_attr attr;
+               wpa_hexdump_buf(MSG_DEBUG, "WPS: WPS IE from (Re)AssocReq",
+                               cfg->assoc_wps_ie);
+               if (wps_parse_msg(cfg->assoc_wps_ie, &attr) < 0) {
+                       wpa_printf(MSG_DEBUG, "WPS: Failed to parse WPS IE "
+                                  "from (Re)AssocReq");
+               } else if (attr.request_type == NULL) {
+                       wpa_printf(MSG_DEBUG, "WPS: No Request Type attribute "
+                                  "in (Re)AssocReq WPS IE");
+               } else {
+                       wpa_printf(MSG_DEBUG, "WPS: Request Type (from WPS IE "
+                                  "in (Re)AssocReq WPS IE): %d",
+                                  *attr.request_type);
+                       data->request_type = *attr.request_type;
+               }
+       }
+
        return data;
 }
 
@@ -153,3 +172,73 @@ const u8 * wps_get_uuid_e(const u8 *buf, size_t len)
                return NULL;
        return attr.uuid_e;
 }
+
+
+struct wpabuf * wps_build_assoc_req_ie(u8 req_type)
+{
+       struct wpabuf *ie;
+       u8 *len;
+
+       wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
+                  "Request");
+       ie = wpabuf_alloc(100);
+       if (ie == NULL)
+               return NULL;
+
+       wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
+       len = wpabuf_put(ie, 1);
+       wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
+
+       if (wps_build_version(ie) ||
+           wps_build_req_type(ie, req_type)) {
+               wpabuf_free(ie);
+               return NULL;
+       }
+
+       *len = wpabuf_len(ie) - 2;
+
+       return ie;
+}
+
+
+struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
+                                      const u8 *uuid, u8 req_type)
+{
+       struct wpabuf *ie;
+       u8 *len;
+       u16 methods;
+
+       wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
+
+       ie = wpabuf_alloc(200);
+       if (ie == NULL)
+               return NULL;
+
+       wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
+       len = wpabuf_put(ie, 1);
+       wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
+
+       if (pbc)
+               methods = WPS_CONFIG_PUSHBUTTON;
+       else
+               methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
+                       WPS_CONFIG_KEYPAD;
+
+       if (wps_build_version(ie) ||
+           wps_build_req_type(ie, req_type) ||
+           wps_build_config_methods(ie, methods) ||
+           wps_build_uuid_e(ie, uuid) ||
+           wps_build_primary_dev_type(dev, ie) ||
+           wps_build_rf_bands(dev, ie) ||
+           wps_build_assoc_state(NULL, ie) ||
+           wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
+           wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
+                                     DEV_PW_DEFAULT)) {
+               wpabuf_free(ie);
+               return NULL;
+       }
+
+       *len = wpabuf_len(ie) - 2;
+
+       return ie;
+}