How to control a Bluetooth LE connection on Windows 10? - c#

I need to develop an application which communicates with a device via bluetooth low energy. Once the application is connected to the device via bluetooth it receives and sends data by using a gatt service.
The application needs to run on a Windows 10 environment. So far I was able to develop and try the application by using the following UWP classes:
DeviceWatcher
BluetoothLEDevice
Once the device has been discovered and paired the communication starts. The main problem I have is that I am not able to control the connection/disconnection with the device, that is the connection starts automatically once the device has been properly and previously paired, but I haven't found any connect()/disconnect() method so far.
Is there a way to control the connection with a specific bluetooth LE device? Are there other APIs which allow to use the bluetooth without using the UWP framework and which offer more control over the bluetooth?

Once the device is paired, whenever it turns on close to the Windows 10 machine, it will try to connect. This is defined behavior in Bluetooth, as the peripheral will always send out a connection request when it is turned on.
There is a DeviceWatcher background task that you can register for to trigger your app when your Bluetooth device connects. You can find some sample code here.
Is there a way to control the connection with a specific bluetooth LE device?
Yes. To initiate a connection: when you create a BluetoothLEDevice via FromBluetoothAddressAsync or FromIdAsync the system will try to initiate a connection to that peripheral, if it does not already hold a connection.
// Connects to a Bluetooth device, given some string deviceId
BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(deviceId);
To dispose of a connection, call the close method on BluetoothLEDevice. If your app is the only entity with a handle to the peripheral, this will cause the system to disconnect. However, if another app or system service has a handle to the peripheral, the connection will not be closed.
// Will disconnect from the BTLE device, if you hold the only handle
bleDevice.close()
These are taken from the BluetoothLEDevice documentation here.
Are there other APIs?
There are not any other APIs built in to Windows 10 that offer more control over Bluetooth. The UWP APIs offer the most control that Windows 10 currently provides. You could use an alternate Bluetooth stack, but these would have to be installed separately and likely break other Bluetooth behavior on Windows 10.

Related

Best way to run USB endpoint in the background? [Android Xamarin/Maui]

I have a program that heavily relies on a usb connection to send and receive packets to a device... This needs to run while the phone is locked. I'm not super familiar with android cycles and I currently have a service running in .net maui. One some devices, the connection will slow down or even stop while the device is locked. This can be resolved by disabling power saving options on the app and phone. Anyone know if there's a correct way to implement this service?
I currently have a working c# service (dependency injection) that allows me to send and receive packets in the background using USB Endpoint.

How to programmatically connect to paired Bluetooth device once connection is lost in Windows 10 UWP

