From patchwork Wed Jun 27 21:53:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Naumov X-Patchwork-Id: 167751 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "maxx.shmoo.com", Issuer "CA Cert Signing Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id B4EBCB6FF4 for ; Thu, 28 Jun 2012 07:53:28 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B4FCF9D2D4; Wed, 27 Jun 2012 17:53:23 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gCJlk2CHoMkD; Wed, 27 Jun 2012 17:53:23 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 3DB889D2F6; Wed, 27 Jun 2012 17:53:19 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 5FD2B9D2F6 for ; Wed, 27 Jun 2012 17:53:18 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9C0m2prTwofv for ; Wed, 27 Jun 2012 17:53:13 -0400 (EDT) Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 947739D2D4 for ; Wed, 27 Jun 2012 17:53:12 -0400 (EDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 27 Jun 2012 14:53:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.71,315,1320652800"; d="scan'208";a="161492763" Received: from mnaumov-sandybridge-platform.hf.intel.com ([10.10.69.69]) by azsmga001.ch.intel.com with ESMTP; 27 Jun 2012 14:53:10 -0700 From: Michael Naumov To: hostap@lists.shmoo.com Subject: [PATCH] P2P: Adding dbus python scripts to preform p2p_find and p2p_connect Date: Wed, 27 Jun 2012 14:53:28 -0700 Message-Id: <1340834008-7013-1-git-send-email-michael.naumov@intel.com> X-Mailer: git-send-email 1.7.9.5 X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com Two DBUS scripts using python glib are added to preform p2p_find and p2p_connect operations respectively. p2p_connect script just preforms the traditional connect to create a new p2p grou. Additional updates will be required to preform 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 | 196 ++++++++++++++++++ 2 files changed, 495 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 0000000..59b0a9d --- /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 0000000..9ff588c --- /dev/null +++ b/wpa_supplicant/examples/p2p/p2p_find.py @@ -0,0 +1,196 @@ +#!/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() + + + +