ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
nci_message.cpp
Go to the documentation of this file.
1#include "nci_core.h"
2#include "nci_message.h"
3#include "esphome/core/log.h"
4
5namespace esphome::nfc {
6
7NciMessage::NciMessage(const uint8_t message_type, const std::span<const uint8_t> payload) {
8 this->set_message(message_type, payload);
9}
10
11NciMessage::NciMessage(const uint8_t message_type, const std::initializer_list<uint8_t> payload)
12 : NciMessage(message_type, std::span<const uint8_t>(payload.begin(), payload.size())) {}
13
14NciMessage::NciMessage(const uint8_t message_type, const uint8_t gid, const uint8_t oid) {
15 this->reset();
16 this->set_header(message_type, gid, oid);
17}
18
19NciMessage::NciMessage(const uint8_t message_type, const uint8_t gid, const uint8_t oid,
20 const std::span<const uint8_t> payload) {
21 this->set_message(message_type, gid, oid, payload);
22}
23
24NciMessage::NciMessage(const uint8_t message_type, const uint8_t gid, const uint8_t oid,
25 const std::initializer_list<uint8_t> payload)
26 : NciMessage(message_type, gid, oid, std::span<const uint8_t>(payload.begin(), payload.size())) {}
27
28NciMessage::NciMessage(const std::span<const uint8_t> raw_packet) {
29 this->nci_message_.assign(raw_packet.begin(), raw_packet.end());
30}
31
32std::span<const uint8_t> NciMessage::encode() {
33 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
34 return this->nci_message_;
35}
36
38 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
39 this->nci_message_[NCI_PKT_MT_GID_OFFSET] = 0;
40 this->nci_message_[NCI_PKT_OID_OFFSET] = 0;
41 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = 0;
42}
43
44uint8_t NciMessage::get_message_type() const { return this->nci_message_[NCI_PKT_MT_GID_OFFSET] & NCI_PKT_MT_MASK; }
45
46uint8_t NciMessage::get_gid() const { return this->nci_message_[NCI_PKT_MT_GID_OFFSET] & NCI_PKT_GID_MASK; }
47
48uint8_t NciMessage::get_oid() const { return this->nci_message_[NCI_PKT_OID_OFFSET] & NCI_PKT_OID_MASK; }
49
50uint8_t NciMessage::get_payload_size(const bool recompute) {
51 if (!this->nci_message_.empty()) {
52 if (recompute) {
53 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
54 }
55 return this->nci_message_[NCI_PKT_LENGTH_OFFSET];
56 }
57 return 0;
58}
59
61 if (this->nci_message_.size() > NCI_PKT_PAYLOAD_OFFSET) {
62 return this->nci_message_[NCI_PKT_PAYLOAD_OFFSET];
63 }
64 return STATUS_FAILED;
65}
66
67uint8_t NciMessage::get_message_byte(const uint8_t offset) const {
68 if (this->nci_message_.size() > offset) {
69 return this->nci_message_[offset];
70 }
71 return 0;
72}
73
74std::span<const uint8_t> NciMessage::get_payload() const {
75 if (this->nci_message_.size() <= NCI_PKT_HEADER_SIZE) {
76 return {};
77 }
78 return {this->nci_message_.data() + NCI_PKT_HEADER_SIZE, this->nci_message_.size() - NCI_PKT_HEADER_SIZE};
79}
80
81bool NciMessage::has_payload() const { return this->nci_message_.size() > NCI_PKT_HEADER_SIZE; }
82
83bool NciMessage::message_type_is(const uint8_t message_type) const {
84 if (!this->nci_message_.empty()) {
85 return message_type == (this->nci_message_[NCI_PKT_MT_GID_OFFSET] & NCI_PKT_MT_MASK);
86 }
87 return false;
88}
89
90bool NciMessage::message_length_is(const uint8_t message_length, const bool recompute) {
91 if (this->nci_message_.size() > NCI_PKT_LENGTH_OFFSET) {
92 if (recompute) {
93 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
94 }
95 return message_length == this->nci_message_[NCI_PKT_LENGTH_OFFSET];
96 }
97 return false;
98}
99
100bool NciMessage::gid_is(const uint8_t gid) const {
101 if (this->nci_message_.size() > NCI_PKT_MT_GID_OFFSET) {
102 return gid == (this->nci_message_[NCI_PKT_MT_GID_OFFSET] & NCI_PKT_GID_MASK);
103 }
104 return false;
105}
106
107bool NciMessage::oid_is(const uint8_t oid) const {
108 if (this->nci_message_.size() > NCI_PKT_OID_OFFSET) {
109 return oid == (this->nci_message_[NCI_PKT_OID_OFFSET] & NCI_PKT_OID_MASK);
110 }
111 return false;
112}
113
114bool NciMessage::simple_status_response_is(const uint8_t response) const {
115 if (this->nci_message_.size() > NCI_PKT_PAYLOAD_OFFSET) {
116 return response == this->nci_message_[NCI_PKT_PAYLOAD_OFFSET];
117 }
118 return false;
119}
120
121void NciMessage::set_header(const uint8_t message_type, const uint8_t gid, const uint8_t oid) {
122 if (this->nci_message_.size() < NCI_PKT_HEADER_SIZE) {
123 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
124 }
125 this->nci_message_[NCI_PKT_MT_GID_OFFSET] = (message_type & NCI_PKT_MT_MASK) | (gid & NCI_PKT_GID_MASK);
126 this->nci_message_[NCI_PKT_OID_OFFSET] = oid & NCI_PKT_OID_MASK;
127}
128
129void NciMessage::set_message(const uint8_t message_type, const std::span<const uint8_t> payload) {
130 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
131 this->nci_message_[NCI_PKT_MT_GID_OFFSET] = message_type & NCI_PKT_MT_MASK;
132 this->nci_message_[NCI_PKT_OID_OFFSET] = 0;
133 this->append(payload);
134 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
135}
136
137void NciMessage::set_message(const uint8_t message_type, const uint8_t gid, const uint8_t oid,
138 const std::span<const uint8_t> payload) {
139 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
140 this->set_header(message_type, gid, oid);
141 this->append(payload);
142 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
143}
144
145void NciMessage::set_message_type(const uint8_t message_type) {
146 if (this->nci_message_.size() < NCI_PKT_HEADER_SIZE) {
147 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
148 }
149 auto mt_masked = this->nci_message_[NCI_PKT_MT_GID_OFFSET] & ~NCI_PKT_MT_MASK;
150 this->nci_message_[NCI_PKT_MT_GID_OFFSET] = mt_masked | (message_type & NCI_PKT_MT_MASK);
151}
152
153void NciMessage::set_gid(const uint8_t gid) {
154 if (this->nci_message_.size() < NCI_PKT_HEADER_SIZE) {
155 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
156 }
157 auto gid_masked = this->nci_message_[NCI_PKT_MT_GID_OFFSET] & ~NCI_PKT_GID_MASK;
158 this->nci_message_[NCI_PKT_MT_GID_OFFSET] = gid_masked | (gid & NCI_PKT_GID_MASK);
159}
160
161void NciMessage::set_oid(const uint8_t oid) {
162 if (this->nci_message_.size() < NCI_PKT_HEADER_SIZE) {
163 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
164 }
165 this->nci_message_[NCI_PKT_OID_OFFSET] = oid & NCI_PKT_OID_MASK;
166}
167
168void NciMessage::set_payload(const std::span<const uint8_t> payload) {
169 this->nci_message_.resize(NCI_PKT_HEADER_SIZE);
170 this->append(payload);
171 this->nci_message_[NCI_PKT_LENGTH_OFFSET] = this->nci_message_.size() - NCI_PKT_HEADER_SIZE;
172}
173
174void NciMessage::append(const std::span<const uint8_t> data) {
175 for (const uint8_t byte : data) {
176 this->nci_message_.push_back(byte);
177 }
178}
179
180void NciMessage::set_payload_size(const uint8_t size) { this->nci_message_.resize(NCI_PKT_HEADER_SIZE + size); }
181
182} // namespace esphome::nfc
size_t size() const
Definition helpers.h:355
void push_back(const T &value)
Definition helpers.h:325
bool empty() const
Definition helpers.h:357
void assign(InputIt first, InputIt last)
Definition helpers.h:338
void resize(size_t n)
Definition helpers.h:335
One NCI packet, held in a fixed buffer so building and reading messages never allocates.
Definition nci_message.h:16
uint8_t get_payload_size(bool recompute=false)
bool message_type_is(uint8_t message_type) const
uint8_t get_oid() const
bool simple_status_response_is(uint8_t response) const
uint8_t get_message_byte(uint8_t offset) const
std::span< const uint8_t > encode()
Stamps the payload length into the header and returns the packet ready to send.
bool gid_is(uint8_t gid) const
void set_gid(uint8_t gid)
void set_header(uint8_t message_type, uint8_t gid, uint8_t oid)
bool message_length_is(uint8_t message_length, bool recompute=false)
void set_payload_size(uint8_t size)
Sets the packet size to the header plus size payload bytes, for a bus driver filling the buffer direc...
std::span< const uint8_t > get_payload() const
The payload bytes that follow the header.
void set_oid(uint8_t oid)
void set_message(uint8_t message_type, std::span< const uint8_t > payload)
uint8_t get_gid() const
void set_message_type(uint8_t message_type)
uint8_t get_simple_status_response() const
bool oid_is(uint8_t oid) const
void set_payload(std::span< const uint8_t > payload)
uint8_t get_message_type() const
void append(std::span< const uint8_t > data)
Appends bytes to the payload; bytes that do not fit are dropped.
uint16_t size
Definition helpers.cpp:34
STL namespace.