blob: 4736f2707c1b8f797e30b653a781c5ae9b872948 [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/iso/iso_stream_manager.h"
namespace bt::iso {
IsoStreamManager::IsoStreamManager(hci_spec::ConnectionHandle handle,
hci::CommandChannel::WeakPtr cmd_channel)
: acl_handle_(handle), cmd_(cmd_channel), weak_self_(this) {
if (!cmd_.is_alive()) {
return;
}
auto self = GetWeakPtr();
cis_request_handler_ = cmd_->AddLEMetaEventHandler(
hci_spec::kLECISRequestSubeventCode,
[self = std::move(self)](const hci::EmbossEventPacket& event) {
if (!self.is_alive()) {
return hci::CommandChannel::EventCallbackResult::kRemove;
}
self->OnCisRequest(event);
return hci::CommandChannel::EventCallbackResult::kContinue;
});
}
IsoStreamManager::~IsoStreamManager() {
if (cmd_.is_alive()) {
cmd_->RemoveEventHandler(cis_request_handler_);
}
}
void IsoStreamManager::OnCisRequest(const hci::EmbossEventPacket& event) {
BT_ASSERT(event.event_code() == hci_spec::kLEMetaEventCode);
auto event_view =
event.view<pw::bluetooth::emboss::LECISRequestSubeventView>();
BT_ASSERT(event_view.le_meta_event().subevent_code().Read() ==
hci_spec::kLECISRequestSubeventCode);
hci_spec::ConnectionHandle request_handle =
event_view.acl_connection_handle().Read();
// Ignore any requests that are not intended for this connection.
if (request_handle != acl_handle_) {
bt_log(DEBUG,
"iso",
"ignoring incoming stream request for handle 0x%x (ours: 0x%x)",
request_handle,
acl_handle_);
return;
}
// For now, just reject all incoming requests.
RejectCisRequest(event_view);
}
void IsoStreamManager::RejectCisRequest(
const pw::bluetooth::emboss::LECISRequestSubeventView& event_view) {
hci_spec::ConnectionHandle cis_handle =
event_view.cis_connection_handle().Read();
auto command = hci::EmbossCommandPacket::New<
pw::bluetooth::emboss::LERejectCISRequestCommandWriter>(
hci_spec::kLERejectCISRequest);
auto cmd_view = command.view_t();
cmd_view.connection_handle().Write(cis_handle);
cmd_view.reason().Write(pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR);
cmd_->SendCommand(std::move(command),
[cis_handle](auto id, const hci::EventPacket& event) {
hci_is_error(event,
ERROR,
"bt-iso",
"reject CIS request failed for handle %#x",
cis_handle);
});
}
} // namespace bt::iso