C/C++ API Reference
Loading...
Searching...
No Matches
h4_packet.h
1// Copyright 2024 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#pragma once
16
17#include <cstdint>
18
19#include "lib/stdcompat/utility.h"
20#include "pw_bluetooth/hci_h4.emb.h"
21#include "pw_function/function.h"
22#include "pw_span/span.h"
23
25
27
34 public:
35 H4PacketInterface() = default;
36
37 H4PacketInterface(const H4PacketInterface& other) = delete;
38
39 H4PacketInterface(H4PacketInterface&& other) = default;
40 H4PacketInterface& operator=(H4PacketInterface&& other) = default;
41
42 virtual ~H4PacketInterface() = default;
43
46 virtual emboss::H4PacketType GetH4Type() const = 0;
47
49 virtual void SetH4Type(emboss::H4PacketType) = 0;
50
53 pw::span<uint8_t> GetHciSpan() { return DoGetHciSpan(); }
54 pw::span<const uint8_t> GetHciSpan() const { return DoGetHciSpan(); }
55
56 protected:
57 H4PacketInterface& operator=(const H4PacketInterface& other) = default;
58
59 static constexpr std::uint8_t kH4PacketIndicatorSize = 1;
60
61 private:
62 virtual pw::span<uint8_t> DoGetHciSpan() const = 0;
63};
64
66class H4PacketWithHci final : public H4PacketInterface {
67 public:
68 H4PacketWithHci(emboss::H4PacketType h4_type, pw::span<uint8_t> hci_span)
69 : hci_span_(hci_span), h4_type_(h4_type) {}
70
72 : hci_span_(h4_span.subspan(kH4PacketIndicatorSize)),
73 h4_type_(emboss::H4PacketType{h4_span[0]}) {}
74
75 H4PacketWithHci(const H4PacketWithHci& other) = delete;
76
77 H4PacketWithHci(H4PacketWithHci&& other) = default;
78 H4PacketWithHci& operator=(H4PacketWithHci&& other) = default;
79
80 ~H4PacketWithHci() final = default;
81
82 emboss::H4PacketType GetH4Type() const final { return h4_type_; }
83
84 void SetH4Type(emboss::H4PacketType h4_type) final { h4_type_ = h4_type; }
85
86 private:
87 H4PacketWithHci& operator=(const H4PacketWithHci& other) = default;
88
89 pw::span<uint8_t> hci_span_;
90
91 emboss::H4PacketType h4_type_;
92
93 pw::span<uint8_t> DoGetHciSpan() const final { return hci_span_; }
94};
95
97class H4PacketWithH4 final : public H4PacketInterface {
98 public:
99 using ReleaseFn = Function<void(const uint8_t*)>;
100
101 H4PacketWithH4() = default;
102 H4PacketWithH4(pw::span<uint8_t> h4_span) : h4_span_(h4_span) {}
103
105 H4PacketWithH4(pw::span<uint8_t> h4_span, ReleaseFn&& release_fn)
106 : h4_span_(h4_span), release_fn_(std::move(release_fn)) {}
107
108 H4PacketWithH4(emboss::H4PacketType h4_type, pw::span<uint8_t> h4_span)
109 : H4PacketWithH4(h4_span) {
110 SetH4Type(h4_type);
111 }
112
113 H4PacketWithH4(const H4PacketWithH4& other) = delete;
114 H4PacketWithH4& operator=(const H4PacketWithH4& other) = delete;
115
116 H4PacketWithH4(H4PacketWithH4&& other)
117 : h4_span_(other.h4_span_), release_fn_(std::move(other.release_fn_)) {
118 other.Reset();
119 }
120
121 H4PacketWithH4& operator=(H4PacketWithH4&& other) {
122 h4_span_ = other.h4_span_;
123 release_fn_ = std::move(other.release_fn_);
124 other.Reset();
125 return *this;
126 }
127
128 ~H4PacketWithH4() final {
129 if (release_fn_) {
130 release_fn_(h4_span_.data());
131 }
132 }
133
134 emboss::H4PacketType GetH4Type() const final {
135 if (h4_span_.empty()) {
136 return emboss::H4PacketType::UNKNOWN;
137 }
138
139 return emboss::H4PacketType(h4_span_[0]);
140 }
141
142 void SetH4Type(emboss::H4PacketType h4_type) final {
143 if (!h4_span_.empty()) {
144 h4_span_.data()[0] = cpp23::to_underlying(h4_type);
145 }
146 }
147
148 bool HasReleaseFn() {
149 // pw::Function bool returns true if not-empty
150 return bool{release_fn_};
151 }
152
153 // Returns the release function (which could be empty) and resets the packet.
154 // Essentially it moves ownership of the buffer to the caller (who should have
155 // already stored `GetH4Span()` since packet's span will be reset by this
156 // call).
157 ReleaseFn ResetAndReturnReleaseFn() {
158 ReleaseFn fn = std::move(release_fn_);
159 Reset();
160 return fn;
161 }
162
163 pw::span<uint8_t> GetH4Span() {
164 if (h4_span_.empty()) {
165 return {};
166 }
167 return h4_span_;
168 }
169
170 private:
171 void Reset() {
172 h4_span_ = pw::span<uint8_t>();
173 release_fn_ = nullptr;
174 }
175
176 pw::span<uint8_t> h4_span_;
177
178 ReleaseFn release_fn_{};
179
180 pw::span<uint8_t> DoGetHciSpan() const final {
181 // If h4_span is empty, then return an empty span for hci also.
182 if (h4_span_.empty()) {
183 return {};
184 }
185 return pw::span(h4_span_.data() + kH4PacketIndicatorSize,
186 h4_span_.size() - kH4PacketIndicatorSize);
187 }
188};
189
190} // namespace pw::bluetooth::proxy
Definition: h4_packet.h:33
H4PacketWithH4 is an H4Packet backed by an H4 buffer.
Definition: h4_packet.h:97
H4PacketWithHci is an H4Packet backed by an HCI buffer.
Definition: h4_packet.h:66
Definition: span_impl.h:235
void SetH4Type(emboss::H4PacketType h4_type) final
Sets HCI packet type indicator.
Definition: h4_packet.h:84
virtual emboss::H4PacketType GetH4Type() const =0
void SetH4Type(emboss::H4PacketType h4_type) final
Sets HCI packet type indicator.
Definition: h4_packet.h:142
emboss::H4PacketType GetH4Type() const final
Definition: h4_packet.h:82
H4PacketWithH4(pw::span< uint8_t > h4_span, ReleaseFn &&release_fn)
release_fn (if callable) will be called when H4PacketWithH4 is destructed.
Definition: h4_packet.h:105
emboss::H4PacketType GetH4Type() const final
Definition: h4_packet.h:134
virtual void SetH4Type(emboss::H4PacketType)=0
Sets HCI packet type indicator.
pw::span< uint8_t > GetHciSpan()
Definition: h4_packet.h:53
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
Lightweight proxy for augmenting Bluetooth functionality.
Definition: h4_packet.h:24