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() = 0;
47
49 virtual void SetH4Type(emboss::H4PacketType) = 0;
50
54
55 protected:
56 H4PacketInterface& operator=(const H4PacketInterface& other) = default;
57
58 static constexpr std::uint8_t kH4PacketIndicatorSize = 1;
59};
60
62class H4PacketWithHci final : public H4PacketInterface {
63 public:
64 H4PacketWithHci(emboss::H4PacketType h4_type, pw::span<uint8_t> hci_span)
65 : hci_span_(hci_span), h4_type_(h4_type) {}
66
68 : hci_span_(h4_span.subspan(kH4PacketIndicatorSize)),
69 h4_type_(emboss::H4PacketType{h4_span[0]}) {}
70
71 H4PacketWithHci(const H4PacketWithHci& other) = delete;
72
73 H4PacketWithHci(H4PacketWithHci&& other) = default;
74 H4PacketWithHci& operator=(H4PacketWithHci&& other) = default;
75
76 ~H4PacketWithHci() final = default;
77
78 emboss::H4PacketType GetH4Type() final { return h4_type_; }
79
80 void SetH4Type(emboss::H4PacketType h4_type) final { h4_type_ = h4_type; }
81
82 pw::span<uint8_t> GetHciSpan() final { return hci_span_; }
83
84 private:
85 H4PacketWithHci& operator=(const H4PacketWithHci& other) = default;
86
87 pw::span<uint8_t> hci_span_;
88
89 emboss::H4PacketType h4_type_;
90};
91
93class H4PacketWithH4 final : public H4PacketInterface {
94 public:
95 H4PacketWithH4() = default;
96 H4PacketWithH4(pw::span<uint8_t> h4_span) : h4_span_(h4_span) {}
97
100 pw::Function<void(const uint8_t* buffer)>&& release_fn)
101 : h4_span_(h4_span), release_fn_(std::move(release_fn)) {}
102
103 H4PacketWithH4(emboss::H4PacketType h4_type, pw::span<uint8_t> h4_span)
104 : H4PacketWithH4(h4_span) {
105 SetH4Type(h4_type);
106 }
107
108 H4PacketWithH4(const H4PacketWithH4& other) = delete;
109 H4PacketWithH4& operator=(const H4PacketWithH4& other) = delete;
110
111 H4PacketWithH4(H4PacketWithH4&& other)
112 : h4_span_(other.h4_span_), release_fn_(std::move(other.release_fn_)) {
113 other.Reset();
114 }
115
116 H4PacketWithH4& operator=(H4PacketWithH4&& other) {
117 h4_span_ = other.h4_span_;
118 release_fn_ = std::move(other.release_fn_);
119 other.Reset();
120 return *this;
121 }
122
123 ~H4PacketWithH4() final {
124 if (release_fn_) {
125 release_fn_(h4_span_.data());
126 }
127 }
128
129 emboss::H4PacketType GetH4Type() final {
130 if (h4_span_.empty()) {
131 return emboss::H4PacketType::UNKNOWN;
132 }
133
134 return emboss::H4PacketType(h4_span_[0]);
135 }
136
137 void SetH4Type(emboss::H4PacketType h4_type) final {
138 if (!h4_span_.empty()) {
139 h4_span_.data()[0] = cpp23::to_underlying(h4_type);
140 }
141 }
142
143 bool HasReleaseFn() {
144 // pw::Function bool returns true if not-empty
145 return bool{release_fn_};
146 }
147
148 // Returns the release function (which could be empty) and resets the packet.
149 // Essentially it moves ownership of the buffer to the caller (who should have
150 // already stored `GetH4Span()` since packet's span will be reset by this
151 // call).
152 pw::Function<void(const uint8_t*)> ResetAndReturnReleaseFn() {
153 pw::Function<void(const uint8_t* packet)> fn = std::move(release_fn_);
154 Reset();
155 return fn;
156 }
157
159 // If h4_span is empty, then return an empty span for hci also.
160 if (h4_span_.empty()) {
161 return {};
162 }
163 return pw::span(h4_span_.data() + kH4PacketIndicatorSize,
164 h4_span_.size() - kH4PacketIndicatorSize);
165 }
166
167 pw::span<uint8_t> GetH4Span() {
168 if (h4_span_.empty()) {
169 return {};
170 }
171 return h4_span_;
172 }
173
174 private:
175 void Reset() {
176 h4_span_ = pw::span<uint8_t>();
177 release_fn_ = nullptr;
178 }
179
180 pw::span<uint8_t> h4_span_;
181
182 pw::Function<void(const uint8_t* packet)> release_fn_{};
183};
184
185} // namespace pw::bluetooth::proxy
Definition: h4_packet.h:33
H4PacketWithH4 is an H4Packet backed by an H4 buffer.
Definition: h4_packet.h:93
H4PacketWithHci is an H4Packet backed by an HCI buffer.
Definition: h4_packet.h:62
Definition: span_impl.h:235
void SetH4Type(emboss::H4PacketType h4_type) final
Sets HCI packet type indicator.
Definition: h4_packet.h:80
void SetH4Type(emboss::H4PacketType h4_type) final
Sets HCI packet type indicator.
Definition: h4_packet.h:137
emboss::H4PacketType GetH4Type() final
Definition: h4_packet.h:78
pw::span< uint8_t > GetHciSpan() final
Definition: h4_packet.h:82
pw::span< uint8_t > GetHciSpan() final
Definition: h4_packet.h:158
virtual void SetH4Type(emboss::H4PacketType)=0
Sets HCI packet type indicator.
virtual emboss::H4PacketType GetH4Type()=0
H4PacketWithH4(pw::span< uint8_t > h4_span, pw::Function< void(const uint8_t *buffer)> &&release_fn)
release_fn (if callable) will be called when H4PacketWithH4 is destructed.
Definition: h4_packet.h:99
emboss::H4PacketType GetH4Type() final
Definition: h4_packet.h:129
virtual pw::span< uint8_t > GetHciSpan()=0
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