List and enable disabled bluetooth-services with WMI? - bluetooth

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.

Related

WebUSB API, for pushing commands/configuration to the device through webApp

I am doing some research on the WebUSB API for our company because we are going to start to manufacture devices in house.
Our current device manufacture comes with an application so the team can plug the device into a computer and diagnose it. Their application allows us to read outputs from the device, as well as pushing commands/configuration to the device over a wired connection.
Since this device is 100% ours, we are also responsible for building out the diagnostic tooling. We need some sort of interface that allows a user to read outputs and send commands/configuration to the device over a wired USB connection.
Is the webUSB the correct API? If not, what are some suggestions for accomplishing the requirement? Are we limited to building some sort of desktop or mobile application?
I would recommend resources below to read to help you understand if the WebUSB API fits your needs or not:
https://web.dev/devices-introduction/ helps you pick the appropriate API to communicate with a hardware device of your choice.
https://web.dev/build-for-webusb/ explains how to build a device to take full advantage of the WebUSB API.
From what you describe, WebUSB isn't strictly required but won't hurt either.
First and foremost, you will need to implement the USB interfaces reading data and sending configurations. It will be a custom protocol, and not one of the standard USB device classes such as HID, video or mass storage. The details of the protocol and if you use control, interrupt or bulk transfers is your choice.
I'm assuming you will connect the devices to Windows PCs, and you likely don't want to put money into writing device drivers. If so, the easiest approach is to add the required descriptors and control requests required for Microsoft OS 2.0 Descriptors. That way, the WinUSB driver will be installed automatically when the device is plugged in.
Using the WinUSB API, a Windows application will then be able to communicate with the USB device. No additional drivers are needed. (On macOS and Linux it's even easier as you don't need the Microsoft OS 2.0 Descriptors in the first place.)
On top of that you can implement the additional descriptors and control requests for WebUSB. It will provide the additional benefit that you can write a web application (instead of a native application) for communicating with the USB device. (Currently, you are restricted to the Chrome browser.) WebUSB devices should implement the WinUSB descriptors as the alternative (.INF files, manual installation process) is a pain.
The already mentioned web page https://web.dev/build-for-webusb/ is a complete example of how to implement it.

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.

Connecting to a custom device via Bluetooth when its SDK is unavailable

I am building an Android app in which I need to connect to an custom device over classic Bluetooth (preferably). My problem is SDK for that device is not created to facilitate the connection. Now I am stuck onto the part where I need to create a Socket which will be opened by the custom device which is acting as a server and other Android devices will act as clients and connect to it.
I am stuck at the part where we need to have identical UUIDs at both client and server for the socket connection to work. I am following the BleutoothChatApp as reference for this but I cannot always make sure that both my app and custom device will have identical UUIDs. Because I may or may not be able to hard code the UUID in custom device.
What can I do in such case.?
Also when I try to use BLE and search for services, I discover only one service which has no description or anything.
What can I do in such cases. What will be the best approach to create a connection to that device.?
You get multiple UUIDs for the same device because the devices offer multiple services. Base UUID for Bluetooth is "00000000-0000-1000-8000-00805F9B34FB".
If you find this UUID in a device, it means it supports Bluetooth Service. Use the UUID for connecting to the device.

How exactly does the new Bluetooth Mesh network handle provisioning?

