WPS: Store (secondary) device type as binary
authorJohannes Berg <johannes.berg@intel.com>
Thu, 17 Mar 2011 16:50:22 +0000 (18:50 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 17 Mar 2011 16:50:22 +0000 (18:50 +0200)
Instead of converting back and forth from the string representation,
always use the binary representation internally.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
hostapd/config_file.c
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/wps_hostapd.c
wpa_supplicant/ap.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/config_winreg.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/wps_supplicant.c

index e892059..4b8b16a 100644 (file)
@@ -1966,8 +1966,8 @@ struct hostapd_config * hostapd_config_read(const char *fname)
                        os_free(bss->serial_number);
                        bss->serial_number = os_strdup(pos);
                } else if (os_strcmp(buf, "device_type") == 0) {
-                       os_free(bss->device_type);
-                       bss->device_type = os_strdup(pos);
+                       if (wps_dev_type_str2bin(pos, bss->device_type))
+                               errors++;
                } else if (os_strcmp(buf, "config_methods") == 0) {
                        os_free(bss->config_methods);
                        bss->config_methods = os_strdup(pos);
index 3fd8276..e77716b 100644 (file)
@@ -456,7 +456,6 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
        os_free(conf->model_name);
        os_free(conf->model_number);
        os_free(conf->serial_number);
-       os_free(conf->device_type);
        os_free(conf->config_methods);
        os_free(conf->ap_pin);
        os_free(conf->extra_cred);
index 0016a7c..fbe8734 100644 (file)
@@ -18,6 +18,7 @@
 #include "common/defs.h"
 #include "ip_addr.h"
 #include "common/wpa_common.h"
+#include "wps/wps.h"
 
 #define MAX_STA_COUNT 2007
 #define MAX_VLAN_ID 4094
@@ -299,7 +300,7 @@ struct hostapd_bss_config {
        char *model_name;
        char *model_number;
        char *serial_number;
-       char *device_type;
+       u8 device_type[WPS_DEV_TYPE_LEN];
        char *config_methods;
        u8 os_version[4];
        char *ap_pin;
index d5042c0..92a6dd4 100644 (file)
@@ -728,13 +728,9 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
        }
 #endif /* CONFIG_WPS2 */
-       if (hapd->conf->device_type &&
-           wps_dev_type_str2bin(hapd->conf->device_type,
-                                wps->dev.pri_dev_type) < 0) {
-               wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
-               os_free(wps);
-               return -1;
-       }
+       os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
+                 WPS_DEV_TYPE_LEN);
+
        wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
        wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
                WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */
index 77e5b78..fb7a10f 100644 (file)
@@ -169,8 +169,8 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
        bss->ap_setup_locked = 2;
        if (wpa_s->conf->config_methods)
                bss->config_methods = os_strdup(wpa_s->conf->config_methods);
