Bluetooth Low Energy (4.0) on Ubuntu 13.10: Advertisements, Sending and Receiving

Here is a quick tutorial on how to send and receive data without pairing with ubuntu 13.10 and two CSR 4.0 BTLE dongles ($12 including shipping from ebay for both dongles). Surprisingly straightforward.

  • install things

$ sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev bluez wireshark

  • plug in the first dongle (it should show up in hciconfig as “hci0”)
  • start LE scan capture

$ sudo hcitool lescan (you’ll see it spit out things such as “00:1A:7D:DA:71:0D (unknown)”)

  • start wireshark as root

$ sudo wireshark

  • In wireshark, start capture on bluetooth0
  • plug in the second dongle, should show up as hci1
  • program hci1 with hciconfig

$ sudo hciconfig hci1 noleadv (sometimes you can skip this step, sometimes the next step, leadv, will throw up “LE set advertise enable on hci1 returned status 12” if you don’t do noleadv first)

$ sudo hciconfig hci1 leadv

$ sudo hciconfig hci1 noscan

$ sudo hcitool -i hci1 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8 00

  • you’ll see the terminal spit out:

< HCI Command: ogf 0x08, ocf 0x0008, plen 32 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8 00

> HCI Event: 0x0e plen 4 01 08 20 00

  • On Wireshark, you should now get a packet and see the above data in it.

 

Screenshot from 2014-06-29 02:16:20

Python

Right now, I have only figured out how to read the advertisement data, not set it.

This is using code on stackoverflow: http://stackoverflow.com/questions/23788176/finding-bluetooth-low-energy-with-python which I saved as ble-python.py. If you add this line, it will print out the payload:

print(':'.join("{0:02x}".format(x) for x in data[44:13:-1]))

$ sudo python3 ble-python.py

00:1a:7d:da:71:09 c8:00:00:00:00:61:a9:07:ad:d1:17:2f:a1:c4:4b:f5:73:f4:39:0a:e2:15:02:00:4c:ff:1a:1a:01:02

You can see that both the manufacturer ID and the advertising payload is now printed out.

UPDATE 30 June 2014

Here is how to write data using the second CSR4.0 dongle and python:

import subprocess
dev = 'hci1'
adr = '0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 05 06 07 08 C8 00'
cmd_cc = "hcitool -i %s cmd %s" % ( dev, adr )
subprocess.Popen(cmd_cc.split(),stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()

and if you want to convert strings to hex,

s = 'some data'
" ".join("{:02x}".format(ord(c)) for c in s)

References

http://www.warski.org/blog/2014/01/how-ibeacons-work/ http://en.wikipedia.org/wiki/IBeacon http://hackaday.com/2013/12/05/turning-a-pi-into-an-ibeacon/ https://learn.adafruit.com/pibeacon-ibeacon-with-a-raspberry-pi/adding-ibeacon-data http://stackoverflow.com/questions/22568232/how-to-retrieve-advertising-payload-from-ibeacon-ble
http://stackoverflow.com/questions/23788176/finding-bluetooth-low-energy-with-python
https://www.bluetooth.org/en-us/specification/adopted-specifications, Core_v4.1.pdf, pg 2023 (Bluetooth 4.0 Core Spec. Volume 3, Part C, Section 11.1.4 or 11.1.10)