#!/usr/bin/python

import sys
import dbus
from optparse import OptionParser, make_option

bus = dbus.SystemBus()

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")

test = dbus.Interface(bus.get_object("org.bluez", "/org/bluez/test"),
			"org.bluez.TelephonyTest")

if len(args) < 1:
	print """Usage: %s <command>

	connect <bdaddr>
	disconnect <bdaddr>
	outgoing <number>
	incoming <number>
	cancel
	signal <level>
	battery <level>
	roaming <yes|no>
	registration <status>
	subscriber <number>
	speakergain <bdaddr> [level]
	microphonegain <bdaddr> [level]
	play <bdaddr>
	stop <bdaddr>
	""" % sys.argv[0]
	sys.exit(1)

if args[0] == "connect":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	headset.Connect()
	sys.exit(0)

if args[0] == "disconnect":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	headset.Disconnect()
	sys.exit(0)

if args[0] == "speakergain":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	if len(args) > 2:
		headset.SetProperty('SpeakerGain', dbus.UInt16(args[2]))
	else:
		props = headset.GetProperties()
		print props['SpeakerGain']

	sys.exit(0)

if args[0] == "microphonegain":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	if len(args) > 2:
		headset.SetProperty('MicrophoneGain', dbus.UInt16(args[2]))
	else:
		props = headset.GetProperties()
		print props['MicrophoneGain']

	sys.exit(0)

if args[0] == "play":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	headset.Play()

	sys.exit(0)

if args[0] == "stop":
	if len(args) < 2:
		print "Need device address parameter"
		sys.exit(1)
	device = adapter.FindDevice(args[1])
	headset = dbus.Interface(bus.get_object("org.bluez", device),
					"org.bluez.Headset")
	headset.Stop()

	sys.exit(0)

if args[0] == "outgoing":
	if len(args) > 1:
		test.OutgoingCall(args[1])
	else:
		print "Need number parameter"
	sys.exit(0)

if args[0] == "incoming":
	if len(args) > 1:
		test.IncomingCall(args[1])
	else:
		print "Need number parameter"
	sys.exit(0)

if args[0] == "cancel":
	test.CancelCall()
	sys.exit(0)

if args[0] == "signal":
	if len(args) > 1:
		test.SignalStrength(args[1])
	else:
		print "Need signal strength parameter"
	sys.exit(0)

if args[0] == "battery":
	if len(args) > 1:
		test.BatteryLevel(args[1])
	else:
		print "Need battery level parameter"
	sys.exit(0)

if args[0] == "roaming":
	if len(args) > 1:
		test.RoamingStatus(args[1] == "yes" or False)
	else:
		print "Need yes/no parameter"
	sys.exit(0)

if args[0] == "registration":
	if len(args) > 1:
		test.RegistrationStatus(args[1] == "yes" or False)
	else:
		print "Need yes/no parameter"
	sys.exit(0)

if args[0] == "subscriber":
	if len(args) > 1:
		test.SetSubscriberNumber(args[1])
	else:
		print "Need number parameter"
	sys.exit(0)

print "Unknown command"
sys.exit(1)
