| // 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_SM_PAIRING_CHANNEL_H_ |
| #define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SM_PAIRING_CHANNEL_H_ |
| |
| #include <unordered_map> |
| |
| #include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h" |
| #include "src/connectivity/bluetooth/core/bt-host/l2cap/channel.h" |
| #include "src/connectivity/bluetooth/core/bt-host/l2cap/scoped_channel.h" |
| #include "src/connectivity/bluetooth/core/bt-host/sm/packet.h" |
| #include "src/connectivity/bluetooth/core/bt-host/sm/util.h" |
| #include "src/lib/fxl/memory/weak_ptr.h" |
| |
| namespace bt::sm { |
| |
| // Bridge class for the SMP L2CAP channel, which implements SM-specific functionality on top of |
| // existing L2CAP functionality. Besides this SM-specific functionality, also allows runtime |
| // modification of L2CAP event callbacks by changing the PairingChannel::Handler pointer. |
| |
| class PairingChannel { |
| public: |
| // Interface for receiving L2CAP channel events. |
| class Handler { |
| public: |
| virtual ~Handler() = default; |
| virtual void OnRxBFrame(ByteBufferPtr) = 0; |
| virtual void OnChannelClosed() = 0; |
| }; |
| |
| // Initializes this PairingChannel with the L2CAP SMP fixed channel that this class wraps and the |
| // specified timer reset method. For use in production code. |
| PairingChannel(fbl::RefPtr<l2cap::Channel> chan, fit::closure timer_resetter); |
| |
| // Initializes this PairingChannel with a no-op timer reset method. Only for use in tests of |
| // classes which do not depend on the timer reset behavior. |
| explicit PairingChannel(fbl::RefPtr<l2cap::Channel> chan); |
| |
| // For setting the new handler, expected to be used when switching phases. PairingChannel is not |
| // fully initialized until SetChannelHandler has been called with a valid Handler. This two-phase |
| // initialization exists because concrete Handlers are expected to depend on PairingChannels. |
| void SetChannelHandler(fxl::WeakPtr<Handler> new_handler); |
| |
| // Wrapper which encapsulates some of the boilerplate involved in sending an SMP object. |
| template <typename PayloadType> |
| void SendMessage(Code message_code, const PayloadType& payload) { |
| auto kExpectedSize = kCodeToPayloadSize.find(message_code); |
| ZX_ASSERT(kExpectedSize != kCodeToPayloadSize.end()); |
| ZX_ASSERT(sizeof(PayloadType) == kExpectedSize->second); |
| auto pdu = util::NewPdu(sizeof(PayloadType)); |
| PacketWriter writer(message_code, pdu.get()); |
| *writer.mutable_payload<PayloadType>() = payload; |
| chan_->Send(std::move(pdu)); |
| reset_timer_(); |
| } |
| |
| fxl::WeakPtr<PairingChannel> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } |
| |
| bool SupportsSecureConnections() const { |
| return chan_->max_rx_sdu_size() >= kLeSecureConnectionsMtu && |
| chan_->max_tx_sdu_size() >= kLeSecureConnectionsMtu; |
| } |
| |
| void SignalLinkError() { chan_->SignalLinkError(); } |
| hci::Connection::LinkType link_type() const { return chan_->link_type(); } |
| ~PairingChannel() = default; |
| |
| private: |
| // Used to delegate the L2CAP callbacks to the current handler |
| void OnRxBFrame(ByteBufferPtr ptr); |
| void OnChannelClosed(); |
| |
| // The L2CAP Channel this class wraps. Uses a ScopedChannel because a PairingChannel is expected |
| // to own the lifetime of the underlying L2CAP channel. |
| l2cap::ScopedChannel chan_; |
| |
| // Per v5.2 Vol. 3 Part H 3.4, "The Security Manager Timer shall be reset when an L2CAP SMP |
| // command is queued for transmission". This closure signals this reset to occur. |
| fit::closure reset_timer_; |
| |
| // L2CAP channel events are delegated to this handler. |
| fxl::WeakPtr<Handler> handler_; |
| |
| fxl::WeakPtrFactory<PairingChannel> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(PairingChannel); |
| }; |
| |
| } // namespace bt::sm |
| |
| #endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_SM_PAIRING_CHANNEL_H_ |