BlueZ: Adding services, attributes, and profiles without sdptool command - linux

Prior to BlueZ 5, the way to add/remove Bluetooth services/attributes/profiles on Linux was done through the sdptool as follows:-
To browse local records
#sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
To add a service
#sdptool add SP
Serial Port service registered
To remove a service
#sdptool del 0x10007
Service Record deleted.
However, sdptool was deprecated (along with hciattach, hciconfig, hcitool, hcidump, rfcomm, ciptool, and gatttool) and removed from the main BlueZ build as can be seen in the following links:-
Link 1
Link 2
Link 3
Fortunately, most of these commands have been replaced with newer ones (btattach, btmgmt, and bluetoothctl). However, there doesn't seem to be any replacement for the sdptool.
My question is:- what tool can I use now instead of sdptool in order to browse local services/profile as well as add or remove profiles?
Please note that I am aware that sdptool can be rebuilt-in and enabled, but I am searching for the replacement to the command rather than a workaround.

From Bluez 5 this needs to be done using ProfileManager DBUS interface. One needs to register the custom/external profile using this interface and Bluez handles all the aspect of security and connection.
Once the connection is ready, bluez provides file descriptor to operate on for the external profile. You can find an example implementation of HFP profile in bluez-alsa.
In detail, You can implement all the methods of org.bluez.Profile1 interface and register it with Bluez using org.bluez.ProfileManager1 interface where you can specify the UUID, auth (if any needed).
In bluez-alsa,
Registration is done here.
Methods are implemented here.
Once the connection for this profile is established, NewConnection API is called with the fd in argument.
But AFAIK, there isn't any direct way to achieve this using existing tools like bluetoothctl.

Related

BlueZ: Removing bonding with BLE device does not work

We've got a use case in which a BLE connection is used to do the basic configuration of an embedded device via an Android app (later also via an iPhone app). The embedded device runs Linux and thus uses BlueZ as Bluetooth stack.
Using the DBus-API of BlueZ, bonding is made possible by making the device pairable, discoverable, and activating advertising. After bonding the apps can access the GATT services and characteristics
(which require bonding to be read/written) on the embedded device.
After the setup is done the bonding of the device (running the app) that managed the setup process, is supposed to be removed. In order to do that we call RemoveDevice() of org.bluez.Adapter1.
The BlueZ documentation states the following
void RemoveDevice(object device)
This removes the remote device object at the given
path. It will remove also the pairing information.
Still the app is able to access the GATT characteristics afterwards.
If bluetoothctl is used to check the list of paired devices, the list is not containing that device anymore though. Before calling RemoveDevice() the bonded device was visible there.
If bluetootd is stopped and restarted the app is no longer able to read/write the GATT characteristics, but needs to re-bonded before doing so.
I can neither find any further information in the BlueZ documentation nor can I find anything about this topic searching anywhere else.
Is this intended behavior or is this a bug? Does "remove pairing information" also mean "remove bonding information"? If this is intended behavior, how do we properly terminate bonding with a device?
Should I use the BlueZ Management API instead of the BlueZ API? I'm not sure about this as multiple source state that the DBus-API is the way to go.
RemoveDevice() indeed removes the bonding information as well. So you have to disconnect first and then call RemoveDevice(). The next time you connect the bonding information will be gone.
However, note that if you only make use of encrypted characteristics, you can still connect and discover services. Only once you start reading/writing the encrypted characteristics will Bluez check if you are bonded.

Bluez server for bidirectional communication

I want to create on my Linux desktop a small server listening to requests using Bluetooth. Clients (such as mobile phones or tablets) will connect to this server and exchange data back and forth.
It should be straightforward, but I'm unable to find an up-to-date tutorial for Bluez's new DBUS-based API, and Bluez documentation is basically just a huge data dump.
Any suggestions on how I should proceed? (The language used does not really matter, since there are DBUS bindings for all major languages.)
These are some useful links to get started, it's not much but it's a start.
Textual (and up-to-date) description of the DBus interfaces exposed by bluez5 : https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc
You can find example for gatt client/server in the prevous cgit at the following path : /tree/src/shared/
An overview of Bluez and it's dbus interfaces (conference given at the 2016 Open IoT Summit) : https://www.youtube.com/watch?v=tclS9arLFzk
If you need example for your dbus bindings, I suggest looking at their test files
As you said yourself, there are dbus bindings in many languages however the language does matter. For example, some old low-level C API are not advised (see for yourself the advices in the dbus tutorial on freedesktop.org)
I suggest the following steps to start (especially for LE) :
Read the adapter-api.txt (first link) description and try to build a proxy to interact the org.bluez.Adapter1 interface (when trying to build the proxy: name would be 'org.bluez' and object path '/org/bluez/hci0' as describded in adapter-api.txt). Call StartDiscovery and StopDiscovery
Once scanning is done, print your proxy introspection to find the devices discovered (you should see MAC addresses preceded by "dev_")
Build proxies to interact with the device (read the device-api.txt file description to find out what you need)
For LE, if you want to access the Services of a Device. Introspect your device proxy and you will find it'serices. Repeat the process to reach Characteristics and Descriptors.

