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