I’ve been working away on the Bluetooth code for some time. I’d been meaning to modernise the code and build with .NET Standard and NuGet in mind and ideally support more platforms. However the project has stopped and started a few times and gone down a few dead ends.
I had planned to rework the library into a full implementation of the UWP API set for Windows.Devices.Bluetooth covering Bluetooth Classic and Bluetooth LE but while I got quite far and had a set of working code for Windows, Android and iOS I decided that that wasn’t the right approach. Some aspects are clearly tied to underlying Windows concepts – the whole device finding/picking process uses magic strings and is not intuitive from a purely Bluetooth perspective. Also there was no real need to integrate both Bluetooth Classic and Bluetooth LE into a single library because there was very little shareable code and these could be maintained separately.
Instead I decided to go with a much simpler option. Build a new library around fundamentally the same API which the library has used for 16 years with a few necessary tweaks, cutting out a few of the more complex features and making it easy to do the most common tasks with Bluetooth Classic. The Bluetooth LE functionality will be revisited in 2020 with a more logical cross-platform API and packaged in a separate NuGet package (but still part of the 32feet.NET project).
What has changed
The library has been renamed InTheHand.Net.Bluetooth to make clear it is a different package and also to make clear the focus as I’ll no longer be including the IrDA functionality. It includes .NET Standard, Classic .NET Desktop, Android and iOS versions. As you can imagine there will be no new version for .NET Compact Framework. The iOS version is not yet complete but will have some limitations as imposed by the platform. I’ll discuss the details further in a separate blog post because it does some fun things over Apple’s quirky API and should make cross-platform Bluetooth Classic a lot easier for iOS.
In due course it will be joined by UWP, Linux and macOS implementations. Linux will require reworking for BlueZ 5 and macOS will be built on top of the IOBluetooth and IOBluetoothUI framework wrappers which are slowly taking shape. Potentially there may be other platforms too, such as Tizen, and hopefully we can grow the community around the project to target other platforms.
There is no BluetoothListener support in this release but it will be included in future builds (except on iOS). 95% of 32feet.NET users are using BluetoothClient to connect out to other devices so this wasn’t a top priority for this release.
The SelectBluetoothDeviceDialog which was heavily tied to WinForms has been replaced with the BluetoothDevicePicker. This offers a similar level of functionality but in a way which feels comfortable from any UI stack and supports async/await.
DiscoverDevices again is vastly simplified to remove concepts which only make sense in the Win32 implementation. Instead this method is used to discover “live” devices in the vicinity. It is accompanied by the new property PairedDevices which offers a more efficient way of retrieving paired devices without doing a live discovery.
When I started working on a modified version of the library for Unity development there was an odd problem. The Sockets stack in the Mono runtime doesn’t correctly support Bluetooth sockets and so the workaround was to P/Invoke the native Sockets APIs directly. In order to simplify the code the Win32 version uses a single implementation which calls the relevant Win32 APIs rather than using System.Net.Sockets. The library defines its own version of NetworkStream to be able to provide a familiar API which also not being tied to .NET Sockets. This makes it easier to support other platforms such as Android where the underlying implementation is completely different but can be wrapped inside a familiar .NET Stream. All of this means that the desktop .NET version of the library will work for the Windows target of a Unity project.
Where is it going?
The aim with this new version is to have a modern code base able to run on the current spectrum of .NET platforms – From IoT devices, to mobile phones to desktop PCs. Alongside the current Bluetooth Classic library and the Bluetooth LE library I’m also planning for other technologies to join the 32feet.NET project all aimed at handling short range device to device communications.