1#!/usr/bin/python 2# 3# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations 4# Copyright (c) 2012, Jouni Malinen <j@w1.fi> 5# 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 12 13import nfc 14import nfc.ndef 15import nfc.llcp 16import nfc.handover 17 18import wpactrl 19 20wpas_ctrl = '/var/run/wpa_supplicant' 21 22def wpas_connect(): 23 ifaces = [] 24 if os.path.isdir(wpas_ctrl): 25 try: 26 ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] 27 except OSError, error: 28 print "Could not find wpa_supplicant: ", error 29 return None 30 31 if len(ifaces) < 1: 32 print "No wpa_supplicant control interface found" 33 return None 34 35 for ctrl in ifaces: 36 try: 37 wpas = wpactrl.WPACtrl(ctrl) 38 return wpas 39 except wpactrl.error, error: 40 print "Error: ", error 41 pass 42 return None 43 44 45def wpas_tag_read(message): 46 wpas = wpas_connect() 47 if (wpas == None): 48 return 49 print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex")) 50 51 52def wpas_get_handover_req(): 53 wpas = wpas_connect() 54 if (wpas == None): 55 return None 56 return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS").rstrip().decode("hex") 57 58 59def wpas_put_handover_sel(message): 60 wpas = wpas_connect() 61 if (wpas == None): 62 return 63 print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex")) 64 65 66def wps_handover_init(peer): 67 print "Trying to initiate WPS handover" 68 69 data = wpas_get_handover_req() 70 if (data == None): 71 print "Could not get handover request message from wpa_supplicant" 72 return 73 print "Handover request from wpa_supplicant: " + data.encode("hex") 74 message = nfc.ndef.Message(data) 75 print "Parsed handover request: " + message.pretty() 76 77 nfc.llcp.activate(peer); 78 time.sleep(0.5) 79 80 client = nfc.handover.HandoverClient() 81 try: 82 print "Trying handover"; 83 client.connect() 84 print "Connected for handover" 85 except nfc.llcp.ConnectRefused: 86 print "Handover connection refused" 87 nfc.llcp.shutdown() 88 client.close() 89 return 90 91 print "Sending handover request" 92 93 if not client.send(message): 94 print "Failed to send handover request" 95 96 print "Receiving handover response" 97 message = client._recv() 98 print "Handover select received" 99 print message.pretty() 100 wpas_put_handover_sel(message) 101 102 print "Remove peer" 103 nfc.llcp.shutdown() 104 client.close() 105 print "Done with handover" 106 107 108def wps_tag_read(tag): 109 if len(tag.ndef.message): 110 message = nfc.ndef.Message(tag.ndef.message) 111 print "message type " + message.type 112 113 for record in message: 114 print "record type " + record.type 115 if record.type == "application/vnd.wfa.wsc": 116 print "WPS tag - send to wpa_supplicant" 117 wpas_tag_read(tag.ndef.message) 118 break 119 else: 120 print "Empty tag" 121 122 print "Remove tag" 123 while tag.is_present: 124 time.sleep(0.1) 125 126 127def main(): 128 clf = nfc.ContactlessFrontend() 129 130 try: 131 while True: 132 print "Waiting for a tag or peer to be touched" 133 134 while True: 135 general_bytes = nfc.llcp.startup({}) 136 tag = clf.poll(general_bytes) 137 if tag == None: 138 continue 139 140 if isinstance(tag, nfc.DEP): 141 wps_handover_init(tag) 142 break 143 144 if tag.ndef: 145 wps_tag_read(tag) 146 break 147 148 if tag: 149 print "Not an NDEF tag - remove tag" 150 while tag.is_present: 151 time.sleep(0.1) 152 break 153 154 except KeyboardInterrupt: 155 raise SystemExit 156 finally: 157 clf.close() 158 159 raise SystemExit 160 161if __name__ == '__main__': 162 main() 163