-       if (wpa_s->conf->device_type)
-               bss->device_type = os_strdup(wpa_s->conf->device_type);
+       os_memcpy(bss->device_type, wpa_s->conf->device_type,
+                 WPS_DEV_TYPE_LEN);
        if (wpa_s->conf->device_name) {
                bss->device_name = os_strdup(wpa_s->conf->device_name);
                bss->friendly_name = os_strdup(wpa_s->conf->device_name);
index d732f54..de68ec8 100644 (file)
@@ -1694,7 +1694,6 @@ void wpa_config_free(struct wpa_config *config)
        struct wpa_config_blob *blob, *prevblob;
 #endif /* CONFIG_NO_CONFIG_BLOBS */
        struct wpa_ssid *ssid, *prev = NULL;
-       int i;
 
        ssid = config->ssid;
        while (ssid) {
@@ -1724,9 +1723,6 @@ void wpa_config_free(struct wpa_config *config)
        os_free(config->model_name);
        os_free(config->model_number);
        os_free(config->serial_number);
-       os_free(config->device_type);
-       for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++)
-               os_free(config->sec_device_type[i]);
        os_free(config->config_methods);
        os_free(config->p2p_ssid_postfix);
        os_free(config->pssid);
@@ -2311,6 +2307,14 @@ static int wpa_config_process_uuid(const struct global_parse_data *data,
 }
 
 
+static int wpa_config_process_device_type(
+       const struct global_parse_data *data,
+       struct wpa_config *config, int line, const char *pos)
+{
+       return wps_dev_type_str2bin(pos, config->device_type);
+}
+
+
 static int wpa_config_process_os_version(const struct global_parse_data *data,
                                         struct wpa_config *config, int line,
                                         const char *pos)
@@ -2333,18 +2337,18 @@ static int wpa_config_process_sec_device_type(
 {
        int idx;
 
-       for (idx = 0; idx < MAX_SEC_DEVICE_TYPES; idx++)
-               if (config->sec_device_type[idx] == NULL)
-                       break;
-       if (idx == MAX_SEC_DEVICE_TYPES) {
+       if (config->num_sec_device_types >= MAX_SEC_DEVICE_TYPES) {
                wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type "
                           "items", line);
                return -1;
        }
 
-       config->sec_device_type[idx] = os_strdup(pos);
-       if (config->sec_device_type[idx] == NULL)
+       idx = config->num_sec_device_types;
+
+       if (wps_dev_type_str2bin(pos, config->sec_device_type[idx]))
                return -1;
+
+       config->num_sec_device_types++;
        return 0;
 }
 #endif /* CONFIG_P2P */
@@ -2391,7 +2395,7 @@ static const struct global_parse_data global_fields[] = {
        { STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING },
        { STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING },
        { STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING },
-       { STR(device_type), CFG_CHANGED_DEVICE_TYPE },
+       { FUNC(device_type), CFG_CHANGED_DEVICE_TYPE },
        { FUNC(os_version), CFG_CHANGED_OS_VERSION },
        { STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
        { INT_RANGE(wps_cred_processing, 0, 2), 0 },
index c0ac41f..cf22ec4 100644 (file)
@@ -28,6 +28,7 @@
 #define DEFAULT_MAX_NUM_STA 128
 
 #include "config_ssid.h"
+#include "wps/wps.h"
 
 
 #define CFG_CHANGED_DEVICE_NAME BIT(0)
@@ -299,18 +300,8 @@ struct wpa_config {
 
        /**
         * device_type - Primary Device Type (WPS)
-        * Used format: categ-OUI-subcateg
-        * categ = Category as an integer value
-        * OUI = OUI and type octet as a 4-octet hex-encoded value;
-        *      0050F204 for default WPS OUI
-        * subcateg = OUI-specific Sub Category as an integer value
-        * Examples:
-        *   1-0050F204-1 (Computer / PC)
-        *   1-0050F204-2 (Computer / Server)
-        *   5-0050F204-1 (Storage / NAS)
-        *   6-0050F204-1 (Network Infrastructure / AP)
         */
-       char *device_type;
+       u8 device_type[WPS_DEV_TYPE_LEN];
 
        /**
         * config_methods - Config Methods
@@ -352,10 +343,10 @@ struct wpa_config {
 
 #define MAX_SEC_DEVICE_TYPES 5
        /**
-        * sec_device_type - Secondary Device Types (P2P)
-        * See device_type for the format used with these.
+        * sec_device_types - Secondary Device Types (P2P)
         */
-       char *sec_device_type[MAX_SEC_DEVICE_TYPES];
+       u8 sec_device_type[MAX_SEC_DEVICE_TYPES][WPS_DEV_TYPE_LEN];
+       int num_sec_device_types;
 
        int p2p_listen_reg_class;
        int p2p_listen_channel;
index 09c99e3..4642335 100644 (file)
@@ -645,8 +645,12 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
                fprintf(f, "model_number=%s\n", config->model_number);
        if (config->serial_number)
                fprintf(f, "serial_number=%s\n", config->serial_number);
-       if (config->device_type)
-               fprintf(f, "device_type=%s\n", config->device_type);
+       {
+               char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
+               buf = wps_dev_type_bin2str(config->device_type,
+                                          _buf, sizeof(_buf));
+               fprintf(f, "device_type=%s\n", buf);
+       }
        if (WPA_GET_BE32(config->os_version))
                fprintf(f, "os_version=%08x\n",
                        WPA_GET_BE32(config->os_version));
index 6b2096f..ea3a2ac 100644 (file)
@@ -247,8 +247,13 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
                hk, TEXT("model_name"));
        config->serial_number = wpa_config_read_reg_string(
                hk, TEXT("serial_number"));
-       config->device_type = wpa_config_read_reg_string(
-               hk, TEXT("device_type"));
+       {
+               char *t = wpa_config_read_reg_string(
+                       hk, TEXT("device_type"));
+               if (t && wps_dev_type_str2bin(t, config->device_type))
+                       errors++;
+               os_free(t);
+       }
        config->config_methods = wpa_config_read_reg_string(
                hk, TEXT("config_methods"));
        if (wpa_config_read_global_os_version(config, hk))
@@ -585,7 +590,12 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
        wpa_config_write_reg_string(hk, "model_number", config->model_number);
        wpa_config_write_reg_string(hk, "serial_number",
                                    config->serial_number);
-       wpa_config_write_reg_string(hk, "device_type", config->device_type);
+       {
+               char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
+               buf = wps_dev_type_bin2str(config->device_type,
+                                          _buf, sizeof(_buf));
+               wpa_config_write_reg_string(hk, "device_type", buf);
+       }
        wpa_config_write_reg_string(hk, "config_methods",
                                    config->config_methods);
        if (WPA_GET_BE32(config->os_version)) {
index b311493..f1153f4 100644 (file)
@@ -931,10 +931,14 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
        C(model_name);
        C(model_number);
        C(serial_number);
-       C(device_type);
        C(config_methods);
 #undef C
 
+       os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
+       os_memcpy(d->sec_device_type, s->sec_device_type,
+                 sizeof(d->sec_device_type));
+       d->num_sec_device_types = s->num_sec_device_types;
+
        d->p2p_group_idle = s->p2p_group_idle;
        d->p2p_intra_bss = s->p2p_intra_bss;
 }
@@ -2291,7 +2295,6 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 {
        struct p2p_config p2p;
        unsigned int r;
-       int i;
 
        if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
                return 0;
@@ -2317,27 +2320,13 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
                wpa_printf(MSG_DEBUG, "P2P: Use driver-based P2P management");
                os_memset(&params, 0, sizeof(params));
                params.dev_name = wpa_s->conf->device_name;
-               if (wpa_s->conf->device_type &&
-                   wps_dev_type_str2bin(wpa_s->conf->device_type,
-                                        params.pri_dev_type) < 0) {
-                       wpa_printf(MSG_ERROR, "P2P: Invalid device_type");
-                       return -1;
-               }
-               for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) {
-                       if (wpa_s->conf->sec_device_type[i] == NULL)
-                               continue;
-                       if (wps_dev_type_str2bin(
-                                   wpa_s->conf->sec_device_type[i],
-                                   params.sec_dev_type[
-                                           params.num_sec_dev_types]) < 0) {
-                               wpa_printf(MSG_ERROR, "P2P: Invalid "
-                                          "sec_device_type");
-                               return -1;
-                       }
-                       params.num_sec_dev_types++;
-                       if (params.num_sec_dev_types == DRV_MAX_SEC_DEV_TYPES)
-                               break;
-               }
+               os_memcpy(params.pri_dev_type, wpa_s->conf->device_type,
+                         WPS_DEV_TYPE_LEN);
+               params.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
+               os_memcpy(params.sec_dev_type,
+                         wpa_s->conf->sec_device_type,
+                         params.num_sec_dev_types * WPS_DEV_TYPE_LEN);
+
                if (wpa_drv_p2p_set_params(wpa_s, &params) < 0)
                        return -1;
 
@@ -2417,26 +2406,12 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
                return -1;
        }
 
-       if (wpa_s->conf->device_type &&
-           wps_dev_type_str2bin(wpa_s->conf->device_type, p2p.pri_dev_type) <
-           0) {
-               wpa_printf(MSG_ERROR, "P2P: Invalid device_type");
-               return -1;
-       }
+       os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
+                 WPS_DEV_TYPE_LEN);
 
-       for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) {
-               if (wpa_s->conf->sec_device_type[i] == NULL)
-                       continue;
-               if (wps_dev_type_str2bin(
-                           wpa_s->conf->sec_device_type[i],
-                           p2p.sec_dev_type[p2p.num_sec_dev_types]) < 0) {
-                       wpa_printf(MSG_ERROR, "P2P: Invalid sec_device_type");
-                       return -1;
-               }
-               p2p.num_sec_dev_types++;
-               if (p2p.num_sec_dev_types == P2P_SEC_DEVICE_TYPES)
-                       break;
-       }
+       p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
+       os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
+                 p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
 
        p2p.concurrent_operations = !!(wpa_s->drv_flags &
                                       WPA_DRIVER_FLAGS_P2P_CONCURRENT);
@@ -3900,38 +3875,13 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
                p2p_set_dev_name(p2p, wpa_s->conf->device_name);
 
-       if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) {
-               u8 pri_dev_type[8];
-               if (wpa_s->conf->device_type) {
-                       if (wps_dev_type_str2bin(wpa_s->conf->device_type,
-                                                pri_dev_type) < 0) {
-                               wpa_printf(MSG_ERROR, "P2P: Invalid "
-                                          "device_type");
-                       } else
-                               p2p_set_pri_dev_type(p2p, pri_dev_type);
-               }
-       }
+       if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
+               p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
 
