blob: 39e8476ac96d6b43bb56ca4f64238951cf534ad8 [file] [log] [blame]
// Copyright 2020 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.
#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_TYPES_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_TYPES_H_
#include <lib/fit/function.h>
#include <optional>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/le_connection_parameters.h"
#include "src/connectivity/bluetooth/core/bt-host/hci-spec/protocol.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/status.h"
#include "src/connectivity/bluetooth/core/bt-host/sm/types.h"
namespace bt::l2cap {
class Channel;
// Callback invoked when a channel has been created or when an error occurs during channel creation
// (in which case the channel will be nullptr).
using ChannelCallback = fit::function<void(fbl::RefPtr<Channel>)>;
// Callback invoked when a logical link should be closed due to an error.
using LinkErrorCallback = fit::closure;
// Callback called to notify LE preferred connection parameters during the "LE
// Connection Parameter Update" procedure.
using LEConnectionParameterUpdateCallback =
fit::function<void(const hci::LEPreferredConnectionParameters&)>;
// Callback called when response received to LE signaling channel Connection Parameters Update
// Request. |accepted| indicates whether the parameters were accepted by the peer.
using ConnectionParameterUpdateRequestCallback = fit::function<void(bool accepted)>;
// Callback used to deliver LE fixed channels that are created when a LE link is
// registered with L2CAP.
using LEFixedChannelsCallback =
fit::function<void(fbl::RefPtr<Channel> att, fbl::RefPtr<Channel> smp)>;
// Callback used to request a security upgrade for an active logical link.
// Invokes its |callback| argument with the result of the operation.
using SecurityUpgradeCallback = fit::function<void(
hci::ConnectionHandle ll_handle, sm::SecurityLevel level, sm::StatusCallback callback)>;
// Channel configuration parameters specified by higher layers.
struct ChannelParameters {
std::optional<ChannelMode> mode;
// MTU
std::optional<uint16_t> max_rx_sdu_size;
std::optional<zx::duration> flush_timeout;
bool operator==(const ChannelParameters& rhs) const {
return mode == rhs.mode && max_rx_sdu_size == rhs.max_rx_sdu_size &&
flush_timeout == rhs.flush_timeout;
}
std::string ToString() const {
auto mode_string = mode.has_value() ? fxl::StringPrintf("%#.2x", static_cast<uint8_t>(*mode))
: std::string("nullopt");
auto sdu_string = max_rx_sdu_size.has_value() ? fxl::StringPrintf("%hu", *max_rx_sdu_size)
: std::string("nullopt");
auto flush_timeout_string = flush_timeout
? fxl::StringPrintf("%ldms", flush_timeout->to_msecs())
: std::string("nullopt");
return fxl::StringPrintf("ChannelParameters{mode: %s, max_rx_sdu_size: %s, flush_timeout: %s}",
mode_string.c_str(), sdu_string.c_str(), flush_timeout_string.c_str());
};
};
// Convenience struct for passsing around information about an opened channel.
// For example, this is useful when describing the L2CAP channel underlying a zx::socket.
struct ChannelInfo {
ChannelInfo() = default;
static ChannelInfo MakeBasicMode(uint16_t max_rx_sdu_size, uint16_t max_tx_sdu_size,
std::optional<PSM> psm = std::nullopt,
std::optional<zx::duration> flush_timeout = std::nullopt) {
return ChannelInfo(ChannelMode::kBasic, max_rx_sdu_size, max_tx_sdu_size, 0, 0, 0, psm,
flush_timeout);
}
static ChannelInfo MakeEnhancedRetransmissionMode(
uint16_t max_rx_sdu_size, uint16_t max_tx_sdu_size, uint8_t n_frames_in_tx_window,
uint8_t max_transmissions, uint16_t max_tx_pdu_payload_size,
std::optional<PSM> psm = std::nullopt,
std::optional<zx::duration> flush_timeout = std::nullopt) {
return ChannelInfo(ChannelMode::kEnhancedRetransmission, max_rx_sdu_size, max_tx_sdu_size,
n_frames_in_tx_window, max_transmissions, max_tx_pdu_payload_size, psm,
flush_timeout);
}
ChannelInfo(ChannelMode mode, uint16_t max_rx_sdu_size, uint16_t max_tx_sdu_size,
uint8_t n_frames_in_tx_window, uint8_t max_transmissions,
uint16_t max_tx_pdu_payload_size, std::optional<PSM> psm = std::nullopt,
std::optional<zx::duration> flush_timeout = std::nullopt)
: mode(mode),
max_rx_sdu_size(max_rx_sdu_size),
max_tx_sdu_size(max_tx_sdu_size),
n_frames_in_tx_window(n_frames_in_tx_window),
max_transmissions(max_transmissions),
max_tx_pdu_payload_size(max_tx_pdu_payload_size),
psm(psm),
flush_timeout(flush_timeout) {}
ChannelMode mode;
uint16_t max_rx_sdu_size;
uint16_t max_tx_sdu_size;
// For Enhanced Retransmission Mode only. See Core Spec v5.0 Vol 3, Part A, Sec 5.4 for details on
// each field. Values are not meaningful if mode = ChannelMode::kBasic.
uint8_t n_frames_in_tx_window;
uint8_t max_transmissions;
uint16_t max_tx_pdu_payload_size;
// PSM of the service the channel is used for.
std::optional<PSM> psm;
// If present, the channel's packets will be marked as flushable. The value will be used to
// configure the link's automatic flush timeout.
std::optional<zx::duration> flush_timeout;
};
// Data stored for services registered by higher layers.
template <typename ChannelCallbackT>
struct ServiceInfo {
ServiceInfo(ChannelParameters params, ChannelCallbackT cb)
: channel_params(params), channel_cb(std::move(cb)) {}
ServiceInfo(ServiceInfo&&) = default;
ServiceInfo& operator=(ServiceInfo&&) = default;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ServiceInfo);
// Preferred channel configuration parameters for new channels for this service.
ChannelParameters channel_params;
// Callback for forwarding new channels to locally-hosted service.
ChannelCallbackT channel_cb;
};
} // namespace bt::l2cap
#endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_TYPES_H_