DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
enocean.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file enocean.h
6 * @brief EnOcean ESP3 serial codec (DETWS_ENABLE_ENOCEAN) - energy-harvesting 868 MHz.
7 *
8 * A UART telegram codec for EnOcean Serial Protocol 3 (ESP3), the framing every USB /
9 * serial EnOcean gateway (TCM 310 / USB 300) speaks. A telegram is:
10 *
11 * 0x55 | data-len (2, big-endian) | opt-len (1) | packet-type (1) | CRC8H
12 * | data[data-len] | opt[opt-len] | CRC8D
13 *
14 * where CRC8H protects the 4 header bytes and CRC8D protects the data + optional data (both
15 * CRC-8, polynomial 0x07, init 0). esp3_parse() frames one telegram out of a byte stream,
16 * resynchronising on a bad sync / CRC, and esp3_build() assembles one. This is the radio-
17 * plugin codec for the gateway: an inbound RADIO_ERP1 telegram carries a sender id (its
18 * source address) and payload; bridge it northbound with det_gw_uplink(). Pure - you feed
19 * it the UART bytes - so it is fully host-testable. See example 13.EnOceanGateway.
20 *
21 * @author Douglas Quigg (dstroy0)
22 * @date 2026
23 */
24
25#ifndef DETERMINISTICESPASYNCWEBSERVER_ENOCEAN_H
26#define DETERMINISTICESPASYNCWEBSERVER_ENOCEAN_H
27
28#include "ServerConfig.h"
29
30#if DETWS_ENABLE_ENOCEAN
31
32#include <stddef.h>
33#include <stdint.h>
34
35/** @brief ESP3 sync byte that starts every telegram. */
36#define ESP3_SYNC 0x55
37
38/** @brief ESP3 packet types (the common ones). */
39enum class esp3_type : uint8_t
40{
41 ESP3_RADIO_ERP1 = 0x01,
42 ESP3_RESPONSE = 0x02,
43 ESP3_RADIO_SUB_TEL = 0x03,
44 ESP3_EVENT = 0x04,
45 ESP3_COMMON_COMMAND = 0x05,
46 ESP3_SMART_ACK = 0x06,
47 ESP3_REMOTE_MAN = 0x07,
48 ESP3_RADIO_ERP2 = 0x0A,
49};
50
51/** @brief A parsed ESP3 telegram (pointers alias the caller's buffer). */
52struct esp3_packet
53{
54 const uint8_t *data; ///< data field
55 const uint8_t *opt; ///< optional-data field
56 uint16_t data_len; ///< data length
57 uint8_t opt_len; ///< optional-data length
58 esp3_type type; ///< packet type (esp3_type)
59};
60
61/** @brief CRC-8 used by ESP3 (polynomial 0x07, MSB-first, init 0x00). */
62uint8_t esp3_crc8(const uint8_t *buf, uint16_t len);
63
64/**
65 * @brief Frame one ESP3 telegram from the front of @p raw.
66 * @return the telegram length consumed (> 0, fields in @p out) if a valid telegram is at
67 * @p raw[0]; 0 if more bytes are needed to complete it; -1 if @p raw[0] is not a
68 * valid telegram start (wrong sync, header CRC, data CRC, or an over-length data
69 * field) - the caller should drop one byte and retry to resynchronise.
70 */
71int esp3_parse(const uint8_t *raw, uint16_t len, esp3_packet *out);
72
73/**
74 * @brief Assemble an ESP3 telegram into @p out.
75 * @return the total telegram length, or 0 if it would not fit @p cap or @p data_len exceeds
76 * DETWS_ENOCEAN_MAX_DATA.
77 */
78uint16_t esp3_build(esp3_type type, const uint8_t *data, uint16_t data_len, const uint8_t *opt, uint8_t opt_len,
79 uint8_t *out, uint16_t cap);
80
81#endif // DETWS_ENABLE_ENOCEAN
82
83#endif // DETERMINISTICESPASYNCWEBSERVER_ENOCEAN_H
User-facing configuration for DeterministicESPAsyncWebServer.