#!/usr/bin/python
#
# Example nfcpy to wpa_supplicant wrapper for WPS NFC operations
-# Copyright (c) 2012, Jouni Malinen <j@w1.fi>
+# Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import os
import sys
import time
+import random
+import StringIO
import nfc
import nfc.ndef
import nfc.llcp
import nfc.handover
+import logging
+logging.basicConfig()
+
import wpactrl
wpas_ctrl = '/var/run/wpa_supplicant'
wpas = wpas_connect()
if (wpas == None):
return None
- return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS").rstrip().decode("hex")
+ return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
def wpas_put_handover_sel(message):
data = wpas_get_handover_req()
if (data == None):
- print "Could not get handover request message from wpa_supplicant"
+ print "Could not get handover request carrier record from wpa_supplicant"
return
- print "Handover request from wpa_supplicant: " + data.encode("hex")
- message = nfc.ndef.Message(data)
- print "Parsed handover request: " + message.pretty()
+ print "Handover request carrier record from wpa_supplicant: " + data.encode("hex")
+ record = nfc.ndef.Record()
+ f = StringIO.StringIO(data)
+ record._read(f)
+ record = nfc.ndef.HandoverCarrierRecord(record)
+ print "Parsed handover request carrier record:"
+ print record.pretty()
+
+ message = nfc.ndef.HandoverRequestMessage(version="1.2")
+ message.nonce = random.randint(0, 0xffff)
+ message.add_carrier(record, "active")
+
+ print "Handover request:"
+ print message.pretty()
nfc.llcp.activate(peer);
- time.sleep(0.5)
client = nfc.handover.HandoverClient()
try:
print "Receiving handover response"
message = client._recv()
+ if message is None:
+ print "No response received"
+ nfc.llcp.shutdown()
+ client.close()
+ return
+ if message.type != "urn:nfc:wkt:Hs":
+ print "Response was not Hs - received: " + message.type
+ nfc.llcp.shutdown()
+ client.close()
+ return
+
+ print "Received message"
+ print message.pretty()
+ message = nfc.ndef.HandoverSelectMessage(message)
print "Handover select received"
print message.pretty()
- wpas_put_handover_sel(message)
+
+ for carrier in message.carriers:
+ print "Remote carrier type: " + carrier.type
+ if carrier.type == "application/vnd.wfa.wsc":
+ print "WPS carrier type match - send to wpa_supplicant"
+ wpas_put_handover_sel(carrier.record)
+ wifi = nfc.ndef.WifiConfigRecord(carrier.record)
+ print wifi.pretty()
print "Remove peer"
nfc.llcp.shutdown()
time.sleep(0.1)
+def find_peer(clf):
+ while True:
+ if nfc.llcp.connected():
+ print "LLCP connected"
+ general_bytes = nfc.llcp.startup({})
+ peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
+ if isinstance(peer, nfc.DEP):
+ print "listen -> DEP";
+ if peer.general_bytes.startswith("Ffm"):
+ print "Found DEP"
+ return peer
+ print "mismatch in general_bytes"
+ print peer.general_bytes
+
+ peer = clf.poll(general_bytes)
+ if isinstance(peer, nfc.DEP):
+ print "poll -> DEP";
+ if peer.general_bytes.startswith("Ffm"):
+ print "Found DEP"
+ return peer
+ print "mismatch in general_bytes"
+ print peer.general_bytes
+
+ if peer:
+ print "Found tag"
+ return peer
+
+
def main():
clf = nfc.ContactlessFrontend()
while True:
print "Waiting for a tag or peer to be touched"
- while True:
- general_bytes = nfc.llcp.startup({})
- tag = clf.poll(general_bytes)
- if tag == None:
- continue
-
- if isinstance(tag, nfc.DEP):
- wps_handover_init(tag)
- break
-
- if tag.ndef:
- wps_tag_read(tag)
- break
-
- if tag:
- print "Not an NDEF tag - remove tag"
- while tag.is_present:
- time.sleep(0.1)
- break
+ tag = find_peer(clf)
+ if isinstance(tag, nfc.DEP):
+ wps_handover_init(tag)
+ continue
+
+ if tag.ndef:
+ wps_tag_read(tag)
+ continue
+
+ print "Not an NDEF tag - remove tag"
+ while tag.is_present:
+ time.sleep(0.1)
except KeyboardInterrupt:
raise SystemExit