Categories
Bluetooth

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.

Categories
Bluetooth Windows

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:-

public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
_watcher = new BluetoothLEAdvertisementWatcher();
_watcher.Received += _watcher_Received;
_watcher.Start();
}
private void _watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
foreach(BluetoothLEManufacturerData md in args.Advertisement.ManufacturerData)
{
if(md.CompanyId == 0x4C) // Apple
{
DataReader reader = DataReader.FromBuffer(md.Data);
byte advertismentType = reader.ReadByte(); // 0x02 – iBeacon
byte len = reader.ReadByte(); // 0x15 (21) – iBeacon
int a = reader.ReadInt32();
short b = reader.ReadInt16();
short c = reader.ReadInt16();
byte[] d = new byte[8];
reader.ReadBytes(d);
Guid uuid = new Guid(a, b, c, d);
ushort major = reader.ReadUInt16();
ushort minor = reader.ReadUInt16();
Debug.WriteLine(uuid + " " + major + " " + minor + " " + args.RawSignalStrengthInDBm);
}
}
}

view raw
App.xaml.cs
hosted with ❤ by GitHub

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.

Categories
Bluetooth GitHub

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.

Categories
Bluetooth Windows 10

Talking to Printers

Recently I’ve been working with a selection of Bluetooth printers. During this work I’ve noticed an odd thing about the UWP Bluetooth APIs. It’s all about the Class of Device. These are a set of defined device types and are categorised into major and minor classes. For example a Printer has a Major class of Imaging and a Minor class of Printer. In the raw form the class of device is a bitmask and the bits reserved for the major class define the behaviour of the rest of the bits. The UWP API exposes a BluetoothClassOfDevice class and this has two properties – MajorClass and MinorClass and each uses an Enumeration. The interesting thing with this approach is that the MinorClass values overlap but have different meanings depending on the major class. There are already multiple fields with the same value – ComputerDesktop, PhoneCellular and PeripheralJoystick for example. For whatever reason all of the Imaging minor classes are missing – they all pre-date the original WinRT codebase so really should have been included.

I created a gist to pull together my helper method and enum to make identifying printers a little easier. I created an extension method to return the correct minor class when you identify a device with a major class of imaging:-

using System;
using Windows.Devices.Bluetooth;
namespace InTheHand.Devices.Bluetooth
{
/// <summary>
/// Defines missing values in the <see cref="BluetoothMinorClass"/> enumeration for devices with a <see cref="BluetoothClassOfDevice.MajorClass"/> of Imaging.
/// </summary>
[Flags]
public enum BluetoothImagingMinorClass
{
Uncategorized = 0,
Display = 4,
Camera = 8,
Scanner = 16,
Printer = 32,
}
/// <summary>
/// Provides an extension method to get the Imaging minor class.
/// </summary>
public static class BluetoothClassOfDeviceExtensions
{
/// <summary>
/// Returns the Minor Class of Device for an Imaging device.
/// </summary>
/// <param name="classOfDevice"></param>
/// <returns></returns>
public static BluetoothImagingMinorClass GetImagingMinorClass(this BluetoothClassOfDevice classOfDevice)
{
return (BluetoothImagingMinorClass)((int)classOfDevice.MinorClass);
}
}
}

Categories
Bluetooth Windows 10

Bluetooth Development made easier in Windows 10

With Windows (and Phone) 8.1 there were two different device capabilities which needed to be set to use either RfComm or Bluetooth LE from your app. You had to specify a target device (or All) and target service name(s). With Windows 10 there is a simpler option. You still have to edit the appxmanifest code as it is not visible in the manifest designer but you can set simply:-

<Capabilities>
    ...
    <DeviceCapability Name="bluetooth" />
</Capabilities>

This gives you access to all Bluetooth functionality from your app. This is a much simpler approach and less prone to errors. Most of the documentation doesn’t mention this new value except for this page:-
What’s different in Windows 10 Insider Preview
“new valid values are “bluetooth”, “wiFiControl”, “radios”, and “optical”.”
These are not mentioned on the “App capability declarations” page so it’s not clear which specific APIs the other intriguing values relate to…

Categories
Bluetooth Windows

32feet and Windows Apps

Some time ago I created a subset of 32feet.NET to extend the Bluetooth functionality in Windows Phone 8.0. This was for the Silverlight app model and the only API at the time was based around the Proximity APIs. When Windows Phone 8.1 came along it brought a whole new Bluetooth (and Bluetooth LE) API which was, for the most part, consistent with Windows 8.1. I never got around to updating my code for this model.

