[bt][transport] Remove use of zx_packet_signal::count
Remove use of zx_packet_signal::count in CommandChannel, AclDataChannel,
and ScoDataChannel. This field is deprecated and hardcoded to 1 for
channel signals.
Bug: 50601
Test: fx test bt-host-transport-tests
Change-Id: I13f53119a5b40d2feb12a8fba44babd61eb3c7da
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/664386
Reviewed-by: Xo Wang <xow@google.com>
Commit-Queue: Ben Lawson <benlawson@google.com>
diff --git a/pw_bluetooth_sapphire/host/transport/acl_data_channel.cc b/pw_bluetooth_sapphire/host/transport/acl_data_channel.cc
index 31dd407..31dade1 100644
--- a/pw_bluetooth_sapphire/host/transport/acl_data_channel.cc
+++ b/pw_bluetooth_sapphire/host/transport/acl_data_channel.cc
@@ -7,6 +7,7 @@
#include <endian.h>
#include <lib/async/cpp/time.h>
#include <lib/async/default.h>
+#include <lib/fit/defer.h>
#include <lib/sys/inspect/cpp/component.h>
#include <zircon/assert.h>
#include <zircon/status.h>
@@ -874,33 +875,39 @@
ZX_DEBUG_ASSERT(async_get_default_dispatcher() == io_dispatcher_);
ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_READABLE);
- for (size_t count = 0; count < signal->count; count++) {
- TRACE_DURATION("bluetooth", "AclDataChannelImpl::OnChannelReady read packet");
- if (!rx_callback_) {
- continue;
+ // The wait needs to be restarted after every signal.
+ auto defer_wait = fit::defer([wait, dispatcher] {
+ zx_status_t status = wait->Begin(dispatcher);
+ if (status != ZX_OK) {
+ bt_log(ERROR, "hci", "wait error: %s", zx_status_get_string(status));
}
- // Allocate a buffer for the event. Since we don't know the size beforehand
- // we allocate the largest possible buffer.
- auto packet = ACLDataPacket::New(slab_allocators::kLargeACLDataPayloadSize);
- if (!packet) {
- bt_log(ERROR, "hci", "failed to allocate buffer received ACL data packet!");
- return;
- }
- zx_status_t status = ReadAclDataPacketFromChannel(channel_, packet);
- if (status == ZX_ERR_INVALID_ARGS) {
- continue;
- } else if (status != ZX_OK) {
- return;
- }
- {
- TRACE_DURATION("bluetooth", "AclDataChannelImpl->rx_callback_");
- rx_callback_(std::move(packet));
- }
+ });
+
+ if (!rx_callback_) {
+ return;
}
- status = wait->Begin(dispatcher);
+ // Allocate a buffer for the event. Since we don't know the size beforehand
+ // we allocate the largest possible buffer.
+ auto packet = ACLDataPacket::New(slab_allocators::kLargeACLDataPayloadSize);
+ if (!packet) {
+ bt_log(ERROR, "hci", "failed to allocate buffer received ACL data packet!");
+ defer_wait.cancel();
+ return;
+ }
+
+ status = ReadAclDataPacketFromChannel(channel_, packet);
+ if (status == ZX_ERR_INVALID_ARGS) {
+ return;
+ }
if (status != ZX_OK) {
- bt_log(ERROR, "hci", "wait error: %s", zx_status_get_string(status));
+ defer_wait.cancel();
+ return;
+ }
+
+ {
+ TRACE_DURATION("bluetooth", "AclDataChannelImpl->rx_callback_");
+ rx_callback_(std::move(packet));
}
}
diff --git a/pw_bluetooth_sapphire/host/transport/command_channel.cc b/pw_bluetooth_sapphire/host/transport/command_channel.cc
index f5c5e83..6858411 100644
--- a/pw_bluetooth_sapphire/host/transport/command_channel.cc
+++ b/pw_bluetooth_sapphire/host/transport/command_channel.cc
@@ -6,6 +6,7 @@
#include <endian.h>
#include <lib/async/default.h>
+#include <lib/fit/defer.h>
#include <lib/trace/event.h>
#include <zircon/assert.h>
#include <zircon/status.h>
@@ -630,7 +631,7 @@
zx_status_t status, const zx_packet_signal_t* signal) {
ZX_DEBUG_ASSERT(signal->observed & ZX_CHANNEL_READABLE);
- TRACE_DURATION("bluetooth", "CommandChannel::OnChannelReady", "signal->count", signal->count);
+ TRACE_DURATION("bluetooth", "CommandChannel::OnChannelReady");
if (status != ZX_OK) {
bt_log(DEBUG, "hci", "channel error: %s", zx_status_get_string(status));
@@ -643,35 +644,35 @@
// TODO(armansito): We could first try to read into a small buffer and retry if the syscall
// returns ZX_ERR_BUFFER_TOO_SMALL. Not sure if the second syscall would be worth it but
// investigate.
- for (size_t count = 0; count < signal->count; count++) {
- std::unique_ptr<EventPacket> packet =
- EventPacket::New(slab_allocators::kLargeControlPayloadSize);
- if (!packet) {
- bt_log(ERROR, "hci", "failed to allocate event packet!");
- return;
- }
-
- zx_status_t status = ReadEventPacketFromChannel(channel_, packet);
- if (status == ZX_ERR_INVALID_ARGS) {
- continue;
- }
-
- if (status != ZX_OK) {
- return;
- }
-
- if (packet->event_code() == hci_spec::kCommandStatusEventCode ||
- packet->event_code() == hci_spec::kCommandCompleteEventCode) {
- UpdateTransaction(std::move(packet));
- TrySendQueuedCommands();
- } else {
- NotifyEventHandler(std::move(packet));
- }
+ std::unique_ptr<EventPacket> packet = EventPacket::New(slab_allocators::kLargeControlPayloadSize);
+ if (!packet) {
+ bt_log(ERROR, "hci", "failed to allocate event packet!");
+ return;
}
- status = wait->Begin(dispatcher);
+ // The wait needs to be restarted after every signal.
+ auto defer_wait = fit::defer([wait, dispatcher] {
+ zx_status_t status = wait->Begin(dispatcher);
+ if (status != ZX_OK) {
+ bt_log(ERROR, "hci", "wait error: %s", zx_status_get_string(status));
+ }
+ });
+
+ status = ReadEventPacketFromChannel(channel_, packet);
+ if (status == ZX_ERR_INVALID_ARGS) {
+ return;
+ }
if (status != ZX_OK) {
- bt_log(DEBUG, "hci", "wait error: %s", zx_status_get_string(status));
+ defer_wait.cancel();
+ return;
+ }
+
+ if (packet->event_code() == hci_spec::kCommandStatusEventCode ||
+ packet->event_code() == hci_spec::kCommandCompleteEventCode) {
+ UpdateTransaction(std::move(packet));
+ TrySendQueuedCommands();
+ } else {
+ NotifyEventHandler(std::move(packet));
}
}
diff --git a/pw_bluetooth_sapphire/host/transport/sco_data_channel.cc b/pw_bluetooth_sapphire/host/transport/sco_data_channel.cc
index 9dfbc9d..4f7589a 100644
--- a/pw_bluetooth_sapphire/host/transport/sco_data_channel.cc
+++ b/pw_bluetooth_sapphire/host/transport/sco_data_channel.cc
@@ -5,6 +5,7 @@
#include "sco_data_channel.h"
#include <lib/async/default.h>
+#include <lib/fit/defer.h>
#include <zircon/status.h>
#include <fbl/ref_counted.h>
@@ -192,31 +193,33 @@
ZX_ASSERT(signal->observed & ZX_CHANNEL_READABLE);
- for (size_t count = 0; count < signal->count; count++) {
- fitx::result<zx_status_t, std::unique_ptr<ScoDataPacket>> result = ReadPacketFromChannel();
- if (result.is_error()) {
- // Ignore malformed packets.
- bt_log(ERROR, "hci", "ignoring packet due to read error: %s",
- zx_status_get_string(result.error_value()));
- continue;
+ // The wait needs to be restarted after every signal.
+ auto defer_wait = fit::defer([wait, dispatcher] {
+ zx_status_t status = wait->Begin(dispatcher);
+ if (status != ZX_OK) {
+ bt_log(ERROR, "hci", "wait error: %s", zx_status_get_string(status));
}
- auto conn_iter = connections_.find(letoh16(result.value()->connection_handle()));
- if (conn_iter == connections_.end()) {
- // Ignore inbound packets for connections that aren't registered. Unlike ACL, buffering data
- // received before a connection is registered is unnecessary for SCO (it's realtime and
- // not expected to be reliable).
- bt_log(DEBUG, "hci", "ignoring inbound SCO packet for unregistered connection: %#.4x",
- result.value()->connection_handle());
- continue;
- }
- conn_iter->second.connection->ReceiveInboundPacket(std::move(result.value()));
+ });
+
+ fitx::result<zx_status_t, std::unique_ptr<ScoDataPacket>> result = ReadPacketFromChannel();
+ if (result.is_error()) {
+ // Ignore malformed packets.
+ bt_log(ERROR, "hci", "ignoring packet due to read error: %s",
+ zx_status_get_string(result.error_value()));
+ return;
}
- // The wait needs to be restarted after every signal.
- status = wait->Begin(dispatcher);
- if (status != ZX_OK) {
- bt_log(ERROR, "hci", "wait error: %s", zx_status_get_string(status));
+ auto conn_iter = connections_.find(letoh16(result.value()->connection_handle()));
+ if (conn_iter == connections_.end()) {
+ // Ignore inbound packets for connections that aren't registered. Unlike ACL, buffering data
+ // received before a connection is registered is unnecessary for SCO (it's realtime and
+ // not expected to be reliable).
+ bt_log(DEBUG, "hci", "ignoring inbound SCO packet for unregistered connection: %#.4x",
+ result.value()->connection_handle());
+ return;
}
+
+ conn_iter->second.connection->ReceiveInboundPacket(std::move(result.value()));
}
fitx::result<zx_status_t, std::unique_ptr<ScoDataPacket>>