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 #include <base/logging.h>
20
21 #include "bt_types.h"
22 #include "buffer_allocator.h"
23 #include "hci_internals.h"
24 #include "hci_layer.h"
25 #include "hci_packet_factory.h"
26 #include "hcidefs.h"
27 #include "hcimsgs.h"
28 #include "osi/include/allocator.h"
29
30 static const allocator_t* buffer_allocator;
31
32 static BT_HDR* make_packet(size_t data_size);
33 static BT_HDR* make_command_no_params(uint16_t opcode);
34 static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
35 uint8_t** stream_out);
36
37 // Interface functions
38
make_reset(void)39 static BT_HDR* make_reset(void) { return make_command_no_params(HCI_RESET); }
40
make_read_buffer_size(void)41 static BT_HDR* make_read_buffer_size(void) {
42 return make_command_no_params(HCI_READ_BUFFER_SIZE);
43 }
44
make_host_buffer_size(uint16_t acl_size,uint8_t sco_size,uint16_t acl_count,uint16_t sco_count)45 static BT_HDR* make_host_buffer_size(uint16_t acl_size, uint8_t sco_size,
46 uint16_t acl_count, uint16_t sco_count) {
47 uint8_t* stream;
48 const uint8_t parameter_size = 2 + 1 + 2 + 2; // from each of the parameters
49 BT_HDR* packet = make_command(HCI_HOST_BUFFER_SIZE, parameter_size, &stream);
50
51 UINT16_TO_STREAM(stream, acl_size);
52 UINT8_TO_STREAM(stream, sco_size);
53 UINT16_TO_STREAM(stream, acl_count);
54 UINT16_TO_STREAM(stream, sco_count);
55 return packet;
56 }
57
make_read_local_version_info(void)58 static BT_HDR* make_read_local_version_info(void) {
59 return make_command_no_params(HCI_READ_LOCAL_VERSION_INFO);
60 }
61
make_read_bd_addr(void)62 static BT_HDR* make_read_bd_addr(void) {
63 return make_command_no_params(HCI_READ_BD_ADDR);
64 }
65
make_read_local_supported_commands(void)66 static BT_HDR* make_read_local_supported_commands(void) {
67 return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CMDS);
68 }
69
make_read_local_extended_features(uint8_t page_number)70 static BT_HDR* make_read_local_extended_features(uint8_t page_number) {
71 uint8_t* stream;
72 const uint8_t parameter_size = 1;
73 BT_HDR* packet =
74 make_command(HCI_READ_LOCAL_EXT_FEATURES, parameter_size, &stream);
75
76 UINT8_TO_STREAM(stream, page_number);
77 return packet;
78 }
79
make_write_simple_pairing_mode(uint8_t mode)80 static BT_HDR* make_write_simple_pairing_mode(uint8_t mode) {
81 uint8_t* stream;
82 const uint8_t parameter_size = 1;
83 BT_HDR* packet =
84 make_command(HCI_WRITE_SIMPLE_PAIRING_MODE, parameter_size, &stream);
85
86 UINT8_TO_STREAM(stream, mode);
87 return packet;
88 }
89
make_write_secure_connections_host_support(uint8_t mode)90 static BT_HDR* make_write_secure_connections_host_support(uint8_t mode) {
91 uint8_t* stream;
92 const uint8_t parameter_size = 1;
93 BT_HDR* packet =
94 make_command(HCI_WRITE_SECURE_CONNS_SUPPORT, parameter_size, &stream);
95
96 UINT8_TO_STREAM(stream, mode);
97 return packet;
98 }
99
make_set_event_mask(const bt_event_mask_t * event_mask)100 static BT_HDR* make_set_event_mask(const bt_event_mask_t* event_mask) {
101 uint8_t* stream;
102 uint8_t parameter_size = sizeof(bt_event_mask_t);
103 BT_HDR* packet = make_command(HCI_SET_EVENT_MASK, parameter_size, &stream);
104
105 ARRAY8_TO_STREAM(stream, event_mask->as_array);
106 return packet;
107 }
108
make_ble_write_host_support(uint8_t supported_host,uint8_t simultaneous_host)109 static BT_HDR* make_ble_write_host_support(uint8_t supported_host,
110 uint8_t simultaneous_host) {
111 uint8_t* stream;
112 const uint8_t parameter_size = 1 + 1;
113 BT_HDR* packet =
114 make_command(HCI_WRITE_LE_HOST_SUPPORT, parameter_size, &stream);
115
116 UINT8_TO_STREAM(stream, supported_host);
117 UINT8_TO_STREAM(stream, simultaneous_host);
118 return packet;
119 }
120
make_ble_read_acceptlist_size(void)121 static BT_HDR* make_ble_read_acceptlist_size(void) {
122 return make_command_no_params(HCI_BLE_READ_ACCEPTLIST_SIZE);
123 }
124
make_ble_read_buffer_size(void)125 static BT_HDR* make_ble_read_buffer_size(void) {
126 return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
127 }
128
make_ble_read_buffer_size_v2(void)129 static BT_HDR* make_ble_read_buffer_size_v2(void) {
130 return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE_V2);
131 }
132
make_ble_read_supported_states(void)133 static BT_HDR* make_ble_read_supported_states(void) {
134 return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
135 }
136
make_ble_read_local_supported_features(void)137 static BT_HDR* make_ble_read_local_supported_features(void) {
138 return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
139 }
140
make_ble_read_resolving_list_size(void)141 static BT_HDR* make_ble_read_resolving_list_size(void) {
142 return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
143 }
144
make_ble_read_suggested_default_data_length(void)145 static BT_HDR* make_ble_read_suggested_default_data_length(void) {
146 return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
147 }
148
make_ble_read_maximum_data_length(void)149 static BT_HDR* make_ble_read_maximum_data_length(void) {
150 return make_command_no_params(HCI_BLE_READ_MAXIMUM_DATA_LENGTH);
151 }
152
make_ble_read_maximum_advertising_data_length(void)153 static BT_HDR* make_ble_read_maximum_advertising_data_length(void) {
154 return make_command_no_params(HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH);
155 }
156
make_ble_read_number_of_supported_advertising_sets(void)157 static BT_HDR* make_ble_read_number_of_supported_advertising_sets(void) {
158 return make_command_no_params(
159 HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS);
160 }
161
make_ble_read_periodic_advertiser_list_size(void)162 static BT_HDR* make_ble_read_periodic_advertiser_list_size(void) {
163 return make_command_no_params(HCI_BLE_READ_PERIODIC_ADVERTISER_LIST_SIZE);
164 }
165
make_read_local_supported_codecs(void)166 static BT_HDR* make_read_local_supported_codecs(void) {
167 return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
168 }
169
make_ble_set_event_mask(const bt_event_mask_t * event_mask)170 static BT_HDR* make_ble_set_event_mask(const bt_event_mask_t* event_mask) {
171 uint8_t* stream;
172 uint8_t parameter_size = sizeof(bt_event_mask_t);
173 BT_HDR* packet =
174 make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
175
176 ARRAY8_TO_STREAM(stream, event_mask->as_array);
177 return packet;
178 }
179
make_ble_set_host_features(uint8_t bit_number,uint8_t bit_value)180 static BT_HDR* make_ble_set_host_features(uint8_t bit_number,
181 uint8_t bit_value) {
182 uint8_t* stream;
183 uint8_t parameter_size = sizeof(bit_number) + sizeof(bit_value);
184 BT_HDR* packet =
185 make_command(HCI_LE_SET_HOST_FEATURE, parameter_size, &stream);
186
187 UINT8_TO_STREAM(stream, bit_number);
188 UINT8_TO_STREAM(stream, bit_value);
189
190 return packet;
191 }
192
193 // Internal functions
194
make_command_no_params(uint16_t opcode)195 static BT_HDR* make_command_no_params(uint16_t opcode) {
196 return make_command(opcode, 0, NULL);
197 }
198
make_command(uint16_t opcode,size_t parameter_size,uint8_t ** stream_out)199 static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
200 uint8_t** stream_out) {
201 BT_HDR* packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
202
203 uint8_t* stream = packet->data;
204 UINT16_TO_STREAM(stream, opcode);
205 UINT8_TO_STREAM(stream, parameter_size);
206
207 if (stream_out != NULL) *stream_out = stream;
208
209 return packet;
210 }
211
make_packet(size_t data_size)212 static BT_HDR* make_packet(size_t data_size) {
213 BT_HDR* ret = (BT_HDR*)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
214 CHECK(ret);
215 ret->event = 0;
216 ret->offset = 0;
217 ret->layer_specific = 0;
218 ret->len = data_size;
219 return ret;
220 }
221
222 static const hci_packet_factory_t interface = {
223 make_reset,
224 make_read_buffer_size,
225 make_host_buffer_size,
226 make_read_local_version_info,
227 make_read_bd_addr,
228 make_read_local_supported_commands,
229 make_read_local_extended_features,
230 make_write_simple_pairing_mode,
231 make_write_secure_connections_host_support,
232 make_set_event_mask,
233 make_ble_write_host_support,
234 make_ble_read_acceptlist_size,
235 make_ble_read_buffer_size,
236 make_ble_read_buffer_size_v2,
237 make_ble_read_supported_states,
238 make_ble_read_local_supported_features,
239 make_ble_read_resolving_list_size,
240 make_ble_read_suggested_default_data_length,
241 make_ble_read_maximum_data_length,
242 make_ble_read_maximum_advertising_data_length,
243 make_ble_read_number_of_supported_advertising_sets,
244 make_ble_read_periodic_advertiser_list_size,
245 make_ble_set_event_mask,
246 make_ble_set_host_features,
247 make_read_local_supported_codecs};
248
hci_packet_factory_get_interface()249 const hci_packet_factory_t* hci_packet_factory_get_interface() {
250 buffer_allocator = buffer_allocator_get_interface();
251 return &interface;
252 }
253