Patchwork P2P: Adding dbus python scripts to preform p2p_find and p2p_connect

login
register
mail settings
Submitter Michael Naumov
Date June 27, 2012, 9:53 p.m.
Message ID <1340834008-7013-1-git-send-email-michael.naumov@intel.com>
Download mbox | patch
Permalink /patch/167751/
State Accepted
Headers show

Comments

Michael Naumov - June 27, 2012, 9:53 p.m.
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 <michael.naumov@intel.com>
Signed-hostap: Nirav Shah <nirav.j2.shah@intel.com>
---
 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
Jouni Malinen - June 30, 2012, 10:14 a.m.
On Wed, Jun 27, 2012 at 02:53:28PM -0700, Michael Naumov wrote:
> 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.

Thanks, applied.

Patch

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 <interface_name> -m <wps_method> \ " \
+		% sys.argv[0]
+	print "		-a <addr> [-p <pin>] [-g <go_intent>] \ "
+	print "  		[-w <wpas_dbus_interface>]"
+	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 <interface_name> [-t <timeout>] \ " \
+		% sys.argv[0]
+	print "  		[-w <wpas_dbus_interface>]"
+	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()
+
+
+
+