Analyzing iBeacon traffic using nRF BLE Sniffer


I’ve been troubleshooting iBeacons lately, and Bluetooth LE Sniffer from Adafruit is my go-to tool for sniffing Bluetooth LE (BLE) traffic such as iBeacon advertisements. iBeacon detection can vary a lot depending on advertisement interval and timing, and signal strength and its variance with distance, line of sight (or lack thereof), interference with other iBeacons etc.

nRF Sniffer software captures all BLE traffic in libpcap format that can be viewed in Wireshark. Its Wireshark dissector has fallen behind and does not work with latest version of Wireshark. Since I have written Wireshark dissectors in Lua before, I was quickly able to port the native dissector to Lua.

Here’s an iBeacon advertisement dissected using the nordic_ble Lua dissector, and Wireshark’s native btle dissector, on OS X. Note that iBeacon payload proprietary to Apple is not yet decoded by Wireshark’s btle dissector.

btle_adv_ind.png

Using data from the packet shown above, Apple’s proprietary payload has the following format

02 - ID
15 - Length (21 bytes)
3aa46f0c80784773be800255132aefda - 128-bit UUID
e4f2 - major number
e4c1 - minor number
b6 - two's complement of calibrated TX power

A filter such as btcommon.eir_ad.entry.data contains e4:f2:e4:c1 can be used to filter packets based on major and minor numbers.

NXP NTAG I2C NFC Forum tag with Bus Pirate


In this post, I use a Bus Pirate v4.0 to interact with an NXP NTAG I2C NFC Forum tag, over the latter’s I2C interface.

Connect Bus Pirate to the tag board as follows

  CLK ↔ SCL
 MOSI ↔ SDA
+3.3V ↔ VCC
  GND ↔ GND
  Vpu ↔ VCC

Transition to I2C mode, in hardware, clock rate of 100KHz

HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
10. PIC
11. DIO
x. exit(without change)

(1)>4
I2C mode:
 1. Software
 2. Hardware

(1)>2
Set speed:
 1. 100KHz
 2. 400KHz
 3. 1MHz
(1)>1
Ready

Enable power

I2C>W
POWER SUPPLIES ON

Enable pull-ups (the board does not come with any)

I2C>P
Pull-up resistors ON

Search for address of tag device

2C>(1)
Searching I2C address space. Found devices at:
0xAA(0x55 W)

Read one 16-byte block at 0x00 containing serial number et al

2C>[0xAA 0x00][0xAB r:16]
I2C START BIT
WRITE: 0xAA ACK
WRITE: 0x00 ACK
I2C STOP BIT
I2C START BIT
WRITE: 0xAB ACK
READ: 0x04  ACK 0x47  ACK 0x91  ACK 0x52  ACK 0x56  ACK 0x40  ACK 0x80  ACK 0x00  ACK 0x44  ACK 0x00  ACK 0x00  ACK 0x00  ACK 0xE1  ACK 0x10  ACK 0x6D  ACK 0x00
NACK
I2C STOP BIT

Read specified (i.e. 0x00) session register (address 0xFE) byte

I2C>[0xAA 0xFE 0x00][0xAB r]
I2C START BIT
WRITE: 0xAA ACK
WRITE: 0xFE ACK
WRITE: 0x00 ACK
I2C STOP BIT
I2C START BIT
WRITE: 0xAB ACK
READ: 0x01
NACK
I2C STOP BIT

I2C with Bus Pirate v4.0 on Windows 10


In this post, I learn to use a Bus Pirate v4.0 to retrieve raw linear acceleration data from a Tilt Compensated Compass Breakout (LSM303DLMTR), over the I2C bus (also referred to as TWI – two wire interface).

I’ve had a Bus Pirate v4.0 for three years now, but it has seen limited use because I’ve never really paused to use it in earnest.

I first used it on Windows 8 which had pretty stringent requirements for installing unsigned drivers, that I circumvented using a self-signed driver. Fortunately, Windows 10 does not require any driver installation.

The only thing you need to start using the Bus Pirate is a terminal emulation software such as Tera Term.

tera-term-bus-pirate.png
Tera Term version 4.93

Once you have Tera Term installed and connected to Bus Pirate’s serial port, you can start using the latter’s command line interface to issue commands.

To view help information

HiZ>?
General                                 Protocol interaction
---------------------------------------------------------------------------
?       This help                       (0)     List current macros
=X/|X   Converts X/reverse X            (x)     Macro x
~       Selftest                        [       Start
o       Set output type                 ]       Stop
$       Jump to bootloader              {       Start with read
&/%     Delay 1 us/ms                   }       Stop
a/A/@   AUXPIN (low/HI/READ)            "abc"   Send string
b       Set baudrate                    123     Send integer value
c/C/k/K AUX assignment (A0/CS/A1/A2)    0x123   Send hex value
d/D     Measure ADC (once/CONT.)        0b110   Send binary value
f       Measure frequency               r       Read
g/S     Generate PWM/Servo              /       CLK hi
h       Commandhistory                  \       CLK lo
i       Versioninfo/statusinfo          ^       CLK tick
l/L     Bitorder (msb/LSB)              -       DAT hi
m       Change mode                     _       DAT lo
e       Set Pullup Method               .       DAT read
p/P     Pullup resistors (off/ON)       !       Bit read
s       Script engine                   :       Repeat e.g. r:10
v       Show volts/states               ;       Bits to read/write e.g. 0x55;2
w/W     PSU (off/ON)            <x>/<x= >/<0>   Usermacro x/assign x/list all

