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 "osi/allocator.h"
22 #include "stack/bt_types.h"
23 #include "stack/hcidefs.h"
24 #include "stack/hcimsgs.h"
25 #include "hci/hci_internals.h"
26 #include "hci/hci_layer.h"
27 #include "hci/hci_packet_factory.h"
28
29
30 static BT_HDR *make_command_no_params(uint16_t opcode);
31 static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out);
32
33 // Interface functions
34
make_reset(void)35 static BT_HDR *make_reset(void)
36 {
37 return make_command_no_params(HCI_RESET);
38 }
39
make_read_buffer_size(void)40 static BT_HDR *make_read_buffer_size(void)
41 {
42 return make_command_no_params(HCI_READ_BUFFER_SIZE);
43 }
44
make_set_c2h_flow_control(uint8_t enable)45 static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
46 {
47 uint8_t *stream;
48 const uint8_t parameter_size = 1;
49 BT_HDR *packet = make_command(HCI_SET_HC_TO_HOST_FLOW_CTRL, parameter_size, &stream);
50
51 UINT8_TO_STREAM(stream, enable);
52 return packet;
53 }
54
make_set_adv_report_flow_control(uint8_t enable,uint16_t num,uint16_t lost_threshold)55 static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, uint16_t lost_threshold)
56 {
57 uint8_t *stream;
58 const uint8_t parameter_size = 1 + 2 + 2;
59 BT_HDR *packet = make_command(HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL, parameter_size, &stream);
60
61 UINT8_TO_STREAM(stream, enable);
62 UINT16_TO_STREAM(stream, num);
63 UINT16_TO_STREAM(stream, lost_threshold);
64 return packet;
65 }
66
make_host_buffer_size(uint16_t acl_size,uint8_t sco_size,uint16_t acl_count,uint16_t sco_count)67 static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
68 {
69 uint8_t *stream;
70 const uint8_t parameter_size = 2 + 1 + 2 + 2; // from each of the parameters
71 BT_HDR *packet = make_command(HCI_HOST_BUFFER_SIZE, parameter_size, &stream);
72
73 UINT16_TO_STREAM(stream, acl_size);
74 UINT8_TO_STREAM(stream, sco_size);
75 UINT16_TO_STREAM(stream, acl_count);
76 UINT16_TO_STREAM(stream, sco_count);
77 return packet;
78 }
79
make_read_local_version_info(void)80 static BT_HDR *make_read_local_version_info(void)
81 {
82 return make_command_no_params(HCI_READ_LOCAL_VERSION_INFO);
83 }
84
make_read_bd_addr(void)85 static BT_HDR *make_read_bd_addr(void)
86 {
87 return make_command_no_params(HCI_READ_BD_ADDR);
88 }
89
make_read_local_supported_commands(void)90 static BT_HDR *make_read_local_supported_commands(void)
91 {
92 return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CMDS);
93 }
94
make_read_local_supported_features(void)95 static BT_HDR *make_read_local_supported_features(void)
96 {
97 return make_command_no_params(HCI_READ_LOCAL_FEATURES);
98 }
99
make_read_local_extended_features(uint8_t page_number)100 static BT_HDR *make_read_local_extended_features(uint8_t page_number)
101 {
102 uint8_t *stream;
103 const uint8_t parameter_size = 1;
104 BT_HDR *packet = make_command(HCI_READ_LOCAL_EXT_FEATURES, parameter_size, &stream);
105
106 UINT8_TO_STREAM(stream, page_number);
107 return packet;
108 }
109
make_write_simple_pairing_mode(uint8_t mode)110 static BT_HDR *make_write_simple_pairing_mode(uint8_t mode)
111 {
112 uint8_t *stream;
113 const uint8_t parameter_size = 1;
114 BT_HDR *packet = make_command(HCI_WRITE_SIMPLE_PAIRING_MODE, parameter_size, &stream);
115
116 UINT8_TO_STREAM(stream, mode);
117 return packet;
118 }
119
make_write_secure_connections_host_support(uint8_t mode)120 static BT_HDR *make_write_secure_connections_host_support(uint8_t mode)
121 {
122 uint8_t *stream;
123 const uint8_t parameter_size = 1;
124 BT_HDR *packet = make_command(HCI_WRITE_SECURE_CONNS_SUPPORT, parameter_size, &stream);
125
126 UINT8_TO_STREAM(stream, mode);
127 return packet;
128 }
129
make_set_event_mask(const bt_event_mask_t * event_mask)130 static BT_HDR *make_set_event_mask(const bt_event_mask_t *event_mask)
131 {
132 uint8_t *stream;
133 uint8_t parameter_size = sizeof(bt_event_mask_t);
134 BT_HDR *packet = make_command(HCI_SET_EVENT_MASK, parameter_size, &stream);
135
136 ARRAY8_TO_STREAM(stream, event_mask->as_array);
137 return packet;
138 }
139
make_ble_write_host_support(uint8_t supported_host,uint8_t simultaneous_host)140 static BT_HDR *make_ble_write_host_support(uint8_t supported_host, uint8_t simultaneous_host)
141 {
142 uint8_t *stream;
143 const uint8_t parameter_size = 1 + 1;
144 BT_HDR *packet = make_command(HCI_WRITE_LE_HOST_SUPPORT, parameter_size, &stream);
145
146 UINT8_TO_STREAM(stream, supported_host);
147 UINT8_TO_STREAM(stream, simultaneous_host);
148 return packet;
149 }
150
make_ble_read_white_list_size(void)151 static BT_HDR *make_ble_read_white_list_size(void)
152 {
153 return make_command_no_params(HCI_BLE_READ_WHITE_LIST_SIZE);
154 }
155
make_ble_read_buffer_size(void)156 static BT_HDR *make_ble_read_buffer_size(void)
157 {
158 return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
159 }
160
make_ble_read_supported_states(void)161 static BT_HDR *make_ble_read_supported_states(void)
162 {
163 return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
164 }
165
make_ble_read_local_supported_features(void)166 static BT_HDR *make_ble_read_local_supported_features(void)
167 {
168 return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
169 }
170
make_ble_read_resolving_list_size(void)171 static BT_HDR *make_ble_read_resolving_list_size(void)
172 {
173 return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
174 }
175
make_ble_read_suggested_default_data_length(void)176 static BT_HDR *make_ble_read_suggested_default_data_length(void)
177 {
178 return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
179 }
180
make_ble_write_suggested_default_data_length(uint16_t SuggestedMaxTxOctets,uint16_t SuggestedMaxTxTime)181 static BT_HDR *make_ble_write_suggested_default_data_length(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime)
182 {
183 uint8_t *stream;
184 uint8_t parameter_size = sizeof(uint16_t) + sizeof(uint16_t);
185 BT_HDR *packet = make_command(HCI_BLE_WRITE_DEFAULT_DATA_LENGTH, parameter_size, &stream);
186
187 UINT16_TO_STREAM(stream, SuggestedMaxTxOctets);
188 UINT16_TO_STREAM(stream, SuggestedMaxTxTime);
189 return packet;
190 }
191
make_ble_set_event_mask(const bt_event_mask_t * event_mask)192 static BT_HDR *make_ble_set_event_mask(const bt_event_mask_t *event_mask)
193 {
194 uint8_t *stream;
195 uint8_t parameter_size = sizeof(bt_event_mask_t);
196 BT_HDR *packet = make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
197
198 ARRAY8_TO_STREAM(stream, event_mask->as_array);
199 return packet;
200 }
201
make_write_sync_flow_control_enable(uint8_t enable)202 static BT_HDR *make_write_sync_flow_control_enable(uint8_t enable)
203 {
204 uint8_t *stream;
205 const uint8_t parameter_size = 1;
206 BT_HDR *packet = make_command(HCI_WRITE_SCO_FLOW_CTRL_ENABLE, parameter_size, &stream);
207
208 UINT8_TO_STREAM(stream, enable);
209 return packet;
210 }
211
make_write_default_erroneous_data_report(uint8_t enable)212 static BT_HDR *make_write_default_erroneous_data_report(uint8_t enable)
213 {
214 uint8_t *stream;
215 const uint8_t parameter_size = 1;
216 BT_HDR *packet = make_command(HCI_WRITE_ERRONEOUS_DATA_RPT, parameter_size, &stream);
217
218 UINT8_TO_STREAM(stream, enable);
219 return packet;
220 }
221 #if (BLE_50_FEATURE_SUPPORT == TRUE)
make_read_max_adv_data_len(void)222 static BT_HDR *make_read_max_adv_data_len(void)
223 {
224 return make_command_no_params(HCI_BLE_RD_MAX_ADV_DATA_LEN);
225 }
226 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
227 // Internal functions
228
make_command_no_params(uint16_t opcode)229 static BT_HDR *make_command_no_params(uint16_t opcode)
230 {
231 return make_command(opcode, 0, NULL);
232 }
233
make_command(uint16_t opcode,size_t parameter_size,uint8_t ** stream_out)234 static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out)
235 {
236 BT_HDR *packet = HCI_GET_CMD_BUF(parameter_size);
237 hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(packet);
238 metadata->opcode = opcode;
239
240 uint8_t *stream = packet->data;
241 UINT16_TO_STREAM(stream, opcode);
242 UINT8_TO_STREAM(stream, parameter_size);
243
244 if (stream_out != NULL) {
245 *stream_out = stream;
246 }
247
248 return packet;
249 }
250
251 static const hci_packet_factory_t interface = {
252 make_reset,
253 make_read_buffer_size,
254 make_set_c2h_flow_control,
255 make_set_adv_report_flow_control,
256 make_host_buffer_size,
257 make_read_local_version_info,
258 make_read_bd_addr,
259 make_read_local_supported_commands,
260 make_read_local_supported_features,
261 make_read_local_extended_features,
262 make_write_simple_pairing_mode,
263 make_write_secure_connections_host_support,
264 make_set_event_mask,
265 make_ble_write_host_support,
266 make_ble_read_white_list_size,
267 make_ble_read_buffer_size,
268 make_ble_read_supported_states,
269 make_ble_read_local_supported_features,
270 make_ble_read_resolving_list_size,
271 #if (BLE_50_FEATURE_SUPPORT == TRUE)
272 make_read_max_adv_data_len,
273 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
274 make_ble_read_suggested_default_data_length,
275 make_ble_write_suggested_default_data_length,
276 make_ble_set_event_mask,
277 make_write_sync_flow_control_enable,
278 make_write_default_erroneous_data_report,
279 };
280
hci_packet_factory_get_interface(void)281 const hci_packet_factory_t *hci_packet_factory_get_interface(void)
282 {
283 return &interface;
284 }
285