2 * Wi-Fi Protected Setup - device attributes
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #include "wps_dev_attr.h"
16 int wps_build_manufacturer(struct wps_device_data
*dev
, struct wpabuf
*msg
)
19 wpa_printf(MSG_DEBUG
, "WPS: * Manufacturer");
20 wpabuf_put_be16(msg
, ATTR_MANUFACTURER
);
21 len
= dev
->manufacturer
? os_strlen(dev
->manufacturer
) : 0;
22 #ifndef CONFIG_WPS_STRICT
25 * Some deployed WPS implementations fail to parse zero-length
26 * attributes. As a workaround, send a space character if the
27 * device attribute string is empty.
29 wpabuf_put_be16(msg
, 1);
30 wpabuf_put_u8(msg
, ' ');
33 #endif /* CONFIG_WPS_STRICT */
34 wpabuf_put_be16(msg
, len
);
35 wpabuf_put_data(msg
, dev
->manufacturer
, len
);
40 int wps_build_model_name(struct wps_device_data
*dev
, struct wpabuf
*msg
)
43 wpa_printf(MSG_DEBUG
, "WPS: * Model Name");
44 wpabuf_put_be16(msg
, ATTR_MODEL_NAME
);
45 len
= dev
->model_name
? os_strlen(dev
->model_name
) : 0;
46 #ifndef CONFIG_WPS_STRICT
49 * Some deployed WPS implementations fail to parse zero-length
50 * attributes. As a workaround, send a space character if the
51 * device attribute string is empty.
53 wpabuf_put_be16(msg
, 1);
54 wpabuf_put_u8(msg
, ' ');
57 #endif /* CONFIG_WPS_STRICT */
58 wpabuf_put_be16(msg
, len
);
59 wpabuf_put_data(msg
, dev
->model_name
, len
);
64 int wps_build_model_number(struct wps_device_data
*dev
, struct wpabuf
*msg
)
67 wpa_printf(MSG_DEBUG
, "WPS: * Model Number");
68 wpabuf_put_be16(msg
, ATTR_MODEL_NUMBER
);
69 len
= dev
->model_number
? os_strlen(dev
->model_number
) : 0;
70 #ifndef CONFIG_WPS_STRICT
73 * Some deployed WPS implementations fail to parse zero-length
74 * attributes. As a workaround, send a space character if the
75 * device attribute string is empty.
77 wpabuf_put_be16(msg
, 1);
78 wpabuf_put_u8(msg
, ' ');
81 #endif /* CONFIG_WPS_STRICT */
82 wpabuf_put_be16(msg
, len
);
83 wpabuf_put_data(msg
, dev
->model_number
, len
);
88 int wps_build_serial_number(struct wps_device_data
*dev
, struct wpabuf
*msg
)
91 wpa_printf(MSG_DEBUG
, "WPS: * Serial Number");
92 wpabuf_put_be16(msg
, ATTR_SERIAL_NUMBER
);
93 len
= dev
->serial_number
? os_strlen(dev
->serial_number
) : 0;
94 #ifndef CONFIG_WPS_STRICT
97 * Some deployed WPS implementations fail to parse zero-length
98 * attributes. As a workaround, send a space character if the
99 * device attribute string is empty.
101 wpabuf_put_be16(msg
, 1);
102 wpabuf_put_u8(msg
, ' ');
105 #endif /* CONFIG_WPS_STRICT */
106 wpabuf_put_be16(msg
, len
);
107 wpabuf_put_data(msg
, dev
->serial_number
, len
);
112 int wps_build_primary_dev_type(struct wps_device_data
*dev
, struct wpabuf
*msg
)
114 wpa_printf(MSG_DEBUG
, "WPS: * Primary Device Type");
115 wpabuf_put_be16(msg
, ATTR_PRIMARY_DEV_TYPE
);
116 wpabuf_put_be16(msg
, WPS_DEV_TYPE_LEN
);
117 wpabuf_put_data(msg
, dev
->pri_dev_type
, WPS_DEV_TYPE_LEN
);
122 int wps_build_secondary_dev_type(struct wps_device_data
*dev
,
125 if (!dev
->num_sec_dev_types
)
128 wpa_printf(MSG_DEBUG
, "WPS: * Secondary Device Type");
129 wpabuf_put_be16(msg
, ATTR_SECONDARY_DEV_TYPE_LIST
);
130 wpabuf_put_be16(msg
, WPS_DEV_TYPE_LEN
* dev
->num_sec_dev_types
);
131 wpabuf_put_data(msg
, dev
->sec_dev_type
,
132 WPS_DEV_TYPE_LEN
* dev
->num_sec_dev_types
);
138 int wps_build_req_dev_type(struct wps_device_data
*dev
, struct wpabuf
*msg
,
139 unsigned int num_req_dev_types
,
140 const u8
*req_dev_types
)
144 for (i
= 0; i
< num_req_dev_types
; i
++) {
145 wpa_hexdump(MSG_DEBUG
, "WPS: * Requested Device Type",
146 req_dev_types
+ i
* WPS_DEV_TYPE_LEN
,
148 wpabuf_put_be16(msg
, ATTR_REQUESTED_DEV_TYPE
);
149 wpabuf_put_be16(msg
, WPS_DEV_TYPE_LEN
);
150 wpabuf_put_data(msg
, req_dev_types
+ i
* WPS_DEV_TYPE_LEN
,
158 int wps_build_dev_name(struct wps_device_data
*dev
, struct wpabuf
*msg
)
161 wpa_printf(MSG_DEBUG
, "WPS: * Device Name");
162 wpabuf_put_be16(msg
, ATTR_DEV_NAME
);
163 len
= dev
->device_name
? os_strlen(dev
->device_name
) : 0;
164 #ifndef CONFIG_WPS_STRICT
167 * Some deployed WPS implementations fail to parse zero-length
168 * attributes. As a workaround, send a space character if the
169 * device attribute string is empty.
171 wpabuf_put_be16(msg
, 1);
172 wpabuf_put_u8(msg
, ' ');
175 #endif /* CONFIG_WPS_STRICT */
176 wpabuf_put_be16(msg
, len
);
177 wpabuf_put_data(msg
, dev
->device_name
, len
);
182 int wps_build_device_attrs(struct wps_device_data
*dev
, struct wpabuf
*msg
)
184 if (wps_build_manufacturer(dev
, msg
) ||
185 wps_build_model_name(dev
, msg
) ||
186 wps_build_model_number(dev
, msg
) ||
187 wps_build_serial_number(dev
, msg
) ||
188 wps_build_primary_dev_type(dev
, msg
) ||
189 wps_build_dev_name(dev
, msg
))
195 int wps_build_os_version(struct wps_device_data
*dev
, struct wpabuf
*msg
)
197 wpa_printf(MSG_DEBUG
, "WPS: * OS Version");
198 wpabuf_put_be16(msg
, ATTR_OS_VERSION
);
199 wpabuf_put_be16(msg
, 4);
200 wpabuf_put_be32(msg
, 0x80000000 | dev
->os_version
);
205 int wps_build_vendor_ext_m1(struct wps_device_data
*dev
, struct wpabuf
*msg
)
207 if (dev
->vendor_ext_m1
!= NULL
) {
208 wpa_hexdump(MSG_DEBUG
, "WPS: * Vendor Extension M1",
209 wpabuf_head_u8(dev
->vendor_ext_m1
),
210 wpabuf_len(dev
->vendor_ext_m1
));
211 wpabuf_put_be16(msg
, ATTR_VENDOR_EXT
);
212 wpabuf_put_be16(msg
, wpabuf_len(dev
->vendor_ext_m1
));
213 wpabuf_put_buf(msg
, dev
->vendor_ext_m1
);
219 int wps_build_rf_bands(struct wps_device_data
*dev
, struct wpabuf
*msg
,
222 return wps_build_rf_bands_attr(msg
, rf_band
? rf_band
: dev
->rf_bands
);
226 int wps_build_vendor_ext(struct wps_device_data
*dev
, struct wpabuf
*msg
)
230 for (i
= 0; i
< MAX_WPS_VENDOR_EXTENSIONS
; i
++) {
231 if (dev
->vendor_ext
[i
] == NULL
)
233 wpa_hexdump(MSG_DEBUG
, "WPS: * Vendor Extension",
234 wpabuf_head_u8(dev
->vendor_ext
[i
]),
235 wpabuf_len(dev
->vendor_ext
[i
]));
236 wpabuf_put_be16(msg
, ATTR_VENDOR_EXT
);
237 wpabuf_put_be16(msg
, wpabuf_len(dev
->vendor_ext
[i
]));
238 wpabuf_put_buf(msg
, dev
->vendor_ext
[i
]);
245 static int wps_process_manufacturer(struct wps_device_data
*dev
, const u8
*str
,
249 wpa_printf(MSG_DEBUG
, "WPS: No Manufacturer received");
253 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Manufacturer", str
, str_len
);
255 os_free(dev
->manufacturer
);
256 dev
->manufacturer
= dup_binstr(str
, str_len
);
257 if (dev
->manufacturer
== NULL
)
264 static int wps_process_model_name(struct wps_device_data
*dev
, const u8
*str
,
268 wpa_printf(MSG_DEBUG
, "WPS: No Model Name received");
272 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Name", str
, str_len
);
274 os_free(dev
->model_name
);
275 dev
->model_name
= dup_binstr(str
, str_len
);
276 if (dev
->model_name
== NULL
)
283 static int wps_process_model_number(struct wps_device_data
*dev
, const u8
*str
,
287 wpa_printf(MSG_DEBUG
, "WPS: No Model Number received");
291 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Number", str
, str_len
);
293 os_free(dev
->model_number
);
294 dev
->model_number
= dup_binstr(str
, str_len
);
295 if (dev
->model_number
== NULL
)
302 static int wps_process_serial_number(struct wps_device_data
*dev
,
303 const u8
*str
, size_t str_len
)
306 wpa_printf(MSG_DEBUG
, "WPS: No Serial Number received");
310 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Serial Number", str
, str_len
);
312 os_free(dev
->serial_number
);
313 dev
->serial_number
= dup_binstr(str
, str_len
);
314 if (dev
->serial_number
== NULL
)
321 static int wps_process_dev_name(struct wps_device_data
*dev
, const u8
*str
,
325 wpa_printf(MSG_DEBUG
, "WPS: No Device Name received");
329 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Device Name", str
, str_len
);
331 os_free(dev
->device_name
);
332 dev
->device_name
= dup_binstr(str
, str_len
);
333 if (dev
->device_name
== NULL
)
340 static int wps_process_primary_dev_type(struct wps_device_data
*dev
,
343 #ifndef CONFIG_NO_STDOUT_DEBUG
344 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
345 #endif /* CONFIG_NO_STDOUT_DEBUG */
347 if (dev_type
== NULL
) {
348 wpa_printf(MSG_DEBUG
, "WPS: No Primary Device Type received");
352 os_memcpy(dev
->pri_dev_type
, dev_type
, WPS_DEV_TYPE_LEN
);
353 wpa_printf(MSG_DEBUG
, "WPS: Primary Device Type: %s",
354 wps_dev_type_bin2str(dev
->pri_dev_type
, devtype
,
361 int wps_process_device_attrs(struct wps_device_data
*dev
,
362 struct wps_parse_attr
*attr
)
364 if (wps_process_manufacturer(dev
, attr
->manufacturer
,
365 attr
->manufacturer_len
) ||
366 wps_process_model_name(dev
, attr
->model_name
,
367 attr
->model_name_len
) ||
368 wps_process_model_number(dev
, attr
->model_number
,
369 attr
->model_number_len
) ||
370 wps_process_serial_number(dev
, attr
->serial_number
,
371 attr
->serial_number_len
) ||
372 wps_process_primary_dev_type(dev
, attr
->primary_dev_type
) ||
373 wps_process_dev_name(dev
, attr
->dev_name
, attr
->dev_name_len
))
379 int wps_process_os_version(struct wps_device_data
*dev
, const u8
*ver
)
382 wpa_printf(MSG_DEBUG
, "WPS: No OS Version received");
386 dev
->os_version
= WPA_GET_BE32(ver
);
387 wpa_printf(MSG_DEBUG
, "WPS: OS Version %08x", dev
->os_version
);
393 void wps_process_vendor_ext_m1(struct wps_device_data
*dev
, const u8 ext
)
395 dev
->multi_ap_ext
= ext
;
396 wpa_printf(MSG_DEBUG
, "WPS: Multi-AP extension value %02x",
401 int wps_process_rf_bands(struct wps_device_data
*dev
, const u8
*bands
)
404 wpa_printf(MSG_DEBUG
, "WPS: No RF Bands received");
408 dev
->rf_bands
= *bands
;
409 wpa_printf(MSG_DEBUG
, "WPS: Enrollee RF Bands 0x%x", dev
->rf_bands
);
415 void wps_device_data_free(struct wps_device_data
*dev
)
417 os_free(dev
->device_name
);
418 dev
->device_name
= NULL
;
419 os_free(dev
->manufacturer
);
420 dev
->manufacturer
= NULL
;
421 os_free(dev
->model_name
);
422 dev
->model_name
= NULL
;
423 os_free(dev
->model_number
);
424 dev
->model_number
= NULL
;
425 os_free(dev
->serial_number
);
426 dev
->serial_number
= NULL
;