
# Configures the Bluetooth device as a LE peripheral.
# BluetoothAutomation

from bluetoothautomation import *
import code

x = ServiceProvider.alloc().init()

paths = BAMDevice.allDevicePathsWithTransport_(x)
if len(paths) <= 0:
	raise Exception("Atleast one Bluetooth serial board must be plugged in.")

y = BAMDevice.deviceWithTransport_atPath_(x, paths[0])

# Configure the device for LE.
y.setVerboseLogging_(kBAMLogLE | kBAMLogCore)
y.setEnabledServices_(kBAMServiceLE)
y.setAllowConnect_(True)
y.setAllowDiscover_(True)
y.le().setEnablePeripheral_(True)
y.le().setInputCapability_(kBAMLEInputCapabilityKeyboard)
y.le().setOutputCapability_(kBAMLEOutputCapabilityDisplay)
y.le().setAddress_(kBAMLEAddressPublic)
y.le().setPasskey_(123456)

# Register some services and characteristics.
serviceUUID = bytearray((0x12, 0x30))
_childCount = 1 + 1 + 1#includedServices + characteristics + descriptor count for this service
serviceHandle = y.le().addServiceWithUUID_primaryService_includeWithAdvertise_withNumChildHandles_(serviceUUID, True, True, _childCount)

if not serviceHandle:
	raise Exception("Unable to add the service.")

childServiceUUID = bytearray((0x12, 0x40))
_childCount = 0 + 0 #includedServices + characteristics + descriptor count for this service
childServiceHandle = y.le().addServiceWithUUID_primaryService_includeWithAdvertise_withNumChildHandles_(childServiceUUID, False, True, _childCount)

if not childServiceHandle:
	raise Exception("Unable to add the child service.")

includedServiceHandle = y.le().addIncludedService_parentService_(childServiceHandle, serviceHandle)

if not includedServiceHandle:
	raise Exception("Unable to add the included service.")

characterUUID = bytearray((0x2A, 0x05))
_childCount = 1 #descriptor count
characterHandle = y.le().addCharacteristic_security_properties_handleReserve_parentService_withNumChildHandles_(characterUUID, kBAMLEAttributeSecurityReadable|kBAMLEAttributeSecurityWritable, kBAMLECharacteristicPropertyRead | kBAMLECharacteristicPropertyWrite, 2, serviceHandle, _childCount)

if not characterHandle:
	raise Exception("Unable to add the characteristic.")
	
y.le().setValueForCharacteristic_value_(characterHandle, bytearray((0x00, 0x00)))
print "Value for the characteristic is %s." % y.le().valueForCharacteristic_(characterHandle).description()

descriptorHandle = y.le().addUserDescriptorForCharacteristic_security_(characterHandle, kBAMLEAttributeSecurityReadable|kBAMLEAttributeSecurityWritable)

if not descriptorHandle:
	raise Exception("Unable to add the descriptor.")
	
y.le().setValueForUserDescriptor_value_(descriptorHandle, bytearray((0x0, 0x0)))
print "Value for the descriptor is %s." % y.le().valueForDescriptor_(descriptorHandle).description()

y.le().startUndirectedAdvertisingAsLimited_undirectedMode_txPower_data_(False, kBAMLEAdModeConnectableUndirected, 1, bytearray((0x09, 0x08, 0x07)))

# Allow the user to input stuff.
code.interact(local=locals())

# Bye bye.
y.le().stopAdvertising()
y.le().removeUserDescriptor_(descriptorHandle)
y.le().removeCharacteristic_(characterHandle)
y.le().removeIncludedService_(includedServiceHandle)
y.le().removeService_(childServiceHandle)
y.le().removeService_(serviceHandle)