diff --git a/hostapd/Makefile b/hostapd/Makefile index 0dbece698..daa971d59 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -324,6 +324,21 @@ OBJS += ../src/wps/wps_ufd.o NEED_WPS_OOB=y endif +ifdef CONFIG_WPS_NFC +CFLAGS += -DCONFIG_WPS_NFC +OBJS += ../src/wps/ndef.o +OBJS += ../src/wps/wps_nfc.o +NEED_WPS_OOB=y +ifdef CONFIG_WPS_NFC_PN531 +PN531_PATH = /usr/local/src/nfc +CFLAGS += -DCONFIG_WPS_NFC_PN531 +CFLAGS += -I${PN531_PATH}/inc +OBJS += ../src/wps/wps_nfc_pn531.o +LIBS += ${PN531_PATH}/lib/wpsnfc.dll +LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll +endif +endif + ifdef NEED_WPS_OOB CFLAGS += -DCONFIG_WPS_OOB endif diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 5d85558fa..d24c4afae 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -257,7 +257,7 @@ static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt) #ifdef CONFIG_WPS_OOB static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt) { - char *path, *method; + char *path, *method, *name; path = os_strchr(txt, ' '); if (path == NULL) @@ -269,7 +269,11 @@ static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt) return -1; *method++ = '\0'; - return hostapd_wps_start_oob(hapd, txt, path, method); + name = os_strchr(method, ' '); + if (name != NULL) + *name++ = '\0'; + + return hostapd_wps_start_oob(hapd, txt, path, method, name); } #endif /* CONFIG_WPS_OOB */ #endif /* CONFIG_WPS */ diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index c32d9d3de..340e9c3c8 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -287,17 +287,24 @@ static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char cmd[256]; int res; - if (argc != 3) { - printf("Invalid WPS_OOB command: need three arguments:\n" - "- OOB_DEV_TYPE: use 'ufd'\n" - "- OOB_PATH: path of OOB device like '/mnt'\n" - "- OOB_METHOD: OOB method 'pin-e' or 'pin-r', " - "'cred'\n"); + if (argc != 3 && argc != 4) { + printf("Invalid WPS_OOB command: need three or four " + "arguments:\n" + "- DEV_TYPE: use 'ufd' or 'nfc'\n" + "- PATH: path of OOB device like '/mnt'\n" + "- METHOD: OOB method 'pin-e' or 'pin-r', " + "'cred'\n" + "- DEV_NAME: (only for NFC) device name like " + "'pn531'\n"); return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", - argv[0], argv[1], argv[2]); + if (argc == 3) + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", + argv[0], argv[1], argv[2]); + else + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s", + argv[0], argv[1], argv[2], argv[3]); if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { printf("Too long WPS_OOB command.\n"); return -1; diff --git a/hostapd/wps_hostapd.c b/hostapd/wps_hostapd.c index 9def50a14..39f67ee28 100644 --- a/hostapd/wps_hostapd.c +++ b/hostapd/wps_hostapd.c @@ -706,7 +706,7 @@ int hostapd_wps_button_pushed(struct hostapd_data *hapd) #ifdef CONFIG_WPS_OOB int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type, - char *path, char *method) + char *path, char *method, char *name) { struct wps_context *wps = hapd->wps; struct oob_device_data *oob_dev; @@ -715,6 +715,7 @@ int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type, if (oob_dev == NULL) return -1; oob_dev->device_path = path; + oob_dev->device_name = name; wps->oob_conf.oob_method = wps_get_oob_method(method); if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) { diff --git a/hostapd/wps_hostapd.h b/hostapd/wps_hostapd.h index 0d39797ff..9d94a4f26 100644 --- a/hostapd/wps_hostapd.h +++ b/hostapd/wps_hostapd.h @@ -24,7 +24,7 @@ int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid, const char *pin); int hostapd_wps_button_pushed(struct hostapd_data *hapd); int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type, - char *path, char *method); + char *path, char *method, char *name); void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr, const u8 *ie, size_t ie_len); diff --git a/src/wps/ndef.c b/src/wps/ndef.c new file mode 100644 index 000000000..f900767b5 --- /dev/null +++ b/src/wps/ndef.c @@ -0,0 +1,174 @@ +/* + * NDEF(NFC Data Exchange Format) routines for Wi-Fi Protected Setup + * Reference is "NFCForum-TS-NDEF_1.0 2006-07-24". + * Copyright (c) 2009, Masashi Honma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" +#include "common.h" +#include "wps/wps.h" + +#define FLAG_MESSAGE_BEGIN (1 << 7) +#define FLAG_MESSAGE_END (1 << 6) +#define FLAG_CHUNK (1 << 5) +#define FLAG_SHORT_RECORD (1 << 4) +#define FLAG_ID_LENGTH_PRESENT (1 << 3) +#define FLAG_TNF_RFC2046 (0x02) + +struct ndef_record { + u8 *type; + u8 *id; + u8 *payload; + u8 type_length; + u8 id_length; + u32 payload_length; + u32 total_length; +}; + +static char wifi_handover_type[] = "application/vnd.wfa.wsc"; + +static int ndef_parse_record(u8 *data, u32 size, struct ndef_record *record) +{ + u8 *pos = data + 1; + + if (size < 2) + return -1; + record->type_length = *pos++; + if (data[0] & FLAG_SHORT_RECORD) { + if (size < 3) + return -1; + record->payload_length = *pos++; + } else { + if (size < 6) + return -1; + record->payload_length = ntohl(*(u32 *)pos); + pos += sizeof(u32); + } + + if (data[0] & FLAG_ID_LENGTH_PRESENT) { + if ((int) size < pos - data + 1) + return -1; + record->id_length = *pos++; + } else + record->id_length = 0; + + record->type = record->type_length == 0 ? NULL : pos; + pos += record->type_length; + + record->id = record->id_length == 0 ? NULL : pos; + pos += record->id_length; + + record->payload = record->payload_length == 0 ? NULL : pos; + pos += record->payload_length; + + record->total_length = pos - data; + if (record->total_length > size) + return -1; + return 0; +} + + +static struct wpabuf * ndef_parse_records(struct wpabuf *buf, + int (*filter)(struct ndef_record *)) +{ + struct ndef_record record; + int len = wpabuf_len(buf); + u8 *data = wpabuf_mhead(buf); + + while (len > 0) { + if (ndef_parse_record(data, len, &record) < 0) { + wpa_printf(MSG_ERROR, "NDEF : Failed to parse"); + return NULL; + } + if (filter == NULL || filter(&record)) + return wpabuf_alloc_copy(record.payload, + record.payload_length); + data += record.total_length; + len -= record.total_length; + } + wpa_printf(MSG_ERROR, "NDEF : Record not found"); + return NULL; +} + + +static struct wpabuf * ndef_build_record(u8 flags, void *type, + u8 type_length, void *id, + u8 id_length, void *payload, + u32 payload_length) +{ + struct wpabuf *record; + size_t total_len; + int short_record; + u8 local_flag; + + short_record = payload_length < 256 ? 1 : 0; + + total_len = 2; /* flag + type length */ + /* payload length */ + total_len += short_record ? sizeof(u8) : sizeof(u32); + if (id_length > 0) + total_len += 1; + total_len += type_length + id_length + payload_length; + record = wpabuf_alloc(total_len); + if (record == NULL) { + wpa_printf(MSG_ERROR, "NDEF : Failed to allocate " + "record for build"); + return NULL; + } + + local_flag = flags; + if (id_length > 0) + local_flag |= FLAG_ID_LENGTH_PRESENT; + if (short_record) + local_flag |= FLAG_SHORT_RECORD; + wpabuf_put_u8(record, local_flag); + + wpabuf_put_u8(record, type_length); + + if (short_record) + wpabuf_put_u8(record, payload_length); + else + wpabuf_put_be32(record, payload_length); + + if (id_length > 0) + wpabuf_put_u8(record, id_length); + wpabuf_put_data(record, type, type_length); + wpabuf_put_data(record, id, id_length); + wpabuf_put_data(record, payload, payload_length); + return record; +} + + +static int wifi_filter(struct ndef_record *record) +{ + if (record->type_length != os_strlen(wifi_handover_type)) + return 0; + if (os_memcmp(record->type, wifi_handover_type, + os_strlen(wifi_handover_type)) != 0) + return 0; + return 1; +} + + +struct wpabuf * ndef_parse_wifi(struct wpabuf *buf) +{ + return ndef_parse_records(buf, wifi_filter); +} + + +struct wpabuf * ndef_build_wifi(struct wpabuf *buf) +{ + return ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_MESSAGE_END | + FLAG_TNF_RFC2046, wifi_handover_type, + os_strlen(wifi_handover_type), NULL, 0, + wpabuf_mhead(buf), wpabuf_len(buf)); +} diff --git a/src/wps/wps.c b/src/wps/wps.c index 79f3512c6..dde16d17a 100644 --- a/src/wps/wps.c +++ b/src/wps/wps.c @@ -305,6 +305,9 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev, #ifdef CONFIG_WPS_UFD methods |= WPS_CONFIG_USBA; #endif /* CONFIG_WPS_UFD */ +#ifdef CONFIG_WPS_NFC + methods |= WPS_CONFIG_NFC_INTERFACE; +#endif /* CONFIG_WPS_NFC */ } if (wps_build_version(ie) || diff --git a/src/wps/wps.h b/src/wps/wps.h index 379033ea5..70d8b0398 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -526,6 +526,7 @@ struct wps_context { }; struct oob_device_data { + char *device_name; char *device_path; void * (*init_func)(struct wps_context *, struct oob_device_data *, int); @@ -534,6 +535,13 @@ struct oob_device_data { void (*deinit_func)(void *); }; +struct oob_nfc_device_data { + int (*init_func)(char *); + void * (*read_func)(size_t *); + int (*write_func)(void *, size_t); + void (*deinit_func)(void); +}; + struct wps_registrar * wps_registrar_init(struct wps_context *wps, const struct wps_registrar_config *cfg); @@ -555,6 +563,7 @@ unsigned int wps_generate_pin(void); void wps_free_pending_msgs(struct upnp_pending_message *msgs); struct oob_device_data * wps_get_oob_device(char *device_type); +struct oob_nfc_device_data * wps_get_oob_nfc_device(char *device_name); int wps_get_oob_method(char *method); int wps_process_oob(struct wps_context *wps, struct oob_device_data *oob_dev, int registrar); diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index f679ff6fe..65b7d99ca 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -525,11 +525,30 @@ struct oob_device_data * wps_get_oob_device(char *device_type) if (os_strstr(device_type, "ufd") != NULL) return &oob_ufd_device_data; #endif /* CONFIG_WPS_UFD */ +#ifdef CONFIG_WPS_NFC + if (os_strstr(device_type, "nfc") != NULL) + return &oob_nfc_device_data; +#endif /* CONFIG_WPS_NFC */ return NULL; } +#ifdef CONFIG_WPS_NFC +struct oob_nfc_device_data * wps_get_oob_nfc_device(char *device_name) +{ + if (device_name == NULL) + return NULL; +#ifdef CONFIG_WPS_NFC_PN531 + if (os_strstr(device_name, "pn531") != NULL) + return &oob_nfc_pn531_device_data; +#endif /* CONFIG_WPS_NFC_PN531 */ + + return NULL; +} +#endif /* CONFIG_WPS_NFC */ + + int wps_get_oob_method(char *method) { if (os_strstr(method, "pin-e") != NULL) diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 73c5ecbab..8c8d087e1 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -135,6 +135,9 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps) #ifdef CONFIG_WPS_UFD methods |= WPS_CONFIG_USBA; #endif /* CONFIG_WPS_UFD */ +#ifdef CONFIG_WPS_NFC + methods |= WPS_CONFIG_NFC_INTERFACE; +#endif /* CONFIG_WPS_NFC */ if (wps->pbc) methods |= WPS_CONFIG_PUSHBUTTON; diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h index e4c0b359f..e3cf23654 100644 --- a/src/wps/wps_i.h +++ b/src/wps/wps_i.h @@ -194,6 +194,8 @@ void wps_success_event(struct wps_context *wps); void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part); extern struct oob_device_data oob_ufd_device_data; +extern struct oob_device_data oob_nfc_device_data; +extern struct oob_nfc_device_data oob_nfc_pn531_device_data; /* wps_attr_parse.c */ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr); @@ -244,6 +246,9 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps, const struct wpabuf *msg); int wps_build_cred(struct wps_data *wps, struct wpabuf *msg); +/* ndef.c */ +struct wpabuf * ndef_parse_wifi(struct wpabuf *buf); +struct wpabuf * ndef_build_wifi(struct wpabuf *buf); static inline int wps_version_supported(const u8 *version) { diff --git a/src/wps/wps_nfc.c b/src/wps/wps_nfc.c new file mode 100644 index 000000000..ff120002b --- /dev/null +++ b/src/wps/wps_nfc.c @@ -0,0 +1,117 @@ +/* + * NFC routines for Wi-Fi Protected Setup + * Copyright (c) 2009, Masashi Honma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" +#include "common.h" + +#include "wps/wps.h" +#include "wps_i.h" + + +struct wps_nfc_data { + struct oob_nfc_device_data *oob_nfc_dev; +}; + + +static void * init_nfc(struct wps_context *wps, + struct oob_device_data *oob_dev, int registrar) +{ + struct oob_nfc_device_data *oob_nfc_dev; + struct wps_nfc_data *data; + + oob_nfc_dev = wps_get_oob_nfc_device(oob_dev->device_name); + if (oob_nfc_dev == NULL) { + wpa_printf(MSG_ERROR, "WPS (NFC): Unknown NFC device (%s)", + oob_dev->device_name); + return NULL; + } + + if (oob_nfc_dev->init_func(oob_dev->device_path) < 0) + return NULL; + + data = os_zalloc(sizeof(*data)); + if (data == NULL) { + wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate " + "nfc data area"); + return NULL; + } + data->oob_nfc_dev = oob_nfc_dev; + return data; +} + + +static struct wpabuf * read_nfc(void *priv) +{ + struct wps_nfc_data *data = priv; + struct wpabuf *wifi, *buf; + char *raw_data; + size_t len; + + raw_data = data->oob_nfc_dev->read_func(&len); + if (raw_data == NULL) + return NULL; + + wifi = wpabuf_alloc_copy(raw_data, len); + os_free(raw_data); + if (wifi == NULL) { + wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate " + "nfc read area"); + return NULL; + } + + buf = ndef_parse_wifi(wifi); + wpabuf_free(wifi); + if (buf == NULL) + wpa_printf(MSG_ERROR, "WPS (NFC): Failed to unwrap"); + return buf; +} + + +static int write_nfc(void *priv, struct wpabuf *buf) +{ + struct wps_nfc_data *data = priv; + struct wpabuf *wifi; + int ret; + + wifi = ndef_build_wifi(buf); + if (wifi == NULL) { + wpa_printf(MSG_ERROR, "WPS (NFC): Failed to wrap"); + return -1; + } + + ret = data->oob_nfc_dev->write_func(wpabuf_mhead(wifi), + wpabuf_len(wifi)); + wpabuf_free(wifi); + return ret; +} + + +static void deinit_nfc(void *priv) +{ + struct wps_nfc_data *data = priv; + + data->oob_nfc_dev->deinit_func(); + + os_free(data); +} + + +struct oob_device_data oob_nfc_device_data = { + .device_name = NULL, + .device_path = NULL, + .init_func = init_nfc, + .read_func = read_nfc, + .write_func = write_nfc, + .deinit_func = deinit_nfc, +}; diff --git a/src/wps/wps_nfc_pn531.c b/src/wps/wps_nfc_pn531.c new file mode 100644 index 000000000..7e05e4dd5 --- /dev/null +++ b/src/wps/wps_nfc_pn531.c @@ -0,0 +1,113 @@ +/* + * NFC PN531 routines for Wi-Fi Protected Setup + * Copyright (c) 2009, Masashi Honma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" +#include "common.h" + +#include "wps/wps.h" +#include "wps_i.h" + +#include "WpsNfcType.h" +#include "WpsNfc.h" + + +static int init_nfc_pn531(char *path) +{ + u32 ret; + + ret = WpsNfcInit(); + if (ret != WPS_NFCLIB_ERR_SUCCESS) { + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to initialize " + "NFC Library: 0x%08x", ret); + return -1; + } + + ret = WpsNfcOpenDevice((int8 *) path); + if (ret != WPS_NFCLIB_ERR_SUCCESS) { + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to open " + "NFC Device(%s): 0x%08x", path, ret); + goto fail; + } + + ret = WpsNfcTokenDiscovery(); + if (ret != WPS_NFCLIB_ERR_SUCCESS) { + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to discover " + "token: 0x%08x", ret); + WpsNfcCloseDevice(); + goto fail; + } + + return 0; + +fail: + WpsNfcDeinit(); + return -1; +} + + +static void * read_nfc_pn531(size_t *size) +{ + uint32 len; + u32 ret; + int8 *data; + + ret = WpsNfcRawReadToken(&data, &len); + if (ret != WPS_NFCLIB_ERR_SUCCESS) { + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to read: 0x%08x", + ret); + return NULL; + } + + *size = len; + return data; +} + + +static int write_nfc_pn531(void *data, size_t len) +{ + u32 ret; + + ret = WpsNfcRawWriteToken(data, len); + if (ret != WPS_NFCLIB_ERR_SUCCESS) { + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to write: 0x%08x", + ret); + return -1; + } + + return 0; +} + + +static void deinit_nfc_pn531(void) +{ + u32 ret; + + ret = WpsNfcCloseDevice(); + if (ret != WPS_NFCLIB_ERR_SUCCESS) + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to close " + "NFC Device: 0x%08x", ret); + + ret = WpsNfcDeinit(); + if (ret != WPS_NFCLIB_ERR_SUCCESS) + wpa_printf(MSG_ERROR, "WPS (PN531): Failed to deinitialize " + "NFC Library: 0x%08x", ret); +} + + +struct oob_nfc_device_data oob_nfc_pn531_device_data = { + .init_func = init_nfc_pn531, + .read_func = read_nfc_pn531, + .write_func = write_nfc_pn531, + .deinit_func = deinit_nfc_pn531, +}; diff --git a/src/wps/wps_ufd.c b/src/wps/wps_ufd.c index 012c906ea..0e713eeee 100644 --- a/src/wps/wps_ufd.c +++ b/src/wps/wps_ufd.c @@ -225,6 +225,7 @@ static void deinit_ufd(void *priv) struct oob_device_data oob_ufd_device_data = { + .device_name = NULL, .device_path = NULL, .init_func = init_ufd, .read_func = read_ufd, diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index b50b661a4..22e4e4984 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -534,6 +534,21 @@ OBJS += ../src/wps/wps_ufd.o NEED_WPS_OOB=y endif +ifdef CONFIG_WPS_NFC +CFLAGS += -DCONFIG_WPS_NFC +OBJS += ../src/wps/ndef.o +OBJS += ../src/wps/wps_nfc.o +NEED_WPS_OOB=y +ifdef CONFIG_WPS_NFC_PN531 +PN531_PATH = /usr/local/src/nfc +CFLAGS += -DCONFIG_WPS_NFC_PN531 +CFLAGS += -I${PN531_PATH}/inc +OBJS += ../src/wps/wps_nfc_pn531.o +LIBS += ${PN531_PATH}/lib/wpsnfc.dll +LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll +endif +endif + ifdef NEED_WPS_OOB CFLAGS += -DCONFIG_WPS_OOB endif diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 494672c9e..7aacd5230 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -208,7 +208,7 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s, char *cmd) { - char *path, *method; + char *path, *method, *name; path = os_strchr(cmd, ' '); if (path == NULL) @@ -220,7 +220,11 @@ static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s, return -1; *method++ = '\0'; - return wpas_wps_start_oob(wpa_s, cmd, path, method); + name = os_strchr(method, ' '); + if (name != NULL) + *name++ = '\0'; + + return wpas_wps_start_oob(wpa_s, cmd, path, method, name); } #endif /* CONFIG_WPS_OOB */ diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index d6055e90b..73937d71e 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -452,17 +452,24 @@ static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[]) char cmd[256]; int res; - if (argc != 3) { - printf("Invalid WPS_OOB command: need three arguments:\n" - "- OOB_DEV_TYPE: use 'ufd'\n" - "- OOB_PATH: path of OOB device like '/mnt'\n" - "- OOB_METHOD: OOB method 'pin-e' or 'pin-r', " - "'cred'\n"); + if (argc != 3 && argc != 4) { + printf("Invalid WPS_OOB command: need three or four " + "arguments:\n" + "- DEV_TYPE: use 'ufd' or 'nfc'\n" + "- PATH: path of OOB device like '/mnt'\n" + "- METHOD: OOB method 'pin-e' or 'pin-r', " + "'cred'\n" + "- DEV_NAME: (only for NFC) device name like " + "'pn531'\n"); return -1; } - res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", - argv[0], argv[1], argv[2]); + if (argc == 3) + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s", + argv[0], argv[1], argv[2]); + else + res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s", + argv[0], argv[1], argv[2], argv[3]); if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { printf("Too long WPS_OOB command.\n"); return -1; @@ -1287,7 +1294,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { #ifdef CONFIG_WPS_OOB { "wps_oob", wpa_cli_cmd_wps_oob, cli_cmd_flag_sensitive, - " = start WPS OOB" }, + " [DEV_NAME] = start WPS OOB" }, #endif /* CONFIG_WPS_OOB */ { "wps_reg", wpa_cli_cmd_wps_reg, cli_cmd_flag_sensitive, diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index e6607c07f..7a20284af 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -563,7 +563,7 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, #ifdef CONFIG_WPS_OOB int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, - char *path, char *method) + char *path, char *method, char *name) { struct wps_context *wps = wpa_s->wps; struct oob_device_data *oob_dev; @@ -572,6 +572,7 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, if (oob_dev == NULL) return -1; oob_dev->device_path = path; + oob_dev->device_name = name; wps->oob_conf.oob_method = wps_get_oob_method(method); if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) { diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h index ad5530144..abc4b9225 100644 --- a/wpa_supplicant/wps_supplicant.h +++ b/wpa_supplicant/wps_supplicant.h @@ -28,7 +28,7 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid); int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin); int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, - char *path, char *method); + char *path, char *method, char *name); int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin); int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,