xref: /freebsd/contrib/wpa/src/wps/wps_dev_attr.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * Wi-Fi Protected Setup - device attributes
339beb93cSSam Leffler  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
5f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo  * See README for more details.
739beb93cSSam Leffler  */
839beb93cSSam Leffler 
939beb93cSSam Leffler #include "includes.h"
1039beb93cSSam Leffler 
1139beb93cSSam Leffler #include "common.h"
1239beb93cSSam Leffler #include "wps_i.h"
1339beb93cSSam Leffler #include "wps_dev_attr.h"
1439beb93cSSam Leffler 
1539beb93cSSam Leffler 
wps_build_manufacturer(struct wps_device_data * dev,struct wpabuf * msg)16f05cddf9SRui Paulo int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg)
1739beb93cSSam Leffler {
1839beb93cSSam Leffler 	size_t len;
1939beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Manufacturer");
2039beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_MANUFACTURER);
2139beb93cSSam Leffler 	len = dev->manufacturer ? os_strlen(dev->manufacturer) : 0;
22f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT
2339beb93cSSam Leffler 	if (len == 0) {
2439beb93cSSam Leffler 		/*
2539beb93cSSam Leffler 		 * Some deployed WPS implementations fail to parse zero-length
26f05cddf9SRui Paulo 		 * attributes. As a workaround, send a space character if the
2739beb93cSSam Leffler 		 * device attribute string is empty.
2839beb93cSSam Leffler 		 */
2939beb93cSSam Leffler 		wpabuf_put_be16(msg, 1);
30f05cddf9SRui Paulo 		wpabuf_put_u8(msg, ' ');
31f05cddf9SRui Paulo 		return 0;
32f05cddf9SRui Paulo 	}
33f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */
3439beb93cSSam Leffler 	wpabuf_put_be16(msg, len);
3539beb93cSSam Leffler 	wpabuf_put_data(msg, dev->manufacturer, len);
3639beb93cSSam Leffler 	return 0;
3739beb93cSSam Leffler }
3839beb93cSSam Leffler 
3939beb93cSSam Leffler 
wps_build_model_name(struct wps_device_data * dev,struct wpabuf * msg)40f05cddf9SRui Paulo int wps_build_model_name(struct wps_device_data *dev, struct wpabuf *msg)
4139beb93cSSam Leffler {
4239beb93cSSam Leffler 	size_t len;
4339beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Model Name");
4439beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_MODEL_NAME);
4539beb93cSSam Leffler 	len = dev->model_name ? os_strlen(dev->model_name) : 0;
46f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT
4739beb93cSSam Leffler 	if (len == 0) {
4839beb93cSSam Leffler 		/*
4939beb93cSSam Leffler 		 * Some deployed WPS implementations fail to parse zero-length
50f05cddf9SRui Paulo 		 * attributes. As a workaround, send a space character if the
5139beb93cSSam Leffler 		 * device attribute string is empty.
5239beb93cSSam Leffler 		 */
5339beb93cSSam Leffler 		wpabuf_put_be16(msg, 1);
54f05cddf9SRui Paulo 		wpabuf_put_u8(msg, ' ');
55f05cddf9SRui Paulo 		return 0;
56f05cddf9SRui Paulo 	}
57f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */
5839beb93cSSam Leffler 	wpabuf_put_be16(msg, len);
5939beb93cSSam Leffler 	wpabuf_put_data(msg, dev->model_name, len);
6039beb93cSSam Leffler 	return 0;
6139beb93cSSam Leffler }
6239beb93cSSam Leffler 
6339beb93cSSam Leffler 
wps_build_model_number(struct wps_device_data * dev,struct wpabuf * msg)64f05cddf9SRui Paulo int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg)
6539beb93cSSam Leffler {
6639beb93cSSam Leffler 	size_t len;
6739beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Model Number");
6839beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_MODEL_NUMBER);
6939beb93cSSam Leffler 	len = dev->model_number ? os_strlen(dev->model_number) : 0;
70f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT
7139beb93cSSam Leffler 	if (len == 0) {
7239beb93cSSam Leffler 		/*
7339beb93cSSam Leffler 		 * Some deployed WPS implementations fail to parse zero-length
74f05cddf9SRui Paulo 		 * attributes. As a workaround, send a space character if the
7539beb93cSSam Leffler 		 * device attribute string is empty.
7639beb93cSSam Leffler 		 */
7739beb93cSSam Leffler 		wpabuf_put_be16(msg, 1);
78f05cddf9SRui Paulo 		wpabuf_put_u8(msg, ' ');
79f05cddf9SRui Paulo 		return 0;
80f05cddf9SRui Paulo 	}
81f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */
8239beb93cSSam Leffler 	wpabuf_put_be16(msg, len);
8339beb93cSSam Leffler 	wpabuf_put_data(msg, dev->model_number, len);
8439beb93cSSam Leffler 	return 0;
8539beb93cSSam Leffler }
8639beb93cSSam Leffler 
8739beb93cSSam Leffler 
wps_build_serial_number(struct wps_device_data * dev,struct wpabuf * msg)885b9c547cSRui Paulo int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg)
8939beb93cSSam Leffler {
9039beb93cSSam Leffler 	size_t len;
9139beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Serial Number");
9239beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_SERIAL_NUMBER);
9339beb93cSSam Leffler 	len = dev->serial_number ? os_strlen(dev->serial_number) : 0;
94f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT
9539beb93cSSam Leffler 	if (len == 0) {
9639beb93cSSam Leffler 		/*
9739beb93cSSam Leffler 		 * Some deployed WPS implementations fail to parse zero-length
98f05cddf9SRui Paulo 		 * attributes. As a workaround, send a space character if the
9939beb93cSSam Leffler 		 * device attribute string is empty.
10039beb93cSSam Leffler 		 */
10139beb93cSSam Leffler 		wpabuf_put_be16(msg, 1);
102f05cddf9SRui Paulo 		wpabuf_put_u8(msg, ' ');
103f05cddf9SRui Paulo 		return 0;
104f05cddf9SRui Paulo 	}
105f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */
10639beb93cSSam Leffler 	wpabuf_put_be16(msg, len);
10739beb93cSSam Leffler 	wpabuf_put_data(msg, dev->serial_number, len);
10839beb93cSSam Leffler 	return 0;
10939beb93cSSam Leffler }
11039beb93cSSam Leffler 
11139beb93cSSam Leffler 
wps_build_primary_dev_type(struct wps_device_data * dev,struct wpabuf * msg)11239beb93cSSam Leffler int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg)
11339beb93cSSam Leffler {
11439beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Primary Device Type");
11539beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE);
116e28a4053SRui Paulo 	wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
117e28a4053SRui Paulo 	wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN);
11839beb93cSSam Leffler 	return 0;
11939beb93cSSam Leffler }
12039beb93cSSam Leffler 
12139beb93cSSam Leffler 
wps_build_secondary_dev_type(struct wps_device_data * dev,struct wpabuf * msg)122f05cddf9SRui Paulo int wps_build_secondary_dev_type(struct wps_device_data *dev,
123f05cddf9SRui Paulo 				  struct wpabuf *msg)
124f05cddf9SRui Paulo {
125f05cddf9SRui Paulo 	if (!dev->num_sec_dev_types)
126f05cddf9SRui Paulo 		return 0;
127f05cddf9SRui Paulo 
128f05cddf9SRui Paulo 	wpa_printf(MSG_DEBUG, "WPS:  * Secondary Device Type");
129f05cddf9SRui Paulo 	wpabuf_put_be16(msg, ATTR_SECONDARY_DEV_TYPE_LIST);
130f05cddf9SRui Paulo 	wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
131f05cddf9SRui Paulo 	wpabuf_put_data(msg, dev->sec_dev_type,
132f05cddf9SRui Paulo 			WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
133f05cddf9SRui Paulo 
134f05cddf9SRui Paulo 	return 0;
135f05cddf9SRui Paulo }
136f05cddf9SRui Paulo 
137f05cddf9SRui Paulo 
wps_build_req_dev_type(struct wps_device_data * dev,struct wpabuf * msg,unsigned int num_req_dev_types,const u8 * req_dev_types)138f05cddf9SRui Paulo int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
139f05cddf9SRui Paulo 			   unsigned int num_req_dev_types,
140f05cddf9SRui Paulo 			   const u8 *req_dev_types)
141f05cddf9SRui Paulo {
142f05cddf9SRui Paulo 	unsigned int i;
143f05cddf9SRui Paulo 
144f05cddf9SRui Paulo 	for (i = 0; i < num_req_dev_types; i++) {
145f05cddf9SRui Paulo 		wpa_hexdump(MSG_DEBUG, "WPS: * Requested Device Type",
146f05cddf9SRui Paulo 			    req_dev_types + i * WPS_DEV_TYPE_LEN,
147f05cddf9SRui Paulo 			    WPS_DEV_TYPE_LEN);
148f05cddf9SRui Paulo 		wpabuf_put_be16(msg, ATTR_REQUESTED_DEV_TYPE);
149f05cddf9SRui Paulo 		wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
150f05cddf9SRui Paulo 		wpabuf_put_data(msg, req_dev_types + i * WPS_DEV_TYPE_LEN,
151f05cddf9SRui Paulo 				WPS_DEV_TYPE_LEN);
152f05cddf9SRui Paulo 	}
153f05cddf9SRui Paulo 
154f05cddf9SRui Paulo 	return 0;
155f05cddf9SRui Paulo }
156f05cddf9SRui Paulo 
157f05cddf9SRui Paulo 
wps_build_dev_name(struct wps_device_data * dev,struct wpabuf * msg)158f05cddf9SRui Paulo int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg)
15939beb93cSSam Leffler {
16039beb93cSSam Leffler 	size_t len;
16139beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * Device Name");
16239beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_DEV_NAME);
16339beb93cSSam Leffler 	len = dev->device_name ? os_strlen(dev->device_name) : 0;
164f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT
16539beb93cSSam Leffler 	if (len == 0) {
16639beb93cSSam Leffler 		/*
16739beb93cSSam Leffler 		 * Some deployed WPS implementations fail to parse zero-length
168f05cddf9SRui Paulo 		 * attributes. As a workaround, send a space character if the
16939beb93cSSam Leffler 		 * device attribute string is empty.
17039beb93cSSam Leffler 		 */
17139beb93cSSam Leffler 		wpabuf_put_be16(msg, 1);
172f05cddf9SRui Paulo 		wpabuf_put_u8(msg, ' ');
173f05cddf9SRui Paulo 		return 0;
174f05cddf9SRui Paulo 	}
175f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */
17639beb93cSSam Leffler 	wpabuf_put_be16(msg, len);
17739beb93cSSam Leffler 	wpabuf_put_data(msg, dev->device_name, len);
17839beb93cSSam Leffler 	return 0;
17939beb93cSSam Leffler }
18039beb93cSSam Leffler 
18139beb93cSSam Leffler 
wps_build_device_attrs(struct wps_device_data * dev,struct wpabuf * msg)18239beb93cSSam Leffler int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg)
18339beb93cSSam Leffler {
18439beb93cSSam Leffler 	if (wps_build_manufacturer(dev, msg) ||
18539beb93cSSam Leffler 	    wps_build_model_name(dev, msg) ||
18639beb93cSSam Leffler 	    wps_build_model_number(dev, msg) ||
18739beb93cSSam Leffler 	    wps_build_serial_number(dev, msg) ||
18839beb93cSSam Leffler 	    wps_build_primary_dev_type(dev, msg) ||
18939beb93cSSam Leffler 	    wps_build_dev_name(dev, msg))
19039beb93cSSam Leffler 		return -1;
19139beb93cSSam Leffler 	return 0;
19239beb93cSSam Leffler }
19339beb93cSSam Leffler 
19439beb93cSSam Leffler 
wps_build_os_version(struct wps_device_data * dev,struct wpabuf * msg)19539beb93cSSam Leffler int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg)
19639beb93cSSam Leffler {
19739beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS:  * OS Version");
19839beb93cSSam Leffler 	wpabuf_put_be16(msg, ATTR_OS_VERSION);
19939beb93cSSam Leffler 	wpabuf_put_be16(msg, 4);
20039beb93cSSam Leffler 	wpabuf_put_be32(msg, 0x80000000 | dev->os_version);
20139beb93cSSam Leffler 	return 0;
20239beb93cSSam Leffler }
20339beb93cSSam Leffler 
20439beb93cSSam Leffler 
wps_build_vendor_ext_m1(struct wps_device_data * dev,struct wpabuf * msg)205f05cddf9SRui Paulo int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
206f05cddf9SRui Paulo {
207f05cddf9SRui Paulo 	if (dev->vendor_ext_m1 != NULL) {
208f05cddf9SRui Paulo 		wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension M1",
209f05cddf9SRui Paulo 			    wpabuf_head_u8(dev->vendor_ext_m1),
210f05cddf9SRui Paulo 			    wpabuf_len(dev->vendor_ext_m1));
211f05cddf9SRui Paulo 		wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
212f05cddf9SRui Paulo 		wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1));
213f05cddf9SRui Paulo 		wpabuf_put_buf(msg, dev->vendor_ext_m1);
214f05cddf9SRui Paulo 	}
215f05cddf9SRui Paulo 	return 0;
216f05cddf9SRui Paulo }
217f05cddf9SRui Paulo 
218f05cddf9SRui Paulo 
wps_build_rf_bands(struct wps_device_data * dev,struct wpabuf * msg,u8 rf_band)2195b9c547cSRui Paulo int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
2205b9c547cSRui Paulo 		       u8 rf_band)
22139beb93cSSam Leffler {
2225b9c547cSRui Paulo 	return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
22339beb93cSSam Leffler }
22439beb93cSSam Leffler 
22539beb93cSSam Leffler 
wps_build_vendor_ext(struct wps_device_data * dev,struct wpabuf * msg)226f05cddf9SRui Paulo int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
227f05cddf9SRui Paulo {
228f05cddf9SRui Paulo 	int i;
229f05cddf9SRui Paulo 
230f05cddf9SRui Paulo 	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
231f05cddf9SRui Paulo 		if (dev->vendor_ext[i] == NULL)
232f05cddf9SRui Paulo 			continue;
233f05cddf9SRui Paulo 		wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension",
234f05cddf9SRui Paulo 			    wpabuf_head_u8(dev->vendor_ext[i]),
235f05cddf9SRui Paulo 			    wpabuf_len(dev->vendor_ext[i]));
236f05cddf9SRui Paulo 		wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
237f05cddf9SRui Paulo 		wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext[i]));
238f05cddf9SRui Paulo 		wpabuf_put_buf(msg, dev->vendor_ext[i]);
239f05cddf9SRui Paulo 	}
240f05cddf9SRui Paulo 
241f05cddf9SRui Paulo 	return 0;
242f05cddf9SRui Paulo }
243f05cddf9SRui Paulo 
244f05cddf9SRui Paulo 
wps_build_application_ext(struct wps_device_data * dev,struct wpabuf * msg)245*c1d255d3SCy Schubert int wps_build_application_ext(struct wps_device_data *dev, struct wpabuf *msg)
246*c1d255d3SCy Schubert {
247*c1d255d3SCy Schubert 	if (!dev->application_ext)
248*c1d255d3SCy Schubert 		return 0;
249*c1d255d3SCy Schubert 
250*c1d255d3SCy Schubert 	wpa_hexdump_buf(MSG_DEBUG, "WPS:  * Application Extension",
251*c1d255d3SCy Schubert 			dev->application_ext);
252*c1d255d3SCy Schubert 	wpabuf_put_be16(msg, ATTR_APPLICATION_EXT);
253*c1d255d3SCy Schubert 	wpabuf_put_be16(msg, wpabuf_len(dev->application_ext));
254*c1d255d3SCy Schubert 	wpabuf_put_buf(msg, dev->application_ext);
255*c1d255d3SCy Schubert 
256*c1d255d3SCy Schubert 	return 0;
257*c1d255d3SCy Schubert }
258*c1d255d3SCy Schubert 
259*c1d255d3SCy Schubert 
wps_process_manufacturer(struct wps_device_data * dev,const u8 * str,size_t str_len)26039beb93cSSam Leffler static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
26139beb93cSSam Leffler 				    size_t str_len)
26239beb93cSSam Leffler {
26339beb93cSSam Leffler 	if (str == NULL) {
26439beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received");
26539beb93cSSam Leffler 		return -1;
26639beb93cSSam Leffler 	}
26739beb93cSSam Leffler 
26839beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
26939beb93cSSam Leffler 
27039beb93cSSam Leffler 	os_free(dev->manufacturer);
2715b9c547cSRui Paulo 	dev->manufacturer = dup_binstr(str, str_len);
27239beb93cSSam Leffler 	if (dev->manufacturer == NULL)
27339beb93cSSam Leffler 		return -1;
27439beb93cSSam Leffler 
27539beb93cSSam Leffler 	return 0;
27639beb93cSSam Leffler }
27739beb93cSSam Leffler 
27839beb93cSSam Leffler 
wps_process_model_name(struct wps_device_data * dev,const u8 * str,size_t str_len)27939beb93cSSam Leffler static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
28039beb93cSSam Leffler 				  size_t str_len)
28139beb93cSSam Leffler {
28239beb93cSSam Leffler 	if (str == NULL) {
28339beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Model Name received");
28439beb93cSSam Leffler 		return -1;
28539beb93cSSam Leffler 	}
28639beb93cSSam Leffler 
28739beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
28839beb93cSSam Leffler 
28939beb93cSSam Leffler 	os_free(dev->model_name);
2905b9c547cSRui Paulo 	dev->model_name = dup_binstr(str, str_len);
29139beb93cSSam Leffler 	if (dev->model_name == NULL)
29239beb93cSSam Leffler 		return -1;
29339beb93cSSam Leffler 
29439beb93cSSam Leffler 	return 0;
29539beb93cSSam Leffler }
29639beb93cSSam Leffler 
29739beb93cSSam Leffler 
wps_process_model_number(struct wps_device_data * dev,const u8 * str,size_t str_len)29839beb93cSSam Leffler static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
29939beb93cSSam Leffler 				    size_t str_len)
30039beb93cSSam Leffler {
30139beb93cSSam Leffler 	if (str == NULL) {
30239beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Model Number received");
30339beb93cSSam Leffler 		return -1;
30439beb93cSSam Leffler 	}
30539beb93cSSam Leffler 
30639beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
30739beb93cSSam Leffler 
30839beb93cSSam Leffler 	os_free(dev->model_number);
3095b9c547cSRui Paulo 	dev->model_number = dup_binstr(str, str_len);
31039beb93cSSam Leffler 	if (dev->model_number == NULL)
31139beb93cSSam Leffler 		return -1;
31239beb93cSSam Leffler 
31339beb93cSSam Leffler 	return 0;
31439beb93cSSam Leffler }
31539beb93cSSam Leffler 
31639beb93cSSam Leffler 
wps_process_serial_number(struct wps_device_data * dev,const u8 * str,size_t str_len)31739beb93cSSam Leffler static int wps_process_serial_number(struct wps_device_data *dev,
31839beb93cSSam Leffler 				     const u8 *str, size_t str_len)
31939beb93cSSam Leffler {
32039beb93cSSam Leffler 	if (str == NULL) {
32139beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Serial Number received");
32239beb93cSSam Leffler 		return -1;
32339beb93cSSam Leffler 	}
32439beb93cSSam Leffler 
32539beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
32639beb93cSSam Leffler 
32739beb93cSSam Leffler 	os_free(dev->serial_number);
3285b9c547cSRui Paulo 	dev->serial_number = dup_binstr(str, str_len);
32939beb93cSSam Leffler 	if (dev->serial_number == NULL)
33039beb93cSSam Leffler 		return -1;
33139beb93cSSam Leffler 
33239beb93cSSam Leffler 	return 0;
33339beb93cSSam Leffler }
33439beb93cSSam Leffler 
33539beb93cSSam Leffler 
wps_process_dev_name(struct wps_device_data * dev,const u8 * str,size_t str_len)33639beb93cSSam Leffler static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
33739beb93cSSam Leffler 				size_t str_len)
33839beb93cSSam Leffler {
33939beb93cSSam Leffler 	if (str == NULL) {
34039beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Device Name received");
34139beb93cSSam Leffler 		return -1;
34239beb93cSSam Leffler 	}
34339beb93cSSam Leffler 
34439beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
34539beb93cSSam Leffler 
34639beb93cSSam Leffler 	os_free(dev->device_name);
3475b9c547cSRui Paulo 	dev->device_name = dup_binstr(str, str_len);
34839beb93cSSam Leffler 	if (dev->device_name == NULL)
34939beb93cSSam Leffler 		return -1;
35039beb93cSSam Leffler 
35139beb93cSSam Leffler 	return 0;
35239beb93cSSam Leffler }
35339beb93cSSam Leffler 
35439beb93cSSam Leffler 
wps_process_primary_dev_type(struct wps_device_data * dev,const u8 * dev_type)35539beb93cSSam Leffler static int wps_process_primary_dev_type(struct wps_device_data *dev,
35639beb93cSSam Leffler 					const u8 *dev_type)
35739beb93cSSam Leffler {
358e28a4053SRui Paulo #ifndef CONFIG_NO_STDOUT_DEBUG
359e28a4053SRui Paulo 	char devtype[WPS_DEV_TYPE_BUFSIZE];
360e28a4053SRui Paulo #endif /* CONFIG_NO_STDOUT_DEBUG */
36139beb93cSSam Leffler 
36239beb93cSSam Leffler 	if (dev_type == NULL) {
36339beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
36439beb93cSSam Leffler 		return -1;
36539beb93cSSam Leffler 	}
36639beb93cSSam Leffler 
367e28a4053SRui Paulo 	os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
368e28a4053SRui Paulo 	wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
369e28a4053SRui Paulo 		   wps_dev_type_bin2str(dev->pri_dev_type, devtype,
370e28a4053SRui Paulo 					sizeof(devtype)));
37139beb93cSSam Leffler 
37239beb93cSSam Leffler 	return 0;
37339beb93cSSam Leffler }
37439beb93cSSam Leffler 
37539beb93cSSam Leffler 
wps_process_device_attrs(struct wps_device_data * dev,struct wps_parse_attr * attr)37639beb93cSSam Leffler int wps_process_device_attrs(struct wps_device_data *dev,
37739beb93cSSam Leffler 			     struct wps_parse_attr *attr)
37839beb93cSSam Leffler {
37939beb93cSSam Leffler 	if (wps_process_manufacturer(dev, attr->manufacturer,
38039beb93cSSam Leffler 				     attr->manufacturer_len) ||
38139beb93cSSam Leffler 	    wps_process_model_name(dev, attr->model_name,
38239beb93cSSam Leffler 				   attr->model_name_len) ||
38339beb93cSSam Leffler 	    wps_process_model_number(dev, attr->model_number,
38439beb93cSSam Leffler 				     attr->model_number_len) ||
38539beb93cSSam Leffler 	    wps_process_serial_number(dev, attr->serial_number,
38639beb93cSSam Leffler 				      attr->serial_number_len) ||
38739beb93cSSam Leffler 	    wps_process_primary_dev_type(dev, attr->primary_dev_type) ||
38839beb93cSSam Leffler 	    wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len))
38939beb93cSSam Leffler 		return -1;
39039beb93cSSam Leffler 	return 0;
39139beb93cSSam Leffler }
39239beb93cSSam Leffler 
39339beb93cSSam Leffler 
wps_process_os_version(struct wps_device_data * dev,const u8 * ver)39439beb93cSSam Leffler int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
39539beb93cSSam Leffler {
39639beb93cSSam Leffler 	if (ver == NULL) {
39739beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No OS Version received");
39839beb93cSSam Leffler 		return -1;
39939beb93cSSam Leffler 	}
40039beb93cSSam Leffler 
40139beb93cSSam Leffler 	dev->os_version = WPA_GET_BE32(ver);
40239beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version);
40339beb93cSSam Leffler 
40439beb93cSSam Leffler 	return 0;
40539beb93cSSam Leffler }
40639beb93cSSam Leffler 
40739beb93cSSam Leffler 
wps_process_vendor_ext_m1(struct wps_device_data * dev,const u8 ext)4084bc52338SCy Schubert void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
4094bc52338SCy Schubert {
4104bc52338SCy Schubert 	dev->multi_ap_ext = ext;
4114bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x",
4124bc52338SCy Schubert 		   dev->multi_ap_ext);
4134bc52338SCy Schubert }
4144bc52338SCy Schubert 
4154bc52338SCy Schubert 
wps_process_rf_bands(struct wps_device_data * dev,const u8 * bands)41639beb93cSSam Leffler int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
41739beb93cSSam Leffler {
41839beb93cSSam Leffler 	if (bands == NULL) {
41939beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No RF Bands received");
42039beb93cSSam Leffler 		return -1;
42139beb93cSSam Leffler 	}
42239beb93cSSam Leffler 
42339beb93cSSam Leffler 	dev->rf_bands = *bands;
42439beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands);
42539beb93cSSam Leffler 
42639beb93cSSam Leffler 	return 0;
42739beb93cSSam Leffler }
42839beb93cSSam Leffler 
42939beb93cSSam Leffler 
wps_device_data_free(struct wps_device_data * dev)43039beb93cSSam Leffler void wps_device_data_free(struct wps_device_data *dev)
43139beb93cSSam Leffler {
43239beb93cSSam Leffler 	os_free(dev->device_name);
43339beb93cSSam Leffler 	dev->device_name = NULL;
43439beb93cSSam Leffler 	os_free(dev->manufacturer);
43539beb93cSSam Leffler 	dev->manufacturer = NULL;
43639beb93cSSam Leffler 	os_free(dev->model_name);
43739beb93cSSam Leffler 	dev->model_name = NULL;
43839beb93cSSam Leffler 	os_free(dev->model_number);
43939beb93cSSam Leffler 	dev->model_number = NULL;
44039beb93cSSam Leffler 	os_free(dev->serial_number);
44139beb93cSSam Leffler 	dev->serial_number = NULL;
442*c1d255d3SCy Schubert 	wpabuf_free(dev->application_ext);
443*c1d255d3SCy Schubert 	dev->application_ext = NULL;
44439beb93cSSam Leffler }
445