hci_packet_parser.cc revision f2af1c42ccb2f642b241c2261b42d0be61d45438
1bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson/****************************************************************************** 2bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * 3bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * Copyright (C) 2014 Google, Inc. 4bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * 5bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * Licensed under the Apache License, Version 2.0 (the "License"); 6bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * you may not use this file except in compliance with the License. 7bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * You may obtain a copy of the License at: 8bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * 9bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * http://www.apache.org/licenses/LICENSE-2.0 10bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * 11bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * Unless required by applicable law or agreed to in writing, software 12bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * distributed under the License is distributed on an "AS IS" BASIS, 13bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * See the License for the specific language governing permissions and 15bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * limitations under the License. 16bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson * 17bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson ******************************************************************************/ 18bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 1949120dc867c7818511b5afec461dfc97d17eef58Marie Janssen#define LOG_TAG "bt_hci" 2049120dc867c7818511b5afec461dfc97d17eef58Marie Janssen 21db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "hci_packet_parser.h" 22dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach 23f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He#include <base/logging.h> 24bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 2530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson#include "buffer_allocator.h" 26bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "hci_layer.h" 27db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "hcimsgs.h" 28dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach#include "osi/include/log.h" 29bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 3030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic const command_opcode_t NO_OPCODE_CHECKING = 0; 3130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 325ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic const allocator_t* buffer_allocator; 3330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 345ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic uint8_t* read_command_complete_header(BT_HDR* response, 355ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson command_opcode_t expected_opcode, 365ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson size_t minimum_bytes_after); 3730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 385ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void parse_generic_command_complete(BT_HDR* response) { 395ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson read_command_complete_header(response, NO_OPCODE_CHECKING, 405ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson 0 /* bytes after */); 4130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 4230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 4330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 4430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 455ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void parse_read_buffer_size_response(BT_HDR* response, 465ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint16_t* data_size_ptr, 475ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint16_t* acl_buffer_count_ptr) { 485ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header(response, HCI_READ_BUFFER_SIZE, 495ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson 5 /* bytes after */); 50f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 51bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson STREAM_TO_UINT16(*data_size_ptr, stream); 525ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson STREAM_SKIP_UINT8(stream); // skip the sco packet length 5330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(*acl_buffer_count_ptr, stream); 5430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 5530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 5630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 5730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 585ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void parse_read_local_version_info_response(BT_HDR* response, 595ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson bt_version_t* bt_version) { 605ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 615ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_READ_LOCAL_VERSION_INFO, 8 /* bytes after */); 62f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 6330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(bt_version->hci_version, stream); 6430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->hci_revision, stream); 6530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(bt_version->lmp_version, stream); 6630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->manufacturer, stream); 6730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->lmp_subversion, stream); 6830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 6930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 7030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 7130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 72f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jellastatic void parse_read_local_supported_codecs_response( 735ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* number_of_local_supported_codecs, 745ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* local_supported_codecs) { 755ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 765ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_READ_LOCAL_SUPPORTED_CODECS, 0 /* bytes after */); 775ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (stream) { 78f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella STREAM_TO_UINT8(*number_of_local_supported_codecs, stream); 795ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson for (uint8_t i = 0; i < *number_of_local_supported_codecs; i++) { 80f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella STREAM_TO_UINT8(*local_supported_codecs, stream); 81f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella local_supported_codecs++; 82f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella } 83f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella } 84f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella 85f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella buffer_allocator->free(response); 86f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella} 87f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella 885ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void parse_read_bd_addr_response(BT_HDR* response, 895ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson bt_bdaddr_t* address_ptr) { 905ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 915ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_READ_BD_ADDR, sizeof(bt_bdaddr_t) /* bytes after */); 92f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 9330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_BDADDR(address_ptr->address, stream); 9430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 9530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 9630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 9730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 9830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_local_supported_commands_response( 995ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* supported_commands_ptr, 10030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t supported_commands_length) { 1015ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = 1025ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson read_command_complete_header(response, HCI_READ_LOCAL_SUPPORTED_CMDS, 1035ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson supported_commands_length /* bytes after */); 104f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 1055ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson STREAM_TO_ARRAY(supported_commands_ptr, stream, 1065ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson (int)supported_commands_length); 10730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 10830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 10930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 11030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 11130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_local_extended_features_response( 1125ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* page_number_ptr, uint8_t* max_page_number_ptr, 1135ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson bt_device_features_t* feature_pages, size_t feature_pages_count) { 1145ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1155ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_READ_LOCAL_EXT_FEATURES, 1165ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson 2 + sizeof(bt_device_features_t) /* bytes after */); 117dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach if (stream != NULL) { 118dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach STREAM_TO_UINT8(*page_number_ptr, stream); 119dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach STREAM_TO_UINT8(*max_page_number_ptr, stream); 120dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach 121f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(*page_number_ptr < feature_pages_count); 1225ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson STREAM_TO_ARRAY(feature_pages[*page_number_ptr].as_array, stream, 1235ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson (int)sizeof(bt_device_features_t)); 124dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach } else { 1255ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson LOG_ERROR(LOG_TAG, 1265ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson "%s() - WARNING: READING EXTENDED FEATURES FAILED. " 1275ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson "THIS MAY INDICATE A FIRMWARE/CONTROLLER ISSUE.", 1285ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson __func__); 129dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach } 13030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 13130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 13230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 133bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 13430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_white_list_size_response( 1355ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* white_list_size_ptr) { 1365ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1375ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_BLE_READ_WHITE_LIST_SIZE, 1 /* byte after */); 138f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 13930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*white_list_size_ptr, stream); 14030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 14130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 142bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 143bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 1445ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void parse_ble_read_buffer_size_response(BT_HDR* response, 1455ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint16_t* data_size_ptr, 1465ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* acl_buffer_count_ptr) { 1475ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1485ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_BLE_READ_BUFFER_SIZE, 3 /* bytes after */); 149f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 15030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(*data_size_ptr, stream); 15130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*acl_buffer_count_ptr, stream); 15230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 15330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 15430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 15530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 15630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_supported_states_response( 1575ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* supported_states, size_t supported_states_size) { 1585ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = 1595ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson read_command_complete_header(response, HCI_BLE_READ_SUPPORTED_STATES, 1605ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson supported_states_size /* bytes after */); 161f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 16230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size); 16330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 16430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 16530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 16630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 16730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_local_supported_features_response( 1685ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, bt_device_features_t* supported_features) { 1695ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1705ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_BLE_READ_LOCAL_SPT_FEAT, 1715ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson sizeof(bt_device_features_t) /* bytes after */); 172f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(stream != NULL); 1735ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson STREAM_TO_ARRAY(supported_features->as_array, stream, 1745ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson (int)sizeof(bt_device_features_t)); 17530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 17630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 17730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 17830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 179444a8da807abaf5f9e813ce70c56a79160495fb3Satya Callojistatic void parse_ble_read_resolving_list_size_response( 1805ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint8_t* resolving_list_size_ptr) { 1815ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1825ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */); 183444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji STREAM_TO_UINT8(*resolving_list_size_ptr, stream); 184444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji 185444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji buffer_allocator->free(response); 186444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji} 187444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji 188636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Agherastatic void parse_ble_read_suggested_default_data_length_response( 1895ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* response, uint16_t* ble_default_packet_length_ptr) { 1905ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = read_command_complete_header( 1915ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */); 192636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera STREAM_TO_UINT8(*ble_default_packet_length_ptr, stream); 1931f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski} 1941f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski 1951f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowskistatic void parse_ble_read_maximum_advertising_data_length( 1961f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski BT_HDR* response, uint16_t* ble_maximum_advertising_data_length_ptr) { 1971f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski uint8_t* stream = read_command_complete_header( 1981f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski response, HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, 1991f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski 2 /* bytes after */); 2001f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski STREAM_TO_UINT8(*ble_maximum_advertising_data_length_ptr, stream); 2011f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski 2021f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski buffer_allocator->free(response); 2031f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski} 2041f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski 2051f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowskistatic void parse_ble_read_number_of_supported_advertising_sets( 2061f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski BT_HDR* response, uint8_t* ble_number_of_supported_advertising_sets_ptr) { 2071f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski uint8_t* stream = read_command_complete_header( 2081f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski response, HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, 2091f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski 1 /* bytes after */); 2101f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski STREAM_TO_UINT8(*ble_number_of_supported_advertising_sets_ptr, stream); 211636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera 212636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera buffer_allocator->free(response); 213636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera} 214636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera 21530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson// Internal functions 21630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 2175ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic uint8_t* read_command_complete_header(BT_HDR* response, 2185ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson command_opcode_t expected_opcode, 2195ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson size_t minimum_bytes_after) { 2205ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* stream = response->data + response->offset; 221bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 22230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Read the event header 22330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t event_code; 22430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t parameter_length; 22530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(event_code, stream); 22630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(parameter_length, stream); 22730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 22830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson const size_t parameter_bytes_we_read_here = 4; 22930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 23030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Check the event header values against what we expect 231f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(event_code == HCI_COMMAND_COMPLETE_EVT); 232f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(parameter_length >= 233f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He (parameter_bytes_we_read_here + minimum_bytes_after)); 23430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 23530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Read the command complete header 23630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson command_opcode_t opcode; 23730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t status; 2385ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson STREAM_SKIP_UINT8(stream); // skip the number of hci command packets field 239bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson STREAM_TO_UINT16(opcode, stream); 240bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 24130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Check the command complete header values against what we expect 24230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson if (expected_opcode != NO_OPCODE_CHECKING) { 243f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(opcode == expected_opcode); 24430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson } 24530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 24630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Assume the next field is the status field 24730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(status, stream); 248dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach 2495ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (status != HCI_SUCCESS) { 25085e22b32ec3482a09dc019ee6fd096a31fd1bf64Jakub Pawlowski LOG_ERROR(LOG_TAG, "%s: return status - 0x%x", __func__, status); 251dbcb1b58baeac019fafd4b43df751ff8f6c3d5d4Andre Eisenbach return NULL; 252f6dcf79f62880e716e127b19c70ea328e07c6051Srinu Jella } 25330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 25430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson return stream; 255bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 256bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 257bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const hci_packet_parser_t interface = { 2585ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_generic_command_complete, 2595ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_buffer_size_response, 2605ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_local_version_info_response, 2615ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_bd_addr_response, 2625ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_local_supported_commands_response, 2635ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_local_extended_features_response, 2645ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_white_list_size_response, 2655ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_buffer_size_response, 2665ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_supported_states_response, 2675ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_local_supported_features_response, 2685ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_resolving_list_size_response, 2695ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_ble_read_suggested_default_data_length_response, 2701f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski parse_ble_read_maximum_advertising_data_length, 2711f4cc6dc61ad5863c3fe31dafd364e064b1e64adJakub Pawlowski parse_ble_read_number_of_supported_advertising_sets, 2725ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson parse_read_local_supported_codecs_response}; 2735ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson 2745ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonconst hci_packet_parser_t* hci_packet_parser_get_interface() { 27530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator = buffer_allocator_get_interface(); 27630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson return &interface; 27730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 27830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 2795ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonconst hci_packet_parser_t* hci_packet_parser_get_test_interface( 2805ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson allocator_t* buffer_allocator_interface) { 28130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator = buffer_allocator_interface; 282bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson return &interface; 283bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 284