ELEC-C7222
Libraries for ELEC C7222 Course Work
Loading...
Searching...
No Matches
advertisement_data.hpp
Go to the documentation of this file.
1
5#ifndef ELEC_C7222_BLE_GAP_ADVERTISEMENT_DATA_H_
6#define ELEC_C7222_BLE_GAP_ADVERTISEMENT_DATA_H_
7
8#include <cassert>
9#include <cstddef>
10#include <cstdint>
11#include <iosfwd>
12#include <list>
13#include <type_traits>
14#include <vector>
15
16namespace c7222 {
17
21constexpr size_t kAdvertisementDataLegacyMaxSize = 31;
29enum class AdvertisementDataType : uint8_t {
30 kFlags = 0x01,
34 kCompleteLocalName = 0x09,
35 kTxPowerLevel = 0x0A,
39};
40
47 public:
48 enum class Flags : uint8_t {
51 kBrEdrNotSupported = 0x04,
54 kAll = 0x1f,
55 };
56
65 AdvertisementData(AdvertisementDataType type, const std::vector<uint8_t>& data) {
66 Build(type, data.data(), data.size());
67 }
68
81 template <typename T>
82 AdvertisementData(AdvertisementDataType type, const T* object_ptr) {
83 static_assert(!std::is_pointer<T>::value, "object_ptr must point to a concrete type");
84 // static_assert(!std::is_array<T>::value, "object_ptr must not be an array type");
85 Build(type, reinterpret_cast<const std::uint8_t*>(object_ptr), sizeof(T));
86 }
87
98 template <typename T>
99 AdvertisementData(AdvertisementDataType type, const T* object_ptr, size_t elem_count) {
100 static_assert(!std::is_pointer<T>::value, "object_ptr must point to a concrete type");
101 // static_assert(std::is_array<T>::value, "object_ptr must be an array type");
102 Build(type, reinterpret_cast<const std::uint8_t*>(object_ptr), sizeof(T) * elem_count);
103 }
104
117 template <typename T>
118 AdvertisementData(AdvertisementDataType type, const T& object_ref) {
119 static_assert(!std::is_pointer<T>::value,
120 "object_ref must refer to a concrete type, not a pointer type");
121 if(std::is_object<T>::value)
122 Build(type, reinterpret_cast<const std::uint8_t*>(&object_ref), sizeof(T));
123 else {
124 T obj = object_ref;
125 Build(type, reinterpret_cast<const std::uint8_t*>(&obj), sizeof(T));
126 }
127 }
128
134 const std::vector<uint8_t>& GetData() const {
135 return data_;
136 }
137
143 const uint8_t* GetBytes() const {
144 return data_.data();
145 }
146
150 size_t GetSize() const {
151 return data_.size();
152 }
153
158 assert(data_.size() >= 2 && "AdvertisementData: data size too small to contain type");
159 return static_cast<AdvertisementDataType>(data_[1]);
160 }
161
165 uint8_t GetLength() const {
166 assert(data_.size() >= 1 && "AdvertisementData: data size too small to contain length");
167 return data_[0];
168 }
169
179 std::vector<uint8_t> operator+=(const AdvertisementData& other) const;
180
184 bool operator==(const AdvertisementData& other) const {
185 return data_ == other.data_;
186 }
187
191 friend std::ostream& operator<<(std::ostream& os, const AdvertisementData& ad);
195 friend std::ostream& operator<<(std::ostream& os, const AdvertisementData::Flags& flag);
196
197 private:
201 std::vector<uint8_t>::iterator begin() {
202 return data_.begin();
203 }
207 std::vector<uint8_t>::const_iterator begin() const {
208 return data_.begin();
209 }
213 std::vector<uint8_t>::const_iterator cbegin() const {
214 return data_.cbegin();
215 }
219 std::vector<uint8_t>::iterator end() {
220 return data_.end();
221 }
225 std::vector<uint8_t>::const_iterator end() const {
226 return data_.end();
227 }
231 std::vector<uint8_t>::const_iterator cend() const {
232 return data_.cend();
233 }
234
235 public:
245 static bool ValidateLength(AdvertisementDataType type, size_t length);
246
258 static bool ValidateBuffer(const uint8_t* adv_data, size_t adv_data_size);
259
266 static bool ValidateBuffer(const std::vector<uint8_t>& adv_data) {
267 return ValidateBuffer(adv_data.data(), adv_data.size());
268 }
269
270 private:
281 void Build(AdvertisementDataType type, const uint8_t* data, size_t size);
282
286 std::vector<uint8_t> data_;
287};
288
296std::vector<uint8_t> operator+(const AdvertisementData& lhs, const AdvertisementData& rhs);
297
305 public:
310
318 explicit AdvertisementDataBuilder(const std::list<AdvertisementData>& ads);
319
326 bool Set(const std::list<AdvertisementData>& ads);
327
335 bool Set(const uint8_t* data, size_t size);
336
342 bool Pop();
343
350 bool Push(const AdvertisementData& ad);
351
358
365
372 bool Add(const std::list<AdvertisementData>& ads);
381 bool Add(const AdvertisementData& ad);
385 const std::vector<uint8_t>& data() const;
386
390 const uint8_t* bytes() const;
391
395 size_t size() const;
396
400 void Clear();
401
411
419
427
435
439 bool operator==(const AdvertisementDataBuilder& other) const;
443 bool Validate() const;
444
452 bool Build();
456 const std::list<AdvertisementData>& advertisement_data_list() const {
457 return advertisements_;
458 }
459
468 static std::list<AdvertisementData> DecodeBufferToAdvertisementDataList(const uint8_t* adv_data,
469 size_t adv_data_size);
470
474 friend std::ostream& operator<<(std::ostream& os, const AdvertisementDataBuilder& adb);
475
476 private:
480 std::list<AdvertisementData> advertisements_;
484 std::vector<uint8_t> data_;
488 bool built_ = false;
489};
490
491} // namespace c7222
492
495 return static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs);
496}
497constexpr uint8_t operator|(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
498 uint8_t ret = lhs | static_cast<uint8_t>(rhs);
499 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
500 return ret;
501}
502constexpr uint8_t operator|=(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
503 uint8_t ret = lhs | static_cast<uint8_t>(rhs);
504 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
505 return ret;
506}
507constexpr uint8_t operator|(c7222::AdvertisementData::Flags lhs, uint8_t rhs) {
508 uint8_t ret = static_cast<uint8_t>(lhs) | rhs;
509 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
510 return ret;
511}
512
515 return static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs);
516}
517
518constexpr uint8_t operator&(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
519 uint8_t ret = lhs & static_cast<uint8_t>(rhs);
520 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
521 return ret;
522}
523
524constexpr uint8_t operator&=(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
525 uint8_t ret = lhs & static_cast<uint8_t>(rhs);
526 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
527 return ret;
528}
529
530constexpr uint8_t operator&(c7222::AdvertisementData::Flags lhs, uint8_t rhs) {
531 uint8_t ret = static_cast<uint8_t>(lhs) & rhs;
532 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
533 return ret;
534}
535
536constexpr uint8_t operator^(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
537 uint8_t ret = lhs ^ static_cast<uint8_t>(rhs);
538 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
539 return ret;
540}
541constexpr uint8_t operator^=(uint8_t lhs, c7222::AdvertisementData::Flags rhs) {
542 uint8_t ret = lhs ^ static_cast<uint8_t>(rhs);
543 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
544 return ret;
545}
546constexpr uint8_t operator^(c7222::AdvertisementData::Flags lhs, uint8_t rhs) {
547 uint8_t ret = static_cast<uint8_t>(lhs) & rhs;
548 assert(ret <= static_cast<uint8_t>(c7222::AdvertisementData::Flags::kAll));
549 return ret;
550}
551
552#endif // ELEC_C7222_BLE_GAP_ADVERTISEMENT_DATA_H_
constexpr uint8_t operator^=(uint8_t lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:541
constexpr uint8_t operator|=(uint8_t lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:502
constexpr uint8_t operator|(c7222::AdvertisementData::Flags lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:493
constexpr uint8_t operator&(c7222::AdvertisementData::Flags lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:513
constexpr uint8_t operator^(uint8_t lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:536
constexpr uint8_t operator&=(uint8_t lhs, c7222::AdvertisementData::Flags rhs)
Definition advertisement_data.hpp:524
Builder for assembling a complete advertising payload.
Definition advertisement_data.hpp:304
void ReplaceOrAdd(AdvertisementData &&ad)
ReplaceOrAdd the AD structure with the same type (move).
AdvertisementDataBuilder & operator+=(const AdvertisementData &ad)
Add an AD structure and enforce uniqueness.
bool Push(const AdvertisementData &ad)
Add an AD structure to the payload.
bool Pop()
Remove the last AD structure from the payload.
bool Validate() const
Validate the assembled payload.
bool Build()
Build the raw payload from stored AD structures.
AdvertisementDataBuilder()
Create an empty builder.
size_t size() const
Return the total payload size in bytes.
const uint8_t * bytes() const
Return a raw pointer to the advertising payload bytes.
friend std::ostream & operator<<(std::ostream &os, const AdvertisementDataBuilder &adb)
Stream the builder payload for logging/debugging.
static std::list< AdvertisementData > DecodeBufferToAdvertisementDataList(const uint8_t *adv_data, size_t adv_data_size)
Decode a raw advertising payload buffer into a list of AD structures.
AdvertisementDataBuilder operator+(const AdvertisementData &ad)
Return a builder with an additional AD structure.
bool Set(const std::list< AdvertisementData > &ads)
ReplaceOrAdd the payload with a list of AD structures.
bool operator==(const AdvertisementDataBuilder &other) const
Compare two builders by payload or list contents.
void ReplaceOrAdd(const AdvertisementData &ad)
ReplaceOrAdd the AD structure with the same type.
AdvertisementDataBuilder operator+(const AdvertisementDataBuilder &adb)
Return a builder that is the merge of two builders.
const std::vector< uint8_t > & data() const
Return the raw advertising payload bytes.
void Clear()
Clear all stored AD structures.
AdvertisementDataBuilder & operator+=(const AdvertisementDataBuilder &adb)
Merge another builder into this one, enforcing uniqueness.
AdvertisementDataBuilder(const std::list< AdvertisementData > &ads)
Create a builder from a list of AD structures.
bool Add(const AdvertisementData &ad)
Add an AD structure to the payload.
const std::list< AdvertisementData > & advertisement_data_list() const
Decode the payload into a list of AD structures.
Definition advertisement_data.hpp:456
bool Add(const std::list< AdvertisementData > &ads)
Add a list of AD structures to the payload.
bool Set(const uint8_t *data, size_t size)
ReplaceOrAdd the payload from a raw advertising buffer.
Generic advertisement data structure builder.
Definition advertisement_data.hpp:46
friend std::ostream & operator<<(std::ostream &os, const AdvertisementData &ad)
Stream an AD structure for logging/debugging.
bool operator==(const AdvertisementData &other) const
Compare AD structure bytes for equality.
Definition advertisement_data.hpp:184
Flags
Definition advertisement_data.hpp:48
static bool ValidateBuffer(const std::vector< uint8_t > &adv_data)
Validate a raw advertising payload stored in a vector.
Definition advertisement_data.hpp:266
AdvertisementData(AdvertisementDataType type, const std::vector< uint8_t > &data)
Build an AD structure from a byte vector.
Definition advertisement_data.hpp:65
static bool ValidateBuffer(const uint8_t *adv_data, size_t adv_data_size)
Validate a raw advertising payload buffer.
uint8_t GetLength() const
Return the length field (type + value bytes).
Definition advertisement_data.hpp:165
friend std::ostream & operator<<(std::ostream &os, const AdvertisementData::Flags &flag)
Stream AD Flags for logging/debugging.
AdvertisementData(AdvertisementDataType type, const T *object_ptr)
Build an AD structure from a typed object pointer.
Definition advertisement_data.hpp:82
const std::vector< uint8_t > & GetData() const
Return the full AD structure bytes.
Definition advertisement_data.hpp:134
size_t GetSize() const
Return the total size of the AD structure (length + type + value).
Definition advertisement_data.hpp:150
AdvertisementDataType GetType() const
Return the AD structure type.
Definition advertisement_data.hpp:157
AdvertisementData(AdvertisementDataType type, const T &object_ref)
Build an AD structure from a typed object reference.
Definition advertisement_data.hpp:118
std::vector< uint8_t > operator+=(const AdvertisementData &other) const
Concatenate two AD structures into a raw byte vector.
AdvertisementData(AdvertisementDataType type, const T *object_ptr, size_t elem_count)
Build an AD structure from an array of typed objects.
Definition advertisement_data.hpp:99
static bool ValidateLength(AdvertisementDataType type, size_t length)
Validate the AD length field for a given type.
const uint8_t * GetBytes() const
Return a raw pointer to the AD structure bytes.
Definition advertisement_data.hpp:143
C7222 course abstractions namespace.
Definition ble.hpp:20
std::vector< uint8_t > operator+(const AdvertisementData &lhs, const AdvertisementData &rhs)
Concatenate two AD structures into a raw byte vector.
constexpr size_t kAdvertisementDataLegacyMaxSize
Maximum length for legacy advertising data (length + type + value).
Definition advertisement_data.hpp:21
AdvertisementDataType
BLE GAP advertisement data types.
Definition advertisement_data.hpp:29
constexpr size_t kAdvertisementDataStructHeaderOverhead
Overhead bytes for an AD structure (length + type).
Definition advertisement_data.hpp:25