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