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