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()
124 nfc.llcp.activate(peer);
127 print "Trying handover";
129 print "Wait for disconnect"
130 while nfc.llcp.connected():
132 print "Disconnected after handover"
133 except nfc.llcp.ConnectRefused:
134 print "Handover connection refused"
139 wpas_report_handover(srv.received_carrier, srv.sent_carrier)
143 print "Done with handover"
146 def wps_tag_read(tag):
147 if len(tag.ndef.message):
148 message = nfc.ndef.Message(tag.ndef.message)
149 print "message type " + message.type
151 for record in message:
152 print "record type " + record.type
153 if record.type == "application/vnd.wfa.wsc":
154 print "WPS tag - send to hostapd"
155 wpas_tag_read(tag.ndef.message)
161 while tag.is_present:
165 def wps_write_config_tag(clf):
166 print "Write WPS config token"
167 data = wpas_get_config_token()
169 print "Could not get WPS config token from hostapd"
172 print "Touch an NFC tag"
180 print "Tag found - writing"
181 tag.ndef.message = data
182 print "Done - remove tag"
183 while tag.is_present:
187 def wps_write_password_tag(clf):
188 print "Write WPS password token"
189 data = wpas_get_password_token()
191 print "Could not get WPS password token from hostapd"
194 print "Touch an NFC tag"
202 print "Tag found - writing"
203 tag.ndef.message = data
204 print "Done - remove tag"
205 while tag.is_present:
211 if nfc.llcp.connected():
212 print "LLCP connected"
213 general_bytes = nfc.llcp.startup({})
214 peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
215 if isinstance(peer, nfc.DEP):
216 print "listen -> DEP";
217 if peer.general_bytes.startswith("Ffm"):
220 print "mismatch in general_bytes"
221 print peer.general_bytes
223 peer = clf.poll(general_bytes)
224 if isinstance(peer, nfc.DEP):
226 if peer.general_bytes.startswith("Ffm"):
229 print "mismatch in general_bytes"
230 print peer.general_bytes
238 clf = nfc.ContactlessFrontend()
241 if len(sys.argv) > 1 and sys.argv[1] == "write-config":
242 wps_write_config_tag(clf)
245 if len(sys.argv) > 1 and sys.argv[1] == "write-password":
246 wps_write_password_tag(clf)
250 print "Waiting for a tag or peer to be touched"
253 if isinstance(tag, nfc.DEP):
254 wps_handover_resp(tag)
261 print "Not an NDEF tag - remove tag"
262 while tag.is_present:
265 except KeyboardInterrupt:
272 if __name__ == '__main__':