Accumulative patch from commit b618a469c42120e984ab1c85ed6058504d1fca78
Author: Jouni Malinen <jouni@qca.qualcomm.com>
Date: Sat Feb 16 19:54:09 2013 +0200
Interworking: Select highest priority cred if multiple matches
Interworking: Select highest priority cred if multiple matches
GAS server: Fix a regression in GAS server callback
hostapd: Fix Max SP Length derivation from QoS Info
nl80211: Configure STA Capabilities and Extended Capabilities
Synchronize with wireless-testing.git include/uapi/linux/nl80211.h
WPS: Fix build without CONFIG_WPS_NFC
WPS: Add support for NFC handover select generation with wpa_supplicant
WPS: Update NFC connection handover documentation
WPS: Add support for config token generation with wpa_supplicant
WPS: Allow password token to be written with nfcpy
WPS: Use pre-configured NFC password token instead of overriding it
TDLS: Pass peer's Capability and Ext Capability info during sta_add
TDLS: Pass peer's HT Capability and QOS information during sta_add
nl80211: Add debug prints for STA add/set operations
TDLS: Fix add/set STA operation
Synchronize with wireless-testing.git include/uapi/linux/nl80211.h
WPS: Allow Device Password to be changed from M1 to M2
WPS: Fix wps_reg nfc-pw option
TDLS: Tear down peers when disconnecting from the AP
P2P: Do not use old scan result data for peer discovery
Use more accurate timestamps for scan results
P2P: Postpone P2P-DEVICE-FOUND if config_methods not known
P2P: Do not allow peer update to clear config_methods
WPS: Report NFC connection handover completion differently
P2P: Avoid concurrent scans during all steps of group formation
P2P: Cancel group formation timeout on group removal (on client)
WPS: Change listen time to match nfcpy default (250 ms)
WPS: Report only the carrier record from NFC to wpa_supplicant
WPS: Fetch only the carrier record from wpa_supplicant for NFC
WPS: Update nfcpy script to support AP mode NFC connection handover
WPS: Add command for fetching carrier record for NFC handover
WPS: Clean up debug prints with nfcpy
WPS: Remove 0.5 sec extra wait from NFC handover with nfcpy
WPS: Use alternating poll/listen for NFC peer discovery with nfcpy
WPS: Configure logging to show nfcpy log message
WPS: Add an example python script for NFC operations with hostapd
hostapd: Do not change HT40 capability due to OBSS scan
dbus: Add missing signal description for WPS (7)
EAP peer: Add Session-Id derivation to more EAP methods
EAP peer: Add Session-Id derivation
EAP-IKEV2 server: Fix invalid memory freeing operation
eap_proxy: Add a dummy implementation for compilation testing
eap_proxy: Add mechanism for allowing EAP methods to be offloaded
Android: Allow setgroups to be overridden from build configuration
P2P: Send p2p_stop_find event on failure to start pending p2p_find
P2P: Fix GO Probe Response IEs when Wi-Fi Display is enabled
Capability matching for 60 GHz band
nl80211: Add ctrl_iface message for AP mode connection rejection
P2P: Allow local configuration to use 5 GHz band 40 MHz channels
Fix BSS RANGE command for no exact id match cases
Change-Id: Iac9284bba31db40911aecc3adf2843c9b1576db1
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/hostapd/wps-ap-nfc.py b/hostapd/wps-ap-nfc.py
new file mode 100755
index 0000000..32a0214
--- /dev/null
+++ b/hostapd/wps-ap-nfc.py
@@ -0,0 +1,273 @@
+#!/usr/bin/python
+#
+# Example nfcpy to hostapd wrapper for WPS NFC operations
+# 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 nfc
+import nfc.ndef
+import nfc.llcp
+import nfc.handover
+
+import logging
+logging.basicConfig()
+
+import wpactrl
+
+wpas_ctrl = '/var/run/hostapd'
+
+def wpas_connect():
+ ifaces = []
+ if os.path.isdir(wpas_ctrl):
+ try:
+ ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
+ except OSError, error:
+ print "Could not find hostapd: ", error
+ return None
+
+ if len(ifaces) < 1:
+ print "No hostapd control interface found"
+ return None
+
+ for ctrl in ifaces:
+ try:
+ wpas = wpactrl.WPACtrl(ctrl)
+ return wpas
+ except wpactrl.error, error:
+ print "Error: ", error
+ pass
+ return None
+
+
+def wpas_tag_read(message):
+ wpas = wpas_connect()
+ if (wpas == None):
+ return
+ print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
+
+
+def wpas_get_config_token():
+ wpas = wpas_connect()
+ if (wpas == None):
+ return None
+ return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
+
+
+def wpas_get_password_token():
+ wpas = wpas_connect()
+ if (wpas == None):
+ return None
+ return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
+
+
+def wpas_get_handover_sel():
+ wpas = wpas_connect()
+ if (wpas == None):
+ return None
+ return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
+
+
+def wpas_report_handover(req, sel):
+ wpas = wpas_connect()
+ if (wpas == None):
+ return None
+ return wpas.request("NFC_REPORT_HANDOVER RESP WPS " +
+ str(req).encode("hex") + " " +
+ str(sel).encode("hex"))
+
+
+class HandoverServer(nfc.handover.HandoverServer):
+ def __init__(self):
+ super(HandoverServer, self).__init__()
+
+ def process_request(self, request):
+ print "HandoverServer - request received"
+ print "Parsed handover request: " + request.pretty()
+
+ sel = nfc.ndef.HandoverSelectMessage(version="1.2")
+
+ for carrier in request.carriers:
+ print "Remote carrier type: " + carrier.type
+ if carrier.type == "application/vnd.wfa.wsc":
+ print "WPS carrier type match - add WPS carrier record"
+ self.received_carrier = carrier.record
+ data = wpas_get_handover_sel()
+ if data is None:
+ print "Could not get handover select carrier record from hostapd"
+ continue
+ print "Handover select carrier record from hostapd:"
+ print data.encode("hex")
+ self.sent_carrier = data
+
+ message = nfc.ndef.Message(data);
+ sel.add_carrier(message[0], "active", message[1:])
+
+ print "Handover select:"
+ print sel.pretty()
+ print str(sel).encode("hex")
+
+ print "Sending handover select"
+ return sel
+
+
+def wps_handover_resp(peer):
+ print "Trying to handle WPS handover"
+
+ srv = HandoverServer()
+
+ nfc.llcp.activate(peer);
+
+ try:
+ print "Trying handover";
+ srv.start()
+ print "Wait for disconnect"
+ while nfc.llcp.connected():
+ time.sleep(0.1)
+ print "Disconnected after handover"
+ except nfc.llcp.ConnectRefused:
+ print "Handover connection refused"
+ nfc.llcp.shutdown()
+ return
+
+ if srv.sent_carrier:
+ wpas_report_handover(srv.received_carrier, srv.sent_carrier)
+
+ print "Remove peer"
+ nfc.llcp.shutdown()
+ print "Done with handover"
+
+
+def wps_tag_read(tag):
+ if len(tag.ndef.message):
+ message = nfc.ndef.Message(tag.ndef.message)
+ print "message type " + message.type
+
+ for record in message:
+ print "record type " + record.type
+ if record.type == "application/vnd.wfa.wsc":
+ print "WPS tag - send to hostapd"
+ wpas_tag_read(tag.ndef.message)
+ break
+ else:
+ print "Empty tag"
+
+ print "Remove tag"
+ while tag.is_present:
+ time.sleep(0.1)
+
+
+def wps_write_config_tag(clf):
+ print "Write WPS config token"
+ data = wpas_get_config_token()
+ if (data == None):
+ print "Could not get WPS config token from hostapd"
+ return
+
+ print "Touch an NFC tag"
+ while True:
+ tag = clf.poll()
+ if tag == None:
+ time.sleep(0.1)
+ continue
+ break
+
+ print "Tag found - writing"
+ tag.ndef.message = data
+ print "Done - remove tag"
+ while tag.is_present:
+ time.sleep(0.1)
+
+
+def wps_write_password_tag(clf):
+ print "Write WPS password token"
+ data = wpas_get_password_token()
+ if (data == None):
+ print "Could not get WPS password token from hostapd"
+ return
+
+ print "Touch an NFC tag"
+ while True:
+ tag = clf.poll()
+ if tag == None:
+ time.sleep(0.1)
+ continue
+ break
+
+ print "Tag found - writing"
+ tag.ndef.message = data
+ print "Done - remove tag"
+ while tag.is_present:
+ 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()
+
+ try:
+ if len(sys.argv) > 1 and sys.argv[1] == "write-config":
+ wps_write_config_tag(clf)
+ raise SystemExit
+
+ if len(sys.argv) > 1 and sys.argv[1] == "write-password":
+ wps_write_password_tag(clf)
+ raise SystemExit
+
+ while True:
+ print "Waiting for a tag or peer to be touched"
+
+ tag = find_peer(clf)
+ if isinstance(tag, nfc.DEP):
+ wps_handover_resp(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
+ finally:
+ clf.close()
+
+ raise SystemExit
+
+if __name__ == '__main__':
+ main()