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