To run a self test (connect ADC to +3.3V)

HiZ>~
Disconnect any devices
Connect (ADC to +3.3V)
Space to continue
Ctrl
AUX OK
MODE LED OK
PULLUP H OK
PULLUP L OK
VREG OK
EEPROM
SCL OK
SDA OK
WP OK
READ&WRITE OK
ADC and supply
Vusb(5.03) OK
5V(5.02) OK
5V VPU(4.89) OK
ADC(3.25) OK
3.3V(3.22) OK
3.3V VPU(3.23) OK
Bus high
MOSI OK
CLK OK
MISO OK
CS OK
Bus Hi-Z 0
MOSI OK
CLK OK
MISO OK
CS OK
Bus Hi-Z 1
MOSI OK
CLK OK
MISO OK
CS OK
MODE, VREG, and USB LEDs should be on!
Any key to exit
Found 0 errors.

Use the m command to select I2C mode

HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
10. PIC
11. DIO
x. exit(without change)

(1)>4
I2C mode:
1. Software
2. Hardware

(1)>2
Set speed:
1. 100KHz
2. 400KHz
3. 1MHz
(1)>1
Ready

Since the breakout is being powered using Bus Pirate, here’s how to disable/enable power output

I2C>w
POWER SUPPLIES OFF
I2C>W
POWER SUPPLIES ON

To check output voltages and I/O state

I2C>v
Pinstates:
#12     #11     #10     #09     #08     #07     #06     #05     #04     #03     #02     #01
GND     5.0V    3.3V    VPU     ADC     AUX2    AUX1    AUX     -       -       SCL     SDA
P       P       P       I       I       I       I       I       I       I       I       I
GND     5.02V   3.28V   0.00V   0.00V   L       L       L       L       L       L       L

To find the address of all devices in the breakout connected to the I2C bus, we can use Bus Pirate’s address search macro. Here’s how you can list all available macros, and run the address search macro

I2C>(0)
0.Macro menu
1.7bit address search
2.I2C sniffer
3.Connect to on-board EEPROM
4.Enable Writing the on-board EEPROM
I2C>(1)
Searching I2C address space. Found devices at:
0x30(0x18 W) 0x31(0x18 R) 0x3C(0x1E W) 0x3D(0x1E R)

For curiosity’s sake, here’s a partial waveform of the I2C bus when doing address search, analyzed using Saleae’s Logic Analyzer

logic-bus-pirate-i2c-macro.png
Address search waveform in Saleae Logic

Now that we know the address of the linear accelerometer (0x18), here’s how we can read register CTRL_REG1_A (note repeated START)

