1252190Srpaulo#!/usr/bin/python 2252190Srpaulo# 3252190Srpaulo# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations 4252190Srpaulo# Copyright (c) 2012, Jouni Malinen <j@w1.fi> 5252190Srpaulo# 6252190Srpaulo# This software may be distributed under the terms of the BSD license. 7252190Srpaulo# See README for more details. 8252190Srpaulo 9252190Srpauloimport os 10252190Srpauloimport sys 11252190Srpauloimport time 12252190Srpaulo 13252190Srpauloimport nfc 14252190Srpauloimport nfc.ndef 15252190Srpauloimport nfc.llcp 16252190Srpauloimport nfc.handover 17252190Srpaulo 18252190Srpauloimport wpactrl 19252190Srpaulo 20252190Srpaulowpas_ctrl = '/var/run/wpa_supplicant' 21252190Srpaulo 22252190Srpaulodef wpas_connect(): 23252190Srpaulo ifaces = [] 24252190Srpaulo if os.path.isdir(wpas_ctrl): 25252190Srpaulo try: 26252190Srpaulo ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 27252190Srpaulo except OSError, error: 28252190Srpaulo print "Could not find wpa_supplicant: ", error 29252190Srpaulo return None 30252190Srpaulo 31252190Srpaulo if len(ifaces) < 1: 32252190Srpaulo print "No wpa_supplicant control interface found" 33252190Srpaulo return None 34252190Srpaulo 35252190Srpaulo for ctrl in ifaces: 36252190Srpaulo try: 37252190Srpaulo wpas = wpactrl.WPACtrl(ctrl) 38252190Srpaulo return wpas 39252190Srpaulo except wpactrl.error, error: 40252190Srpaulo print "Error: ", error 41252190Srpaulo pass 42252190Srpaulo return None 43252190Srpaulo 44252190Srpaulo 45252190Srpaulodef wpas_tag_read(message): 46252190Srpaulo wpas = wpas_connect() 47252190Srpaulo if (wpas == None): 48252190Srpaulo return 49252190Srpaulo print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex")) 50252190Srpaulo 51252190Srpaulo 52252190Srpaulodef wpas_get_handover_req(): 53252190Srpaulo wpas = wpas_connect() 54252190Srpaulo if (wpas == None): 55252190Srpaulo return None 56252190Srpaulo return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS").rstrip().decode("hex") 57252190Srpaulo 58252190Srpaulo 59252190Srpaulodef wpas_put_handover_sel(message): 60252190Srpaulo wpas = wpas_connect() 61252190Srpaulo if (wpas == None): 62252190Srpaulo return 63252190Srpaulo print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex")) 64252190Srpaulo 65252190Srpaulo 66252190Srpaulodef wps_handover_init(peer): 67252190Srpaulo print "Trying to initiate WPS handover" 68252190Srpaulo 69252190Srpaulo data = wpas_get_handover_req() 70252190Srpaulo if (data == None): 71252190Srpaulo print "Could not get handover request message from wpa_supplicant" 72252190Srpaulo return 73252190Srpaulo print "Handover request from wpa_supplicant: " + data.encode("hex") 74252190Srpaulo message = nfc.ndef.Message(data) 75252190Srpaulo print "Parsed handover request: " + message.pretty() 76252190Srpaulo 77252190Srpaulo nfc.llcp.activate(peer); 78252190Srpaulo time.sleep(0.5) 79252190Srpaulo 80252190Srpaulo client = nfc.handover.HandoverClient() 81252190Srpaulo try: 82252190Srpaulo print "Trying handover"; 83252190Srpaulo client.connect() 84252190Srpaulo print "Connected for handover" 85252190Srpaulo except nfc.llcp.ConnectRefused: 86252190Srpaulo print "Handover connection refused" 87252190Srpaulo nfc.llcp.shutdown() 88252190Srpaulo client.close() 89252190Srpaulo return 90252190Srpaulo 91252190Srpaulo print "Sending handover request" 92252190Srpaulo 93252190Srpaulo if not client.send(message): 94252190Srpaulo print "Failed to send handover request" 95252190Srpaulo 96252190Srpaulo print "Receiving handover response" 97252190Srpaulo message = client._recv() 98252190Srpaulo print "Handover select received" 99252190Srpaulo print message.pretty() 100252190Srpaulo wpas_put_handover_sel(message) 101252190Srpaulo 102252190Srpaulo print "Remove peer" 103252190Srpaulo nfc.llcp.shutdown() 104252190Srpaulo client.close() 105252190Srpaulo print "Done with handover" 106252190Srpaulo 107252190Srpaulo 108252190Srpaulodef wps_tag_read(tag): 109252190Srpaulo if len(tag.ndef.message): 110252190Srpaulo message = nfc.ndef.Message(tag.ndef.message) 111252190Srpaulo print "message type " + message.type 112252190Srpaulo 113252190Srpaulo for record in message: 114252190Srpaulo print "record type " + record.type 115252190Srpaulo if record.type == "application/vnd.wfa.wsc": 116252190Srpaulo print "WPS tag - send to wpa_supplicant" 117252190Srpaulo wpas_tag_read(tag.ndef.message) 118252190Srpaulo break 119252190Srpaulo else: 120252190Srpaulo print "Empty tag" 121252190Srpaulo 122252190Srpaulo print "Remove tag" 123252190Srpaulo while tag.is_present: 124252190Srpaulo time.sleep(0.1) 125252190Srpaulo 126252190Srpaulo 127252190Srpaulodef main(): 128252190Srpaulo clf = nfc.ContactlessFrontend() 129252190Srpaulo 130252190Srpaulo try: 131252190Srpaulo while True: 132252190Srpaulo print "Waiting for a tag or peer to be touched" 133252190Srpaulo 134252190Srpaulo while True: 135252190Srpaulo general_bytes = nfc.llcp.startup({}) 136252190Srpaulo tag = clf.poll(general_bytes) 137252190Srpaulo if tag == None: 138252190Srpaulo continue 139252190Srpaulo 140252190Srpaulo if isinstance(tag, nfc.DEP): 141252190Srpaulo wps_handover_init(tag) 142252190Srpaulo break 143252190Srpaulo 144252190Srpaulo if tag.ndef: 145252190Srpaulo wps_tag_read(tag) 146252190Srpaulo break 147252190Srpaulo 148252190Srpaulo if tag: 149252190Srpaulo print "Not an NDEF tag - remove tag" 150252190Srpaulo while tag.is_present: 151252190Srpaulo time.sleep(0.1) 152252190Srpaulo break 153252190Srpaulo 154252190Srpaulo except KeyboardInterrupt: 155252190Srpaulo raise SystemExit 156252190Srpaulo finally: 157252190Srpaulo clf.close() 158252190Srpaulo 159252190Srpaulo raise SystemExit 160252190Srpaulo 161252190Srpauloif __name__ == '__main__': 162252190Srpaulo main() 163