I have read in a couple of places (but nowhere official) that you need to use a smartphone to setup and add devices to a mesh. Is that true? Can you not do it with IR or a NFC? What are my options?
Bluetooth Mesh defines the Provisioner as the device that is able to create a mesh network and add (provision) new nodes into the network.
A Provisioner does not necessarily have to be a smartphone, although that will generally be the case. Provisioning is performed over Bluetooth channels - either over advertising channels (using a new protocol defined by Bluetooth Mesh), or over GATT (to support legacy smartphones that cannot advertise custom AD types).
To provision nodes over the advertising channels (the so-called PB-ADV bearer), the smartphone OS needs to be updated to allow developers to implement the PB-ADV protocol. That is not likely to happen soon enough.
Therefore the best option will be to provision nodes over GATT. The unprovisioned node (e.g., the sensor) will have to include the Mesh Provisioning Service in its GATT Database. The smartphone (as GATT Client) will connect and discover this service, and use its characteristics to exchange Mesh Provisioning PDUs.
You can wait until some companies will develop these smartphone apps, or, if you are in a hurry, you can grab the Mesh specification available on the Bluetooth website and develop a provisioning app yourself. The current smartphones' OS allows you to develop a GATT Provisioner (both on Android and iOS).
In general, a phone/tablet class device is needed for provisioning. IR or NFC can be used for OOB authentication, but the full Bluetooth mesh stack is required to initiate and complete the provisioning process.
A good reference as an introduction to Bluetooth mesh can be downloaded from the bluetooth.com web site Bluetooth mesh Introduction for Developers.
At the moment, the best place to start is the Nordic Mesh SDK that uses the Bluetooth SIG mesh. This has an example (for lighting) where a Bluetooth device itself does the provisioning. There's also a 'Serial' example where, again, a Bluetooth device does the provisioning connected via UART to USB that can be controlled via a desktop/laptop. You could extend the examples so that the provisioning BT device has extra GATT services that open up the provisioning to smartphones.

Accessing Bluetooth virtual COM port on Windows without manual pairing

I need to connect to a Bluetooth device through virtual COM port created in Windows. It's easy when the port has been already created during manual pairing procedure. But I would like my application to relieve an user from the manual pairing of a device. I would like to present all devices in the range, allow user to chose one, and then create virtual COM port connected with the selected device. I'm not trying to avoid the pairing procedure itself, but rather I would like to invoke it by my application.
I started getting familiar with Microsoft Bluetooth API. And then some doubts arose. I've been wondering what happen if some user would use different (than Microsoft's) Bluetooth stack? Is the Microsoft's API the real Bluetooth API, which have to be implemented by any other Bluetooth stack provider? Or rather each provider has its own API, and the Microsoft's is only one of many other?
Thanks everyone for valuable input. I'd like to summarize what I've found so far. The Microsoft Bluetooth API is not operating system API. Application written against it will not cooperate correctly with any other Bluetooth stack. It seems that applications which are intended to cooperate with multiple stacks need to provide some stack abstraction layer, and stack specific code for all of them.The other solution is to allow user for manual pairing of the Bluetooth device, which eventually create some virtual device in the operating system (e.g., COM port). Then the application can use standard interface of such a device.
I can't speak for the Microsoft Bluetooth API, but there are multiple Bluetooth stacks available for the PC platform (even more for mobile devices).
The underlying API is defined by the Bluetooth Core Spec and so all stacks should be able to interact, in fact it is mandatory that they interop or they cannot use the Bluetooth name and logo.
As to pairing, your going to have a hard time getting devices to pair if they have default security, which requires a pin code.
Things might be simpler in the (near) future, as the Bluetooth standard has introduced a new security model, secure simple pairing, which has a 'just works' mode that requires no Pin code. This is still stronger then the current security, except against Man in the middle attacks. However, it could be a while before you see the chips with this feature in PCs.
If you can change to using .NET :-/ I can recommend our library 32feet.NET.
For explicit pairing there's BluetoothSecurity.PairDevice. We can also create the virtual port for you, for example:
BluetoothClient cli = new BluetoothClient();
BluetoothDeviceInfo[] list = cli.DiscoverDevices();
BluetoothDeviceInfo selected = GetUserToSelectOne(list);
BluetoothSecurity.PairDevice(selected, pin);
// Ask Win32 to create a virtual serial port
selected.SetServiceState(BluetoothService.SerialPort);
However I really don't like virtual serial ports so I always suggest that people use a normal sockets connection using our BluetoothClient class, it will automatically handle a pairing request if required.
On Win32 we support the stacks from Microsoft, Widcomm/Broadcom, and BlueSoleil. On Widcomm there's no support for SetServiceState there yet, and their API has no support for responding to pairing requests. BlueSoleil should support both.
A brief user's guide is at 32feet.NET — User’s Guide, and all the class documentation is available at the main site http://32feet.net, the Widcomm documentation is only in our code repository at the moment.

Resources