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_white_list_size(void)121 static BT_HDR* make_ble_read_white_list_size(void) {
122   return make_command_no_params(HCI_BLE_READ_WHITE_LIST_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_supported_states(void)129 static BT_HDR* make_ble_read_supported_states(void) {
130   return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
131 }
132 
make_ble_read_local_supported_features(void)133 static BT_HDR* make_ble_read_local_supported_features(void) {
134   return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
135 }
136 
make_ble_read_resolving_list_size(void)137 static BT_HDR* make_ble_read_resolving_list_size(void) {
138   return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
139 }
140 
make_ble_read_suggested_default_data_length(void)141 static BT_HDR* make_ble_read_suggested_default_data_length(void) {
142   return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
143 }
144 
make_ble_read_maximum_data_length(void)145 static BT_HDR* make_ble_read_maximum_data_length(void) {
146   return make_command_no_params(HCI_BLE_READ_MAXIMUM_DATA_LENGTH);
147 }
148 
make_ble_read_maximum_advertising_data_length(void)149 static BT_HDR* make_ble_read_maximum_advertising_data_length(void) {
150   return make_command_no_params(HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH);
151 }
152 
make_ble_read_number_of_supported_advertising_sets(void)153 static BT_HDR* make_ble_read_number_of_supported_advertising_sets(void) {
154   return make_command_no_params(
155       HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS);
156 }
157 
make_read_local_supported_codecs(void)158 static BT_HDR* make_read_local_supported_codecs(void) {
159   return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
160 }
161 
make_ble_set_event_mask(const bt_event_mask_t * event_mask)162 static BT_HDR* make_ble_set_event_mask(const bt_event_mask_t* event_mask) {
163   uint8_t* stream;
164   uint8_t parameter_size = sizeof(bt_event_mask_t);
165   BT_HDR* packet =
166       make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
167 
168   ARRAY8_TO_STREAM(stream, event_mask->as_array);
169   return packet;
170 }
171 
172 // Internal functions
173 
make_command_no_params(uint16_t opcode)174 static BT_HDR* make_command_no_params(uint16_t opcode) {
175   return make_command(opcode, 0, NULL);
176 }
177 
make_command(uint16_t opcode,size_t parameter_size,uint8_t ** stream_out)178 static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
179                             uint8_t** stream_out) {
180   BT_HDR* packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
181 
182   uint8_t* stream = packet->data;
183   UINT16_TO_STREAM(stream, opcode);
184   UINT8_TO_STREAM(stream, parameter_size);
185 
186   if (stream_out != NULL) *stream_out = stream;
187 
188   return packet;
189 }
190 
make_packet(size_t data_size)191 static BT_HDR* make_packet(size_t data_size) {
192   BT_HDR* ret = (BT_HDR*)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
193   CHECK(ret);
194   ret->event = 0;
195   ret->offset = 0;
196   ret->layer_specific = 0;
197   ret->len = data_size;
198   return ret;
199 }
200 
201 static const hci_packet_factory_t interface = {
202     make_reset,
203     make_read_buffer_size,
204     make_host_buffer_size,
205     make_read_local_version_info,
206     make_read_bd_addr,
207     make_read_local_supported_commands,
208     make_read_local_extended_features,
209     make_write_simple_pairing_mode,
210     make_write_secure_connections_host_support,
211     make_set_event_mask,
212     make_ble_write_host_support,
213     make_ble_read_white_list_size,
214     make_ble_read_buffer_size,
215     make_ble_read_supported_states,
216     make_ble_read_local_supported_features,
217     make_ble_read_resolving_list_size,
218     make_ble_read_suggested_default_data_length,
219     make_ble_read_maximum_data_length,
220     make_ble_read_maximum_advertising_data_length,
221     make_ble_read_number_of_supported_advertising_sets,
222     make_ble_set_event_mask,
223     make_read_local_supported_codecs};
224 
hci_packet_factory_get_interface()225 const hci_packet_factory_t* hci_packet_factory_get_interface() {
226   buffer_allocator = buffer_allocator_get_interface();
227   return &interface;
228 }
229