Tuesday, December 21, 2010

Getting started hacking BLE CC2540DK-Mini on Linux

One of the currently available BLE (Bluetooth Low Energy) development kits is CC2540DK-MINI from Texas Instruments. We at Signove managed to get a few kits and I got to hack on these for a while. This post will describe some knowledge gathered regarding the kit.

The kit comes with:
  • 1 CC2540 key fob (slave)
  • 1 CC2540 USB dongle (master)
  • 1 CC debugger, used to program both key fob and dongle
Before trying to use it on Linux, I tried to follow TI instructions on their CC2540 Mini Development Kit Quick Start Guide (pdf). It teaches you how to program both key fob and dongle using the CC Debugger, their software (BLE software stack and tools) and the flash images already shipped with their software.

The programming of the devices was pretty straight-forward, the only thing worth mentioning is to be careful when connecting the cables - follow the images on the instructions and you won't have a problem.

Once the devices were programmed, I followed CC2540 Mini Development Kit User's Guide (pdf). It is a walk-through that shows how to use the dongle and the key fob together with BTool, a very simple tool that can locate the key fob, connect, read/write attributes, and so on. All functions worked fine with my setup and I moved on to hacking it on Linux.

We managed to get the dongle basic functions working on Linux with the following steps:

1. Plug in the dongle (this step is important)

2. Check which module was automatically loaded with:
dmesg | tail
In my case it was cdc_acm and it created the device /dev/ttyACM0.

3. Check whether the dongle was detected:
If it was detected, you may have a "Bus aaa Device bbb: ID 0451:16aa Texas Instruments, Inc." line on the output.

4. Attach the device to the BlueZ stack:
sudo hciattach /dev/ttyACM0 any 57600 flow
This step should output something similar to this:
Device setup complete
We used "any" for it to use a HCI_UART interface without vendor specific options. If you try to use "texas", it'll will complain about a missing /lib/firmware/TIInit_0.2.0.bts, which we don't know if it would make our hacking any easier. Anyways, using "any" works with our basic hacking and we're in contact with TI Low Power RF department to get some more info about it.

Now the device is attached to BlueZ, you should be able to list it on hciconfig:
hciconfig -a
In my case, my laptop only has one bluetooth adapter (hci0), so the new device was assigned to hci1. The output for the new adapter is something like this:
hci1: Type: BR/EDR Bus: UART
BD Address: 3C:2D:B7:84:0B:3B ACL MTU: 0:0 SCO MTU: 0:0
RX bytes: 271 acl:0 sco:0 events:19 errors:0
TX bytes: 121 acl:0 sco:0 commands:16 errors:0
Features: 0x00 0x00 0x00 0x60 0x00 0x00 0x00 0x00
Packet type: DM1 DH1 HV1
Link policy:
Can't read local name on hci1: Input/output error (5).
From this output, we can see our device is not getting detected as of BLE type. Also, hciconfig can't read its local name. If you attach a hcidump to hci1, you will see that the read local name command is not known by the dongle - incomplete firmware? yes.

But that won't stop your hacking. Now you have the dongle ready to be used within hcitool and use hcidump to observe the outcome of commands. After several attempts, we managed to get some commands (using hcitool -i hci1 cmd) working on the dongle.

One thing you might notice while playing some BLE commands is that some of them just don't work. Texas warns you about it on the TI_BLE_Vendor_Specific_HCI_Guide.pdf document, included on the software package. Basically, it says some commands/events might be discarded by the BLE stack they provided. Turns out that it actually does.

We tried to use the Low Energy scan - "lescan" - of BlueZ's hcitool and it hang on Set Scan Enable, a basic LE command. On the other hand, when we crafted two HCI vendor commands we got from BTool, we managed to locate the keyfob using BlueZ. For our simple test, we created a new function for hcitool named "texas-lescan", a ugly hack for using the HCI vendor commands for scanning, imitating BTool. If you're interested, you can take a look at the patch here (applies on bluez git tree parent ec31eb74a9e7).

It works. It starts a LE scan by sending two HCI vendor commands and keyfob gets detected when the right key is pressed. Though, we're not sure if this is the correct approach for BlueZ or dealing with these TI devices.

The thing is, the HEX images provided by TI seem not to be fully compliant with BLE. Maybe this is why they provided the source code for them and pointers on how to build your own firmware (using IAR embedded workbench). Are they expecting us to write the full BLE-compliant firmware for these two devices?


Arvydas Sidorenko said...

Thank you! Was very helpful to get me started since I was kinda stuck where to begin.
Btw, if anyone is getting errors on hciattach or cannot see /dev/ttyACM0 device, you might be missing some kernel modules inside Networking support ---> Bluetooth subsystem support:
o BNEP protocol support
o Bluetooth device drivers --> HCI UART driver
o Bluetooth device drivers --> HCI USB driver

Zoran said...

Could you, please tell me, what firmware did you use for CC2540?


George Lin said...

I followed your tutorial to setup CC2540.
But what I got is as following:

hci0: Type: BR/EDR Bus: UART
BD Address: 00:00:00:00:00:00 ACL MTU: 0:0 SCO MTU: 0:0
RX bytes:15 acl:0 sco:0 events:1 errors:0
TX bytes:4 acl:0 sco:0 commands:1 errors:0

The BD address is NULL and I cant type "hciconfig hci0 up" either.
Is there anything I should notice?

George Lin