Browse files through bluez

I want to create an app in Linux that can browse the files from a bluetooth phone and eventually retrieve them. I've been reading and googling and it seems the way to do it is communicating with Bluez via DBus.
However there doesn't seem to be DBus methods for interacting with files. Therefore, do I need to use obex protocol to do this instead? I'm quite lost here.
Thanks
In your case you want to use FTP profile which uses obex protocol,this obex will call RFCOMM layer and thus bluetooth will be used.You need to create a filetransfer(org.bluez.obex.FileTransfer) interface and call obex methods via dbus call,check here or the ftp plugin available in bluez

List and enable disabled bluetooth-services with WMI?

I'm currently looking for a way to list the services exposed by a remote bluetooth device and to enable them.
Normally I would be using the WindowsAPI-functions (or more likely one of the known wrappers) to list the services and to enable them by GUID (SetServiceEnable).
The problem is, that the device is exposing two Services with the same GUID!
Thus using the windowsAPI-functions only enables one of these services. The other service can't be enabled.
I thought perhaps WMI could do the trick, but I'm still new to WMI and couldn't find any
Windows itself is able to enable both, none or a specific service over the servicemenu.
UPDATE
The problem I want to solve is to be able to enable either the first or the second service. By now only the first service (which is usually the service I need), but I couldn't find a solution to enable the second service (except by using the Windows UI).
If both services are enabled I have two Commports in devicemanager (SPP).
Since I can't add comment/questions (don't have the privilege on stackoverflow yet). Here's my best take.
If I understand correctly, it's invalid to have the service available more than once in the service record, right? Can you right click on the device in Bluetooth Pairing UI and see if you see two services and that you can enable them through the Windows UI? And once you enable them do you see two PNP devnodes under that device in device manager (view by connection) with the corresponding opposite role of the two service you enabled? (I can't try this because I don't know of a device I have with two identical UUIDs.)
As you might already know, when you enable service on a remote device, you are not actually enabling the service on the remote device through the Windows Bluetooth API. What you are doing is telling the core bluetooth component in Windows to generate the corresponding opposite role of the service. (This is what BluetoothSetLocalServiceInfo does.) For example, if the remote device supports A2DP sink, by enabling that service the Bluetooth service on desktop would then register a A2DP source service for that device, which generates a PNP devnode for matching A2DP source drivers to install on that devnode. By disabling that service, the Bluetooth service would then unregister the A2DP source devnode and the PNP devnode would be removed (sort of like unplugging a USB device).
Depending on what profile you are seeing being duplicated, it might not make sense to have two instances of device objects and driver objects that matches on the same mac address of the remote device.
My answer (which is actually not answering your question) is to check if it's even valid for the two services to be enabled in that case on the desktop with the drivers on the desktop that you will be working with. For example, a bundle of A2DP plus HFP would require A2DP and HFP to synchronize certain behavior, such as AVDTP suspend. Depending on the implementation and the drivers, they might not be expecting there are two instances of A2DP driver installed, hence causing the unexpected state of the local drivers.

how to get an SDP record for bluetooth service?

I'm new to both winsock and bluetooth programming. I need to develop a bluetooth service to run on a pc.
Looking at the MSDN library they say to use WSASetService(http://msdn.microsoft.com/en-us/library/aa362921%28VS.85%29.aspx) function to publish a service.
The problem is that the WSAQUERYSET(http://msdn.microsoft.com/en-us/library/aa362920%28VS.85%29.aspx) structure, that has to be passed to WSASetService, needs a binary SDP record and i don't know how to get it.
In the Windows embedded section of the MSDN library they describe a procedure to obtain an SDP record using Bthnscreate.
I installed Windows CE 6 to use this tool but i can't find it in the install directory nor in the entire system.
How can i get an SDP record?
Thanks!
Pay me to create it for you? No I'm kidding -- unless you need expert help. I'm maintainer of the 32feet.NET Bluetooth library for .NET. We include full SDP record parsing, creating, and diagnostic dumping. You should be able to create your record with our ServiceRecordBuilder class and then have it converted to binary form with method ServiceRecordCreator.CreateServiceRecord. See some documentation in the "Bluetooth SDP — Service Discovery Protocol" section in 32feet.NET -- User Guide

Resources