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