Looking forwards Windows 10 is just around the corner and the UWP app model includes this same consistent API, with a few additions, across all the flavours of Windows – IoT, Phones and all shapes and sizes of PC. This time I went back to the drawing board and looked at what functionality was missing and could be added in.

One of the new APIs in Windows 10 is the DevicePicker in Windows.Devices.Enumeration. This is not strictly Bluetooth functionality – any class of device which can be enumerated can be used with it. However it serves as a Bluetooth device picker just fine. Since Windows 10 on phones is a little further away than the imminent launch on the desktop I thought there was a good case for providing this UI now to Windows Phone 8.1 apps and showing how to wrap it to pick Bluetooth devices. Thus you can easily reuse the same code in a Windows 10 project further down the track. Thus the InTheHand.Devices.Enumeration.DevicePicker was born. It uses the same API the exception being that screen rectangles passed in are ignored for Windows Phone as it uses a ContentDialog to pop up the selector. You can still customise the foreground/background and accent colors to match your app. For example the sample code displays this:-

32feet DevicePicker

To use the DevicePicker for Bluetooth devices you need to first have the capabilities set correctly in your package manifest (see here for details). Then assuming you have a button or similar to allow the user to start the selection process you can use the following code:-

string aqs = RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush);

DevicePicker picker = new DevicePicker();
picker.Appearance.BackgroundColor = Color.FromArgb(0xff, 0, 0x33, 0x33);
picker.Appearance.ForegroundColor = Colors.White;
picker.Appearance.AccentColor = Colors.Goldenrod;

// add our query string
picker.Filter.SupportedDeviceSelectors.Add(aqs);

// prompt user to select a single device
DeviceInformation dev = await picker.PickSingleDeviceAsync(new Rect());
if (dev != null)
{
   // if a device is selected create a BluetoothDevice instance to get more information
   BluetoothDevice device = await BluetoothDevice.FromIdAsync(dev.Id);

   // or get the service which you can connect to
   RfcommDeviceService service = await RfcommDeviceService.FromIdAsync(dev.Id);
}

