1281681Srpaulo#!/usr/bin/python 2281681Srpaulo# 3281681Srpaulo# Example nfcpy to wpa_supplicant wrapper for P2P NFC operations 4281681Srpaulo# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi> 5281681Srpaulo# 6281681Srpaulo# This software may be distributed under the terms of the BSD license. 7281681Srpaulo# See README for more details. 8281681Srpaulo 9281681Srpauloimport os 10281681Srpauloimport sys 11281681Srpauloimport time 12281681Srpauloimport random 13281681Srpauloimport threading 14281681Srpauloimport argparse 15281681Srpaulo 16281681Srpauloimport nfc 17281681Srpauloimport nfc.ndef 18281681Srpauloimport nfc.llcp 19281681Srpauloimport nfc.handover 20281681Srpaulo 21281681Srpauloimport logging 22281681Srpaulo 23281681Srpauloimport wpaspy 24281681Srpaulo 25281681Srpaulowpas_ctrl = '/var/run/wpa_supplicant' 26281681Srpauloifname = None 27281681Srpauloinit_on_touch = False 28281681Srpauloin_raw_mode = False 29281681Srpauloprev_tcgetattr = 0 30281681Srpauloinclude_wps_req = True 31281681Srpauloinclude_p2p_req = True 32281681Srpaulono_input = False 33281681Srpaulosrv = None 34281681Srpaulocontinue_loop = True 35281681Srpauloterminate_now = False 36281681Srpaulosummary_file = None 37281681Srpaulosuccess_file = None 38281681Srpaulo 39281681Srpaulodef summary(txt): 40281681Srpaulo print txt 41281681Srpaulo if summary_file: 42281681Srpaulo with open(summary_file, 'a') as f: 43281681Srpaulo f.write(txt + "\n") 44281681Srpaulo 45281681Srpaulodef success_report(txt): 46281681Srpaulo summary(txt) 47281681Srpaulo if success_file: 48281681Srpaulo with open(success_file, 'a') as f: 49281681Srpaulo f.write(txt + "\n") 50281681Srpaulo 51281681Srpaulodef wpas_connect(): 52281681Srpaulo ifaces = [] 53281681Srpaulo if os.path.isdir(wpas_ctrl): 54281681Srpaulo try: 55281681Srpaulo ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 56281681Srpaulo except OSError, error: 57281681Srpaulo print "Could not find wpa_supplicant: ", error 58281681Srpaulo return None 59281681Srpaulo 60281681Srpaulo if len(ifaces) < 1: 61281681Srpaulo print "No wpa_supplicant control interface found" 62281681Srpaulo return None 63281681Srpaulo 64281681Srpaulo for ctrl in ifaces: 65281681Srpaulo if ifname: 66281681Srpaulo if ifname not in ctrl: 67281681Srpaulo continue 68281681Srpaulo try: 69281681Srpaulo print "Trying to use control interface " + ctrl 70281681Srpaulo wpas = wpaspy.Ctrl(ctrl) 71281681Srpaulo return wpas 72281681Srpaulo except Exception, e: 73281681Srpaulo pass 74281681Srpaulo return None 75281681Srpaulo 76281681Srpaulo 77281681Srpaulodef wpas_tag_read(message): 78281681Srpaulo wpas = wpas_connect() 79281681Srpaulo if (wpas == None): 80281681Srpaulo return False 81281681Srpaulo cmd = "WPS_NFC_TAG_READ " + str(message).encode("hex") 82281681Srpaulo global force_freq 83281681Srpaulo if force_freq: 84281681Srpaulo cmd = cmd + " freq=" + force_freq 85281681Srpaulo if "FAIL" in wpas.request(cmd): 86281681Srpaulo return False 87281681Srpaulo return True 88281681Srpaulo 89281681Srpaulo 90281681Srpaulodef wpas_get_handover_req(): 91281681Srpaulo wpas = wpas_connect() 92281681Srpaulo if (wpas == None): 93281681Srpaulo return None 94281681Srpaulo res = wpas.request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip() 95281681Srpaulo if "FAIL" in res: 96281681Srpaulo return None 97281681Srpaulo return res.decode("hex") 98281681Srpaulo 99281681Srpaulodef wpas_get_handover_req_wps(): 100281681Srpaulo wpas = wpas_connect() 101281681Srpaulo if (wpas == None): 102281681Srpaulo return None 103281681Srpaulo res = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip() 104281681Srpaulo if "FAIL" in res: 105281681Srpaulo return None 106281681Srpaulo return res.decode("hex") 107281681Srpaulo 108281681Srpaulo 109281681Srpaulodef wpas_get_handover_sel(tag=False): 110281681Srpaulo wpas = wpas_connect() 111281681Srpaulo if (wpas == None): 112281681Srpaulo return None 113281681Srpaulo if tag: 114281681Srpaulo res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG").rstrip() 115281681Srpaulo else: 116281681Srpaulo res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip() 117281681Srpaulo if "FAIL" in res: 118281681Srpaulo return None 119281681Srpaulo return res.decode("hex") 120281681Srpaulo 121281681Srpaulo 122281681Srpaulodef wpas_get_handover_sel_wps(): 123281681Srpaulo wpas = wpas_connect() 124281681Srpaulo if (wpas == None): 125281681Srpaulo return None 126281681Srpaulo res = wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR"); 127281681Srpaulo if "FAIL" in res: 128281681Srpaulo return None 129281681Srpaulo return res.rstrip().decode("hex") 130281681Srpaulo 131281681Srpaulo 132281681Srpaulodef wpas_report_handover(req, sel, type): 133281681Srpaulo wpas = wpas_connect() 134281681Srpaulo if (wpas == None): 135281681Srpaulo return None 136281681Srpaulo cmd = "NFC_REPORT_HANDOVER " + type + " P2P " + str(req).encode("hex") + " " + str(sel).encode("hex") 137281681Srpaulo global force_freq 138281681Srpaulo if force_freq: 139281681Srpaulo cmd = cmd + " freq=" + force_freq 140281681Srpaulo return wpas.request(cmd) 141281681Srpaulo 142281681Srpaulo 143281681Srpaulodef wpas_report_handover_wsc(req, sel, type): 144281681Srpaulo wpas = wpas_connect() 145281681Srpaulo if (wpas == None): 146281681Srpaulo return None 147281681Srpaulo cmd = "NFC_REPORT_HANDOVER " + type + " WPS " + str(req).encode("hex") + " " + str(sel).encode("hex") 148281681Srpaulo if force_freq: 149281681Srpaulo cmd = cmd + " freq=" + force_freq 150281681Srpaulo return wpas.request(cmd) 151281681Srpaulo 152281681Srpaulo 153281681Srpaulodef p2p_handover_client(llc): 154281681Srpaulo message = nfc.ndef.HandoverRequestMessage(version="1.2") 155281681Srpaulo message.nonce = random.randint(0, 0xffff) 156281681Srpaulo 157281681Srpaulo global include_p2p_req 158281681Srpaulo if include_p2p_req: 159281681Srpaulo data = wpas_get_handover_req() 160281681Srpaulo if (data == None): 161281681Srpaulo summary("Could not get handover request carrier record from wpa_supplicant") 162281681Srpaulo return 163281681Srpaulo print "Handover request carrier record from wpa_supplicant: " + data.encode("hex") 164281681Srpaulo datamsg = nfc.ndef.Message(data) 165281681Srpaulo message.add_carrier(datamsg[0], "active", datamsg[1:]) 166281681Srpaulo 167281681Srpaulo global include_wps_req 168281681Srpaulo if include_wps_req: 169281681Srpaulo print "Handover request (pre-WPS):" 170281681Srpaulo try: 171281681Srpaulo print message.pretty() 172281681Srpaulo except Exception, e: 173281681Srpaulo print e 174281681Srpaulo 175281681Srpaulo data = wpas_get_handover_req_wps() 176281681Srpaulo if data: 177281681Srpaulo print "Add WPS request in addition to P2P" 178281681Srpaulo datamsg = nfc.ndef.Message(data) 179281681Srpaulo message.add_carrier(datamsg[0], "active", datamsg[1:]) 180281681Srpaulo 181281681Srpaulo print "Handover request:" 182281681Srpaulo try: 183281681Srpaulo print message.pretty() 184281681Srpaulo except Exception, e: 185281681Srpaulo print e 186281681Srpaulo print str(message).encode("hex") 187281681Srpaulo 188281681Srpaulo client = nfc.handover.HandoverClient(llc) 189281681Srpaulo try: 190281681Srpaulo summary("Trying to initiate NFC connection handover") 191281681Srpaulo client.connect() 192281681Srpaulo summary("Connected for handover") 193281681Srpaulo except nfc.llcp.ConnectRefused: 194281681Srpaulo summary("Handover connection refused") 195281681Srpaulo client.close() 196281681Srpaulo return 197281681Srpaulo except Exception, e: 198281681Srpaulo summary("Other exception: " + str(e)) 199281681Srpaulo client.close() 200281681Srpaulo return 201281681Srpaulo 202281681Srpaulo summary("Sending handover request") 203281681Srpaulo 204281681Srpaulo if not client.send(message): 205281681Srpaulo summary("Failed to send handover request") 206281681Srpaulo client.close() 207281681Srpaulo return 208281681Srpaulo 209281681Srpaulo summary("Receiving handover response") 210281681Srpaulo message = client._recv() 211281681Srpaulo if message is None: 212281681Srpaulo summary("No response received") 213281681Srpaulo client.close() 214281681Srpaulo return 215281681Srpaulo if message.type != "urn:nfc:wkt:Hs": 216281681Srpaulo summary("Response was not Hs - received: " + message.type) 217281681Srpaulo client.close() 218281681Srpaulo return 219281681Srpaulo 220281681Srpaulo print "Received message" 221281681Srpaulo try: 222281681Srpaulo print message.pretty() 223281681Srpaulo except Exception, e: 224281681Srpaulo print e 225281681Srpaulo print str(message).encode("hex") 226281681Srpaulo message = nfc.ndef.HandoverSelectMessage(message) 227281681Srpaulo summary("Handover select received") 228281681Srpaulo try: 229281681Srpaulo print message.pretty() 230281681Srpaulo except Exception, e: 231281681Srpaulo print e 232281681Srpaulo 233281681Srpaulo for carrier in message.carriers: 234281681Srpaulo print "Remote carrier type: " + carrier.type 235281681Srpaulo if carrier.type == "application/vnd.wfa.p2p": 236281681Srpaulo print "P2P carrier type match - send to wpa_supplicant" 237281681Srpaulo if "OK" in wpas_report_handover(data, carrier.record, "INIT"): 238281681Srpaulo success_report("P2P handover reported successfully (initiator)") 239281681Srpaulo else: 240281681Srpaulo summary("P2P handover report rejected") 241281681Srpaulo break 242281681Srpaulo 243281681Srpaulo print "Remove peer" 244281681Srpaulo client.close() 245281681Srpaulo print "Done with handover" 246281681Srpaulo global only_one 247281681Srpaulo if only_one: 248281681Srpaulo print "only_one -> stop loop" 249281681Srpaulo global continue_loop 250281681Srpaulo continue_loop = False 251281681Srpaulo 252281681Srpaulo global no_wait 253281681Srpaulo if no_wait: 254281681Srpaulo print "Trying to exit.." 255281681Srpaulo global terminate_now 256281681Srpaulo terminate_now = True 257281681Srpaulo 258281681Srpaulo 259281681Srpauloclass HandoverServer(nfc.handover.HandoverServer): 260281681Srpaulo def __init__(self, llc): 261281681Srpaulo super(HandoverServer, self).__init__(llc) 262281681Srpaulo self.sent_carrier = None 263281681Srpaulo self.ho_server_processing = False 264281681Srpaulo self.success = False 265281681Srpaulo 266281681Srpaulo # override to avoid parser error in request/response.pretty() in nfcpy 267281681Srpaulo # due to new WSC handover format 268281681Srpaulo def _process_request(self, request): 269281681Srpaulo summary("received handover request {}".format(request.type)) 270281681Srpaulo response = nfc.ndef.Message("\xd1\x02\x01Hs\x12") 271281681Srpaulo if not request.type == 'urn:nfc:wkt:Hr': 272281681Srpaulo summary("not a handover request") 273281681Srpaulo else: 274281681Srpaulo try: 275281681Srpaulo request = nfc.ndef.HandoverRequestMessage(request) 276281681Srpaulo except nfc.ndef.DecodeError as e: 277281681Srpaulo summary("error decoding 'Hr' message: {}".format(e)) 278281681Srpaulo else: 279281681Srpaulo response = self.process_request(request) 280281681Srpaulo summary("send handover response {}".format(response.type)) 281281681Srpaulo return response 282281681Srpaulo 283281681Srpaulo def process_request(self, request): 284281681Srpaulo self.ho_server_processing = True 285281681Srpaulo clear_raw_mode() 286281681Srpaulo print "HandoverServer - request received" 287281681Srpaulo try: 288281681Srpaulo print "Parsed handover request: " + request.pretty() 289281681Srpaulo except Exception, e: 290281681Srpaulo print e 291281681Srpaulo 292281681Srpaulo sel = nfc.ndef.HandoverSelectMessage(version="1.2") 293281681Srpaulo 294281681Srpaulo found = False 295281681Srpaulo 296281681Srpaulo for carrier in request.carriers: 297281681Srpaulo print "Remote carrier type: " + carrier.type 298281681Srpaulo if carrier.type == "application/vnd.wfa.p2p": 299281681Srpaulo print "P2P carrier type match - add P2P carrier record" 300281681Srpaulo found = True 301281681Srpaulo self.received_carrier = carrier.record 302281681Srpaulo print "Carrier record:" 303281681Srpaulo try: 304281681Srpaulo print carrier.record.pretty() 305281681Srpaulo except Exception, e: 306281681Srpaulo print e 307281681Srpaulo data = wpas_get_handover_sel() 308281681Srpaulo if data is None: 309281681Srpaulo print "Could not get handover select carrier record from wpa_supplicant" 310281681Srpaulo continue 311281681Srpaulo print "Handover select carrier record from wpa_supplicant:" 312281681Srpaulo print data.encode("hex") 313281681Srpaulo self.sent_carrier = data 314281681Srpaulo if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"): 315281681Srpaulo success_report("P2P handover reported successfully (responder)") 316281681Srpaulo else: 317281681Srpaulo summary("P2P handover report rejected") 318281681Srpaulo break 319281681Srpaulo 320281681Srpaulo message = nfc.ndef.Message(data); 321281681Srpaulo sel.add_carrier(message[0], "active", message[1:]) 322281681Srpaulo break 323281681Srpaulo 324281681Srpaulo for carrier in request.carriers: 325281681Srpaulo if found: 326281681Srpaulo break 327281681Srpaulo print "Remote carrier type: " + carrier.type 328281681Srpaulo if carrier.type == "application/vnd.wfa.wsc": 329281681Srpaulo print "WSC carrier type match - add WSC carrier record" 330281681Srpaulo found = True 331281681Srpaulo self.received_carrier = carrier.record 332281681Srpaulo print "Carrier record:" 333281681Srpaulo try: 334281681Srpaulo print carrier.record.pretty() 335281681Srpaulo except Exception, e: 336281681Srpaulo print e 337281681Srpaulo data = wpas_get_handover_sel_wps() 338281681Srpaulo if data is None: 339281681Srpaulo print "Could not get handover select carrier record from wpa_supplicant" 340281681Srpaulo continue 341281681Srpaulo print "Handover select carrier record from wpa_supplicant:" 342281681Srpaulo print data.encode("hex") 343281681Srpaulo self.sent_carrier = data 344281681Srpaulo if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"): 345281681Srpaulo success_report("WSC handover reported successfully") 346281681Srpaulo else: 347281681Srpaulo summary("WSC handover report rejected") 348281681Srpaulo break 349281681Srpaulo 350281681Srpaulo message = nfc.ndef.Message(data); 351281681Srpaulo sel.add_carrier(message[0], "active", message[1:]) 352281681Srpaulo found = True 353281681Srpaulo break 354281681Srpaulo 355281681Srpaulo print "Handover select:" 356281681Srpaulo try: 357281681Srpaulo print sel.pretty() 358281681Srpaulo except Exception, e: 359281681Srpaulo print e 360281681Srpaulo print str(sel).encode("hex") 361281681Srpaulo 362281681Srpaulo summary("Sending handover select") 363281681Srpaulo self.success = True 364281681Srpaulo return sel 365281681Srpaulo 366281681Srpaulo 367281681Srpaulodef clear_raw_mode(): 368281681Srpaulo import sys, tty, termios 369281681Srpaulo global prev_tcgetattr, in_raw_mode 370281681Srpaulo if not in_raw_mode: 371281681Srpaulo return 372281681Srpaulo fd = sys.stdin.fileno() 373281681Srpaulo termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr) 374281681Srpaulo in_raw_mode = False 375281681Srpaulo 376281681Srpaulo 377281681Srpaulodef getch(): 378281681Srpaulo import sys, tty, termios, select 379281681Srpaulo global prev_tcgetattr, in_raw_mode 380281681Srpaulo fd = sys.stdin.fileno() 381281681Srpaulo prev_tcgetattr = termios.tcgetattr(fd) 382281681Srpaulo ch = None 383281681Srpaulo try: 384281681Srpaulo tty.setraw(fd) 385281681Srpaulo in_raw_mode = True 386281681Srpaulo [i, o, e] = select.select([fd], [], [], 0.05) 387281681Srpaulo if i: 388281681Srpaulo ch = sys.stdin.read(1) 389281681Srpaulo finally: 390281681Srpaulo termios.tcsetattr(fd, termios.TCSADRAIN, prev_tcgetattr) 391281681Srpaulo in_raw_mode = False 392281681Srpaulo return ch 393281681Srpaulo 394281681Srpaulo 395281681Srpaulodef p2p_tag_read(tag): 396281681Srpaulo success = False 397281681Srpaulo if len(tag.ndef.message): 398281681Srpaulo for record in tag.ndef.message: 399281681Srpaulo print "record type " + record.type 400281681Srpaulo if record.type == "application/vnd.wfa.wsc": 401281681Srpaulo summary("WPS tag - send to wpa_supplicant") 402281681Srpaulo success = wpas_tag_read(tag.ndef.message) 403281681Srpaulo break 404281681Srpaulo if record.type == "application/vnd.wfa.p2p": 405281681Srpaulo summary("P2P tag - send to wpa_supplicant") 406281681Srpaulo success = wpas_tag_read(tag.ndef.message) 407281681Srpaulo break 408281681Srpaulo else: 409281681Srpaulo summary("Empty tag") 410281681Srpaulo 411281681Srpaulo if success: 412281681Srpaulo success_report("Tag read succeeded") 413281681Srpaulo 414281681Srpaulo return success 415281681Srpaulo 416281681Srpaulo 417281681Srpaulodef rdwr_connected_p2p_write(tag): 418281681Srpaulo summary("Tag found - writing - " + str(tag)) 419281681Srpaulo global p2p_sel_data 420281681Srpaulo tag.ndef.message = str(p2p_sel_data) 421281681Srpaulo success_report("Tag write succeeded") 422281681Srpaulo print "Done - remove tag" 423281681Srpaulo global only_one 424281681Srpaulo if only_one: 425281681Srpaulo global continue_loop 426281681Srpaulo continue_loop = False 427281681Srpaulo global p2p_sel_wait_remove 428281681Srpaulo return p2p_sel_wait_remove 429281681Srpaulo 430281681Srpaulodef wps_write_p2p_handover_sel(clf, wait_remove=True): 431281681Srpaulo print "Write P2P handover select" 432281681Srpaulo data = wpas_get_handover_sel(tag=True) 433281681Srpaulo if (data == None): 434281681Srpaulo summary("Could not get P2P handover select from wpa_supplicant") 435281681Srpaulo return 436281681Srpaulo 437281681Srpaulo global p2p_sel_wait_remove 438281681Srpaulo p2p_sel_wait_remove = wait_remove 439281681Srpaulo global p2p_sel_data 440281681Srpaulo p2p_sel_data = nfc.ndef.HandoverSelectMessage(version="1.2") 441281681Srpaulo message = nfc.ndef.Message(data); 442281681Srpaulo p2p_sel_data.add_carrier(message[0], "active", message[1:]) 443281681Srpaulo print "Handover select:" 444281681Srpaulo try: 445281681Srpaulo print p2p_sel_data.pretty() 446281681Srpaulo except Exception, e: 447281681Srpaulo print e 448281681Srpaulo print str(p2p_sel_data).encode("hex") 449281681Srpaulo 450281681Srpaulo print "Touch an NFC tag" 451281681Srpaulo clf.connect(rdwr={'on-connect': rdwr_connected_p2p_write}) 452281681Srpaulo 453281681Srpaulo 454281681Srpaulodef rdwr_connected(tag): 455281681Srpaulo global only_one, no_wait 456281681Srpaulo summary("Tag connected: " + str(tag)) 457281681Srpaulo 458281681Srpaulo if tag.ndef: 459281681Srpaulo print "NDEF tag: " + tag.type 460281681Srpaulo try: 461281681Srpaulo print tag.ndef.message.pretty() 462281681Srpaulo except Exception, e: 463281681Srpaulo print e 464281681Srpaulo success = p2p_tag_read(tag) 465281681Srpaulo if only_one and success: 466281681Srpaulo global continue_loop 467281681Srpaulo continue_loop = False 468281681Srpaulo else: 469281681Srpaulo summary("Not an NDEF tag - remove tag") 470281681Srpaulo return True 471281681Srpaulo 472281681Srpaulo return not no_wait 473281681Srpaulo 474281681Srpaulo 475281681Srpaulodef llcp_worker(llc): 476281681Srpaulo global init_on_touch 477281681Srpaulo if init_on_touch: 478281681Srpaulo print "Starting handover client" 479281681Srpaulo p2p_handover_client(llc) 480281681Srpaulo return 481281681Srpaulo 482281681Srpaulo global no_input 483281681Srpaulo if no_input: 484281681Srpaulo print "Wait for handover to complete" 485281681Srpaulo else: 486281681Srpaulo print "Wait for handover to complete - press 'i' to initiate ('w' for WPS only, 'p' for P2P only)" 487281681Srpaulo global srv 488281681Srpaulo global wait_connection 489281681Srpaulo while not wait_connection and srv.sent_carrier is None: 490281681Srpaulo if srv.ho_server_processing: 491281681Srpaulo time.sleep(0.025) 492281681Srpaulo elif no_input: 493281681Srpaulo time.sleep(0.5) 494281681Srpaulo else: 495281681Srpaulo global include_wps_req, include_p2p_req 496281681Srpaulo res = getch() 497281681Srpaulo if res == 'i': 498281681Srpaulo include_wps_req = True 499281681Srpaulo include_p2p_req = True 500281681Srpaulo elif res == 'p': 501281681Srpaulo include_wps_req = False 502281681Srpaulo include_p2p_req = True 503281681Srpaulo elif res == 'w': 504281681Srpaulo include_wps_req = True 505281681Srpaulo include_p2p_req = False 506281681Srpaulo else: 507281681Srpaulo continue 508281681Srpaulo clear_raw_mode() 509281681Srpaulo print "Starting handover client" 510281681Srpaulo p2p_handover_client(llc) 511281681Srpaulo return 512281681Srpaulo 513281681Srpaulo clear_raw_mode() 514281681Srpaulo print "Exiting llcp_worker thread" 515281681Srpaulo 516281681Srpaulodef llcp_startup(clf, llc): 517281681Srpaulo print "Start LLCP server" 518281681Srpaulo global srv 519281681Srpaulo srv = HandoverServer(llc) 520281681Srpaulo return llc 521281681Srpaulo 522281681Srpaulodef llcp_connected(llc): 523281681Srpaulo print "P2P LLCP connected" 524281681Srpaulo global wait_connection 525281681Srpaulo wait_connection = False 526281681Srpaulo global init_on_touch 527281681Srpaulo if not init_on_touch: 528281681Srpaulo global srv 529281681Srpaulo srv.start() 530281681Srpaulo if init_on_touch or not no_input: 531281681Srpaulo threading.Thread(target=llcp_worker, args=(llc,)).start() 532281681Srpaulo return True 533281681Srpaulo 534281681Srpaulodef terminate_loop(): 535281681Srpaulo global terminate_now 536281681Srpaulo return terminate_now 537281681Srpaulo 538281681Srpaulodef main(): 539281681Srpaulo clf = nfc.ContactlessFrontend() 540281681Srpaulo 541281681Srpaulo parser = argparse.ArgumentParser(description='nfcpy to wpa_supplicant integration for P2P and WPS NFC operations') 542281681Srpaulo parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO, 543281681Srpaulo action='store_const', dest='loglevel', 544281681Srpaulo help='verbose debug output') 545281681Srpaulo parser.add_argument('-q', const=logging.WARNING, action='store_const', 546281681Srpaulo dest='loglevel', help='be quiet') 547281681Srpaulo parser.add_argument('--only-one', '-1', action='store_true', 548281681Srpaulo help='run only one operation and exit') 549281681Srpaulo parser.add_argument('--init-on-touch', '-I', action='store_true', 550281681Srpaulo help='initiate handover on touch') 551281681Srpaulo parser.add_argument('--no-wait', action='store_true', 552281681Srpaulo help='do not wait for tag to be removed before exiting') 553281681Srpaulo parser.add_argument('--ifname', '-i', 554281681Srpaulo help='network interface name') 555281681Srpaulo parser.add_argument('--no-wps-req', '-N', action='store_true', 556281681Srpaulo help='do not include WPS carrier record in request') 557281681Srpaulo parser.add_argument('--no-input', '-a', action='store_true', 558281681Srpaulo help='do not use stdout input to initiate handover') 559281681Srpaulo parser.add_argument('--tag-read-only', '-t', action='store_true', 560281681Srpaulo help='tag read only (do not allow connection handover)') 561281681Srpaulo parser.add_argument('--handover-only', action='store_true', 562281681Srpaulo help='connection handover only (do not allow tag read)') 563281681Srpaulo parser.add_argument('--freq', '-f', 564281681Srpaulo help='forced frequency of operating channel in MHz') 565281681Srpaulo parser.add_argument('--summary', 566281681Srpaulo help='summary file for writing status updates') 567281681Srpaulo parser.add_argument('--success', 568281681Srpaulo help='success file for writing success update') 569281681Srpaulo parser.add_argument('command', choices=['write-p2p-sel'], 570281681Srpaulo nargs='?') 571281681Srpaulo args = parser.parse_args() 572281681Srpaulo 573281681Srpaulo global only_one 574281681Srpaulo only_one = args.only_one 575281681Srpaulo 576281681Srpaulo global no_wait 577281681Srpaulo no_wait = args.no_wait 578281681Srpaulo 579281681Srpaulo global force_freq 580281681Srpaulo force_freq = args.freq 581281681Srpaulo 582281681Srpaulo logging.basicConfig(level=args.loglevel) 583281681Srpaulo 584281681Srpaulo global init_on_touch 585281681Srpaulo init_on_touch = args.init_on_touch 586281681Srpaulo 587281681Srpaulo if args.ifname: 588281681Srpaulo global ifname 589281681Srpaulo ifname = args.ifname 590281681Srpaulo print "Selected ifname " + ifname 591281681Srpaulo 592281681Srpaulo if args.no_wps_req: 593281681Srpaulo global include_wps_req 594281681Srpaulo include_wps_req = False 595281681Srpaulo 596281681Srpaulo if args.summary: 597281681Srpaulo global summary_file 598281681Srpaulo summary_file = args.summary 599281681Srpaulo 600281681Srpaulo if args.success: 601281681Srpaulo global success_file 602281681Srpaulo success_file = args.success 603281681Srpaulo 604281681Srpaulo if args.no_input: 605281681Srpaulo global no_input 606281681Srpaulo no_input = True 607281681Srpaulo 608281681Srpaulo clf = nfc.ContactlessFrontend() 609281681Srpaulo global wait_connection 610281681Srpaulo 611281681Srpaulo try: 612281681Srpaulo if not clf.open("usb"): 613281681Srpaulo print "Could not open connection with an NFC device" 614281681Srpaulo raise SystemExit 615281681Srpaulo 616281681Srpaulo if args.command == "write-p2p-sel": 617281681Srpaulo wps_write_p2p_handover_sel(clf, wait_remove=not args.no_wait) 618281681Srpaulo raise SystemExit 619281681Srpaulo 620281681Srpaulo global continue_loop 621281681Srpaulo while continue_loop: 622281681Srpaulo print "Waiting for a tag or peer to be touched" 623281681Srpaulo wait_connection = True 624281681Srpaulo try: 625281681Srpaulo if args.tag_read_only: 626281681Srpaulo if not clf.connect(rdwr={'on-connect': rdwr_connected}): 627281681Srpaulo break 628281681Srpaulo elif args.handover_only: 629281681Srpaulo if not clf.connect(llcp={'on-startup': llcp_startup, 630281681Srpaulo 'on-connect': llcp_connected}, 631281681Srpaulo terminate=terminate_loop): 632281681Srpaulo break 633281681Srpaulo else: 634281681Srpaulo if not clf.connect(rdwr={'on-connect': rdwr_connected}, 635281681Srpaulo llcp={'on-startup': llcp_startup, 636281681Srpaulo 'on-connect': llcp_connected}, 637281681Srpaulo terminate=terminate_loop): 638281681Srpaulo break 639281681Srpaulo except Exception, e: 640281681Srpaulo print "clf.connect failed" 641281681Srpaulo 642281681Srpaulo global srv 643281681Srpaulo if only_one and srv and srv.success: 644281681Srpaulo raise SystemExit 645281681Srpaulo 646281681Srpaulo except KeyboardInterrupt: 647281681Srpaulo raise SystemExit 648281681Srpaulo finally: 649281681Srpaulo clf.close() 650281681Srpaulo 651281681Srpaulo raise SystemExit 652281681Srpaulo 653281681Srpauloif __name__ == '__main__': 654281681Srpaulo main() 655