So far we have seen ways to get Adapter properties, set the properties and also to list the devices using GetManagedObjects. To get started with real Bluetooth operation in action we need to understand the general use case and methods to achieve it. First thing in communication using Bluetooth is for,
- Sharing some data (file, music, voice calls) between the Adapter and device
- To achieve this, one must need to connect with the device. For this,
- We need to scan for the Bluetooth device nearby
- Pair with the device
- Connect with the device
To get this action going we will get started with scanning for the nearby Bluetooth devices. This can be done using DBUS method “StartDiscovery“, as the name suggests, it starts the discovery session for the nearby devices.
Code:
This sample does the following things in order,
- Subscribes for “PropertiesChanged” signal
- We already saw the details about PropertiesChanged signal handling in our “set property” example. Here we repeat the same signal subscription to print the current power state of the Adapter.
- We also filtering our signal for the property “Discovering” here. This property is readonly and it will be automatically set by Bluetoothd when discovery session is started and stopped respectively.
- Subscribes for “InterfacesAdded” signal
- This signal is emitted for two notification events,
- New object path added:
- For example, /org/bluez/hciX will appear automatically when you power on Bluetooth adapter (powering on the Adapter which is already powered on doesn’t create new object path and no signal will be generated). This internally means, bluetoothd is creating this object path when a new controlled is added and emit this signal to notify the changes.
- More importantly, when we start scanning for new devices using “StartDiscovery” method, bluetoothd creates a new object path for every new devices which are discovered. For example, /org/bluez/hci0/dev_XX_YY_ZZ_AA_BB_CC will be created when a new device with MAC address XX:YY:ZZ:AA:BB:CC is found during scanning process by hci0 adapter.
- When an object path gains a new interface: This happens when a new interface is dynamically added by the DBUS service during runtime under the object path. We will explore this use case when understanding media interface for audio playback.
- New object path added:
- Signature pattern: “(oa{sa{sv}})“. This is similar to the one which we discussed already about GetManagedObject in out get property example. The difference is GetManagedObject’s signature is “a{oa{sa{sv}}}“, which returns the array of all the object path under a particular service. Whereas in this signature “(oa{sa{sv}})“, during InterfacesAdded we will get only the particular object path which is added or gains new interface. So,
- o – object path which is added or gained the interface(s)
- a{s – array of interfaces which are newly added or appeared after new object path created
- a{sv} – array of properties. Note: We still didn’t explore about the DICT entries in a signature. I will move the scope explaining all the signature in details to future blogs about DBUS to avoid more confusion here.
- This signal is emitted for two notification events,
- Subscribes for “InterfacesRemoved” signal
- This signal is emitted for two notification events
- Object path is removed:
- For example, If Bluetooth adapter is removed (assuming USB Bluetooth dongle here) or powered off, then /org/bluez/hciX will be disappeared and this signal will be generated to notify.
- More importantly, either a device removed explicitly using “RemoveDevice” method (which we see in out next blog with sample source) or the device path is removed automatically. bluetoothd automatically removes the device from the cache after 180 seconds of no action (like pairing or connection) i.e idleness of the device. This is the cleanup action against all the devices which are not used after 180 seconds. If the device is paired or connected, bluetoothd will leave it untouched.
- When an interface is removed from an object path: This happens when a new interface is dynamically removed by the DBUS service during runtime under the object path. We will explore this use case when understanding media interface for audio playback.
- Object path is removed:
- Signature pattern: “(oas)“. This pattern is very simple to understand and process.
- o – Object path which is removed or interfaces under this object path is removed
- as – array of interface names which are removed. Note that there is no properties and values informed under this signal. This is because, properties changes are informed using “PropertiesChanged” signal. DBUS client application developer should be careful in releasing all the memory or references to the properties, interfaces and object path (including proxies if created) which is removed using this signal.
- This signal is emitted for two notification events
- Power on the Adapter: See more details about this in Set property example.
- Starts the discovery session
- bluez_adapter_call_method function is implemented in such a way to handle both start and stop discovery method call under Adapter1 interface. There is no response or reply for this method (i.e. void return type). This is because the devices are appeared on the fly during scanning and new devices needs to be handled using InterfacesAdded signal.
- Wait for at least one device removal action
- bluez_device_disappeared for InterfacesRemoved is written in such a way to exit the mail loop of the program when at least one device is removed from the object path. This can happen
- If any device is cleaned up after 180 seconds by bluetoothd OR
- If the device is removed using “RemoveDevice” method call. One can achieve this using bluetoothctl utility to avoid waiting for 180 seconds of execution time.
- bluez_device_disappeared for InterfacesRemoved is written in such a way to exit the mail loop of the program when at least one device is removed from the object path. This can happen
- Stop the discovery session: Stops the discovery session
- Power off the Adapter: See more details about this in Set property example.
In this example, we are printing all the information about the device when it is appeared and printing only the MAC address when the device is disappeared (as we are not storing any device information when it is appeared).
I copied the same code but when I run it, I get a message “Not able to enable the adapter “.
How can I solve that?
There could be 2 possible reasons,
1. bluetooth adapter is not configured to run as non-root, check the permissions
2. Already powered and enabled, check the error in dbus-monitor
You can also cross check the powering option with bluetoothctl to start with.