DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
rawl2.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 rawl2.h
6 * @brief Raw Layer-2 Ethernet frame codec (DETWS_ENABLE_RAWL2).
7 *
8 * The host-testable core of raw-L2 frame TX/RX: build and parse Ethernet II frames (and 802.1Q
9 * VLAN-tagged frames) so the app can inject/receive arbitrary L2 frames - the basis for the raw-L2
10 * industrial protocols (PROFINET DCP, IEC 61850 GOOSE, POWERLINK, SERCOS) and for custom management /
11 * proprietary MAC framing. On device the bytes go out via `esp_eth_transmit()` (wired) or
12 * `esp_wifi_80211_tx()` (Wi-Fi); the MAC normally appends the FCS, so the builder emits the frame
13 * without it and `detws_eth_fcs` is provided for the cases that need it.
14 *
15 * Ethernet II: [dst MAC 6][src MAC 6][ethertype 2][payload]
16 * 802.1Q: [dst 6][src 6][0x8100][TCI 2][ethertype 2][payload]
17 *
18 * Pure, zero heap, no stdlib, host-testable.
19 */
20
21#ifndef DETERMINISTICESPASYNCWEBSERVER_RAWL2_H
22#define DETERMINISTICESPASYNCWEBSERVER_RAWL2_H
23
24#include "ServerConfig.h"
25#include <stddef.h>
26#include <stdint.h>
27
28#if DETWS_ENABLE_RAWL2
29
30// Ethernet II framing sizes + ethertypes: wire values, so integer constants in a namespacing struct.
31struct RawL2
32{
33 static constexpr uint16_t ETH_ALEN = 6; ///< MAC address length.
34 static constexpr uint16_t ETH_HDR_LEN = 14; ///< dst + src + ethertype.
35 static constexpr uint16_t ETH_VLAN_HDR_LEN = 18; ///< with the 4-octet 802.1Q tag.
36 static constexpr uint16_t ETH_TPID_8021Q = 0x8100; ///< 802.1Q tag protocol id.
37 static constexpr uint16_t ETHERTYPE_IPV4 = 0x0800;
38 static constexpr uint16_t ETHERTYPE_ARP = 0x0806;
39 static constexpr uint16_t ETHERTYPE_PROFINET = 0x8892; ///< PROFINET RT / DCP.
40 static constexpr uint16_t ETHERTYPE_GOOSE = 0x88B8; ///< IEC 61850 GOOSE.
41 static constexpr uint16_t ETHERTYPE_POWERLINK = 0x88AB;
42};
43
44/**
45 * @brief Build an Ethernet II frame (no FCS).
46 * @return the frame length (14 + payload_len), or 0 if it won't fit or a pointer is null.
47 */
48size_t detws_eth_build(const uint8_t *dst, const uint8_t *src, uint16_t ethertype, const uint8_t *payload,
49 size_t payload_len, uint8_t *out, size_t cap);
50
51/**
52 * @brief Build an 802.1Q VLAN-tagged Ethernet frame (no FCS).
53 * @param pcp priority code point (0..7).
54 * @param dei drop-eligible indicator.
55 * @param vid VLAN id (0..4095).
56 * @return the frame length (18 + payload_len), or 0 on overflow.
57 */
58size_t detws_eth_build_vlan(const uint8_t *dst, const uint8_t *src, uint8_t pcp, bool dei, uint16_t vid,
59 uint16_t ethertype, const uint8_t *payload, size_t payload_len, uint8_t *out, size_t cap);
60
61/** @brief A parsed Ethernet frame (pointers into the input). */
62struct EthFrame
63{
64 const uint8_t *dst;
65 const uint8_t *src;
66 bool vlan;
67 uint8_t pcp;
68 uint16_t vid;
69 uint16_t ethertype;
70 const uint8_t *payload;
71 size_t payload_len;
72};
73
74/** @brief Parse an Ethernet II / 802.1Q frame (FCS not expected). @return true if well-formed. */
75bool detws_eth_parse(const uint8_t *frame, size_t len, EthFrame *out);
76
77/** @brief IEEE 802.3 frame check sequence (CRC-32, reflected, init 0xFFFFFFFF, xorout 0xFFFFFFFF). */
78uint32_t detws_eth_fcs(const uint8_t *bytes, size_t len);
79
80#endif // DETWS_ENABLE_RAWL2
81#endif // DETERMINISTICESPASYNCWEBSERVER_RAWL2_H
User-facing configuration for DeterministicESPAsyncWebServer.