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 #include "pw_bluetooth_sapphire/internal/host/l2cap/low_energy_command_handler.h"
16
17 namespace bt::l2cap::internal {
Decode(const ByteBuffer & payload_buf)18 bool LowEnergyCommandHandler::ConnectionParameterUpdateResponse::Decode(
19 const ByteBuffer& payload_buf) {
20 const auto result = le16toh(
21 static_cast<uint16_t>(payload_buf.ReadMember<&PayloadT::result>()));
22 result_ = ConnectionParameterUpdateResult{result};
23 return true;
24 }
25
26 LowEnergyCommandHandler::ConnectionParameterUpdateResponder::
ConnectionParameterUpdateResponder(SignalingChannel::Responder * sig_responder)27 ConnectionParameterUpdateResponder(
28 SignalingChannel::Responder* sig_responder)
29 : Responder(sig_responder) {}
30
Send(ConnectionParameterUpdateResult result)31 void LowEnergyCommandHandler::ConnectionParameterUpdateResponder::Send(
32 ConnectionParameterUpdateResult result) {
33 ConnectionParameterUpdateResponsePayload payload;
34 payload.result =
35 ConnectionParameterUpdateResult{htole16(static_cast<uint16_t>(result))};
36 sig_responder_->Send(BufferView(&payload, sizeof(payload)));
37 }
38
LowEnergyCommandHandler(SignalingChannelInterface * sig,fit::closure request_fail_callback)39 LowEnergyCommandHandler::LowEnergyCommandHandler(
40 SignalingChannelInterface* sig, fit::closure request_fail_callback)
41 : CommandHandler(sig, std::move(request_fail_callback)) {}
42
SendConnectionParameterUpdateRequest(uint16_t interval_min,uint16_t interval_max,uint16_t peripheral_latency,uint16_t timeout_multiplier,ConnectionParameterUpdateResponseCallback cb)43 bool LowEnergyCommandHandler::SendConnectionParameterUpdateRequest(
44 uint16_t interval_min,
45 uint16_t interval_max,
46 uint16_t peripheral_latency,
47 uint16_t timeout_multiplier,
48 ConnectionParameterUpdateResponseCallback cb) {
49 auto on_param_update_rsp =
50 BuildResponseHandler<ConnectionParameterUpdateResponse>(std::move(cb));
51
52 ConnectionParameterUpdateRequestPayload payload;
53 payload.interval_min = htole16(interval_min);
54 payload.interval_max = htole16(interval_max);
55 payload.peripheral_latency = htole16(peripheral_latency);
56 payload.timeout_multiplier = htole16(timeout_multiplier);
57
58 return sig()->SendRequest(kConnectionParameterUpdateRequest,
59 BufferView(&payload, sizeof(payload)),
60 std::move(on_param_update_rsp));
61 }
62
ServeConnectionParameterUpdateRequest(ConnectionParameterUpdateRequestCallback cb)63 void LowEnergyCommandHandler::ServeConnectionParameterUpdateRequest(
64 ConnectionParameterUpdateRequestCallback cb) {
65 auto on_param_update_req = [cb = std::move(cb)](
66 const ByteBuffer& request_payload,
67 SignalingChannel::Responder* sig_responder) {
68 if (request_payload.size() !=
69 sizeof(ConnectionParameterUpdateRequestPayload)) {
70 bt_log(DEBUG,
71 "l2cap-le",
72 "cmd: rejecting malformed Connection Parameter Update Request, "
73 "size %zu",
74 request_payload.size());
75 sig_responder->RejectNotUnderstood();
76 return;
77 }
78
79 const auto& req =
80 request_payload.To<ConnectionParameterUpdateRequestPayload>();
81 const auto interval_min = le16toh(req.interval_min);
82 const auto interval_max = le16toh(req.interval_max);
83 const auto peripheral_latency = le16toh(req.peripheral_latency);
84 const auto timeout_multiplier = le16toh(req.timeout_multiplier);
85 ConnectionParameterUpdateResponder responder(sig_responder);
86 cb(interval_min,
87 interval_max,
88 peripheral_latency,
89 timeout_multiplier,
90 &responder);
91 };
92
93 sig()->ServeRequest(kConnectionParameterUpdateRequest,
94 std::move(on_param_update_req));
95 }
96
97 } // namespace bt::l2cap::internal
98