Thursday, January 2, 2014

Using Pure Python to Interact With an Ubertooth and Parse Bluetooth Baseband Data

In mid 2013 I gave a talk at a conference called Lockdown in Wisconsin. During the talk I released a pure python library for parsing rudimentary bluetooth baseband data and interacting with an Ubertooth USB device.

The core Ubertooth C libraries and tools are much more robust (and faster), but the pure python implementation provided the following:

Quick deployment with no need for compiling.

Rapid prototyping of new and custom Ubertooth tools in python.

Quick and easy way to hook up an Ubertooth to mobile phones and other ARM devices.

Ubertooth data integration into my favorite python analytic libraries

An excuse for me to better understand the baseband layer and pyusb

Quick Notes:

you will need the pure python pyusb library installed to use pyubertooth

Setup:

download the pyubertooth source code via git

the cli pyubertooth.py is in the pyubertooth/pyubertooth directory

git clone https://github.com/hackgnar/pyubertooth.git

cd pyubertooth/pyubertooth

For usage help:

python ubertooth.py --help

To log ubertooth data to a file (usable with ubertooth-rx -i filename):

An example of directly streaming ubertooth data to a file for 60 seconds:

Changing the channel on an ubertooth device:

import ubertooth
ut = Ubertooth()
ut.set_channel(66)

The libraries for this project only provide a fraction of Ubertooth's capabilities, and the baseband parser only provide LAP address and address parsing on baseband data. As time goes on, I will try to expand the functionality and speed of the library. I have also considered creating a python ctypes variant of the library to take advantage of the core Ubertooth C libaries. A ctypes variant would be much faster while still providing a python API for interacting with the Ubertooth and its data.

The pure python libraries can be found in this github repo, but be warned, the code is ugly and needs some serious refactoring.

1 comment:

Do you know if the data array given by self.rx_stream() comprises the RSSI value? (Here the Ubertooth-one USB hardware is set with `device.ctrl_transfer(0x40, 12, 2402+channel, 0)`; whereas in the ubertooth-specan-ui they compute the RSSI but the device is set `device.ctrl_transfer(0x40, 27, low_frequency, high_frequency)`.)