New Year, New 32feet.NET Library

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.

View the project on GitHub

See the latest InTheHand.Net.Bluetooth NuGet package

Xamarin macOS Binding Libraries

In creating an IOBluetooth binding for Xamarin Mac I learned about Objective Sharpie and binding libraries. There is little documentation on this but it is fairly similar to Xamarin iOS and for that there is a lot more source material. The output from Objective Sharpie gives you binding definitions which you can use in a dll project to produce a binding library you can then call from any other Xamarin dll or app. This was fine to a point but there are issues with some of the complex types used and these cannot always be marshalled automatically. This left me with an API with a few missing bits as I tried and failed to manually adjust the binding via trial and error.

The project sat around untouched for some time but recently I’ve begun to revive it and hope to sort out these bits so it can be released as a complete functioning API for Xamarin Mac. At first I thought I was going to have to create two libraries – one with the raw API calls and another with a clean API over the top but I had missed something buried in the docs and it turns out there is an easier solution.

When you have a binding library it will, by default, have two files – ApiDefinition.cs which contains all the API calls and has a Build action of BindingApiDefinition and a StructsAndEnums.cs which contains (well I’ll let you guess from the name) and this has a Build action of ObjcBindingCoreSource. When the classes are generated from the interface definitions in ApiDefinition.cs they are actually partial classes. This means you can extend them and have additional functionality built cleanly into the library. If you have a particularly messy API call you can mark it as internal and then surface it in a more friendly way from a partial class. To do this add another source file to the library project (I’ve called it Extra.cs because I saw that in a sample but the name isn’t important) and set the Build action to Compile. Here you’ll need to create a partial class with the same name and namespace as the “interface” you want to extend from ApiDefinition.cs, and then add methods, properties etc.

The first time I added this my build failed. I subsequently found out that there is one additional step to tell the binding compiler to ignore this file. Open the project properties, under Build select the Objective-C Binding Build page. Here in Additional btouch arguments box add -x:Extra.cs (or replace with your own filenames). This stops the initial binding compilation from using the partial class, which then gets built normally in the subsequent managed code build. The project should now build and expose the combined functionality. I did find that intellisense often gets confused when editing the partial class because there isn’t another definition of a partial class at this time (remember in ApiDefinition.cs it’s actually an interface). However it seems you can safely ignore this!

This in theory allows you to completely change the API surface which you expose to Xamarin from whatever you started with. I don’t want to go too crazy with IOBluetooth – my feeling is that it should match the native API with a few tweaks for C# naming conventions, using namespaces rather than huge class names, and .NET friendly types where appropriate. Objective Sharpie struggled with some of the enum/constant definitions and so these still require a bit of massaging. It should be obvious how it maps to the native API.

If you have feedback on the API or would like to get involved in getting the library up to release standard please let me know. All the current code is on GitHub in the IOBluetooth and IOBluetoothUI folders.

32feet.NET and Audio

There are a few different Bluetooth profiles which handle audio, but they all work in a very similar way. There are two connections open between the client (usually a phone) and the server (some kind of audio device such as a speaker or car entertainment system).

The first of these is an Rfcomm channel which handles commands between the devices. Rfcomm is essentially a serial connection emulated over Bluetooth and these commands are often a mixture of AT commands from the world of modems and other commands for associated functionality (think phone book contacts, track names etc).

The second channel is a low level SCO (Synchronous Connection-Oriented) connection which is better suited to real-time audio data. Depending on the profile this may be used for one-way (audio) or two-way (hands-free etc) audio.

32feet.NET has only support for Rfcomm out of the box. This means it is possible to establish a connection to a headset device and even do things like capture button presses and send rings but it does not support opening an audio channel. Also if you connect to a headset device or similar rather than use the platform’s built in support you’ll block the device from using its native functionality. Mobile devices have support and drivers for headset/hands-free etc and this will go through the normal audio APIs on the platform so there is rarely a need to try and interfere with this.

If you want your app to play audio over Bluetooth then pair the device with the OS and just play audio and the system will handle it for you.

Bluetooth with Xamarin Mac

