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/sm/packet.h"
16
17 #include <pw_assert/check.h>
18
19 #include <unordered_map>
20
21 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
22 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
23 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
24
25 namespace bt::sm {
26
PacketReader(const ByteBuffer * buffer)27 PacketReader::PacketReader(const ByteBuffer* buffer)
28 : PacketView<Header>(buffer, buffer->size() - sizeof(Header)) {}
29
ValidPacketReader(const ByteBuffer * buffer)30 ValidPacketReader::ValidPacketReader(const ByteBuffer* buffer)
31 : PacketReader(buffer) {}
32
ParseSdu(const ByteBufferPtr & sdu)33 fit::result<ErrorCode, ValidPacketReader> ValidPacketReader::ParseSdu(
34 const ByteBufferPtr& sdu) {
35 PW_CHECK(sdu);
36 size_t length = sdu->size();
37 if (length < sizeof(Header)) {
38 bt_log(DEBUG, "sm", "PDU too short!");
39 return fit::error(ErrorCode::kInvalidParameters);
40 }
41 auto reader = PacketReader(sdu.get());
42 auto expected_payload_size = kCodeToPayloadSize.find(reader.code());
43 if (expected_payload_size == kCodeToPayloadSize.end()) {
44 bt_log(DEBUG, "sm", "smp code not recognized: %#.2X", reader.code());
45 return fit::error(ErrorCode::kCommandNotSupported);
46 }
47 if (reader.payload_size() != expected_payload_size->second) {
48 bt_log(DEBUG, "sm", "malformed packet with code %#.2X", reader.code());
49 return fit::error(ErrorCode::kInvalidParameters);
50 }
51 return fit::ok(ValidPacketReader(sdu.get()));
52 }
53
PacketWriter(Code code,MutableByteBuffer * buffer)54 PacketWriter::PacketWriter(Code code, MutableByteBuffer* buffer)
55 : MutablePacketView<Header>(buffer, buffer->size() - sizeof(Header)) {
56 mutable_header()->code = code;
57 }
58
59 } // namespace bt::sm
60