SE050 Driver
API reference
Loading...
Searching...
No Matches
se050_tlv.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include "se050_types.hpp"
10
11#include <cstddef>
12#include <cstdint>
13#include <cstring>
14
15namespace se050::tlv {
16
17[[nodiscard]] inline Error AppendTagAndLength(std::uint8_t tag, std::size_t value_len, std::uint8_t* out,
18 std::size_t out_cap, std::size_t* off) noexcept {
19 if (out == nullptr || off == nullptr) {
21 }
22 if (*off >= out_cap) {
24 }
25 out[(*off)++] = tag;
26 if (value_len <= 0x7FU) {
27 if (*off >= out_cap) {
29 }
30 out[(*off)++] = static_cast<std::uint8_t>(value_len);
31 return Error::Ok;
32 }
33 if (value_len <= 0xFFU) {
34 if (*off + 1U >= out_cap) {
36 }
37 out[(*off)++] = 0x81U;
38 out[(*off)++] = static_cast<std::uint8_t>(value_len);
39 return Error::Ok;
40 }
41 if (value_len <= 0xFFFFU) {
42 if (*off + 2U >= out_cap) {
44 }
45 out[(*off)++] = 0x82U;
46 out[(*off)++] = static_cast<std::uint8_t>((value_len >> 8U) & 0xFFU);
47 out[(*off)++] = static_cast<std::uint8_t>(value_len & 0xFFU);
48 return Error::Ok;
49 }
51}
52
53[[nodiscard]] inline Error Append(std::uint8_t tag, const std::uint8_t* value, std::size_t value_len,
54 std::uint8_t* out, std::size_t out_cap, std::size_t* off) noexcept {
55 const Error h = AppendTagAndLength(tag, value_len, out, out_cap, off);
56 if (h != Error::Ok) {
57 return h;
58 }
59 if (*off + value_len > out_cap) {
61 }
62 if (value_len > 0U && value != nullptr) {
63 std::memcpy(out + *off, value, value_len);
64 }
65 *off += value_len;
66 return Error::Ok;
67}
68
69[[nodiscard]] inline Error AppendU8(std::uint8_t tag, std::uint8_t value, std::uint8_t* out, std::size_t out_cap,
70 std::size_t* off) noexcept {
71 return Append(tag, &value, 1U, out, out_cap, off);
72}
73
74[[nodiscard]] inline Error AppendU16Be(std::uint8_t tag, std::uint16_t value, std::uint8_t* out,
75 std::size_t out_cap, std::size_t* off) noexcept {
76 const std::uint8_t bytes[2] = {static_cast<std::uint8_t>((value >> 8U) & 0xFFU),
77 static_cast<std::uint8_t>(value & 0xFFU)};
78 return Append(tag, bytes, sizeof(bytes), out, out_cap, off);
79}
80
81[[nodiscard]] inline bool DecodeLength(const std::uint8_t* data, std::size_t data_len, std::size_t* off,
82 std::size_t* value_len) noexcept {
83 if (data == nullptr || off == nullptr || value_len == nullptr || *off >= data_len) {
84 return false;
85 }
86 const std::uint8_t l0 = data[(*off)++];
87 if ((l0 & 0x80U) == 0U) {
88 *value_len = l0;
89 return true;
90 }
91 const std::size_t num_bytes = static_cast<std::size_t>(l0 & 0x7FU);
92 if (num_bytes == 0U || num_bytes > 2U || *off + num_bytes > data_len) {
93 return false;
94 }
95 std::size_t len = 0;
96 for (std::size_t i = 0; i < num_bytes; ++i) {
97 len = (len << 8U) | data[(*off)++];
98 }
99 *value_len = len;
100 return true;
101}
102
103[[nodiscard]] inline bool FindFirst(std::uint8_t wanted_tag, const std::uint8_t* tlv_data, std::size_t tlv_len,
104 const std::uint8_t** value_out, std::size_t* value_len_out) noexcept {
105 if (tlv_data == nullptr || value_out == nullptr || value_len_out == nullptr) {
106 return false;
107 }
108 std::size_t off = 0;
109 while (off < tlv_len) {
110 const std::uint8_t tag = tlv_data[off++];
111 std::size_t value_len = 0;
112 if (!DecodeLength(tlv_data, tlv_len, &off, &value_len)) {
113 return false;
114 }
115 if (off + value_len > tlv_len) {
116 return false;
117 }
118 if (tag == wanted_tag) {
119 *value_out = tlv_data + off;
120 *value_len_out = value_len;
121 return true;
122 }
123 off += value_len;
124 }
125 return false;
126}
127
128} // namespace se050::tlv
Definition se050_tlv.hpp:15
bool DecodeLength(const std::uint8_t *data, std::size_t data_len, std::size_t *off, std::size_t *value_len) noexcept
Definition se050_tlv.hpp:81
Error Append(std::uint8_t tag, const std::uint8_t *value, std::size_t value_len, std::uint8_t *out, std::size_t out_cap, std::size_t *off) noexcept
Definition se050_tlv.hpp:53
Error AppendU16Be(std::uint8_t tag, std::uint16_t value, std::uint8_t *out, std::size_t out_cap, std::size_t *off) noexcept
Definition se050_tlv.hpp:74
Error AppendU8(std::uint8_t tag, std::uint8_t value, std::uint8_t *out, std::size_t out_cap, std::size_t *off) noexcept
Definition se050_tlv.hpp:69
Error AppendTagAndLength(std::uint8_t tag, std::size_t value_len, std::uint8_t *out, std::size_t out_cap, std::size_t *off) noexcept
Definition se050_tlv.hpp:17
bool FindFirst(std::uint8_t wanted_tag, const std::uint8_t *tlv_data, std::size_t tlv_len, const std::uint8_t **value_out, std::size_t *value_len_out) noexcept
Definition se050_tlv.hpp:103
Error
Definition se050_types.hpp:14
Shared types, limits, and error codes for the HF-SE050 driver.