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 <assert.h>
20 
21 #include "osi/include/allocator.h"
22 #include "bt_types.h"
23 #include "buffer_allocator.h"
24 #include "hcidefs.h"
25 #include "hcimsgs.h"
26 #include "hci_internals.h"
27 #include "hci_layer.h"
28 #include "hci_packet_factory.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, uint8_t **stream_out);
35 
36 // Interface functions
37 
make_reset(void)38 static BT_HDR *make_reset(void) {
39   return make_command_no_params(HCI_RESET);
40 }
41 
make_read_buffer_size(void)42 static BT_HDR *make_read_buffer_size(void) {
43   return make_command_no_params(HCI_READ_BUFFER_SIZE);
44 }
45 
make_host_buffer_size(uint16_t acl_size,uint8_t sco_size,uint16_t acl_count,uint16_t sco_count)46 static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, 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 = make_command(HCI_READ_LOCAL_EXT_FEATURES, parameter_size, &stream);
74 
75   UINT8_TO_STREAM(stream, page_number);
76   return packet;
77 }
78 
make_write_simple_pairing_mode(uint8_t mode)79 static BT_HDR *make_write_simple_pairing_mode(uint8_t mode) {
80   uint8_t *stream;
81   const uint8_t parameter_size = 1;
82   BT_HDR *packet = make_command(HCI_WRITE_SIMPLE_PAIRING_MODE, parameter_size, &stream);
83 
84   UINT8_TO_STREAM(stream, mode);
85   return packet;
86 }
87 
make_write_secure_connections_host_support(uint8_t mode)88 static BT_HDR *make_write_secure_connections_host_support(uint8_t mode) {
89   uint8_t *stream;
90   const uint8_t parameter_size = 1;
91   BT_HDR *packet = make_command(HCI_WRITE_SECURE_CONNS_SUPPORT, parameter_size, &stream);
92 
93   UINT8_TO_STREAM(stream, mode);
94   return packet;
95 }
96 
make_set_event_mask(const bt_event_mask_t * event_mask)97 static BT_HDR *make_set_event_mask(const bt_event_mask_t *event_mask) {
98   uint8_t *stream;
99   uint8_t parameter_size = sizeof(bt_event_mask_t);
100   BT_HDR *packet = make_command(HCI_SET_EVENT_MASK, parameter_size, &stream);
101 
102   ARRAY8_TO_STREAM(stream, event_mask->as_array);
103   return packet;
104 }
105 
make_ble_write_host_support(uint8_t supported_host,uint8_t simultaneous_host)106 static BT_HDR *make_ble_write_host_support(uint8_t supported_host, uint8_t simultaneous_host) {
107   uint8_t *stream;
108   const uint8_t parameter_size = 1 + 1;
109   BT_HDR *packet = make_command(HCI_WRITE_LE_HOST_SUPPORT, parameter_size, &stream);
110 
111   UINT8_TO_STREAM(stream, supported_host);
112   UINT8_TO_STREAM(stream, simultaneous_host);
113   return packet;
114 }
115 
make_ble_read_white_list_size(void)116 static BT_HDR *make_ble_read_white_list_size(void) {
117   return make_command_no_params(HCI_BLE_READ_WHITE_LIST_SIZE);
118 }
119 
make_ble_read_buffer_size(void)120 static BT_HDR *make_ble_read_buffer_size(void) {
121   return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
122 }
123 
make_ble_read_supported_states(void)124 static BT_HDR *make_ble_read_supported_states(void) {
125   return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
126 }
127 
make_ble_read_local_supported_features(void)128 static BT_HDR *make_ble_read_local_supported_features(void) {
129   return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
130 }
131 
make_ble_read_resolving_list_size(void)132 static BT_HDR *make_ble_read_resolving_list_size(void) {
133   return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
134 }
135 
make_ble_read_suggested_default_data_length(void)136 static BT_HDR *make_ble_read_suggested_default_data_length(void) {
137     return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
138 }
139 
make_read_local_supported_codecs(void)140 static BT_HDR *make_read_local_supported_codecs(void) {
141     return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
142 }
143 
make_ble_set_event_mask(const bt_event_mask_t * event_mask)144 static BT_HDR *make_ble_set_event_mask(const bt_event_mask_t *event_mask) {
145   uint8_t *stream;
146   uint8_t parameter_size = sizeof(bt_event_mask_t);
147   BT_HDR *packet = make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
148 
149   ARRAY8_TO_STREAM(stream, event_mask->as_array);
150   return packet;
151 }
152 
153 // Internal functions
154 
make_command_no_params(uint16_t opcode)155 static BT_HDR *make_command_no_params(uint16_t opcode) {
156   return make_command(opcode, 0, NULL);
157 }
158 
make_command(uint16_t opcode,size_t parameter_size,uint8_t ** stream_out)159 static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out) {
160   BT_HDR *packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
161 
162   uint8_t *stream = packet->data;
163   UINT16_TO_STREAM(stream, opcode);
164   UINT8_TO_STREAM(stream, parameter_size);
165 
166   if (stream_out != NULL)
167     *stream_out = stream;
168 
169   return packet;
170 }
171 
make_packet(size_t data_size)172 static BT_HDR *make_packet(size_t data_size) {
173   BT_HDR *ret = (BT_HDR *)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
174   assert(ret);
175   ret->event = 0;
176   ret->offset = 0;
177   ret->layer_specific = 0;
178   ret->len = data_size;
179   return ret;
180 }
181 
182 static const hci_packet_factory_t interface = {
183   make_reset,
184   make_read_buffer_size,
185   make_host_buffer_size,
186   make_read_local_version_info,
187   make_read_bd_addr,
188   make_read_local_supported_commands,
189   make_read_local_extended_features,
190   make_write_simple_pairing_mode,
191   make_write_secure_connections_host_support,
192   make_set_event_mask,
193   make_ble_write_host_support,
194   make_ble_read_white_list_size,
195   make_ble_read_buffer_size,
196   make_ble_read_supported_states,
197   make_ble_read_local_supported_features,
198   make_ble_read_resolving_list_size,
199   make_ble_read_suggested_default_data_length,
200   make_ble_set_event_mask,
201   make_read_local_supported_codecs
202 };
203 
hci_packet_factory_get_interface()204 const hci_packet_factory_t *hci_packet_factory_get_interface() {
205   buffer_allocator = buffer_allocator_get_interface();
206   return &interface;
207 }
208