#!/usr/bin/python
# Script for testing the Attribute D-Bus API

import sys
from optparse import OptionParser, OptionValueError
from binascii import hexlify, unhexlify

import gobject

import sys
import dbus
import dbus.mainloop.glib
from optparse import OptionParser, make_option

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
mainloop = gobject.MainLoop()

manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.bluez.Manager")

option_list = [
		make_option("-i", "--device", action="store",
				type="string", dest="dev_id"),
		]
parser = OptionParser(option_list=option_list)

(options, args) = parser.parse_args()

if options.dev_id:
	adapter_path = manager.FindAdapter(options.dev_id)
else:
	adapter_path = manager.DefaultAdapter()

adapter = dbus.Interface(bus.get_object("org.bluez", adapter_path),
							"org.bluez.Adapter")

if (len(args) < 1):
	print "Usage: %s <command>" % (sys.argv[0])
	print ""
	print "	 list"
	print "	 services <address>"
	print "	 discover <service path>"
	print "	 chars <service path>"
	sys.exit(1)

if (args[0] == "list"):
	for path in adapter.ListDevices():
		device = dbus.Interface(bus.get_object("org.bluez", path),
							"org.bluez.Device")
		devprop = device.GetProperties()
		print "[ %s ]" % devprop["Address"]
		for path in devprop["Services"]:

			service = dbus.Interface(bus.get_object("org.bluez", path),
									 "org.bluez.Characteristic")
			srvprop = service.GetProperties()
			print " * %s" % (path)
			print "	UUID: %s" % srvprop["UUID"]
			print "	Chars: ",
			for char in srvprop["Characteristics"]:
				print "%s " % char,
			print
			print
		print
	sys.exit(0)

if (args[0] == "services"):
	if (len(args) < 2):
		print "Need address parameter"
	else:
		path = adapter.FindDevice(args[1])
		device = dbus.Interface(bus.get_object("org.bluez", path),
							"org.bluez.Device")
		properties = device.GetProperties()
		for path in properties["Services"]:
			print path
	sys.exit(0)

if (args[0] == "discover"):
	if (len(args) < 2):
		print "Need service path parameter"
	else:
		service = dbus.Interface(bus.get_object("org.bluez", args[1]),
							"org.bluez.Characteristic")
		for path in service.DiscoverCharacteristics():
			print path
	sys.exit(0)

if (args[0] == "chars"):
	if (len(args) < 2):
		print "Need service path parameter"
	else:
		service = dbus.Interface(bus.get_object("org.bluez", args[1]),
								 "org.bluez.Characteristic")
		srvprop = service.GetProperties()
		for path in srvprop["Characteristics"]:
			print "[ %s ]" % (path)
			char = dbus.Interface(bus.get_object("org.bluez", path),
								 "org.bluez.Characteristic")
			charprop = char.GetProperties()
			print "	Name: %s" % charprop["Name"]
			print "	UUID: %s" % charprop["UUID"]
			print
		print
	sys.exit(0)

print "Unknown command"
sys.exit(1)
