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.

Migrating Wiki content from CodePlex to GitHub

I’ve seen a few articles on migrating your projects from CodePlex but they kind of ignore the Wiki and suggest just copying and pasting the text across. There is a way which will copy the entire contents and only require a little manual work. The instructions below are the steps I took to migrate the 32feet documentation across. There were 76 files in total so much easier that copying and pasting!

First from the Home page of your CodePlex project you’ll see a button “Download Wiki” in the page toolbar. Click this to download a Zip file containing all the documents and supporting attachments for your Wiki.

migrate-wiki-1

This contains two folders, one in raw CodePlex format and the other (called “docs”) in Markdown. You’ll want the Markdown version. There are two standard files in this folder – Home.md is the homepage – the equivalent to your Readme on GitHub. This one you’ll probably want to copy and paste into a Readme.md file in your new repository. The Documentation.md is the entry point into your documentation Wiki. I removed the Home.md after copying the contents and renamed Documentation.md to Home.md as this is now the entry point into the Wiki documentation. If there are hard links back from child pages these may require fixing.

migrate-wiki-2.png

In your GitHub project go to the Wiki tab and you’ll see an option on the right “Clone this wiki locally”. You can then use Visual Studio or any Git tool of your choice to work on a local clone of the Wiki repository.

migrate-wiki-3.png

This should be empty for a new GitHub project. Once you’ve done this you can copy all the Markdown and attachment files you downloaded and unzipped from CodePlex into this folder. Commit and Push this git repository and you’ve uploaded a (mostly) working Wiki to your new site.

After doing this I noticed a couple of issues which required further changes. Firstly the inline code examples were broken:-

migrate-wiki-4

A bit of digging revealed a slightly different “tag” for code in GitHub markdown which should be:-

migrate-wiki-5

Another quick fix was that GitHub requires tables to have a preceding blank line otherwise it just renders as raw text full of pipes.

The last big formatting issue was the main Wiki page uses a number of anchors to various points in the table of contents and this was broken in conversion. It appears that there are automatically generated anchors for top level headers only. It is possible to workaround (although it feels dirty) by using inline HTML A tags e.g. replace

{anchor:General Bluetooth Data Connections}

with

and link to it using

[General Bluetooth Data Connections](#user-content-general-bluetooth-data-connections)

I hope this helps you as you migrate your own projects from CodePlex.