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 "hci/hci_layer.h"
20
21 #include <base/bind.h>
22
23 #include <algorithm>
24 #include <cstdint>
25
26 #include "callbacks/callbacks.h"
27 #include "gd/common/init_flags.h"
28 #include "hci/hci_packets.h"
29 #include "hci/include/packet_fragmenter.h"
30 #include "hci/le_acl_connection_interface.h"
31 #include "hci/vendor_specific_event_manager.h"
32 #include "main/shim/hci_layer.h"
33 #include "main/shim/shim.h"
34 #include "main/shim/stack.h"
35 #include "osi/include/allocator.h"
36 #include "osi/include/future.h"
37 #include "packet/raw_builder.h"
38 #include "src/bridge.rs.h"
39 #include "stack/include/bt_types.h"
40
41 /**
42 * Callback data wrapped as opaque token bundled with the command
43 * transmit request to the Gd layer.
44 *
45 * Upon completion a token for a corresponding command transmit.
46 * request is returned from the Gd layer.
47 */
48 using CommandCallbackData = struct { void* context; };
49
50 constexpr size_t kBtHdrSize = sizeof(BT_HDR);
51 constexpr size_t kCommandLengthSize = sizeof(uint8_t);
52 constexpr size_t kCommandOpcodeSize = sizeof(uint16_t);
53
54 static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards;
55 static const packet_fragmenter_t* packet_fragmenter;
56
57 namespace {
is_valid_event_code(bluetooth::hci::EventCode event_code)58 bool is_valid_event_code(bluetooth::hci::EventCode event_code) {
59 switch (event_code) {
60 case bluetooth::hci::EventCode::INQUIRY_COMPLETE:
61 case bluetooth::hci::EventCode::INQUIRY_RESULT:
62 case bluetooth::hci::EventCode::CONNECTION_COMPLETE:
63 case bluetooth::hci::EventCode::CONNECTION_REQUEST:
64 case bluetooth::hci::EventCode::DISCONNECTION_COMPLETE:
65 case bluetooth::hci::EventCode::AUTHENTICATION_COMPLETE:
66 case bluetooth::hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE:
67 case bluetooth::hci::EventCode::ENCRYPTION_CHANGE:
68 case bluetooth::hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
69 case bluetooth::hci::EventCode::CENTRAL_LINK_KEY_COMPLETE:
70 case bluetooth::hci::EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
71 case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE:
72 case bluetooth::hci::EventCode::QOS_SETUP_COMPLETE:
73 case bluetooth::hci::EventCode::COMMAND_COMPLETE:
74 case bluetooth::hci::EventCode::COMMAND_STATUS:
75 case bluetooth::hci::EventCode::HARDWARE_ERROR:
76 case bluetooth::hci::EventCode::FLUSH_OCCURRED:
77 case bluetooth::hci::EventCode::ROLE_CHANGE:
78 case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS:
79 case bluetooth::hci::EventCode::MODE_CHANGE:
80 case bluetooth::hci::EventCode::RETURN_LINK_KEYS:
81 case bluetooth::hci::EventCode::PIN_CODE_REQUEST:
82 case bluetooth::hci::EventCode::LINK_KEY_REQUEST:
83 case bluetooth::hci::EventCode::LINK_KEY_NOTIFICATION:
84 case bluetooth::hci::EventCode::LOOPBACK_COMMAND:
85 case bluetooth::hci::EventCode::DATA_BUFFER_OVERFLOW:
86 case bluetooth::hci::EventCode::MAX_SLOTS_CHANGE:
87 case bluetooth::hci::EventCode::READ_CLOCK_OFFSET_COMPLETE:
88 case bluetooth::hci::EventCode::CONNECTION_PACKET_TYPE_CHANGED:
89 case bluetooth::hci::EventCode::QOS_VIOLATION:
90 case bluetooth::hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE:
91 case bluetooth::hci::EventCode::FLOW_SPECIFICATION_COMPLETE:
92 case bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI:
93 case bluetooth::hci::EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE:
94 case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE:
95 case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED:
96 case bluetooth::hci::EventCode::SNIFF_SUBRATING:
97 case bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT:
98 case bluetooth::hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
99 case bluetooth::hci::EventCode::IO_CAPABILITY_REQUEST:
100 case bluetooth::hci::EventCode::IO_CAPABILITY_RESPONSE:
101 case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST:
102 case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST:
103 case bluetooth::hci::EventCode::REMOTE_OOB_DATA_REQUEST:
104 case bluetooth::hci::EventCode::SIMPLE_PAIRING_COMPLETE:
105 case bluetooth::hci::EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED:
106 case bluetooth::hci::EventCode::ENHANCED_FLUSH_COMPLETE:
107 case bluetooth::hci::EventCode::USER_PASSKEY_NOTIFICATION:
108 case bluetooth::hci::EventCode::KEYPRESS_NOTIFICATION:
109 case bluetooth::hci::EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION:
110 case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_DATA_BLOCKS:
111 return true;
112 case bluetooth::hci::EventCode::VENDOR_SPECIFIC:
113 case bluetooth::hci::EventCode::LE_META_EVENT: // Private to hci
114 return false;
115 }
116 return false;
117 };
118
is_valid_subevent_code(bluetooth::hci::SubeventCode subevent_code)119 bool is_valid_subevent_code(bluetooth::hci::SubeventCode subevent_code) {
120 switch (subevent_code) {
121 case bluetooth::hci::SubeventCode::CONNECTION_COMPLETE:
122 case bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE:
123 case bluetooth::hci::SubeventCode::DATA_LENGTH_CHANGE:
124 case bluetooth::hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE:
125 case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE:
126 case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:
127 case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:
128 case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
129 case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE:
130 case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:
131 case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:
132 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
133 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:
134 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
135 case bluetooth::hci::SubeventCode::SCAN_TIMEOUT:
136 case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED:
137 case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED:
138 case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:
139 case bluetooth::hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:
140 case bluetooth::hci::SubeventCode::CONNECTION_IQ_REPORT:
141 case bluetooth::hci::SubeventCode::CTE_REQUEST_FAILED:
142 case bluetooth::hci::SubeventCode::
143 PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
144 case bluetooth::hci::SubeventCode::CIS_ESTABLISHED:
145 case bluetooth::hci::SubeventCode::CIS_REQUEST:
146 case bluetooth::hci::SubeventCode::CREATE_BIG_COMPLETE:
147 case bluetooth::hci::SubeventCode::TERMINATE_BIG_COMPLETE:
148 case bluetooth::hci::SubeventCode::BIG_SYNC_ESTABLISHED:
149 case bluetooth::hci::SubeventCode::BIG_SYNC_LOST:
150 case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:
151 case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD:
152 case bluetooth::hci::SubeventCode::TRANSMIT_POWER_REPORTING:
153 case bluetooth::hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT:
154 case bluetooth::hci::SubeventCode::ADVERTISING_REPORT:
155 case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST:
156 return true;
157 default:
158 return false;
159 }
160 }
161
event_already_registered_in_hci_layer(bluetooth::hci::EventCode event_code)162 static bool event_already_registered_in_hci_layer(
163 bluetooth::hci::EventCode event_code) {
164 switch (event_code) {
165 case bluetooth::hci::EventCode::COMMAND_COMPLETE:
166 case bluetooth::hci::EventCode::COMMAND_STATUS:
167 case bluetooth::hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE:
168 case bluetooth::hci::EventCode::MAX_SLOTS_CHANGE:
169 case bluetooth::hci::EventCode::LE_META_EVENT:
170 return bluetooth::shim::is_gd_hci_enabled() ||
171 bluetooth::shim::is_gd_acl_enabled() ||
172 bluetooth::shim::is_gd_l2cap_enabled();
173 case bluetooth::hci::EventCode::DISCONNECTION_COMPLETE:
174 case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE:
175 return bluetooth::shim::is_gd_acl_enabled() ||
176 bluetooth::shim::is_gd_l2cap_enabled();
177 default:
178 return false;
179 }
180 }
181
event_already_registered_in_controller_layer(bluetooth::hci::EventCode event_code)182 static bool event_already_registered_in_controller_layer(
183 bluetooth::hci::EventCode event_code) {
184 switch (event_code) {
185 case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS:
186 return bluetooth::shim::is_gd_acl_enabled() ||
187 bluetooth::shim::is_gd_l2cap_enabled();
188 default:
189 return false;
190 }
191 }
192
event_already_registered_in_acl_layer(bluetooth::hci::EventCode event_code)193 static bool event_already_registered_in_acl_layer(
194 bluetooth::hci::EventCode event_code) {
195 for (auto event : bluetooth::hci::AclConnectionEvents) {
196 if (event == event_code) {
197 return bluetooth::shim::is_gd_acl_enabled() ||
198 bluetooth::shim::is_gd_l2cap_enabled();
199 }
200 }
201 return false;
202 }
203
subevent_already_registered_in_le_hci_layer(bluetooth::hci::SubeventCode subevent_code)204 static bool subevent_already_registered_in_le_hci_layer(
205 bluetooth::hci::SubeventCode subevent_code) {
206 switch (subevent_code) {
207 case bluetooth::hci::SubeventCode::CONNECTION_COMPLETE:
208 case bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE:
209 case bluetooth::hci::SubeventCode::DATA_LENGTH_CHANGE:
210 case bluetooth::hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE:
211 case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE:
212 case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:
213 return bluetooth::shim::is_gd_acl_enabled() ||
214 bluetooth::shim::is_gd_l2cap_enabled() ||
215 bluetooth::shim::is_gd_advertising_enabled() ||
216 bluetooth::shim::is_gd_scanning_enabled();
217 case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED:
218 case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED:
219 return bluetooth::shim::is_gd_acl_enabled() ||
220 bluetooth::shim::is_gd_l2cap_enabled() ||
221 bluetooth::shim::is_gd_advertising_enabled();
222 case bluetooth::hci::SubeventCode::SCAN_TIMEOUT:
223 case bluetooth::hci::SubeventCode::ADVERTISING_REPORT:
224 case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:
225 case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:
226 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:
227 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
228 case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
229 return bluetooth::shim::is_gd_scanning_enabled();
230 case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:
231 case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
232 case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE:
233 case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:
234 case bluetooth::hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:
235 case bluetooth::hci::SubeventCode::CONNECTION_IQ_REPORT:
236 case bluetooth::hci::SubeventCode::CTE_REQUEST_FAILED:
237 case bluetooth::hci::SubeventCode::
238 PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
239 case bluetooth::hci::SubeventCode::CIS_ESTABLISHED:
240 case bluetooth::hci::SubeventCode::CIS_REQUEST:
241 case bluetooth::hci::SubeventCode::CREATE_BIG_COMPLETE:
242 case bluetooth::hci::SubeventCode::TERMINATE_BIG_COMPLETE:
243 case bluetooth::hci::SubeventCode::BIG_SYNC_ESTABLISHED:
244 case bluetooth::hci::SubeventCode::BIG_SYNC_LOST:
245 case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:
246 case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD:
247 case bluetooth::hci::SubeventCode::TRANSMIT_POWER_REPORTING:
248 case bluetooth::hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT:
249 case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST:
250 default:
251 return false;
252 }
253 }
254
event_already_registered_in_le_advertising_manager(bluetooth::hci::EventCode event_code)255 static bool event_already_registered_in_le_advertising_manager(
256 bluetooth::hci::EventCode event_code) {
257 for (auto event : bluetooth::hci::AclConnectionEvents) {
258 if (event == event_code) {
259 return bluetooth::shim::is_gd_advertising_enabled();
260 }
261 }
262 return false;
263 }
264
event_already_registered_in_le_scanning_manager(bluetooth::hci::EventCode event_code)265 static bool event_already_registered_in_le_scanning_manager(
266 bluetooth::hci::EventCode event_code) {
267 for (auto event : bluetooth::hci::AclConnectionEvents) {
268 if (event == event_code) {
269 return bluetooth::shim::is_gd_scanning_enabled();
270 }
271 }
272 return false;
273 }
274
275 class OsiObject {
276 public:
OsiObject(void * ptr)277 OsiObject(void* ptr) : ptr_(ptr) {}
~OsiObject()278 ~OsiObject() {
279 if (ptr_ != nullptr) {
280 osi_free(ptr_);
281 }
282 }
Release()283 void* Release() {
284 void* ptr = ptr_;
285 ptr_ = nullptr;
286 return ptr;
287 }
288
289 private:
290 void* ptr_;
291 };
292
293 } // namespace
294
295 namespace cpp {
296 bluetooth::common::BidiQueueEnd<bluetooth::hci::AclBuilder,
297 bluetooth::hci::AclView>* hci_queue_end =
298 nullptr;
299 static bluetooth::os::EnqueueBuffer<bluetooth::hci::AclBuilder>* pending_data =
300 nullptr;
301
MakeUniquePacket(const uint8_t * data,size_t len)302 static std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(
303 const uint8_t* data, size_t len) {
304 bluetooth::packet::RawBuilder builder;
305 std::vector<uint8_t> bytes(data, data + len);
306
307 auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
308 payload->AddOctets(bytes);
309
310 return payload;
311 }
312
WrapPacketAndCopy(uint16_t event,bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> * data)313 static BT_HDR* WrapPacketAndCopy(
314 uint16_t event,
315 bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>* data) {
316 size_t packet_size = data->size() + kBtHdrSize;
317 BT_HDR* packet = reinterpret_cast<BT_HDR*>(osi_malloc(packet_size));
318 packet->offset = 0;
319 packet->len = data->size();
320 packet->layer_specific = 0;
321 packet->event = event;
322 std::copy(data->begin(), data->end(), packet->data);
323 return packet;
324 }
325
event_callback(bluetooth::hci::EventView event_packet_view)326 static void event_callback(bluetooth::hci::EventView event_packet_view) {
327 if (!send_data_upwards) {
328 return;
329 }
330 send_data_upwards.Run(FROM_HERE, WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT,
331 &event_packet_view));
332 }
333
subevent_callback(bluetooth::hci::LeMetaEventView le_meta_event_view)334 static void subevent_callback(
335 bluetooth::hci::LeMetaEventView le_meta_event_view) {
336 if (!send_data_upwards) {
337 return;
338 }
339 send_data_upwards.Run(FROM_HERE, WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT,
340 &le_meta_event_view));
341 }
342
vendor_specific_event_callback(bluetooth::hci::VendorSpecificEventView vendor_specific_event_view)343 static void vendor_specific_event_callback(
344 bluetooth::hci::VendorSpecificEventView vendor_specific_event_view) {
345 if (!send_data_upwards) {
346 return;
347 }
348 send_data_upwards.Run(
349 FROM_HERE,
350 WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &vendor_specific_event_view));
351 }
352
OnTransmitPacketCommandComplete(command_complete_cb complete_callback,void * context,bluetooth::hci::CommandCompleteView view)353 void OnTransmitPacketCommandComplete(command_complete_cb complete_callback,
354 void* context,
355 bluetooth::hci::CommandCompleteView view) {
356 LOG_DEBUG("Received cmd complete for %s",
357 bluetooth::hci::OpCodeText(view.GetCommandOpCode()).c_str());
358 std::vector<uint8_t> data(view.begin(), view.end());
359 BT_HDR* response = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &view);
360 complete_callback(response, context);
361 }
362
OnTransmitPacketStatus(command_status_cb status_callback,void * context,std::unique_ptr<OsiObject> command,bluetooth::hci::CommandStatusView view)363 void OnTransmitPacketStatus(command_status_cb status_callback, void* context,
364 std::unique_ptr<OsiObject> command,
365 bluetooth::hci::CommandStatusView view) {
366 LOG_DEBUG("Received cmd status %s for %s",
367 bluetooth::hci::ErrorCodeText(view.GetStatus()).c_str(),
368 bluetooth::hci::OpCodeText(view.GetCommandOpCode()).c_str());
369 uint8_t status = static_cast<uint8_t>(view.GetStatus());
370 status_callback(status, static_cast<BT_HDR*>(command->Release()), context);
371 }
372
transmit_command(BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)373 static void transmit_command(BT_HDR* command,
374 command_complete_cb complete_callback,
375 command_status_cb status_callback, void* context) {
376 CHECK(command != nullptr);
377 uint8_t* data = command->data + command->offset;
378 size_t len = command->len;
379 CHECK(len >= (kCommandOpcodeSize + kCommandLengthSize));
380
381 // little endian command opcode
382 uint16_t command_op_code = (data[1] << 8 | data[0]);
383 // Gd stack API requires opcode specification and calculates length, so
384 // no need to provide opcode or length here.
385 data += (kCommandOpcodeSize + kCommandLengthSize);
386 len -= (kCommandOpcodeSize + kCommandLengthSize);
387
388 auto op_code = static_cast<const bluetooth::hci::OpCode>(command_op_code);
389
390 auto payload = MakeUniquePacket(data, len);
391 auto packet =
392 bluetooth::hci::CommandBuilder::Create(op_code, std::move(payload));
393
394 LOG_DEBUG("Sending command %s", bluetooth::hci::OpCodeText(op_code).c_str());
395
396 if (bluetooth::hci::Checker::IsCommandStatusOpcode(op_code)) {
397 auto command_unique = std::make_unique<OsiObject>(command);
398 bluetooth::shim::GetHciLayer()->EnqueueCommand(
399 std::move(packet), bluetooth::shim::GetGdShimHandler()->BindOnce(
400 OnTransmitPacketStatus, status_callback, context,
401 std::move(command_unique)));
402 } else {
403 bluetooth::shim::GetHciLayer()->EnqueueCommand(
404 std::move(packet),
405 bluetooth::shim::GetGdShimHandler()->BindOnce(
406 OnTransmitPacketCommandComplete, complete_callback, context));
407 osi_free(command);
408 }
409 }
410
transmit_fragment(const uint8_t * stream,size_t length)411 static void transmit_fragment(const uint8_t* stream, size_t length) {
412 uint16_t handle_with_flags;
413 STREAM_TO_UINT16(handle_with_flags, stream);
414 auto pb_flag = static_cast<bluetooth::hci::PacketBoundaryFlag>(
415 handle_with_flags >> 12 & 0b11);
416 auto bc_flag =
417 static_cast<bluetooth::hci::BroadcastFlag>(handle_with_flags >> 14);
418 uint16_t handle = handle_with_flags & 0xEFF;
419 length -= 2;
420 // skip data total length
421 stream += 2;
422 length -= 2;
423 auto payload = MakeUniquePacket(stream, length);
424 auto acl_packet = bluetooth::hci::AclBuilder::Create(handle, pb_flag, bc_flag,
425 std::move(payload));
426 pending_data->Enqueue(std::move(acl_packet),
427 bluetooth::shim::GetGdShimHandler());
428 }
429
register_event(bluetooth::hci::EventCode event_code)430 static void register_event(bluetooth::hci::EventCode event_code) {
431 auto handler = bluetooth::shim::GetGdShimHandler();
432 bluetooth::shim::GetHciLayer()->RegisterEventHandler(
433 event_code, handler->Bind(event_callback));
434 }
435
register_le_event(bluetooth::hci::SubeventCode subevent_code)436 static void register_le_event(bluetooth::hci::SubeventCode subevent_code) {
437 auto handler = bluetooth::shim::GetGdShimHandler();
438 bluetooth::shim::GetHciLayer()->RegisterLeEventHandler(
439 subevent_code, handler->Bind(subevent_callback));
440 }
441
acl_data_callback()442 static void acl_data_callback() {
443 if (hci_queue_end == nullptr) {
444 return;
445 }
446 auto packet = hci_queue_end->TryDequeue();
447 ASSERT(packet != nullptr);
448 if (!packet->IsValid()) {
449 LOG_INFO("Dropping invalid packet of size %zu", packet->size());
450 return;
451 }
452 if (!send_data_upwards) {
453 return;
454 }
455 auto data = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, packet.get());
456 packet_fragmenter->reassemble_and_dispatch(data);
457 }
458
register_for_acl()459 static void register_for_acl() {
460 hci_queue_end = bluetooth::shim::GetHciLayer()->GetAclQueueEnd();
461
462 // if gd advertising/scanning enabled, hci_queue_end will be register in
463 // AclManager::impl::Start
464 if (!bluetooth::shim::is_gd_advertising_enabled() &&
465 !bluetooth::shim::is_gd_scanning_enabled() &&
466 !bluetooth::shim::is_gd_l2cap_enabled()) {
467 hci_queue_end->RegisterDequeue(bluetooth::shim::GetGdShimHandler(),
468 bluetooth::common::Bind(acl_data_callback));
469 }
470
471 pending_data = new bluetooth::os::EnqueueBuffer<bluetooth::hci::AclBuilder>(
472 hci_queue_end);
473 }
474
on_shutting_down()475 static void on_shutting_down() {
476 if (pending_data != nullptr) {
477 pending_data->Clear();
478 delete pending_data;
479 pending_data = nullptr;
480 }
481 if (hci_queue_end != nullptr) {
482 if (!bluetooth::shim::is_gd_advertising_enabled() &&
483 !bluetooth::shim::is_gd_l2cap_enabled()) {
484 hci_queue_end->UnregisterDequeue();
485 }
486 for (uint16_t event_code_raw = 0; event_code_raw < 0x100;
487 event_code_raw++) {
488 auto event_code = static_cast<bluetooth::hci::EventCode>(event_code_raw);
489 if (!is_valid_event_code(event_code)) {
490 continue;
491 }
492 if (event_already_registered_in_hci_layer(event_code)) {
493 continue;
494 } else if (event_already_registered_in_le_advertising_manager(
495 event_code)) {
496 continue;
497 } else if (event_already_registered_in_le_scanning_manager(event_code)) {
498 continue;
499 }
500 bluetooth::shim::GetHciLayer()->UnregisterEventHandler(event_code);
501 }
502 hci_queue_end = nullptr;
503 }
504 }
505
506 } // namespace cpp
507
508 using bluetooth::common::Bind;
509 using bluetooth::common::BindOnce;
510 using bluetooth::common::Unretained;
511
512 namespace rust {
513
514 using bluetooth::shim::rust::u8SliceCallback;
515 using bluetooth::shim::rust::u8SliceOnceCallback;
516
WrapRustPacketAndCopy(uint16_t event,::rust::Slice<const uint8_t> * data)517 static BT_HDR* WrapRustPacketAndCopy(uint16_t event,
518 ::rust::Slice<const uint8_t>* data) {
519 size_t packet_size = data->length() + kBtHdrSize;
520 BT_HDR* packet = reinterpret_cast<BT_HDR*>(osi_malloc(packet_size));
521 packet->offset = 0;
522 packet->len = data->length();
523 packet->layer_specific = 0;
524 packet->event = event;
525 std::copy(data->data(), data->data() + data->length(), packet->data);
526 return packet;
527 }
528
on_acl(::rust::Slice<const uint8_t> data)529 static void on_acl(::rust::Slice<const uint8_t> data) {
530 if (!send_data_upwards) {
531 return;
532 }
533 auto legacy_data = WrapRustPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, &data);
534 packet_fragmenter->reassemble_and_dispatch(legacy_data);
535 }
536
on_event(::rust::Slice<const uint8_t> data)537 static void on_event(::rust::Slice<const uint8_t> data) {
538 if (!send_data_upwards) {
539 return;
540 }
541 send_data_upwards.Run(FROM_HERE,
542 WrapRustPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &data));
543 }
544
OnRustTransmitPacketCommandComplete(command_complete_cb complete_callback,void * context,::rust::Slice<const uint8_t> data)545 void OnRustTransmitPacketCommandComplete(command_complete_cb complete_callback,
546 void* context,
547 ::rust::Slice<const uint8_t> data) {
548 BT_HDR* response = WrapRustPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &data);
549 complete_callback(response, context);
550 }
551
OnRustTransmitPacketStatus(command_status_cb status_callback,void * context,std::unique_ptr<OsiObject> command,::rust::Slice<const uint8_t> data)552 void OnRustTransmitPacketStatus(command_status_cb status_callback,
553 void* context,
554 std::unique_ptr<OsiObject> command,
555 ::rust::Slice<const uint8_t> data) {
556 ASSERT(data.length() >= 3);
557 uint8_t status = data.data()[2];
558 status_callback(status, static_cast<BT_HDR*>(command->Release()), context);
559 }
560
transmit_command(BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)561 static void transmit_command(BT_HDR* command,
562 command_complete_cb complete_callback,
563 command_status_cb status_callback, void* context) {
564 CHECK(command != nullptr);
565 const uint8_t* data = command->data + command->offset;
566 size_t len = command->len;
567 CHECK(len >= (kCommandOpcodeSize + kCommandLengthSize));
568
569 // little endian command opcode
570 uint16_t command_op_code = (data[1] << 8 | data[0]);
571 auto op_code = static_cast<const bluetooth::hci::OpCode>(command_op_code);
572
573 LOG_DEBUG("Sending command %s", bluetooth::hci::OpCodeText(op_code).c_str());
574
575 if (bluetooth::hci::Checker::IsCommandStatusOpcode(op_code)) {
576 auto command_unique = std::make_unique<OsiObject>(command);
577 bluetooth::shim::rust::hci_send_command(
578 **bluetooth::shim::Stack::Stack::GetInstance()->GetRustHci(),
579 ::rust::Slice(data, len),
580 std::make_unique<u8SliceOnceCallback>(
581 BindOnce(OnRustTransmitPacketStatus, status_callback, context,
582 std::move(command_unique))));
583 } else {
584 bluetooth::shim::rust::hci_send_command(
585 **bluetooth::shim::Stack::Stack::GetInstance()->GetRustHci(),
586 ::rust::Slice(data, len),
587 std::make_unique<u8SliceOnceCallback>(BindOnce(
588 OnRustTransmitPacketCommandComplete, complete_callback, context)));
589 osi_free(command);
590 }
591 }
592
transmit_fragment(const uint8_t * stream,size_t length)593 static void transmit_fragment(const uint8_t* stream, size_t length) {
594 bluetooth::shim::rust::hci_send_acl(
595 **bluetooth::shim::Stack::Stack::GetInstance()->GetRustHci(),
596 ::rust::Slice(stream, length));
597 }
598
register_event(bluetooth::hci::EventCode event_code)599 static void register_event(bluetooth::hci::EventCode event_code) {
600 bluetooth::shim::rust::hci_register_event(
601 **bluetooth::shim::Stack::GetInstance()->GetRustHci(),
602 static_cast<uint8_t>(event_code));
603 }
604
register_le_event(bluetooth::hci::SubeventCode subevent_code)605 static void register_le_event(bluetooth::hci::SubeventCode subevent_code) {
606 bluetooth::shim::rust::hci_register_le_event(
607 **bluetooth::shim::Stack::Stack::GetInstance()->GetRustHci(),
608 static_cast<uint8_t>(subevent_code));
609 }
610
hci_on_reset_complete()611 static void hci_on_reset_complete() {
612 bluetooth::shim::rust::hci_set_evt_callback(
613 **bluetooth::shim::Stack::GetInstance()->GetRustHci(),
614 std::make_unique<u8SliceCallback>(Bind(rust::on_event)));
615 bluetooth::shim::rust::hci_set_le_evt_callback(
616 **bluetooth::shim::Stack::GetInstance()->GetRustHci(),
617 std::make_unique<u8SliceCallback>(Bind(rust::on_event)));
618 }
619
register_for_acl()620 static void register_for_acl() {
621 bluetooth::shim::rust::hci_set_acl_callback(
622 **bluetooth::shim::Stack::GetInstance()->GetRustHci(),
623 std::make_unique<u8SliceCallback>(Bind(rust::on_acl)));
624 }
625
on_shutting_down()626 static void on_shutting_down() {}
627
628 } // namespace rust
629
set_data_cb(base::Callback<void (const base::Location &,BT_HDR *)> send_data_cb)630 static void set_data_cb(
631 base::Callback<void(const base::Location&, BT_HDR*)> send_data_cb) {
632 send_data_upwards = std::move(send_data_cb);
633 }
634
transmit_command(BT_HDR * command,command_complete_cb complete_callback,command_status_cb status_callback,void * context)635 static void transmit_command(BT_HDR* command,
636 command_complete_cb complete_callback,
637 command_status_cb status_callback, void* context) {
638 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
639 rust::transmit_command(command, complete_callback, status_callback,
640 context);
641 } else {
642 cpp::transmit_command(command, complete_callback, status_callback, context);
643 }
644 }
645
command_complete_callback(BT_HDR * response,void * context)646 static void command_complete_callback(BT_HDR* response, void* context) {
647 auto future = static_cast<future_t*>(context);
648 future_ready(future, response);
649 }
650
command_status_callback(uint8_t status,BT_HDR * command,void * context)651 static void command_status_callback(uint8_t status, BT_HDR* command,
652 void* context) {
653 LOG_ALWAYS_FATAL(
654 "transmit_command_futured should only send command complete opcode");
655 }
656
transmit_command_futured(BT_HDR * command)657 static future_t* transmit_command_futured(BT_HDR* command) {
658 future_t* future = future_new();
659 transmit_command(command, command_complete_callback, command_status_callback,
660 future);
661 return future;
662 }
663
transmit_fragment(BT_HDR * packet,bool send_transmit_finished)664 static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
665 // HCI command packets are freed on a different thread when the matching
666 // event is received. Check packet->event before sending to avoid a race.
667 bool free_after_transmit =
668 (packet->event & MSG_EVT_MASK) != MSG_STACK_TO_HC_HCI_CMD &&
669 send_transmit_finished;
670
671 const uint8_t* stream = packet->data + packet->offset;
672 size_t length = packet->len;
673 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
674 rust::transmit_fragment(stream, length);
675 } else {
676 cpp::transmit_fragment(stream, length);
677 }
678 if (free_after_transmit) {
679 osi_free(packet);
680 }
681 }
dispatch_reassembled(BT_HDR * packet)682 static void dispatch_reassembled(BT_HDR* packet) {
683 // Events should already have been dispatched before this point
684 CHECK((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
685 CHECK(!send_data_upwards.is_null());
686 send_data_upwards.Run(FROM_HERE, packet);
687 }
fragmenter_transmit_finished(BT_HDR * packet,bool all_fragments_sent)688 static void fragmenter_transmit_finished(BT_HDR* packet,
689 bool all_fragments_sent) {
690 if (all_fragments_sent) {
691 osi_free(packet);
692 } else {
693 // This is kind of a weird case, since we're dispatching a partially sent
694 // packet up to a higher layer.
695 // TODO(zachoverflow): rework upper layer so this isn't necessary.
696 send_data_upwards.Run(FROM_HERE, packet);
697 }
698 }
699
700 static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
701 transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};
702
transmit_downward(uint16_t type,void * raw_data)703 static void transmit_downward(uint16_t type, void* raw_data) {
704 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
705 packet_fragmenter->fragment_and_dispatch(static_cast<BT_HDR*>(raw_data));
706 } else {
707 bluetooth::shim::GetGdShimHandler()->Call(
708 packet_fragmenter->fragment_and_dispatch,
709 static_cast<BT_HDR*>(raw_data));
710 }
711 }
712
713 static hci_t interface = {.set_data_cb = set_data_cb,
714 .transmit_command = transmit_command,
715 .transmit_command_futured = transmit_command_futured,
716 .transmit_downward = transmit_downward};
717
hci_layer_get_interface()718 const hci_t* bluetooth::shim::hci_layer_get_interface() {
719 packet_fragmenter = packet_fragmenter_get_interface();
720 packet_fragmenter->init(&packet_fragmenter_callbacks);
721 return &interface;
722 }
723
hci_on_reset_complete()724 void bluetooth::shim::hci_on_reset_complete() {
725 ASSERT(send_data_upwards);
726 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
727 ::rust::hci_on_reset_complete();
728 }
729
730 for (uint16_t event_code_raw = 0; event_code_raw < 0x100; event_code_raw++) {
731 auto event_code = static_cast<bluetooth::hci::EventCode>(event_code_raw);
732 if (!is_valid_event_code(event_code)) {
733 continue;
734 }
735 if (event_already_registered_in_acl_layer(event_code)) {
736 continue;
737 } else if (event_already_registered_in_controller_layer(event_code)) {
738 continue;
739 } else if (event_already_registered_in_hci_layer(event_code)) {
740 continue;
741 } else if (event_already_registered_in_le_advertising_manager(event_code)) {
742 continue;
743 } else if (event_already_registered_in_le_scanning_manager(event_code)) {
744 continue;
745 }
746
747 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
748 ::rust::register_event(event_code);
749 } else {
750 cpp::register_event(event_code);
751 }
752 }
753
754 for (uint16_t subevent_code_raw = 0; subevent_code_raw < 0x100;
755 subevent_code_raw++) {
756 auto subevent_code =
757 static_cast<bluetooth::hci::SubeventCode>(subevent_code_raw);
758 if (!is_valid_subevent_code(subevent_code)) {
759 continue;
760 }
761 if (subevent_already_registered_in_le_hci_layer(subevent_code)) {
762 continue;
763 }
764
765 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
766 ::rust::register_le_event(subevent_code);
767 } else {
768 cpp::register_le_event(subevent_code);
769 }
770 }
771
772 // TODO handle BQR event in GD
773 auto handler = bluetooth::shim::GetGdShimHandler();
774 bluetooth::shim::GetVendorSpecificEventManager()->RegisterEventHandler(
775 bluetooth::hci::VseSubeventCode::BQR_EVENT,
776 handler->Bind(cpp::vendor_specific_event_callback));
777
778 if (bluetooth::shim::is_gd_acl_enabled()) {
779 return;
780 }
781
782 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
783 ::rust::register_for_acl();
784 } else {
785 cpp::register_for_acl();
786 }
787 }
788
hci_on_shutting_down()789 void bluetooth::shim::hci_on_shutting_down() {
790 if (bluetooth::common::init_flags::gd_rust_is_enabled()) {
791 ::rust::on_shutting_down();
792 } else {
793 cpp::on_shutting_down();
794 }
795 }
796