DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
fins.cpp
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.cpp
6 * @brief Omron FINS command/response builder + parser (pure, host-tested).
7 */
8
10
11#if DETWS_ENABLE_FINS
12
13#include <string.h>
14
15static size_t write_header(uint8_t *buf, const FinsHeader *h)
16{
17 buf[0] = h->icf;
18 buf[1] = h->rsv;
19 buf[2] = h->gct;
20 buf[3] = h->dna;
21 buf[4] = h->da1;
22 buf[5] = h->da2;
23 buf[6] = h->sna;
24 buf[7] = h->sa1;
25 buf[8] = h->sa2;
26 buf[9] = h->sid;
27 return FINS_HEADER_SIZE;
28}
29
30static void read_header(const uint8_t *buf, FinsHeader *h)
31{
32 h->icf = buf[0];
33 h->rsv = buf[1];
34 h->gct = buf[2];
35 h->dna = buf[3];
36 h->da1 = buf[4];
37 h->da2 = buf[5];
38 h->sna = buf[6];
39 h->sa1 = buf[7];
40 h->sa2 = buf[8];
41 h->sid = buf[9];
42}
43
44size_t fins_build_command(uint8_t *buf, size_t cap, const FinsHeader *h, uint8_t mrc, uint8_t src,
45 const uint8_t *params, size_t params_len)
46{
47 if (!buf || !h || (params_len && !params))
48 return 0;
49 size_t total = FINS_HEADER_SIZE + 2 + params_len;
50 if (total > cap)
51 return 0;
52 size_t p = write_header(buf, h);
53 buf[p++] = mrc;
54 buf[p++] = src;
55 if (params_len)
56 {
57 memcpy(buf + p, params, params_len);
58 p += params_len;
59 }
60 return p;
61}
62
63size_t fins_build_memory_area_read(uint8_t *buf, size_t cap, const FinsHeader *h, uint8_t area, uint16_t address,
64 uint8_t bit, uint16_t count)
65{
66 uint8_t params[6];
67 params[0] = area;
68 params[1] = (uint8_t)(address >> 8);
69 params[2] = (uint8_t)(address & 0xFF);
70 params[3] = bit;
71 params[4] = (uint8_t)(count >> 8);
72 params[5] = (uint8_t)(count & 0xFF);
73 return fins_build_command(buf, cap, h, FINS_MRC_MEMORY_AREA, FINS_SRC_MEMORY_AREA_READ, params, sizeof(params));
74}
75
76bool fins_parse_command(const uint8_t *buf, size_t len, FinsCommand *out)
77{
78 if (!buf || !out || len < FINS_HEADER_SIZE + 2)
79 return false;
80 read_header(buf, &out->header);
81 out->mrc = buf[FINS_HEADER_SIZE];
82 out->src = buf[FINS_HEADER_SIZE + 1];
83 out->params = buf + FINS_HEADER_SIZE + 2;
84 out->params_len = len - (FINS_HEADER_SIZE + 2);
85 return true;
86}
87
88bool fins_parse_response(const uint8_t *buf, size_t len, FinsResponse *out)
89{
90 if (!buf || !out || len < FINS_HEADER_SIZE + 4) // header + MRC + SRC + MRES + SRES
91 return false;
92 read_header(buf, &out->header);
93 out->mrc = buf[FINS_HEADER_SIZE];
94 out->src = buf[FINS_HEADER_SIZE + 1];
95 out->mres = buf[FINS_HEADER_SIZE + 2];
96 out->sres = buf[FINS_HEADER_SIZE + 3];
97 out->data = buf + FINS_HEADER_SIZE + 4;
98 out->data_len = len - (FINS_HEADER_SIZE + 4);
99 return true;
100}
101
102#endif // DETWS_ENABLE_FINS
Omron FINS frame codec (DETWS_ENABLE_FINS) - zero-heap command/response builder + parser for the Fact...