aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hostapd/Makefile15
-rw-r--r--hostapd/ctrl_iface.c8
-rw-r--r--hostapd/hostapd_cli.c23
-rw-r--r--hostapd/wps_hostapd.c3
-rw-r--r--hostapd/wps_hostapd.h2
-rw-r--r--src/wps/ndef.c174
-rw-r--r--src/wps/wps.c3
-rw-r--r--src/wps/wps.h9
-rw-r--r--src/wps/wps_common.c19
-rw-r--r--src/wps/wps_enrollee.c3
-rw-r--r--src/wps/wps_i.h5
-rw-r--r--src/wps/wps_nfc.c117
-rw-r--r--src/wps/wps_nfc_pn531.c113
-rw-r--r--src/wps/wps_ufd.c1
-rw-r--r--wpa_supplicant/Makefile15
-rw-r--r--wpa_supplicant/ctrl_iface.c8
-rw-r--r--wpa_supplicant/wpa_cli.c25
-rw-r--r--wpa_supplicant/wps_supplicant.c3
-rw-r--r--wpa_supplicant/wps_supplicant.h2
19 files changed, 523 insertions, 25 deletions
diff --git a/hostapd/Makefile b/hostapd/Makefile
index 0dbece6..daa971d 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 5d85558..d24c4af 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 c32d9d3..340e9c3 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 9def50a..39f67ee 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 0d39797..9d94a4f 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 0000000..f900767
--- /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 <honma@ictec.co.jp>
+ *
+ * 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 79f3512..dde16d1 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 379033e..70d8b03 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 f679ff6..65b7d99 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 73c5ecb..8c8d087 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 e4c0b35..e3cf236 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 0000000..ff12000
--- /dev/null
+++ b/src/wps/wps_nfc.c
@@ -0,0 +1,117 @@
+/*
+ * NFC routines for Wi-Fi Protected Setup
+ * Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
+ *
+ * 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 0000000..7e05e4d
--- /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 <honma@ictec.co.jp>
+ *
+ * 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 012c906..0e713ee 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 b50b661..22e4e49 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 494672c..7aacd52 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 d6055e9..73937d7 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,
- "<OOB_DEV_TYPE> <OOB_PATH> <OOB_METHOD> = start WPS OOB" },
+ "<DEV_TYPE> <PATH> <METHOD> [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 e6607c0..7a20284 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 ad55301..abc4b92 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,