161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#!/usr/bin/python
261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt# Tests P2P_Find
361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt# Will listen
461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt# Then Program will exit
561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt######### MAY NEED TO RUN AS SUDO #############
661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport dbus
861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport sys, os
961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport time
1061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport gobject
1161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport threading
1261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtimport getopt
1361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfrom dbus.mainloop.glib import DBusGMainLoop
1461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtdef usage():
1661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "Usage:"
1761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  %s -i <interface_name> [-t <timeout>] \ " \
1861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		% sys.argv[0]
1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  		[-w <wpas_dbus_interface>]"
2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "Options:"
2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  -i = interface name"
2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  -t = timeout = 0s (infinite)"
2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  -w = wpas dbus interface = fi.w1.wpa_supplicant1"
2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "Example:"
2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print "  %s -i wlan0 -t 5" % sys.argv[0]
2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
2761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt# Required Signals
2861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtdef p2pStateChange(status):
2961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	print status
3061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
3161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtclass P2P_Listen(threading.Thread):
3261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Needed Variables
3361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global bus
3461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_object
3561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global interface_object
3661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global p2p_interface
3761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global interface_name
3861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas
3961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_dbus_interface
4061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global path
4161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global timeout
4261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
4361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Dbus Paths
4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_dbus_opath
4561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_dbus_interfaces_opath
4661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_dbus_interfaces_interface
4761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global wpas_dbus_interfaces_p2pdevice
4861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
4961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Constructor
5061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	def __init__(self,interface_name,wpas_dbus_interface,timeout):
5161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Initializes variables and threads
5261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.timeout = int(timeout)
5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.interface_name = interface_name
5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_dbus_interface = wpas_dbus_interface
5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Initializes thread and daemon allows for ctrl-c kill
5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		threading.Thread.__init__(self)
5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.daemon = True
5961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Generating interface/object paths
6161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_dbus_opath = "/" + \
6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interface.replace(".","/")
6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_wpas_dbus_interfaces_opath = self.wpas_dbus_opath + \
6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"/Interfaces"
6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_dbus_interfaces_interface = \
6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interface + ".Interface"
6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_dbus_interfaces_p2pdevice = \
6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interfaces_interface \
6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				+ ".P2PDevice"
7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Getting interfaces and objects
7261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		DBusGMainLoop(set_as_default=True)
7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.bus = dbus.SystemBus()
7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas_object = self.bus.get_object(
7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interface,
7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_opath)
7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.wpas = dbus.Interface(self.wpas_object,
7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interface)
7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
8061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Try to see if supplicant knows about interface
8161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# If not, throw an exception
8261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		try:
8361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			self.path = self.wpas.GetInterface(
8461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					self.interface_name)
8561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		except dbus.DBusException, exc:
8661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			error = 'Error:\n  Interface ' + self.interface_name \
8761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				+ ' was not found'
8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			print error
8961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			usage()
9061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os._exit(0)
9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.interface_object = self.bus.get_object(
9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interface, self.path)
9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.p2p_interface = dbus.Interface(self.interface_object,
9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				self.wpas_dbus_interfaces_p2pdevice)
9661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
9761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.bus.add_signal_receiver(p2pStateChange,
9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			dbus_interface=self.wpas_dbus_interfaces_p2pdevice,
9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			signal_name="P2PStateChanged")
10061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
10161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Run p2p_find
10261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	def run(self):
10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Sets up p2p_listen
10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		self.p2p_interface.Listen(int(self.timeout))
10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Allows other threads to keep working while MainLoop runs
10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Required for timeout implementation
10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		gobject.MainLoop().get_context().iteration(True)
10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		gobject.threads_init()
11061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		gobject.MainLoop().run()
11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtif __name__ == "__main__":
11361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Defaults for optional inputs
11561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	timeout = 0
11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_dbus_interface = 'fi.w1.wpa_supplicant1'
11761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
11861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# interface_name is required
11961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interface_name = None
12061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
12161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Using getopts to handle options
12261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	try:
12361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		options, args = getopt.getopt(sys.argv[1:],"hi:t:w:")
12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
12561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	except getopt.GetoptError:
12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		usage()
12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		quit()
12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# If theres a switch, override default option
13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	for key, value in options:
13161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Help
13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (key == "-h"):
13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			usage()
13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			quit()
13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Interface Name
13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		elif (key == "-i"):
13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			interface_name = value
13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Timeout
13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		elif (key == "-t"):
14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if ( int(value) >= 0):
14161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				timeout = value
14261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			else:
14361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				print "Error:\n  Timeout cannot be negative"
14461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				usage()
14561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				quit()
14661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Dbus interface
14761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		elif (key == "-w"):
14861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpas_dbus_interface = value
14961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		else:
15061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			assert False, "unhandled option"
15161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Interface name is required and was not given
15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (interface_name == None):
15461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		print "Error:\n  interface_name is required"
15561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		usage()
15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		quit()
15761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Constructor
15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	try:
16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		p2p_listen_test = P2P_Listen(interface_name, wpas_dbus_interface, timeout)
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	except:
16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		print "Error:\n  Invalid wpas_dbus_interface"
16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		usage()
16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		quit()
16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	# Start P2P_Find
16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	p2p_listen_test.start()
16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	try:
17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# If timeout is 0, then run forever
17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (int(p2p_listen_test.timeout) == 0):
17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			while(True):
17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				pass
17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		# Else sleep for (timeout)
17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		else:
17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			time.sleep(int(p2p_listen_test.timeout))
17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	except:
18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pass
18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
18261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	quit()
183