hci_packet_parser.cc revision 30e58068c1adaac7c5ccb3aa9cfb045d41d2a10e
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 19bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include <assert.h> 20bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 2130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson#include "buffer_allocator.h" 22bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "bt_types.h" 23bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "hcimsgs.h" 24bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "hci_layer.h" 25bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "hci_packet_parser.h" 26bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 2730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic const command_opcode_t NO_OPCODE_CHECKING = 0; 2830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 2930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic const allocator_t *buffer_allocator; 3030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 3130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic uint8_t *read_command_complete_header( 3230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 3330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson command_opcode_t expected_opcode, 3430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t minimum_bytes_after); 3530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 3630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_generic_command_complete(BT_HDR *response) { 3730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson read_command_complete_header(response, NO_OPCODE_CHECKING, 0 /* bytes after */); 3830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 3930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 4030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 4130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 42bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic void parse_read_buffer_size_response( 43bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson BT_HDR *response, 4430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint16_t *data_size_ptr, 4530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint16_t *acl_buffer_count_ptr) { 46bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 4730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_READ_BUFFER_SIZE, 5 /* bytes after */); 48bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson STREAM_TO_UINT16(*data_size_ptr, stream); 4930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_SKIP_UINT8(stream); // skip the sco packet length 5030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(*acl_buffer_count_ptr, stream); 5130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 5230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 5330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 5430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 5530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_local_version_info_response( 5630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 5730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson bt_version_t *bt_version) { 5830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 5930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_VERSION_INFO, 8 /* bytes after */); 6030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(bt_version->hci_version, stream); 6130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->hci_revision, stream); 6230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(bt_version->lmp_version, stream); 6330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->manufacturer, stream); 6430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(bt_version->lmp_subversion, stream); 6530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 6630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 6730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 6830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 6930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_bd_addr_response( 7030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 7130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson bt_bdaddr_t *address_ptr) { 7230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 7330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_READ_BD_ADDR, sizeof(bt_bdaddr_t) /* bytes after */); 7430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_BDADDR(address_ptr->address, stream); 7530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 7630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 7730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 7830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 7930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_local_supported_commands_response( 8030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 8130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *supported_commands_ptr, 8230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t supported_commands_length) { 8330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 8430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_SUPPORTED_CMDS, supported_commands_length /* bytes after */); 8530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_ARRAY(supported_commands_ptr, stream, (int)supported_commands_length); 8630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 8730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 8830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 8930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 9030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_read_local_extended_features_response( 9130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 9230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *page_number_ptr, 9330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *max_page_number_ptr, 9430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson bt_device_features_t *feature_pages, 9530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t feature_pages_count) { 9630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 9730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_EXT_FEATURES, 2 + sizeof(bt_device_features_t) /* bytes after */); 9830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*page_number_ptr, stream); 9930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*max_page_number_ptr, stream); 10030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 10130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson assert(*page_number_ptr < feature_pages_count); 10230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_ARRAY(feature_pages[*page_number_ptr].as_array, stream, (int)sizeof(bt_device_features_t)); 10330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 10430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 10530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 106bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 10730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_white_list_size_response( 10830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 10930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *white_list_size_ptr) { 11030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 11130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_WHITE_LIST_SIZE, 1 /* byte after */); 11230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*white_list_size_ptr, stream); 11330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 11430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 115bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 116bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 117bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic void parse_ble_read_buffer_size_response( 118bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson BT_HDR *response, 11930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint16_t *data_size_ptr, 12030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *acl_buffer_count_ptr) { 12130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 12230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SIZE, 3 /* bytes after */); 12330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT16(*data_size_ptr, stream); 12430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(*acl_buffer_count_ptr, stream); 12530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 12630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 12730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 12830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 12930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_supported_states_response( 13030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 13130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *supported_states, 13230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t supported_states_size) { 13330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 13430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_SUPPORTED_STATES, supported_states_size /* bytes after */); 13530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size); 13630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 13730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 13830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 13930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 14030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic void parse_ble_read_local_supported_features_response( 14130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 14230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson bt_device_features_t *supported_features) { 14330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 14430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_LOCAL_SPT_FEAT, sizeof(bt_device_features_t) /* bytes after */); 14530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_ARRAY(supported_features->as_array, stream, (int)sizeof(bt_device_features_t)); 14630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 14730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator->free(response); 14830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 14930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 15030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson// Internal functions 15130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 15230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonstatic uint8_t *read_command_complete_header( 15330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson BT_HDR *response, 15430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson command_opcode_t expected_opcode, 15530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson size_t minimum_bytes_after) { 15630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 157bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson uint8_t *stream = response->data + response->offset; 158bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 15930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Read the event header 16030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t event_code; 16130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t parameter_length; 16230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(event_code, stream); 16330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(parameter_length, stream); 16430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 16530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson const size_t parameter_bytes_we_read_here = 4; 16630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 16730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Check the event header values against what we expect 16830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson assert(event_code == HCI_COMMAND_COMPLETE_EVT); 16930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson assert(parameter_length >= (parameter_bytes_we_read_here + minimum_bytes_after)); 17030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 17130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Read the command complete header 17230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson command_opcode_t opcode; 17330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson uint8_t status; 17430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_SKIP_UINT8(stream); // skip the number of hci command packets field 175bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson STREAM_TO_UINT16(opcode, stream); 176bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 17730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Check the command complete header values against what we expect 17830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson if (expected_opcode != NO_OPCODE_CHECKING) { 17930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson assert(opcode == expected_opcode); 18030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson } 18130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 18230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Assume the next field is the status field 18330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson STREAM_TO_UINT8(status, stream); 18430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson // Make sure it was successful 18530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson assert(status == HCI_SUCCESS); 18630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 18730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson return stream; 188bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 189bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 190bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const hci_packet_parser_t interface = { 19130e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_generic_command_complete, 192bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson parse_read_buffer_size_response, 19330e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_read_local_version_info_response, 19430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_read_bd_addr_response, 19530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_read_local_supported_commands_response, 19630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_read_local_extended_features_response, 19730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_ble_read_white_list_size_response, 19830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_ble_read_buffer_size_response, 19930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_ble_read_supported_states_response, 20030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson parse_ble_read_local_supported_features_response 201bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson}; 202bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson 203bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonconst hci_packet_parser_t *hci_packet_parser_get_interface() { 20430e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator = buffer_allocator_get_interface(); 20530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson return &interface; 20630e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson} 20730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson 20830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnsonconst hci_packet_parser_t *hci_packet_parser_get_test_interface( 20930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson allocator_t *buffer_allocator_interface) { 21030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson buffer_allocator = buffer_allocator_interface; 211bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson return &interface; 212bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson} 213