p2p_connect.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #!/usr/bin/python
  2. # Tests p2p_connect
  3. # Will try to connect to another peer
  4. # and form a group
  5. ######### MAY NEED TO RUN AS SUDO #############
  6. import dbus
  7. import sys, os
  8. import time
  9. import gobject
  10. import getopt
  11. from dbus.mainloop.glib import DBusGMainLoop
  12. def usage():
  13. print "Usage:"
  14. print " %s -i <interface_name> -m <wps_method> \ " \
  15. % sys.argv[0]
  16. print " -a <addr> [-p <pin>] [-g <go_intent>] \ "
  17. print " [-w <wpas_dbus_interface>]"
  18. print "Options:"
  19. print " -i = interface name"
  20. print " -m = wps method"
  21. print " -a = peer address"
  22. print " -p = pin number (8 digits)"
  23. print " -g = group owner intent"
  24. print " -w = wpas dbus interface = fi.w1.wpa_supplicant1"
  25. print "Example:"
  26. print " %s -i wlan0 -a 0015008352c0 -m display -p 12345670" % sys.argv[0]
  27. # Required Signals
  28. def GONegotiationSuccess(status):
  29. print "Go Negotiation Success"
  30. def GONegotiationFailure(status):
  31. print 'Go Negotiation Failed. Status:'
  32. print format(status)
  33. os._exit(0)
  34. def GroupStarted(properties):
  35. if properties.has_key("group_object"):
  36. print 'Group Formation Complete %s' \
  37. % properties["group_object"]
  38. os._exit(0)
  39. def WpsFailure(status, etc):
  40. print "WPS Authentication Failure".format(status)
  41. print etc
  42. os._exit(0)
  43. class P2P_Connect():
  44. # Needed Variables
  45. global bus
  46. global wpas_object
  47. global interface_object
  48. global p2p_interface
  49. global ifname
  50. global wpas
  51. global wpas_dbus_interface
  52. global timeout
  53. global path
  54. global wps_method
  55. global go_intent
  56. global addr
  57. global pin
  58. # Dbus Paths
  59. global wpas_dbus_opath
  60. global wpas_dbus_interfaces_opath
  61. global wpas_dbus_interfaces_interface
  62. global wpas_dbus_interfaces_p2pdevice
  63. # Dictionary of Arguements
  64. global p2p_connect_arguements
  65. # Constructor
  66. def __init__(self,ifname,wpas_dbus_interface,addr,
  67. pin,wps_method,go_intent):
  68. # Initializes variables and threads
  69. self.ifname = ifname
  70. self.wpas_dbus_interface = wpas_dbus_interface
  71. self.wps_method = wps_method
  72. self.go_intent = go_intent
  73. self.addr = addr
  74. self.pin = pin
  75. # Generating interface/object paths
  76. self.wpas_dbus_opath = \
  77. "/" + self.wpas_dbus_interface.replace(".","/")
  78. self.wpas_wpas_dbus_interfaces_opath = \
  79. self.wpas_dbus_opath + "/Interfaces"
  80. self.wpas_dbus_interfaces_interface = \
  81. self.wpas_dbus_interface + ".Interface"
  82. self.wpas_dbus_interfaces_p2pdevice = \
  83. self.wpas_dbus_interfaces_interface + ".P2PDevice"
  84. # Getting interfaces and objects
  85. DBusGMainLoop(set_as_default=True)
  86. self.bus = dbus.SystemBus()
  87. self.wpas_object = self.bus.get_object(
  88. self.wpas_dbus_interface,
  89. self.wpas_dbus_opath)
  90. self.wpas = dbus.Interface(
  91. self.wpas_object, self.wpas_dbus_interface)
  92. # See if wpa_supplicant already knows about this interface
  93. self.path = None
  94. try:
  95. self.path = self.wpas.GetInterface(ifname)
  96. except:
  97. if not str(exc).startswith(
  98. self.wpas_dbus_interface + \
  99. ".InterfaceUnknown:"):
  100. raise exc
  101. try:
  102. path = self.wpas.CreateInterface(
  103. {'Ifname': ifname, 'Driver': 'test'})
  104. time.sleep(1)
  105. except dbus.DBusException, exc:
  106. if not str(exc).startswith(
  107. self.wpas_dbus_interface + \
  108. ".InterfaceExists:"):
  109. raise exc
  110. # Get Interface and objects
  111. self.interface_object = self.bus.get_object(
  112. self.wpas_dbus_interface,self.path)
  113. self.p2p_interface = dbus.Interface(
  114. self.interface_object,
  115. self.wpas_dbus_interfaces_p2pdevice)
  116. # Add signals
  117. self.bus.add_signal_receiver(GONegotiationSuccess,
  118. dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
  119. signal_name="GONegotiationSuccess")
  120. self.bus.add_signal_receiver(GONegotiationFailure,
  121. dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
  122. signal_name="GONegotiationFailure")
  123. self.bus.add_signal_receiver(GroupStarted,
  124. dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
  125. signal_name="GroupStarted")
  126. self.bus.add_signal_receiver(WpsFailure,
  127. dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
  128. signal_name="WpsFailed")
  129. #Constructing all the arguements needed to connect
  130. def constructArguements(self):
  131. # Adding required arguements
  132. self.p2p_connect_arguements = {'wps_method':self.wps_method,
  133. 'peer':dbus.ObjectPath(self.path+'/Peers/'+self.addr)}
  134. # Display requires a pin, and a go intent of 15
  135. if (self.wps_method == 'display'):
  136. if (self.pin != None):
  137. self.p2p_connect_arguements.update({'pin':self.pin})
  138. else:
  139. print "Error:\n Pin required for wps_method=display"
  140. usage()
  141. quit()
  142. if (self.go_intent != None and int(self.go_intent) != 15):
  143. print "go_intent overwritten to 15"
  144. self.go_intent = '15'
  145. # Keypad requires a pin, and a go intent of less than 15
  146. elif (self.wps_method == 'keypad'):
  147. if (self.pin != None):
  148. self.p2p_connect_arguements.update({'pin':self.pin})
  149. else:
  150. print "Error:\n Pin required for wps_method=keypad"
  151. usage()
  152. quit()
  153. if (self.go_intent != None and int(self.go_intent) == 15):
  154. error = "Error :\n Group Owner intent cannot be" + \
  155. " 15 for wps_method=keypad"
  156. print error
  157. usage()
  158. quit()
  159. # Doesn't require pin
  160. # for ./wpa_cli, p2p_connect [mac] [pin#], wps_method=keypad
  161. elif (self.wps_method == 'pin'):
  162. if (self.pin != None):
  163. print "pin ignored"
  164. # No pin is required for pbc so it is ignored
  165. elif (self.wps_method == 'pbc'):
  166. if (self.pin != None):
  167. print "pin ignored"
  168. else:
  169. print "Error:\n wps_method not supported or does not exist"
  170. usage()
  171. quit()
  172. # Go_intent is optional for all arguements
  173. if (self.go_intent != None):
  174. self.p2p_connect_arguements.update(
  175. {'go_intent':dbus.Int32(self.go_intent)})
  176. # Running p2p_connect
  177. def run(self):
  178. try:
  179. result_pin = self.p2p_interface.Connect(
  180. self.p2p_connect_arguements)
  181. except dbus.DBusException, exc:
  182. raise exc
  183. if (self.wps_method == 'pin' and \
  184. not self.p2p_connect_arguements.has_key('pin') ):
  185. print "Connect return with pin value of %d " % int(result_pin)
  186. gobject.MainLoop().run()
  187. if __name__ == "__main__":
  188. # Required
  189. interface_name = None
  190. wps_method = None
  191. addr = None
  192. # Conditionally optional
  193. pin = None
  194. # Optional
  195. wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
  196. go_intent = None
  197. # Using getopts to handle options
  198. try:
  199. options, args = getopt.getopt(sys.argv[1:],"hi:m:a:p:g:w:")
  200. except getopt.GetoptError:
  201. usage()
  202. quit()
  203. # If theres a switch, override default option
  204. for key, value in options:
  205. # Help
  206. if (key == "-h"):
  207. usage()
  208. quit()
  209. # Interface Name
  210. elif (key == "-i"):
  211. interface_name = value
  212. # WPS Method
  213. elif (key == "-m"):
  214. wps_method = value
  215. # Address
  216. elif (key == "-a"):
  217. addr = value
  218. # Pin
  219. elif (key == "-p"):
  220. pin = value
  221. # Group Owner Intent
  222. elif (key == "-g"):
  223. go_intent = value
  224. # Dbus interface
  225. elif (key == "-w"):
  226. wpas_dbus_interface = value
  227. else:
  228. assert False, "unhandled option"
  229. # Required Arguements check
  230. if (interface_name == None or wps_method == None or addr == None):
  231. print "Error:\n Required arguements not specified"
  232. usage()
  233. quit()
  234. # Group Owner Intent Check
  235. if (go_intent != None and (int(go_intent) > 15 or int(go_intent) < 0) ):
  236. print "Error:\n Group Owner Intent must be between 0 and 15 inclusive"
  237. usage()
  238. quit()
  239. # Pin Check
  240. if (pin != None and len(pin) != 8):
  241. print "Error:\n Pin is not 8 digits"
  242. usage()
  243. quit()
  244. try:
  245. p2p_connect_test = P2P_Connect(interface_name,wpas_dbus_interface,
  246. addr,pin,wps_method,go_intent)
  247. except:
  248. print "Error:\n Invalid Arguements"
  249. usage()
  250. quit()
  251. p2p_connect_test.constructArguements()
  252. p2p_connect_test.run()
  253. os._exit(0)