Sunday, 5 January 2014

Scanning BLE adverts from Linux

As I mentioned before, I need my Pies to be able to see each other's BLE adverts so that new Things can discover existing ones and find a place to belong to. I even suggested that a place could advertise itself directly, instead of jumping via a Thing object's "within:" link. That will be needed for the first Thing, at least.

Also, one day I'll want all my Pies to be scanning for mobile advertisers, such as people, robots, dogs and cars. Android currently can't itself be a beacon, but when it can, I'll need my Pies to be able to spot the app.

So I did a little research and came up with a possible answer. Unfortunately, as I said before, there doesn't seem to be a BLE API for Java yet, so we still have to call out to the command line. And the tools we have are apparently undocumented and rather clunky to use.


Clunky Method

First you kick off hcidump:

root@duncan-dell/0:~ -> jobs
[1]  + Running                       hcidump -x -R

You need "-R" to show the raw data and "-x" for hex dumping.

Now call "lescan", and watch the output of hcidump:

root@duncan-dell/0:~ -> hcitool lescan > & out

The following is the output of hcidump:

< 01 0B 20 07 01 10 00 10 00 00 00 
> 04 0E 04 01 0B 20 00 

Don't know what that is.

< 01 0C 20 02 01 01 
> 04 0E 04 01 0C 20 00 

Or that.

> 04 3E 2A 02 01 03 00 B3 F1 C6 72 02 00 1E 02 01 1A 1A FF 4C 
  00 02 15 C0 A8 00 12 1F 92 B5 0D C3 24 A3 7F 7A 66 00 00 00 
  00 00 00 00 C2 
> 04 3E 2A 02 01 03 00 87 6C C8 72 02 00 1E 02 01 1A 1A FF 4C 
  00 02 15 C0 A8 00 11 1F 92 4B CF D9 1F 26 0E F6 E2 00 00 00 
  00 00 00 00 BC 

Aha! There're my two Pies. I've highlighted the MAC number, which is reversed. The hex following is our advertising data, containing the URLs.

Interestingly, the last octet of the data has a number there. I did some tests to see if that was the RSSI, but it didn't seem to change in any correlation to the distance. The "1E" after the MAC tells us that there are 30 octets following, which does indeed fall one short of the end. More on this below.

It then hangs, presumably continuing to scan. When you kill it, hcidump splutters a bit:

< 01 0C 20 02 00 01 
> 04 0E 04 01 0C 20 00 

Here's the rather uninteresting output saved by the actual lescan command:

root@duncan-dell/0:~ -> cat out
LE Scan ...
00:02:72:C6:F1:B3 (unknown)
00:02:72:C8:6C:87 (unknown)

I believe that "unknown" refers to the fact that it found the "FF", or manufacturer-specific data, in the octet string. See below for more on that.


RSSI?

In pursuit of the RSSI, I ran hcidump without the raw mode flag and got more promising-looking output:

< HCI Command: LE Set Scan Parameters (0x08|0x000b) plen 7
    type 0x01 (active)
    interval 10.000ms window 10.000ms
    own address: 0x00 (Public) policy: All
> HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Parameters (0x08|0x000b) ncmd 1
    status 0x00

Ah! So that's what that meant.

< HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2
    value 0x01 (scanning enabled)
    filter duplicates 0x01 (enabled)
> HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00

Uh-huh..

> HCI Event: LE Meta Event (0x3e) plen 42
    LE Advertising Report
      ADV_NONCONN_IND - Non connectable undirected advertising (3)
      bdaddr 00:02:72:C8:6C:87 (Public)
      Flags: 0x1a
      Unknown type 0xff with 25 bytes data
      RSSI: -62
> HCI Event: LE Meta Event (0x3e) plen 42
    LE Advertising Report
      ADV_NONCONN_IND - Non connectable undirected advertising (3)
      bdaddr 00:02:72:C6:F1:B3 (Public)
      Flags: 0x1a
      Unknown type 0xff with 25 bytes data
      RSSI: -68

There's the supposed RSSI, then - but it's the same as that "random" octet - and it similarly doesn't change even when I press the Pi right up against the laptop BLE.

Notice the bit where it says it doesn't understand all this Apple-ese (0xff).

< HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2
    value 0x00 (scanning disabled)
    filter duplicates 0x01 (enabled)
> HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00

Killing the lescan.

This is all extremely clunky, but can be made to work, as long as I find out what's up with the RSSI. Someone else had the same issue it seems. I can at least set up the light object place links this way instead of hard-coding them.



5 comments:

  1. Any luck figuring out how to nail down RSSI?

    ReplyDelete
  2. Here is a patch for hcidump to include raw data with the LE Advertisements containing RSSI:
    https://github.com/twasiluk/bluez/commit/74def775c4a014b478ddfbc27a254a46ff94b99a

    Example output:
    > HCI Event: LE Meta Event (0x3e) plen 39
    LE Advertising Report
    ADV_NONCONN_IND - Non connectable undirected advertising (3)
    bdaddr F8:80:C9:73:97:43 (Random)
    Data:
    03 01 43 97 73 C9 80 F8 1B 1A FF 4C 00 02 15 2F 23 44 54 CF
    6D 4A 0F AD F2 F4 91 1B A9 FF A6 00 01 00 01 C8 D0
    RSSI: -48

    ReplyDelete
  3. hcidump -R will also print raw data without the patch, which you can then parse.

    ReplyDelete
  4. how to get a .cfa file for hci logs in linux

    ReplyDelete