An open API service indexing awesome lists of open source software.

https://github.com/bertrandmartel/bluetooth-hci-decoder

:iphone: C++ Bluetooth HCI decoder library
https://github.com/bertrandmartel/bluetooth-hci-decoder

bluetooth cpp cpp-library hci json

Last synced: 11 months ago
JSON representation

:iphone: C++ Bluetooth HCI decoder library

Awesome Lists containing this project

README

          

# Bluetooth HCI decoder library #

[![Build Status](https://travis-ci.org/bertrandmartel/bluetooth-hci-decoder.svg?branch=master)](https://travis-ci.org/bertrandmartel/bluetooth-hci-decoder)
[![Download](https://api.bintray.com/packages/bertrandmartel/generic/bluetooth-hci-decoder/images/download.svg) ](https://bintray.com/bertrandmartel/generic/bluetooth-hci-decoder/_latestVersion)
[![License](http://img.shields.io/:license-mit-blue.svg)](LICENSE.md)

Lightweight Bluetooth HCI decoder library parsing individually HCI frames into JSON format

ChangeLogs can be found here

## Documentation

http://bertrandmartel.github.io/bluetooth-hci-decoder

## Setup & Build

```
git submodule init
git submodule update
cmake .
make
```

library release is located under `lib` directory.

## Test

A small test program is provided extracting HCI frames from a btsnoop file decoded with https://github.com/bertrandmartel/btsnoop-decoder

Syntax : ``./bthci-test ``

```
./bin/bthci-test ./snoop_files/btsnoop_hci.log
```

##Decoding

###Decode frame

Input should be a single HCI frame in `std::vector packet` format

Instanciate a `HciDecoder` class and call `IHciFrame* decode(std::vector packet);` :

```
HciDecoder hci_decoder;

IHciFrame * frame = hci_decoder.decode(packet);

```

`IHciFrame * frame` can be null if HCI frame is not currently supported

### Architecture

![architecture](img/arch.png)

###List of HCI frames

You can retrieve full list of `IHciFrame` decoded with a single `HciDecoder` with `std::vector getFrameList()` method :

```
std::vector frame_list = hci_decoder.getFrameList();

for (unsigned int i = 0; i < frame_list.size();i++){
frame_list.at(i)->print();
}
```

###Complete HCI frame list in JSON array

To convert all HCI frames previously decoded to json array format, use `std::string toJson(bool beautify)` :

```
std::string json_array_list = hci_decoder.toJson(false);

```
`beautify` to `true` will insert indentation and linefeed to string output

##JSON output format

Common fields for all HCI frames :

* packet_type
* parameters


field name
subfield name
type
description


packet_type
code
int
hci packet type numeric value


value
string
hci packet type string value


parameters

json object
parameters items

###Event

Common fields for all HCI Event frames:

* event_code
* parameter_total_length
* subevent_code (for subevent)


field name
subfield name
type
description


event_code
code
int
event numeric value


value
string
event string value


parameter_total_length

int
total length of parameters


subevent_code
code
int
subevent numeric value


value
string
subevent string value

Example :

```
{
"event_code" : {
"code" : 14,
"value" : "HCI_EVENT_COMMAND_COMPLETE"
},
"packet_type" : {
"code" : 4,
"value" : "HCI_TYPE_EVENT"
},
"parameter_total_length" : 4,
"parameters" : {
"command_opcode" : {
"ocf" : {
"code" : 26,
"value" : "HCI_CMD_OCF_CTRL_BSB_WRITE_SCAN_ENABLE_COMMAND"
},
"ogf" : {
"code" : 3,
"value" : "HCI_CMD_OGF_CONTROLLER_BASEBAND_COMMANDS"
}
},
"num_hci_command_packets" : 1,
"return_parameters" : {
"values" : {
"status" : 0
}
}
}
}
```

###Command

Common fields for all HCI Command frames:

* ogf (Opcode Group field)
* ocf (Opcode Command field)


field name
subfield name
type
description


ogf
code
int
opcode group field numeric value


value
string
opcode group field string value


ocf
code
int
opcode command field numeric value


value
string
opcode command field string value

```
{
"ocf" : {
"code" : 8,
"value" : "HCI_CMD_OCF_LE_SET_ADVERTISING_DATA_COMMAND"
},
"ogf" : {
"code" : 8,
"value" : "HCI_CMD_OGF_LE_CONTROLLER_COMMANDS"
},
"packet_type" : {
"code" : 1,
"value" : "HCI_TYPE_COMMAND"
},
"parameter_total_length" : 32,
"parameters" : {
"advertising_data" : [ 2, 1, 0 ],
"advertising_data_length" : 3
}
}
```
###Model & Supported Command / Events

* Packet types

| Packet type string | packet type value |
|--------------------|-------------------|
| HCI_TYPE_UNKNOWN | 0x00 |
| HCI_TYPE_COMMAND | 0x01 |
| HCI_TYPE_ACL_DATA | 0x02 |
| HCI_TYPE_SCO_DATA | 0x03 |
| HCI_TYPE_EVENT | 0x04 |


* Opcode Group field

| OGF string | OGF value |
|--------------------|-------------------|
| HCI_CMD_OGF_LINK_CONTROl_COMMANDS | 0x01 |
| HCI_CMD_OGF_LINK_POLICY_COMMANDS | 0x02 |
| HCI_CMD_OGF_CONTROLLER_BASEBAND_COMMANDS | 0x03 |
| HCI_CMD_OGF_INFORMATIONAL_PARAMETERS | 0x04 |
| HCI_CMD_OGF_STATUS_PARAMETERS | 0x05 |
| HCI_CMD_OGF_TESTING_COMMANDS | 0x06 |
| HCI_CMD_OGF_LE_CONTROLLER_COMMANDS | 0x08 |
| HCI_CMD_OGF_VENDOR_SPECIFIC | 0x3F |


* Informational Command

| HCI Command string | HCI command value |
|--------------------|-------------------|
| HCI_CMD_OCF_INFORMATIONAL_READ_LOCAL_SUPPORTED_COMMAND | 0x0002 |
| HCI_CMD_OCF_INFORMATIONAL_READ_BUFFER_SIZE_COMMAND | 0x0005 |
| HCI_CMD_OCF_INFORMATIONAL_READ_BD_ADDR | 0x0009 |
| HCI_CMD_OCF_INFORMATIONAL_READ_LOCAL_VERSION_INFORMATION_COMMAND | 0x0001 |
| HCI_CMD_OCF_INFORMATIONAL_READ_LOCAL_EXTENDED_FEATURES_COMMAND | 0x0004 |


* Le Command

| HCI Command string | HCI command value |
|--------------------|-------------------|
| HCI_CMD_OCF_LE_SET_SCAN_PARAMETERS_COMMAND | 0x000B |
| HCI_CMD_OCF_LE_SET_ADVERTISING_PARAMETERS_COMMAND | 0x0006 |
| HCI_CMD_OCF_LE_SET_SCAN_ENABLE_COMMAND | 0x000C |
| HCI_CMD_OCF_LE_CREATE_CONNECTION_COMMAND | 0x000D |
| HCI_CMD_OCF_LE_CLEAR_WHITE_LIST_COMMAND | 0x0010 |
| HCI_CMD_OCF_LE_READ_REMOTE_USED_FEATURES_COMMAND | 0x0016 |
| HCI_CMD_OCF_LE_READ_WHITE_LIST_SIZE_COMMAND | 0x000F |
| HCI_CMD_OCF_LE_SET_ADVERTISING_DATA_COMMAND | 0x0008 |
| HCI_CMD_OCF_LE_READ_BUFFER_SIZE_COMMAND | 0x0002 |
| HCI_CMD_OCF_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND | 0x0003 |
| HCI_CMD_OCF_LE_SET_EVENT_MASK_COMMAND | 0x0001 |
| HCI_CMD_OCF_LE_SET_RANDOM_ADDRESS_COMMAND | 0x0005 |
| HCI_CMD_OCF_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND | 0x001C |


* Link Control Command

| HCI Command string | HCI command value |
|--------------------|-------------------|
| HCI_CMD_OCF_LINK_CONTROL_INQUIRY_COMMAND | 0x0001 |
| HCI_CMD_OCF_LINK_CONTROL_INQUIRY_CANCEL_COMMAND | 0x0002 |
| HCI_CMD_OCF_LINK_CONTROL_DISCONNECT_COMMAND | 0x0006 |


* Link Policy Command

| HCI Command string | HCI command value |
|--------------------|-------------------|
| HCI_CMD_OCF_LINK_POLICY_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND | 0x000F |


* Baseband Control Command

| HCI Command string | HCI command value |
|--------------------|-------------------|
| HCI_CMD_OCF_CTRL_BSB_RESET_COMMAND | 0x0003 |
| HCI_CMD_OCF_CTRL_BSB_SET_EVENT_FILTER_COMMAND | 0x0005 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_LOCAL_NAME_COMMAND | 0x0013 |
| HCI_CMD_OCF_CTRL_BSB_READ_LOCAL_NAME_COMMAND | 0x0014 |
| HCI_CMD_OCF_CTRL_BSB_READ_CLASS_OF_DEVICE_COMMAND | 0x0023 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_CLASS_OF_DEVICE_COMMAND | 0x0024 |
| HCI_CMD_OCF_CTRL_BSB_READ_INQUIRY_MODE_COMMAND | 0x0044 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_INQUIRY_MODE_COMMAND | 0x0045 |
| HCI_CMD_OCF_CTRL_BSB_READ_LE_HOST_SUPPORT_COMMAND | 0x006C |
| HCI_CMD_OCF_CTRL_BSB_WRITE_LE_HOST_SUPPORT_COMMAND | 0x006D |
| HCI_CMD_OCF_CTRL_BSB_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND | 0x001E |
| HCI_CMD_OCF_CTRL_BSB_READ_INQUIRY_SCAN_ACTIVITY_COMMAND | 0x001D |
| HCI_CMD_OCF_CTRL_BSB_READ_VOICE_SETTING_COMMAND | 0x0025 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_VOICE_SETTING_COMMAND | 0x0026 |
| HCI_CMD_OCF_CTRL_BSB_READ_CURRENT_IAC_LAP_COMMAND | 0x0039 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_CURRENT_IAC_LAP_COMMAND | 0x003A |
| HCI_CMD_OCF_CTRL_BSB_READ_PAGE_SCAN_TYPE_COMMAND | 0x0046 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_PAGE_SCAN_TYPE_COMMAND | 0x0047 |
| HCI_CMD_OCF_CTRL_BSB_READ_SIMPLE_PAIRING_MODE_COMMAND | 0x0055 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_SIMPLE_PAIRING_MODE_COMMAND | 0x0056 |
| HCI_CMD_OCF_CTRL_BSB_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND | 0x0051 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND | 0x0052 |
| HCI_CMD_OCF_CTRL_BSB_READ_SCAN_ENABLE_COMMAND | 0x0019 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_SCAN_ENABLE_COMMAND | 0x001A |
| HCI_CMD_OCF_CTRL_BSB_READ_INQUIRY_SCAN_TYPE_COMMAND | 0x0042 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_INQUIRY_SCAN_TYPE_COMMAND | 0x0043 |
| HCI_CMD_OCF_CTRL_BSB_SET_EVENT_MASK_COMMAND | 0x0001 |
| HCI_CMD_OCF_CTRL_BSB_READ_PAGE_TIMEOUT_COMMAND | 0x0017 |
| HCI_CMD_OCF_CTRL_BSB_WRITE_PAGE_TIMEOUT_COMMAND | 0x0018 |
| HCI_CMD_OCF_CTRL_BSB_HOST_BUFFER_SIZE_COMMAND | 0x0033 |


* Events

| HCI event string | HCI event value |
|--------------------|-------------------|
| HCI_EVENT_COMMAND_COMPLETE | 0x0E |
| HCI_EVENT_LE_META | 0x3E |
| HCI_EVENT_DISCONNECTION_COMPLETE | 0x05 |
| HCI_EVENT_NUMBER_OF_COMPLETED_PACKET | 0x13 |
| HCI_EVENT_EXTENDED_INQUIRY_RESULT | 0x2F |
| HCI_EVENT_INQUIRY_COMPLETE | 0x01 |
| HCI_EVENT_COMMAND_STATUS | 0x0F |


* LE subevent

| HCI subevent string | HCI subevent value |
|--------------------|-------------------|
| HCI_EVENT_LE_CONNECTION_COMPLETE | 0x01 |
| HCI_EVENT_LE_ADVERTISING_REPORT | 0x02 |
| HCI_EVENT_LE_CONNECTION_UPDATE_COMPLETE | 0x03 |
| HCI_EVENT_LE_READ_REMOTE_USED_FEATURES_COMPLETE | 0x04 |
| HCI_EVENT_LE_LONG_TERM_KEY_REQUEST | 0x05 |
| HCI_EVENT_LE_REMOTE_CONNECTION_PARAMETER_REQUEST | 0x06 |
| HCI_EVENT_LE_DATA_LENGTH_CHANGE | 0x07 |
| HCI_EVENT_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE | 0x08 |
| HCI_EVENT_LE_GENERATE_DHKEY_COMPLETE | 0x09 |
| HCI_EVENT_LE_ENHANCED_CONNECTION_COMPLETE | 0x0A |
| HCI_EVENT_LE_DIRECT_ADVERTISING_REPORT | 0x0B |


* Advertising packets type

| HCI subevent string | HCI subevent value | fully decoded |
|--------------------------------------------------|-------------------|----------------|
| ADVERTIZING_TYPE_UNKNOWN | 0x00 | |
| ADVERTIZING_TYPE_FLAGS | 0x01 | X |
| ADVERTIZING_TYPE_INCOMPLETE_LIST_16BIT_SERVICE_CLASS_UUID | 0x02 | |
| ADVERTIZING_TYPE_COMPLETE_LIST_16BIT_SERVICE_CLASS_UUID | 0x03 | |
| ADVERTIZING_TYPE_INCOMPLETE_LIST_32BIT_SERVICE_CLASS_UUID | 0x04 | |
| ADVERTIZING_TYPE_COMPLETE_LIST_32BIT_SERVICE_CLASS_UUID | 0x05 | |
| ADVERTIZING_TYPE_INCOMPLETE_LIST_128BIT_SERVICE_CLASS_UUID | 0x06 | |
| ADVERTIZING_TYPE_COMPLETE_LIST_128BIT_SERVICE_CLASS_UUID | 0x07 | |
| ADVERTIZING_TYPE_SHORTENED_LOCAL_NAME | 0x08 | X |
| ADVERTIZING_TYPE_COMPLETE_LOCAL_NAME | 0x09 | X |
| ADVERTIZING_TYPE_TX_POWER_LEVEL | 0x0A | X |
| ADVERTIZING_TYPE_CLASS_OF_DEVICE | 0x0D | |
| ADVERTIZING_TYPE_SIMPLE_PAIRING_HASH_C | 0x0E | |
| ADVERTIZING_TYPE_SIMPLE_PAIRING_RANDOMIZER_R | 0x0F | |
| ADVERTIZING_TYPE_DEVICE_ID | 0x10 | |
| ADVERTIZING_TYPE_SECURITY_MANAGER_OUT_OF_BAND_FLAGS | 0x11 | |
| ADVERTIZING_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE | 0x12 | |
| ADVERTIZING_TYPE_LIST_16BIT_SOLICITATION_UUIDS | 0x14 | |
| ADVERTIZING_TYPE_LIST_32BIT_SOLICITATION_UUIDS | 0x1F | |
| ADVERTIZING_TYPE_LIST_128BIT_SOLICITATION_UUIDS | 0x15 | |
| ADVERTIZING_TYPE_SERVICE_DATA_16BIT | 0x16 | |
| ADVERTIZING_TYPE_SERVICE_DATA_32BIT | 0x20 | |
| ADVERTIZING_TYPE_SERVICE_DATA_128BIT | 0x21 | |
| ADVERTIZING_TYPE_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE | 0x22 | |
| ADVERTIZING_TYPE_LE_SECURE_CONNECTIONS_RANDOM_VALUE | 0x23 | |
| ADVERTIZING_TYPE_PUBLIC_TARGET_ADDRESS | 0x17 | |
| ADVERTIZING_TYPE_RANDOM_TARGET_ADDRESS | 0x18 | |
| ADVERTIZING_TYPE_APPEARANCE | 0x19 | |
| ADVERTIZING_TYPE_ADVERTIZING_INTERVAL | 0x1A | |
| ADVERTIZING_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS | 0x1B | |
| ADVERTIZING_TYPE_LE_ROLE | 0x1C | |
| ADVERTIZING_TYPE_SIMPLE_PAIRING_HASH | 0x1D | |
| ADVERTIZING_TYPE_SIMPLE_PAIRING_RANDOMIZER | 0x1E | |
| ADVERTIZING_TYPE_INFORMATION_DATA_3D | 0x3D | |
| ADVERTIZING_TYPE_MANUFACTURER_SPECIFIC_DATA | 0xFF | X |


##Android integration

An example using HCI decoder library is provided in `android-example` directory.

This example will decode a snoop file extracted from raw directory, parse all HCI frames in it and display results on the screen

An update of submodule of https://github.com/bertrandmartel/btsnoop-decoder is needed to retrieve source of btsnoop decoder project. Make sure you have done a `git submodule update` before

This is an Android Studio project which can be built with gradle :

```
cd android-example
./gradlew clean build
```

![android application](img/android.png)

###Troubleshoot

If you dont use Android NDK rc10 in your `Android.mk` change std include with your own path in you android-ndk source :

```
LOCAL_C_INCLUDES := $NDK/sources/cxx-stl/gnu-libstdc++/4.8/include
```


##External library

* json encoding with jsonccp : https://github.com/open-source-parsers/jsoncpp
* for testing HCI library, bluetooth snoop decoder : https://github.com/bertrandmartel/btsnoop-decoder

##Specifications

* Bluetooth specifications v4.2 - Volume 2 - Part E Host Controller Interface Functionnal Specification https://www.bluetooth.org