xref: /freebsd/contrib/wpa/src/wps/wps_dev_attr.c (revision 5b9c547c072b84410b50897cc53710c75b2f6b74)
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 
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 
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 
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 
88*5b9c547cSRui 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 
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 
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 
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 
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 
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 
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 
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 
219*5b9c547cSRui Paulo int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
220*5b9c547cSRui Paulo 		       u8 rf_band)
22139beb93cSSam Leffler {
222*5b9c547cSRui Paulo 	return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
22339beb93cSSam Leffler }
22439beb93cSSam Leffler 
22539beb93cSSam Leffler 
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 
24539beb93cSSam Leffler static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
24639beb93cSSam Leffler 				    size_t str_len)
24739beb93cSSam Leffler {
24839beb93cSSam Leffler 	if (str == NULL) {
24939beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received");
25039beb93cSSam Leffler 		return -1;
25139beb93cSSam Leffler 	}
25239beb93cSSam Leffler 
25339beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
25439beb93cSSam Leffler 
25539beb93cSSam Leffler 	os_free(dev->manufacturer);
256*5b9c547cSRui Paulo 	dev->manufacturer = dup_binstr(str, str_len);
25739beb93cSSam Leffler 	if (dev->manufacturer == NULL)
25839beb93cSSam Leffler 		return -1;
25939beb93cSSam Leffler 
26039beb93cSSam Leffler 	return 0;
26139beb93cSSam Leffler }
26239beb93cSSam Leffler 
26339beb93cSSam Leffler 
26439beb93cSSam Leffler static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
26539beb93cSSam Leffler 				  size_t str_len)
26639beb93cSSam Leffler {
26739beb93cSSam Leffler 	if (str == NULL) {
26839beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Model Name received");
26939beb93cSSam Leffler 		return -1;
27039beb93cSSam Leffler 	}
27139beb93cSSam Leffler 
27239beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
27339beb93cSSam Leffler 
27439beb93cSSam Leffler 	os_free(dev->model_name);
275*5b9c547cSRui Paulo 	dev->model_name = dup_binstr(str, str_len);
27639beb93cSSam Leffler 	if (dev->model_name == NULL)
27739beb93cSSam Leffler 		return -1;
27839beb93cSSam Leffler 
27939beb93cSSam Leffler 	return 0;
28039beb93cSSam Leffler }
28139beb93cSSam Leffler 
28239beb93cSSam Leffler 
28339beb93cSSam Leffler static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
28439beb93cSSam Leffler 				    size_t str_len)
28539beb93cSSam Leffler {
28639beb93cSSam Leffler 	if (str == NULL) {
28739beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Model Number received");
28839beb93cSSam Leffler 		return -1;
28939beb93cSSam Leffler 	}
29039beb93cSSam Leffler 
29139beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
29239beb93cSSam Leffler 
29339beb93cSSam Leffler 	os_free(dev->model_number);
294*5b9c547cSRui Paulo 	dev->model_number = dup_binstr(str, str_len);
29539beb93cSSam Leffler 	if (dev->model_number == NULL)
29639beb93cSSam Leffler 		return -1;
29739beb93cSSam Leffler 
29839beb93cSSam Leffler 	return 0;
29939beb93cSSam Leffler }
30039beb93cSSam Leffler 
30139beb93cSSam Leffler 
30239beb93cSSam Leffler static int wps_process_serial_number(struct wps_device_data *dev,
30339beb93cSSam Leffler 				     const u8 *str, size_t str_len)
30439beb93cSSam Leffler {
30539beb93cSSam Leffler 	if (str == NULL) {
30639beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Serial Number received");
30739beb93cSSam Leffler 		return -1;
30839beb93cSSam Leffler 	}
30939beb93cSSam Leffler 
31039beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
31139beb93cSSam Leffler 
31239beb93cSSam Leffler 	os_free(dev->serial_number);
313*5b9c547cSRui Paulo 	dev->serial_number = dup_binstr(str, str_len);
31439beb93cSSam Leffler 	if (dev->serial_number == NULL)
31539beb93cSSam Leffler 		return -1;
31639beb93cSSam Leffler 
31739beb93cSSam Leffler 	return 0;
31839beb93cSSam Leffler }
31939beb93cSSam Leffler 
32039beb93cSSam Leffler 
32139beb93cSSam Leffler static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
32239beb93cSSam Leffler 				size_t str_len)
32339beb93cSSam Leffler {
32439beb93cSSam Leffler 	if (str == NULL) {
32539beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Device Name received");
32639beb93cSSam Leffler 		return -1;
32739beb93cSSam Leffler 	}
32839beb93cSSam Leffler 
32939beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
33039beb93cSSam Leffler 
33139beb93cSSam Leffler 	os_free(dev->device_name);
332*5b9c547cSRui Paulo 	dev->device_name = dup_binstr(str, str_len);
33339beb93cSSam Leffler 	if (dev->device_name == NULL)
33439beb93cSSam Leffler 		return -1;
33539beb93cSSam Leffler 
33639beb93cSSam Leffler 	return 0;
33739beb93cSSam Leffler }
33839beb93cSSam Leffler 
33939beb93cSSam Leffler 
34039beb93cSSam Leffler static int wps_process_primary_dev_type(struct wps_device_data *dev,
34139beb93cSSam Leffler 					const u8 *dev_type)
34239beb93cSSam Leffler {
343e28a4053SRui Paulo #ifndef CONFIG_NO_STDOUT_DEBUG
344e28a4053SRui Paulo 	char devtype[WPS_DEV_TYPE_BUFSIZE];
345e28a4053SRui Paulo #endif /* CONFIG_NO_STDOUT_DEBUG */
34639beb93cSSam Leffler 
34739beb93cSSam Leffler 	if (dev_type == NULL) {
34839beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
34939beb93cSSam Leffler 		return -1;
35039beb93cSSam Leffler 	}
35139beb93cSSam Leffler 
352e28a4053SRui Paulo 	os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
353e28a4053SRui Paulo 	wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
354e28a4053SRui Paulo 		   wps_dev_type_bin2str(dev->pri_dev_type, devtype,
355e28a4053SRui Paulo 					sizeof(devtype)));
35639beb93cSSam Leffler 
35739beb93cSSam Leffler 	return 0;
35839beb93cSSam Leffler }
35939beb93cSSam Leffler 
36039beb93cSSam Leffler 
36139beb93cSSam Leffler int wps_process_device_attrs(struct wps_device_data *dev,
36239beb93cSSam Leffler 			     struct wps_parse_attr *attr)
36339beb93cSSam Leffler {
36439beb93cSSam Leffler 	if (wps_process_manufacturer(dev, attr->manufacturer,
36539beb93cSSam Leffler 				     attr->manufacturer_len) ||
36639beb93cSSam Leffler 	    wps_process_model_name(dev, attr->model_name,
36739beb93cSSam Leffler 				   attr->model_name_len) ||
36839beb93cSSam Leffler 	    wps_process_model_number(dev, attr->model_number,
36939beb93cSSam Leffler 				     attr->model_number_len) ||
37039beb93cSSam Leffler 	    wps_process_serial_number(dev, attr->serial_number,
37139beb93cSSam Leffler 				      attr->serial_number_len) ||
37239beb93cSSam Leffler 	    wps_process_primary_dev_type(dev, attr->primary_dev_type) ||
37339beb93cSSam Leffler 	    wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len))
37439beb93cSSam Leffler 		return -1;
37539beb93cSSam Leffler 	return 0;
37639beb93cSSam Leffler }
37739beb93cSSam Leffler 
37839beb93cSSam Leffler 
37939beb93cSSam Leffler int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
38039beb93cSSam Leffler {
38139beb93cSSam Leffler 	if (ver == NULL) {
38239beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No OS Version received");
38339beb93cSSam Leffler 		return -1;
38439beb93cSSam Leffler 	}
38539beb93cSSam Leffler 
38639beb93cSSam Leffler 	dev->os_version = WPA_GET_BE32(ver);
38739beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version);
38839beb93cSSam Leffler 
38939beb93cSSam Leffler 	return 0;
39039beb93cSSam Leffler }
39139beb93cSSam Leffler 
39239beb93cSSam Leffler 
39339beb93cSSam Leffler int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
39439beb93cSSam Leffler {
39539beb93cSSam Leffler 	if (bands == NULL) {
39639beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: No RF Bands received");
39739beb93cSSam Leffler 		return -1;
39839beb93cSSam Leffler 	}
39939beb93cSSam Leffler 
40039beb93cSSam Leffler 	dev->rf_bands = *bands;
40139beb93cSSam Leffler 	wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands);
40239beb93cSSam Leffler 
40339beb93cSSam Leffler 	return 0;
40439beb93cSSam Leffler }
40539beb93cSSam Leffler 
40639beb93cSSam Leffler 
40739beb93cSSam Leffler void wps_device_data_free(struct wps_device_data *dev)
40839beb93cSSam Leffler {
40939beb93cSSam Leffler 	os_free(dev->device_name);
41039beb93cSSam Leffler 	dev->device_name = NULL;
41139beb93cSSam Leffler 	os_free(dev->manufacturer);
41239beb93cSSam Leffler 	dev->manufacturer = NULL;
41339beb93cSSam Leffler 	os_free(dev->model_name);
41439beb93cSSam Leffler 	dev->model_name = NULL;
41539beb93cSSam Leffler 	os_free(dev->model_number);
41639beb93cSSam Leffler 	dev->model_number = NULL;
41739beb93cSSam Leffler 	os_free(dev->serial_number);
41839beb93cSSam Leffler 	dev->serial_number = NULL;
41939beb93cSSam Leffler }
420