DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
fins.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 fins.h
6 * @brief Omron FINS frame codec (DETWS_ENABLE_FINS) - zero-heap command/response builder +
7 * parser for the Factory Interface Network Service (FINS/UDP), so a device can talk
8 * to an Omron PLC over the shipped UDP transport.
9 *
10 * A FINS message is a 10-octet header then the command code and data:
11 * @code
12 * ICF RSV GCT DNA DA1 DA2 SNA SA1 SA2 SID MRC SRC [params / data...]
13 * @endcode
14 * - ICF: bit 6 = command(0)/response(1), bit 0 = response required(0)/not(1), bit 7 = use
15 * gateway. RSV = 0, GCT = 0x02. DNA/DA1/DA2 = destination net/node/unit; SNA/SA1/SA2 =
16 * source; SID = service id (echoed in the response).
17 * - MRC/SRC are the main/sub command code. A response inserts a 2-octet end code
18 * (MRES/SRES) before its data; MRES = SRES = 0 means normal completion.
19 * - Multi-octet command parameters (addresses, counts) are big-endian.
20 *
21 * FINS/UDP carries this frame directly (UDP provides integrity, so there is no checksum);
22 * FINS/TCP would prepend its own header. This is the message codec; the send is the app's.
23 *
24 * @author Douglas Quigg (dstroy0)
25 * @date 2026
26 */
27
28#ifndef DETERMINISTICESPASYNCWEBSERVER_FINS_H
29#define DETERMINISTICESPASYNCWEBSERVER_FINS_H
30
31#include "ServerConfig.h"
32
33#if DETWS_ENABLE_FINS
34
35#include <stddef.h>
36#include <stdint.h>
37
38#define FINS_HEADER_SIZE 10
39
40#define FINS_ICF_COMMAND 0x80 ///< command, response required, gateway
41#define FINS_ICF_RESPONSE 0xC0 ///< response
42#define FINS_ICF_NO_RESPONSE 0x01 ///< OR into ICF: response not required
43
44// Common command codes (MRC, SRC).
45#define FINS_MRC_MEMORY_AREA 0x01
46#define FINS_SRC_MEMORY_AREA_READ 0x01
47#define FINS_SRC_MEMORY_AREA_WRITE 0x02
48
49/** @brief The 10-octet FINS routing header. */
50struct FinsHeader
51{
52 uint8_t icf;
53 uint8_t rsv;
54 uint8_t gct;
55 uint8_t dna;
56 uint8_t da1;
57 uint8_t da2; ///< destination network / node / unit
58 uint8_t sna;
59 uint8_t sa1;
60 uint8_t sa2; ///< source network / node / unit
61 uint8_t sid; ///< service id
62};
63
64/** @brief Build a command frame: header + MRC + SRC + params. Returns total octets, or 0. */
65size_t fins_build_command(uint8_t *buf, size_t cap, const FinsHeader *h, uint8_t mrc, uint8_t src,
66 const uint8_t *params, size_t params_len);
67
68/**
69 * @brief Build a Memory Area Read command (0101): area code, 2-octet word address + bit,
70 * 2-octet item count. The number of items is big-endian.
71 */
72size_t fins_build_memory_area_read(uint8_t *buf, size_t cap, const FinsHeader *h, uint8_t area, uint16_t address,
73 uint8_t bit, uint16_t count);
74
75/** @brief A parsed command (request side). @ref params points INTO the source buffer. */
76struct FinsCommand
77{
78 FinsHeader header;
79 uint8_t mrc;
80 uint8_t src;
81 const uint8_t *params;
82 size_t params_len;
83};
84
85/** @brief Parse a command frame (header + MRC + SRC + params). */
86bool fins_parse_command(const uint8_t *buf, size_t len, FinsCommand *out);
87
88/** @brief A parsed response. @ref data points INTO the source buffer. */
89struct FinsResponse
90{
91 FinsHeader header;
92 uint8_t mrc;
93 uint8_t src; ///< echoed command code
94 uint8_t mres;
95 uint8_t sres; ///< end code (0/0 = normal completion)
96 const uint8_t *data;
97 size_t data_len;
98};
99
100/** @brief Parse a response frame (header + MRC + SRC + MRES + SRES + data). */
101bool fins_parse_response(const uint8_t *buf, size_t len, FinsResponse *out);
102
103#endif // DETWS_ENABLE_FINS
104
105#endif // DETERMINISTICESPASYNCWEBSERVER_FINS_H
User-facing configuration for DeterministicESPAsyncWebServer.