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