I have a windows 10 UWP app that is able to pair with a bluetooth LE device programmatically. Once the pairing is successful, a connection to the device is also established.
If at some point, the device gets disconnected, I am not able to read any of the GattCharacteristics from the LE device. I'm able to check if the connection is present or not but I'm unable to re-establish the connection.
DeviceInformation deviceInfo = await DeviceInformation.CreateFromIdAsync("deviceId", "additionalProperties", "DeviceInformationKind");
if(deviceInfo.ConnectionStatus != BluetoothConnectionStatus.Connected) { // re-establish the connection }
Thanks.
The Problem
The Bluetooth LE device is not storing the bonding information created during the pairing process. Bonding information allows two previously paired devices to initiate new connections if they have become disconnected.
The Windows 10 Solution
Using the in-app pairing APIs, you can programmatically tell the system to pair with the Bluetooth LE device (it sounds like you are already doing this). To work around the bonding problem described above, the DevicePairingProtectionLevel must be set to None. So your in-app pairing code could look like:
var result = await someDevice.Pairing.PairAsync(DevicePairingProtectionLevel.None);
Setting the DevicePairingProtectionLevel to None tells the system to ignore bonding information and just look for a matching device.
The Peripheral Solution
Alternatively, if you have access to the peripheral's firmware, you can set it to remember the bonding information. Then your current pairing calls on Windows 10 should work.

Detecting Bluetooth SPP serial port disconnect (C# 4.5, Windows 8.1)

C# application using .NET 4.5 running on Windows 8.1
Classic Bluetooth device connects and uses SPP, using Microsoft Bluetooth stack only. Device is paired prior starting the application (the application is not involved in pairing and thinks its a real serial port).
Application connects to the SPP COM port using C# SerialPort class.
All works OK, until...
Bluetooth device is powered off, but...
SerialPort.IsConnected still reports true (for at least a minute).
I've tried hooking the main form's WndProc and trapping WM_DEVICECHANGE, but while I see messages for USB devices coming and going, no message is generated after the Bluetooth device is powered off.
Anybody know how to get PROMPT and ACCURATE information about the connection?
Thanks!
Best Regards, Dave

Connect WP8 device to a bluetooth headset programmatically

I'm trying to connect a Windows Phone 8 phone with a generic bluetooth headset using some information stored on a NFC tag. As for bluetooth part, it should be possible to find paired devices, which are active, using
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var peers = await PeerFinder.FindAllPeersAsync();
and call
await socket.ConnectAsync(peer.HostName,
serviceName);
to connect to the particural device. However, I am unable to get the serviceName. According to documentation, the device should return advertised service in PeerInformation.ServiceName, but I am only getting blank string.
Is there some workaround for how to get nams of supported services (bluetooth profiles)? I specifically need to connect the bt device using A2DP profile, but I am unable to get (or even find on the internet) the correct service name string.
ConnectAsync opens a socket for the calling program to send/receive data over. That's not what you want, instead you want the OS to connect to the Headset service. In Win32 that's BluetoothSetServiceState but I don't know an equivalent 'modern' API.
Also in Win32 one could use BluetoothAuthenticateDeviceEx which would cause pairing, and *probably* connect the headset services -- and with full Out-Of-Band authentication if supplied by the NFC channel. Again I don't know of an equivalent.
I suppose there's a possibility that doing a ConnectAsync to an arbitrary endpoint (e.g. "15") will cause pairing to start which will then complete and enable the Headset service... The ConnectAsync call itself will fail but it is its side-effect we're interested in. May be worth a try.
Presumably you're getting the headset device's device address from the NFC comms? If so, you can create the HostName object to use in the ConnectAsync as Peter describes: http://peterfoot.net/PersistBluetoothAddressesOnWindowsPhone8.aspx

How to detect the presence of certain device

In a C# application, what are some good ways to detect the presence of certain device connected to the computer? Programatically, of course. I need to support Windows XP and 7.
Background
I've been given a huge C# application that uses some connected device. The devices are custom hardware and are not designed to use without the software. When the C# app starts, it searches for such connected devices and communicates with them when appropriate. There can be more than one connected devices. I haven't looked into the source code that searches the devices. The devices are plugged into the PC with either USB or serial cable. They appear as COM port in device manager. Sometimes there can be USB hub or serial to USB converters in between the PC and the device.
When the device is connected with certain USB hub, or certain serial to USB converter is used, sometimes the software cannot detect the device properly. Sometimes it varies from PC to PC. We're not sure if it causes for some driver.
I'm told to look into the device searching algorithm and if possible, come up with better solution and replace current implementation. I haven't done this sort of task before and I need to learn how Windows manage the devices under the hood.
How can I search for specific connected devices in C#? What are some good practice and what I should be aware of or avoid?
You can find all devices in registry: HKLM/CurrentControlSet/Enum ( http://msdn.microsoft.com/en-us/library/windows/hardware/ff546173(v=vs.85).aspx )
But there will be problem with serial port. You can't be certain in which device is connected to a serial port. It can be mobile phone, modem, mouse, your device, another custom device, etc. To guarantee that it is your device connected to a given serial port you must try to communicate with it. And if it responds in proper way - then yes, it is your device.
Because of this many programs that works with serial devices asks user to manually select serial port, where device is connected.
UPD:
Another link about enumerating serial ports: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/afb62e84-53e5-4f17-ba91-8de15c4c2e38/

Categories

Resources