• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/le_signaling_channel.h"
16 
17 #include <pw_assert/check.h>
18 #include <pw_bytes/endian.h>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
21 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel.h"
22 
23 namespace bt::l2cap::internal {
24 
LESignalingChannel(Channel::WeakPtr chan,pw::bluetooth::emboss::ConnectionRole role,pw::async::Dispatcher & dispatcher)25 LESignalingChannel::LESignalingChannel(
26     Channel::WeakPtr chan,
27     pw::bluetooth::emboss::ConnectionRole role,
28     pw::async::Dispatcher& dispatcher)
29     : SignalingChannel(std::move(chan), role, dispatcher) {
30   set_mtu(kMinLEMTU);
31 }
32 
DecodeRxUnit(ByteBufferPtr sdu,const SignalingPacketHandler & cb)33 void LESignalingChannel::DecodeRxUnit(ByteBufferPtr sdu,
34                                       const SignalingPacketHandler& cb) {
35   // "[O]nly one command per C-frame shall be sent over [the LE] Fixed Channel"
36   // (v5.0, Vol 3, Part A, Section 4).
37   PW_DCHECK(sdu);
38   if (sdu->size() < sizeof(CommandHeader)) {
39     bt_log(DEBUG, "l2cap-le", "sig: dropped malformed LE signaling packet");
40     return;
41   }
42 
43   SignalingPacket packet(sdu.get());
44   uint16_t expected_payload_length = pw::bytes::ConvertOrderFrom(
45       cpp20::endian::little, packet.header().length);
46   if (expected_payload_length != sdu->size() - sizeof(CommandHeader)) {
47     bt_log(DEBUG,
48            "l2cap-le",
49            "sig: packet size mismatch (expected: %u, recv: %zu); drop",
50            expected_payload_length,
51            sdu->size() - sizeof(CommandHeader));
52     SendCommandReject(
53         packet.header().id, RejectReason::kNotUnderstood, BufferView());
54     return;
55   }
56 
57   cb(SignalingPacket(sdu.get(), expected_payload_length));
58 }
59 
IsSupportedResponse(CommandCode code) const60 bool LESignalingChannel::IsSupportedResponse(CommandCode code) const {
61   switch (code) {
62     case kCommandRejectCode:
63     case kConnectionParameterUpdateResponse:
64     case kDisconnectionResponse:
65     case kLECreditBasedConnectionResponse:
66       return true;
67   }
68 
69   // Other response-type commands are for AMP/BREDR and are not supported.
70   return false;
71 }
72 
73 }  // namespace bt::l2cap::internal
74