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