18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#!/usr/bin/python
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport dbus
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport sys, os
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport time
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport gobject
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfrom dbus.mainloop.glib import DBusGMainLoop
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACE = "fi.w1.wpa_supplicant1"
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_OPATH = "/fi/w1/wpa_supplicant1"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACES_INTERFACE = "fi.w1.wpa_supplicant1.Interface"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_INTERFACES_OPATH = "/fi/w1/wpa_supplicant1/Interfaces"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtWPAS_DBUS_BSS_INTERFACE = "fi.w1.wpa_supplicant1.BSS"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef byte_array_to_string(s):
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	import urllib
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r = ""
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for c in s:
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if c >= 32 and c < 127:
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r += "%c" % c
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else:
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r += urllib.quote(chr(c))
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return r
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef list_interfaces(wpas_obj):
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ifaces = wpas_obj.Get(WPAS_DBUS_INTERFACE, 'Interfaces',
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      dbus_interface=dbus.PROPERTIES_IFACE)
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for path in ifaces:
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ifname = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'Ifname',
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      dbus_interface=dbus.PROPERTIES_IFACE)
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		print ifname
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef propertiesChanged(properties):
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if properties.has_key("State"):
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		print "PropertiesChanged: State: %s" % (properties["State"])
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef showBss(bss):
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	net_obj = bus.get_object(WPAS_DBUS_SERVICE, bss)
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	net = dbus.Interface(net_obj, WPAS_DBUS_BSS_INTERFACE)
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	# Convert the byte-array for SSID and BSSID to printable strings
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'BSSID',
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  dbus_interface=dbus.PROPERTIES_IFACE)
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid = ""
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for item in val:
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = bssid + ":%02x" % item
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid = bssid[1:]
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'SSID',
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  dbus_interface=dbus.PROPERTIES_IFACE)
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = byte_array_to_string(val)
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA',
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  dbus_interface=dbus.PROPERTIES_IFACE)
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa = "no"
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if len(val["KeyMgmt"]) > 0:
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa = "yes"
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN',
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  dbus_interface=dbus.PROPERTIES_IFACE)
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa2 = "no"
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if len(val["KeyMgmt"]) > 0:
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa2 = "yes"
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency',
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   dbus_interface=dbus.PROPERTIES_IFACE)
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	signal = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Signal',
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     dbus_interface=dbus.PROPERTIES_IFACE)
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Rates',
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  dbus_interface=dbus.PROPERTIES_IFACE)
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if len(val) > 0:
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		maxrate = val[0] / 1000000
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else:
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		maxrate = 0
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	print "  %s  ::  ssid='%s'  wpa=%s  wpa2=%s  signal=%d  rate=%d  freq=%d" % (bssid, ssid, wpa, wpa2, signal, maxrate, freq)
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef scanDone(success):
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	print "Scan done: success=%s" % success
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = if_obj.Get(WPAS_DBUS_INTERFACES_INTERFACE, 'BSSs',
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 dbus_interface=dbus.PROPERTIES_IFACE)
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	print "Scanned wireless networks:"
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for opath in res:
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		print opath
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		showBss(opath)
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef bssAdded(bss, properties):
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	print "BSS added: %s" % (bss)
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	showBss(bss)
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef bssRemoved(bss):
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	print "BSS removed: %s" % (bss)
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdef main():
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global bus
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bus = dbus.SystemBus()
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if len(sys.argv) != 2:
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		list_interfaces(wpas_obj)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os._exit(1)
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bus.add_signal_receiver(scanDone,
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				signal_name="ScanDone")
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bus.add_signal_receiver(bssAdded,
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				signal_name="BSSAdded")
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bus.add_signal_receiver(bssRemoved,
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				signal_name="BSSRemoved")
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bus.add_signal_receiver(propertiesChanged,
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				dbus_interface=WPAS_DBUS_INTERFACES_INTERFACE,
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				signal_name="PropertiesChanged")
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ifname = sys.argv[1]
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	# See if wpa_supplicant already knows about this interface
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	path = None
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	try:
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		path = wpas.GetInterface(ifname)
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	except dbus.DBusException, exc:
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceUnknown:"):
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			raise exc
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		try:
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			path = wpas.CreateInterface({'Ifname': ifname, 'Driver': 'test'})
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			time.sleep(1)
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		except dbus.DBusException, exc:
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if not str(exc).startswith("fi.w1.wpa_supplicant1.InterfaceExists:"):
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				raise exc
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global if_obj
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global iface
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface.Scan({'Type': 'active'})
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	gobject.MainLoop().run()
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas.RemoveInterface(dbus.ObjectPath(path))
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtif __name__ == "__main__":
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	main()
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
150