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/types.h"
16
17 #include <cinttypes>
18
19 namespace bt::l2cap {
20 namespace {
21 // Helper for implementing the AnyChannelMode equality operators.
22 template <typename T, typename... Alternatives>
VariantEqualsHelper(const std::variant<Alternatives...> & v,const T & x)23 bool VariantEqualsHelper(const std::variant<Alternatives...>& v, const T& x) {
24 return std::holds_alternative<T>(v) && (std::get<T>(v) == x);
25 }
26
27 // Size for a string/buffer that ensures that pw::ToString<AnyChannelMode> will
28 // succeed.
29 constexpr size_t kAnyChannelModeMaxStringSize = 40;
30 } // namespace
31
32 // Allow checking equality of AnyChannelMode with variant members.
operator ==(const AnyChannelMode & any,RetransmissionAndFlowControlMode mode)33 bool operator==(const AnyChannelMode& any,
34 RetransmissionAndFlowControlMode mode) {
35 return VariantEqualsHelper(any, mode);
36 }
operator ==(RetransmissionAndFlowControlMode mode,const AnyChannelMode & any)37 bool operator==(RetransmissionAndFlowControlMode mode,
38 const AnyChannelMode& any) {
39 return VariantEqualsHelper(any, mode);
40 }
operator ==(const AnyChannelMode & any,CreditBasedFlowControlMode mode)41 bool operator==(const AnyChannelMode& any, CreditBasedFlowControlMode mode) {
42 return VariantEqualsHelper(any, mode);
43 }
operator ==(CreditBasedFlowControlMode mode,const AnyChannelMode & any)44 bool operator==(CreditBasedFlowControlMode mode, const AnyChannelMode& any) {
45 return VariantEqualsHelper(any, mode);
46 }
operator !=(const AnyChannelMode & any,RetransmissionAndFlowControlMode mode)47 bool operator!=(const AnyChannelMode& any,
48 RetransmissionAndFlowControlMode mode) {
49 return !VariantEqualsHelper(any, mode);
50 }
operator !=(RetransmissionAndFlowControlMode mode,const AnyChannelMode & any)51 bool operator!=(RetransmissionAndFlowControlMode mode,
52 const AnyChannelMode& any) {
53 return !VariantEqualsHelper(any, mode);
54 }
operator !=(const AnyChannelMode & any,CreditBasedFlowControlMode mode)55 bool operator!=(const AnyChannelMode& any, CreditBasedFlowControlMode mode) {
56 return !VariantEqualsHelper(any, mode);
57 }
operator !=(CreditBasedFlowControlMode mode,const AnyChannelMode & any)58 bool operator!=(CreditBasedFlowControlMode mode, const AnyChannelMode& any) {
59 return !VariantEqualsHelper(any, mode);
60 }
61
AnyChannelModeToString(const AnyChannelMode & mode)62 std::string AnyChannelModeToString(const AnyChannelMode& mode) {
63 std::string buffer(kAnyChannelModeMaxStringSize, 0);
64 pw::StatusWithSize result = pw::ToString(mode, buffer);
65 PW_CHECK(result.ok());
66 buffer.resize(result.size());
67 return buffer;
68 }
69
AnyChannelModeToPwString(const AnyChannelMode & mode,pw::span<char> buffer)70 pw::StatusWithSize AnyChannelModeToPwString(const AnyChannelMode& mode,
71 pw::span<char> buffer) {
72 return std::visit(
73 [&](auto content) -> pw::StatusWithSize {
74 if constexpr (std::is_same_v<decltype(content),
75 RetransmissionAndFlowControlMode>) {
76 static_assert(
77 std::string_view("(RetransmissionAndFlowControlMode) 0x00")
78 .size() < kAnyChannelModeMaxStringSize);
79 return pw::string::Format(
80 buffer,
81 "(RetransmissionAndFlowControlMode) %#.2" PRIx8,
82 static_cast<uint8_t>(content));
83 } else if constexpr (std::is_same_v<decltype(content),
84 CreditBasedFlowControlMode>) {
85 static_assert(
86 std::string_view("(CreditBasedFlowControlMode) 0x00").size() <
87 kAnyChannelModeMaxStringSize);
88 return pw::string::Format(buffer,
89 "(CreditBasedFlowControlMode) %#.2" PRIx8,
90 static_cast<uint8_t>(content));
91 }
92 },
93 mode);
94 }
95 } // namespace bt::l2cap
96
97 namespace pw {
98 template <>
ToString(const bt::l2cap::AnyChannelMode & mode,span<char> buffer)99 StatusWithSize ToString(const bt::l2cap::AnyChannelMode& mode,
100 span<char> buffer) {
101 return bt::l2cap::AnyChannelModeToPwString(mode, buffer);
102 }
103 } // namespace pw
104