1*03f9172cSAndroid Build Coastguard Worker#!/usr/bin/python 2*03f9172cSAndroid Build Coastguard Worker# 3*03f9172cSAndroid Build Coastguard Worker# Example nfcpy to hostapd wrapper for WPS NFC operations 4*03f9172cSAndroid Build Coastguard Worker# Copyright (c) 2012-2013, Jouni Malinen <[email protected]> 5*03f9172cSAndroid Build Coastguard Worker# 6*03f9172cSAndroid Build Coastguard Worker# This software may be distributed under the terms of the BSD license. 7*03f9172cSAndroid Build Coastguard Worker# See README for more details. 8*03f9172cSAndroid Build Coastguard Worker 9*03f9172cSAndroid Build Coastguard Workerimport os 10*03f9172cSAndroid Build Coastguard Workerimport sys 11*03f9172cSAndroid Build Coastguard Workerimport time 12*03f9172cSAndroid Build Coastguard Workerimport argparse 13*03f9172cSAndroid Build Coastguard Worker 14*03f9172cSAndroid Build Coastguard Workerimport nfc 15*03f9172cSAndroid Build Coastguard Workerimport nfc.ndef 16*03f9172cSAndroid Build Coastguard Workerimport nfc.llcp 17*03f9172cSAndroid Build Coastguard Workerimport nfc.handover 18*03f9172cSAndroid Build Coastguard Worker 19*03f9172cSAndroid Build Coastguard Workerimport logging 20*03f9172cSAndroid Build Coastguard Worker 21*03f9172cSAndroid Build Coastguard Workerimport wpaspy 22*03f9172cSAndroid Build Coastguard Worker 23*03f9172cSAndroid Build Coastguard Workerwpas_ctrl = '/var/run/hostapd' 24*03f9172cSAndroid Build Coastguard Workercontinue_loop = True 25*03f9172cSAndroid Build Coastguard Workersummary_file = None 26*03f9172cSAndroid Build Coastguard Workersuccess_file = None 27*03f9172cSAndroid Build Coastguard Worker 28*03f9172cSAndroid Build Coastguard Workerdef summary(txt): 29*03f9172cSAndroid Build Coastguard Worker print(txt) 30*03f9172cSAndroid Build Coastguard Worker if summary_file: 31*03f9172cSAndroid Build Coastguard Worker with open(summary_file, 'a') as f: 32*03f9172cSAndroid Build Coastguard Worker f.write(txt + "\n") 33*03f9172cSAndroid Build Coastguard Worker 34*03f9172cSAndroid Build Coastguard Workerdef success_report(txt): 35*03f9172cSAndroid Build Coastguard Worker summary(txt) 36*03f9172cSAndroid Build Coastguard Worker if success_file: 37*03f9172cSAndroid Build Coastguard Worker with open(success_file, 'a') as f: 38*03f9172cSAndroid Build Coastguard Worker f.write(txt + "\n") 39*03f9172cSAndroid Build Coastguard Worker 40*03f9172cSAndroid Build Coastguard Workerdef wpas_connect(): 41*03f9172cSAndroid Build Coastguard Worker ifaces = [] 42*03f9172cSAndroid Build Coastguard Worker if os.path.isdir(wpas_ctrl): 43*03f9172cSAndroid Build Coastguard Worker try: 44*03f9172cSAndroid Build Coastguard Worker ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 45*03f9172cSAndroid Build Coastguard Worker except OSError as error: 46*03f9172cSAndroid Build Coastguard Worker print("Could not find hostapd: ", error) 47*03f9172cSAndroid Build Coastguard Worker return None 48*03f9172cSAndroid Build Coastguard Worker 49*03f9172cSAndroid Build Coastguard Worker if len(ifaces) < 1: 50*03f9172cSAndroid Build Coastguard Worker print("No hostapd control interface found") 51*03f9172cSAndroid Build Coastguard Worker return None 52*03f9172cSAndroid Build Coastguard Worker 53*03f9172cSAndroid Build Coastguard Worker for ctrl in ifaces: 54*03f9172cSAndroid Build Coastguard Worker try: 55*03f9172cSAndroid Build Coastguard Worker wpas = wpaspy.Ctrl(ctrl) 56*03f9172cSAndroid Build Coastguard Worker return wpas 57*03f9172cSAndroid Build Coastguard Worker except Exception as e: 58*03f9172cSAndroid Build Coastguard Worker pass 59*03f9172cSAndroid Build Coastguard Worker return None 60*03f9172cSAndroid Build Coastguard Worker 61*03f9172cSAndroid Build Coastguard Worker 62*03f9172cSAndroid Build Coastguard Workerdef wpas_tag_read(message): 63*03f9172cSAndroid Build Coastguard Worker wpas = wpas_connect() 64*03f9172cSAndroid Build Coastguard Worker if (wpas == None): 65*03f9172cSAndroid Build Coastguard Worker return False 66*03f9172cSAndroid Build Coastguard Worker if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")): 67*03f9172cSAndroid Build Coastguard Worker return False 68*03f9172cSAndroid Build Coastguard Worker return True 69*03f9172cSAndroid Build Coastguard Worker 70*03f9172cSAndroid Build Coastguard Worker 71*03f9172cSAndroid Build Coastguard Workerdef wpas_get_config_token(): 72*03f9172cSAndroid Build Coastguard Worker wpas = wpas_connect() 73*03f9172cSAndroid Build Coastguard Worker if (wpas == None): 74*03f9172cSAndroid Build Coastguard Worker return None 75*03f9172cSAndroid Build Coastguard Worker ret = wpas.request("WPS_NFC_CONFIG_TOKEN NDEF") 76*03f9172cSAndroid Build Coastguard Worker if "FAIL" in ret: 77*03f9172cSAndroid Build Coastguard Worker return None 78*03f9172cSAndroid Build Coastguard Worker return ret.rstrip().decode("hex") 79*03f9172cSAndroid Build Coastguard Worker 80*03f9172cSAndroid Build Coastguard Worker 81*03f9172cSAndroid Build Coastguard Workerdef wpas_get_password_token(): 82*03f9172cSAndroid Build Coastguard Worker wpas = wpas_connect() 83*03f9172cSAndroid Build Coastguard Worker if (wpas == None): 84*03f9172cSAndroid Build Coastguard Worker return None 85*03f9172cSAndroid Build Coastguard Worker ret = wpas.request("WPS_NFC_TOKEN NDEF") 86*03f9172cSAndroid Build Coastguard Worker if "FAIL" in ret: 87*03f9172cSAndroid Build Coastguard Worker return None 88*03f9172cSAndroid Build Coastguard Worker return ret.rstrip().decode("hex") 89*03f9172cSAndroid Build Coastguard Worker 90*03f9172cSAndroid Build Coastguard Worker 91*03f9172cSAndroid Build Coastguard Workerdef wpas_get_handover_sel(): 92*03f9172cSAndroid Build Coastguard Worker wpas = wpas_connect() 93*03f9172cSAndroid Build Coastguard Worker if (wpas == None): 94*03f9172cSAndroid Build Coastguard Worker return None 95*03f9172cSAndroid Build Coastguard Worker ret = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR") 96*03f9172cSAndroid Build Coastguard Worker if "FAIL" in ret: 97*03f9172cSAndroid Build Coastguard Worker return None 98*03f9172cSAndroid Build Coastguard Worker return ret.rstrip().decode("hex") 99*03f9172cSAndroid Build Coastguard Worker 100*03f9172cSAndroid Build Coastguard Worker 101*03f9172cSAndroid Build Coastguard Workerdef wpas_report_handover(req, sel): 102*03f9172cSAndroid Build Coastguard Worker wpas = wpas_connect() 103*03f9172cSAndroid Build Coastguard Worker if (wpas == None): 104*03f9172cSAndroid Build Coastguard Worker return None 105*03f9172cSAndroid Build Coastguard Worker return wpas.request("NFC_REPORT_HANDOVER RESP WPS " + 106*03f9172cSAndroid Build Coastguard Worker str(req).encode("hex") + " " + 107*03f9172cSAndroid Build Coastguard Worker str(sel).encode("hex")) 108*03f9172cSAndroid Build Coastguard Worker 109*03f9172cSAndroid Build Coastguard Worker 110*03f9172cSAndroid Build Coastguard Workerclass HandoverServer(nfc.handover.HandoverServer): 111*03f9172cSAndroid Build Coastguard Worker def __init__(self, llc): 112*03f9172cSAndroid Build Coastguard Worker super(HandoverServer, self).__init__(llc) 113*03f9172cSAndroid Build Coastguard Worker self.ho_server_processing = False 114*03f9172cSAndroid Build Coastguard Worker self.success = False 115*03f9172cSAndroid Build Coastguard Worker 116*03f9172cSAndroid Build Coastguard Worker # override to avoid parser error in request/response.pretty() in nfcpy 117*03f9172cSAndroid Build Coastguard Worker # due to new WSC handover format 118*03f9172cSAndroid Build Coastguard Worker def _process_request(self, request): 119*03f9172cSAndroid Build Coastguard Worker summary("received handover request {}".format(request.type)) 120*03f9172cSAndroid Build Coastguard Worker response = nfc.ndef.Message("\xd1\x02\x01Hs\x12") 121*03f9172cSAndroid Build Coastguard Worker if not request.type == 'urn:nfc:wkt:Hr': 122*03f9172cSAndroid Build Coastguard Worker summary("not a handover request") 123*03f9172cSAndroid Build Coastguard Worker else: 124*03f9172cSAndroid Build Coastguard Worker try: 125*03f9172cSAndroid Build Coastguard Worker request = nfc.ndef.HandoverRequestMessage(request) 126*03f9172cSAndroid Build Coastguard Worker except nfc.ndef.DecodeError as e: 127*03f9172cSAndroid Build Coastguard Worker summary("error decoding 'Hr' message: {}".format(e)) 128*03f9172cSAndroid Build Coastguard Worker else: 129*03f9172cSAndroid Build Coastguard Worker response = self.process_request(request) 130*03f9172cSAndroid Build Coastguard Worker summary("send handover response {}".format(response.type)) 131*03f9172cSAndroid Build Coastguard Worker return response 132*03f9172cSAndroid Build Coastguard Worker 133*03f9172cSAndroid Build Coastguard Worker def process_request(self, request): 134*03f9172cSAndroid Build Coastguard Worker summary("HandoverServer - request received") 135*03f9172cSAndroid Build Coastguard Worker try: 136*03f9172cSAndroid Build Coastguard Worker print("Parsed handover request: " + request.pretty()) 137*03f9172cSAndroid Build Coastguard Worker except Exception as e: 138*03f9172cSAndroid Build Coastguard Worker print(e) 139*03f9172cSAndroid Build Coastguard Worker print(str(request).encode("hex")) 140*03f9172cSAndroid Build Coastguard Worker 141*03f9172cSAndroid Build Coastguard Worker sel = nfc.ndef.HandoverSelectMessage(version="1.2") 142*03f9172cSAndroid Build Coastguard Worker 143*03f9172cSAndroid Build Coastguard Worker for carrier in request.carriers: 144*03f9172cSAndroid Build Coastguard Worker print("Remote carrier type: " + carrier.type) 145*03f9172cSAndroid Build Coastguard Worker if carrier.type == "application/vnd.wfa.wsc": 146*03f9172cSAndroid Build Coastguard Worker summary("WPS carrier type match - add WPS carrier record") 147*03f9172cSAndroid Build Coastguard Worker data = wpas_get_handover_sel() 148*03f9172cSAndroid Build Coastguard Worker if data is None: 149*03f9172cSAndroid Build Coastguard Worker summary("Could not get handover select carrier record from hostapd") 150*03f9172cSAndroid Build Coastguard Worker continue 151*03f9172cSAndroid Build Coastguard Worker print("Handover select carrier record from hostapd:") 152*03f9172cSAndroid Build Coastguard Worker print(data.encode("hex")) 153*03f9172cSAndroid Build Coastguard Worker if "OK" in wpas_report_handover(carrier.record, data): 154*03f9172cSAndroid Build Coastguard Worker success_report("Handover reported successfully") 155*03f9172cSAndroid Build Coastguard Worker else: 156*03f9172cSAndroid Build Coastguard Worker summary("Handover report rejected") 157*03f9172cSAndroid Build Coastguard Worker 158*03f9172cSAndroid Build Coastguard Worker message = nfc.ndef.Message(data); 159*03f9172cSAndroid Build Coastguard Worker sel.add_carrier(message[0], "active", message[1:]) 160*03f9172cSAndroid Build Coastguard Worker 161*03f9172cSAndroid Build Coastguard Worker print("Handover select:") 162*03f9172cSAndroid Build Coastguard Worker try: 163*03f9172cSAndroid Build Coastguard Worker print(sel.pretty()) 164*03f9172cSAndroid Build Coastguard Worker except Exception as e: 165*03f9172cSAndroid Build Coastguard Worker print(e) 166*03f9172cSAndroid Build Coastguard Worker print(str(sel).encode("hex")) 167*03f9172cSAndroid Build Coastguard Worker 168*03f9172cSAndroid Build Coastguard Worker summary("Sending handover select") 169*03f9172cSAndroid Build Coastguard Worker self.success = True 170*03f9172cSAndroid Build Coastguard Worker return sel 171*03f9172cSAndroid Build Coastguard Worker 172*03f9172cSAndroid Build Coastguard Worker 173*03f9172cSAndroid Build Coastguard Workerdef wps_tag_read(tag): 174*03f9172cSAndroid Build Coastguard Worker success = False 175*03f9172cSAndroid Build Coastguard Worker if len(tag.ndef.message): 176*03f9172cSAndroid Build Coastguard Worker for record in tag.ndef.message: 177*03f9172cSAndroid Build Coastguard Worker print("record type " + record.type) 178*03f9172cSAndroid Build Coastguard Worker if record.type == "application/vnd.wfa.wsc": 179*03f9172cSAndroid Build Coastguard Worker summary("WPS tag - send to hostapd") 180*03f9172cSAndroid Build Coastguard Worker success = wpas_tag_read(tag.ndef.message) 181*03f9172cSAndroid Build Coastguard Worker break 182*03f9172cSAndroid Build Coastguard Worker else: 183*03f9172cSAndroid Build Coastguard Worker summary("Empty tag") 184*03f9172cSAndroid Build Coastguard Worker 185*03f9172cSAndroid Build Coastguard Worker if success: 186*03f9172cSAndroid Build Coastguard Worker success_report("Tag read succeeded") 187*03f9172cSAndroid Build Coastguard Worker 188*03f9172cSAndroid Build Coastguard Worker return success 189*03f9172cSAndroid Build Coastguard Worker 190*03f9172cSAndroid Build Coastguard Worker 191*03f9172cSAndroid Build Coastguard Workerdef rdwr_connected_write(tag): 192*03f9172cSAndroid Build Coastguard Worker summary("Tag found - writing - " + str(tag)) 193*03f9172cSAndroid Build Coastguard Worker global write_data 194*03f9172cSAndroid Build Coastguard Worker tag.ndef.message = str(write_data) 195*03f9172cSAndroid Build Coastguard Worker success_report("Tag write succeeded") 196*03f9172cSAndroid Build Coastguard Worker print("Done - remove tag") 197*03f9172cSAndroid Build Coastguard Worker global only_one 198*03f9172cSAndroid Build Coastguard Worker if only_one: 199*03f9172cSAndroid Build Coastguard Worker global continue_loop 200*03f9172cSAndroid Build Coastguard Worker continue_loop = False 201*03f9172cSAndroid Build Coastguard Worker global write_wait_remove 202*03f9172cSAndroid Build Coastguard Worker while write_wait_remove and tag.is_present: 203*03f9172cSAndroid Build Coastguard Worker time.sleep(0.1) 204*03f9172cSAndroid Build Coastguard Worker 205*03f9172cSAndroid Build Coastguard Workerdef wps_write_config_tag(clf, wait_remove=True): 206*03f9172cSAndroid Build Coastguard Worker summary("Write WPS config token") 207*03f9172cSAndroid Build Coastguard Worker global write_data, write_wait_remove 208*03f9172cSAndroid Build Coastguard Worker write_wait_remove = wait_remove 209*03f9172cSAndroid Build Coastguard Worker write_data = wpas_get_config_token() 210*03f9172cSAndroid Build Coastguard Worker if write_data == None: 211*03f9172cSAndroid Build Coastguard Worker summary("Could not get WPS config token from hostapd") 212*03f9172cSAndroid Build Coastguard Worker return 213*03f9172cSAndroid Build Coastguard Worker 214*03f9172cSAndroid Build Coastguard Worker print("Touch an NFC tag") 215*03f9172cSAndroid Build Coastguard Worker clf.connect(rdwr={'on-connect': rdwr_connected_write}) 216*03f9172cSAndroid Build Coastguard Worker 217*03f9172cSAndroid Build Coastguard Worker 218*03f9172cSAndroid Build Coastguard Workerdef wps_write_password_tag(clf, wait_remove=True): 219*03f9172cSAndroid Build Coastguard Worker summary("Write WPS password token") 220*03f9172cSAndroid Build Coastguard Worker global write_data, write_wait_remove 221*03f9172cSAndroid Build Coastguard Worker write_wait_remove = wait_remove 222*03f9172cSAndroid Build Coastguard Worker write_data = wpas_get_password_token() 223*03f9172cSAndroid Build Coastguard Worker if write_data == None: 224*03f9172cSAndroid Build Coastguard Worker summary("Could not get WPS password token from hostapd") 225*03f9172cSAndroid Build Coastguard Worker return 226*03f9172cSAndroid Build Coastguard Worker 227*03f9172cSAndroid Build Coastguard Worker print("Touch an NFC tag") 228*03f9172cSAndroid Build Coastguard Worker clf.connect(rdwr={'on-connect': rdwr_connected_write}) 229*03f9172cSAndroid Build Coastguard Worker 230*03f9172cSAndroid Build Coastguard Worker 231*03f9172cSAndroid Build Coastguard Workerdef rdwr_connected(tag): 232*03f9172cSAndroid Build Coastguard Worker global only_one, no_wait 233*03f9172cSAndroid Build Coastguard Worker summary("Tag connected: " + str(tag)) 234*03f9172cSAndroid Build Coastguard Worker 235*03f9172cSAndroid Build Coastguard Worker if tag.ndef: 236*03f9172cSAndroid Build Coastguard Worker print("NDEF tag: " + tag.type) 237*03f9172cSAndroid Build Coastguard Worker try: 238*03f9172cSAndroid Build Coastguard Worker print(tag.ndef.message.pretty()) 239*03f9172cSAndroid Build Coastguard Worker except Exception as e: 240*03f9172cSAndroid Build Coastguard Worker print(e) 241*03f9172cSAndroid Build Coastguard Worker success = wps_tag_read(tag) 242*03f9172cSAndroid Build Coastguard Worker if only_one and success: 243*03f9172cSAndroid Build Coastguard Worker global continue_loop 244*03f9172cSAndroid Build Coastguard Worker continue_loop = False 245*03f9172cSAndroid Build Coastguard Worker else: 246*03f9172cSAndroid Build Coastguard Worker summary("Not an NDEF tag - remove tag") 247*03f9172cSAndroid Build Coastguard Worker return True 248*03f9172cSAndroid Build Coastguard Worker 249*03f9172cSAndroid Build Coastguard Worker return not no_wait 250*03f9172cSAndroid Build Coastguard Worker 251*03f9172cSAndroid Build Coastguard Worker 252*03f9172cSAndroid Build Coastguard Workerdef llcp_startup(clf, llc): 253*03f9172cSAndroid Build Coastguard Worker print("Start LLCP server") 254*03f9172cSAndroid Build Coastguard Worker global srv 255*03f9172cSAndroid Build Coastguard Worker srv = HandoverServer(llc) 256*03f9172cSAndroid Build Coastguard Worker return llc 257*03f9172cSAndroid Build Coastguard Worker 258*03f9172cSAndroid Build Coastguard Workerdef llcp_connected(llc): 259*03f9172cSAndroid Build Coastguard Worker print("P2P LLCP connected") 260*03f9172cSAndroid Build Coastguard Worker global wait_connection 261*03f9172cSAndroid Build Coastguard Worker wait_connection = False 262*03f9172cSAndroid Build Coastguard Worker global srv 263*03f9172cSAndroid Build Coastguard Worker srv.start() 264*03f9172cSAndroid Build Coastguard Worker return True 265*03f9172cSAndroid Build Coastguard Worker 266*03f9172cSAndroid Build Coastguard Worker 267*03f9172cSAndroid Build Coastguard Workerdef main(): 268*03f9172cSAndroid Build Coastguard Worker clf = nfc.ContactlessFrontend() 269*03f9172cSAndroid Build Coastguard Worker 270*03f9172cSAndroid Build Coastguard Worker parser = argparse.ArgumentParser(description='nfcpy to hostapd integration for WPS NFC operations') 271*03f9172cSAndroid Build Coastguard Worker parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO, 272*03f9172cSAndroid Build Coastguard Worker action='store_const', dest='loglevel', 273*03f9172cSAndroid Build Coastguard Worker help='verbose debug output') 274*03f9172cSAndroid Build Coastguard Worker parser.add_argument('-q', const=logging.WARNING, action='store_const', 275*03f9172cSAndroid Build Coastguard Worker dest='loglevel', help='be quiet') 276*03f9172cSAndroid Build Coastguard Worker parser.add_argument('--only-one', '-1', action='store_true', 277*03f9172cSAndroid Build Coastguard Worker help='run only one operation and exit') 278*03f9172cSAndroid Build Coastguard Worker parser.add_argument('--no-wait', action='store_true', 279*03f9172cSAndroid Build Coastguard Worker help='do not wait for tag to be removed before exiting') 280*03f9172cSAndroid Build Coastguard Worker parser.add_argument('--summary', 281*03f9172cSAndroid Build Coastguard Worker help='summary file for writing status updates') 282*03f9172cSAndroid Build Coastguard Worker parser.add_argument('--success', 283*03f9172cSAndroid Build Coastguard Worker help='success file for writing success update') 284*03f9172cSAndroid Build Coastguard Worker parser.add_argument('command', choices=['write-config', 285*03f9172cSAndroid Build Coastguard Worker 'write-password'], 286*03f9172cSAndroid Build Coastguard Worker nargs='?') 287*03f9172cSAndroid Build Coastguard Worker args = parser.parse_args() 288*03f9172cSAndroid Build Coastguard Worker 289*03f9172cSAndroid Build Coastguard Worker global only_one 290*03f9172cSAndroid Build Coastguard Worker only_one = args.only_one 291*03f9172cSAndroid Build Coastguard Worker 292*03f9172cSAndroid Build Coastguard Worker global no_wait 293*03f9172cSAndroid Build Coastguard Worker no_wait = args.no_wait 294*03f9172cSAndroid Build Coastguard Worker 295*03f9172cSAndroid Build Coastguard Worker if args.summary: 296*03f9172cSAndroid Build Coastguard Worker global summary_file 297*03f9172cSAndroid Build Coastguard Worker summary_file = args.summary 298*03f9172cSAndroid Build Coastguard Worker 299*03f9172cSAndroid Build Coastguard Worker if args.success: 300*03f9172cSAndroid Build Coastguard Worker global success_file 301*03f9172cSAndroid Build Coastguard Worker success_file = args.success 302*03f9172cSAndroid Build Coastguard Worker 303*03f9172cSAndroid Build Coastguard Worker logging.basicConfig(level=args.loglevel) 304*03f9172cSAndroid Build Coastguard Worker 305*03f9172cSAndroid Build Coastguard Worker try: 306*03f9172cSAndroid Build Coastguard Worker if not clf.open("usb"): 307*03f9172cSAndroid Build Coastguard Worker print("Could not open connection with an NFC device") 308*03f9172cSAndroid Build Coastguard Worker raise SystemExit 309*03f9172cSAndroid Build Coastguard Worker 310*03f9172cSAndroid Build Coastguard Worker if args.command == "write-config": 311*03f9172cSAndroid Build Coastguard Worker wps_write_config_tag(clf, wait_remove=not args.no_wait) 312*03f9172cSAndroid Build Coastguard Worker raise SystemExit 313*03f9172cSAndroid Build Coastguard Worker 314*03f9172cSAndroid Build Coastguard Worker if args.command == "write-password": 315*03f9172cSAndroid Build Coastguard Worker wps_write_password_tag(clf, wait_remove=not args.no_wait) 316*03f9172cSAndroid Build Coastguard Worker raise SystemExit 317*03f9172cSAndroid Build Coastguard Worker 318*03f9172cSAndroid Build Coastguard Worker global continue_loop 319*03f9172cSAndroid Build Coastguard Worker while continue_loop: 320*03f9172cSAndroid Build Coastguard Worker print("Waiting for a tag or peer to be touched") 321*03f9172cSAndroid Build Coastguard Worker wait_connection = True 322*03f9172cSAndroid Build Coastguard Worker try: 323*03f9172cSAndroid Build Coastguard Worker if not clf.connect(rdwr={'on-connect': rdwr_connected}, 324*03f9172cSAndroid Build Coastguard Worker llcp={'on-startup': llcp_startup, 325*03f9172cSAndroid Build Coastguard Worker 'on-connect': llcp_connected}): 326*03f9172cSAndroid Build Coastguard Worker break 327*03f9172cSAndroid Build Coastguard Worker except Exception as e: 328*03f9172cSAndroid Build Coastguard Worker print("clf.connect failed") 329*03f9172cSAndroid Build Coastguard Worker 330*03f9172cSAndroid Build Coastguard Worker global srv 331*03f9172cSAndroid Build Coastguard Worker if only_one and srv and srv.success: 332*03f9172cSAndroid Build Coastguard Worker raise SystemExit 333*03f9172cSAndroid Build Coastguard Worker 334*03f9172cSAndroid Build Coastguard Worker except KeyboardInterrupt: 335*03f9172cSAndroid Build Coastguard Worker raise SystemExit 336*03f9172cSAndroid Build Coastguard Worker finally: 337*03f9172cSAndroid Build Coastguard Worker clf.close() 338*03f9172cSAndroid Build Coastguard Worker 339*03f9172cSAndroid Build Coastguard Worker raise SystemExit 340*03f9172cSAndroid Build Coastguard Worker 341*03f9172cSAndroid Build Coastguard Workerif __name__ == '__main__': 342*03f9172cSAndroid Build Coastguard Worker main() 343