I2C>[0x30 0x20 [ 0x31 r]
I2C START BIT
WRITE: 0x30 ACK
WRITE: 0x20 ACK
I2C START BIT
WRITE: 0x31 ACK
READ: 0x07
NACK
I2C STOP BIT

I configure the breakout to normal (power) mode by writing to register CTRL_REG1_A (address 0x20), and read it back

I2C>[0x30 0x20 0x27]
I2C START BIT
WRITE: 0x30 ACK
WRITE: 0x20 ACK
WRITE: 0x27 ACK
I2C STOP BIT
I2C>[0x30 0x20 [ 0x31 r]
I2C START BIT
WRITE: 0x30 ACK
WRITE: 0x20 ACK
I2C START BIT
WRITE: 0x31 ACK
READ: 0x27
NACK

Here’s how to make use of the autoincrement bit in register address, to read registers STATUS_REG_A (address 0x27) through OUT_Z_H_A (0x2D), in one go

I2C>[0x30 0xa7 [ 0x31 r:7]
I2C START BIT
WRITE: 0x30 ACK
WRITE: 0xA7 ACK
I2C START BIT
WRITE: 0x31 ACK
READ: 0xFF  ACK 0xA0  ACK 0xF9  ACK 0x30  ACK 0x05  ACK 0xF0  ACK 0xC2
NACK
I2C STOP BIT

Read WHO_AM_I_M register (address 0x0F)

I2C>[0x3c 0x0f [ 0x3d r]
I2C START BIT
WRITE: 0x3C ACK
WRITE: 0x0F ACK
I2C START BIT
WRITE: 0x3D ACK
READ: 0x3C
NACK
I2C STOP BIT

Inquire Bluetooth service record on Windows


Linux distros have excellent built-in support for inquiring characteristics of Bluetooth devices around you, using hcitool and sdptool. The closest thing on Windows is the Bluetooth Inquiry Record Verifier tool (sdpverify.exe) that ships with Windows Driver Kit (WDK). Beware, WDK is a rather large download.

Screen Shot 2016-12-06 at 10.27.36.png

USB bulk data transfer


USB bulk data transfers is how most data transfer occurs between a USB host such as a PC and a peripheral. This post shows, with help from a Total Phase Beagle USB 480, how the data transfer looks like. Here’s data captured using Data Center software and a Total Phase Beagle USB 480. According to the USB specification, all bits in a byte are written to the bus in little-endian fashion, and multi-byte values are also written in little-endian order. While the latter is still valid with the Beagle USB 480, single byte values are represented in their normal big-endian order.

bulk transfer

Each USB bulk data transfer is broken into smaller data transfers. Each of the smaller data transfers is initiated by a token packet, followed by a data packet, and an ACK packet.

Incoming transfers begin with a token packet, that has a PID (packet identifier) of IN (0x69) in the first byte. Actually, the PID is contained in the last 4 bits (0x9), the first 4 bits are a one’s complement of that value (0x6). The second and third bytes form a single word in little endian byte order, containing a 5-bit CRC, followed by a 4-bit endpoint ID, followed by a 7-bit device ID. Thus ASCII hex sequence 81 58 in the figure above, should be interpreted as 0x5881, which results in a CRC of 0x0B, an endpoint ID of 0x1, and a device ID of 0x01.

The token packet is followed by a data packet. The PID of the data packet may be DATA0 (0xC3) or DATA1 (0x4B) for full-speed, and also DATA2 (0x87) for high-speed bulk transfers. The data packet has a maximum payload size determined by the USB specification, and is described by wMaxPacketSize attribute in the endpoint descriptor. It may be 8, 16, 32, or 64 bytes for full-speed bulk endpoints (USB 1.1), and also 512 bytes for high-speed (USB 2.0) bulk endpoints. It is 64 bytes in the capture shown above. The payload is followed by a 2-byte CRC.

The ACK handshake packet indicates the end of data transfer. A bulk data transfer is composed of several such data transfers in sequence. The end of a bulk data transfer is signalled by a data packet that has less than wMaxPacketSize bytes. If the last, or only data packet, carries wMaxPacketSize, a data transfer containing data packet with payload size of 0 bytes is required.

Outgoing transfers are quite similar, except that the token packet uses a PID of OUT (0xE1, or 0x1 to be more accurate). Outgoing bulk data transfers can appear jumbled up with incoming bulk data transfers. Applications that leverage Beagle API need to take this into consideration, when parsing data captured on the bus.

Physical serial port redirection


I have previously posted about Virtual serial port redirection on Windows, to develop and test applications that use serial ports. I’ve found the available drivers increasingly buggy on Windows 8.1. This post shows how you can wire two USB-Serial cables to achieve the same objective.

Serial Port Redirection

You’ll need two USB-Serial cables such as USB to TTL Serial Cable for Raspberry Pi from Adafruit or several similar ones from Amazon. Wire the cables so that the ground wires are connected, and receive wire of one cable is connected to the transmit of another and vice-versa. Plug the cables in and install the appropriate drivers. Windows usually works with FTDI chipset based cables without requiring installation of drivers.

Now, you should see two serial ports, which redirect data to each other.

Getting Started with Bluetooth Low Energy by Kevin Townsend et al; O’Reilly Media


Getting Started with Bluetooth Low Energy, Tools and Techniques for Low-Power Networking

Bluetooth LE, or Bluetooth Smart as it is officially known, has generated a lot of interest for all the good reasons. Getting Started with Bluetooth Low Energy by Kevin Townsend et al is a solid guide to the topic, along with other good books such as Bluetooth Low Energy: The Developer’s Handbook.

The book begins by discussing the key characteristics, limitations, and use cases of Bluetooth LE technology, in chapter 1. The following four chapters take a deep dive into the protocols that comprise Bluetooth LE, beginning with an overview in Chapter 2. Chapter 3 delves into the Generic Attribute Profile or GAP (advertising and connections). Chapter 4 delves into Generic Attribute Profile or GATT (services and characteristics).

Makers need to select hardware to leverage Bluetooth LE. It may come in the form of a module that you program to act as a peripheral, or a USB dongle that you may plug into a USB host. Chapter 5 discusses several such options. Chapters 6 and 7 delve into debugging and design tools that aid developers during development and troubleshooting.

Chapter 8 shows how to leverage Bluetooth LE on Android using the Bluetooth Application Accelerator library from the Bluetooth SIG. You’ll learn how to establish connection and communicate with a remote device. Chapter 9 delves into Bluetooth LE programming on iOS by demonstrating several practical applications.

Chapter 10, the concluding chapter, shows how to leverage Bluetooth LE on embedded devices. It uses a hardware module introduced in chapter 5, in conjunction with ARM’s mbed platform, to build a peripheral that can be used with Android and iOS devices.

All source code shown in the book can be forked from the author’s GitHub repo. The text has occasional spelling mistakes that don’t affect readability.

I’d like to thank O’Reilly Media for providing an e-book for review.