1#!/usr/bin/python
2# Tests p2p_group_add
3######### MAY NEED TO RUN AS SUDO #############
4
5import dbus
6import sys, os
7import time
8import gobject
9import getopt
10import threading
11from dbus.mainloop.glib import DBusGMainLoop
12
13def usage():
14	print("Usage:")
15	print("  %s -i <interface_name> [-p <persistent>] \ " \
16		% sys.argv[0])
17	print("		[-f <frequency>] [-o <group_object_path>] \ ")
18	print("  		[-w <wpas_dbus_interface>]")
19	print("Options:")
20	print("  -i = interface name")
21	print("  -p = persistant group = 0 (0=false, 1=true)")
22	print("  -f = frequency")
23	print("  -o = persistent group object path")
24	print("  -w = wpas dbus interface = fi.w1.wpa_supplicant1")
25	print("Example:")
26	print("  %s -i wlan0" % sys.argv[0])
27
28# Required Signals
29def GroupStarted(properties):
30	if properties.has_key("group_object"):
31		print('Group Formation Complete %s' \
32			% properties["group_object"])
33	os._exit(0)
34
35def WpsFailure(status, etc):
36	print("WPS Authentication Failure".format(status))
37	print(etc)
38	os._exit(0)
39
40class P2P_Group_Add (threading.Thread):
41	# Needed Variables
42	global bus
43	global wpas_object
44	global interface_object
45	global p2p_interface
46	global interface_name
47	global wpas
48	global wpas_dbus_interface
49	global path
50	global persistent
51	global frequency
52	global persistent_group_object
53
54	# Dbus Paths
55	global wpas_dbus_opath
56	global wpas_dbus_interfaces_opath
57	global wpas_dbus_interfaces_interface
58	global wpas_dbus_interfaces_p2pdevice
59
60	# Arguements
61	global P2PDictionary
62
63	# Constructor
64	def __init__(self,interface_name,wpas_dbus_interface,persistent,frequency,
65						persistent_group_object):
66		# Initializes variables and threads
67		self.interface_name = interface_name
68		self.wpas_dbus_interface = wpas_dbus_interface
69		self.persistent = persistent
70		self.frequency = frequency
71		self.persistent_group_object = persistent_group_object
72
73		# Initializes thread and daemon allows for ctrl-c kill
74		threading.Thread.__init__(self)
75		self.daemon = True
76
77		# Generating interface/object paths
78		self.wpas_dbus_opath = "/" + \
79				self.wpas_dbus_interface.replace(".","/")
80		self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
81				"/Interfaces"
82		self.wpas_dbus_interfaces_interface = \
83				self.wpas_dbus_interface + ".Interface"
84		self.wpas_dbus_interfaces_p2pdevice = \
85				self.wpas_dbus_interfaces_interface \
86				+ ".P2PDevice"
87
88		# Getting interfaces and objects
89		DBusGMainLoop(set_as_default=True)
90		self.bus = dbus.SystemBus()
91		self.wpas_object = self.bus.get_object(
92				self.wpas_dbus_interface,
93				self.wpas_dbus_opath)
94		self.wpas = dbus.Interface(self.wpas_object,
95				self.wpas_dbus_interface)
96
97		# Try to see if supplicant knows about interface
98		# If not, throw an exception
99		try:
100			self.path = self.wpas.GetInterface(
101					self.interface_name)
102		except dbus.DBusException as exc:
103			error = 'Error:\n  Interface ' + self.interface_name \
104				+ ' was not found'
105			print(error)
106			usage()
107			os._exit(0)
108
109		self.interface_object = self.bus.get_object(
110				self.wpas_dbus_interface, self.path)
111		self.p2p_interface = dbus.Interface(self.interface_object,
112				self.wpas_dbus_interfaces_p2pdevice)
113
114		#Adds listeners
115		self.bus.add_signal_receiver(GroupStarted,
116			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
117			signal_name="GroupStarted")
118		self.bus.add_signal_receiver(WpsFailure,
119			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
120			signal_name="WpsFailed")
121
122		# Sets up p2p_group_add dictionary
123	def constructArguements(self):
124		self.P2PDictionary = {'persistent':self.persistent}
125
126		if (self.frequency != None):
127			if (int(self.frequency) > 0):
128				self.P2PDictionary.update({'frequency':int(self.frequency)})
129			else:
130				print("Error:\n  Frequency must be greater than 0")
131				usage()
132				os._exit(0)
133
134		if (self.persistent_group_object != None):
135			self.P2PDictionary.update({'persistent_group_object':
136						self.persistent_group_object})
137
138	# Run p2p_group_remove
139	def run(self):
140		try:
141			self.p2p_interface.GroupAdd(self.P2PDictionary)
142
143		except:
144			print("Error:\n  Could not preform group add")
145			usage()
146			os._exit(0)
147
148		# Allows other threads to keep working while MainLoop runs
149		# Required for timeout implementation
150		gobject.MainLoop().get_context().iteration(True)
151		gobject.threads_init()
152		gobject.MainLoop().run()
153
154
155if __name__ == "__main__":
156
157	# Defaults for optional inputs
158	# 0 = false, 1 = true
159	persistent = False
160	frequency = None
161	persistent_group_object = None
162	wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
163
164	# interface_name is required
165	interface_name = None
166
167	# Using getopts to handle options
168	try:
169		options, args = getopt.getopt(sys.argv[1:],"hi:p:f:o:w:")
170
171	except getopt.GetoptError:
172		usage()
173		quit()
174
175	# If theres a switch, override default option
176	for key, value in options:
177		# Help
178		if (key == "-h"):
179			usage()
180			quit()
181		# Interface Name
182		elif (key == "-i"):
183			interface_name = value
184		# Timeout
185		elif (key == "-p"):
186			if (value == '0'):
187				persistent = False
188			elif (value == '1'):
189				persistent = True
190			else:
191				print("Error:\n  Persistent can only be 1 or 0")
192				usage()
193				os._exit(0)
194		# Frequency
195		elif (key == "-f"):
196			frequency = value
197		# Persistent group object path
198		elif (key == "-o"):
199			persistent_group_object = value
200		# Dbus interface
201		elif (key == "-w"):
202			wpas_dbus_interface = value
203		else:
204			assert False, "unhandled option"
205
206	# Interface name is required and was not given
207	if (interface_name == None):
208		print("Error:\n  interface_name is required")
209		usage()
210		quit()
211
212	try:
213		p2p_group_add_test = P2P_Group_Add(interface_name,wpas_dbus_interface,
214					persistent,frequency,persistent_group_object)
215	except:
216		print("Error:\n  Invalid Arguements")
217
218	p2p_group_add_test.constructArguements()
219	p2p_group_add_test.start()
220	time.sleep(5)
221	print("Error:\n  Group formation timed out")
222	os._exit(0)
223