I’ve been working on adding macOS support to 32feet.NET and there are two frameworks in macOS for Classic Bluetooth – IOBluetooth and IOBluetoothUI. I soon discovered that neither of these had bindings in the standard Xamarin.Mac package which is referenced by all Xamarin Mac applications. I decided to build binding libraries for both APIs and publish the code as part of 32feet.NET. This means you can either use the IOBluetooth lower-level APIs yourself or later use the platform-agnostic 32feet API.

Today I’ve published the first release of the InTheHand.IOBluetoothUI package. There are fewer APIs than IOBluetooth and I’ve already begun the manual process of simplifying and making it more “.NET friendly”. There is also documentation to add, though even Apple’s documentation on IOBluetooth is rather thin at best…

These are by no means final and there will be changes to the APIs as names are cleaned up and more is tested and fixed. If you’d like to try them in your projects please let me know your feedback via GitHub. Those NuGet packages are:-

https://www.nuget.org/packages/InTheHand.IOBluetooth/

https://www.nuget.org/packages/InTheHand.IOBluetoothUI/

 

Bluetooth from Unity

An ongoing issue with 32feet.NET is that it wouldn’t work inside Unity. The reason is that the System.Net.Sockets classes behave slightly differently in the Mono runtime to the desktop .NET framework and you can’t create a Socket using the Bluetooth specific address family.

In order to work around the issue it was necessary to P/Invoke into the native winsock functions, essentially rebuilding a subset of the Socket class. In parallel to this work I’ve been rebuilding 32feet with a more modern API which is less tied to Sockets (primarily just used on desktop Windows) and able to map onto a range of platforms. Another big change for this version is support for Bluetooth LE alongside classic Rfcomm on supported platform. Currently this library supports Xamarin Android and iOS along with UWP, Windows desktop .NET 4.6 and Mono .NET 2.0 for Unity. I’m working on a macOS implementation too. The API is essentially designed to be a more friendly version of the UWP API. In order to support such an old version of .NET, the Unity version is entirely synchronous whereas most of the API is normally async.

In order to test this I wrote a very simple script for Unity which picks a specific paired device, connects to a serial port service over Rfcomm and sends a string. Yes that’s right I have a 3d game that I can print from!

This is currently in preview (but available on NuGet now). There is a lot still to finish including generating the documentation. I’m hoping for some useful feedback, particularly on the Unity work but also any of the other current platforms. Feel free to join in the discussions on GitHub.

Read iBeacons from UWP

I recently got some estimate beacons and have been trying out various things with them. By default they are configured to support Apple’s iBeacon format and could be used in an iOS app to provide location awareness in a close environment. You can read the same data from UWP and can add some location/context awareness in this way. In this post I’ll just discuss the iBeacon approach.

In UWP development there is a BluetoothLEAdvertisementWatcher which is used to read advertisement data from nearby Bluetooth Low Energy devices. The watcher fires the Received event for each advertisement found and you can read the data as required. The key to using iBeacon is to understand how the data is encoded. Advertisement sizes are limited so they need to be designed to be as compact as possible while providing enough information to uniquely identify each device. The iBeacon format consists of a UUID (Guid) and two unsigned short integers. These should be thought of as a hierarchical format:-

UUID > Major > Minor

A location aware app would use a unique UUID for its own use, for example a chain of stores. The Major id would then represent an individual store and the Minor id a location within that store. In iOS the raw iBeacon advertisements are “hidden” from the CoreBluetooth API and instead exposed by CoreLocation. In UWP we use the BluetoothLEAdvertisementWatcher and reconstruct the elements of the beacon. These are stored in a ManufacturerData section with Apple’s manufacturer id (0x4C) used. Within this we access the raw data as an iBuffer (WinRT/UWP equivalent of a byte[] array). The DataReader class is used to sequentially read through the data. The data is:-

Byte 0 – type – 2 for iBeacon

Byte 1 – data length: 21 bytes for iBeacon

Bytes 2-17: UUID

Bytes 18-19: Major ID

Bytes 20-21: Minor ID

We must be careful to respect the byte ordering of the Guid element, the following Gist wraps up the operation:-

The event also gives you the Rssi, you can use this to make a general assumption about the relative distance of multiple beacons but should not assume a direct measurement of distance from it.