-       if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
-               u8 sec_dev_type[P2P_SEC_DEVICE_TYPES][8];
-               size_t num = 0;
-               int i;
-               for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) {
-                       if (wpa_s->conf->sec_device_type[i] == NULL)
-                               continue;
-                       if (wps_dev_type_str2bin(
-                                   wpa_s->conf->sec_device_type[i],
-                                   sec_dev_type[num]) < 0) {
-                               wpa_printf(MSG_ERROR, "P2P: Invalid "
-                                          "sec_device_type");
-                               continue;
-                       }
-                       num++;
-                       if (num == P2P_SEC_DEVICE_TYPES)
-                               break;
-               }
-               p2p_set_sec_dev_types(p2p, (void *) sec_dev_type, num);
-       }
+       if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
+               p2p_set_sec_dev_types(p2p,
+                                     (void *) wpa_s->conf->sec_device_type,
+                                     wpa_s->conf->num_sec_device_types);
 
        if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
            wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
index 1bdfea8..778ccaf 100644 (file)
@@ -1094,7 +1094,6 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
 {
        struct wps_context *wps;
        struct wps_registrar_config rcfg;
-       int i;
 
        wps = os_zalloc(sizeof(*wps));
        if (wps == NULL)
@@ -1119,28 +1118,12 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
                return -1;
        }
        wps->config_methods = wps_fix_config_methods(wps->config_methods);
