1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 17 #include "pw_bluetooth_sapphire/internal/host/l2cap/command_handler.h" 18 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h" 19 20 namespace bt::l2cap::internal { 21 class LowEnergyCommandHandler final : public CommandHandler { 22 public: 23 class LeCreditBasedConnectionResponse final : public Response { 24 public: 25 using PayloadT = LECreditBasedConnectionResponsePayload; 26 static constexpr const char* kName = "LE Credit Based Connection Response"; 27 28 using Response::Response; // Inherit ctor 29 bool Decode(const ByteBuffer& payload_buf); 30 destination_cid()31 ChannelId destination_cid() const { return destination_cid_; } mtu()32 uint16_t mtu() const { return mtu_; } mps()33 uint16_t mps() const { return mps_; } initial_credits()34 uint16_t initial_credits() const { return initial_credits_; } result()35 LECreditBasedConnectionResult result() const { return result_; } 36 37 private: 38 friend class LowEnergyCommandHandler; 39 40 ChannelId destination_cid_; 41 uint16_t mtu_; 42 uint16_t mps_; 43 uint16_t initial_credits_; 44 LECreditBasedConnectionResult result_; 45 }; 46 47 class ConnectionParameterUpdateResponse final : public Response { 48 public: 49 using PayloadT = ConnectionParameterUpdateResponsePayload; 50 static constexpr const char* kName = "Connection Parameter Update Response"; 51 52 using Response::Response; // Inherit ctor 53 bool Decode(const ByteBuffer& payload_buf); 54 result()55 ConnectionParameterUpdateResult result() const { return result_; } 56 57 private: 58 friend class LowEnergyCommandHandler; 59 60 ConnectionParameterUpdateResult result_; 61 }; 62 63 class ConnectionParameterUpdateResponder final : public Responder { 64 public: 65 explicit ConnectionParameterUpdateResponder( 66 SignalingChannel::Responder* sig_responder); 67 68 void Send(ConnectionParameterUpdateResult result); 69 }; 70 71 class LeCreditBasedConnectionResponder final : public Responder { 72 public: 73 explicit LeCreditBasedConnectionResponder( 74 SignalingChannel::Responder* sig_responder); 75 76 void Send(ChannelId destination_cid, 77 uint16_t mtu, 78 uint16_t mps, 79 uint16_t initial_credits, 80 LECreditBasedConnectionResult result); 81 }; 82 83 // |sig| must be valid for the lifetime of this object. 84 // |command_failed_callback| is called if an outbound request timed out with 85 // RTX or ERTX timers after retransmission (if configured). The call may come 86 // after the lifetime of this object. 87 explicit LowEnergyCommandHandler( 88 SignalingChannelInterface* sig, 89 fit::closure request_fail_callback = nullptr); 90 ~LowEnergyCommandHandler() = default; 91 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyCommandHandler); 92 93 // Outbound request sending methods. Response callbacks are required to be 94 // non-empty. The callbacks are wrapped and moved into the SignalingChannel 95 // and may outlive LowEnergyCommandHandler. 96 97 using SendLeCreditBasedConnectionRequestCallback = 98 fit::function<void(const LeCreditBasedConnectionResponse& rsp)>; 99 bool SendLeCreditBasedConnectionRequest( 100 uint16_t psm, 101 uint16_t cid, 102 uint16_t mtu, 103 uint16_t mps, 104 uint16_t credits, 105 SendLeCreditBasedConnectionRequestCallback cb); 106 107 using ConnectionParameterUpdateResponseCallback = 108 fit::function<void(const ConnectionParameterUpdateResponse& rsp)>; 109 bool SendConnectionParameterUpdateRequest( 110 uint16_t interval_min, 111 uint16_t interval_max, 112 uint16_t peripheral_latency, 113 uint16_t timeout_multiplier, 114 ConnectionParameterUpdateResponseCallback cb); 115 116 // Inbound request delegate registration methods. The callbacks are wrapped 117 // and moved into the SignalingChannel and may outlive 118 // LowEnergyCommandHandler. It is expected that any request delegates 119 // registered will span the lifetime of its signaling channel and hence link, 120 // so no unregistration is provided. However each call to register will 121 // replace any currently registered request delegate. 122 123 using ConnectionParameterUpdateRequestCallback = 124 fit::function<void(uint16_t interval_min, 125 uint16_t interval_max, 126 uint16_t peripheral_latency, 127 uint16_t timeout_multiplier, 128 ConnectionParameterUpdateResponder* responder)>; 129 void ServeConnectionParameterUpdateRequest( 130 ConnectionParameterUpdateRequestCallback callback); 131 132 using LeCreditBasedConnectionRequestCallback = 133 fit::function<void(uint16_t psm, 134 uint16_t cid, 135 uint16_t mtu, 136 uint16_t mps, 137 uint16_t credits, 138 LeCreditBasedConnectionResponder* responder)>; 139 void ServeLeCreditBasedConnectionRequest( 140 LeCreditBasedConnectionRequestCallback callback); 141 }; 142 } // namespace bt::l2cap::internal 143