3 # Example nfcpy to hostapd wrapper for WPS NFC operations
4 # Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
23 wpas_ctrl = '/var/run/hostapd'
27 if os.path.isdir(wpas_ctrl):
29 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
30 except OSError, error:
31 print "Could not find hostapd: ", error
35 print "No hostapd control interface found"
40 wpas = wpactrl.WPACtrl(ctrl)
42 except wpactrl.error, error:
43 print "Error: ", error
48 def wpas_tag_read(message):
52 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
55 def wpas_get_config_token():
59 return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
62 def wpas_get_password_token():
66 return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
69 def wpas_get_handover_sel():
73 return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
76 def wpas_report_handover(req, sel):
80 return wpas.request("NFC_REPORT_HANDOVER RESP WPS " +
81 str(req).encode("hex") + " " +
82 str(sel).encode("hex"))
85 class HandoverServer(nfc.handover.HandoverServer):
87 super(HandoverServer, self).__init__()
89 def process_request(self, request):
90 print "HandoverServer - request received"
91 print "Parsed handover request: " + request.pretty()
93 sel = nfc.ndef.HandoverSelectMessage(version="1.2")
95 for carrier in request.carriers:
96 print "Remote carrier type: " + carrier.type
97 if carrier.type == "application/vnd.wfa.wsc":
98 print "WPS carrier type match - add WPS carrier record"
99 self.received_carrier = carrier.record
100 data = wpas_get_handover_sel()
102 print "Could not get handover select carrier record from hostapd"
104 print "Handover select carrier record from hostapd:"
105 print data.encode("hex")
106 self.sent_carrier = data
108 message = nfc.ndef.Message(data);
109 sel.add_carrier(message[0], "active", message[1:])
111 print "Handover select:"
113 print str(sel).encode("hex")
115 print "Sending handover select"
119 def wps_handover_resp(peer):
120 print "Trying to handle WPS handover"
122 srv = HandoverServer()
123 srv.sent_carrier = None
125 nfc.llcp.activate(peer);
128 print "Trying handover";
130 print "Wait for disconnect"
131 while nfc.llcp.connected():
133 print "Disconnected after handover"
134 except nfc.llcp.ConnectRefused:
135 print "Handover connection refused"
140 wpas_report_handover(srv.received_carrier, srv.sent_carrier)
144 print "Done with handover"
147 def wps_tag_read(tag):
148 if len(tag.ndef.message):
149 message = nfc.ndef.Message(tag.ndef.message)
150 print "message type " + message.type
152 for record in message:
153 print "record type " + record.type
154 if record.type == "application/vnd.wfa.wsc":
155 print "WPS tag - send to hostapd"
156 wpas_tag_read(tag.ndef.message)
162 while tag.is_present:
166 def wps_write_config_tag(clf):
167 print "Write WPS config token"
168 data = wpas_get_config_token()
170 print "Could not get WPS config token from hostapd"
173 print "Touch an NFC tag"
181 print "Tag found - writing"
182 tag.ndef.message = data
183 print "Done - remove tag"
184 while tag.is_present:
188 def wps_write_password_tag(clf):
189 print "Write WPS password token"
190 data = wpas_get_password_token()
192 print "Could not get WPS password token from hostapd"
195 print "Touch an NFC tag"
203 print "Tag found - writing"
204 tag.ndef.message = data
205 print "Done - remove tag"
206 while tag.is_present:
212 if nfc.llcp.connected():
213 print "LLCP connected"
214 general_bytes = nfc.llcp.startup({})
215 peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
216 if isinstance(peer, nfc.DEP):
217 print "listen -> DEP";
218 if peer.general_bytes.startswith("Ffm"):
221 print "mismatch in general_bytes"
222 print peer.general_bytes
224 peer = clf.poll(general_bytes)
225 if isinstance(peer, nfc.DEP):
227 if peer.general_bytes.startswith("Ffm"):
230 print "mismatch in general_bytes"
231 print peer.general_bytes
239 clf = nfc.ContactlessFrontend()
242 if len(sys.argv) > 1 and sys.argv[1] == "write-config":
243 wps_write_config_tag(clf)
246 if len(sys.argv) > 1 and sys.argv[1] == "write-password":
247 wps_write_password_tag(clf)
251 print "Waiting for a tag or peer to be touched"
254 if isinstance(tag, nfc.DEP):
255 wps_handover_resp(tag)
262 print "Not an NDEF tag - remove tag"
263 while tag.is_present:
266 except KeyboardInterrupt:
273 if __name__ == '__main__':