Hacking Bluetooth To Learn More About Boondock Battery Life

Capturing Bluetooth Data

Where to Intercept Data in the BluetoothLE Software Stack

Bluetooth is a very complicated protocol. A few years ago I wrote "What is Bluetooth 5?  Learn about the Bit Paths Behind the New BLE Standard" for AllAboutCircuits.com.  That article looked at the bit manipulations performed on raw data in the Link Layer just before it hits the airwaves in the Physical Layer. There are convolutional encoders that provide forward error correction, data whitening filters, and oh, the standard allows the data to jump over a variety of channels.  All of this makes intercepting and then interpreting over-the-air packets relatively cumbersome. While you can use Software Defined Radios to capture and channelize RF data and convert it into packets, it is much easier to capture data at the Host Controller Interface (HCI) level in the Bluetooth Software Stack, and that's the method I chose.

Use an Android Phone

Android phones can capture data packets at the Host Controller Interface level and write it to internal memory for later analysis.  Start by putting your device into developer mode.

Go into Settings, find Build Number and tap it repeatedly until the phone switches to developer mode. 

This screen capture shows that developer mode is on.

Next, in settings, find Developer Options and enable the Enable Bluetooth HCI Snoop Log option.  Then power cycle Bluetooth to turn snooping on -- you'll need Bluetooth to be active for the next part to work.

This screen grab shows how to turn Bluetooth logging on

Connect to the Device and Systematicaly Press Every Button

Open the app you're interested in reverse engineering and connect to your Bluetooth enabled device.  Then systematically press every button in the app.  If the app collects data, let it collect data for several minutes.  If possible, carefully control the inputs so you'll know what the values should be.  Finally disconnect the bluetooth device and close the app.

The FNIRSI FN58B App

Turn off Developer Mode and Export the Logfile

Go back into Settings and disable Enable HCI Snoop Log. Then open up the phone calling app and type #9900# or *#9900# to enter a hidden screen. Click Run dumpstate/logcat and once complete, click Copy to sdcard(include CP Ramdump).

This screen grab shows how to transfer the log files to accessible memory

Find the Logfile and Copy it to Your Computer

Open up your Files app, navigate to Internal Storage > log > bluetooth.  Look for btsnoop_hci_yyyymmddhhmm.cfa  Once you find it, transfer that file to your computer

This screen shows the log files that you need to transfer to your computer

Open the logfile in WireShark

You're going to get a lot of data, not all of which is relevant.  To filter just the relevant conversation, and only when there is data, use the following filter in Wireshark:

bluetooth.addr ==  98:da:b0:08:aa:88 && btatt.value >= 0

Wireshark Screen Capture

Then, in WireShark, go to File > Export Packet Dissections > As CSV

After you filter the data in wireshark, export the data values you want to analyze

Then you can open the .csv file and you'll have all the packets.

Excel probably isn't the best analysis program for this, but it does make it easy to demonstrate in an article

At this point, the data analysis is part art and part science.  Start by looking for repeating bytes.  In this case, 0xAA shows up at the beginning of every data frame.  So I split all the data everytime I saw 0xAA, and then sorted by the next packet number.













00: Start of frame
01: Data Type
02: Data Length
04-end: Data





00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
                                         
aa 04 0c 99 c5 00 00 da 03 00 00 7e 13 00 00 92          
aa 04 0c 51 c6 00 00 21 03 00 00 e5 0f 00 00 81          
aa 04 0c 82 c4 00 00 dc 03 00 00 6d 13 00 00 0c          
aa 04 0c ee c7 00 00 f7 02 00 00 2e 0f 00 00 8e          
                                         
aa 05 07 05 d3 07 00 01 52 01 c7                    
aa 05 07 09 aa 09 00 01 52 01 7a                    
aa 05 07 8e c3 07 00 01 52 01 95                    
aa 05 07 c2 48 0a 00 01 52 01 ea                    
                                         
aa 06 06 7a 0b 7b 0b 00 00 c2                      
aa 06 06 78 0b 76 0b 00 00 04                      
aa 06 06 72 0b 72 0b 00 00 f7                      
aa 06 06 79 0b 7a 0b 00 00 96                      
aa 06 06 7f 0b 7e 0b 00 00 86                      
aa 06 06 76 0b 76 0b 00 00 a7                      
aa 06 06 74 0b 73 0b 00 00 a2                      
aa 06 06 76 0b 78 0b 00 00 fd                      
aa 06 06 7f 0b 7f 0b 00 00 32                      
aa 06 06 6d 0b 6e 0b 00 00 e5                      
aa 06 06 7c 0b 7b 0b 00 00 23                      
                                         
aa 07 04 d1 13 4d 00 12                          
aa 07 04 bd 13 63 00 1b                          
aa 07 04 cf 13 6a 00 9e                          
aa 07 04 d4 13 50 00 78                          
aa 07 04 b1 13 68 00 d3                          
aa 07 04 e8 13 4a 00 1b                          
aa 07 04 a6 13 5d 00 39                          
aa 07 04 ba 13 51 00 c1                          
aa 07 04 fe 13 4b 00 14                          
aa 07 04 a7 13 71 00 06                          
aa 07 04 ce 13 52 00 16                          
                                         
aa 08 11 02 c4 d5 00 00 11 2a 00 00 10 0e 00 00 28 00 00 00 31
aa 08 11 02 c4 d5 00 00 11 2a 00 00 10 0e 00 00 29 00 00 00 85

That's when things started making a bit more sense.  Here's the basic structure.

Byte
Values
Notes
01 0xAA Start of frame
02 0x04, 0x05, 0x06, 0x07, 0x08 Data type (e.g. 0x07 is Voltage and Current, 0x06 appears to be DP and DN voltage, 0x04 might be Impedance, etc.)
03 0x04, 0x06, 0x07, 0x0C, 0x11, 0xC4 Data length
04/05 0xXXYY Little-Endian Values
etc. 0xZZ The last byte in each data packet isn't clear.  It doesn't appear to be a CRC.  It might be a nib that adds a degree of precision to the previous doubles, making them 24 bit-depth.  Unknown.

That's the hard part.  Now to determine which data types the other parts are, you've just got to match screen values to little-endian doible values.  That's been left as an exercise for the reader.

Happy Hacking everyone!