blob: 0cfc1f684dc9f6f834834927a9e677e04d3133fe [file] [log] [blame]
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001#!/usr/bin/python
2#
3# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations
4# Copyright (c) 2012, Jouni Malinen <j@w1.fi>
5#
6# This software may be distributed under the terms of the BSD license.
7# See README for more details.
8
9import os
10import sys
11import time
12
13import nfc
14import nfc.ndef
15import nfc.llcp
16import nfc.handover
17
18import wpactrl
19
20wpas_ctrl = '/var/run/wpa_supplicant'
21
22def wpas_connect():
23 ifaces = []
24 if os.path.isdir(wpas_ctrl):
25 try:
26 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
27 except OSError, error:
28 print "Could not find wpa_supplicant: ", error
29 return None
30
31 if len(ifaces) < 1:
32 print "No wpa_supplicant control interface found"
33 return None
34
35 for ctrl in ifaces:
36 try:
37 wpas = wpactrl.WPACtrl(ctrl)
38 return wpas
39 except wpactrl.error, error:
40 print "Error: ", error
41 pass
42 return None
43
44
45def wpas_tag_read(message):
46 wpas = wpas_connect()
47 if (wpas == None):
48 return
49 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
50
51
52def wpas_get_handover_req():
53 wpas = wpas_connect()
54 if (wpas == None):
55 return None
56 return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS").rstrip().decode("hex")
57
58
59def wpas_put_handover_sel(message):
60 wpas = wpas_connect()
61 if (wpas == None):
62 return
63 print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex"))
64
65
66def wps_handover_init(peer):
67 print "Trying to initiate WPS handover"
68
69 data = wpas_get_handover_req()
70 if (data == None):
71 print "Could not get handover request message from wpa_supplicant"
72 return
73 print "Handover request from wpa_supplicant: " + data.encode("hex")
74 message = nfc.ndef.Message(data)
75 print "Parsed handover request: " + message.pretty()
76
77 nfc.llcp.activate(peer);
78 time.sleep(0.5)
79
80 client = nfc.handover.HandoverClient()
81 try:
82 print "Trying handover";
83 client.connect()
84 print "Connected for handover"
85 except nfc.llcp.ConnectRefused:
86 print "Handover connection refused"
87 nfc.llcp.shutdown()
88 client.close()
89 return
90
91 print "Sending handover request"
92
93 if not client.send(message):
94 print "Failed to send handover request"
95
96 print "Receiving handover response"
97 message = client._recv()
98 print "Handover select received"
99 print message.pretty()
100 wpas_put_handover_sel(message)
101
102 print "Remove peer"
103 nfc.llcp.shutdown()
104 client.close()
105 print "Done with handover"
106
107
108def wps_tag_read(tag):
109 if len(tag.ndef.message):
110 message = nfc.ndef.Message(tag.ndef.message)
111 print "message type " + message.type
112
113 for record in message:
114 print "record type " + record.type
115 if record.type == "application/vnd.wfa.wsc":
116 print "WPS tag - send to wpa_supplicant"
117 wpas_tag_read(tag.ndef.message)
118 break
119 else:
120 print "Empty tag"
121
122 print "Remove tag"
123 while tag.is_present:
124 time.sleep(0.1)
125
126
127def main():
128 clf = nfc.ContactlessFrontend()
129
130 try:
131 while True:
132 print "Waiting for a tag or peer to be touched"
133
134 while True:
135 general_bytes = nfc.llcp.startup({})
136 tag = clf.poll(general_bytes)
137 if tag == None:
138 continue
139
140 if isinstance(tag, nfc.DEP):
141 wps_handover_init(tag)
142 break
143
144 if tag.ndef:
145 wps_tag_read(tag)
146 break
147
148 if tag:
149 print "Not an NDEF tag - remove tag"
150 while tag.is_present:
151 time.sleep(0.1)
152 break
153
154 except KeyboardInterrupt:
155 raise SystemExit
156 finally:
157 clf.close()
158
159 raise SystemExit
160
161if __name__ == '__main__':
162 main()