8namespace packet_transport {
48static const char *
const TAG =
"packet_transport";
50static size_t round4(
size_t value) {
return (value + 3) & ~3; }
57static const uint16_t MAGIC_NUMBER = 0x4553;
58static const uint16_t MAGIC_PING = 0x5048;
59static const uint32_t PREF_HASH = 0x45535043;
76static const size_t MAX_PING_KEYS = 4;
78static inline void add(std::vector<uint8_t> &vec, uint32_t data) {
79 vec.push_back(data & 0xFF);
80 vec.push_back((data >> 8) & 0xFF);
81 vec.push_back((data >> 16) & 0xFF);
82 vec.push_back((data >> 24) & 0xFF);
87 PacketDecoder(
const uint8_t *buffer,
size_t len) : buffer_(buffer), len_(
len) {}
90 if (this->position_ == this->len_)
92 auto len = this->buffer_[this->position_];
93 if (
len == 0 || this->position_ + 1 +
len > this->len_ ||
len >= maxlen)
96 memcpy(data, this->buffer_ + this->position_,
len);
98 this->position_ +=
len;
103 if (this->position_ +
sizeof(T) > this->len_)
106 for (
size_t i = 0; i !=
sizeof(T); ++i) {
107 value += this->buffer_[this->position_++] << (i * 8);
113 template<
typename T>
DecodeResult decode(uint8_t key, T &data) {
114 if (this->position_ == this->len_)
116 if (this->buffer_[this->position_] != key)
118 if (this->position_ + 1 +
sizeof(T) > this->len_)
122 for (
size_t i = 0; i !=
sizeof(T); ++i) {
123 value += this->buffer_[this->position_++] << (i * 8);
129 template<
typename T>
DecodeResult decode(uint8_t key,
char *buf,
size_t buflen, T &data) {
130 if (this->position_ == this->len_)
132 if (this->buffer_[this->position_] != key)
136 for (
size_t i = 0; i !=
sizeof(T); ++i) {
137 value += this->buffer_[this->position_++] << (i * 8);
140 return this->decode_string(buf, buflen);
144 if (this->position_ == this->len_)
146 if (this->buffer_[this->position_] != key)
152 size_t get_remaining_size()
const {
return this->len_ - this->position_; }
155 bool bump_to(
size_t boundary) {
156 auto newpos = this->position_;
157 auto offset = this->position_ % boundary;
159 newpos += boundary - offset;
161 if (newpos >= this->len_)
163 this->position_ = newpos;
167 bool decrypt(
const uint32_t *key) {
168 if (this->get_remaining_size() % 4 != 0) {
171 xxtea::decrypt((uint32_t *) (this->buffer_ + this->position_), this->get_remaining_size() / 4, key);
176 const uint8_t *buffer_;
181static inline void add(std::vector<uint8_t> &vec, uint8_t data) { vec.push_back(data); }
182static inline void add(std::vector<uint8_t> &vec, uint16_t data) {
183 vec.push_back((uint8_t) data);
184 vec.push_back((uint8_t) (data >> 8));
186static inline void add(std::vector<uint8_t> &vec,
DataKey data) { vec.push_back(data); }
187static void add(std::vector<uint8_t> &vec,
const char *str) {
188 auto len = strlen(str);
190 for (
size_t i = 0; i !=
len; i++) {
191 vec.push_back(*str++);
197 if (strlen(this->
name_) > 255) {
212 ESP_LOGV(TAG,
"Rolling code incremented, upper part now %u", (
unsigned) this->
rolling_code_[1]);
215 for (
auto &sensor : this->
sensors_) {
216 sensor.sensor->add_on_state_callback([
this, &sensor](
float x) {
218 sensor.updated =
true;
222#ifdef USE_BINARY_SENSOR
224 sensor.sensor->add_on_state_callback([
this, &sensor](
bool value) {
226 sensor.updated =
true;
231 add(this->
header_, MAGIC_NUMBER);
234 while (this->
header_.size() & 0x3)
250 add(this->
data_, pkey.second);
257 auto header_len = round4(this->
header_.size());
259 auto encode_buffer = std::vector<uint8_t>(round4(header_len +
len));
260 memcpy(encode_buffer.data(), this->header_.data(), this->header_.size());
261 memcpy(encode_buffer.data() + header_len, this->data_.data(), this->data_.size());
264 (uint32_t *) this->encryption_key_.data());
270 auto len = 1 + 1 + 1 + strlen(
id);
271 if (
len + this->
header_.size() + this->data_.size() > this->get_max_packet_size()) {
274 add(this->
data_, key);
275 add(this->
data_, (uint8_t) data);
276 add(this->
data_,
id);
279 FuData udata{.f32 = data};
284 auto len = 4 + 1 + 1 + strlen(
id);
285 if (
len + this->
header_.size() + this->data_.size() > this->get_max_packet_size()) {
288 add(this->
data_, key);
289 add(this->
data_, data);
290 add(this->
data_,
id);
297 for (
auto &sensor : this->
sensors_) {
298 if (all || sensor.updated) {
299 sensor.updated =
false;
304#ifdef USE_BINARY_SENSOR
306 if (all || sensor.updated) {
307 sensor.updated =
false;
317 auto now =
millis() / 1000;
327 if (this->
ping_keys_.count(name) == 0 && this->ping_keys_.size() == MAX_PING_KEYS) {
328 ESP_LOGW(TAG,
"Ping key from %s discarded", name);
333 ESP_LOGV(TAG,
"Ping key from %s now %X", name, (
unsigned) key);
336static bool process_rolling_code(
Provider &provider, PacketDecoder &decoder) {
337 uint32_t code0, code1;
339 ESP_LOGW(TAG,
"Rolling code requires 8 bytes");
343 ESP_LOGW(TAG,
"Rolling code for %s %08lX:%08lX is old", provider.
name, (
unsigned long) code1,
344 (
unsigned long) code0);
349 ESP_LOGV(TAG,
"Saw new rolling code for %s %08lX:%08lX", provider.
name, (
unsigned long) code1, (
unsigned long) code0);
358 PacketDecoder decoder((data.data()), data.size());
364 ESP_LOGD(TAG,
"Short buffer");
367 if (magic != MAGIC_NUMBER && magic != MAGIC_PING) {
368 ESP_LOGV(TAG,
"Bad magic %X", magic);
372 if (decoder.decode_string(namebuf,
sizeof namebuf) !=
DECODE_OK) {
373 ESP_LOGV(TAG,
"Bad hostname length");
376 if (strcmp(this->
name_, namebuf) == 0) {
377 ESP_LOGVV(TAG,
"Ignoring our own data");
380 if (magic == MAGIC_PING) {
383 ESP_LOGW(TAG,
"Bad ping request");
387 ESP_LOGV(TAG,
"Updated ping key for %s to %08X", namebuf, (
unsigned) key);
392 ESP_LOGVV(TAG,
"Unknown hostname %s", namebuf);
395 ESP_LOGV(TAG,
"Found hostname %s", namebuf);
400#ifdef USE_BINARY_SENSOR
404 if (!decoder.bump_to(4)) {
405 ESP_LOGW(TAG,
"Bad packet length %zu", data.size());
407 auto len = decoder.get_remaining_size();
409 ESP_LOGW(TAG,
"Bad payload length %zu",
len);
416 ping_key_seen =
true;
419 decoder.decrypt((
const uint32_t *) provider.
encryption_key.data());
422 ESP_LOGV(TAG,
"No key byte");
427 if (!process_rolling_code(provider, decoder))
430 ESP_LOGV(TAG,
"Expected rolling_key or data_key, got %X",
byte);
434 while (decoder.get_remaining_size() != 0) {
439 ping_key_seen =
true;
440 ESP_LOGV(TAG,
"Found good ping key %X", (
unsigned) key);
442 ESP_LOGV(TAG,
"Unknown ping key %X", (
unsigned) key);
446 if (!ping_key_seen) {
447 ESP_LOGW(TAG,
"Ping key not seen");
452 ESP_LOGV(TAG,
"Got binary sensor %s %d", namebuf,
byte);
453#ifdef USE_BINARY_SENSOR
454 if (binary_sensors.count(namebuf) != 0)
455 binary_sensors[namebuf]->publish_state(
byte != 0);
460 ESP_LOGV(TAG,
"Got sensor %s %f", namebuf, rdata.f32);
462 if (sensors.count(namebuf) != 0)
463 sensors[namebuf]->publish_state(rdata.f32);
468 ESP_LOGW(TAG,
"Unknown key %X",
byte);
469 ESP_LOGD(TAG,
"Buffer pos: %zu contents: %s", data.size() - decoder.get_remaining_size(),
477 ESP_LOGCONFIG(TAG,
"Packet Transport:");
479 ESP_LOGCONFIG(TAG,
" Encrypted: %s", YESNO(this->
is_encrypted_()));
483 ESP_LOGCONFIG(TAG,
" Sensor: %s", sensor.id);
485#ifdef USE_BINARY_SENSOR
487 ESP_LOGCONFIG(TAG,
" Binary Sensor: %s", sensor.id);
490 ESP_LOGCONFIG(TAG,
" Remote host: %s", host.first.c_str());
491 ESP_LOGCONFIG(TAG,
" Encrypted: %s", YESNO(!host.second.encryption_key.empty()));
494 ESP_LOGCONFIG(TAG,
" Sensor: %s", sensor.first.c_str());
496#ifdef USE_BINARY_SENSOR
498 ESP_LOGCONFIG(TAG,
" Binary Sensor: %s", sensor.first.c_str());
531 ESP_LOGV(TAG,
"Sent new ping request %08X", (
unsigned) this->
ping_key_);