blob: bb458fb37a845dff9c943958e0b0f773c84e28d7 [file] [log] [blame]
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001#!/usr/bin/python
2#
3# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations
Dmitry Shmidtf8623282013-02-20 14:34:59 -08004# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005#
6# This software may be distributed under the terms of the BSD license.
7# See README for more details.
8
9import os
10import sys
11import time
Dmitry Shmidtf8623282013-02-20 14:34:59 -080012import random
Dmitry Shmidtcf32e602014-01-28 10:57:39 -080013import threading
14import argparse
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080015
16import nfc
17import nfc.ndef
18import nfc.llcp
19import nfc.handover
20
Dmitry Shmidtf8623282013-02-20 14:34:59 -080021import logging
Dmitry Shmidtf8623282013-02-20 14:34:59 -080022
Dmitry Shmidt700a1372013-03-15 14:14:44 -070023import wpaspy
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080024
25wpas_ctrl = '/var/run/wpa_supplicant'
Dmitry Shmidtcf32e602014-01-28 10:57:39 -080026srv = None
27continue_loop = True
28terminate_now = False
Dmitry Shmidt96be6222014-02-13 10:16:51 -080029summary_file = None
30success_file = None
31
32def summary(txt):
Hai Shalom74f70d42019-02-11 14:42:39 -080033 print(txt)
Dmitry Shmidt96be6222014-02-13 10:16:51 -080034 if summary_file:
35 with open(summary_file, 'a') as f:
36 f.write(txt + "\n")
37
38def success_report(txt):
39 summary(txt)
40 if success_file:
41 with open(success_file, 'a') as f:
42 f.write(txt + "\n")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080043
44def wpas_connect():
45 ifaces = []
46 if os.path.isdir(wpas_ctrl):
47 try:
48 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
Hai Shalom74f70d42019-02-11 14:42:39 -080049 except OSError as error:
50 print("Could not find wpa_supplicant: ", error)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080051 return None
52
53 if len(ifaces) < 1:
Hai Shalom74f70d42019-02-11 14:42:39 -080054 print("No wpa_supplicant control interface found")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080055 return None
56
57 for ctrl in ifaces:
58 try:
Dmitry Shmidt700a1372013-03-15 14:14:44 -070059 wpas = wpaspy.Ctrl(ctrl)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080060 return wpas
Hai Shalom74f70d42019-02-11 14:42:39 -080061 except Exception as e:
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080062 pass
63 return None
64
65
66def wpas_tag_read(message):
67 wpas = wpas_connect()
68 if (wpas == None):
Dmitry Shmidt4b060592013-04-29 16:42:49 -070069 return False
Dmitry Shmidtcf32e602014-01-28 10:57:39 -080070 if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")):
Dmitry Shmidt4b060592013-04-29 16:42:49 -070071 return False
72 return True
Dmitry Shmidtd5e49232012-12-03 15:08:10 -080073
Dmitry Shmidt1e78e762013-04-02 11:05:36 -070074def wpas_get_config_token(id=None):
Dmitry Shmidtf8623282013-02-20 14:34:59 -080075 wpas = wpas_connect()
76 if (wpas == None):
77 return None
Dmitry Shmidt1e78e762013-04-02 11:05:36 -070078 if id:
Dmitry Shmidt4b060592013-04-29 16:42:49 -070079 ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id)
80 else:
81 ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF")
82 if "FAIL" in ret:
83 return None
84 return ret.rstrip().decode("hex")
Dmitry Shmidtf8623282013-02-20 14:34:59 -080085
86
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -080087def wpas_get_er_config_token(uuid):
88 wpas = wpas_connect()
89 if (wpas == None):
90 return None
Dmitry Shmidtcf32e602014-01-28 10:57:39 -080091 ret = wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid)
92 if "FAIL" in ret:
93 return None
94 return ret.rstrip().decode("hex")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -080095
96
Dmitry Shmidtf8623282013-02-20 14:34:59 -080097def wpas_get_password_token():
98 wpas = wpas_connect()
99 if (wpas == None):
100 return None
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800101 ret = wpas.request("WPS_NFC_TOKEN NDEF")
102 if "FAIL" in ret:
103 return None
104 return ret.rstrip().decode("hex")
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800105
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800106def wpas_get_handover_req():
107 wpas = wpas_connect()
108 if (wpas == None):
109 return None
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800110 ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR")
111 if "FAIL" in ret:
112 return None
113 return ret.rstrip().decode("hex")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800114
115
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800116def wpas_get_handover_sel(uuid):
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800117 wpas = wpas_connect()
118 if (wpas == None):
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800119 return None
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800120 if uuid is None:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800121 res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip()
122 else:
123 res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip()
124 if "FAIL" in res:
125 return None
126 return res.decode("hex")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800127
128
129def wpas_report_handover(req, sel, type):
130 wpas = wpas_connect()
131 if (wpas == None):
132 return None
133 return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " +
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800134 str(req).encode("hex") + " " +
135 str(sel).encode("hex"))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800136
137
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800138class HandoverServer(nfc.handover.HandoverServer):
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800139 def __init__(self, llc):
140 super(HandoverServer, self).__init__(llc)
141 self.sent_carrier = None
142 self.ho_server_processing = False
143 self.success = False
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800144
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800145 # override to avoid parser error in request/response.pretty() in nfcpy
146 # due to new WSC handover format
147 def _process_request(self, request):
148 summary("received handover request {}".format(request.type))
149 response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
150 if not request.type == 'urn:nfc:wkt:Hr':
151 summary("not a handover request")
152 else:
153 try:
154 request = nfc.ndef.HandoverRequestMessage(request)
155 except nfc.ndef.DecodeError as e:
156 summary("error decoding 'Hr' message: {}".format(e))
157 else:
158 response = self.process_request(request)
159 summary("send handover response {}".format(response.type))
160 return response
161
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800162 def process_request(self, request):
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800163 self.ho_server_processing = True
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800164 summary("HandoverServer - request received")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800165 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800166 print("Parsed handover request: " + request.pretty())
167 except Exception as e:
168 print(e)
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800169
170 sel = nfc.ndef.HandoverSelectMessage(version="1.2")
171
172 for carrier in request.carriers:
Hai Shalom74f70d42019-02-11 14:42:39 -0800173 print("Remote carrier type: " + carrier.type)
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800174 if carrier.type == "application/vnd.wfa.wsc":
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800175 summary("WPS carrier type match - add WPS carrier record")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800176 data = wpas_get_handover_sel(self.uuid)
177 if data is None:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800178 summary("Could not get handover select carrier record from wpa_supplicant")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800179 continue
Hai Shalom74f70d42019-02-11 14:42:39 -0800180 print("Handover select carrier record from wpa_supplicant:")
181 print(data.encode("hex"))
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800182 self.sent_carrier = data
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800183 if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"):
184 success_report("Handover reported successfully (responder)")
185 else:
186 summary("Handover report rejected (responder)")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800187
188 message = nfc.ndef.Message(data);
189 sel.add_carrier(message[0], "active", message[1:])
190
Hai Shalom74f70d42019-02-11 14:42:39 -0800191 print("Handover select:")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800192 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800193 print(sel.pretty())
194 except Exception as e:
195 print(e)
196 print(str(sel).encode("hex"))
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800197
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800198 summary("Sending handover select")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800199 self.success = True
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800200 return sel
201
202
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800203def wps_handover_init(llc):
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800204 summary("Trying to initiate WPS handover")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800205
206 data = wpas_get_handover_req()
207 if (data == None):
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800208 summary("Could not get handover request carrier record from wpa_supplicant")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800209 return
Hai Shalom74f70d42019-02-11 14:42:39 -0800210 print("Handover request carrier record from wpa_supplicant: " + data.encode("hex"))
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800211
212 message = nfc.ndef.HandoverRequestMessage(version="1.2")
213 message.nonce = random.randint(0, 0xffff)
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800214 datamsg = nfc.ndef.Message(data)
215 message.add_carrier(datamsg[0], "active", datamsg[1:])
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800216
Hai Shalom74f70d42019-02-11 14:42:39 -0800217 print("Handover request:")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800218 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800219 print(message.pretty())
220 except Exception as e:
221 print(e)
222 print(str(message).encode("hex"))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800223
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800224 client = nfc.handover.HandoverClient(llc)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800225 try:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800226 summary("Trying to initiate NFC connection handover")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800227 client.connect()
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800228 summary("Connected for handover")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800229 except nfc.llcp.ConnectRefused:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800230 summary("Handover connection refused")
231 client.close()
232 return
Hai Shalom74f70d42019-02-11 14:42:39 -0800233 except Exception as e:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800234 summary("Other exception: " + str(e))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800235 client.close()
236 return
237
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800238 summary("Sending handover request")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800239
240 if not client.send(message):
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800241 summary("Failed to send handover request")
242 client.close()
243 return
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800244
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800245 summary("Receiving handover response")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800246 message = client._recv()
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800247 if message is None:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800248 summary("No response received")
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800249 client.close()
250 return
251 if message.type != "urn:nfc:wkt:Hs":
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800252 summary("Response was not Hs - received: " + message.type)
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800253 client.close()
254 return
255
Hai Shalom74f70d42019-02-11 14:42:39 -0800256 print("Received message")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800257 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800258 print(message.pretty())
259 except Exception as e:
260 print(e)
261 print(str(message).encode("hex"))
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800262 message = nfc.ndef.HandoverSelectMessage(message)
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800263 summary("Handover select received")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800264 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800265 print(message.pretty())
266 except Exception as e:
267 print(e)
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800268
269 for carrier in message.carriers:
Hai Shalom74f70d42019-02-11 14:42:39 -0800270 print("Remote carrier type: " + carrier.type)
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800271 if carrier.type == "application/vnd.wfa.wsc":
Hai Shalom74f70d42019-02-11 14:42:39 -0800272 print("WPS carrier type match - send to wpa_supplicant")
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800273 if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
274 success_report("Handover reported successfully (initiator)")
275 else:
276 summary("Handover report rejected (initiator)")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800277 # nfcpy does not support the new format..
278 #wifi = nfc.ndef.WifiConfigRecord(carrier.record)
279 #print wifi.pretty()
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800280
Hai Shalom74f70d42019-02-11 14:42:39 -0800281 print("Remove peer")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800282 client.close()
Hai Shalom74f70d42019-02-11 14:42:39 -0800283 print("Done with handover")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800284 global only_one
285 if only_one:
286 global continue_loop
287 continue_loop = False
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800288
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800289 global no_wait
290 if no_wait:
Hai Shalom74f70d42019-02-11 14:42:39 -0800291 print("Trying to exit..")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800292 global terminate_now
293 terminate_now = True
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800294
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700295def wps_tag_read(tag, wait_remove=True):
296 success = False
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800297 if len(tag.ndef.message):
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800298 for record in tag.ndef.message:
Hai Shalom74f70d42019-02-11 14:42:39 -0800299 print("record type " + record.type)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800300 if record.type == "application/vnd.wfa.wsc":
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800301 summary("WPS tag - send to wpa_supplicant")
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700302 success = wpas_tag_read(tag.ndef.message)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800303 break
304 else:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800305 summary("Empty tag")
306
307 if success:
308 success_report("Tag read succeeded")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800309
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700310 if wait_remove:
Hai Shalom74f70d42019-02-11 14:42:39 -0800311 print("Remove tag")
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700312 while tag.is_present:
313 time.sleep(0.1)
314
315 return success
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800316
317
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800318def rdwr_connected_write(tag):
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800319 summary("Tag found - writing - " + str(tag))
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800320 global write_data
321 tag.ndef.message = str(write_data)
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800322 success_report("Tag write succeeded")
Hai Shalom74f70d42019-02-11 14:42:39 -0800323 print("Done - remove tag")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800324 global only_one
325 if only_one:
326 global continue_loop
327 continue_loop = False
328 global write_wait_remove
329 while write_wait_remove and tag.is_present:
330 time.sleep(0.1)
331
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700332def wps_write_config_tag(clf, id=None, wait_remove=True):
Hai Shalom74f70d42019-02-11 14:42:39 -0800333 print("Write WPS config token")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800334 global write_data, write_wait_remove
335 write_wait_remove = wait_remove
336 write_data = wpas_get_config_token(id)
337 if write_data == None:
Hai Shalom74f70d42019-02-11 14:42:39 -0800338 print("Could not get WPS config token from wpa_supplicant")
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700339 sys.exit(1)
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800340 return
Hai Shalom74f70d42019-02-11 14:42:39 -0800341 print("Touch an NFC tag")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800342 clf.connect(rdwr={'on-connect': rdwr_connected_write})
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800343
344
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800345def wps_write_er_config_tag(clf, uuid, wait_remove=True):
Hai Shalom74f70d42019-02-11 14:42:39 -0800346 print("Write WPS ER config token")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800347 global write_data, write_wait_remove
348 write_wait_remove = wait_remove
349 write_data = wpas_get_er_config_token(uuid)
350 if write_data == None:
Hai Shalom74f70d42019-02-11 14:42:39 -0800351 print("Could not get WPS config token from wpa_supplicant")
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800352 return
353
Hai Shalom74f70d42019-02-11 14:42:39 -0800354 print("Touch an NFC tag")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800355 clf.connect(rdwr={'on-connect': rdwr_connected_write})
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800356
357
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700358def wps_write_password_tag(clf, wait_remove=True):
Hai Shalom74f70d42019-02-11 14:42:39 -0800359 print("Write WPS password token")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800360 global write_data, write_wait_remove
361 write_wait_remove = wait_remove
362 write_data = wpas_get_password_token()
363 if write_data == None:
Hai Shalom74f70d42019-02-11 14:42:39 -0800364 print("Could not get WPS password token from wpa_supplicant")
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800365 return
366
Hai Shalom74f70d42019-02-11 14:42:39 -0800367 print("Touch an NFC tag")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800368 clf.connect(rdwr={'on-connect': rdwr_connected_write})
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800369
370
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800371def rdwr_connected(tag):
372 global only_one, no_wait
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800373 summary("Tag connected: " + str(tag))
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800374
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800375 if tag.ndef:
Hai Shalom74f70d42019-02-11 14:42:39 -0800376 print("NDEF tag: " + tag.type)
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800377 try:
Hai Shalom74f70d42019-02-11 14:42:39 -0800378 print(tag.ndef.message.pretty())
379 except Exception as e:
380 print(e)
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800381 success = wps_tag_read(tag, not only_one)
382 if only_one and success:
383 global continue_loop
384 continue_loop = False
385 else:
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800386 summary("Not an NDEF tag - remove tag")
387 return True
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800388
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800389 return not no_wait
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800390
391
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800392def llcp_worker(llc):
393 global arg_uuid
394 if arg_uuid is None:
395 wps_handover_init(llc)
Hai Shalom74f70d42019-02-11 14:42:39 -0800396 print("Exiting llcp_worker thread")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800397 return
398
399 global srv
400 global wait_connection
401 while not wait_connection and srv.sent_carrier is None:
402 if srv.ho_server_processing:
403 time.sleep(0.025)
404
405def llcp_startup(clf, llc):
406 global arg_uuid
407 if arg_uuid:
Hai Shalom74f70d42019-02-11 14:42:39 -0800408 print("Start LLCP server")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800409 global srv
410 srv = HandoverServer(llc)
411 if arg_uuid is "ap":
Hai Shalom74f70d42019-02-11 14:42:39 -0800412 print("Trying to handle WPS handover")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800413 srv.uuid = None
414 else:
Hai Shalom74f70d42019-02-11 14:42:39 -0800415 print("Trying to handle WPS handover with AP " + arg_uuid)
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800416 srv.uuid = arg_uuid
417 return llc
418
419def llcp_connected(llc):
Hai Shalom74f70d42019-02-11 14:42:39 -0800420 print("P2P LLCP connected")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800421 global wait_connection
422 wait_connection = False
423 global arg_uuid
424 if arg_uuid:
425 global srv
426 srv.start()
427 else:
428 threading.Thread(target=llcp_worker, args=(llc,)).start()
Hai Shalom74f70d42019-02-11 14:42:39 -0800429 print("llcp_connected returning")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800430 return True
431
432
433def terminate_loop():
434 global terminate_now
435 return terminate_now
436
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800437def main():
438 clf = nfc.ContactlessFrontend()
439
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800440 parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for WPS NFC operations')
441 parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO,
442 action='store_const', dest='loglevel',
443 help='verbose debug output')
444 parser.add_argument('-q', const=logging.WARNING, action='store_const',
445 dest='loglevel', help='be quiet')
446 parser.add_argument('--only-one', '-1', action='store_true',
447 help='run only one operation and exit')
448 parser.add_argument('--no-wait', action='store_true',
449 help='do not wait for tag to be removed before exiting')
450 parser.add_argument('--uuid',
451 help='UUID of an AP (used for WPS ER operations)')
452 parser.add_argument('--id',
453 help='network id (used for WPS ER operations)')
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800454 parser.add_argument('--summary',
455 help='summary file for writing status updates')
456 parser.add_argument('--success',
457 help='success file for writing success update')
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800458 parser.add_argument('command', choices=['write-config',
459 'write-er-config',
460 'write-password'],
461 nargs='?')
462 args = parser.parse_args()
463
464 global arg_uuid
465 arg_uuid = args.uuid
466
467 global only_one
468 only_one = args.only_one
469
470 global no_wait
471 no_wait = args.no_wait
472
Dmitry Shmidt96be6222014-02-13 10:16:51 -0800473 if args.summary:
474 global summary_file
475 summary_file = args.summary
476
477 if args.success:
478 global success_file
479 success_file = args.success
480
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800481 logging.basicConfig(level=args.loglevel)
482
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800483 try:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800484 if not clf.open("usb"):
Hai Shalom74f70d42019-02-11 14:42:39 -0800485 print("Could not open connection with an NFC device")
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800486 raise SystemExit
487
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800488 if args.command == "write-config":
489 wps_write_config_tag(clf, id=args.id, wait_remove=not args.no_wait)
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700490 raise SystemExit
491
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800492 if args.command == "write-er-config":
493 wps_write_er_config_tag(clf, args.uuid, wait_remove=not args.no_wait)
Dmitry Shmidt1e78e762013-04-02 11:05:36 -0700494 raise SystemExit
495
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800496 if args.command == "write-password":
497 wps_write_password_tag(clf, wait_remove=not args.no_wait)
Dmitry Shmidt33e38bf2013-02-27 12:56:00 -0800498 raise SystemExit
499
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800500 global continue_loop
501 while continue_loop:
Hai Shalom74f70d42019-02-11 14:42:39 -0800502 print("Waiting for a tag or peer to be touched")
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800503 wait_connection = True
504 try:
505 if not clf.connect(rdwr={'on-connect': rdwr_connected},
506 llcp={'on-startup': llcp_startup,
507 'on-connect': llcp_connected},
508 terminate=terminate_loop):
Dmitry Shmidt4b060592013-04-29 16:42:49 -0700509 break
Hai Shalom74f70d42019-02-11 14:42:39 -0800510 except Exception as e:
511 print("clf.connect failed")
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800512
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800513 global srv
514 if only_one and srv and srv.success:
515 raise SystemExit
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800516
517 except KeyboardInterrupt:
518 raise SystemExit
519 finally:
520 clf.close()
521
522 raise SystemExit
523
524if __name__ == '__main__':
525 main()