WPS: Select the BSD license terms as the only license alternative
[mech_eap.git] / src / wps / wps_nfc.c
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
16 struct wps_nfc_data {
17         struct oob_nfc_device_data *oob_nfc_dev;
18 };
19
20
21 static 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
48 static 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
75 static 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
94 static 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
104 struct 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 };