1 /******************************************************************************
2 *
3 * Copyright (C) 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 #include "common/bt_defs.h"
20
21 #include "stack/bt_types.h"
22 #include "stack/hcimsgs.h"
23 #include "hci/hci_layer.h"
24 #include "hci/hci_packet_parser.h"
25
26 static const command_opcode_t NO_OPCODE_CHECKING = 0;
27
28 static uint8_t *read_command_complete_header(
29 BT_HDR *response,
30 command_opcode_t expected_opcode,
31 size_t minimum_bytes_after);
32
parse_generic_command_complete(BT_HDR * response)33 static void parse_generic_command_complete(BT_HDR *response)
34 {
35 read_command_complete_header(response, NO_OPCODE_CHECKING, 0 /* bytes after */);
36
37 osi_free(response);
38 }
39
parse_read_buffer_size_response(BT_HDR * response,uint16_t * acl_data_size_ptr,uint16_t * acl_buffer_count_ptr,uint8_t * sco_data_size_ptr,uint16_t * sco_buffer_count_ptr)40 static void parse_read_buffer_size_response(
41 BT_HDR *response,
42 uint16_t *acl_data_size_ptr,
43 uint16_t *acl_buffer_count_ptr,
44 uint8_t *sco_data_size_ptr,
45 uint16_t *sco_buffer_count_ptr)
46 {
47
48 uint8_t *stream = read_command_complete_header(response, HCI_READ_BUFFER_SIZE, 7 /* bytes after */);
49 assert(stream != NULL);
50 STREAM_TO_UINT16(*acl_data_size_ptr, stream);
51 STREAM_TO_UINT8(*sco_data_size_ptr, stream);
52 STREAM_TO_UINT16(*acl_buffer_count_ptr, stream);
53 STREAM_TO_UINT16(*sco_buffer_count_ptr, stream);
54 osi_free(response);
55 }
56
parse_read_local_version_info_response(BT_HDR * response,bt_version_t * bt_version)57 static void parse_read_local_version_info_response(
58 BT_HDR *response,
59 bt_version_t *bt_version)
60 {
61
62 uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_VERSION_INFO, 8 /* bytes after */);
63 assert(stream != NULL);
64 STREAM_TO_UINT8(bt_version->hci_version, stream);
65 STREAM_TO_UINT16(bt_version->hci_revision, stream);
66 STREAM_TO_UINT8(bt_version->lmp_version, stream);
67 STREAM_TO_UINT16(bt_version->manufacturer, stream);
68 STREAM_TO_UINT16(bt_version->lmp_subversion, stream);
69
70 osi_free(response);
71 }
72
parse_read_bd_addr_response(BT_HDR * response,bt_bdaddr_t * address_ptr)73 static void parse_read_bd_addr_response(
74 BT_HDR *response,
75 bt_bdaddr_t *address_ptr)
76 {
77
78 uint8_t *stream = read_command_complete_header(response, HCI_READ_BD_ADDR, sizeof(bt_bdaddr_t) /* bytes after */);
79 assert(stream != NULL);
80 STREAM_TO_BDADDR(address_ptr->address, stream);
81
82 osi_free(response);
83 }
84
parse_read_local_supported_commands_response(BT_HDR * response,uint8_t * supported_commands_ptr,size_t supported_commands_length)85 static void parse_read_local_supported_commands_response(
86 BT_HDR *response,
87 uint8_t *supported_commands_ptr,
88 size_t supported_commands_length)
89 {
90
91 uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_SUPPORTED_CMDS, supported_commands_length /* bytes after */);
92 assert(stream != NULL);
93 STREAM_TO_ARRAY(supported_commands_ptr, stream, (int)supported_commands_length);
94
95 osi_free(response);
96 }
97
parse_read_local_supported_features_response(BT_HDR * response,bt_device_features_t * feature_pages)98 static void parse_read_local_supported_features_response(
99 BT_HDR *response,
100 bt_device_features_t *feature_pages)
101 {
102 uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_FEATURES, sizeof(bt_device_features_t) /* bytes after */);
103 if (stream != NULL) {
104 STREAM_TO_ARRAY(feature_pages->as_array, stream, (int)sizeof(bt_device_features_t));
105 }
106 osi_free(response);
107 }
108
parse_read_local_extended_features_response(BT_HDR * response,uint8_t * page_number_ptr,uint8_t * max_page_number_ptr,bt_device_features_t * feature_pages,size_t feature_pages_count)109 static void parse_read_local_extended_features_response(
110 BT_HDR *response,
111 uint8_t *page_number_ptr,
112 uint8_t *max_page_number_ptr,
113 bt_device_features_t *feature_pages,
114 size_t feature_pages_count)
115 {
116
117 uint8_t *stream = read_command_complete_header(response, HCI_READ_LOCAL_EXT_FEATURES, 2 + sizeof(bt_device_features_t) /* bytes after */);
118 if (stream != NULL) {
119 STREAM_TO_UINT8(*page_number_ptr, stream);
120 STREAM_TO_UINT8(*max_page_number_ptr, stream);
121
122 assert(*page_number_ptr < feature_pages_count);
123 STREAM_TO_ARRAY(feature_pages[*page_number_ptr].as_array, stream, (int)sizeof(bt_device_features_t));
124 } else {
125 HCI_TRACE_ERROR("%s() - WARNING: READING EXTENDED FEATURES FAILED. "
126 "THIS MAY INDICATE A FIRMWARE/CONTROLLER ISSUE.", __func__);
127 }
128
129 osi_free(response);
130 }
131
parse_ble_read_white_list_size_response(BT_HDR * response,uint8_t * white_list_size_ptr)132 static void parse_ble_read_white_list_size_response(
133 BT_HDR *response,
134 uint8_t *white_list_size_ptr)
135 {
136
137 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_WHITE_LIST_SIZE, 1 /* byte after */);
138 assert(stream != NULL);
139 STREAM_TO_UINT8(*white_list_size_ptr, stream);
140
141 osi_free(response);
142 }
143
parse_ble_read_buffer_size_response(BT_HDR * response,uint16_t * data_size_ptr,uint8_t * acl_buffer_count_ptr)144 static void parse_ble_read_buffer_size_response(
145 BT_HDR *response,
146 uint16_t *data_size_ptr,
147 uint8_t *acl_buffer_count_ptr)
148 {
149
150 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SIZE, 3 /* bytes after */);
151 assert(stream != NULL);
152 STREAM_TO_UINT16(*data_size_ptr, stream);
153 STREAM_TO_UINT8(*acl_buffer_count_ptr, stream);
154
155 osi_free(response);
156 }
157
parse_ble_read_supported_states_response(BT_HDR * response,uint8_t * supported_states,size_t supported_states_size)158 static void parse_ble_read_supported_states_response(
159 BT_HDR *response,
160 uint8_t *supported_states,
161 size_t supported_states_size)
162 {
163
164 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_SUPPORTED_STATES, supported_states_size /* bytes after */);
165 assert(stream != NULL);
166 STREAM_TO_ARRAY(supported_states, stream, (int)supported_states_size);
167
168 osi_free(response);
169 }
170
parse_ble_read_local_supported_features_response(BT_HDR * response,bt_device_features_t * supported_features)171 static void parse_ble_read_local_supported_features_response(
172 BT_HDR *response,
173 bt_device_features_t *supported_features)
174 {
175
176 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_LOCAL_SPT_FEAT, sizeof(bt_device_features_t) /* bytes after */);
177 assert(stream != NULL);
178 STREAM_TO_ARRAY(supported_features->as_array, stream, (int)sizeof(bt_device_features_t));
179
180 osi_free(response);
181 }
182
parse_ble_read_resolving_list_size_response(BT_HDR * response,uint8_t * resolving_list_size_ptr)183 static void parse_ble_read_resolving_list_size_response(
184 BT_HDR *response,
185 uint8_t *resolving_list_size_ptr)
186 {
187
188 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_RESOLVING_LIST_SIZE, 1 /* bytes after */);
189 if (stream) {
190 STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
191 }
192
193 osi_free(response);
194 }
195
parse_ble_read_suggested_default_data_length_response(BT_HDR * response,uint16_t * ble_default_packet_length_ptr,uint16_t * ble_default_packet_txtime_ptr)196 static void parse_ble_read_suggested_default_data_length_response(
197 BT_HDR *response,
198 uint16_t *ble_default_packet_length_ptr,
199 uint16_t *ble_default_packet_txtime_ptr)
200 {
201
202 uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
203 if (stream) {
204 STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
205 STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
206 }
207
208 osi_free(response);
209 }
210
211 #if (BLE_50_FEATURE_SUPPORT == TRUE)
parse_ble_read_adv_max_len_response(BT_HDR * response,uint16_t * adv_max_len_ptr)212 static void parse_ble_read_adv_max_len_response(
213 BT_HDR *response,
214 uint16_t *adv_max_len_ptr)
215 {
216
217 uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */);
218 if (stream) {
219 // Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length
220 STREAM_TO_UINT16(*adv_max_len_ptr, stream);
221 }
222 osi_free(response);
223 }
224 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
225
226
227 // Internal functions
228
read_command_complete_header(BT_HDR * response,command_opcode_t expected_opcode,size_t minimum_bytes_after)229 static uint8_t *read_command_complete_header(
230 BT_HDR *response,
231 command_opcode_t expected_opcode,
232 size_t minimum_bytes_after)
233 {
234
235 uint8_t *stream = response->data + response->offset;
236
237 // Read the event header
238 uint8_t event_code __attribute__((unused));
239 uint8_t parameter_length __attribute__((unused));
240 STREAM_TO_UINT8(event_code, stream);
241 STREAM_TO_UINT8(parameter_length, stream);
242
243 const size_t parameter_bytes_we_read_here __attribute__((unused)) = 4;
244
245 // Check the event header values against what we expect
246 assert(event_code == HCI_COMMAND_COMPLETE_EVT);
247 assert(parameter_length >= (parameter_bytes_we_read_here + minimum_bytes_after));
248
249 // Read the command complete header
250 command_opcode_t opcode __attribute__((unused));
251 uint8_t status;
252 STREAM_SKIP_UINT8(stream); // skip the number of hci command packets field
253 STREAM_TO_UINT16(opcode, stream);
254
255 // Check the command complete header values against what we expect
256 if (expected_opcode != NO_OPCODE_CHECKING) {
257 assert(opcode == expected_opcode);
258 }
259
260 // Assume the next field is the status field
261 STREAM_TO_UINT8(status, stream);
262
263 if (status != HCI_SUCCESS) {
264 HCI_TRACE_ERROR("%s failed: opcode 0x%04x, status 0x%02x", __func__, opcode, status);
265 return NULL;
266 }
267
268 return stream;
269 }
270
271 static const hci_packet_parser_t interface = {
272 parse_generic_command_complete,
273 parse_read_buffer_size_response,
274 parse_read_local_version_info_response,
275 parse_read_bd_addr_response,
276 parse_read_local_supported_commands_response,
277 parse_read_local_supported_features_response,
278 parse_read_local_extended_features_response,
279 parse_ble_read_white_list_size_response,
280 parse_ble_read_buffer_size_response,
281 parse_ble_read_supported_states_response,
282 parse_ble_read_local_supported_features_response,
283 parse_ble_read_resolving_list_size_response,
284 #if (BLE_50_FEATURE_SUPPORT == TRUE)
285 parse_ble_read_adv_max_len_response,
286 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
287 parse_ble_read_suggested_default_data_length_response
288 };
289
hci_packet_parser_get_interface(void)290 const hci_packet_parser_t *hci_packet_parser_get_interface(void)
291 {
292 return &interface;
293 }
294