From acc5f4ec60d3cd2f79f6e249b9d249b726667cdc Mon Sep 17 00:00:00 2001 From: Michael Naumov Date: Sat, 30 Jun 2012 13:11:26 +0300 Subject: [PATCH] P2P: Add dbus python scripts to perform p2p_find and p2p_connect Two DBUS scripts using python glib are added to perform p2p_find and p2p_connect operations respectively. p2p_connect script just performs the traditional connect to create a new p2p group. Additional updates will be required to perform join, auth etc. al. Signed-hostap: Michael Naumov Signed-hostap: Nirav Shah --- wpa_supplicant/examples/p2p/p2p_connect.py | 299 +++++++++++++++++++++ wpa_supplicant/examples/p2p/p2p_find.py | 192 +++++++++++++ 2 files changed, 491 insertions(+) create mode 100644 wpa_supplicant/examples/p2p/p2p_connect.py create mode 100644 wpa_supplicant/examples/p2p/p2p_find.py diff --git a/wpa_supplicant/examples/p2p/p2p_connect.py b/wpa_supplicant/examples/p2p/p2p_connect.py new file mode 100644 index 000000000..59b0a9d36 --- /dev/null +++ b/wpa_supplicant/examples/p2p/p2p_connect.py @@ -0,0 +1,299 @@ +#!/usr/bin/python +# Tests p2p_connect +# Will try to connect to another peer +# and form a group +######### MAY NEED TO RUN AS SUDO ############# + +import dbus +import sys, os +import time +import gobject +import getopt +from dbus.mainloop.glib import DBusGMainLoop + + +def usage(): + print "Usage:" + print " %s -i -m \ " \ + % sys.argv[0] + print " -a [-p ] [-g ] \ " + print " [-w ]" + print "Options:" + print " -i = interface name" + print " -m = wps method" + print " -a = peer address" + print " -p = pin number (8 digits)" + print " -g = group owner intent" + print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" + print "Example:" + print " %s -i wlan0 -a 0015008352c0 -m display -p 12345670" % sys.argv[0] + + +# Required Signals +def GONegotiationSuccess(status): + print "Go Negotiation Success" + +def GONegotiationFailure(status): + print 'Go Negotiation Failed. Status:' + print format(status) + os._exit(0) + +def GroupStarted(properties): + if properties.has_key("group_object"): + print 'Group Formation Complete %s' \ + % properties["group_object"] + os._exit(0) + +def WpsFailure(status, etc): + print "WPS Authentication Failure".format(status) + print etc + os._exit(0) + +class P2P_Connect(): + # Needed Variables + global bus + global wpas_object + global interface_object + global p2p_interface + global ifname + global wpas + global wpas_dbus_interface + global timeout + global path + global wps_method + global go_intent + global addr + global pin + + # Dbus Paths + global wpas_dbus_opath + global wpas_dbus_interfaces_opath + global wpas_dbus_interfaces_interface + global wpas_dbus_interfaces_p2pdevice + + # Dictionary of Arguements + global p2p_connect_arguements + + # Constructor + def __init__(self,ifname,wpas_dbus_interface,addr, + pin,wps_method,go_intent): + # Initializes variables and threads + self.ifname = ifname + self.wpas_dbus_interface = wpas_dbus_interface + self.wps_method = wps_method + self.go_intent = go_intent + self.addr = addr + self.pin = pin + + # Generating interface/object paths + self.wpas_dbus_opath = \ + "/" + self.wpas_dbus_interface.replace(".","/") + self.wpas_wpas_dbus_interfaces_opath = \ + self.wpas_dbus_opath + "/Interfaces" + self.wpas_dbus_interfaces_interface = \ + self.wpas_dbus_interface + ".Interface" + self.wpas_dbus_interfaces_p2pdevice = \ + self.wpas_dbus_interfaces_interface + ".P2PDevice" + + # Getting interfaces and objects + DBusGMainLoop(set_as_default=True) + self.bus = dbus.SystemBus() + self.wpas_object = self.bus.get_object( + self.wpas_dbus_interface, + self.wpas_dbus_opath) + self.wpas = dbus.Interface( + self.wpas_object, self.wpas_dbus_interface) + + # See if wpa_supplicant already knows about this interface + self.path = None + try: + self.path = self.wpas.GetInterface(ifname) + except: + if not str(exc).startswith( + self.wpas_dbus_interface + \ + ".InterfaceUnknown:"): + raise exc + try: + path = self.wpas.CreateInterface( + {'Ifname': ifname, 'Driver': 'test'}) + time.sleep(1) + + except dbus.DBusException, exc: + if not str(exc).startswith( + self.wpas_dbus_interface + \ + ".InterfaceExists:"): + raise exc + + # Get Interface and objects + self.interface_object = self.bus.get_object( + self.wpas_dbus_interface,self.path) + self.p2p_interface = dbus.Interface( + self.interface_object, + self.wpas_dbus_interfaces_p2pdevice) + + # Add signals + self.bus.add_signal_receiver(GONegotiationSuccess, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="GONegotiationSuccess") + self.bus.add_signal_receiver(GONegotiationFailure, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="GONegotiationFailure") + self.bus.add_signal_receiver(GroupStarted, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="GroupStarted") + self.bus.add_signal_receiver(WpsFailure, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="WpsFailed") + + + #Constructing all the arguements needed to connect + def constructArguements(self): + # Adding required arguements + self.p2p_connect_arguements = {'wps_method':self.wps_method, + 'peer':dbus.ObjectPath(self.path+'/Peers/'+self.addr)} + + # Display requires a pin, and a go intent of 15 + if (self.wps_method == 'display'): + if (self.pin != None): + self.p2p_connect_arguements.update({'pin':self.pin}) + else: + print "Error:\n Pin required for wps_method=display" + usage() + quit() + + if (self.go_intent != None and int(self.go_intent) != 15): + print "go_intent overwritten to 15" + + self.go_intent = '15' + + # Keypad requires a pin, and a go intent of less than 15 + elif (self.wps_method == 'keypad'): + if (self.pin != None): + self.p2p_connect_arguements.update({'pin':self.pin}) + else: + print "Error:\n Pin required for wps_method=keypad" + usage() + quit() + + if (self.go_intent != None and int(self.go_intent) == 15): + error = "Error :\n Group Owner intent cannot be" + \ + " 15 for wps_method=keypad" + print error + usage() + quit() + + # Doesn't require pin + # for ./wpa_cli, p2p_connect [mac] [pin#], wps_method=keypad + elif (self.wps_method == 'pin'): + if (self.pin != None): + print "pin ignored" + + # No pin is required for pbc so it is ignored + elif (self.wps_method == 'pbc'): + if (self.pin != None): + print "pin ignored" + + else: + print "Error:\n wps_method not supported or does not exist" + usage() + quit() + + # Go_intent is optional for all arguements + if (self.go_intent != None): + self.p2p_connect_arguements.update( + {'go_intent':dbus.Int32(self.go_intent)}) + + # Running p2p_connect + def run(self): + try: + result_pin = self.p2p_interface.Connect( + self.p2p_connect_arguements) + + except dbus.DBusException, exc: + raise exc + + if (self.wps_method == 'pin' and \ + not self.p2p_connect_arguements.has_key('pin') ): + print "Connect return with pin value of %d " % int(result_pin) + gobject.MainLoop().run() + +if __name__ == "__main__": + + # Required + interface_name = None + wps_method = None + addr = None + + # Conditionally optional + pin = None + + # Optional + wpas_dbus_interface = 'fi.w1.wpa_supplicant1' + go_intent = None + + # Using getopts to handle options + try: + options, args = getopt.getopt(sys.argv[1:],"hi:m:a:p:g:w:") + + except getopt.GetoptError: + usage() + quit() + + # If theres a switch, override default option + for key, value in options: + # Help + if (key == "-h"): + usage() + quit() + # Interface Name + elif (key == "-i"): + interface_name = value + # WPS Method + elif (key == "-m"): + wps_method = value + # Address + elif (key == "-a"): + addr = value + # Pin + elif (key == "-p"): + pin = value + # Group Owner Intent + elif (key == "-g"): + go_intent = value + # Dbus interface + elif (key == "-w"): + wpas_dbus_interface = value + else: + assert False, "unhandled option" + + # Required Arguements check + if (interface_name == None or wps_method == None or addr == None): + print "Error:\n Required arguements not specified" + usage() + quit() + + # Group Owner Intent Check + if (go_intent != None and (int(go_intent) > 15 or int(go_intent) < 0) ): + print "Error:\n Group Owner Intent must be between 0 and 15 inclusive" + usage() + quit() + + # Pin Check + if (pin != None and len(pin) != 8): + print "Error:\n Pin is not 8 digits" + usage() + quit() + + try: + p2p_connect_test = P2P_Connect(interface_name,wpas_dbus_interface, + addr,pin,wps_method,go_intent) + + except: + print "Error:\n Invalid Arguements" + usage() + quit() + + p2p_connect_test.constructArguements() + p2p_connect_test.run() + + os._exit(0) diff --git a/wpa_supplicant/examples/p2p/p2p_find.py b/wpa_supplicant/examples/p2p/p2p_find.py new file mode 100644 index 000000000..973d46ab0 --- /dev/null +++ b/wpa_supplicant/examples/p2p/p2p_find.py @@ -0,0 +1,192 @@ +#!/usr/bin/python +# Tests p2p_find +# Will list all devices found/lost within a time frame (timeout) +# Then Program will exit +######### MAY NEED TO RUN AS SUDO ############# + +import dbus +import sys, os +import time +import gobject +import threading +import getopt +from dbus.mainloop.glib import DBusGMainLoop + +def usage(): + print "Usage:" + print " %s -i [-t ] \ " \ + % sys.argv[0] + print " [-w ]" + print "Options:" + print " -i = interface name" + print " -t = timeout = 0s (infinite)" + print " -w = wpas dbus interface = fi.w1.wpa_supplicant1" + print "Example:" + print " %s -i wlan0 -t 10" % sys.argv[0] + +# Required Signals +def deviceFound(devicepath): + print "Device found: %s" % (devicepath) + +def deviceLost(devicepath): + print "Device lost: %s" % (devicepath) + +class P2P_Find (threading.Thread): + # Needed Variables + global bus + global wpas_object + global interface_object + global p2p_interface + global interface_name + global wpas + global wpas_dbus_interface + global timeout + global path + + # Dbus Paths + global wpas_dbus_opath + global wpas_dbus_interfaces_opath + global wpas_dbus_interfaces_interface + global wpas_dbus_interfaces_p2pdevice + + # Constructor + def __init__(self,interface_name,wpas_dbus_interface,timeout): + # Initializes variables and threads + self.timeout = int(timeout) + self.interface_name = interface_name + self.wpas_dbus_interface = wpas_dbus_interface + + # Initializes thread and daemon allows for ctrl-c kill + threading.Thread.__init__(self) + self.daemon = True + + # Generating interface/object paths + self.wpas_dbus_opath = "/" + \ + self.wpas_dbus_interface.replace(".","/") + self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \ + "/Interfaces" + self.wpas_dbus_interfaces_interface = \ + self.wpas_dbus_interface + ".Interface" + self.wpas_dbus_interfaces_p2pdevice = \ + self.wpas_dbus_interfaces_interface \ + + ".P2PDevice" + + # Getting interfaces and objects + DBusGMainLoop(set_as_default=True) + self.bus = dbus.SystemBus() + self.wpas_object = self.bus.get_object( + self.wpas_dbus_interface, + self.wpas_dbus_opath) + self.wpas = dbus.Interface(self.wpas_object, + self.wpas_dbus_interface) + + # Try to see if supplicant knows about interface + # If not, throw an exception + try: + self.path = self.wpas.GetInterface( + self.interface_name) + except dbus.DBusException, exc: + error = 'Error:\n Interface ' + self.interface_name \ + + ' was not found' + print error + usage() + os._exit(0) + + self.interface_object = self.bus.get_object( + self.wpas_dbus_interface, self.path) + self.p2p_interface = dbus.Interface(self.interface_object, + self.wpas_dbus_interfaces_p2pdevice) + + #Adds listeners for find and lost + self.bus.add_signal_receiver(deviceFound, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="DeviceFound") + self.bus.add_signal_receiver(deviceLost, + dbus_interface=self.wpas_dbus_interfaces_p2pdevice, + signal_name="DeviceLost") + + + # Sets up p2p_find + P2PFindDict = dbus.Dictionary( + {'Timeout':int(self.timeout)}) + self.p2p_interface.Find(P2PFindDict) + + # Run p2p_find + def run(self): + # Allows other threads to keep working while MainLoop runs + # Required for timeout implementation + gobject.MainLoop().get_context().iteration(True) + gobject.threads_init() + gobject.MainLoop().run() + +if __name__ == "__main__": + + # Defaults for optional inputs + timeout = 0 + wpas_dbus_interface = 'fi.w1.wpa_supplicant1' + + # interface_name is required + interface_name = None + + # Using getopts to handle options + try: + options, args = getopt.getopt(sys.argv[1:],"hi:t:w:") + + except getopt.GetoptError: + usage() + quit() + + # If theres a switch, override default option + for key, value in options: + # Help + if (key == "-h"): + usage() + quit() + # Interface Name + elif (key == "-i"): + interface_name = value + # Timeout + elif (key == "-t"): + if ( int(value) >= 0): + timeout = value + else: + print "Error:\n Timeout cannot be negative" + usage() + quit() + # Dbus interface + elif (key == "-w"): + wpas_dbus_interface = value + else: + assert False, "unhandled option" + + # Interface name is required and was not given + if (interface_name == None): + print "Error:\n interface_name is required" + usage() + quit() + + # Constructor + try: + p2p_find_test = P2P_Find(interface_name, wpas_dbus_interface, timeout) + + except: + print "Error:\n Invalid wpas_dbus_interface" + usage() + quit() + + # Start P2P_Find + p2p_find_test.start() + + try: + # If timeout is 0, then run forever + if (timeout == 0): + while(True): + pass + # Else sleep for (timeout) + else: + time.sleep(p2p_find_test.timeout) + + except: + pass + + quit()