1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "bt_shim_hci"
18
19 #include "main/shim/hci_layer.h"
20
21 #include <base/functional/bind.h>
22 #include <bluetooth/log.h>
23
24 #include <algorithm>
25 #include <cstdint>
26
27 #include "common/bidi_queue.h"
28 #include "hci/hci_interface.h"
29 #include "hci/hci_packets.h"
30 #include "hci/include/packet_fragmenter.h"
31 #include "main/shim/entry.h"
32 #include "osi/include/allocator.h"
33 #include "packet/raw_builder.h"
34 #include "stack/include/bt_hdr.h"
35 #include "stack/include/bt_types.h"
36 #include "stack/include/btm_iso_api.h"
37 #include "stack/include/hcimsgs.h"
38 #include "stack/include/main_thread.h"
39
40 // TODO(b/369381361) Enfore -Wmissing-prototypes
41 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
42
43 using namespace bluetooth;
44
45 /**
46 * Callback data wrapped as opaque token bundled with the command
47 * transmit request to the Gd layer.
48 *
49 * Upon completion a token for a corresponding command transmit.
50 * request is returned from the Gd layer.
51 */
52 using CommandCallbackData = struct {
53 void* context;
54 };
55
56 constexpr size_t kBtHdrSize = sizeof(BT_HDR);
57 constexpr size_t kCommandLengthSize = sizeof(uint8_t);
58 constexpr size_t kCommandOpcodeSize = sizeof(uint16_t);
59
60 static base::Callback<void(BT_HDR*)> send_data_upwards;
61 static const packet_fragmenter_t* packet_fragmenter;
62
63 namespace {
register_event_code(bluetooth::hci::EventCode event_code)64 bool register_event_code(bluetooth::hci::EventCode event_code) {
65 switch (event_code) {
66 // SCO
67 case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE:
68 case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED:
69
70 // SecurityEvents
71 case bluetooth::hci::EventCode::ENCRYPTION_CHANGE:
72 case bluetooth::hci::EventCode::PIN_CODE_REQUEST:
73 case bluetooth::hci::EventCode::LINK_KEY_REQUEST:
74 case bluetooth::hci::EventCode::LINK_KEY_NOTIFICATION:
75 case bluetooth::hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
76 case bluetooth::hci::EventCode::IO_CAPABILITY_REQUEST:
77 case bluetooth::hci::EventCode::IO_CAPABILITY_RESPONSE:
78 case bluetooth::hci::EventCode::REMOTE_OOB_DATA_REQUEST:
79 case bluetooth::hci::EventCode::SIMPLE_PAIRING_COMPLETE:
80 case bluetooth::hci::EventCode::USER_PASSKEY_NOTIFICATION:
81 case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST:
82 case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST:
83 case bluetooth::hci::EventCode::ENCRYPTION_CHANGE_V2:
84 return true;
85 default:
86 return false;
87 }
88 }
89
register_subevent_code(bluetooth::hci::SubeventCode subevent_code)90 static bool register_subevent_code(bluetooth::hci::SubeventCode subevent_code) {
91 switch (subevent_code) {
92 case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:
93 case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST:
94 case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
95 case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE:
96 case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:
97 case bluetooth::hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:
98 case bluetooth::hci::SubeventCode::CONNECTION_IQ_REPORT:
99 case bluetooth::hci::SubeventCode::CTE_REQUEST_FAILED:
100 case bluetooth::hci::SubeventCode::CIS_ESTABLISHED:
101 case bluetooth::hci::SubeventCode::CIS_REQUEST:
102 case bluetooth::hci::SubeventCode::CREATE_BIG_COMPLETE:
103 case bluetooth::hci::SubeventCode::TERMINATE_BIG_COMPLETE:
104 case bluetooth::hci::SubeventCode::BIG_SYNC_ESTABLISHED:
105 case bluetooth::hci::SubeventCode::BIG_SYNC_LOST:
106 case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:
107 case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD:
108 return true;
109 default:
110 return false;
111 }
112 }
113
114 } // namespace
115
116 namespace cpp {
117 bluetooth::common::BidiQueueEnd<bluetooth::hci::IsoBuilder, bluetooth::hci::IsoView>*
118 hci_iso_queue_end = nullptr;
119 static bluetooth::os::EnqueueBuffer<bluetooth::hci::IsoBuilder>* pending_iso_data = nullptr;
120
MakeUniquePacket(const uint8_t * data,size_t len)121 static std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(const uint8_t* data,
122 size_t len) {
123 bluetooth::packet::RawBuilder builder;
124 std::vector<uint8_t> bytes(data, data + len);
125
126 auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
127 payload->AddOctets(bytes);
128
129 return payload;
130 }
131
WrapPacketAndCopy(uint16_t event,bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> * data)132 static BT_HDR* WrapPacketAndCopy(uint16_t event,
133 bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>* data) {
134 size_t packet_size = data->size() + kBtHdrSize;
135 BT_HDR* packet = reinterpret_cast<BT_HDR*>(osi_malloc(packet_size));
136 packet->offset = 0;
137 packet->len = data->size();
138 packet->layer_specific = 0;
139 packet->event = event;
140 std::copy(data->begin(), data->end(), packet->data);
141 return packet;
142 }
143
event_callback(bluetooth::hci::EventView event_packet_view)144 static void event_callback(bluetooth::hci::EventView event_packet_view) {
145 if (!send_data_upwards) {
146 return;
147 }
148 send_data_upwards.Run(WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &event_packet_view));
149 }
150
subevent_callback(bluetooth::hci::LeMetaEventView le_meta_event_view)151 static void subevent_callback(bluetooth::hci::LeMetaEventView le_meta_event_view) {
152 if (!send_data_upwards) {
153 return;
154 }
155 send_data_upwards.Run(WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &le_meta_event_view));
156 }
157
OnTransmitPacketCommandComplete(command_complete_cb complete_callback,void * context,bluetooth::hci::CommandCompleteView view)158 void OnTransmitPacketCommandComplete(command_complete_cb complete_callback, void* context,
159 bluetooth::hci::CommandCompleteView view) {
160 log::debug("Received cmd complete for {}", bluetooth::hci::OpCodeText(view.GetCommandOpCode()));
161 BT_HDR* response = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &view);
162 complete_callback(response, context);
163 }
164
OnTransmitPacketStatus(command_status_cb status_callback,void * context,std::unique_ptr<OsiObject> command,bluetooth::hci::CommandStatusView view)165 void OnTransmitPacketStatus(command_status_cb status_callback, void* context,
166 std::unique_ptr<OsiObject> command,
167 bluetooth::hci::CommandStatusView view) {
168 log::debug("Received cmd status {} for {}", bluetooth::hci::ErrorCodeText(view.GetStatus()),
169 bluetooth::hci::OpCodeText(view.GetCommandOpCode()));
170 uint8_t status = static_cast<uint8_t>(view.GetStatus());
171 status_callback(status, static_cast<BT_HDR*>(command->Release()), context);
172 }
173
transmit_command(const BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)174 static void transmit_command(const BT_HDR* command, command_complete_cb complete_callback,
175 command_status_cb status_callback, void* context) {
176 log::assert_that(command != nullptr, "assert failed: command != nullptr");
177 const uint8_t* data = command->data + command->offset;
178 size_t len = command->len;
179 log::assert_that(len >= (kCommandOpcodeSize + kCommandLengthSize),
180 "assert failed: len >= (kCommandOpcodeSize + kCommandLengthSize)");
181
182 // little endian command opcode
183 uint16_t command_op_code = (data[1] << 8 | data[0]);
184 // Gd stack API requires opcode specification and calculates length, so
185 // no need to provide opcode or length here.
186 data += (kCommandOpcodeSize + kCommandLengthSize);
187 len -= (kCommandOpcodeSize + kCommandLengthSize);
188
189 auto op_code = static_cast<const bluetooth::hci::OpCode>(command_op_code);
190
191 auto payload = MakeUniquePacket(data, len);
192 auto packet = bluetooth::hci::CommandBuilder::Create(op_code, std::move(payload));
193
194 log::debug("Sending command {}", bluetooth::hci::OpCodeText(op_code));
195
196 if (bluetooth::hci::Checker::IsCommandStatusOpcode(op_code)) {
197 auto command_unique = std::make_unique<OsiObject>(command);
198 bluetooth::shim::GetHciLayer()->EnqueueCommand(
199 std::move(packet),
200 bluetooth::shim::GetGdShimHandler()->BindOnce(OnTransmitPacketStatus, status_callback,
201 context, std::move(command_unique)));
202 } else {
203 bluetooth::shim::GetHciLayer()->EnqueueCommand(
204 std::move(packet),
205 bluetooth::shim::GetGdShimHandler()->BindOnce(OnTransmitPacketCommandComplete,
206 complete_callback, context));
207 osi_free(const_cast<void*>(static_cast<const void*>(command)));
208 }
209 }
210
transmit_iso_fragment(const uint8_t * stream,size_t length)211 static void transmit_iso_fragment(const uint8_t* stream, size_t length) {
212 uint16_t handle_with_flags;
213 STREAM_TO_UINT16(handle_with_flags, stream);
214 auto pb_flag = static_cast<bluetooth::hci::IsoPacketBoundaryFlag>(handle_with_flags >> 12 & 0b11);
215 auto ts_flag = static_cast<bluetooth::hci::TimeStampFlag>(handle_with_flags >> 14);
216 uint16_t handle = HCID_GET_HANDLE(handle_with_flags);
217 log::assert_that(handle <= HCI_HANDLE_MAX, "Require handle <= 0x{:X}, but is 0x{:X}",
218 HCI_HANDLE_MAX, handle);
219 length -= 2;
220 // skip data total length
221 stream += 2;
222 length -= 2;
223 auto payload = MakeUniquePacket(stream, length);
224 auto iso_packet =
225 bluetooth::hci::IsoBuilder::Create(handle, pb_flag, ts_flag, std::move(payload));
226
227 pending_iso_data->Enqueue(std::move(iso_packet), bluetooth::shim::GetGdShimHandler());
228 }
229
register_event(bluetooth::hci::EventCode event_code)230 static void register_event(bluetooth::hci::EventCode event_code) {
231 auto handler = bluetooth::shim::GetGdShimHandler();
232 bluetooth::shim::GetHciLayer()->RegisterEventHandler(event_code, handler->Bind(event_callback));
233 }
234
register_le_event(bluetooth::hci::SubeventCode subevent_code)235 static void register_le_event(bluetooth::hci::SubeventCode subevent_code) {
236 auto handler = bluetooth::shim::GetGdShimHandler();
237 bluetooth::shim::GetHciLayer()->RegisterLeEventHandler(subevent_code,
238 handler->Bind(subevent_callback));
239 }
240
iso_data_callback()241 static void iso_data_callback() {
242 if (hci_iso_queue_end == nullptr) {
243 return;
244 }
245 auto packet = hci_iso_queue_end->TryDequeue();
246 log::assert_that(packet != nullptr, "assert failed: packet != nullptr");
247 if (!packet->IsValid()) {
248 log::info("Dropping invalid packet of size {}", packet->size());
249 return;
250 }
251 if (!send_data_upwards) {
252 return;
253 }
254 auto data = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ISO, packet.get());
255 packet_fragmenter->reassemble_and_dispatch(data);
256 }
257
register_for_iso()258 static void register_for_iso() {
259 hci_iso_queue_end = bluetooth::shim::GetHciLayer()->GetIsoQueueEnd();
260 hci_iso_queue_end->RegisterDequeue(bluetooth::shim::GetGdShimHandler(),
261 bluetooth::common::Bind(iso_data_callback));
262 pending_iso_data =
263 new bluetooth::os::EnqueueBuffer<bluetooth::hci::IsoBuilder>(hci_iso_queue_end);
264 // Register ISO for disconnect notifications
265 bluetooth::shim::GetHciLayer()->RegisterForDisconnects(
266 get_main_thread()->Bind([](uint16_t handle, bluetooth::hci::ErrorCode error_code) {
267 auto iso = bluetooth::hci::IsoManager::GetInstance();
268 if (iso) {
269 auto reason = static_cast<uint8_t>(error_code);
270 log::info("ISO disconnection from GD, handle: 0x{:02x}, reason: 0x{:02x}", handle,
271 reason);
272 iso->HandleDisconnect(handle, reason);
273 }
274 }));
275 }
276
on_shutting_down()277 static void on_shutting_down() {
278 if (pending_iso_data != nullptr) {
279 pending_iso_data->Clear();
280 delete pending_iso_data;
281 pending_iso_data = nullptr;
282 }
283 if (hci_iso_queue_end != nullptr) {
284 hci_iso_queue_end->UnregisterDequeue();
285 hci_iso_queue_end = nullptr;
286 }
287 }
288
289 } // namespace cpp
290
291 using bluetooth::common::Bind;
292 using bluetooth::common::BindOnce;
293 using bluetooth::common::Unretained;
294
set_data_cb(base::Callback<void (BT_HDR *)> send_data_cb)295 static void set_data_cb(base::Callback<void(BT_HDR*)> send_data_cb) {
296 send_data_upwards = std::move(send_data_cb);
297 }
298
transmit_command(const BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)299 static void transmit_command(const BT_HDR* command, command_complete_cb complete_callback,
300 command_status_cb status_callback, void* context) {
301 cpp::transmit_command(command, complete_callback, status_callback, context);
302 }
303
transmit_fragment(BT_HDR * packet,bool send_transmit_finished)304 static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
305 uint16_t event = packet->event & MSG_EVT_MASK;
306
307 // HCI command packets are freed on a different thread when the matching
308 // event is received. Check packet->event before sending to avoid a race.
309 bool free_after_transmit = event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished;
310
311 if (event == MSG_STACK_TO_HC_HCI_ISO) {
312 const uint8_t* stream = packet->data + packet->offset;
313 size_t length = packet->len;
314 cpp::transmit_iso_fragment(stream, length);
315 }
316
317 if (free_after_transmit) {
318 osi_free(packet);
319 }
320 }
dispatch_reassembled(BT_HDR * packet)321 static void dispatch_reassembled(BT_HDR* packet) {
322 // Only ISO should be handled here
323 log::assert_that((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ISO,
324 "assert failed: (packet->event & MSG_EVT_MASK) == "
325 "MSG_HC_TO_STACK_HCI_ISO");
326 log::assert_that(!send_data_upwards.is_null(), "assert failed: !send_data_upwards.is_null()");
327 send_data_upwards.Run(packet);
328 }
329
330 static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {transmit_fragment,
331 dispatch_reassembled};
332
transmit_downward(void * raw_data,uint16_t iso_buffer_size)333 static void transmit_downward(void* raw_data, uint16_t iso_buffer_size) {
334 bluetooth::shim::GetGdShimHandler()->Call(packet_fragmenter->fragment_and_dispatch,
335 static_cast<BT_HDR*>(raw_data), iso_buffer_size);
336 }
337
338 static hci_t interface = {.set_data_cb = set_data_cb,
339 .transmit_command = transmit_command,
340 .transmit_downward = transmit_downward};
341
hci_layer_get_interface()342 const hci_t* bluetooth::shim::hci_layer_get_interface() {
343 packet_fragmenter = packet_fragmenter_get_interface();
344 packet_fragmenter->init(&packet_fragmenter_callbacks);
345 return &interface;
346 }
347
hci_on_reset_complete()348 void bluetooth::shim::hci_on_reset_complete() {
349 log::assert_that(!send_data_upwards.is_null(), "assert failed: !send_data_upwards.is_null()");
350
351 for (uint16_t event_code_raw = 0; event_code_raw < 0x100; event_code_raw++) {
352 auto event_code = static_cast<bluetooth::hci::EventCode>(event_code_raw);
353 if (!register_event_code(event_code)) {
354 continue;
355 }
356 cpp::register_event(event_code);
357 }
358
359 for (uint16_t subevent_code_raw = 0; subevent_code_raw < 0x100; subevent_code_raw++) {
360 auto subevent_code = static_cast<bluetooth::hci::SubeventCode>(subevent_code_raw);
361 if (!register_subevent_code(subevent_code)) {
362 continue;
363 }
364 cpp::register_le_event(subevent_code);
365 }
366
367 cpp::register_for_iso();
368 }
369
hci_on_shutting_down()370 void bluetooth::shim::hci_on_shutting_down() { cpp::on_shutting_down(); }
371