139beb93cSSam Leffler /* 239beb93cSSam Leffler * Wi-Fi Protected Setup - device attributes 339beb93cSSam Leffler * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6*f05cddf9SRui 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 16*f05cddf9SRui 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; 22*f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT 2339beb93cSSam Leffler if (len == 0) { 2439beb93cSSam Leffler /* 2539beb93cSSam Leffler * Some deployed WPS implementations fail to parse zero-length 26*f05cddf9SRui 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); 30*f05cddf9SRui Paulo wpabuf_put_u8(msg, ' '); 31*f05cddf9SRui Paulo return 0; 32*f05cddf9SRui Paulo } 33*f05cddf9SRui 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 40*f05cddf9SRui 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; 46*f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT 4739beb93cSSam Leffler if (len == 0) { 4839beb93cSSam Leffler /* 4939beb93cSSam Leffler * Some deployed WPS implementations fail to parse zero-length 50*f05cddf9SRui 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); 54*f05cddf9SRui Paulo wpabuf_put_u8(msg, ' '); 55*f05cddf9SRui Paulo return 0; 56*f05cddf9SRui Paulo } 57*f05cddf9SRui 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 64*f05cddf9SRui 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; 70*f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT 7139beb93cSSam Leffler if (len == 0) { 7239beb93cSSam Leffler /* 7339beb93cSSam Leffler * Some deployed WPS implementations fail to parse zero-length 74*f05cddf9SRui 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); 78*f05cddf9SRui Paulo wpabuf_put_u8(msg, ' '); 79*f05cddf9SRui Paulo return 0; 80*f05cddf9SRui Paulo } 81*f05cddf9SRui 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 8839beb93cSSam Leffler static int wps_build_serial_number(struct wps_device_data *dev, 8939beb93cSSam Leffler struct wpabuf *msg) 9039beb93cSSam Leffler { 9139beb93cSSam Leffler size_t len; 9239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: * Serial Number"); 9339beb93cSSam Leffler wpabuf_put_be16(msg, ATTR_SERIAL_NUMBER); 9439beb93cSSam Leffler len = dev->serial_number ? os_strlen(dev->serial_number) : 0; 95*f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT 9639beb93cSSam Leffler if (len == 0) { 9739beb93cSSam Leffler /* 9839beb93cSSam Leffler * Some deployed WPS implementations fail to parse zero-length 99*f05cddf9SRui Paulo * attributes. As a workaround, send a space character if the 10039beb93cSSam Leffler * device attribute string is empty. 10139beb93cSSam Leffler */ 10239beb93cSSam Leffler wpabuf_put_be16(msg, 1); 103*f05cddf9SRui Paulo wpabuf_put_u8(msg, ' '); 104*f05cddf9SRui Paulo return 0; 105*f05cddf9SRui Paulo } 106*f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */ 10739beb93cSSam Leffler wpabuf_put_be16(msg, len); 10839beb93cSSam Leffler wpabuf_put_data(msg, dev->serial_number, len); 10939beb93cSSam Leffler return 0; 11039beb93cSSam Leffler } 11139beb93cSSam Leffler 11239beb93cSSam Leffler 11339beb93cSSam Leffler int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg) 11439beb93cSSam Leffler { 11539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type"); 11639beb93cSSam Leffler wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE); 117e28a4053SRui Paulo wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN); 118e28a4053SRui Paulo wpabuf_put_data(msg, dev->pri_dev_type, WPS_DEV_TYPE_LEN); 11939beb93cSSam Leffler return 0; 12039beb93cSSam Leffler } 12139beb93cSSam Leffler 12239beb93cSSam Leffler 123*f05cddf9SRui Paulo int wps_build_secondary_dev_type(struct wps_device_data *dev, 124*f05cddf9SRui Paulo struct wpabuf *msg) 125*f05cddf9SRui Paulo { 126*f05cddf9SRui Paulo if (!dev->num_sec_dev_types) 127*f05cddf9SRui Paulo return 0; 128*f05cddf9SRui Paulo 129*f05cddf9SRui Paulo wpa_printf(MSG_DEBUG, "WPS: * Secondary Device Type"); 130*f05cddf9SRui Paulo wpabuf_put_be16(msg, ATTR_SECONDARY_DEV_TYPE_LIST); 131*f05cddf9SRui Paulo wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN * dev->num_sec_dev_types); 132*f05cddf9SRui Paulo wpabuf_put_data(msg, dev->sec_dev_type, 133*f05cddf9SRui Paulo WPS_DEV_TYPE_LEN * dev->num_sec_dev_types); 134*f05cddf9SRui Paulo 135*f05cddf9SRui Paulo return 0; 136*f05cddf9SRui Paulo } 137*f05cddf9SRui Paulo 138*f05cddf9SRui Paulo 139*f05cddf9SRui Paulo int wps_build_req_dev_type(struct wps_device_data *dev, struct wpabuf *msg, 140*f05cddf9SRui Paulo unsigned int num_req_dev_types, 141*f05cddf9SRui Paulo const u8 *req_dev_types) 142*f05cddf9SRui Paulo { 143*f05cddf9SRui Paulo unsigned int i; 144*f05cddf9SRui Paulo 145*f05cddf9SRui Paulo for (i = 0; i < num_req_dev_types; i++) { 146*f05cddf9SRui Paulo wpa_hexdump(MSG_DEBUG, "WPS: * Requested Device Type", 147*f05cddf9SRui Paulo req_dev_types + i * WPS_DEV_TYPE_LEN, 148*f05cddf9SRui Paulo WPS_DEV_TYPE_LEN); 149*f05cddf9SRui Paulo wpabuf_put_be16(msg, ATTR_REQUESTED_DEV_TYPE); 150*f05cddf9SRui Paulo wpabuf_put_be16(msg, WPS_DEV_TYPE_LEN); 151*f05cddf9SRui Paulo wpabuf_put_data(msg, req_dev_types + i * WPS_DEV_TYPE_LEN, 152*f05cddf9SRui Paulo WPS_DEV_TYPE_LEN); 153*f05cddf9SRui Paulo } 154*f05cddf9SRui Paulo 155*f05cddf9SRui Paulo return 0; 156*f05cddf9SRui Paulo } 157*f05cddf9SRui Paulo 158*f05cddf9SRui Paulo 159*f05cddf9SRui Paulo int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg) 16039beb93cSSam Leffler { 16139beb93cSSam Leffler size_t len; 16239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: * Device Name"); 16339beb93cSSam Leffler wpabuf_put_be16(msg, ATTR_DEV_NAME); 16439beb93cSSam Leffler len = dev->device_name ? os_strlen(dev->device_name) : 0; 165*f05cddf9SRui Paulo #ifndef CONFIG_WPS_STRICT 16639beb93cSSam Leffler if (len == 0) { 16739beb93cSSam Leffler /* 16839beb93cSSam Leffler * Some deployed WPS implementations fail to parse zero-length 169*f05cddf9SRui Paulo * attributes. As a workaround, send a space character if the 17039beb93cSSam Leffler * device attribute string is empty. 17139beb93cSSam Leffler */ 17239beb93cSSam Leffler wpabuf_put_be16(msg, 1); 173*f05cddf9SRui Paulo wpabuf_put_u8(msg, ' '); 174*f05cddf9SRui Paulo return 0; 175*f05cddf9SRui Paulo } 176*f05cddf9SRui Paulo #endif /* CONFIG_WPS_STRICT */ 17739beb93cSSam Leffler wpabuf_put_be16(msg, len); 17839beb93cSSam Leffler wpabuf_put_data(msg, dev->device_name, len); 17939beb93cSSam Leffler return 0; 18039beb93cSSam Leffler } 18139beb93cSSam Leffler 18239beb93cSSam Leffler 18339beb93cSSam Leffler int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg) 18439beb93cSSam Leffler { 18539beb93cSSam Leffler if (wps_build_manufacturer(dev, msg) || 18639beb93cSSam Leffler wps_build_model_name(dev, msg) || 18739beb93cSSam Leffler wps_build_model_number(dev, msg) || 18839beb93cSSam Leffler wps_build_serial_number(dev, msg) || 18939beb93cSSam Leffler wps_build_primary_dev_type(dev, msg) || 19039beb93cSSam Leffler wps_build_dev_name(dev, msg)) 19139beb93cSSam Leffler return -1; 19239beb93cSSam Leffler return 0; 19339beb93cSSam Leffler } 19439beb93cSSam Leffler 19539beb93cSSam Leffler 19639beb93cSSam Leffler int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg) 19739beb93cSSam Leffler { 19839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: * OS Version"); 19939beb93cSSam Leffler wpabuf_put_be16(msg, ATTR_OS_VERSION); 20039beb93cSSam Leffler wpabuf_put_be16(msg, 4); 20139beb93cSSam Leffler wpabuf_put_be32(msg, 0x80000000 | dev->os_version); 20239beb93cSSam Leffler return 0; 20339beb93cSSam Leffler } 20439beb93cSSam Leffler 20539beb93cSSam Leffler 206*f05cddf9SRui Paulo int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg) 207*f05cddf9SRui Paulo { 208*f05cddf9SRui Paulo if (dev->vendor_ext_m1 != NULL) { 209*f05cddf9SRui Paulo wpa_hexdump(MSG_DEBUG, "WPS: * Vendor Extension M1", 210*f05cddf9SRui Paulo wpabuf_head_u8(dev->vendor_ext_m1), 211*f05cddf9SRui Paulo wpabuf_len(dev->vendor_ext_m1)); 212*f05cddf9SRui Paulo wpabuf_put_be16(msg, ATTR_VENDOR_EXT); 213*f05cddf9SRui Paulo wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1)); 214*f05cddf9SRui Paulo wpabuf_put_buf(msg, dev->vendor_ext_m1); 215*f05cddf9SRui Paulo } 216*f05cddf9SRui Paulo return 0; 217*f05cddf9SRui Paulo } 218*f05cddf9SRui Paulo 219*f05cddf9SRui Paulo 22039beb93cSSam Leffler int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg) 22139beb93cSSam Leffler { 22239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", dev->rf_bands); 22339beb93cSSam Leffler wpabuf_put_be16(msg, ATTR_RF_BANDS); 22439beb93cSSam Leffler wpabuf_put_be16(msg, 1); 22539beb93cSSam Leffler wpabuf_put_u8(msg, dev->rf_bands); 22639beb93cSSam Leffler return 0; 22739beb93cSSam Leffler } 22839beb93cSSam Leffler 22939beb93cSSam Leffler 230*f05cddf9SRui Paulo int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg) 231*f05cddf9SRui Paulo { 232*f05cddf9SRui Paulo int i; 233*f05cddf9SRui Paulo 234*f05cddf9SRui Paulo for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { 235*f05cddf9SRui Paulo if (dev->vendor_ext[i] == NULL) 236*f05cddf9SRui Paulo continue; 237*f05cddf9SRui Paulo wpa_hexdump(MSG_DEBUG, "WPS: * Vendor Extension", 238*f05cddf9SRui Paulo wpabuf_head_u8(dev->vendor_ext[i]), 239*f05cddf9SRui Paulo wpabuf_len(dev->vendor_ext[i])); 240*f05cddf9SRui Paulo wpabuf_put_be16(msg, ATTR_VENDOR_EXT); 241*f05cddf9SRui Paulo wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext[i])); 242*f05cddf9SRui Paulo wpabuf_put_buf(msg, dev->vendor_ext[i]); 243*f05cddf9SRui Paulo } 244*f05cddf9SRui Paulo 245*f05cddf9SRui Paulo return 0; 246*f05cddf9SRui Paulo } 247*f05cddf9SRui Paulo 248*f05cddf9SRui Paulo 24939beb93cSSam Leffler static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str, 25039beb93cSSam Leffler size_t str_len) 25139beb93cSSam Leffler { 25239beb93cSSam Leffler if (str == NULL) { 25339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Manufacturer received"); 25439beb93cSSam Leffler return -1; 25539beb93cSSam Leffler } 25639beb93cSSam Leffler 25739beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len); 25839beb93cSSam Leffler 25939beb93cSSam Leffler os_free(dev->manufacturer); 26039beb93cSSam Leffler dev->manufacturer = os_malloc(str_len + 1); 26139beb93cSSam Leffler if (dev->manufacturer == NULL) 26239beb93cSSam Leffler return -1; 26339beb93cSSam Leffler os_memcpy(dev->manufacturer, str, str_len); 26439beb93cSSam Leffler dev->manufacturer[str_len] = '\0'; 26539beb93cSSam Leffler 26639beb93cSSam Leffler return 0; 26739beb93cSSam Leffler } 26839beb93cSSam Leffler 26939beb93cSSam Leffler 27039beb93cSSam Leffler static int wps_process_model_name(struct wps_device_data *dev, const u8 *str, 27139beb93cSSam Leffler size_t str_len) 27239beb93cSSam Leffler { 27339beb93cSSam Leffler if (str == NULL) { 27439beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Model Name received"); 27539beb93cSSam Leffler return -1; 27639beb93cSSam Leffler } 27739beb93cSSam Leffler 27839beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len); 27939beb93cSSam Leffler 28039beb93cSSam Leffler os_free(dev->model_name); 28139beb93cSSam Leffler dev->model_name = os_malloc(str_len + 1); 28239beb93cSSam Leffler if (dev->model_name == NULL) 28339beb93cSSam Leffler return -1; 28439beb93cSSam Leffler os_memcpy(dev->model_name, str, str_len); 28539beb93cSSam Leffler dev->model_name[str_len] = '\0'; 28639beb93cSSam Leffler 28739beb93cSSam Leffler return 0; 28839beb93cSSam Leffler } 28939beb93cSSam Leffler 29039beb93cSSam Leffler 29139beb93cSSam Leffler static int wps_process_model_number(struct wps_device_data *dev, const u8 *str, 29239beb93cSSam Leffler size_t str_len) 29339beb93cSSam Leffler { 29439beb93cSSam Leffler if (str == NULL) { 29539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Model Number received"); 29639beb93cSSam Leffler return -1; 29739beb93cSSam Leffler } 29839beb93cSSam Leffler 29939beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len); 30039beb93cSSam Leffler 30139beb93cSSam Leffler os_free(dev->model_number); 30239beb93cSSam Leffler dev->model_number = os_malloc(str_len + 1); 30339beb93cSSam Leffler if (dev->model_number == NULL) 30439beb93cSSam Leffler return -1; 30539beb93cSSam Leffler os_memcpy(dev->model_number, str, str_len); 30639beb93cSSam Leffler dev->model_number[str_len] = '\0'; 30739beb93cSSam Leffler 30839beb93cSSam Leffler return 0; 30939beb93cSSam Leffler } 31039beb93cSSam Leffler 31139beb93cSSam Leffler 31239beb93cSSam Leffler static int wps_process_serial_number(struct wps_device_data *dev, 31339beb93cSSam Leffler const u8 *str, size_t str_len) 31439beb93cSSam Leffler { 31539beb93cSSam Leffler if (str == NULL) { 31639beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Serial Number received"); 31739beb93cSSam Leffler return -1; 31839beb93cSSam Leffler } 31939beb93cSSam Leffler 32039beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len); 32139beb93cSSam Leffler 32239beb93cSSam Leffler os_free(dev->serial_number); 32339beb93cSSam Leffler dev->serial_number = os_malloc(str_len + 1); 32439beb93cSSam Leffler if (dev->serial_number == NULL) 32539beb93cSSam Leffler return -1; 32639beb93cSSam Leffler os_memcpy(dev->serial_number, str, str_len); 32739beb93cSSam Leffler dev->serial_number[str_len] = '\0'; 32839beb93cSSam Leffler 32939beb93cSSam Leffler return 0; 33039beb93cSSam Leffler } 33139beb93cSSam Leffler 33239beb93cSSam Leffler 33339beb93cSSam Leffler static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str, 33439beb93cSSam Leffler size_t str_len) 33539beb93cSSam Leffler { 33639beb93cSSam Leffler if (str == NULL) { 33739beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Device Name received"); 33839beb93cSSam Leffler return -1; 33939beb93cSSam Leffler } 34039beb93cSSam Leffler 34139beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len); 34239beb93cSSam Leffler 34339beb93cSSam Leffler os_free(dev->device_name); 34439beb93cSSam Leffler dev->device_name = os_malloc(str_len + 1); 34539beb93cSSam Leffler if (dev->device_name == NULL) 34639beb93cSSam Leffler return -1; 34739beb93cSSam Leffler os_memcpy(dev->device_name, str, str_len); 34839beb93cSSam Leffler dev->device_name[str_len] = '\0'; 34939beb93cSSam Leffler 35039beb93cSSam Leffler return 0; 35139beb93cSSam Leffler } 35239beb93cSSam Leffler 35339beb93cSSam Leffler 35439beb93cSSam Leffler static int wps_process_primary_dev_type(struct wps_device_data *dev, 35539beb93cSSam Leffler const u8 *dev_type) 35639beb93cSSam Leffler { 357e28a4053SRui Paulo #ifndef CONFIG_NO_STDOUT_DEBUG 358e28a4053SRui Paulo char devtype[WPS_DEV_TYPE_BUFSIZE]; 359e28a4053SRui Paulo #endif /* CONFIG_NO_STDOUT_DEBUG */ 36039beb93cSSam Leffler 36139beb93cSSam Leffler if (dev_type == NULL) { 36239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No Primary Device Type received"); 36339beb93cSSam Leffler return -1; 36439beb93cSSam Leffler } 36539beb93cSSam Leffler 366e28a4053SRui Paulo os_memcpy(dev->pri_dev_type, dev_type, WPS_DEV_TYPE_LEN); 367e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "WPS: Primary Device Type: %s", 368e28a4053SRui Paulo wps_dev_type_bin2str(dev->pri_dev_type, devtype, 369e28a4053SRui Paulo sizeof(devtype))); 37039beb93cSSam Leffler 37139beb93cSSam Leffler return 0; 37239beb93cSSam Leffler } 37339beb93cSSam Leffler 37439beb93cSSam Leffler 37539beb93cSSam Leffler int wps_process_device_attrs(struct wps_device_data *dev, 37639beb93cSSam Leffler struct wps_parse_attr *attr) 37739beb93cSSam Leffler { 37839beb93cSSam Leffler if (wps_process_manufacturer(dev, attr->manufacturer, 37939beb93cSSam Leffler attr->manufacturer_len) || 38039beb93cSSam Leffler wps_process_model_name(dev, attr->model_name, 38139beb93cSSam Leffler attr->model_name_len) || 38239beb93cSSam Leffler wps_process_model_number(dev, attr->model_number, 38339beb93cSSam Leffler attr->model_number_len) || 38439beb93cSSam Leffler wps_process_serial_number(dev, attr->serial_number, 38539beb93cSSam Leffler attr->serial_number_len) || 38639beb93cSSam Leffler wps_process_primary_dev_type(dev, attr->primary_dev_type) || 38739beb93cSSam Leffler wps_process_dev_name(dev, attr->dev_name, attr->dev_name_len)) 38839beb93cSSam Leffler return -1; 38939beb93cSSam Leffler return 0; 39039beb93cSSam Leffler } 39139beb93cSSam Leffler 39239beb93cSSam Leffler 39339beb93cSSam Leffler int wps_process_os_version(struct wps_device_data *dev, const u8 *ver) 39439beb93cSSam Leffler { 39539beb93cSSam Leffler if (ver == NULL) { 39639beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No OS Version received"); 39739beb93cSSam Leffler return -1; 39839beb93cSSam Leffler } 39939beb93cSSam Leffler 40039beb93cSSam Leffler dev->os_version = WPA_GET_BE32(ver); 40139beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: OS Version %08x", dev->os_version); 40239beb93cSSam Leffler 40339beb93cSSam Leffler return 0; 40439beb93cSSam Leffler } 40539beb93cSSam Leffler 40639beb93cSSam Leffler 40739beb93cSSam Leffler int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands) 40839beb93cSSam Leffler { 40939beb93cSSam Leffler if (bands == NULL) { 41039beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: No RF Bands received"); 41139beb93cSSam Leffler return -1; 41239beb93cSSam Leffler } 41339beb93cSSam Leffler 41439beb93cSSam Leffler dev->rf_bands = *bands; 41539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "WPS: Enrollee RF Bands 0x%x", dev->rf_bands); 41639beb93cSSam Leffler 41739beb93cSSam Leffler return 0; 41839beb93cSSam Leffler } 41939beb93cSSam Leffler 42039beb93cSSam Leffler 42139beb93cSSam Leffler void wps_device_data_dup(struct wps_device_data *dst, 42239beb93cSSam Leffler const struct wps_device_data *src) 42339beb93cSSam Leffler { 42439beb93cSSam Leffler if (src->device_name) 42539beb93cSSam Leffler dst->device_name = os_strdup(src->device_name); 42639beb93cSSam Leffler if (src->manufacturer) 42739beb93cSSam Leffler dst->manufacturer = os_strdup(src->manufacturer); 42839beb93cSSam Leffler if (src->model_name) 42939beb93cSSam Leffler dst->model_name = os_strdup(src->model_name); 43039beb93cSSam Leffler if (src->model_number) 43139beb93cSSam Leffler dst->model_number = os_strdup(src->model_number); 43239beb93cSSam Leffler if (src->serial_number) 43339beb93cSSam Leffler dst->serial_number = os_strdup(src->serial_number); 434e28a4053SRui Paulo os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN); 43539beb93cSSam Leffler dst->os_version = src->os_version; 43639beb93cSSam Leffler dst->rf_bands = src->rf_bands; 43739beb93cSSam Leffler } 43839beb93cSSam Leffler 43939beb93cSSam Leffler 44039beb93cSSam Leffler void wps_device_data_free(struct wps_device_data *dev) 44139beb93cSSam Leffler { 44239beb93cSSam Leffler os_free(dev->device_name); 44339beb93cSSam Leffler dev->device_name = NULL; 44439beb93cSSam Leffler os_free(dev->manufacturer); 44539beb93cSSam Leffler dev->manufacturer = NULL; 44639beb93cSSam Leffler os_free(dev->model_name); 44739beb93cSSam Leffler dev->model_name = NULL; 44839beb93cSSam Leffler os_free(dev->model_number); 44939beb93cSSam Leffler dev->model_number = NULL; 45039beb93cSSam Leffler os_free(dev->serial_number); 45139beb93cSSam Leffler dev->serial_number = NULL; 45239beb93cSSam Leffler } 453