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
- Host: GitHub
- URL: https://github.com/bertrandmartel/bluetooth-hci-decoder
- Owner: bertrandmartel
- License: mit
- Created: 2015-11-22T03:03:27.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2020-10-01T21:54:37.000Z (over 5 years ago)
- Last Synced: 2025-04-19T20:17:43.727Z (12 months ago)
- Topics: bluetooth, cpp, cpp-library, hci, json
- Language: C++
- Homepage:
- Size: 1.72 MB
- Stars: 27
- Watchers: 8
- Forks: 10
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Bluetooth HCI decoder library #
[](https://travis-ci.org/bertrandmartel/bluetooth-hci-decoder)
[ ](https://bintray.com/bertrandmartel/generic/bluetooth-hci-decoder/_latestVersion)
[](LICENSE.md)
Lightweight Bluetooth HCI decoder library parsing individually HCI frames into JSON format
## 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

###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
```

###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