The CodePlex project includes the source code and two samples – one showing the device picker and retrieving device information, the other a Chat application (which is interoperable with the existing 32feet BluetoothChat sample on other platforms. The binaries for the DevicePicker are up on NuGet in this package.

That covers off device selection, the other main area I knew needed some attention is Service Discovery. The Windows API provides the ability to supply custom SDP attributes when creating a service (or as mentioned in a previous blog post an “extension” record containing custom attributes). It also gives the ability to retrieve SDP records. However in both cases it uses IBuffer (the WinRT equivalent of a byte array). Therefore the other part of the new 32feet project is a set of functionality for building (and eventually parsing) SDP attribute values and records. I haven’t published this to NuGet yet as I’m still working on it but the code is there if you fancy a look.

So the next step for 32feet on Windows is a DevicePicker for 8.1 which allows you to painlessly move your code forward to 10, and a portable SDP library which will work with 8.1 and 10 and possibly outside of Windows platforms too in the future…

Categories
Bluetooth Windows Phone

Background Bluetooth Services on Windows Phone 8.1

Added in Windows Phone 8.1 was a new RfcommConnectionTrigger which allows you to host a Bluetooth service on the device and have your background task triggered when an incoming connection is established. This makes a lot of sense as having to have your app in the foreground to receive connections limits the usage somewhat.

In its simplest form you just need to specify an RfcommServiceId for your service, register your background task and the system publishes the required SDP record which allows other devices to discover your service. Your background task is executed when an incoming connection is received and you can cast the TriggerDetails of the received IBackgroundTaskInstance to an RfcommConnectionTriggerDetails. This gives you two useful things – RemoteDevice – a BluetoothDevice which describes the device which initiated the connection and Socket a StreamSocket which allows you to talk to the remote device.

This works well for most devices but what if you have more specific requirements for the published SDP record. In a foreground app you’d use RfcommServiceProvider and this allows you to set individual SDP attributes which are appended to the default record. The RfcommConnectionTrigger mechanism provides something similar but there is literally no documentation on how it is expected to work. The difference from the foreground approach is that rather than setting attributes with id and raw body it has a property called SdpRecord which accepts an iBuffer. It’s very easy to get from a byte array to an iBuffer but we still have to create the SDP record…

At first I thought the best approach was to look at what the default record contained – but unless you assign a record the property returns null (even once the background task is registered and the SDP record is published). The only way to see the exposed record is to read it remotely from another Bluetooth device (one which is a desktop app since device and service discovery is not supported from WinRT). I used Alan’s SdpBrowserDesktop app from 32feet.This showed a fairly standard set of attributes:-

• Record:
AttrId: 0x0000 -- ServiceRecordHandle
UInt32: 0x10009
AttrId: 0x0001 -- ServiceClassIdList
ElementSequence
    Uuid16: 0x1101 -- SerialPort
AttrId: 0x0004 -- ProtocolDescriptorList
ElementSequence
    ElementSequence
        Uuid16: 0x100 -- L2CapProtocol
        UInt16: 0x3
    ElementSequence
        Uuid16: 0x3 -- RFCommProtocol
        UInt8: 0x6
( ( L2Cap, PSM=Rfcomm ), ( Rfcomm, ChannelNumber=6 ) )
AttrId: 0x0005 -- BrowseGroupList
ElementSequence
    Uuid16: 0x1002 -- PublicBrowseGroup

The ServiceRecordHandle is allocated by the host device as is the Rfcomm channel (here 6). If I want to add a service name to this I realised I would have a problem – how can I build a record when I don’t yet know the port that will be assigned (and there is never a way to find this out from WinRT). I built the record anyway hoping that the system would simply read it and replace the value at registration. You get an ArgumentException at the point you call BackgroundTaskBuilder.Register() and it doesn’t contain any useful information. I tried a few variations of this approach and then happened upon another approach – what if I build a valid record but just for the attributes I want to add. Luckily this approach works – your custom attributes are appended to the end of the record and registration succeeds.

I’m documenting this here because there isn’t a way to add to the MSDN documentation and hopefully someone searching will find the answer. I’m working on porting code across so that there is a friendly API available for all current Windows flavours which helps in reading and writing SDP records and attribute values. I can only assume the approaches used by the foreground and background APIs differ because they were written at different times by different teams.

My custom record consists of an ElementSequence, with a 16bit UUID for the attribute (0x0100 – ServiceName) followed by a UTF-8 encoded string e.g.

Element Sequence
   Uuid16: 0x0100
   String (len 11): "Hello World"

Windows 10 supports this same approach and it is no longer for Phones only – it should be universal across phones, desktop and IOT so I anticipate people doing more advanced things with Bluetooth…

Categories
Bluetooth NFC

Resources from Bluetooth and NFC for Windows Phone and Beyond

As promised here are the resources from yesterday’s session on Bluetooth and NFC. I’ve begun uploading the slides and code to this SkyDrive folder:-

http://sdrv.ms/143OZD7

I have a few finishing touches to put on the sharing library for NFC – it will be up on NuGet and CodePlex shortly.

 

Categories
Bluetooth

Update to 32feet.NET for Windows Phone

Version 8.1 of 32feet.NET for Windows Phone is now available via NuGet. This package adds some helper functionality for Bluetooth development. In particular this version includes the RfCommServiceId (designed to match the Windows 8.1 API) to provide information about various standard RfComm profiles. You can use this when connecting a StreamSocket or to filter devices in the BluetoothDevicePicker.

Speaking of which the BluetoothDevicePicker has been updated to more closely follow the appearance of the dialog displayed when you use the built in Bluetooth photo sharing feature. Currently the library is built with localized resources in mind but has only English text. If you are interested in providing localized text in your own language please contact me.

The CodePlex project contains the source and the Serial sample app. I’m working on some additional sample apps which will be added soon.

Categories
Bluetooth Windows Store

Bluetooth Development with Windows 8.1

Unless you’ve been stuck under a rock (in which case what are you doing reading this?) you’ll know that Microsoft announced a preview release of Windows 8.1 at Build yesterday. While I haven’t got a development machine up and running yet (No easy upgrade if your device is UK English) I’ve been looking at the updated documentation at MSDN. Of the many new APIs described there are a couple of new namespaces which will be interesting to those working with Bluetooth devices:-

Windows.Devices.Bluetooth.GenericAttributeProfile – Contains functionality to work with Bluetooth LE devices. This will make it possible to interact with devices such as FitBit and other low energy sensors and devices from within apps – which means support on ARM devices.

Windows.Devices.Bluetooth.Rfcomm – Support for normal serial sockets Bluetooth. While completely different from the Windows Phone 8 API it provides the same functionality and more. Ability to enumerate and get notified of device arrival and departure and access to SDP attributes. There are identifiers for a number of standard profiles – Generic File Transfer, ObexFileTransfer, ObexObjectPush, PhoneBookAccess (client and server), SerialPort (SPP).

A new Chat sample is available for 8.1 here – http://code.msdn.microsoft.com/windowsapps/Bluetooth-Rfcomm-Chat-afcee559