-       if (wpa_s->conf->device_type &&
-           wps_dev_type_str2bin(wpa_s->conf->device_type,
-                                wps->dev.pri_dev_type) < 0) {
-               wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
-               os_free(wps);
-               return -1;
-       }
+       os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
+                 WPS_DEV_TYPE_LEN);
 
-       for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) {
-               if (wpa_s->conf->sec_device_type[i] == NULL)
-                       continue;
-               if (wps_dev_type_str2bin(
-                           wpa_s->conf->sec_device_type[i],
-                           wps->dev.sec_dev_type[wps->dev.num_sec_dev_types])
-                   < 0) {
-                       wpa_printf(MSG_ERROR, "WPS: Invalid sec_device_type");
-                       return -1;
-               }
-               wps->dev.num_sec_dev_types++;
-               if (wps->dev.num_sec_dev_types == WPS_SEC_DEVICE_TYPES)
-                       break;
-       }
+       wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
+       os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
+                 WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
 
        wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
        wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */
@@ -1665,33 +1648,14 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
        }
        wps->config_methods = wps_fix_config_methods(wps->config_methods);
 
-       if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) {
-               if (wpa_s->conf->device_type &&
-                   wps_dev_type_str2bin(wpa_s->conf->device_type,
-                                        wps->dev.pri_dev_type) < 0)
-                       wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
-       }
+       if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
+               os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
+                         WPS_DEV_TYPE_LEN);
 
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
-               int i;
-
-               wps->dev.num_sec_dev_types = 0;
-
-               for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) {
-                       if (wpa_s->conf->sec_device_type[i] == NULL)
-                               continue;
-                       if (wps_dev_type_str2bin(
-                                   wpa_s->conf->sec_device_type[i],
-                                   wps->dev.sec_dev_type[
-                                           wps->dev.num_sec_dev_types]) < 0) {
-                               wpa_printf(MSG_ERROR,
-                                          "WPS: Invalid sec_device_type");
-                               continue;
-                       }
-                       wps->dev.num_sec_dev_types++;
-                       if (wps->dev.num_sec_dev_types == WPS_SEC_DEVICE_TYPES)
-                               break;
-               }
+               wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
+               os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
+                         wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
        }
 
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)