]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/examples/wps-nfc.py
WPS: Use alternating poll/listen for NFC peer discovery with nfcpy
[thirdparty/hostap.git] / wpa_supplicant / examples / wps-nfc.py
CommitLineData
d4f612b7
JM
1#!/usr/bin/python
2#
3# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations
8140ae96 4# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
d4f612b7
JM
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
e50d01b4
JM
15import nfc.llcp
16import nfc.handover
d4f612b7 17
8140ae96
JM
18import logging
19logging.basicConfig()
20
d4f612b7
JM
21import wpactrl
22
23wpas_ctrl = '/var/run/wpa_supplicant'
24
ec4f5a37 25def wpas_connect():
d4f612b7
JM
26 ifaces = []
27 if os.path.isdir(wpas_ctrl):
28 try:
29 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
30 except OSError, error:
31 print "Could not find wpa_supplicant: ", error
ec4f5a37 32 return None
d4f612b7
JM
33
34 if len(ifaces) < 1:
35 print "No wpa_supplicant control interface found"
ec4f5a37 36 return None
d4f612b7
JM
37
38 for ctrl in ifaces:
39 try:
40 wpas = wpactrl.WPACtrl(ctrl)
ec4f5a37 41 return wpas
d4f612b7
JM
42 except wpactrl.error, error:
43 print "Error: ", error
44 pass
ec4f5a37
JM
45 return None
46
47
48def wpas_tag_read(message):
49 wpas = wpas_connect()
50 if (wpas == None):
51 return
52 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
d4f612b7 53
dab710c4 54
e50d01b4
JM
55def wpas_get_handover_req():
56 wpas = wpas_connect()
57 if (wpas == None):
58 return None
59 return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS").rstrip().decode("hex")
60
61
62def wpas_put_handover_sel(message):
63 wpas = wpas_connect()
64 if (wpas == None):
65 return
66 print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex"))
67
68
69def wps_handover_init(peer):
70 print "Trying to initiate WPS handover"
71
72 data = wpas_get_handover_req()
73 if (data == None):
74 print "Could not get handover request message from wpa_supplicant"
75 return
76 print "Handover request from wpa_supplicant: " + data.encode("hex")
77 message = nfc.ndef.Message(data)
78 print "Parsed handover request: " + message.pretty()
79
80 nfc.llcp.activate(peer);
81 time.sleep(0.5)
82
83 client = nfc.handover.HandoverClient()
84 try:
85 print "Trying handover";
86 client.connect()
87 print "Connected for handover"
88 except nfc.llcp.ConnectRefused:
89 print "Handover connection refused"
90 nfc.llcp.shutdown()
91 client.close()
92 return
93
94 print "Sending handover request"
95
96 if not client.send(message):
97 print "Failed to send handover request"
98
99 print "Receiving handover response"
100 message = client._recv()
101 print "Handover select received"
102 print message.pretty()
103 wpas_put_handover_sel(message)
104
105 print "Remove peer"
106 nfc.llcp.shutdown()
107 client.close()
108 print "Done with handover"
109
110
dab710c4
JM
111def wps_tag_read(tag):
112 if len(tag.ndef.message):
113 message = nfc.ndef.Message(tag.ndef.message)
114 print "message type " + message.type
115
116 for record in message:
117 print "record type " + record.type
118 if record.type == "application/vnd.wfa.wsc":
119 print "WPS tag - send to wpa_supplicant"
120 wpas_tag_read(tag.ndef.message)
121 break
122 else:
123 print "Empty tag"
124
125 print "Remove tag"
126 while tag.is_present:
127 time.sleep(0.1)
128
129
dc6bda11
JM
130def find_peer(clf):
131 while True:
132 if nfc.llcp.connected():
133 print "LLCP connected"
134 general_bytes = nfc.llcp.startup({})
135 peer = clf.listen(ord(os.urandom(1)) + 200, general_bytes)
136 if isinstance(peer, nfc.DEP):
137 print "listen -> DEP";
138 if peer.general_bytes.startswith("Ffm"):
139 print "Found DEP"
140 return peer
141 print "mismatch in general_bytes"
142 print peer.general_bytes
143
144 peer = clf.poll(general_bytes)
145 if isinstance(peer, nfc.DEP):
146 print "poll -> DEP";
147 if peer.general_bytes.startswith("Ffm"):
148 print "Found DEP"
149 return peer
150 print "mismatch in general_bytes"
151 print peer.general_bytes
152
153 if peer:
154 print "Found tag"
155 return peer
156
157
d4f612b7
JM
158def main():
159 clf = nfc.ContactlessFrontend()
160
161 try:
162 while True:
e50d01b4 163 print "Waiting for a tag or peer to be touched"
d4f612b7 164
dc6bda11
JM
165 tag = find_peer(clf)
166 if isinstance(tag, nfc.DEP):
167 wps_handover_init(tag)
168 continue
169
170 if tag.ndef:
171 wps_tag_read(tag)
172 continue
173
174 print "Not an NDEF tag - remove tag"
175 while tag.is_present:
176 time.sleep(0.1)
d4f612b7
JM
177
178 except KeyboardInterrupt:
179 raise SystemExit
180 finally:
181 clf.close()
182
183 raise SystemExit
184
185if __name__ == '__main__':
186 main()