xref: /netbsd/external/bsd/wpa/dist/src/wps/wps_dev_attr.c (revision 0d69f216)
18dbcf02cSchristos /*
28dbcf02cSchristos  * Wi-Fi Protected Setup - device attributes
38dbcf02cSchristos  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos  *
562a52023Schristos  * This software may be distributed under the terms of the BSD license.
662a52023Schristos  * See README for more details.
78dbcf02cSchristos  */
88dbcf02cSchristos 
98dbcf02cSchristos #include "includes.h"
108dbcf02cSchristos 
118dbcf02cSchristos #include "common.h"
128dbcf02cSchristos #include "wps_i.h"
138dbcf02cSchristos #include "wps_dev_attr.h"
148dbcf02cSchristos 
158dbcf02cSchristos 
wps_build_manufacturer(struct wps_device_data * dev,struct wpabuf * msg)1642669be3Schristos int wps_build_manufacturer(struct wps_device_data *dev, struct wpabuf *msg)
178dbcf02cSchristos {
188dbcf02cSchristos 	size_t len;
198dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Manufacturer");
208dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_MANUFACTURER);
218dbcf02cSchristos 	len = dev->manufacturer ? os_strlen(dev->manufacturer) : 0;
2242669be3Schristos #ifndef CONFIG_WPS_STRICT
238dbcf02cSchristos 	if (len == 0) {
248dbcf02cSchristos 		/*
258dbcf02cSchristos 		 * Some deployed WPS implementations fail to parse zero-length
2642669be3Schristos 		 * attributes. As a workaround, send a space character if the
278dbcf02cSchristos 		 * device attribute string is empty.
288dbcf02cSchristos 		 */
298dbcf02cSchristos 		wpabuf_put_be16(msg, 1);
3042669be3Schristos 		wpabuf_put_u8(msg, ' ');
3142669be3Schristos 		return 0;
3242669be3Schristos 	}
3342669be3Schristos #endif /* CONFIG_WPS_STRICT */
348dbcf02cSchristos 	wpabuf_put_be16(msg, len);
358dbcf02cSchristos 	wpabuf_put_data(msg, dev->manufacturer, len);
368dbcf02cSchristos 	return 0;
378dbcf02cSchristos }
388dbcf02cSchristos 
398dbcf02cSchristos 
wps_build_model_name(struct wps_device_data * dev,struct wpabuf * msg)4042669be3Schristos int wps_build_model_name(struct wps_device_data *dev, struct wpabuf *msg)
418dbcf02cSchristos {
428dbcf02cSchristos 	size_t len;
438dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Model Name");
448dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_MODEL_NAME);
458dbcf02cSchristos 	len = dev->model_name ? os_strlen(dev->model_name) : 0;
4642669be3Schristos #ifndef CONFIG_WPS_STRICT
478dbcf02cSchristos 	if (len == 0) {
488dbcf02cSchristos 		/*
498dbcf02cSchristos 		 * Some deployed WPS implementations fail to parse zero-length
5042669be3Schristos 		 * attributes. As a workaround, send a space character if the
518dbcf02cSchristos 		 * device attribute string is empty.
528dbcf02cSchristos 		 */
538dbcf02cSchristos 		wpabuf_put_be16(msg, 1);
5442669be3Schristos 		wpabuf_put_u8(msg, ' ');
5542669be3Schristos 		return 0;
5642669be3Schristos 	}
5742669be3Schristos #endif /* CONFIG_WPS_STRICT */
588dbcf02cSchristos 	wpabuf_put_be16(msg, len);
598dbcf02cSchristos 	wpabuf_put_data(msg, dev->model_name, len);
608dbcf02cSchristos 	return 0;
618dbcf02cSchristos }
628dbcf02cSchristos 
638dbcf02cSchristos 
wps_build_model_number(struct wps_device_data * dev,struct wpabuf * msg)6442669be3Schristos int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg)
658dbcf02cSchristos {
668dbcf02cSchristos 	size_t len;
678dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Model Number");
688dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_MODEL_NUMBER);
698dbcf02cSchristos 	len = dev->model_number ? os_strlen(dev->model_number) : 0;
7042669be3Schristos #ifndef CONFIG_WPS_STRICT
718dbcf02cSchristos 	if (len == 0) {
728dbcf02cSchristos 		/*
738dbcf02cSchristos 		 * Some deployed WPS implementations fail to parse zero-length
7442669be3Schristos 		 * attributes. As a workaround, send a space character if the
758dbcf02cSchristos 		 * device attribute string is empty.
768dbcf02cSchristos 		 */
778dbcf02cSchristos 		wpabuf_put_be16(msg, 1);
7842669be3Schristos 		wpabuf_put_u8(msg, ' ');
7942669be3Schristos 		return 0;
8042669be3Schristos 	}
8142669be3Schristos #endif /* CONFIG_WPS_STRICT */
828dbcf02cSchristos 	wpabuf_put_be16(msg, len);
838dbcf02cSchristos 	wpabuf_put_data(msg, dev->model_number, len);
848dbcf02cSchristos 	return 0;
858dbcf02cSchristos }
868dbcf02cSchristos 
878dbcf02cSchristos 
wps_build_serial_number(struct wps_device_data * dev,struct wpabuf * msg)8836d97821Schristos int wps_build_serial_number(struct wps_device_data *dev, struct wpabuf *msg)
898dbcf02cSchristos {
908dbcf02cSchristos 	size_t len;
918dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Serial Number");
928dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_SERIAL_NUMBER);
938dbcf02cSchristos 	len = dev->serial_number ? os_strlen(dev->serial_number) : 0;
9442669be3Schristos #ifndef CONFIG_WPS_STRICT
958dbcf02cSchristos 	if (len == 0) {
968dbcf02cSchristos 		/*
978dbcf02cSchristos 		 * Some deployed WPS implementations fail to parse zero-length
9842669be3Schristos 		 * attributes. As a workaround, send a space character if the
998dbcf02cSchristos 		 * device attribute string is empty.
1008dbcf02cSchristos 		 */
1018dbcf02cSchristos 		wpabuf_put_be16(msg, 1);
10242669be3Schristos 		wpabuf_put_u8(msg, ' ');
10342669be3Schristos 		return 0;
10442669be3Schristos 	}
10542669be3Schristos #endif /* CONFIG_WPS_STRICT */
1068dbcf02cSchristos 	wpabuf_put_be16(msg, len);
1078dbcf02cSchristos 	wpabuf_put_data(msg, dev->serial_number, len);
1088dbcf02cSchristos 	return 0;
1098dbcf02cSchristos }
1108dbcf02cSchristos 
1118dbcf02cSchristos 
wps_build_primary_dev_type(struct wps_device_data * dev,struct wpabuf * msg)1128dbcf02cSchristos int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg)
1138dbcf02cSchristos {
1148dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Primary Device Type");
1158dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE);
1168dbcf02cSchristos 	wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
1178dbcf02cSchristos 	wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN);
1188dbcf02cSchristos 	return 0;
1198dbcf02cSchristos }
1208dbcf02cSchristos 
1218dbcf02cSchristos 
wps_build_secondary_dev_type(struct wps_device_data * dev,struct wpabuf * msg)12242669be3Schristos int wps_build_secondary_dev_type(struct wps_device_data *dev,
12342669be3Schristos 				  struct wpabuf *msg)
12442669be3Schristos {
12542669be3Schristos 	if (!dev->num_sec_dev_types)
12642669be3Schristos 		return 0;
12742669be3Schristos 
12842669be3Schristos 	wpa_printf(MSG_DEBUG, "WPS:  * Secondary Device Type");
12942669be3Schristos 	wpabuf_put_be16(msg, ATTR_SECONDARY_DEV_TYPE_LIST);
13042669be3Schristos 	wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
13142669be3Schristos 	wpabuf_put_data(msg, dev->sec_dev_type,
13242669be3Schristos 			WPS_DEV_TYPE_LEN * dev->num_sec_dev_types);
13342669be3Schristos 
13442669be3Schristos 	return 0;
13542669be3Schristos }
13642669be3Schristos 
13742669be3Schristos 
wps_build_req_dev_type(struct wps_device_data * dev,struct wpabuf * msg,unsigned int num_req_dev_types,const u8 * req_dev_types)13842669be3Schristos int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg,
13942669be3Schristos 			   unsigned int num_req_dev_types,
14042669be3Schristos 			   const u8 *req_dev_types)
14142669be3Schristos {
14242669be3Schristos 	unsigned int i;
14342669be3Schristos 
14442669be3Schristos 	for (i = 0; i < num_req_dev_types; i++) {
14542669be3Schristos 		wpa_hexdump(MSG_DEBUG, "WPS: * Requested Device Type",
14642669be3Schristos 			    req_dev_types + i * WPS_DEV_TYPE_LEN,
14742669be3Schristos 			    WPS_DEV_TYPE_LEN);
14842669be3Schristos 		wpabuf_put_be16(msg, ATTR_REQUESTED_DEV_TYPE);
14942669be3Schristos 		wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN);
15042669be3Schristos 		wpabuf_put_data(msg, req_dev_types + i * WPS_DEV_TYPE_LEN,
15142669be3Schristos 				WPS_DEV_TYPE_LEN);
15242669be3Schristos 	}
15342669be3Schristos 
15442669be3Schristos 	return 0;
15542669be3Schristos }
15642669be3Schristos 
15742669be3Schristos 
wps_build_dev_name(struct wps_device_data * dev,struct wpabuf * msg)15842669be3Schristos int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg)
1598dbcf02cSchristos {
1608dbcf02cSchristos 	size_t len;
1618dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * Device Name");
1628dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_DEV_NAME);
1638dbcf02cSchristos 	len = dev->device_name ? os_strlen(dev->device_name) : 0;
16442669be3Schristos #ifndef CONFIG_WPS_STRICT
1658dbcf02cSchristos 	if (len == 0) {
1668dbcf02cSchristos 		/*
1678dbcf02cSchristos 		 * Some deployed WPS implementations fail to parse zero-length
16842669be3Schristos 		 * attributes. As a workaround, send a space character if the
1698dbcf02cSchristos 		 * device attribute string is empty.
1708dbcf02cSchristos 		 */
1718dbcf02cSchristos 		wpabuf_put_be16(msg, 1);
17242669be3Schristos 		wpabuf_put_u8(msg, ' ');
17342669be3Schristos 		return 0;
17442669be3Schristos 	}
17542669be3Schristos #endif /* CONFIG_WPS_STRICT */
1768dbcf02cSchristos 	wpabuf_put_be16(msg, len);
1778dbcf02cSchristos 	wpabuf_put_data(msg, dev->device_name, len);
1788dbcf02cSchristos 	return 0;
1798dbcf02cSchristos }
1808dbcf02cSchristos 
1818dbcf02cSchristos 
wps_build_device_attrs(struct wps_device_data * dev,struct wpabuf * msg)1828dbcf02cSchristos int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg)
1838dbcf02cSchristos {
1848dbcf02cSchristos 	if (wps_build_manufacturer(dev, msg) ||
1858dbcf02cSchristos 	    wps_build_model_name(dev, msg) ||
1868dbcf02cSchristos 	    wps_build_model_number(dev, msg) ||
1878dbcf02cSchristos 	    wps_build_serial_number(dev, msg) ||
1888dbcf02cSchristos 	    wps_build_primary_dev_type(dev, msg) ||
1898dbcf02cSchristos 	    wps_build_dev_name(dev, msg))
1908dbcf02cSchristos 		return -1;
1918dbcf02cSchristos 	return 0;
1928dbcf02cSchristos }
1938dbcf02cSchristos 
1948dbcf02cSchristos 
wps_build_os_version(struct wps_device_data * dev,struct wpabuf * msg)1958dbcf02cSchristos int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg)
1968dbcf02cSchristos {
1978dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS:  * OS Version");
1988dbcf02cSchristos 	wpabuf_put_be16(msg, ATTR_OS_VERSION);
1998dbcf02cSchristos 	wpabuf_put_be16(msg, 4);
2008dbcf02cSchristos 	wpabuf_put_be32(msg, 0x80000000 | dev->os_version);
2018dbcf02cSchristos 	return 0;
2028dbcf02cSchristos }
2038dbcf02cSchristos 
2048dbcf02cSchristos 
wps_build_vendor_ext_m1(struct wps_device_data * dev,struct wpabuf * msg)20562a52023Schristos int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
20662a52023Schristos {
20762a52023Schristos 	if (dev->vendor_ext_m1 != NULL) {
20862a52023Schristos 		wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension M1",
20962a52023Schristos 			    wpabuf_head_u8(dev->vendor_ext_m1),
21062a52023Schristos 			    wpabuf_len(dev->vendor_ext_m1));
21162a52023Schristos 		wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
21262a52023Schristos 		wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1));
21362a52023Schristos 		wpabuf_put_buf(msg, dev->vendor_ext_m1);
21462a52023Schristos 	}
21562a52023Schristos 	return 0;
21662a52023Schristos }
21762a52023Schristos 
21862a52023Schristos 
wps_build_rf_bands(struct wps_device_data * dev,struct wpabuf * msg,u8 rf_band)21936d97821Schristos int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg,
22036d97821Schristos 		       u8 rf_band)
2218dbcf02cSchristos {
22236d97821Schristos 	return wps_build_rf_bands_attr(msg, rf_band ? rf_band : dev->rf_bands);
2238dbcf02cSchristos }
2248dbcf02cSchristos 
2258dbcf02cSchristos 
wps_build_vendor_ext(struct wps_device_data * dev,struct wpabuf * msg)22642669be3Schristos int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
22742669be3Schristos {
22842669be3Schristos 	int i;
22942669be3Schristos 
23042669be3Schristos 	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
23142669be3Schristos 		if (dev->vendor_ext[i] == NULL)
23242669be3Schristos 			continue;
23342669be3Schristos 		wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension",
23442669be3Schristos 			    wpabuf_head_u8(dev->vendor_ext[i]),
23542669be3Schristos 			    wpabuf_len(dev->vendor_ext[i]));
23642669be3Schristos 		wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
23742669be3Schristos 		wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext[i]));
23842669be3Schristos 		wpabuf_put_buf(msg, dev->vendor_ext[i]);
23942669be3Schristos 	}
24042669be3Schristos 
24142669be3Schristos 	return 0;
24242669be3Schristos }
24342669be3Schristos 
24442669be3Schristos 
wps_process_manufacturer(struct wps_device_data * dev,const u8 * str,size_t str_len)2458dbcf02cSchristos static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
2468dbcf02cSchristos 				    size_t str_len)
2478dbcf02cSchristos {
2488dbcf02cSchristos 	if (str == NULL) {
2498dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received");
2508dbcf02cSchristos 		return -1;
2518dbcf02cSchristos 	}
2528dbcf02cSchristos 
2538dbcf02cSchristos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
2548dbcf02cSchristos 
2558dbcf02cSchristos 	os_free(dev->manufacturer);
25636d97821Schristos 	dev->manufacturer = dup_binstr(str, str_len);
2578dbcf02cSchristos 	if (dev->manufacturer == NULL)
2588dbcf02cSchristos 		return -1;
2598dbcf02cSchristos 
2608dbcf02cSchristos 	return 0;
2618dbcf02cSchristos }
2628dbcf02cSchristos 
2638dbcf02cSchristos 
wps_process_model_name(struct wps_device_data * dev,const u8 * str,size_t str_len)2648dbcf02cSchristos static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
2658dbcf02cSchristos 				  size_t str_len)
2668dbcf02cSchristos {
2678dbcf02cSchristos 	if (str == NULL) {
2688dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Model Name received");
2698dbcf02cSchristos 		return -1;
2708dbcf02cSchristos 	}
2718dbcf02cSchristos 
2728dbcf02cSchristos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
2738dbcf02cSchristos 
2748dbcf02cSchristos 	os_free(dev->model_name);
27536d97821Schristos 	dev->model_name = dup_binstr(str, str_len);
2768dbcf02cSchristos 	if (dev->model_name == NULL)
2778dbcf02cSchristos 		return -1;
2788dbcf02cSchristos 
2798dbcf02cSchristos 	return 0;
2808dbcf02cSchristos }
2818dbcf02cSchristos 
2828dbcf02cSchristos 
wps_process_model_number(struct wps_device_data * dev,const u8 * str,size_t str_len)2838dbcf02cSchristos static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
2848dbcf02cSchristos 				    size_t str_len)
2858dbcf02cSchristos {
2868dbcf02cSchristos 	if (str == NULL) {
2878dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Model Number received");
2888dbcf02cSchristos 		return -1;
2898dbcf02cSchristos 	}
2908dbcf02cSchristos 
2918dbcf02cSchristos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
2928dbcf02cSchristos 
2938dbcf02cSchristos 	os_free(dev->model_number);
29436d97821Schristos 	dev->model_number = dup_binstr(str, str_len);
2958dbcf02cSchristos 	if (dev->model_number == NULL)
2968dbcf02cSchristos 		return -1;
2978dbcf02cSchristos 
2988dbcf02cSchristos 	return 0;
2998dbcf02cSchristos }
3008dbcf02cSchristos 
3018dbcf02cSchristos 
wps_process_serial_number(struct wps_device_data * dev,const u8 * str,size_t str_len)3028dbcf02cSchristos static int wps_process_serial_number(struct wps_device_data *dev,
3038dbcf02cSchristos 				     const u8 *str, size_t str_len)
3048dbcf02cSchristos {
3058dbcf02cSchristos 	if (str == NULL) {
3068dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Serial Number received");
3078dbcf02cSchristos 		return -1;
3088dbcf02cSchristos 	}
3098dbcf02cSchristos 
3108dbcf02cSchristos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
3118dbcf02cSchristos 
3128dbcf02cSchristos 	os_free(dev->serial_number);
31336d97821Schristos 	dev->serial_number = dup_binstr(str, str_len);
3148dbcf02cSchristos 	if (dev->serial_number == NULL)
3158dbcf02cSchristos 		return -1;
3168dbcf02cSchristos 
3178dbcf02cSchristos 	return 0;
3188dbcf02cSchristos }
3198dbcf02cSchristos 
3208dbcf02cSchristos 
wps_process_dev_name(struct wps_device_data * dev,const u8 * str,size_t str_len)3218dbcf02cSchristos static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
3228dbcf02cSchristos 				size_t str_len)
3238dbcf02cSchristos {
3248dbcf02cSchristos 	if (str == NULL) {
3258dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Device Name received");
3268dbcf02cSchristos 		return -1;
3278dbcf02cSchristos 	}
3288dbcf02cSchristos 
3298dbcf02cSchristos 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
3308dbcf02cSchristos 
3318dbcf02cSchristos 	os_free(dev->device_name);
33236d97821Schristos 	dev->device_name = dup_binstr(str, str_len);
3338dbcf02cSchristos 	if (dev->device_name == NULL)
3348dbcf02cSchristos 		return -1;
3358dbcf02cSchristos 
3368dbcf02cSchristos 	return 0;
3378dbcf02cSchristos }
3388dbcf02cSchristos 
3398dbcf02cSchristos 
wps_process_primary_dev_type(struct wps_device_data * dev,const u8 * dev_type)3408dbcf02cSchristos static int wps_process_primary_dev_type(struct wps_device_data *dev,
3418dbcf02cSchristos 					const u8 *dev_type)
3428dbcf02cSchristos {
3438dbcf02cSchristos #ifndef CONFIG_NO_STDOUT_DEBUG
3448dbcf02cSchristos 	char devtype[WPS_DEV_TYPE_BUFSIZE];
3458dbcf02cSchristos #endif /* CONFIG_NO_STDOUT_DEBUG */
3468dbcf02cSchristos 
3478dbcf02cSchristos 	if (dev_type == NULL) {
3488dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received");
3498dbcf02cSchristos 		return -1;
3508dbcf02cSchristos 	}
3518dbcf02cSchristos 
3528dbcf02cSchristos 	os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN);
3538dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s",
3548dbcf02cSchristos 		   wps_dev_type_bin2str(dev->pri_dev_type, devtype,
3558dbcf02cSchristos 					sizeof(devtype)));
3568dbcf02cSchristos 
3578dbcf02cSchristos 	return 0;
3588dbcf02cSchristos }
3598dbcf02cSchristos 
3608dbcf02cSchristos 
wps_process_device_attrs(struct wps_device_data * dev,struct wps_parse_attr * attr)3618dbcf02cSchristos int wps_process_device_attrs(struct wps_device_data *dev,
3628dbcf02cSchristos 			     struct wps_parse_attr *attr)
3638dbcf02cSchristos {
3648dbcf02cSchristos 	if (wps_process_manufacturer(dev, attr->manufacturer,
3658dbcf02cSchristos 				     attr->manufacturer_len) ||
3668dbcf02cSchristos 	    wps_process_model_name(dev, attr->model_name,
3678dbcf02cSchristos 				   attr->model_name_len) ||
3688dbcf02cSchristos 	    wps_process_model_number(dev, attr->model_number,
3698dbcf02cSchristos 				     attr->model_number_len) ||
3708dbcf02cSchristos 	    wps_process_serial_number(dev, attr->serial_number,
3718dbcf02cSchristos 				      attr->serial_number_len) ||
3728dbcf02cSchristos 	    wps_process_primary_dev_type(dev, attr->primary_dev_type) ||
3738dbcf02cSchristos 	    wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len))
3748dbcf02cSchristos 		return -1;
3758dbcf02cSchristos 	return 0;
3768dbcf02cSchristos }
3778dbcf02cSchristos 
3788dbcf02cSchristos 
wps_process_os_version(struct wps_device_data * dev,const u8 * ver)3798dbcf02cSchristos int wps_process_os_version(struct wps_device_data *dev, const u8 *ver)
3808dbcf02cSchristos {
3818dbcf02cSchristos 	if (ver == NULL) {
3828dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No OS Version received");
3838dbcf02cSchristos 		return -1;
3848dbcf02cSchristos 	}
3858dbcf02cSchristos 
3868dbcf02cSchristos 	dev->os_version = WPA_GET_BE32(ver);
3878dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version);
3888dbcf02cSchristos 
3898dbcf02cSchristos 	return 0;
3908dbcf02cSchristos }
3918dbcf02cSchristos 
3928dbcf02cSchristos 
wps_process_vendor_ext_m1(struct wps_device_data * dev,const u8 ext)393*0d69f216Schristos void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
394*0d69f216Schristos {
395*0d69f216Schristos 	dev->multi_ap_ext = ext;
396*0d69f216Schristos 	wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x",
397*0d69f216Schristos 		   dev->multi_ap_ext);
398*0d69f216Schristos }
399*0d69f216Schristos 
400*0d69f216Schristos 
wps_process_rf_bands(struct wps_device_data * dev,const u8 * bands)4018dbcf02cSchristos int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
4028dbcf02cSchristos {
4038dbcf02cSchristos 	if (bands == NULL) {
4048dbcf02cSchristos 		wpa_printf(MSG_DEBUG, "WPS: No RF Bands received");
4058dbcf02cSchristos 		return -1;
4068dbcf02cSchristos 	}
4078dbcf02cSchristos 
4088dbcf02cSchristos 	dev->rf_bands = *bands;
4098dbcf02cSchristos 	wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands);
4108dbcf02cSchristos 
4118dbcf02cSchristos 	return 0;
4128dbcf02cSchristos }
4138dbcf02cSchristos 
4148dbcf02cSchristos 
wps_device_data_free(struct wps_device_data * dev)4158dbcf02cSchristos void wps_device_data_free(struct wps_device_data *dev)
4168dbcf02cSchristos {
4178dbcf02cSchristos 	os_free(dev->device_name);
4188dbcf02cSchristos 	dev->device_name = NULL;
4198dbcf02cSchristos 	os_free(dev->manufacturer);
4208dbcf02cSchristos 	dev->manufacturer = NULL;
4218dbcf02cSchristos 	os_free(dev->model_name);
4228dbcf02cSchristos 	dev->model_name = NULL;
4238dbcf02cSchristos 	os_free(dev->model_number);
4248dbcf02cSchristos 	dev->model_number = NULL;
4258dbcf02cSchristos 	os_free(dev->serial_number);
4268dbcf02cSchristos 	dev->serial_number = NULL;
4278dbcf02cSchristos }
428