1#!/usr/bin/python
2# Tests p2p_invite
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> -a <addr> \ " \
16		% sys.argv[0])
17	print("		[-o <persistent_group_object>] [-w <wpas_dbus_interface>]")
18	print("Options:")
19	print("  -i = interface name")
20	print("  -a = address of peer")
21	print("  -o = persistent group object path")
22	print("  -w = wpas dbus interface = fi.w1.wpa_supplicant1")
23	print("Example:")
24	print("  %s -i p2p-wlan0-0 -a 00150083523c" % sys.argv[0])
25
26# Required Signals
27def InvitationResult(invite_result):
28	print("Invitation Result signal :")
29	status = invite_result['status']
30	print("status = ", status)
31	if invite_result.has_key('BSSID'):
32		bssid = invite_result['BSSID']
33		print("BSSID = ", hex(bssid[0]) , ":" , \
34		 hex(bssid[1]) , ":" , hex(bssid[2]) , ":", \
35		 hex(bssid[3]) , ":" , hex(bssid[4]) , ":" , \
36		hex(bssid[5]))
37	os._exit(0)
38
39class P2P_Invite (threading.Thread):
40	# Needed Variables
41	global bus
42	global wpas_object
43	global interface_object
44	global p2p_interface
45	global interface_name
46	global wpas
47	global wpas_dbus_interface
48	global path
49	global addr
50	global persistent_group_object
51
52	# Dbus Paths
53	global wpas_dbus_opath
54	global wpas_dbus_interfaces_opath
55	global wpas_dbus_interfaces_interface
56	global wpas_dbus_interfaces_p2pdevice
57
58	# Arguments
59	global P2PDictionary
60
61	# Constructor
62	def __init__(self,interface_name,wpas_dbus_interface,addr,
63						persistent_group_object):
64		# Initializes variables and threads
65		self.interface_name = interface_name
66		self.wpas_dbus_interface = wpas_dbus_interface
67		self.addr = addr
68		self.persistent_group_object = persistent_group_object
69
70		# Initializes thread and daemon allows for ctrl-c kill
71		threading.Thread.__init__(self)
72		self.daemon = True
73
74		# Generating interface/object paths
75		self.wpas_dbus_opath = "/" + \
76				self.wpas_dbus_interface.replace(".","/")
77		self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
78				"/Interfaces"
79		self.wpas_dbus_interfaces_interface = \
80				self.wpas_dbus_interface + ".Interface"
81		self.wpas_dbus_interfaces_p2pdevice = \
82				self.wpas_dbus_interfaces_interface \
83				+ ".P2PDevice"
84
85		# Getting interfaces and objects
86		DBusGMainLoop(set_as_default=True)
87		self.bus = dbus.SystemBus()
88		self.wpas_object = self.bus.get_object(
89				self.wpas_dbus_interface,
90				self.wpas_dbus_opath)
91		self.wpas = dbus.Interface(self.wpas_object,
92				self.wpas_dbus_interface)
93
94		# Try to see if supplicant knows about interface
95		# If not, throw an exception
96		try:
97			self.path = self.wpas.GetInterface(
98					self.interface_name)
99		except dbus.DBusException as exc:
100			error = 'Error:\n  Interface ' + self.interface_name \
101				+ ' was not found'
102			print(error)
103			usage()
104			os._exit(0)
105
106		self.interface_object = self.bus.get_object(
107				self.wpas_dbus_interface, self.path)
108		self.p2p_interface = dbus.Interface(self.interface_object,
109				self.wpas_dbus_interfaces_p2pdevice)
110
111		#Adds listeners
112		self.bus.add_signal_receiver(InvitationResult,
113			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
114			signal_name="InvitationResult")
115
116	# Sets up p2p_invite dictionary
117	def constructArguements(self):
118		self.P2PDictionary = \
119			{'peer':dbus.ObjectPath(self.path+'/Peers/'+self.addr)}
120		if (self.persistent_group_object != None):
121			self.P2PDictionary.update({"persistent_group_object":
122					self.persistent_group_object})
123
124	# Run p2p_invite
125	def run(self):
126		try:
127			self.p2p_interface.Invite(self.P2PDictionary)
128
129		except:
130			print("Error:\n  Invalid Arguments")
131			usage()
132			os._exit(0)
133
134		# Allows other threads to keep working while MainLoop runs
135		# Required for timeout implementation
136		gobject.MainLoop().get_context().iteration(True)
137		gobject.threads_init()
138		gobject.MainLoop().run()
139
140if __name__ == "__main__":
141	# Defaults for optional inputs
142	addr = None
143	persistent_group_object = None
144	wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
145
146	# interface_name is required
147	interface_name = None
148
149	# Using getopts to handle options
150	try:
151		options, args = getopt.getopt(sys.argv[1:],"hi:o:w:a:")
152
153	except getopt.GetoptError:
154		usage()
155		quit()
156
157	# If there's a switch, override default option
158	for key, value in options:
159		# Help
160		if (key == "-h"):
161			usage()
162			quit()
163		# Interface Name
164		elif (key == "-i"):
165			interface_name = value
166		elif (key == "-a"):
167			addr = value
168		# Persistent group object path
169		elif (key == "-o"):
170			persistent_group_object = value
171		# Dbus interface
172		elif (key == "-w"):
173			wpas_dbus_interface = value
174		else:
175			assert False, "unhandled option"
176
177	# Interface name is required and was not given
178	if (interface_name == None):
179		print("Error:\n  interface_name is required")
180		usage()
181		quit()
182
183	if (addr == None):
184		print("Error:\n  peer address is required")
185		usage()
186		quit()
187
188	try:
189		p2p_invite_test = \
190			P2P_Invite(interface_name,wpas_dbus_interface,
191					addr,persistent_group_object)
192	except:
193		print("Error:\n  Invalid Arguments")
194		usage()
195		os._exit(1)
196
197	p2p_invite_test.constructArguements()
198	p2p_invite_test.start()
199	time.sleep(10)
200	print("Error:\n  p2p_invite timed out")
201	os._exit(0)
202