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     STREAM_TO_UINT8(*resolving_list_size_ptr, stream);
190 
191     osi_free(response);
192 }
193 
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)194 static void parse_ble_read_suggested_default_data_length_response(
195     BT_HDR *response,
196     uint16_t *ble_default_packet_length_ptr,
197     uint16_t *ble_default_packet_txtime_ptr)
198 {
199 
200     uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_DEFAULT_DATA_LENGTH, 2 /* bytes after */);
201     STREAM_TO_UINT16(*ble_default_packet_length_ptr, stream);
202     STREAM_TO_UINT16(*ble_default_packet_txtime_ptr, stream);
203     osi_free(response);
204 }
205 #if (BLE_50_FEATURE_SUPPORT == TRUE)
parse_ble_read_adv_max_len_response(BT_HDR * response,uint16_t * adv_max_len_ptr)206 static void parse_ble_read_adv_max_len_response(
207     BT_HDR *response,
208     uint16_t *adv_max_len_ptr)
209 {
210 
211     uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */);
212     STREAM_TO_UINT8(*adv_max_len_ptr, stream);
213 
214     osi_free(response);
215 }
216 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
217 
218 
219 // Internal functions
220 
read_command_complete_header(BT_HDR * response,command_opcode_t expected_opcode,size_t minimum_bytes_after)221 static uint8_t *read_command_complete_header(
222     BT_HDR *response,
223     command_opcode_t expected_opcode,
224     size_t minimum_bytes_after)
225 {
226 
227     uint8_t *stream = response->data + response->offset;
228 
229     // Read the event header
230     uint8_t event_code;
231     uint8_t parameter_length;
232     STREAM_TO_UINT8(event_code, stream);
233     STREAM_TO_UINT8(parameter_length, stream);
234 
235     const size_t parameter_bytes_we_read_here = 4;
236 
237     // Check the event header values against what we expect
238     assert(event_code == HCI_COMMAND_COMPLETE_EVT);
239     assert(parameter_length >= (parameter_bytes_we_read_here + minimum_bytes_after));
240 
241     // Read the command complete header
242     command_opcode_t opcode;
243     uint8_t status;
244     STREAM_SKIP_UINT8(stream); // skip the number of hci command packets field
245     STREAM_TO_UINT16(opcode, stream);
246 
247     // Check the command complete header values against what we expect
248     if (expected_opcode != NO_OPCODE_CHECKING) {
249         assert(opcode == expected_opcode);
250     }
251 
252     // Assume the next field is the status field
253     STREAM_TO_UINT8(status, stream);
254 
255     if (status != HCI_SUCCESS) {
256         return NULL;
257     }
258 
259     return stream;
260 }
261 
262 static const hci_packet_parser_t interface = {
263     parse_generic_command_complete,
264     parse_read_buffer_size_response,
265     parse_read_local_version_info_response,
266     parse_read_bd_addr_response,
267     parse_read_local_supported_commands_response,
268     parse_read_local_supported_features_response,
269     parse_read_local_extended_features_response,
270     parse_ble_read_white_list_size_response,
271     parse_ble_read_buffer_size_response,
272     parse_ble_read_supported_states_response,
273     parse_ble_read_local_supported_features_response,
274     parse_ble_read_resolving_list_size_response,
275 #if (BLE_50_FEATURE_SUPPORT == TRUE)
276     parse_ble_read_adv_max_len_response,
277 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
278     parse_ble_read_suggested_default_data_length_response
279 };
280 
hci_packet_parser_get_interface(void)281 const hci_packet_parser_t *hci_packet_parser_get_interface(void)
282 {
283     return &interface;
284 }
285