1f05cddf9SRui Paulo#!/usr/bin/python 2f05cddf9SRui Paulo# 3f05cddf9SRui Paulo# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations 45b9c547cSRui Paulo# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi> 5f05cddf9SRui Paulo# 6f05cddf9SRui Paulo# This software may be distributed under the terms of the BSD license. 7f05cddf9SRui Paulo# See README for more details. 8f05cddf9SRui Paulo 9f05cddf9SRui Pauloimport os 10f05cddf9SRui Pauloimport sys 11f05cddf9SRui Pauloimport time 125b9c547cSRui Pauloimport random 135b9c547cSRui Pauloimport threading 145b9c547cSRui Pauloimport argparse 15f05cddf9SRui Paulo 16f05cddf9SRui Pauloimport nfc 17f05cddf9SRui Pauloimport nfc.ndef 18f05cddf9SRui Pauloimport nfc.llcp 19f05cddf9SRui Pauloimport nfc.handover 20f05cddf9SRui Paulo 215b9c547cSRui Pauloimport logging 225b9c547cSRui Paulo 235b9c547cSRui Pauloimport wpaspy 24f05cddf9SRui Paulo 25f05cddf9SRui Paulowpas_ctrl = '/var/run/wpa_supplicant' 265b9c547cSRui Paulosrv = None 275b9c547cSRui Paulocontinue_loop = True 285b9c547cSRui Pauloterminate_now = False 295b9c547cSRui Paulosummary_file = None 305b9c547cSRui Paulosuccess_file = None 315b9c547cSRui Paulo 325b9c547cSRui Paulodef summary(txt): 33*4bc52338SCy Schubert print(txt) 345b9c547cSRui Paulo if summary_file: 355b9c547cSRui Paulo with open(summary_file, 'a') as f: 365b9c547cSRui Paulo f.write(txt + "\n") 375b9c547cSRui Paulo 385b9c547cSRui Paulodef success_report(txt): 395b9c547cSRui Paulo summary(txt) 405b9c547cSRui Paulo if success_file: 415b9c547cSRui Paulo with open(success_file, 'a') as f: 425b9c547cSRui Paulo f.write(txt + "\n") 43f05cddf9SRui Paulo 44f05cddf9SRui Paulodef wpas_connect(): 45f05cddf9SRui Paulo ifaces = [] 46f05cddf9SRui Paulo if os.path.isdir(wpas_ctrl): 47f05cddf9SRui Paulo try: 48f05cddf9SRui Paulo ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 49*4bc52338SCy Schubert except OSError as error: 50*4bc52338SCy Schubert print("Could not find wpa_supplicant: ", error) 51f05cddf9SRui Paulo return None 52f05cddf9SRui Paulo 53f05cddf9SRui Paulo if len(ifaces) < 1: 54*4bc52338SCy Schubert print("No wpa_supplicant control interface found") 55f05cddf9SRui Paulo return None 56f05cddf9SRui Paulo 57f05cddf9SRui Paulo for ctrl in ifaces: 58f05cddf9SRui Paulo try: 595b9c547cSRui Paulo wpas = wpaspy.Ctrl(ctrl) 60f05cddf9SRui Paulo return wpas 61*4bc52338SCy Schubert except Exception as e: 62f05cddf9SRui Paulo pass 63f05cddf9SRui Paulo return None 64f05cddf9SRui Paulo 65f05cddf9SRui Paulo 66f05cddf9SRui Paulodef wpas_tag_read(message): 67f05cddf9SRui Paulo wpas = wpas_connect() 68f05cddf9SRui Paulo if (wpas == None): 695b9c547cSRui Paulo return False 705b9c547cSRui Paulo if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")): 715b9c547cSRui Paulo return False 725b9c547cSRui Paulo return True 73f05cddf9SRui Paulo 745b9c547cSRui Paulodef wpas_get_config_token(id=None): 755b9c547cSRui Paulo wpas = wpas_connect() 765b9c547cSRui Paulo if (wpas == None): 775b9c547cSRui Paulo return None 785b9c547cSRui Paulo if id: 795b9c547cSRui Paulo ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id) 805b9c547cSRui Paulo else: 815b9c547cSRui Paulo ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF") 825b9c547cSRui Paulo if "FAIL" in ret: 835b9c547cSRui Paulo return None 845b9c547cSRui Paulo return ret.rstrip().decode("hex") 855b9c547cSRui Paulo 865b9c547cSRui Paulo 875b9c547cSRui Paulodef wpas_get_er_config_token(uuid): 885b9c547cSRui Paulo wpas = wpas_connect() 895b9c547cSRui Paulo if (wpas == None): 905b9c547cSRui Paulo return None 915b9c547cSRui Paulo ret = wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid) 925b9c547cSRui Paulo if "FAIL" in ret: 935b9c547cSRui Paulo return None 945b9c547cSRui Paulo return ret.rstrip().decode("hex") 955b9c547cSRui Paulo 965b9c547cSRui Paulo 975b9c547cSRui Paulodef wpas_get_password_token(): 985b9c547cSRui Paulo wpas = wpas_connect() 995b9c547cSRui Paulo if (wpas == None): 1005b9c547cSRui Paulo return None 1015b9c547cSRui Paulo ret = wpas.request("WPS_NFC_TOKEN NDEF") 1025b9c547cSRui Paulo if "FAIL" in ret: 1035b9c547cSRui Paulo return None 1045b9c547cSRui Paulo return ret.rstrip().decode("hex") 105f05cddf9SRui Paulo 106f05cddf9SRui Paulodef wpas_get_handover_req(): 107f05cddf9SRui Paulo wpas = wpas_connect() 108f05cddf9SRui Paulo if (wpas == None): 109f05cddf9SRui Paulo return None 1105b9c547cSRui Paulo ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR") 1115b9c547cSRui Paulo if "FAIL" in ret: 1125b9c547cSRui Paulo return None 1135b9c547cSRui Paulo return ret.rstrip().decode("hex") 114f05cddf9SRui Paulo 115f05cddf9SRui Paulo 1165b9c547cSRui Paulodef wpas_get_handover_sel(uuid): 117f05cddf9SRui Paulo wpas = wpas_connect() 118f05cddf9SRui Paulo if (wpas == None): 1195b9c547cSRui Paulo return None 1205b9c547cSRui Paulo if uuid is None: 1215b9c547cSRui Paulo res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() 1225b9c547cSRui Paulo else: 1235b9c547cSRui Paulo res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip() 1245b9c547cSRui Paulo if "FAIL" in res: 1255b9c547cSRui Paulo return None 1265b9c547cSRui Paulo return res.decode("hex") 127f05cddf9SRui Paulo 128f05cddf9SRui Paulo 1295b9c547cSRui Paulodef wpas_report_handover(req, sel, type): 1305b9c547cSRui Paulo wpas = wpas_connect() 1315b9c547cSRui Paulo if (wpas == None): 1325b9c547cSRui Paulo return None 1335b9c547cSRui Paulo return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " + 1345b9c547cSRui Paulo str(req).encode("hex") + " " + 1355b9c547cSRui Paulo str(sel).encode("hex")) 1365b9c547cSRui Paulo 1375b9c547cSRui Paulo 1385b9c547cSRui Pauloclass HandoverServer(nfc.handover.HandoverServer): 1395b9c547cSRui Paulo def __init__(self, llc): 1405b9c547cSRui Paulo super(HandoverServer, self).__init__(llc) 1415b9c547cSRui Paulo self.sent_carrier = None 1425b9c547cSRui Paulo self.ho_server_processing = False 1435b9c547cSRui Paulo self.success = False 1445b9c547cSRui Paulo 1455b9c547cSRui Paulo # override to avoid parser error in request/response.pretty() in nfcpy 1465b9c547cSRui Paulo # due to new WSC handover format 1475b9c547cSRui Paulo def _process_request(self, request): 1485b9c547cSRui Paulo summary("received handover request {}".format(request.type)) 1495b9c547cSRui Paulo response = nfc.ndef.Message("\xd1\x02\x01Hs\x12") 1505b9c547cSRui Paulo if not request.type == 'urn:nfc:wkt:Hr': 1515b9c547cSRui Paulo summary("not a handover request") 1525b9c547cSRui Paulo else: 1535b9c547cSRui Paulo try: 1545b9c547cSRui Paulo request = nfc.ndef.HandoverRequestMessage(request) 1555b9c547cSRui Paulo except nfc.ndef.DecodeError as e: 1565b9c547cSRui Paulo summary("error decoding 'Hr' message: {}".format(e)) 1575b9c547cSRui Paulo else: 1585b9c547cSRui Paulo response = self.process_request(request) 1595b9c547cSRui Paulo summary("send handover response {}".format(response.type)) 1605b9c547cSRui Paulo return response 1615b9c547cSRui Paulo 1625b9c547cSRui Paulo def process_request(self, request): 1635b9c547cSRui Paulo self.ho_server_processing = True 1645b9c547cSRui Paulo summary("HandoverServer - request received") 1655b9c547cSRui Paulo try: 166*4bc52338SCy Schubert print("Parsed handover request: " + request.pretty()) 167*4bc52338SCy Schubert except Exception as e: 168*4bc52338SCy Schubert print(e) 1695b9c547cSRui Paulo 1705b9c547cSRui Paulo sel = nfc.ndef.HandoverSelectMessage(version="1.2") 1715b9c547cSRui Paulo 1725b9c547cSRui Paulo for carrier in request.carriers: 173*4bc52338SCy Schubert print("Remote carrier type: " + carrier.type) 1745b9c547cSRui Paulo if carrier.type == "application/vnd.wfa.wsc": 1755b9c547cSRui Paulo summary("WPS carrier type match - add WPS carrier record") 1765b9c547cSRui Paulo data = wpas_get_handover_sel(self.uuid) 1775b9c547cSRui Paulo if data is None: 1785b9c547cSRui Paulo summary("Could not get handover select carrier record from wpa_supplicant") 1795b9c547cSRui Paulo continue 180*4bc52338SCy Schubert print("Handover select carrier record from wpa_supplicant:") 181*4bc52338SCy Schubert print(data.encode("hex")) 1825b9c547cSRui Paulo self.sent_carrier = data 1835b9c547cSRui Paulo if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"): 1845b9c547cSRui Paulo success_report("Handover reported successfully (responder)") 1855b9c547cSRui Paulo else: 1865b9c547cSRui Paulo summary("Handover report rejected (responder)") 1875b9c547cSRui Paulo 1885b9c547cSRui Paulo message = nfc.ndef.Message(data); 1895b9c547cSRui Paulo sel.add_carrier(message[0], "active", message[1:]) 1905b9c547cSRui Paulo 191*4bc52338SCy Schubert print("Handover select:") 1925b9c547cSRui Paulo try: 193*4bc52338SCy Schubert print(sel.pretty()) 194*4bc52338SCy Schubert except Exception as e: 195*4bc52338SCy Schubert print(e) 196*4bc52338SCy Schubert print(str(sel).encode("hex")) 1975b9c547cSRui Paulo 1985b9c547cSRui Paulo summary("Sending handover select") 1995b9c547cSRui Paulo self.success = True 2005b9c547cSRui Paulo return sel 2015b9c547cSRui Paulo 2025b9c547cSRui Paulo 2035b9c547cSRui Paulodef wps_handover_init(llc): 2045b9c547cSRui Paulo summary("Trying to initiate WPS handover") 205f05cddf9SRui Paulo 206f05cddf9SRui Paulo data = wpas_get_handover_req() 207f05cddf9SRui Paulo if (data == None): 2085b9c547cSRui Paulo summary("Could not get handover request carrier record from wpa_supplicant") 209f05cddf9SRui Paulo return 210*4bc52338SCy Schubert print("Handover request carrier record from wpa_supplicant: " + data.encode("hex")) 211f05cddf9SRui Paulo 2125b9c547cSRui Paulo message = nfc.ndef.HandoverRequestMessage(version="1.2") 2135b9c547cSRui Paulo message.nonce = random.randint(0, 0xffff) 2145b9c547cSRui Paulo datamsg = nfc.ndef.Message(data) 2155b9c547cSRui Paulo message.add_carrier(datamsg[0], "active", datamsg[1:]) 216f05cddf9SRui Paulo 217*4bc52338SCy Schubert print("Handover request:") 218f05cddf9SRui Paulo try: 219*4bc52338SCy Schubert print(message.pretty()) 220*4bc52338SCy Schubert except Exception as e: 221*4bc52338SCy Schubert print(e) 222*4bc52338SCy Schubert print(str(message).encode("hex")) 2235b9c547cSRui Paulo 2245b9c547cSRui Paulo client = nfc.handover.HandoverClient(llc) 2255b9c547cSRui Paulo try: 2265b9c547cSRui Paulo summary("Trying to initiate NFC connection handover") 227f05cddf9SRui Paulo client.connect() 2285b9c547cSRui Paulo summary("Connected for handover") 229f05cddf9SRui Paulo except nfc.llcp.ConnectRefused: 2305b9c547cSRui Paulo summary("Handover connection refused") 2315b9c547cSRui Paulo client.close() 2325b9c547cSRui Paulo return 233*4bc52338SCy Schubert except Exception as e: 2345b9c547cSRui Paulo summary("Other exception: " + str(e)) 235f05cddf9SRui Paulo client.close() 236f05cddf9SRui Paulo return 237f05cddf9SRui Paulo 2385b9c547cSRui Paulo summary("Sending handover request") 239f05cddf9SRui Paulo 240f05cddf9SRui Paulo if not client.send(message): 2415b9c547cSRui Paulo summary("Failed to send handover request") 2425b9c547cSRui Paulo client.close() 2435b9c547cSRui Paulo return 244f05cddf9SRui Paulo 2455b9c547cSRui Paulo summary("Receiving handover response") 246f05cddf9SRui Paulo message = client._recv() 2475b9c547cSRui Paulo if message is None: 2485b9c547cSRui Paulo summary("No response received") 2495b9c547cSRui Paulo client.close() 2505b9c547cSRui Paulo return 2515b9c547cSRui Paulo if message.type != "urn:nfc:wkt:Hs": 2525b9c547cSRui Paulo summary("Response was not Hs - received: " + message.type) 2535b9c547cSRui Paulo client.close() 2545b9c547cSRui Paulo return 2555b9c547cSRui Paulo 256*4bc52338SCy Schubert print("Received message") 2575b9c547cSRui Paulo try: 258*4bc52338SCy Schubert print(message.pretty()) 259*4bc52338SCy Schubert except Exception as e: 260*4bc52338SCy Schubert print(e) 261*4bc52338SCy Schubert print(str(message).encode("hex")) 2625b9c547cSRui Paulo message = nfc.ndef.HandoverSelectMessage(message) 2635b9c547cSRui Paulo summary("Handover select received") 2645b9c547cSRui Paulo try: 265*4bc52338SCy Schubert print(message.pretty()) 266*4bc52338SCy Schubert except Exception as e: 267*4bc52338SCy Schubert print(e) 2685b9c547cSRui Paulo 2695b9c547cSRui Paulo for carrier in message.carriers: 270*4bc52338SCy Schubert print("Remote carrier type: " + carrier.type) 2715b9c547cSRui Paulo if carrier.type == "application/vnd.wfa.wsc": 272*4bc52338SCy Schubert print("WPS carrier type match - send to wpa_supplicant") 2735b9c547cSRui Paulo if "OK" in wpas_report_handover(data, carrier.record, "INIT"): 2745b9c547cSRui Paulo success_report("Handover reported successfully (initiator)") 2755b9c547cSRui Paulo else: 2765b9c547cSRui Paulo summary("Handover report rejected (initiator)") 2775b9c547cSRui Paulo # nfcpy does not support the new format.. 2785b9c547cSRui Paulo #wifi = nfc.ndef.WifiConfigRecord(carrier.record) 2795b9c547cSRui Paulo #print wifi.pretty() 280f05cddf9SRui Paulo 281*4bc52338SCy Schubert print("Remove peer") 282f05cddf9SRui Paulo client.close() 283*4bc52338SCy Schubert print("Done with handover") 2845b9c547cSRui Paulo global only_one 2855b9c547cSRui Paulo if only_one: 2865b9c547cSRui Paulo global continue_loop 2875b9c547cSRui Paulo continue_loop = False 288f05cddf9SRui Paulo 2895b9c547cSRui Paulo global no_wait 2905b9c547cSRui Paulo if no_wait: 291*4bc52338SCy Schubert print("Trying to exit..") 2925b9c547cSRui Paulo global terminate_now 2935b9c547cSRui Paulo terminate_now = True 294f05cddf9SRui Paulo 2955b9c547cSRui Paulodef wps_tag_read(tag, wait_remove=True): 2965b9c547cSRui Paulo success = False 297f05cddf9SRui Paulo if len(tag.ndef.message): 2985b9c547cSRui Paulo for record in tag.ndef.message: 299*4bc52338SCy Schubert print("record type " + record.type) 300f05cddf9SRui Paulo if record.type == "application/vnd.wfa.wsc": 3015b9c547cSRui Paulo summary("WPS tag - send to wpa_supplicant") 3025b9c547cSRui Paulo success = wpas_tag_read(tag.ndef.message) 303f05cddf9SRui Paulo break 304f05cddf9SRui Paulo else: 3055b9c547cSRui Paulo summary("Empty tag") 306f05cddf9SRui Paulo 3075b9c547cSRui Paulo if success: 3085b9c547cSRui Paulo success_report("Tag read succeeded") 3095b9c547cSRui Paulo 3105b9c547cSRui Paulo if wait_remove: 311*4bc52338SCy Schubert print("Remove tag") 312f05cddf9SRui Paulo while tag.is_present: 313f05cddf9SRui Paulo time.sleep(0.1) 314f05cddf9SRui Paulo 3155b9c547cSRui Paulo return success 3165b9c547cSRui Paulo 3175b9c547cSRui Paulo 3185b9c547cSRui Paulodef rdwr_connected_write(tag): 3195b9c547cSRui Paulo summary("Tag found - writing - " + str(tag)) 3205b9c547cSRui Paulo global write_data 3215b9c547cSRui Paulo tag.ndef.message = str(write_data) 3225b9c547cSRui Paulo success_report("Tag write succeeded") 323*4bc52338SCy Schubert print("Done - remove tag") 3245b9c547cSRui Paulo global only_one 3255b9c547cSRui Paulo if only_one: 3265b9c547cSRui Paulo global continue_loop 3275b9c547cSRui Paulo continue_loop = False 3285b9c547cSRui Paulo global write_wait_remove 3295b9c547cSRui Paulo while write_wait_remove and tag.is_present: 3305b9c547cSRui Paulo time.sleep(0.1) 3315b9c547cSRui Paulo 3325b9c547cSRui Paulodef wps_write_config_tag(clf, id=None, wait_remove=True): 333*4bc52338SCy Schubert print("Write WPS config token") 3345b9c547cSRui Paulo global write_data, write_wait_remove 3355b9c547cSRui Paulo write_wait_remove = wait_remove 3365b9c547cSRui Paulo write_data = wpas_get_config_token(id) 3375b9c547cSRui Paulo if write_data == None: 338*4bc52338SCy Schubert print("Could not get WPS config token from wpa_supplicant") 3395b9c547cSRui Paulo sys.exit(1) 3405b9c547cSRui Paulo return 341*4bc52338SCy Schubert print("Touch an NFC tag") 3425b9c547cSRui Paulo clf.connect(rdwr={'on-connect': rdwr_connected_write}) 3435b9c547cSRui Paulo 3445b9c547cSRui Paulo 3455b9c547cSRui Paulodef wps_write_er_config_tag(clf, uuid, wait_remove=True): 346*4bc52338SCy Schubert print("Write WPS ER config token") 3475b9c547cSRui Paulo global write_data, write_wait_remove 3485b9c547cSRui Paulo write_wait_remove = wait_remove 3495b9c547cSRui Paulo write_data = wpas_get_er_config_token(uuid) 3505b9c547cSRui Paulo if write_data == None: 351*4bc52338SCy Schubert print("Could not get WPS config token from wpa_supplicant") 3525b9c547cSRui Paulo return 3535b9c547cSRui Paulo 354*4bc52338SCy Schubert print("Touch an NFC tag") 3555b9c547cSRui Paulo clf.connect(rdwr={'on-connect': rdwr_connected_write}) 3565b9c547cSRui Paulo 3575b9c547cSRui Paulo 3585b9c547cSRui Paulodef wps_write_password_tag(clf, wait_remove=True): 359*4bc52338SCy Schubert print("Write WPS password token") 3605b9c547cSRui Paulo global write_data, write_wait_remove 3615b9c547cSRui Paulo write_wait_remove = wait_remove 3625b9c547cSRui Paulo write_data = wpas_get_password_token() 3635b9c547cSRui Paulo if write_data == None: 364*4bc52338SCy Schubert print("Could not get WPS password token from wpa_supplicant") 3655b9c547cSRui Paulo return 3665b9c547cSRui Paulo 367*4bc52338SCy Schubert print("Touch an NFC tag") 3685b9c547cSRui Paulo clf.connect(rdwr={'on-connect': rdwr_connected_write}) 3695b9c547cSRui Paulo 3705b9c547cSRui Paulo 3715b9c547cSRui Paulodef rdwr_connected(tag): 3725b9c547cSRui Paulo global only_one, no_wait 3735b9c547cSRui Paulo summary("Tag connected: " + str(tag)) 3745b9c547cSRui Paulo 3755b9c547cSRui Paulo if tag.ndef: 376*4bc52338SCy Schubert print("NDEF tag: " + tag.type) 3775b9c547cSRui Paulo try: 378*4bc52338SCy Schubert print(tag.ndef.message.pretty()) 379*4bc52338SCy Schubert except Exception as e: 380*4bc52338SCy Schubert print(e) 3815b9c547cSRui Paulo success = wps_tag_read(tag, not only_one) 3825b9c547cSRui Paulo if only_one and success: 3835b9c547cSRui Paulo global continue_loop 3845b9c547cSRui Paulo continue_loop = False 3855b9c547cSRui Paulo else: 3865b9c547cSRui Paulo summary("Not an NDEF tag - remove tag") 3875b9c547cSRui Paulo return True 3885b9c547cSRui Paulo 3895b9c547cSRui Paulo return not no_wait 3905b9c547cSRui Paulo 3915b9c547cSRui Paulo 3925b9c547cSRui Paulodef llcp_worker(llc): 3935b9c547cSRui Paulo global arg_uuid 3945b9c547cSRui Paulo if arg_uuid is None: 3955b9c547cSRui Paulo wps_handover_init(llc) 396*4bc52338SCy Schubert print("Exiting llcp_worker thread") 3975b9c547cSRui Paulo return 3985b9c547cSRui Paulo 3995b9c547cSRui Paulo global srv 4005b9c547cSRui Paulo global wait_connection 4015b9c547cSRui Paulo while not wait_connection and srv.sent_carrier is None: 4025b9c547cSRui Paulo if srv.ho_server_processing: 4035b9c547cSRui Paulo time.sleep(0.025) 4045b9c547cSRui Paulo 4055b9c547cSRui Paulodef llcp_startup(clf, llc): 4065b9c547cSRui Paulo global arg_uuid 4075b9c547cSRui Paulo if arg_uuid: 408*4bc52338SCy Schubert print("Start LLCP server") 4095b9c547cSRui Paulo global srv 4105b9c547cSRui Paulo srv = HandoverServer(llc) 4115b9c547cSRui Paulo if arg_uuid is "ap": 412*4bc52338SCy Schubert print("Trying to handle WPS handover") 4135b9c547cSRui Paulo srv.uuid = None 4145b9c547cSRui Paulo else: 415*4bc52338SCy Schubert print("Trying to handle WPS handover with AP " + arg_uuid) 4165b9c547cSRui Paulo srv.uuid = arg_uuid 4175b9c547cSRui Paulo return llc 4185b9c547cSRui Paulo 4195b9c547cSRui Paulodef llcp_connected(llc): 420*4bc52338SCy Schubert print("P2P LLCP connected") 4215b9c547cSRui Paulo global wait_connection 4225b9c547cSRui Paulo wait_connection = False 4235b9c547cSRui Paulo global arg_uuid 4245b9c547cSRui Paulo if arg_uuid: 4255b9c547cSRui Paulo global srv 4265b9c547cSRui Paulo srv.start() 4275b9c547cSRui Paulo else: 4285b9c547cSRui Paulo threading.Thread(target=llcp_worker, args=(llc,)).start() 429*4bc52338SCy Schubert print("llcp_connected returning") 4305b9c547cSRui Paulo return True 4315b9c547cSRui Paulo 4325b9c547cSRui Paulo 4335b9c547cSRui Paulodef terminate_loop(): 4345b9c547cSRui Paulo global terminate_now 4355b9c547cSRui Paulo return terminate_now 436f05cddf9SRui Paulo 437f05cddf9SRui Paulodef main(): 438f05cddf9SRui Paulo clf = nfc.ContactlessFrontend() 439f05cddf9SRui Paulo 4405b9c547cSRui Paulo parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for WPS NFC operations') 4415b9c547cSRui Paulo parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO, 4425b9c547cSRui Paulo action='store_const', dest='loglevel', 4435b9c547cSRui Paulo help='verbose debug output') 4445b9c547cSRui Paulo parser.add_argument('-q', const=logging.WARNING, action='store_const', 4455b9c547cSRui Paulo dest='loglevel', help='be quiet') 4465b9c547cSRui Paulo parser.add_argument('--only-one', '-1', action='store_true', 4475b9c547cSRui Paulo help='run only one operation and exit') 4485b9c547cSRui Paulo parser.add_argument('--no-wait', action='store_true', 4495b9c547cSRui Paulo help='do not wait for tag to be removed before exiting') 4505b9c547cSRui Paulo parser.add_argument('--uuid', 4515b9c547cSRui Paulo help='UUID of an AP (used for WPS ER operations)') 4525b9c547cSRui Paulo parser.add_argument('--id', 4535b9c547cSRui Paulo help='network id (used for WPS ER operations)') 4545b9c547cSRui Paulo parser.add_argument('--summary', 4555b9c547cSRui Paulo help='summary file for writing status updates') 4565b9c547cSRui Paulo parser.add_argument('--success', 4575b9c547cSRui Paulo help='success file for writing success update') 4585b9c547cSRui Paulo parser.add_argument('command', choices=['write-config', 4595b9c547cSRui Paulo 'write-er-config', 4605b9c547cSRui Paulo 'write-password'], 4615b9c547cSRui Paulo nargs='?') 4625b9c547cSRui Paulo args = parser.parse_args() 4635b9c547cSRui Paulo 4645b9c547cSRui Paulo global arg_uuid 4655b9c547cSRui Paulo arg_uuid = args.uuid 4665b9c547cSRui Paulo 4675b9c547cSRui Paulo global only_one 4685b9c547cSRui Paulo only_one = args.only_one 4695b9c547cSRui Paulo 4705b9c547cSRui Paulo global no_wait 4715b9c547cSRui Paulo no_wait = args.no_wait 4725b9c547cSRui Paulo 4735b9c547cSRui Paulo if args.summary: 4745b9c547cSRui Paulo global summary_file 4755b9c547cSRui Paulo summary_file = args.summary 4765b9c547cSRui Paulo 4775b9c547cSRui Paulo if args.success: 4785b9c547cSRui Paulo global success_file 4795b9c547cSRui Paulo success_file = args.success 4805b9c547cSRui Paulo 4815b9c547cSRui Paulo logging.basicConfig(level=args.loglevel) 4825b9c547cSRui Paulo 483f05cddf9SRui Paulo try: 4845b9c547cSRui Paulo if not clf.open("usb"): 485*4bc52338SCy Schubert print("Could not open connection with an NFC device") 4865b9c547cSRui Paulo raise SystemExit 4875b9c547cSRui Paulo 4885b9c547cSRui Paulo if args.command == "write-config": 4895b9c547cSRui Paulo wps_write_config_tag(clf, id=args.id, wait_remove=not args.no_wait) 4905b9c547cSRui Paulo raise SystemExit 4915b9c547cSRui Paulo 4925b9c547cSRui Paulo if args.command == "write-er-config": 4935b9c547cSRui Paulo wps_write_er_config_tag(clf, args.uuid, wait_remove=not args.no_wait) 4945b9c547cSRui Paulo raise SystemExit 4955b9c547cSRui Paulo 4965b9c547cSRui Paulo if args.command == "write-password": 4975b9c547cSRui Paulo wps_write_password_tag(clf, wait_remove=not args.no_wait) 4985b9c547cSRui Paulo raise SystemExit 4995b9c547cSRui Paulo 5005b9c547cSRui Paulo global continue_loop 5015b9c547cSRui Paulo while continue_loop: 502*4bc52338SCy Schubert print("Waiting for a tag or peer to be touched") 5035b9c547cSRui Paulo wait_connection = True 5045b9c547cSRui Paulo try: 5055b9c547cSRui Paulo if not clf.connect(rdwr={'on-connect': rdwr_connected}, 5065b9c547cSRui Paulo llcp={'on-startup': llcp_startup, 5075b9c547cSRui Paulo 'on-connect': llcp_connected}, 5085b9c547cSRui Paulo terminate=terminate_loop): 509f05cddf9SRui Paulo break 510*4bc52338SCy Schubert except Exception as e: 511*4bc52338SCy Schubert print("clf.connect failed") 512f05cddf9SRui Paulo 5135b9c547cSRui Paulo global srv 5145b9c547cSRui Paulo if only_one and srv and srv.success: 5155b9c547cSRui Paulo raise SystemExit 516f05cddf9SRui Paulo 517f05cddf9SRui Paulo except KeyboardInterrupt: 518f05cddf9SRui Paulo raise SystemExit 519f05cddf9SRui Paulo finally: 520f05cddf9SRui Paulo clf.close() 521f05cddf9SRui Paulo 522f05cddf9SRui Paulo raise SystemExit 523f05cddf9SRui Paulo 524f05cddf9SRui Pauloif __name__ == '__main__': 525f05cddf9SRui Paulo main() 526