1 /****************************************************************************** 2 * 3 * Copyright 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #define LOG_TAG "bt_hci" 20 21 #include "hci_packet_parser.h" 22 23 #include <base/logging.h> 24 25 #include "buffer_allocator.h" 26 #include "hci_layer.h" 27 #include "hcimsgs.h" 28 #include "osi/include/log.h" 29 30 static const command_opcode_t NO_OPCODE_CHECKING = 0; 31 32 static const allocator_t* buffer_allocator; 33 34 static uint8_t* read_command_complete_header(BT_HDR* response, 35 command_opcode_t expected_opcode, 36 size_t minimum_bytes_after); 37 38 static void parse_generic_command_complete(BT_HDR* response) { 39 read_command_complete_header(response, NO_OPCODE_CHECKING, 40 0 /* bytes after */); 41 42 buffer_allocator->free(response); 43 } 44 45 static void parse_read_buffer_size_response(BT_HDR* response, 46 uint16_t* data_size_ptr, 47 uint16_t* acl_buffer_count_ptr) { 48 uint8_t* stream = read_command_complete_header(response, HCI_READ_BUFFER_SIZE, 49 5 /* bytes after */); 50 CHECK(stream != NULL); 51 STREAM_TO_UINT16(*data_size_ptr, stream); 52 STREAM_SKIP_UINT8(stream); // skip the sco packet length 53 STREAM_TO_UINT16(*acl_buffer_count_ptr, stream); 54 55 buffer_allocator->free(response); 56 } 57 58 static void parse_read_local_version_info_response(BT_HDR* response, 59 bt_version_t* bt_version) { 60 uint8_t* stream = read_command_complete_header( 61 response, HCI_READ_LOCAL_VERSION_INFO, 8 /* bytes after */); 62 CHECK(stream != NULL); 63 STREAM_TO_UINT8(bt_version->hci_version, stream); 64 STREAM_TO_UINT16(bt_version->hci_revision, stream); 65 STREAM_TO_UINT8(bt_version->lmp_version, stream); 66 STREAM_TO_UINT16(bt_version->manufacturer, stream); 67 STREAM_TO_UINT16(bt_version->lmp_subversion, stream); 68 69 buffer_allocator->free(response); 70 } 71 72 static void parse_read_local_supported_codecs_response( 73 BT_HDR* response, uint8_t* number_of_local_supported_codecs, 74 uint8_t* local_supported_codecs) { 75 uint8_t* stream = read_command_complete_header( 76 response, HCI_READ_LOCAL_SUPPORTED_CODECS, 0 /* bytes after */); 77 if (stream) { 78 STREAM_TO_UINT8(*number_of_local_supported_codecs, stream); 79 for (uint8_t i = 0; i < *number_of_local_supported_codecs; i++) { 80 STREAM_TO_UINT8(*local_supported_codecs, stream); 81 local_supported_codecs++; 82 } 83 } 84 85 buffer_allocator->free(response); 86 } 87 88 static void parse_read_bd_addr_response(BT_HDR* response, 89 RawAddress* address_ptr) { 90 uint8_t* stream = read_command_complete_header( 91 response, HCI_READ_BD_ADDR, RawAddress::kLength /* bytes after */); 92 CHECK(stream != NULL); 93 STREAM_TO_BDADDR(*address_ptr, stream); 94 95 buffer_allocator->free(response); 96 } 97 98 static void parse_read_local_supported_commands_response( 99 BT_HDR* response, uint8_t* supported_commands_ptr, 100 size_t supported_commands_length) { 101 uint8_t* stream = 102 read_command_complete_header(response, HCI_READ_LOCAL_SUPPORTED_CMDS, 103 supported_commands_length /* bytes after */); 104 CHECK(stream != NULL); 105 STREAM_TO_ARRAY(supported_commands_ptr, stream, 106 (int)supported_commands_length); 107 108 buffer_allocator->free(response); 109 } 110 111 static void parse_read_local_extended_features_response( 112 BT_HDR* response, uint8_t* page_number_ptr, uint8_t* max_page_number_ptr, 113 bt_device_features_t* feature_pages, size_t feature_pages_count) { 114 uint8_t* stream = read_command_complete_header( 115 response, HCI_READ_LOCAL_EXT_FEATURES, 116 2 + sizeof(bt_device_features_t) /* bytes after */); 117 CHECK(stream != NULL); 118 119 STREAM_TO_UINT8(*page_number_ptr, stream); 120 STREAM_TO_UINT8(*max_page_number_ptr, stream); 121 122 CHECK(*page_number_ptr < feature_pages_count); 123 STREAM_TO_ARRAY(feature_pages[*page_number_ptr].as_array, stream, 124 (int)sizeof(bt_device_features_t)); 125 126 buffer_allocator->free(response); 127 } 128 129 static void parse_ble_read_white_list_size_response( 130 BT_HDR* response, uint8_t* white_list_size_ptr) { 131 uint8_t* stream = read_command_complete_header( 132 response, HCI_BLE_READ_WHITE_LIST_SIZE, 1 /* byte after */); 133 CHECK(stream != NULL); 134 STREAM_TO_UINT8(*white_list_size_ptr, stream); 135 136 buffer_allocator->free(response); 137 } 138 139 static void parse_ble_read_buffer_size_response(BT_HDR* response, 140 uint16_t* data_size_ptr, 141 uint8_t* acl_buffer_count_ptr) { 142 uint8_t* stream = read_command_complete_header( 143 response, HCI_BLE_READ_BUFFER_SIZE, 3 /* bytes after */); 144 CHECK(stream != NULL); 145 STREAM_TO_UINT16(*data_size_ptr, stream); 146 STREAM_TO_UINT8(*acl_buffer_count_ptr, stream); 147 148 buffer_allocator->free(response); 149 } 150 151 static void parse_ble_read_supported_states_response( 152 BT_HDR* response, uint8_t* supported_states, size_t supported_states_size) { 153 uint8_t* stream = 154 read_command_complete_header(response, HCI_BLE_READ_SUPPORTED_STATES, 155 supported_states_size /* bytes after */); 156 CHECK(stream != NULL); 157 STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size); 158 159 buffer_allocator->free(response); 160 } 161 162 static void parse_ble_read_local_supported_features_response( 163 BT_HDR* response, bt_device_features_t* supported_features) { 164 uint8_t* stream = read_command_complete_header( 165 response, HCI_BLE_READ_LOCAL_SPT_FEAT, 166 sizeof(bt_device_features_t) /* bytes after */); 167 CHECK(stream != NULL); 168 STREAM_TO_ARRAY(supported_features->as_array, stream, 169 (int)sizeof(bt_device_features_t)); 170 171 buffer_allocator->free(response); 172 } 173 174 static void parse_ble_read_resolving_list_size_response( 175 BT_HDR* response, uint8_t* resolving_list_size_ptr) { 176 uint8_t* stream = read_command_complete_header( 177 response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */); 178 STREAM_TO_UINT8(*resolving_list_size_ptr, stream); 179 180 buffer_allocator->free(response); 181 } 182 183 static void parse_ble_read_suggested_default_data_length_response( 184 BT_HDR* response, uint16_t* ble_default_packet_length_ptr) { 185 uint8_t* stream = read_command_complete_header( 186 response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */); 187 STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream); 188 189 buffer_allocator->free(response); 190 } 191 192 static void parse_ble_read_maximum_data_length_response( 193 BT_HDR* response, uint16_t* ble_supported_max_tx_octets, 194 uint16_t* ble_supported_max_tx_time, uint16_t* ble_supported_max_rx_octets, 195 uint16_t* ble_supported_max_rx_time) { 196 uint8_t* stream = read_command_complete_header( 197 response, HCI_BLE_READ_MAXIMUM_DATA_LENGTH, 8 /* bytes after */); 198 STREAM_TO_UINT16(*ble_supported_max_tx_octets, stream); 199 STREAM_TO_UINT16(*ble_supported_max_tx_time, stream); 200 STREAM_TO_UINT16(*ble_supported_max_rx_octets, stream); 201 STREAM_TO_UINT16(*ble_supported_max_rx_time, stream); 202 203 buffer_allocator->free(response); 204 } 205 206 static void parse_ble_read_maximum_advertising_data_length( 207 BT_HDR* response, uint16_t* ble_maximum_advertising_data_length_ptr) { 208 uint8_t* stream = read_command_complete_header( 209 response, HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, 210 2 /* bytes after */); 211 STREAM_TO_UINT16(*ble_maximum_advertising_data_length_ptr, stream); 212 213 buffer_allocator->free(response); 214 } 215 216 static void parse_ble_read_number_of_supported_advertising_sets( 217 BT_HDR* response, uint8_t* ble_number_of_supported_advertising_sets_ptr) { 218 uint8_t* stream = read_command_complete_header( 219 response, HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, 220 1 /* bytes after */); 221 STREAM_TO_UINT8(*ble_number_of_supported_advertising_sets_ptr, stream); 222 223 buffer_allocator->free(response); 224 } 225 226 // Internal functions 227 228 static uint8_t* read_command_complete_header(BT_HDR* response, 229 command_opcode_t expected_opcode, 230 size_t minimum_bytes_after) { 231 uint8_t* stream = response->data + response->offset; 232 233 // Read the event header 234 uint8_t event_code; 235 uint8_t parameter_length; 236 STREAM_TO_UINT8(event_code, stream); 237 STREAM_TO_UINT8(parameter_length, stream); 238 239 const size_t parameter_bytes_we_read_here = 4; 240 241 // Check the event header values against what we expect 242 CHECK(event_code == HCI_COMMAND_COMPLETE_EVT); 243 CHECK(parameter_length >= 244 (parameter_bytes_we_read_here + minimum_bytes_after)); 245 246 // Read the command complete header 247 command_opcode_t opcode; 248 uint8_t status; 249 STREAM_SKIP_UINT8(stream); // skip the number of hci command packets field 250 STREAM_TO_UINT16(opcode, stream); 251 252 // Check the command complete header values against what we expect 253 if (expected_opcode != NO_OPCODE_CHECKING) { 254 CHECK(opcode == expected_opcode); 255 } 256 257 // Assume the next field is the status field 258 STREAM_TO_UINT8(status, stream); 259 260 if (status != HCI_SUCCESS) { 261 LOG_ERROR(LOG_TAG, "%s: return status - 0x%x", __func__, status); 262 return NULL; 263 } 264 265 return stream; 266 } 267 268 static const hci_packet_parser_t interface = { 269 parse_generic_command_complete, 270 parse_read_buffer_size_response, 271 parse_read_local_version_info_response, 272 parse_read_bd_addr_response, 273 parse_read_local_supported_commands_response, 274 parse_read_local_extended_features_response, 275 parse_ble_read_white_list_size_response, 276 parse_ble_read_buffer_size_response, 277 parse_ble_read_supported_states_response, 278 parse_ble_read_local_supported_features_response, 279 parse_ble_read_resolving_list_size_response, 280 parse_ble_read_suggested_default_data_length_response, 281 parse_ble_read_maximum_data_length_response, 282 parse_ble_read_maximum_advertising_data_length, 283 parse_ble_read_number_of_supported_advertising_sets, 284 parse_read_local_supported_codecs_response}; 285 286 const hci_packet_parser_t* hci_packet_parser_get_interface() { 287 buffer_allocator = buffer_allocator_get_interface(); 288 return &interface; 289 } 290 291 const hci_packet_parser_t* hci_packet_parser_get_test_interface( 292 allocator_t* buffer_allocator_interface) { 293 buffer_allocator = buffer_allocator_interface; 294 return &interface; 295 } 296