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 = wpaspy.Ctrl(ctrl)
47 def wpas_tag_read(message):
51 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
54 def wpas_get_config_token():
58 return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
61 def wpas_get_password_token():
65 return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
68 def wpas_get_handover_sel():
72 return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
75 def wpas_report_handover(req, sel):
79 return wpas.request("NFC_REPORT_HANDOVER RESP WPS " +
80 str(req).encode("hex") + " " +
81 str(sel).encode("hex"))
84 class HandoverServer(nfc.handover.HandoverServer):
86 super(HandoverServer, self).__init__()
88 def process_request(self, request):
89 print "HandoverServer - request received"
90 print "Parsed handover request: " + request.pretty()
92 sel = nfc.ndef.HandoverSelectMessage(version="1.2")
94 for carrier in request.carriers:
95 print "Remote carrier type: " + carrier.type
96 if carrier.type == "application/vnd.wfa.wsc":
97 print "WPS carrier type match - add WPS carrier record"
98 self.received_carrier = carrier.record
99 data = wpas_get_handover_sel()
101 print "Could not get handover select carrier record from hostapd"
103 print "Handover select carrier record from hostapd:"
104 print data.encode("hex")
105 self.sent_carrier = data
107 message = nfc.ndef.Message(data);
108 sel.add_carrier(message[0], "active", message[1:])
110 print "Handover select:"
112 print str(sel).encode("hex")
114 print "Sending handover select"
118 def wps_handover_resp(peer):
119 print "Trying to handle WPS handover"
121 srv = HandoverServer()
122 srv.sent_carrier = None
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__':