wps-nfc.py 3.9 KB

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