1/*
2 * NFC routines for Wi-Fi Protected Setup
3 * Copyright (c) 2009-2012, Masashi Honma <masashi.honma@gmail.com>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10#include "common.h"
11
12#include "wps/wps.h"
13#include "wps_i.h"
14
15
16struct wps_nfc_data {
17	struct oob_nfc_device_data *oob_nfc_dev;
18};
19
20
21static void * init_nfc(struct wps_context *wps,
22		       struct oob_device_data *oob_dev, int registrar)
23{
24	struct oob_nfc_device_data *oob_nfc_dev;
25	struct wps_nfc_data *data;
26
27	oob_nfc_dev = wps_get_oob_nfc_device(oob_dev->device_name);
28	if (oob_nfc_dev == NULL) {
29		wpa_printf(MSG_ERROR, "WPS (NFC): Unknown NFC device (%s)",
30			   oob_dev->device_name);
31		return NULL;
32	}
33
34	if (oob_nfc_dev->init_func(oob_dev->device_path) < 0)
35		return NULL;
36
37	data = os_zalloc(sizeof(*data));
38	if (data == NULL) {
39		wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate "
40			   "nfc data area");
41		return NULL;
42	}
43	data->oob_nfc_dev = oob_nfc_dev;
44	return data;
45}
46
47
48static struct wpabuf * read_nfc(void *priv)
49{
50	struct wps_nfc_data *data = priv;
51	struct wpabuf *wifi, *buf;
52	char *raw_data;
53	size_t len;
54
55	raw_data = data->oob_nfc_dev->read_func(&len);
56	if (raw_data == NULL)
57		return NULL;
58
59	wifi = wpabuf_alloc_copy(raw_data, len);
60	os_free(raw_data);
61	if (wifi == NULL) {
62		wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate "
63			   "nfc read area");
64		return NULL;
65	}
66
67	buf = ndef_parse_wifi(wifi);
68	wpabuf_free(wifi);
69	if (buf == NULL)
70		wpa_printf(MSG_ERROR, "WPS (NFC): Failed to unwrap");
71	return buf;
72}
73
74
75static int write_nfc(void *priv, struct wpabuf *buf)
76{
77	struct wps_nfc_data *data = priv;
78	struct wpabuf *wifi;
79	int ret;
80
81	wifi = ndef_build_wifi(buf);
82	if (wifi == NULL) {
83		wpa_printf(MSG_ERROR, "WPS (NFC): Failed to wrap");
84		return -1;
85	}
86
87	ret = data->oob_nfc_dev->write_func(wpabuf_mhead(wifi),
88					    wpabuf_len(wifi));
89	wpabuf_free(wifi);
90	return ret;
91}
92
93
94static void deinit_nfc(void *priv)
95{
96	struct wps_nfc_data *data = priv;
97
98	data->oob_nfc_dev->deinit_func();
99
100	os_free(data);
101}
102
103
104struct oob_device_data oob_nfc_device_data = {
105	.device_name	= NULL,
106	.device_path	= NULL,
107	.init_func	= init_nfc,
108	.read_func	= read_nfc,
109	.write_func	= write_nfc,
110	.deinit_func	= deinit_nfc,
111};
112