3 # Example nfcpy to wpa_supplicant 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.
25 wpas_ctrl = '/var/run/wpa_supplicant'
29 if os.path.isdir(wpas_ctrl):
31 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
32 except OSError, error:
33 print "Could not find wpa_supplicant: ", error
37 print "No wpa_supplicant control interface found"
42 wpas = wpactrl.WPACtrl(ctrl)
44 except wpactrl.error, error:
45 print "Error: ", error
50 def wpas_tag_read(message):
54 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
57 def wpas_get_config_token():
61 return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
64 def wpas_get_password_token():
68 return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
71 def wpas_get_handover_req():
75 return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
78 def wpas_report_handover(req, sel):
82 return wpas.request("NFC_REPORT_HANDOVER INIT WPS " +
83 str(req).encode("hex") + " " +
84 str(sel).encode("hex"))
87 def wps_handover_init(peer):
88 print "Trying to initiate WPS handover"
90 data = wpas_get_handover_req()
92 print "Could not get handover request carrier record from wpa_supplicant"
94 print "Handover request carrier record from wpa_supplicant: " + data.encode("hex")
95 record = nfc.ndef.Record()
96 f = StringIO.StringIO(data)
98 record = nfc.ndef.HandoverCarrierRecord(record)
99 print "Parsed handover request carrier record:"
100 print record.pretty()
102 message = nfc.ndef.HandoverRequestMessage(version="1.2")
103 message.nonce = random.randint(0, 0xffff)
104 message.add_carrier(record, "active")
106 print "Handover request:"
107 print message.pretty()
109 nfc.llcp.activate(peer);
111 client = nfc.handover.HandoverClient()
113 print "Trying handover";
115 print "Connected for handover"
116 except nfc.llcp.ConnectRefused:
117 print "Handover connection refused"
122 print "Sending handover request"
124 if not client.send(message):
125 print "Failed to send handover request"
127 print "Receiving handover response"
128 message = client._recv()
130 print "No response received"
134 if message.type != "urn:nfc:wkt:Hs":
135 print "Response was not Hs - received: " + message.type
140 print "Received message"
141 print message.pretty()
142 message = nfc.ndef.HandoverSelectMessage(message)
143 print "Handover select received"
144 print message.pretty()
146 for carrier in message.carriers:
147 print "Remote carrier type: " + carrier.type
148 if carrier.type == "application/vnd.wfa.wsc":
149 print "WPS carrier type match - send to wpa_supplicant"
150 wpas_report_handover(data, carrier.record)
151 wifi = nfc.ndef.WifiConfigRecord(carrier.record)
157 print "Done with handover"
160 def wps_tag_read(tag):
161 if len(tag.ndef.message):
162 message = nfc.ndef.Message(tag.ndef.message)
163 print "message type " + message.type
165 for record in message:
166 print "record type " + record.type
167 if record.type == "application/vnd.wfa.wsc":
168 print "WPS tag - send to wpa_supplicant"
169 wpas_tag_read(tag.ndef.message)
175 while tag.is_present:
179 def wps_write_config_tag(clf):
180 print "Write WPS config token"
181 data = wpas_get_config_token()
183 print "Could not get WPS config token from wpa_supplicant"
186 print "Touch an NFC tag"
194 print "Tag found - writing"
195 tag.ndef.message = data
196 print "Done - remove tag"
197 while tag.is_present:
201 def wps_write_password_tag(clf):
202 print "Write WPS password token"
203 data = wpas_get_password_token()
205 print "Could not get WPS password token from wpa_supplicant"
208 print "Touch an NFC tag"
216 print "Tag found - writing"
217 tag.ndef.message = data
218 print "Done - remove tag"
219 while tag.is_present:
225 if nfc.llcp.connected():
226 print "LLCP connected"
227 general_bytes = nfc.llcp.startup({})
228 peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
229 if isinstance(peer, nfc.DEP):
230 print "listen -> DEP";
231 if peer.general_bytes.startswith("Ffm"):
234 print "mismatch in general_bytes"
235 print peer.general_bytes
237 peer = clf.poll(general_bytes)
238 if isinstance(peer, nfc.DEP):
240 if peer.general_bytes.startswith("Ffm"):
243 print "mismatch in general_bytes"
244 print peer.general_bytes
252 clf = nfc.ContactlessFrontend()
255 if len(sys.argv) > 1 and sys.argv[1] == "write-config":
256 wps_write_config_tag(clf)
259 if len(sys.argv) > 1 and sys.argv[1] == "write-password":
260 wps_write_password_tag(clf)
264 print "Waiting for a tag or peer to be touched"
267 if isinstance(tag, nfc.DEP):
268 wps_handover_init(tag)
275 print "Not an NDEF tag - remove tag"
276 while tag.is_present:
279 except KeyboardInterrupt:
286 if __name__ == '__main__':