1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <base/functional/bind.h>
21 #include <base/functional/callback.h>
22 
23 #include <list>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 
28 #include "btm_dev.h"
29 #include "btm_iso_api.h"
30 #include "common/time_util.h"
31 #include "hci/controller_interface.h"
32 #include "hci/include/hci_layer.h"
33 #include "internal_include/stack_config.h"
34 #include "main/shim/entry.h"
35 #include "main/shim/hci_layer.h"
36 #include "osi/include/allocator.h"
37 #include "stack/include/bt_hdr.h"
38 #include "stack/include/bt_types.h"
39 #include "stack/include/btm_log_history.h"
40 #include "stack/include/hci_error_code.h"
41 #include "stack/include/hcidefs.h"
42 #include "stack/include/hcimsgs.h"
43 
44 namespace bluetooth {
45 namespace hci {
46 namespace iso_manager {
47 static constexpr uint8_t kIsoHeaderWithTsLen = 12;
48 static constexpr uint8_t kIsoHeaderWithoutTsLen = 8;
49 
50 static constexpr uint8_t kStateFlagsNone = 0x00;
51 static constexpr uint8_t kStateFlagIsConnecting = 0x01;
52 static constexpr uint8_t kStateFlagIsConnected = 0x02;
53 static constexpr uint8_t kStateFlagHasDataPathSet = 0x04;
54 static constexpr uint8_t kStateFlagIsBroadcast = 0x10;
55 static constexpr uint8_t kStateFlagIsCancelled = 0x20;
56 
57 constexpr char kBtmLogTag[] = "ISO";
58 
59 struct iso_sync_info {
60   uint16_t tx_seq_nb;
61   uint16_t rx_seq_nb;
62 };
63 
64 struct iso_base {
65   union {
66     uint8_t cig_id;
67     uint8_t big_handle;
68   };
69 
70   struct iso_sync_info sync_info;
71   std::atomic_uint8_t state_flags;
72   uint32_t sdu_itv;
73   std::atomic_uint16_t used_credits;
74 
75   struct credits_stats {
76     size_t credits_underflow_bytes = 0;
77     size_t credits_underflow_count = 0;
78     uint64_t credits_last_underflow_us = 0;
79   };
80 
81   struct event_stats {
82     size_t evt_lost_count = 0;
83     size_t seq_nb_mismatch_count = 0;
84     uint64_t evt_last_lost_us = 0;
85   };
86 
87   credits_stats cr_stats;
88   event_stats evt_stats;
89 };
90 
91 typedef iso_base iso_cis;
92 typedef iso_base iso_bis;
93 
94 struct iso_impl {
iso_impliso_impl95   iso_impl() {
96     iso_credits_ = shim::GetController()->GetControllerIsoBufferSize().total_num_le_packets_;
97     iso_buffer_size_ = shim::GetController()->GetControllerIsoBufferSize().le_data_packet_length_;
98     log::info("{} created, iso credits: {}, buffer size: {}.", std::format_ptr(this),
99               iso_credits_.load(), iso_buffer_size_);
100   }
101 
~iso_impliso_impl102   ~iso_impl() { log::info("{} removed.", std::format_ptr(this)); }
103 
handle_register_cis_callbacksiso_impl104   void handle_register_cis_callbacks(CigCallbacks* callbacks) {
105     log::assert_that(callbacks != nullptr, "Invalid CIG callbacks");
106     cig_callbacks_ = callbacks;
107   }
108 
handle_register_big_callbacksiso_impl109   void handle_register_big_callbacks(BigCallbacks* callbacks) {
110     log::assert_that(callbacks != nullptr, "Invalid BIG callbacks");
111     big_callbacks_ = callbacks;
112   }
113 
handle_register_on_iso_traffic_active_callbackiso_impl114   void handle_register_on_iso_traffic_active_callback(void callback(bool)) {
115     log::assert_that(callback != nullptr, "Invalid OnIsoTrafficActive callback");
116     const std::lock_guard<std::mutex> lock(on_iso_traffic_active_callbacks_list_mutex_);
117     on_iso_traffic_active_callbacks_list_.push_back(callback);
118   }
119 
on_set_cig_paramsiso_impl120   void on_set_cig_params(uint8_t cig_id, uint32_t sdu_itv_mtos, uint8_t* stream, uint16_t len) {
121     uint8_t cis_cnt;
122     uint16_t conn_handle;
123     cig_create_cmpl_evt evt;
124 
125     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
126     log::assert_that(len >= 3, "Invalid packet length: {}", len);
127 
128     STREAM_TO_UINT8(evt.status, stream);
129     STREAM_TO_UINT8(evt.cig_id, stream);
130     STREAM_TO_UINT8(cis_cnt, stream);
131 
132     uint8_t evt_code =
133             IsCigKnown(cig_id) ? kIsoEventCigOnReconfigureCmpl : kIsoEventCigOnCreateCmpl;
134 
135     BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "CIG Create complete",
136                    base::StringPrintf("cig_id:0x%02x, status: %s", evt.cig_id,
137                                       hci_status_code_text((tHCI_STATUS)(evt.status)).c_str()));
138 
139     if (evt.status == HCI_SUCCESS) {
140       log::assert_that(len >= (3) + (cis_cnt * sizeof(uint16_t)), "Invalid CIS count: {}", cis_cnt);
141 
142       /* Remove entries for the reconfigured CIG */
143       if (evt_code == kIsoEventCigOnReconfigureCmpl) {
144         auto cis_it = conn_hdl_to_cis_map_.cbegin();
145         while (cis_it != conn_hdl_to_cis_map_.cend()) {
146           if (cis_it->second->cig_id == evt.cig_id) {
147             cis_it = conn_hdl_to_cis_map_.erase(cis_it);
148           } else {
149             ++cis_it;
150           }
151         }
152       }
153 
154       evt.conn_handles.reserve(cis_cnt);
155       for (int i = 0; i < cis_cnt; i++) {
156         STREAM_TO_UINT16(conn_handle, stream);
157 
158         evt.conn_handles.push_back(conn_handle);
159 
160         auto cis = std::unique_ptr<iso_cis>(new iso_cis());
161         cis->cig_id = cig_id;
162         cis->sdu_itv = sdu_itv_mtos;
163         cis->sync_info = {.tx_seq_nb = 0, .rx_seq_nb = 0};
164         cis->used_credits = 0;
165         cis->state_flags = kStateFlagsNone;
166         conn_hdl_to_cis_map_[conn_handle] = std::move(cis);
167       }
168     }
169 
170     cig_callbacks_->OnCigEvent(evt_code, &evt);
171 
172     if (evt_code == kIsoEventCigOnCreateCmpl) {
173       const std::lock_guard<std::mutex> lock(on_iso_traffic_active_callbacks_list_mutex_);
174       for (auto callback : on_iso_traffic_active_callbacks_list_) {
175         callback(true);
176       }
177     }
178   }
179 
create_cigiso_impl180   void create_cig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
181     log::assert_that(!IsCigKnown(cig_id), "Invalid cig - already exists: {}", cig_id);
182 
183     btsnd_hcic_set_cig_params(
184             cig_id, cig_params.sdu_itv_mtos, cig_params.sdu_itv_stom, cig_params.sca,
185             cig_params.packing, cig_params.framing, cig_params.max_trans_lat_stom,
186             cig_params.max_trans_lat_mtos, cig_params.cis_cfgs.size(), cig_params.cis_cfgs.data(),
187             base::BindOnce(&iso_impl::on_set_cig_params, weak_factory_.GetWeakPtr(), cig_id,
188                            cig_params.sdu_itv_mtos));
189 
190     BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "CIG Create",
191                    base::StringPrintf("cig_id:0x%02x, size: %d", cig_id,
192                                       static_cast<int>(cig_params.cis_cfgs.size())));
193   }
194 
reconfigure_cigiso_impl195   void reconfigure_cig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
196     log::assert_that(IsCigKnown(cig_id), "No such cig: {}", cig_id);
197 
198     btsnd_hcic_set_cig_params(
199             cig_id, cig_params.sdu_itv_mtos, cig_params.sdu_itv_stom, cig_params.sca,
200             cig_params.packing, cig_params.framing, cig_params.max_trans_lat_stom,
201             cig_params.max_trans_lat_mtos, cig_params.cis_cfgs.size(), cig_params.cis_cfgs.data(),
202             base::BindOnce(&iso_impl::on_set_cig_params, weak_factory_.GetWeakPtr(), cig_id,
203                            cig_params.sdu_itv_mtos));
204   }
205 
on_remove_cigiso_impl206   void on_remove_cig(uint8_t* stream, uint16_t len) {
207     cig_remove_cmpl_evt evt;
208 
209     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
210     log::assert_that(len == 2, "Invalid packet length: {}", len);
211 
212     STREAM_TO_UINT8(evt.status, stream);
213     STREAM_TO_UINT8(evt.cig_id, stream);
214 
215     BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "CIG Remove complete",
216                    base::StringPrintf("cig_id:0x%02x, status: %s", evt.cig_id,
217                                       hci_status_code_text((tHCI_STATUS)(evt.status)).c_str()));
218 
219     if (evt.status == HCI_SUCCESS) {
220       auto cis_it = conn_hdl_to_cis_map_.cbegin();
221       while (cis_it != conn_hdl_to_cis_map_.cend()) {
222         if (cis_it->second->cig_id == evt.cig_id) {
223           cis_it = conn_hdl_to_cis_map_.erase(cis_it);
224         } else {
225           ++cis_it;
226         }
227       }
228     }
229 
230     cig_callbacks_->OnCigEvent(kIsoEventCigOnRemoveCmpl, &evt);
231 
232     {
233       const std::lock_guard<std::mutex> lock(on_iso_traffic_active_callbacks_list_mutex_);
234       for (auto callback : on_iso_traffic_active_callbacks_list_) {
235         callback(false);
236       }
237     }
238   }
239 
remove_cigiso_impl240   void remove_cig(uint8_t cig_id, bool force) {
241     if (!force) {
242       log::assert_that(IsCigKnown(cig_id), "No such cig: {}", cig_id);
243     } else {
244       log::warn("Forcing to remove CIG {}", cig_id);
245     }
246 
247     btsnd_hcic_remove_cig(cig_id,
248                           base::BindOnce(&iso_impl::on_remove_cig, weak_factory_.GetWeakPtr()));
249     BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "CIG Remove",
250                    base::StringPrintf("cig_id:0x%02x (f:%d)", cig_id, force));
251   }
252 
on_status_establish_cisiso_impl253   void on_status_establish_cis(struct iso_manager::cis_establish_params conn_params,
254                                uint8_t* stream, uint16_t len) {
255     uint8_t status;
256 
257     log::assert_that(len == 2, "Invalid packet length: {}", len);
258 
259     STREAM_TO_UINT16(status, stream);
260 
261     for (auto cis_param : conn_params.conn_pairs) {
262       cis_establish_cmpl_evt evt;
263 
264       if (status != HCI_SUCCESS) {
265         auto cis = GetCisIfKnown(cis_param.cis_conn_handle);
266         log::assert_that(cis != nullptr, "No such cis: {}", cis_param.cis_conn_handle);
267 
268         evt.status = status;
269         evt.cis_conn_hdl = cis_param.cis_conn_handle;
270         evt.cig_id = cis->cig_id;
271         cis->state_flags &= ~kStateFlagIsConnecting;
272         cig_callbacks_->OnCisEvent(kIsoEventCisEstablishCmpl, &evt);
273 
274         BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[evt.cis_conn_hdl], "Establish CIS failed ",
275                        base::StringPrintf("handle:0x%04x, status: %s", evt.cis_conn_hdl,
276                                           hci_status_code_text((tHCI_STATUS)(status)).c_str()));
277         cis_hdl_to_addr.erase(evt.cis_conn_hdl);
278       }
279     }
280   }
281 
establish_cisiso_impl282   void establish_cis(struct iso_manager::cis_establish_params conn_params) {
283     for (auto& el : conn_params.conn_pairs) {
284       auto cis = GetCisIfKnown(el.cis_conn_handle);
285       log::assert_that(cis, "No such cis: {}", el.cis_conn_handle);
286       log::assert_that(!(cis->state_flags &
287                          (kStateFlagIsConnected | kStateFlagIsConnecting | kStateFlagIsCancelled)),
288                        "cis: {} is already connected/connecting/cancelled flags: {}, "
289                        "num of cis params: {}",
290                        el.cis_conn_handle, cis->state_flags, conn_params.conn_pairs.size());
291 
292       cis->state_flags |= kStateFlagIsConnecting;
293 
294       tBTM_SEC_DEV_REC* p_rec = btm_find_dev_by_handle(el.acl_conn_handle);
295       if (p_rec) {
296         cis_hdl_to_addr[el.cis_conn_handle] = p_rec->ble.pseudo_addr;
297         BTM_LogHistory(kBtmLogTag, p_rec->ble.pseudo_addr, "Establish CIS",
298                        base::StringPrintf("handle:0x%04x", el.acl_conn_handle));
299       }
300     }
301     btsnd_hcic_create_cis(conn_params.conn_pairs.size(), conn_params.conn_pairs.data(),
302                           base::BindOnce(&iso_impl::on_status_establish_cis,
303                                          weak_factory_.GetWeakPtr(), conn_params));
304   }
305 
disconnect_cisiso_impl306   void disconnect_cis(uint16_t cis_handle, uint8_t reason) {
307     auto cis = GetCisIfKnown(cis_handle);
308     log::assert_that(cis, "No such cis: {}", cis_handle);
309     log::assert_that(
310             cis->state_flags & kStateFlagIsConnected || cis->state_flags & kStateFlagIsConnecting,
311             "Not connected");
312 
313     if (cis->state_flags & kStateFlagIsConnecting) {
314       cis->state_flags &= ~kStateFlagIsConnecting;
315       cis->state_flags |= kStateFlagIsCancelled;
316     }
317 
318     bluetooth::legacy::hci::GetInterface().Disconnect(cis_handle, static_cast<tHCI_STATUS>(reason));
319 
320     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[cis_handle], "Disconnect CIS ",
321                    base::StringPrintf("handle:0x%04x, reason:%s", cis_handle,
322                                       hci_reason_code_text((tHCI_REASON)(reason)).c_str()));
323   }
324 
get_number_of_active_isoiso_impl325   int get_number_of_active_iso() {
326     int num_iso = conn_hdl_to_cis_map_.size() + conn_hdl_to_bis_map_.size();
327     log::info("Current number of active_iso is {}", num_iso);
328     return num_iso;
329   }
330 
on_setup_iso_data_pathiso_impl331   void on_setup_iso_data_path(uint8_t* stream, uint16_t /* len */) {
332     uint8_t status;
333     uint16_t conn_handle;
334 
335     STREAM_TO_UINT8(status, stream);
336     STREAM_TO_UINT16(conn_handle, stream);
337 
338     iso_base* iso = GetIsoIfKnown(conn_handle);
339     if (iso == nullptr) {
340       /* That can happen when ACL has been disconnected while ISO patch was
341        * creating */
342       log::warn("Invalid connection handle: {}", conn_handle);
343       return;
344     }
345 
346     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[conn_handle], "Setup data path complete",
347                    base::StringPrintf("handle:0x%04x, status:%s", conn_handle,
348                                       hci_status_code_text((tHCI_STATUS)(status)).c_str()));
349 
350     if (status == HCI_SUCCESS) {
351       iso->state_flags |= kStateFlagHasDataPathSet;
352     }
353     if (iso->state_flags & kStateFlagIsBroadcast) {
354       log::assert_that(big_callbacks_ != nullptr, "Invalid BIG callbacks");
355       big_callbacks_->OnSetupIsoDataPath(status, conn_handle, iso->big_handle);
356     } else {
357       log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
358       cig_callbacks_->OnSetupIsoDataPath(status, conn_handle, iso->cig_id);
359     }
360   }
361 
setup_iso_data_pathiso_impl362   void setup_iso_data_path(uint16_t conn_handle,
363                            struct iso_manager::iso_data_path_params path_params) {
364     iso_base* iso = GetIsoIfKnown(conn_handle);
365     log::assert_that(iso != nullptr, "No such iso connection: {}", conn_handle);
366 
367     if (!(iso->state_flags & kStateFlagIsBroadcast)) {
368       log::assert_that(iso->state_flags & kStateFlagIsConnected, "CIS not established");
369     }
370 
371     btsnd_hcic_setup_iso_data_path(
372             conn_handle, path_params.data_path_dir, path_params.data_path_id,
373             path_params.codec_id_format, path_params.codec_id_company, path_params.codec_id_vendor,
374             path_params.controller_delay, std::move(path_params.codec_conf),
375             base::BindOnce(&iso_impl::on_setup_iso_data_path, weak_factory_.GetWeakPtr()));
376     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[conn_handle], "Setup data path",
377                    base::StringPrintf("handle:0x%04x, dir:0x%02x, path_id:0x%02x, codec_id:0x%02x",
378                                       conn_handle, path_params.data_path_dir,
379                                       path_params.data_path_id, path_params.codec_id_format));
380   }
381 
on_remove_iso_data_pathiso_impl382   void on_remove_iso_data_path(uint8_t* stream, uint16_t len) {
383     uint8_t status;
384     uint16_t conn_handle;
385 
386     if (len < 3) {
387       log::warn("Malformatted packet received");
388       return;
389     }
390     STREAM_TO_UINT8(status, stream);
391     STREAM_TO_UINT16(conn_handle, stream);
392 
393     iso_base* iso = GetIsoIfKnown(conn_handle);
394     if (iso == nullptr) {
395       /* That could happen when ACL has been disconnected while removing data
396        * path */
397       log::warn("Invalid connection handle: {}", conn_handle);
398       return;
399     }
400 
401     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[conn_handle], "Remove data path complete",
402                    base::StringPrintf("handle:0x%04x, status:%s", conn_handle,
403                                       hci_status_code_text((tHCI_STATUS)(status)).c_str()));
404 
405     if (status == HCI_SUCCESS) {
406       iso->state_flags &= ~kStateFlagHasDataPathSet;
407     }
408 
409     if (iso->state_flags & kStateFlagIsBroadcast) {
410       log::assert_that(big_callbacks_ != nullptr, "Invalid BIG callbacks");
411       big_callbacks_->OnRemoveIsoDataPath(status, conn_handle, iso->big_handle);
412     } else {
413       log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
414       cig_callbacks_->OnRemoveIsoDataPath(status, conn_handle, iso->cig_id);
415     }
416   }
417 
remove_iso_data_pathiso_impl418   void remove_iso_data_path(uint16_t iso_handle, uint8_t data_path_dir) {
419     iso_base* iso = GetIsoIfKnown(iso_handle);
420     log::assert_that(iso != nullptr, "No such iso connection: 0x{:x}", iso_handle);
421     log::assert_that((iso->state_flags & kStateFlagHasDataPathSet) == kStateFlagHasDataPathSet,
422                      "Data path not set");
423 
424     btsnd_hcic_remove_iso_data_path(
425             iso_handle, data_path_dir,
426             base::BindOnce(&iso_impl::on_remove_iso_data_path, weak_factory_.GetWeakPtr()));
427 
428     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[iso_handle], "Remove data path",
429                    base::StringPrintf("handle:0x%04x, dir:0x%02x", iso_handle, data_path_dir));
430   }
431 
on_iso_link_quality_readiso_impl432   void on_iso_link_quality_read(uint8_t* stream, uint16_t len) {
433     uint8_t status;
434     uint16_t conn_handle;
435     uint32_t txUnackedPackets;
436     uint32_t txFlushedPackets;
437     uint32_t txLastSubeventPackets;
438     uint32_t retransmittedPackets;
439     uint32_t crcErrorPackets;
440     uint32_t rxUnreceivedPackets;
441     uint32_t duplicatePackets;
442 
443     // 1 + 2 + 4 * 7
444 #define ISO_LINK_QUALITY_SIZE 31
445     if (len < ISO_LINK_QUALITY_SIZE) {
446       log::error("Malformated link quality format, len={}", len);
447       return;
448     }
449 
450     STREAM_TO_UINT8(status, stream);
451     if (status != HCI_SUCCESS) {
452       log::error("Failed to Read ISO Link Quality, status: 0x{:x}", status);
453       return;
454     }
455 
456     STREAM_TO_UINT16(conn_handle, stream);
457 
458     iso_base* iso = GetIsoIfKnown(conn_handle);
459     if (iso == nullptr) {
460       /* That could happen when ACL has been disconnected while waiting on the
461        * read respose */
462       log::warn("Invalid connection handle: {}", conn_handle);
463       return;
464     }
465 
466     STREAM_TO_UINT32(txUnackedPackets, stream);
467     STREAM_TO_UINT32(txFlushedPackets, stream);
468     STREAM_TO_UINT32(txLastSubeventPackets, stream);
469     STREAM_TO_UINT32(retransmittedPackets, stream);
470     STREAM_TO_UINT32(crcErrorPackets, stream);
471     STREAM_TO_UINT32(rxUnreceivedPackets, stream);
472     STREAM_TO_UINT32(duplicatePackets, stream);
473 
474     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
475     cig_callbacks_->OnIsoLinkQualityRead(
476             conn_handle, iso->cig_id, txUnackedPackets, txFlushedPackets, txLastSubeventPackets,
477             retransmittedPackets, crcErrorPackets, rxUnreceivedPackets, duplicatePackets);
478   }
479 
read_iso_link_qualityiso_impl480   void read_iso_link_quality(uint16_t iso_handle) {
481     iso_base* iso = GetIsoIfKnown(iso_handle);
482     if (iso == nullptr) {
483       log::error("No such iso connection: 0x{:x}", iso_handle);
484       return;
485     }
486 
487     btsnd_hcic_read_iso_link_quality(iso_handle, base::BindOnce(&iso_impl::on_iso_link_quality_read,
488                                                                 weak_factory_.GetWeakPtr()));
489   }
490 
prepare_hci_packetiso_impl491   BT_HDR* prepare_hci_packet(uint16_t iso_handle, uint16_t seq_nb, uint16_t data_len) {
492     /* Add 2 for packet seq., 2 for length */
493     uint16_t iso_data_load_len = data_len + 4;
494 
495     /* Add 2 for handle, 2 for length */
496     uint16_t iso_full_len = iso_data_load_len + 4;
497     BT_HDR* packet = (BT_HDR*)osi_malloc(iso_full_len + sizeof(BT_HDR));
498     packet->len = iso_full_len;
499     packet->offset = 0;
500     packet->event = MSG_STACK_TO_HC_HCI_ISO;
501     packet->layer_specific = 0;
502 
503     uint8_t* packet_data = packet->data;
504     UINT16_TO_STREAM(packet_data, iso_handle);
505     UINT16_TO_STREAM(packet_data, iso_data_load_len);
506 
507     UINT16_TO_STREAM(packet_data, seq_nb);
508     UINT16_TO_STREAM(packet_data, data_len);
509 
510     return packet;
511   }
512 
send_iso_dataiso_impl513   void send_iso_data(uint16_t iso_handle, const uint8_t* data, uint16_t data_len) {
514     iso_base* iso = GetIsoIfKnown(iso_handle);
515     log::assert_that(iso != nullptr, "No such iso connection handle: 0x{:x}", iso_handle);
516 
517     if (!(iso->state_flags & kStateFlagIsBroadcast)) {
518       if (!(iso->state_flags & kStateFlagIsConnected)) {
519         log::warn("Cis handle: 0x{:x} not established", iso_handle);
520         return;
521       }
522     }
523 
524     if (!(iso->state_flags & kStateFlagHasDataPathSet)) {
525       log::warn("Data path not set for handle: 0x{:04x}", iso_handle);
526       return;
527     }
528 
529     /* Calculate sequence number for the ISO data packet.
530      * It should be incremented by 1 every SDU Interval.
531      */
532     uint16_t seq_nb = iso->sync_info.tx_seq_nb;
533     iso->sync_info.tx_seq_nb = (seq_nb + 1) & 0xffff;
534 
535     if (iso_credits_ == 0 || data_len > iso_buffer_size_) {
536       iso->cr_stats.credits_underflow_bytes += data_len;
537       iso->cr_stats.credits_underflow_count++;
538       iso->cr_stats.credits_last_underflow_us = bluetooth::common::time_get_os_boottime_us();
539 
540       log::warn(", dropping ISO packet, len: {}, iso credits: {}, iso handle: 0x{:x}",
541                 static_cast<int>(data_len), static_cast<int>(iso_credits_), iso_handle);
542       return;
543     }
544 
545     iso_credits_--;
546     iso->used_credits++;
547 
548     BT_HDR* packet = prepare_hci_packet(iso_handle, seq_nb, data_len);
549     memcpy(packet->data + kIsoHeaderWithoutTsLen, data, data_len);
550     auto hci = bluetooth::shim::hci_layer_get_interface();
551     packet->event = MSG_STACK_TO_HC_HCI_ISO | 0x0001;
552     hci->transmit_downward(packet, iso_buffer_size_);
553   }
554 
process_cis_est_pktiso_impl555   void process_cis_est_pkt(uint8_t len, uint8_t* data) {
556     cis_establish_cmpl_evt evt;
557 
558     log::assert_that(len == 28, "Invalid packet length: {}", len);
559     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
560 
561     STREAM_TO_UINT8(evt.status, data);
562     STREAM_TO_UINT16(evt.cis_conn_hdl, data);
563 
564     auto cis = GetCisIfKnown(evt.cis_conn_hdl);
565     log::assert_that(cis != nullptr, "No such cis: {}", evt.cis_conn_hdl);
566 
567     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[evt.cis_conn_hdl], "CIS established event",
568                    base::StringPrintf("cis_handle:0x%04x status:%s", evt.cis_conn_hdl,
569                                       hci_error_code_text((tHCI_STATUS)(evt.status)).c_str()));
570 
571     STREAM_TO_UINT24(evt.cig_sync_delay, data);
572     STREAM_TO_UINT24(evt.cis_sync_delay, data);
573     STREAM_TO_UINT24(evt.trans_lat_mtos, data);
574     STREAM_TO_UINT24(evt.trans_lat_stom, data);
575     STREAM_TO_UINT8(evt.phy_mtos, data);
576     STREAM_TO_UINT8(evt.phy_stom, data);
577     STREAM_TO_UINT8(evt.nse, data);
578     STREAM_TO_UINT8(evt.bn_mtos, data);
579     STREAM_TO_UINT8(evt.bn_stom, data);
580     STREAM_TO_UINT8(evt.ft_mtos, data);
581     STREAM_TO_UINT8(evt.ft_stom, data);
582     STREAM_TO_UINT16(evt.max_pdu_mtos, data);
583     STREAM_TO_UINT16(evt.max_pdu_stom, data);
584     STREAM_TO_UINT16(evt.iso_itv, data);
585 
586     if (evt.status == HCI_SUCCESS) {
587       cis->state_flags |= kStateFlagIsConnected;
588     } else {
589       cis_hdl_to_addr.erase(evt.cis_conn_hdl);
590     }
591 
592     cis->state_flags &= ~kStateFlagIsConnecting;
593 
594     evt.cig_id = cis->cig_id;
595     cig_callbacks_->OnCisEvent(kIsoEventCisEstablishCmpl, &evt);
596   }
597 
disconnection_completeiso_impl598   void disconnection_complete(uint16_t handle, uint8_t reason) {
599     /* Check if this is an ISO handle */
600     auto cis = GetCisIfKnown(handle);
601     if (cis == nullptr) {
602       return;
603     }
604 
605     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
606 
607     log::info("flags: {}", cis->state_flags);
608 
609     BTM_LogHistory(kBtmLogTag, cis_hdl_to_addr[handle], "CIS disconnected",
610                    base::StringPrintf("cis_handle:0x%04x, reason:%s", handle,
611                                       hci_error_code_text((tHCI_REASON)(reason)).c_str()));
612     cis_hdl_to_addr.erase(handle);
613 
614     if (cis->state_flags & kStateFlagIsConnected || cis->state_flags & kStateFlagIsCancelled) {
615       cis_disconnected_evt evt = {
616               .reason = reason,
617               .cig_id = cis->cig_id,
618               .cis_conn_hdl = handle,
619       };
620 
621       cig_callbacks_->OnCisEvent(kIsoEventCisDisconnected, &evt);
622       cis->state_flags &= ~kStateFlagIsConnected;
623       cis->state_flags &= ~kStateFlagIsCancelled;
624 
625       /* return used credits */
626       iso_credits_ += cis->used_credits;
627       cis->used_credits = 0;
628 
629       /* Data path is considered still valid, but can be reconfigured only once
630        * CIS is reestablished.
631        */
632     }
633   }
634 
handle_gd_num_completed_pktsiso_impl635   void handle_gd_num_completed_pkts(uint16_t handle, uint16_t credits) {
636     auto iter = conn_hdl_to_cis_map_.find(handle);
637     if (iter != conn_hdl_to_cis_map_.end()) {
638       iter->second->used_credits -= credits;
639       iso_credits_ += credits;
640       return;
641     }
642 
643     iter = conn_hdl_to_bis_map_.find(handle);
644     if (iter != conn_hdl_to_bis_map_.end()) {
645       iter->second->used_credits -= credits;
646       iso_credits_ += credits;
647     }
648   }
649 
process_create_big_cmpl_pktiso_impl650   void process_create_big_cmpl_pkt(uint8_t len, uint8_t* data) {
651     struct big_create_cmpl_evt evt;
652 
653     log::assert_that(len >= 18, "Invalid packet length: {}", len);
654     log::assert_that(big_callbacks_ != nullptr, "Invalid BIG callbacks");
655 
656     STREAM_TO_UINT8(evt.status, data);
657     STREAM_TO_UINT8(evt.big_id, data);
658     STREAM_TO_UINT24(evt.big_sync_delay, data);
659     STREAM_TO_UINT24(evt.transport_latency_big, data);
660     STREAM_TO_UINT8(evt.phy, data);
661     STREAM_TO_UINT8(evt.nse, data);
662     STREAM_TO_UINT8(evt.bn, data);
663     STREAM_TO_UINT8(evt.pto, data);
664     STREAM_TO_UINT8(evt.irc, data);
665     STREAM_TO_UINT16(evt.max_pdu, data);
666     STREAM_TO_UINT16(evt.iso_interval, data);
667 
668     uint8_t num_bis;
669     STREAM_TO_UINT8(num_bis, data);
670 
671     log::assert_that(num_bis != 0, "Bis count is 0");
672     log::assert_that(len == (18 + num_bis * sizeof(uint16_t)),
673                      "Invalid packet length: {}. Number of bis: {}", len, num_bis);
674 
675     for (auto i = 0; i < num_bis; ++i) {
676       uint16_t conn_handle;
677       STREAM_TO_UINT16(conn_handle, data);
678       evt.conn_handles.push_back(conn_handle);
679       log::info("received BIS conn_hdl {}", conn_handle);
680 
681       if (evt.status == HCI_SUCCESS) {
682         auto bis = std::unique_ptr<iso_bis>(new iso_bis());
683         bis->big_handle = evt.big_id;
684         bis->sdu_itv = last_big_create_req_sdu_itv_;
685         bis->sync_info = {.tx_seq_nb = 0, .rx_seq_nb = 0};
686         bis->used_credits = 0;
687         bis->state_flags = kStateFlagIsBroadcast;
688         conn_hdl_to_bis_map_[conn_handle] = std::move(bis);
689       }
690     }
691 
692     big_callbacks_->OnBigEvent(kIsoEventBigOnCreateCmpl, &evt);
693 
694     {
695       const std::lock_guard<std::mutex> lock(on_iso_traffic_active_callbacks_list_mutex_);
696       for (auto callbacks : on_iso_traffic_active_callbacks_list_) {
697         callbacks(true);
698       }
699     }
700   }
701 
process_terminate_big_cmpl_pktiso_impl702   void process_terminate_big_cmpl_pkt(uint8_t len, uint8_t* data) {
703     struct big_terminate_cmpl_evt evt;
704 
705     log::assert_that(len == 2, "Invalid packet length: {}", len);
706     log::assert_that(big_callbacks_ != nullptr, "Invalid BIG callbacks");
707 
708     STREAM_TO_UINT8(evt.big_id, data);
709     STREAM_TO_UINT8(evt.reason, data);
710 
711     bool is_known_handle = false;
712     auto bis_it = conn_hdl_to_bis_map_.cbegin();
713     while (bis_it != conn_hdl_to_bis_map_.cend()) {
714       if (bis_it->second->big_handle == evt.big_id) {
715         bis_it = conn_hdl_to_bis_map_.erase(bis_it);
716         is_known_handle = true;
717       } else {
718         ++bis_it;
719       }
720     }
721 
722     log::assert_that(is_known_handle, "No such big: {}", evt.big_id);
723     big_callbacks_->OnBigEvent(kIsoEventBigOnTerminateCmpl, &evt);
724 
725     {
726       const std::lock_guard<std::mutex> lock(on_iso_traffic_active_callbacks_list_mutex_);
727       for (auto callbacks : on_iso_traffic_active_callbacks_list_) {
728         callbacks(false);
729       }
730     }
731   }
732 
create_bigiso_impl733   void create_big(uint8_t big_id, struct big_create_params big_params) {
734     log::assert_that(!IsBigKnown(big_id), "Invalid big - already exists: {}", big_id);
735 
736     if (stack_config_get_interface()->get_pts_unencrypt_broadcast()) {
737       log::info("Force create broadcst without encryption for PTS test");
738       big_params.enc = 0;
739       big_params.enc_code = {0};
740     }
741 
742     last_big_create_req_sdu_itv_ = big_params.sdu_itv;
743     btsnd_hcic_create_big(big_id, big_params.adv_handle, big_params.num_bis, big_params.sdu_itv,
744                           big_params.max_sdu_size, big_params.max_transport_latency, big_params.rtn,
745                           big_params.phy, big_params.packing, big_params.framing, big_params.enc,
746                           big_params.enc_code);
747   }
748 
terminate_bigiso_impl749   void terminate_big(uint8_t big_id, uint8_t reason) {
750     log::assert_that(IsBigKnown(big_id), "No such big: {}", big_id);
751 
752     btsnd_hcic_term_big(big_id, reason);
753   }
754 
on_iso_eventiso_impl755   void on_iso_event(uint8_t code, uint8_t* packet, uint16_t packet_len) {
756     switch (code) {
757       case HCI_BLE_CIS_EST_EVT:
758         process_cis_est_pkt(packet_len, packet);
759         break;
760       case HCI_BLE_CREATE_BIG_CPL_EVT:
761         process_create_big_cmpl_pkt(packet_len, packet);
762         break;
763       case HCI_BLE_TERM_BIG_CPL_EVT:
764         process_terminate_big_cmpl_pkt(packet_len, packet);
765         break;
766       case HCI_BLE_CIS_REQ_EVT:
767         /* Not supported */
768         break;
769       case HCI_BLE_BIG_SYNC_EST_EVT:
770         /* Not supported */
771         break;
772       case HCI_BLE_BIG_SYNC_LOST_EVT:
773         /* Not supported */
774         break;
775       default:
776         log::error("Unhandled event code {}", code);
777     }
778   }
779 
handle_iso_dataiso_impl780   void handle_iso_data(BT_HDR* p_msg) {
781     const uint8_t* stream = p_msg->data;
782     cis_data_evt evt;
783     uint16_t handle, seq_nb;
784 
785     if (p_msg->len <= ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) ? kIsoHeaderWithTsLen
786                                                                         : kIsoHeaderWithoutTsLen)) {
787       return;
788     }
789 
790     log::assert_that(cig_callbacks_ != nullptr, "Invalid CIG callbacks");
791 
792     STREAM_TO_UINT16(handle, stream);
793     evt.cis_conn_hdl = HCID_GET_HANDLE(handle);
794 
795     iso_base* iso = GetCisIfKnown(evt.cis_conn_hdl);
796     if (iso == nullptr) {
797       log::error(", received data for the non-registered CIS!");
798       return;
799     }
800 
801     STREAM_SKIP_UINT16(stream);
802     if (p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) {
803       STREAM_TO_UINT32(evt.ts, stream);
804     } else {
805       evt.ts = 0;
806     }
807 
808     STREAM_TO_UINT16(seq_nb, stream);
809 
810     uint16_t expected_seq_nb = iso->sync_info.rx_seq_nb;
811     iso->sync_info.rx_seq_nb = (seq_nb + 1) & 0xffff;
812 
813     evt.evt_lost = ((1 << 16) + seq_nb - expected_seq_nb) & 0xffff;
814     if (evt.evt_lost > 0) {
815       iso->evt_stats.evt_lost_count += evt.evt_lost;
816       iso->evt_stats.evt_last_lost_us = bluetooth::common::time_get_os_boottime_us();
817 
818       log::warn("{} packets lost.", evt.evt_lost);
819       iso->evt_stats.seq_nb_mismatch_count++;
820     }
821 
822     evt.p_msg = p_msg;
823     evt.cig_id = iso->cig_id;
824     evt.seq_nb = seq_nb;
825     cig_callbacks_->OnCisEvent(kIsoEventCisDataAvailable, &evt);
826   }
827 
GetCisIfKnowniso_impl828   iso_cis* GetCisIfKnown(uint16_t cis_conn_handle) {
829     auto cis_it = conn_hdl_to_cis_map_.find(cis_conn_handle);
830     return (cis_it != conn_hdl_to_cis_map_.end()) ? cis_it->second.get() : nullptr;
831   }
832 
GetBisIfKnowniso_impl833   iso_bis* GetBisIfKnown(uint16_t bis_conn_handle) {
834     auto bis_it = conn_hdl_to_bis_map_.find(bis_conn_handle);
835     return (bis_it != conn_hdl_to_bis_map_.end()) ? bis_it->second.get() : nullptr;
836   }
837 
GetIsoIfKnowniso_impl838   iso_base* GetIsoIfKnown(uint16_t iso_handle) {
839     struct iso_base* iso = GetCisIfKnown(iso_handle);
840     return (iso != nullptr) ? iso : GetBisIfKnown(iso_handle);
841   }
842 
IsCigKnowniso_impl843   bool IsCigKnown(uint8_t cig_id) const {
844     auto const cis_it =
845             std::find_if(conn_hdl_to_cis_map_.cbegin(), conn_hdl_to_cis_map_.cend(),
846                          [&cig_id](auto& kv_pair) { return kv_pair.second->cig_id == cig_id; });
847     return cis_it != conn_hdl_to_cis_map_.cend();
848   }
849 
IsBigKnowniso_impl850   bool IsBigKnown(uint8_t big_id) const {
851     auto bis_it =
852             std::find_if(conn_hdl_to_bis_map_.cbegin(), conn_hdl_to_bis_map_.cend(),
853                          [&big_id](auto& kv_pair) { return kv_pair.second->big_handle == big_id; });
854     return bis_it != conn_hdl_to_bis_map_.cend();
855   }
856 
dump_credits_statsiso_impl857   static void dump_credits_stats(int fd, const iso_base::credits_stats& stats) {
858     uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
859 
860     dprintf(fd, "        Credits Stats:\n");
861     dprintf(fd, "          Credits underflow (count): %zu\n", stats.credits_underflow_count);
862     dprintf(fd, "          Credits underflow (bytes): %zu\n", stats.credits_underflow_bytes);
863     dprintf(fd, "          Last underflow time ago (ms): %llu\n",
864             (stats.credits_last_underflow_us > 0
865                      ? (unsigned long long)(now_us - stats.credits_last_underflow_us) / 1000
866                      : 0llu));
867   }
868 
dump_event_statsiso_impl869   static void dump_event_stats(int fd, const iso_base::event_stats& stats) {
870     uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
871 
872     dprintf(fd, "        Event Stats:\n");
873     dprintf(fd, "          Sequence number mismatch (count): %zu\n", stats.seq_nb_mismatch_count);
874     dprintf(fd, "          Event lost (count): %zu\n", stats.evt_lost_count);
875     dprintf(fd, "          Last event lost time ago (ms): %llu\n",
876             (stats.evt_last_lost_us > 0
877                      ? (unsigned long long)(now_us - stats.evt_last_lost_us) / 1000
878                      : 0llu));
879   }
880 
dumpiso_impl881   void dump(int fd) const {
882     dprintf(fd, "  ----------------\n ");
883     dprintf(fd, "  ISO Manager:\n");
884     dprintf(fd, "    Available credits: %d\n", iso_credits_.load());
885     dprintf(fd, "    Controller buffer size: %d\n", iso_buffer_size_);
886     dprintf(fd, "    Num of ISO traffic callbacks: %lu\n",
887             static_cast<unsigned long>(on_iso_traffic_active_callbacks_list_.size()));
888     dprintf(fd, "    CISes:\n");
889     for (auto const& cis_pair : conn_hdl_to_cis_map_) {
890       dprintf(fd, "      CIS Connection handle: %d\n", cis_pair.first);
891       dprintf(fd, "        CIG ID: %d\n", cis_pair.second->cig_id);
892       dprintf(fd, "        Used Credits: %d\n", cis_pair.second->used_credits.load());
893       dprintf(fd, "        SDU Interval: %d\n", cis_pair.second->sdu_itv);
894       dprintf(fd, "        State Flags: 0x%02hx\n", cis_pair.second->state_flags.load());
895       dump_credits_stats(fd, cis_pair.second->cr_stats);
896       dump_event_stats(fd, cis_pair.second->evt_stats);
897     }
898     dprintf(fd, "    BISes:\n");
899     for (auto const& cis_pair : conn_hdl_to_bis_map_) {
900       dprintf(fd, "      BIS Connection handle: %d\n", cis_pair.first);
901       dprintf(fd, "        BIG Handle: %d\n", cis_pair.second->big_handle);
902       dprintf(fd, "        Used Credits: %d\n", cis_pair.second->used_credits.load());
903       dprintf(fd, "        SDU Interval: %d\n", cis_pair.second->sdu_itv);
904       dprintf(fd, "        State Flags: 0x%02hx\n", cis_pair.second->state_flags.load());
905       dump_credits_stats(fd, cis_pair.second->cr_stats);
906       dump_event_stats(fd, cis_pair.second->evt_stats);
907     }
908     dprintf(fd, "  ----------------\n ");
909   }
910 
911   std::map<uint16_t, std::unique_ptr<iso_cis>> conn_hdl_to_cis_map_;
912   std::map<uint16_t, std::unique_ptr<iso_bis>> conn_hdl_to_bis_map_;
913   std::map<uint16_t, RawAddress> cis_hdl_to_addr;
914 
915   std::atomic_uint16_t iso_credits_;
916   uint16_t iso_buffer_size_;
917   uint32_t last_big_create_req_sdu_itv_;
918 
919   CigCallbacks* cig_callbacks_ = nullptr;
920   BigCallbacks* big_callbacks_ = nullptr;
921   std::mutex on_iso_traffic_active_callbacks_list_mutex_;
922   std::list<void (*)(bool)> on_iso_traffic_active_callbacks_list_;
923   base::WeakPtrFactory<iso_impl> weak_factory_{this};
924 };
925 
926 }  // namespace iso_manager
927 }  // namespace hci
928 }  // namespace bluetooth
929