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 using ReleaseFn = Function<void(const uint8_t*)>;
36
37 constexpr H4PacketInterface() = default;
39 size_t hci_offset,
40 ReleaseFn&& release_fn)
41 : buffer_(buffer),
42 hci_offset_(hci_offset),
43 release_fn_(std::move(release_fn)) {}
44
45 H4PacketInterface(const H4PacketInterface& other) = delete;
46 H4PacketInterface& operator=(const H4PacketInterface& other) = delete;
47
48 H4PacketInterface(H4PacketInterface&& other) { *this = std::move(other); }
49 H4PacketInterface& operator=(H4PacketInterface&& other) {
50 if (this != &other) {
51 buffer_ = other.buffer_;
52 hci_offset_ = other.hci_offset_;
53 release_fn_ = std::move(other.release_fn_);
54 other.Reset();
55 }
56 return *this;
57 }
58
59 virtual ~H4PacketInterface() {
60 if (!buffer_.empty() && HasReleaseFn()) {
61 release_fn_(buffer_.data());
62 }
63 }
64
67 emboss::H4PacketType GetH4Type() const { return DoGetH4Type(); }
68
70 void SetH4Type(emboss::H4PacketType type) { DoSetH4Type(type); }
71
75 return buffer_.empty() ? buffer_ : buffer_.subspan(hci_offset_);
76 }
77 constexpr span<const uint8_t> GetHciSpan() const {
78 return buffer_.empty() ? buffer_ : buffer_.subspan(hci_offset_);
79 }
80
81 bool HasReleaseFn() { return bool{release_fn_}; }
82
83 // Returns the release function (which could be empty) and resets the packet.
84 // The caller takes ownership of the buffer and should already have stored it.
85 ReleaseFn ResetAndReturnReleaseFn() {
86 ReleaseFn fn = std::move(release_fn_);
87 Reset();
88 return fn;
89 }
90
91 protected:
92 static constexpr std::uint8_t kH4PacketIndicatorSize = 1;
93
94 constexpr span<uint8_t> buffer() { return buffer_; }
95 constexpr span<const uint8_t> buffer() const { return buffer_; }
96
97 private:
98 virtual emboss::H4PacketType DoGetH4Type() const = 0;
99 virtual void DoSetH4Type(emboss::H4PacketType) = 0;
100
101 void Reset() {
102 buffer_ = span<uint8_t>();
103 hci_offset_ = 0;
104 release_fn_ = ReleaseFn{};
105 }
106
107 span<uint8_t> buffer_;
108 size_t hci_offset_ = 0;
109 ReleaseFn release_fn_{};
110};
111
113class H4PacketWithHci final : public H4PacketInterface {
114 public:
115 constexpr H4PacketWithHci() = default;
116
117 H4PacketWithHci(emboss::H4PacketType h4_type,
118 span<uint8_t> hci_span,
119 ReleaseFn&& release_fn = nullptr)
120 : H4PacketInterface(hci_span, 0, std::move(release_fn)),
121 h4_type_(h4_type) {}
122
123 H4PacketWithHci(span<uint8_t> h4_span, ReleaseFn&& release_fn = nullptr)
125 h4_span, kH4PacketIndicatorSize, std::move(release_fn)),
126 h4_type_(emboss::H4PacketType{h4_span[0]}) {}
127
128 H4PacketWithHci(H4PacketWithHci&& other) = default;
129 H4PacketWithHci& operator=(H4PacketWithHci&& other) = default;
130
131 private:
132 emboss::H4PacketType DoGetH4Type() const override { return h4_type_; }
133 void DoSetH4Type(emboss::H4PacketType h4_type) override {
134 h4_type_ = h4_type;
135 }
136
137 emboss::H4PacketType h4_type_ = emboss::H4PacketType::UNKNOWN;
138};
139
141class H4PacketWithH4 final : public H4PacketInterface {
142 public:
143 constexpr H4PacketWithH4() = default;
144
145 H4PacketWithH4(span<uint8_t> h4_span, ReleaseFn&& release_fn = nullptr)
147 h4_span, kH4PacketIndicatorSize, std::move(release_fn)) {}
148
149 H4PacketWithH4(emboss::H4PacketType h4_type,
150 span<uint8_t> h4_span,
151 ReleaseFn&& release_fn = nullptr)
152 : H4PacketWithH4(h4_span, std::move(release_fn)) {
153 SetH4Type(h4_type);
154 }
155
156 constexpr span<uint8_t> GetH4Span() { return buffer(); }
157 constexpr span<const uint8_t> GetH4Span() const { return buffer(); }
158
159 private:
160 emboss::H4PacketType DoGetH4Type() const override {
161 span<const uint8_t> h4_span = GetH4Span();
162 return !h4_span.empty() ? emboss::H4PacketType(h4_span[0])
163 : emboss::H4PacketType::UNKNOWN;
164 }
165
166 void DoSetH4Type(emboss::H4PacketType h4_type) override {
167 span<uint8_t> h4_span = GetH4Span();
168 if (!h4_span.empty()) {
169 h4_span.data()[0] = cpp23::to_underlying(h4_type);
170 }
171 }
172};
173
174} // namespace pw::bluetooth::proxy
Definition: h4_packet.h:33
H4PacketWithH4 is an H4Packet backed by an H4 buffer.
Definition: h4_packet.h:141
H4PacketWithHci is an H4Packet backed by an HCI buffer.
Definition: h4_packet.h:113
Definition: span_impl.h:235
constexpr span< uint8_t > GetHciSpan()
Definition: h4_packet.h:74
emboss::H4PacketType GetH4Type() const
Definition: h4_packet.h:67
void SetH4Type(emboss::H4PacketType type)
Sets HCI packet type indicator.
Definition: h4_packet.h:70
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