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