ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
hostlink.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 hostlink.h
6 * @brief Omron Host Link (C-mode) frame codec (PC_ENABLE_HOSTLINK) - zero-heap ASCII
7 * command/response framing for the Omron serial host-link protocol, the RS-232/485
8 * sibling of FINS.
9 *
10 * A Host Link frame is ASCII:
11 * @code
12 * @ UU XX <text> FF * CR
13 * @endcode
14 * - `@` start, `UU` the 2-digit unit/node number, `XX` the 2-char header code (e.g. `RD`),
15 * `<text>` the data, `FF` the 2-hex-char FCS, then the `*` + CR (0x0D) terminator.
16 * - FCS = the 8-bit XOR of every character from `@` through the last text character,
17 * rendered as two uppercase hex digits.
18 * - A response's text begins with a 2-char end code (00 = normal).
19 *
20 * This is the frame codec (build + FCS-validated parse); the serial transport is the app's.
21 *
22 * @author Douglas Quigg (dstroy0)
23 * @date 2026
24 */
25
26#ifndef PROTOCORE_HOSTLINK_H
27#define PROTOCORE_HOSTLINK_H
28
29#include "protocore_config.h"
30
31#if PC_ENABLE_HOSTLINK
32
33#include <stddef.h>
34#include <stdint.h>
35
36/** @brief FCS: 8-bit XOR of [data, data+len). */
37uint8_t pc_hostlink_fcs(const char *data, size_t len);
38
39/**
40 * @brief Build a frame: `@UU` + header_code(2) + text + FCS(2 hex) + `*` + CR.
41 * @param node unit/node number (0-99, rendered as 2 BCD-style digits).
42 * @param header_code the 2-character header code (e.g. "RD"); must be 2 chars.
43 * @return total characters written (NOT counting the NUL), or 0 on overflow / bad input.
44 * @note The frame is NUL-terminated, so @p cap must hold the frame plus one terminator
45 * byte; the return value is the frame length, so callers may also treat @p buf as a
46 * C-string.
47 */
48size_t pc_hostlink_build(char *buf, size_t cap, uint8_t node, const char *header_code, const char *text,
49 size_t text_len);
50
51/** @brief A parsed frame; @ref text points INTO the source buffer (after the header, before the FCS). */
52struct HostlinkFrame
53{
54 uint8_t node;
55 char header_code[3]; ///< 2 chars + NUL
56 const char *text;
57 size_t text_len;
58};
59
60/**
61 * @brief Parse + FCS-validate a frame (command or response).
62 * @return true on a complete, FCS-valid `@...*CR` frame; false otherwise.
63 */
64bool pc_hostlink_parse(const char *buf, size_t len, HostlinkFrame *out);
65
66/** @brief Read a response's 2-char end code (the first two text characters) as a byte. */
67bool pc_hostlink_end_code(const HostlinkFrame *f, uint8_t *code);
68
69/**
70 * @brief Build an RD (DM-area read) command: `@UU` + `RD` + a 4-digit beginning word address + a 4-digit
71 * word count + FCS + `*` CR.
72 * @return the frame length, or 0 on overflow, an address or count outside 0..9999, or a zero count.
73 */
74size_t pc_hostlink_build_read(char *buf, size_t cap, uint8_t node, uint16_t address, uint16_t count);
75
76/**
77 * @brief Extract word @p index (0-based) from an RD response's text: a 4-hex-char value that follows the
78 * 2-character end code.
79 * @return true iff the response text holds that word and it is valid hex; false otherwise.
80 */
81bool pc_hostlink_read_word(const HostlinkFrame *f, size_t index, uint16_t *out);
82
83/**
84 * @brief Build a WR (DM-area write) command: `@UU` + `WR` + a 4-digit beginning word address + one
85 * 4-hex-char value per word + FCS + `*` CR. The PLC's response text is only the 2-character end
86 * code (read it with pc_hostlink_end_code).
87 * @return the frame length, or 0 on overflow, an address outside 0..9999, a zero @p word_count, or a
88 * null @p words.
89 */
90size_t pc_hostlink_build_write(char *buf, size_t cap, uint8_t node, uint16_t address, const uint16_t *words,
91 size_t word_count);
92
93#endif // PC_ENABLE_HOSTLINK
94
95#endif // PROTOCORE_HOSTLINK_H
User-facing configuration for ProtoCore.