DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
enip.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 enip.h
6 * @brief EtherNet/IP encapsulation codec (DETWS_ENABLE_ENIP) - zero-heap builder + parser
7 * for the ODVA EtherNet/IP encapsulation layer (TCP/UDP 44818), the transport that
8 * carries CIP. The reusable base for CIP / EtherNet/IP explicit messaging.
9 *
10 * The 24-octet encapsulation header (all fields LITTLE-endian):
11 * @code
12 * Command(2) Length(2) SessionHandle(4) Status(4) SenderContext(8) Options(4) <data>
13 * @endcode
14 * Length is the octet count of the command-specific data that follows the header.
15 * - RegisterSession (0x0065): data = protocol version(2)=1 + options flags(2)=0; the reply
16 * carries the assigned session handle.
17 * - SendRRData (0x006F): data = interface handle(4)=0 + timeout(2) + a Common Packet Format
18 * block: item count(2), then items (Type ID(2), Length(2), data). Unconnected explicit
19 * messaging uses a Null Address item (0x0000) then an Unconnected Data item (0x00B2)
20 * carrying the CIP request/response.
21 *
22 * Commands + CPF item types verified against the Wireshark ENIP dissector. This codec frames
23 * the encapsulation; the CIP message inside the Unconnected Data item is the application's.
24 *
25 * @author Douglas Quigg (dstroy0)
26 * @date 2026
27 */
28
29#ifndef DETERMINISTICESPASYNCWEBSERVER_ENIP_H
30#define DETERMINISTICESPASYNCWEBSERVER_ENIP_H
31
32#include "ServerConfig.h"
33
34#if DETWS_ENABLE_ENIP
35
36#include <stddef.h>
37#include <stdint.h>
38
39#define EIP_HEADER_SIZE 24
40
41// Encapsulation commands.
42#define EIP_CMD_LIST_SERVICES 0x0004
43#define EIP_CMD_LIST_IDENTITY 0x0063
44#define EIP_CMD_LIST_INTERFACES 0x0064
45#define EIP_CMD_REGISTER_SESSION 0x0065
46#define EIP_CMD_UNREGISTER_SESSION 0x0066
47#define EIP_CMD_SEND_RR_DATA 0x006F
48#define EIP_CMD_SEND_UNIT_DATA 0x0070
49
50#define EIP_STATUS_SUCCESS 0x00000000u
51
52// Common Packet Format item type ids.
53#define EIP_CPF_NULL 0x0000 ///< null address item
54#define EIP_CPF_CONNECTED_ADDRESS 0x00A1 ///< connected address item
55#define EIP_CPF_CONNECTED_DATA 0x00B1 ///< connected data item
56#define EIP_CPF_UNCONNECTED_DATA 0x00B2 ///< unconnected data item (carries the CIP message)
57
58/** @brief The 24-octet encapsulation header. */
59struct EipHeader
60{
61 uint16_t command;
62 uint16_t length; ///< octets of command-specific data after the header
63 uint32_t session_handle;
64 uint32_t status;
65 uint8_t sender_context[8];
66 uint32_t options;
67};
68
69/** @brief Build the encapsulation header + command data. Returns total octets, or 0. */
70size_t eip_build(uint8_t *buf, size_t cap, const EipHeader *h, const uint8_t *data, size_t data_len);
71
72/** @brief Parse the encapsulation header and slice the command data. */
73bool eip_parse(const uint8_t *buf, size_t len, EipHeader *out, const uint8_t **data, size_t *data_len);
74
75/** @brief Build a RegisterSession request (protocol version 1). @p sender_context may be null (zeros). */
76size_t eip_build_register_session(uint8_t *buf, size_t cap, const uint8_t sender_context[8]);
77
78/**
79 * @brief Build a SendRRData request wrapping @p cip as an unconnected message (Null Address
80 * item + Unconnected Data item).
81 */
82size_t eip_build_send_rr_data(uint8_t *buf, size_t cap, uint32_t session_handle, const uint8_t sender_context[8],
83 uint16_t timeout, const uint8_t *cip, size_t cip_len);
84
85/** @brief From a SendRRData command-data block, extract the Unconnected Data item (the CIP reply). */
86bool eip_parse_send_rr_data(const uint8_t *data, size_t data_len, const uint8_t **cip, size_t *cip_len);
87
88#endif // DETWS_ENABLE_ENIP
89
90#endif // DETERMINISTICESPASYNCWEBSERVER_ENIP_H
User-facing configuration for DeterministicESPAsyncWebServer.