20uint8_t pc_esp3_crc8(
const uint8_t *buf, uint16_t len)
28int pc_esp3_parse(
const uint8_t *raw, uint16_t len, pc_esp3_packet *out)
34 if (raw[0] != ESP3_SYNC)
42 uint16_t data_len = (uint16_t)((raw[1] << 8) | raw[2]);
43 uint8_t opt_len = raw[3];
44 uint8_t type = raw[4];
49 if (pc_esp3_crc8(&raw[1], 4) != raw[5])
53 uint32_t total = 6u + data_len + opt_len + 1u;
58 if (pc_esp3_crc8(&raw[6], (uint16_t)(data_len + opt_len)) != raw[6 + data_len + opt_len])
64 out->type = (pc_esp3_type)type;
66 out->data_len = data_len;
67 out->opt = &raw[6 + data_len];
68 out->opt_len = opt_len;
73uint16_t pc_esp3_build(pc_esp3_type type,
const uint8_t *data, uint16_t data_len,
const uint8_t *opt, uint8_t opt_len,
74 uint8_t *out, uint16_t cap)
80 uint32_t total = 6u + data_len + opt_len + 1u;
86 out[1] = (uint8_t)(data_len >> 8);
87 out[2] = (uint8_t)(data_len & 0xFF);
89 out[4] = (uint8_t)type;
90 out[5] = pc_esp3_crc8(&out[1], 4);
91 for (uint16_t i = 0; i < data_len; i++)
95 for (uint8_t i = 0; i < opt_len; i++)
97 out[6 + data_len + i] = opt[i];
99 out[6 + data_len + opt_len] = pc_esp3_crc8(&out[6], (uint16_t)(data_len + opt_len));
100 return (uint16_t)total;
103bool pc_erp1_parse(
const uint8_t *data, uint16_t len, pc_erp1 *out)
105 if (!data || !out || len < 6)
110 out->payload = (len > 6) ? data + 1 : nullptr;
111 out->payload_len = (uint8_t)(len - 6);
112 const uint8_t *
id = data + len - 5;
114 ((uint32_t)
id[0] << 24) | ((uint32_t)
id[1] << 16) | ((uint32_t)
id[2] << 8) | (uint32_t)
id[3];
115 out->status = data[len - 1];
119uint16_t pc_erp1_build(uint8_t *out, uint16_t cap, uint8_t rorg,
const uint8_t *payload, uint8_t payload_len,
120 uint32_t sender_id, uint8_t status)
122 if (!out || (payload_len && !payload))
126 uint16_t total = (uint16_t)(1 + payload_len + 4 + 1);
135 memcpy(out + p, payload, payload_len);
136 p = (uint16_t)(p + payload_len);
138 out[p++] = (uint8_t)(sender_id >> 24);
139 out[p++] = (uint8_t)(sender_id >> 16);
140 out[p++] = (uint8_t)(sender_id >> 8);
141 out[p++] = (uint8_t)sender_id;
Parameterized CRC engine - one source of truth for every cyclic redundancy check.
constexpr pc_crc_params PC_CRC8_SMBUS
CRC-8/SMBUS (a.k.a. CRC-8). check = 0xF4.
uint32_t pc_crc(const pc_crc_params *p, const uint8_t *data, size_t len)
One-shot CRC of len octets at data.
EnOcean ESP3 serial codec (PC_ENABLE_ENOCEAN) - energy-harvesting 868 MHz.
#define PC_ENOCEAN_MAX_DATA
Reject an ESP3 telegram whose declared data length exceeds this (framing sanity).