Friday, 20 December 2013

Advertising an Object URL with Bluetooth LE

In a post the other day, I described the magic incantation to set the advertising data in a BLE beacon:

hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 00

Today I'd like to sketch out some thoughts about how to set a URL in that data, as I discussed in yesterday's post.

First step is to break it down into bits. Following the page I linked to before on The Register, plus extra information from this page on StackOverflow, it seems that this is what the various parts mean:

0x08 0x0008 - command: HCI_LE_Set_Advertising_Data
1e - 30 octets follow out of 31 max
02 01 1a - 2 octets follow, bluetooth flags
1a - 26 octets follow
ff 4c 00 - manufacturer data: Apple specific
02 15 - iBeacon: 21 octets follow
e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 - UUID
00 00 00 00 - Major/Minor
c5 - calibrated strength
00 - padding to reach the 31-octet maximum length

Now some of this is iBeacon-specific, and we're not trying to play within Apple's walled gardens, here. But I don't know the magic codes to send data that isn't manufacturer-specific, yet, so at the cost of losing some valuable octets, we can pretend to be Apple for now. But again, what is Apple's magic for data that isn't an iBeacon? We'll have to lose two more octets and start at the UUID. We can at least (hopefully) regain that lost final octet by bumping up all the lengths by one to use the whole available space:

0x08 0x0008 - command: HCI_LE_Set_Advertising_Data
1f - 31 octets follow out of 31 max
02 01 1a - 2 octets follow, bluetooth flags
1b - 27 octets follow
ff 4c 00 - manufacturer data: Apple specific
02 16 - iBeacon: 22 octets follow 
68 74 74 70 3a 2f 2f 66 6f 6f 2e 63 6f 6d 2f 35 31 2e 6a 73 6f 6e
- "http://foo.com/51.json"

Here we've used all the 22 characters to put in a string URL. Hm. 22 characters isn't very long, and this URL has a lot of redundancy, requires us to find a short domain name, as well as depending on DNS to expand that host part into what would be a much longer IP string. Also, there's no room for a port number, and it would be a bit odd using DNS to resolve to a NAT address, so this would only really be useful for public IoT installations.

How about using a link-shortening service? Here is the 21-char URL of my Raspberry Pi hosted Cyrus light object on my LAN, created by Bitly:

http://bit.ly/19i3iqr

So yes, we can put any URL we like into those 21 characters, but now we depend on both the DNS and the Bitly public-Web services!

So we're forced to go back to the octets. What about IPv6? Every Thing has its own IP address! We could put in either the direct IPv6 address of our JSON object, which is 16 octets, or come up with a convention to use IPv4 4-octet addresses plus a unique ID for the object - which is what I use in the Object Network anyway: I currently use 8-byte hex-rendered "UIDs", but there's no limit on their length.

So, not forgetting the port number, the Object Net URL:

http://192.168.0.18:8082/o/uid-c093-a908-a9d8-f1c1.json

Would be reduced down to:

192 168 0 18, 8082, c093 a908 a9d8 f1c1

Which would fit into just 14 octets! With 16-byte Object Net UIDs, we'd hit our 22-octet limit, so we'd hopefully have figured out the whole Bluetooth advertising thing by then, to get the extra space back.

A couple more octets would need to be used to choose either IPv6 or this IPv4 scheme, and to switch on TLS, choose JSON or Cyrus formats, etc.

It does mean that the arbitrary convention I started using for paths to Object Net UIDs - prefixing them with "/o/" - would become baked in, but that's not too restrictive, I think.

It also prevents us using the indirection of DNS if we should need to, when broadcasting URLs from beacon Things. I haven't thought through how much of an issue that would be in the IoT and Object Network future. I'll let you know..

I'll try all this out and report back on how I got on.

No comments:

Post a Comment