hci_packet_factory.cc revision f2af1c42ccb2f642b241c2261b42d0be61d45438
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 <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
30static const allocator_t* buffer_allocator;
31
32static BT_HDR* make_packet(size_t data_size);
33static BT_HDR* make_command_no_params(uint16_t opcode);
34static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
35                            uint8_t** stream_out);
36
37// Interface functions
38
39static BT_HDR* make_reset(void) { return make_command_no_params(HCI_RESET); }
40
41static BT_HDR* make_read_buffer_size(void) {
42  return make_command_no_params(HCI_READ_BUFFER_SIZE);
43}
44
45static 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
58static BT_HDR* make_read_local_version_info(void) {
59  return make_command_no_params(HCI_READ_LOCAL_VERSION_INFO);
60}
61
62static BT_HDR* make_read_bd_addr(void) {
63  return make_command_no_params(HCI_READ_BD_ADDR);
64}
65
66static BT_HDR* make_read_local_supported_commands(void) {
67  return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CMDS);
68}
69
70static 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
80static 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
90static 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
100static 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
109static 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
121static BT_HDR* make_ble_read_white_list_size(void) {
122  return make_command_no_params(HCI_BLE_READ_WHITE_LIST_SIZE);
123}
124
125static BT_HDR* make_ble_read_buffer_size(void) {
126  return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
127}
128
129static BT_HDR* make_ble_read_supported_states(void) {
130  return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
131}
132
133static BT_HDR* make_ble_read_local_supported_features(void) {
134  return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
135}
136
137static BT_HDR* make_ble_read_resolving_list_size(void) {
138  return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
139}
140
141static BT_HDR* make_ble_read_suggested_default_data_length(void) {
142  return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
143}
144
145static BT_HDR* make_ble_read_maximum_advertising_data_length(void) {
146  return make_command_no_params(HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH);
147}
148
149static BT_HDR* make_ble_read_number_of_supported_advertising_sets(void) {
150  return make_command_no_params(
151      HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS);
152}
153
154static BT_HDR* make_read_local_supported_codecs(void) {
155  return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
156}
157
158static BT_HDR* make_ble_set_event_mask(const bt_event_mask_t* event_mask) {
159  uint8_t* stream;
160  uint8_t parameter_size = sizeof(bt_event_mask_t);
161  BT_HDR* packet =
162      make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
163
164  ARRAY8_TO_STREAM(stream, event_mask->as_array);
165  return packet;
166}
167
168// Internal functions
169
170static BT_HDR* make_command_no_params(uint16_t opcode) {
171  return make_command(opcode, 0, NULL);
172}
173
174static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
175                            uint8_t** stream_out) {
176  BT_HDR* packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
177
178  uint8_t* stream = packet->data;
179  UINT16_TO_STREAM(stream, opcode);
180  UINT8_TO_STREAM(stream, parameter_size);
181
182  if (stream_out != NULL) *stream_out = stream;
183
184  return packet;
185}
186
187static BT_HDR* make_packet(size_t data_size) {
188  BT_HDR* ret = (BT_HDR*)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
189  CHECK(ret);
190  ret->event = 0;
191  ret->offset = 0;
192  ret->layer_specific = 0;
193  ret->len = data_size;
194  return ret;
195}
196
197static const hci_packet_factory_t interface = {
198    make_reset,
199    make_read_buffer_size,
200    make_host_buffer_size,
201    make_read_local_version_info,
202    make_read_bd_addr,
203    make_read_local_supported_commands,
204    make_read_local_extended_features,
205    make_write_simple_pairing_mode,
206    make_write_secure_connections_host_support,
207    make_set_event_mask,
208    make_ble_write_host_support,
209    make_ble_read_white_list_size,
210    make_ble_read_buffer_size,
211    make_ble_read_supported_states,
212    make_ble_read_local_supported_features,
213    make_ble_read_resolving_list_size,
214    make_ble_read_suggested_default_data_length,
215    make_ble_read_maximum_advertising_data_length,
216    make_ble_read_number_of_supported_advertising_sets,
217    make_ble_set_event_mask,
218    make_read_local_supported_codecs};
219
220const hci_packet_factory_t* hci_packet_factory_get_interface() {
221  buffer_allocator = buffer_allocator_get_interface();
222  return &interface;
223}
224