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