1#!/usr/bin/python
2# Tests p2p_find
3# Will list all devices found/lost within a time frame (timeout)
4# Then Program will exit
5######### MAY NEED TO RUN AS SUDO #############
6
7import dbus
8import sys, os
9import time
10import gobject
11import threading
12import getopt
13from dbus.mainloop.glib import DBusGMainLoop
14
15def usage():
16	print("Usage:")
17	print("  %s -i <interface_name> [-t <timeout>] \ " \
18		% sys.argv[0])
19	print("  		[-w <wpas_dbus_interface>]")
20	print("Options:")
21	print("  -i = interface name")
22	print("  -t = timeout = 0s (infinite)")
23	print("  -w = wpas dbus interface = fi.w1.wpa_supplicant1")
24	print("Example:")
25	print("  %s -i wlan0 -t 10" % sys.argv[0])
26
27# Required Signals
28def deviceFound(devicepath):
29	print("Device found: %s" % (devicepath))
30
31def deviceLost(devicepath):
32	print("Device lost: %s" % (devicepath))
33
34class P2P_Find (threading.Thread):
35	# Needed Variables
36	global bus
37	global wpas_object
38	global interface_object
39	global p2p_interface
40	global interface_name
41	global wpas
42	global wpas_dbus_interface
43	global timeout
44	global path
45
46	# Dbus Paths
47	global wpas_dbus_opath
48	global wpas_dbus_interfaces_opath
49	global wpas_dbus_interfaces_interface
50	global wpas_dbus_interfaces_p2pdevice
51
52	# Constructor
53	def __init__(self,interface_name,wpas_dbus_interface,timeout):
54		# Initializes variables and threads
55		self.timeout = int(timeout)
56		self.interface_name = interface_name
57		self.wpas_dbus_interface = wpas_dbus_interface
58
59		# Initializes thread and daemon allows for ctrl-c kill
60		threading.Thread.__init__(self)
61		self.daemon = True
62
63		# Generating interface/object paths
64		self.wpas_dbus_opath = "/" + \
65				self.wpas_dbus_interface.replace(".","/")
66		self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
67				"/Interfaces"
68		self.wpas_dbus_interfaces_interface = \
69				self.wpas_dbus_interface + ".Interface"
70		self.wpas_dbus_interfaces_p2pdevice = \
71				self.wpas_dbus_interfaces_interface \
72				+ ".P2PDevice"
73
74		# Getting interfaces and objects
75		DBusGMainLoop(set_as_default=True)
76		self.bus = dbus.SystemBus()
77		self.wpas_object = self.bus.get_object(
78				self.wpas_dbus_interface,
79				self.wpas_dbus_opath)
80		self.wpas = dbus.Interface(self.wpas_object,
81				self.wpas_dbus_interface)
82
83		# Try to see if supplicant knows about interface
84		# If not, throw an exception
85		try:
86			self.path = self.wpas.GetInterface(
87					self.interface_name)
88		except dbus.DBusException as exc:
89			error = 'Error:\n  Interface ' + self.interface_name \
90				+ ' was not found'
91			print(error)
92			usage()
93			os._exit(0)
94
95		self.interface_object = self.bus.get_object(
96				self.wpas_dbus_interface, self.path)
97		self.p2p_interface = dbus.Interface(self.interface_object,
98				self.wpas_dbus_interfaces_p2pdevice)
99
100		#Adds listeners for find and lost
101		self.bus.add_signal_receiver(deviceFound,
102			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
103			signal_name="DeviceFound")
104		self.bus.add_signal_receiver(deviceLost,
105			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
106			signal_name="DeviceLost")
107
108
109		# Sets up p2p_find
110		P2PFindDict = dbus.Dictionary(
111				{'Timeout':int(self.timeout)})
112		self.p2p_interface.Find(P2PFindDict)
113
114	# Run p2p_find
115	def run(self):
116		# Allows other threads to keep working while MainLoop runs
117		# Required for timeout implementation
118		gobject.MainLoop().get_context().iteration(True)
119		gobject.threads_init()
120		gobject.MainLoop().run()
121
122if __name__ == "__main__":
123
124	# Defaults for optional inputs
125	timeout = 0
126	wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
127
128	# interface_name is required
129	interface_name = None
130
131	# Using getopts to handle options
132	try:
133		options, args = getopt.getopt(sys.argv[1:],"hi:t:w:")
134
135	except getopt.GetoptError:
136		usage()
137		quit()
138
139	# If theres a switch, override default option
140	for key, value in options:
141		# Help
142		if (key == "-h"):
143			usage()
144			quit()
145		# Interface Name
146		elif (key == "-i"):
147			interface_name = value
148		# Timeout
149		elif (key == "-t"):
150			if ( int(value) >= 0):
151				timeout = value
152			else:
153				print("Error:\n  Timeout cannot be negative")
154				usage()
155				quit()
156		# Dbus interface
157		elif (key == "-w"):
158			wpas_dbus_interface = value
159		else:
160			assert False, "unhandled option"
161
162	# Interface name is required and was not given
163	if (interface_name == None):
164		print("Error:\n  interface_name is required")
165		usage()
166		quit()
167
168	# Constructor
169	try:
170		p2p_find_test = P2P_Find(interface_name, wpas_dbus_interface, timeout)
171
172	except:
173		print("Error:\n  Invalid wpas_dbus_interface")
174		usage()
175		quit()
176
177	# Start P2P_Find
178	p2p_find_test.start()
179
180	try:
181		# If timeout is 0, then run forever
182		if (timeout == 0):
183			while(True):
184				pass
185		# Else sleep for (timeout)
186		else:
187			time.sleep(p2p_find_test.timeout)
188
189	except:
190		pass
191
192	quit()
193