]>
git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/examples/wps-nfc.py
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.
26 wpas_ctrl
= '/var/run/wpa_supplicant'
33 if os
.path
.isdir(wpas_ctrl
):
35 ifaces
= [os
.path
.join(wpas_ctrl
, i
) for i
in os
.listdir(wpas_ctrl
)]
36 except OSError, error
:
37 print "Could not find wpa_supplicant: ", error
41 print "No wpa_supplicant control interface found"
46 wpas
= wpaspy
.Ctrl(ctrl
)
53 def wpas_tag_read(message
):
57 if "FAIL" in wpas
.request("WPS_NFC_TAG_READ " + str(message
).encode("hex")):
61 def wpas_get_config_token(id=None):
66 ret
= wpas
.request("WPS_NFC_CONFIG_TOKEN NDEF " + id)
68 ret
= wpas
.request("WPS_NFC_CONFIG_TOKEN NDEF")
71 return ret
.rstrip().decode("hex")
74 def wpas_get_er_config_token(uuid
):
78 ret
= wpas
.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid
)
81 return ret
.rstrip().decode("hex")
84 def wpas_get_password_token():
88 return wpas
.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
91 def wpas_get_handover_req():
95 return wpas
.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
98 def wpas_get_handover_sel(uuid
):
103 res
= wpas
.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip()
105 res
= wpas
.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid
).rstrip()
108 return res
.decode("hex")
111 def wpas_report_handover(req
, sel
, type):
112 wpas
= wpas_connect()
115 return wpas
.request("NFC_REPORT_HANDOVER " + type + " WPS " +
116 str(req
).encode("hex") + " " +
117 str(sel
).encode("hex"))
120 class HandoverServer(nfc
.handover
.HandoverServer
):
121 def __init__(self
, llc
):
122 super(HandoverServer
, self
).__init
__(llc
)
123 self
.sent_carrier
= None
124 self
.ho_server_processing
= False
127 def process_request(self
, request
):
128 self
.ho_server_processing
= True
129 print "HandoverServer - request received"
130 print "Parsed handover request: " + request
.pretty()
132 sel
= nfc
.ndef
.HandoverSelectMessage(version
="1.2")
134 for carrier
in request
.carriers
:
135 print "Remote carrier type: " + carrier
.type
136 if carrier
.type == "application/vnd.wfa.wsc":
137 print "WPS carrier type match - add WPS carrier record"
138 data
= wpas_get_handover_sel(self
.uuid
)
140 print "Could not get handover select carrier record from wpa_supplicant"
142 print "Handover select carrier record from wpa_supplicant:"
143 print data
.encode("hex")
144 self
.sent_carrier
= data
145 wpas_report_handover(carrier
.record
, self
.sent_carrier
, "RESP")
147 message
= nfc
.ndef
.Message(data
);
148 sel
.add_carrier(message
[0], "active", message
[1:])
150 print "Handover select:"
152 print str(sel
).encode("hex")
154 print "Sending handover select"
159 def wps_handover_init(llc
):
160 print "Trying to initiate WPS handover"
162 data
= wpas_get_handover_req()
164 print "Could not get handover request carrier record from wpa_supplicant"
166 print "Handover request carrier record from wpa_supplicant: " + data
.encode("hex")
167 record
= nfc
.ndef
.Record()
168 f
= StringIO
.StringIO(data
)
170 record
= nfc
.ndef
.HandoverCarrierRecord(record
)
171 print "Parsed handover request carrier record:"
172 print record
.pretty()
174 message
= nfc
.ndef
.HandoverRequestMessage(version
="1.2")
175 message
.nonce
= random
.randint(0, 0xffff)
176 message
.add_carrier(record
, "active")
178 print "Handover request:"
179 print message
.pretty()
181 client
= nfc
.handover
.HandoverClient(llc
)
183 print "Trying handover";
185 print "Connected for handover"
186 except nfc
.llcp
.ConnectRefused
:
187 print "Handover connection refused"
191 print "Sending handover request"
193 if not client
.send(message
):
194 print "Failed to send handover request"
196 print "Receiving handover response"
197 message
= client
._recv
()
199 print "No response received"
202 if message
.type != "urn:nfc:wkt:Hs":
203 print "Response was not Hs - received: " + message
.type
207 print "Received message"
208 print message
.pretty()
209 message
= nfc
.ndef
.HandoverSelectMessage(message
)
210 print "Handover select received"
211 print message
.pretty()
213 for carrier
in message
.carriers
:
214 print "Remote carrier type: " + carrier
.type
215 if carrier
.type == "application/vnd.wfa.wsc":
216 print "WPS carrier type match - send to wpa_supplicant"
217 wpas_report_handover(data
, carrier
.record
, "INIT")
218 wifi
= nfc
.ndef
.WifiConfigRecord(carrier
.record
)
223 print "Done with handover"
227 continue_loop
= False
231 print "Trying to exit.."
235 def wps_tag_read(tag
, wait_remove
=True):
237 if len(tag
.ndef
.message
):
238 for record
in tag
.ndef
.message
:
239 print "record type " + record
.type
240 if record
.type == "application/vnd.wfa.wsc":
241 print "WPS tag - send to wpa_supplicant"
242 success
= wpas_tag_read(tag
.ndef
.message
)
249 while tag
.is_present
:
255 def rdwr_connected_write(tag
):
256 print "Tag found - writing"
258 tag
.ndef
.message
= str(write_data
)
259 print "Done - remove tag"
263 continue_loop
= False
264 global write_wait_remove
265 while write_wait_remove
and tag
.is_present
:
268 def wps_write_config_tag(clf
, id=None, wait_remove
=True):
269 print "Write WPS config token"
270 global write_data
, write_wait_remove
271 write_wait_remove
= wait_remove
272 write_data
= wpas_get_config_token(id)
273 if write_data
== None:
274 print "Could not get WPS config token from wpa_supplicant"
277 print "Touch an NFC tag"
278 clf
.connect(rdwr
={'on-connect': rdwr_connected_write
})
281 def wps_write_er_config_tag(clf
, uuid
, wait_remove
=True):
282 print "Write WPS ER config token"
283 global write_data
, write_wait_remove
284 write_wait_remove
= wait_remove
285 write_data
= wpas_get_er_config_token(uuid
)
286 if write_data
== None:
287 print "Could not get WPS config token from wpa_supplicant"
290 print "Touch an NFC tag"
291 clf
.connect(rdwr
={'on-connect': rdwr_connected_write
})
294 def wps_write_password_tag(clf
, wait_remove
=True):
295 print "Write WPS password token"
296 global write_data
, write_wait_remove
297 write_wait_remove
= wait_remove
298 write_data
= wpas_get_password_token()
299 if write_data
== None:
300 print "Could not get WPS password token from wpa_supplicant"
303 print "Touch an NFC tag"
304 clf
.connect(rdwr
={'on-connect': rdwr_connected_write
})
307 def rdwr_connected(tag
):
308 global only_one
, no_wait
309 print "Tag connected: " + str(tag
)
312 print "NDEF tag: " + tag
.type
314 print tag
.ndef
.message
.pretty()
317 success
= wps_tag_read(tag
, not only_one
)
318 if only_one
and success
:
320 continue_loop
= False
322 print "Not an NDEF tag - remove tag"
327 def llcp_worker(llc
):
330 wps_handover_init(llc
)
331 print "Exiting llcp_worker thread"
335 global wait_connection
336 while not wait_connection
and srv
.sent_carrier
is None:
337 if srv
.ho_server_processing
:
340 def llcp_startup(clf
, llc
):
343 print "Start LLCP server"
345 srv
= HandoverServer(llc
)
347 print "Trying to handle WPS handover"
350 print "Trying to handle WPS handover with AP " + arg_uuid
354 def llcp_connected(llc
):
355 print "P2P LLCP connected"
356 global wait_connection
357 wait_connection
= False
363 threading
.Thread(target
=llcp_worker
, args
=(llc
,)).start()
364 print "llcp_connected returning"
368 def terminate_loop():
373 clf
= nfc
.ContactlessFrontend()
375 parser
= argparse
.ArgumentParser(description
='nfcpy to wpa_supplicant integration for WPS NFC operations')
376 parser
.add_argument('-d', const
=logging
.DEBUG
, default
=logging
.INFO
,
377 action
='store_const', dest
='loglevel',
378 help='verbose debug output')
379 parser
.add_argument('-q', const
=logging
.WARNING
, action
='store_const',
380 dest
='loglevel', help='be quiet')
381 parser
.add_argument('--only-one', '-1', action
='store_true',
382 help='run only one operation and exit')
383 parser
.add_argument('--no-wait', action
='store_true',
384 help='do not wait for tag to be removed before exiting')
385 parser
.add_argument('--uuid',
386 help='UUID of an AP (used for WPS ER operations)')
387 parser
.add_argument('--id',
388 help='network id (used for WPS ER operations)')
389 parser
.add_argument('command', choices
=['write-config',
393 args
= parser
.parse_args()
399 only_one
= args
.only_one
402 no_wait
= args
.no_wait
404 logging
.basicConfig(level
=args
.loglevel
)
407 if not clf
.open("usb"):
408 print "Could not open connection with an NFC device"
411 if args
.command
== "write-config":
412 wps_write_config_tag(clf
, id=args
.id, wait_remove
=not args
.no_wait
)
415 if args
.command
== "write-er-config":
416 wps_write_er_config_tag(clf
, args
.uuid
, wait_remove
=not args
.no_wait
)
419 if args
.command
== "write-password":
420 wps_write_password_tag(clf
, wait_remove
=not args
.no_wait
)
425 print "Waiting for a tag or peer to be touched"
426 wait_connection
= True
428 if not clf
.connect(rdwr
={'on-connect': rdwr_connected
},
429 llcp
={'on-startup': llcp_startup
,
430 'on-connect': llcp_connected
},
431 terminate
=terminate_loop
):
434 print "clf.connect failed"
437 if only_one
and srv
and srv
.success
:
440 except KeyboardInterrupt:
447 if __name__
== '__main__':