Skip to content

Inspect Bluetooth packets

This should give some ideas and hints how to decode the Bluetooth protocol used by a gadget.

Tools

Articles

Android's Bluetooth logging

The most simple approach to "decode" the protocol would be sniffing packets sent by the original app. Android comes with a function to log all incoming and outgoing BT packets.

In order to capture the Bluetooth traffic, open Android's "Settings → Developer options" and check "Enable Bluetooth HCI snoop log". Then perform the action that you want to capture. After doing that, uncheck the option again.

The logging process (on Android 10) requires the following steps: 1. Enable developer options on your device. 2. Enable ADB on your device. 3. Enable Bluetooth HCI snoop log. 4. Toggle Bluetooth for logging to take effect. 5. Use original vendor app to connect to you your device, fire some commands.

Note

On some devices/Android versions the Bluetooth snoop log might be stored in a different location (e.g. /sdcard/Android/data/btsnoop_hci.log for a Samsung Galaxy S5). If you cannot find the log file, you can find out the correct path with (ADB must be installed):

adb shell cat /etc/bluetooth/bt_stack.conf | grep BtSnoop

See here for further details.

Alternatively, you can dump BT log by adb shell dumpsys bluetooth_manager:

  • Copy bugreport including BT log to PC adb bugreport or by adb pull data/misc/bluetooth/logs/btsnoop_hci.log
  • Paths can vary depending on device / android version. adb needs to run as root (adb root) to access /data
  • Find the log in the .zip package if you choose the bugreport way.
  • You will find the logfile at /sdcard/btsnoop_hci.log.

Getting on LineageOS

While the above explanations are correct, getting the bt_snoop easily is a critical skill and should be as fast as possible. Pulling data with adb bugreport, extracting the bt_snoop or even generating it with pybtsnooz.py takes a very long time and can often result in files which actually do not contain required data. Getting the bt_snoop is super easy on a rooted phone or an open ROM, like LineageOS, which actually provides rooted adb access directly (no installation of super su needed) in the Developer options in settings:

  • Enable Developer options.
  • Enable Bluetooth HCI snoop log.
  • Enable Rooted debugging.
  • Enable root adb with adb root on the computer.
  • Get the log with adb pull /data/misc/bluetooth/logs/btsnoop_hci.log btsnoop.log.

To reset the log, simple erase it on the phone:

  • Run adb shell rm /data/misc/bluetooth/logs/btsnoop_hci.log.
  • Disable/enable Bluetooth and then pull a new log.

Getting live bt_snoop data with Wireshark

Wireshark has support for live bt_snoop capture. This seems to work even on phones without root or adb root. Make first sure that bt_snoop logging is enabled:

  • Enable Developer options.
  • Enable Bluetooth HCI snoop log.
  • Connect the phone with your computer over USB cable.
  • Start Wireshark and in the menu → Capture, select "Refresh interfaces".
  • Select the newly visible Android Bluetooth Btsnoop.
  • Profit :).

On newer versions of Android the btsnoop port (8872) is not opened regardless of the option in Developer Options, so Wireshark won't detect it automatically. To check that this is the case use adb shell nc localhost 8871. As a workaround you can manually redirect the BtSnoop log into the port using the following command (copied from here):

adb shell su -c "'nc -s 127.0.0.1 -p 8872 -L system/bin/tail -f -c +0 data/misc/bluetooth/logs/btsnoop_hci.log'"

Wireshark dissectors

Wireshark offers the possibility to define dissectors which can highlight some data, filter them, calculate them, for further analysis. See some examples of dissectors here.

Working with data

By using a BLE scanner (listed above), basic information like BT MAC address, supported GATT services and ATT layer communication can already be collected. Also, collect the bt_snoop data as per above.

Analyze the logs

Now that we have the log we can use Wireshark to read and analyze the data.

  1. Open the btsnoop_hci.log you just pulled with Wireshark
  2. It is a good idea to see timestamp of the packets, you can do this by right clicking on the columns and enabling Time. Then, in the menu: "Edit → Preferences → Appearance → Columns → Time → double click on the Type" and choose the required time format, typically one of the UTC (UTC date, as YYYY....).
  3. Things can be made more clear by making use of Wireshark's great filtering capabilities. For example it may be good to only check packets from smartphone to gadget at first. This can be easily achieved by adding a filter bluetooth.dst == 78:02:xx:xx:xx:xx with the MAC address of your gadget (which you've found earlier by using nRF).
  4. Now you need a starting point. If you can link one easy command with it's packet you're nearly done. You could probably use the "find-my-device" command of the original vendor that lets your gadget vibrate. By firing this command often enough you may see an abnormality in the packet log with many similar packets.
  5. Once found a simple command and its associated packet you can use it as "marker". Make use of the packet colorization function and set up a rule for this marker packet. (e.g. btatt contains ab:00:00:00:01:02:07:01).
  6. Fire a couple marker commands, then a command you want to know the packet for and afterwards some marker commands again. By varying the amount of markers you can easily differentiate between the different unknown commands.

Once you found the first functions and its associated command bytes it makes to check the existing Gadgetbridge sources. It's really likely someone already uses this protocol (Or at least a similar version). That can make things a lot easier.

Following the data

  1. In Wireshark, set a filter to btatt, to only see the data flow and not all other stuff
  2. Find the place, where the phone did some action, to set something on the device (or the other way)
  3. Look at the handle and value in the Bluetooth Attribute Protocol tree:
    Bluetooth Attribute Protocol
        Opcode: Write Command (0x52)
        Handle: 0x0038 (Anhui Huami Information Technology Co., Ltd.: Unknown)
        Value: 06140001
    
  4. This gives you the characteristics and the data value.

Isolate parts of the captured data

In order to analyze data capture it is useful to isolate specific portion of the snoop. Here is one of the ways to do this. Basic capturing and exporting knowledge as describe above is presumed.

  1. Start the app in question, connect it to your band, go to the screen where you will want to perform the action of interest, wait for all syncing to happen.
  2. Capture the bt_snoop, open it in Wireshark, go to last line and note the line number.
  3. In the app, now perform the action of your interest, do only minimal actions, no screen switching etc.
  4. Capture the bt_snoop, open it in Wireshark. Go to line number as noted in step #2. Select all lines from here down (Shift + ). You might like to first apply the btatt filter, to only list relevant lines.
  5. Export only these lines via Wireshark menu: "Export specific packets → Export as Symbian OS btsnoop → Selected packets only".

This now gives you only the performed action captured as bt_snoop. It seems, that MAC addresses are now reset to 00:00. This is not a bad thing in order to be able to share it.