@@ -3616,6 +3616,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
}
os_free(bss->device_name);
bss->device_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "wps_application_ext") == 0) {
+ wpabuf_free(bss->wps_application_ext);
+ bss->wps_application_ext = wpabuf_parse_bin(pos);
} else if (os_strcmp(buf, "manufacturer") == 0) {
if (os_strlen(pos) > 64) {
wpa_printf(MSG_ERROR, "Line %d: Too long manufacturer",
@@ -813,6 +813,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->upc);
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
wpabuf_free(conf->wps_vendor_ext[i]);
+ wpabuf_free(conf->wps_application_ext);
wpabuf_free(conf->wps_nfc_dh_pubkey);
wpabuf_free(conf->wps_nfc_dh_privkey);
wpabuf_free(conf->wps_nfc_dev_pw);
@@ -498,6 +498,7 @@ struct hostapd_bss_config {
char *model_url;
char *upc;
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+ struct wpabuf *wps_application_ext;
int wps_nfc_pw_from_config;
int wps_nfc_dev_pw_id;
struct wpabuf *wps_nfc_dh_pubkey;
@@ -985,6 +985,16 @@ static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
}
+static int hostapd_wps_set_application_ext(struct hostapd_data *hapd,
+ struct wps_context *wps)
+{
+ wpabuf_free(wps->dev.application_ext);
+ wps->dev.application_ext = wpabuf_dup(hapd->conf->wps_application_ext);
+
+ return 0;
+}
+
+
static void hostapd_free_wps(struct wps_context *wps)
{
int i;
@@ -1077,6 +1087,9 @@ int hostapd_init_wps(struct hostapd_data *hapd,
if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
goto fail;
+ if (hostapd_wps_set_application_ext(hapd, wps) < 0)
+ goto fail;
+
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
if (conf->wps_rf_bands) {
@@ -1311,6 +1324,7 @@ void hostapd_update_wps(struct hostapd_data *hapd)
#endif /* CONFIG_WPS_UPNP */
hostapd_wps_set_vendor_ext(hapd, hapd->wps);
+ hostapd_wps_set_application_ext(hapd, hapd->wps);
if (hapd->conf->wps_state)
wps_registrar_update_ie(hapd->wps->registrar);
@@ -98,6 +98,7 @@ struct wps_device_data {
u16 config_methods;
struct wpabuf *vendor_ext_m1;
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+ struct wpabuf *application_ext;
int p2p;
u8 multi_ap_ext;
@@ -242,6 +242,19 @@ int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
}
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg)
+{
+ wpa_hexdump(MSG_DEBUG, "WPS: * Application Extension",
+ wpabuf_head_u8(dev->application_ext),
+ wpabuf_len(dev->application_ext));
+ wpabuf_put_be16(msg, ATTR_APPLICATION_EXT);
+ wpabuf_put_be16(msg, wpabuf_len(dev->application_ext));
+ wpabuf_put_buf(msg, dev->application_ext);
+
+ return 0;
+}
+
+
static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
size_t str_len)
{
@@ -33,6 +33,7 @@ void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
void wps_device_data_free(struct wps_device_data *dev);
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
+int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg);
int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
unsigned int num_req_dev_types,
const u8 *req_dev_types);
@@ -1331,7 +1331,8 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
(reg->dualband && wps_build_rf_bands(®->wps->dev, beacon, 0)) ||
wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(®->wps->dev, beacon)) {
+ wps_build_vendor_ext(®->wps->dev, beacon) ||
+ wps_build_application_ext(®->wps->dev, beacon)) {
wpabuf_free(beacon);
wpabuf_free(probe);
return -1;
@@ -1361,7 +1362,8 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_probe_config_methods(reg, probe) ||
(reg->dualband && wps_build_rf_bands(®->wps->dev, probe, 0)) ||
wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(®->wps->dev, probe)) {
+ wps_build_vendor_ext(®->wps->dev, probe) ||
+ wps_build_application_ext(®->wps->dev, probe)) {
wpabuf_free(beacon);
wpabuf_free(probe);
return -1;