11#if DETWS_ENABLE_HOSTLINK
15uint8_t hostlink_fcs(
const char *data,
size_t len)
18 for (
size_t i = 0; i < len; i++)
19 f ^= (uint8_t)data[i];
23static char hex_digit(uint8_t v)
25 return (
char)(v < 10 ?
'0' + v :
'A' + (v - 10));
29static int hex_val(
char c)
31 if (c >=
'0' && c <=
'9')
33 if (c >=
'A' && c <=
'F')
35 if (c >=
'a' && c <=
'f')
40size_t hostlink_build(
char *buf,
size_t cap, uint8_t node,
const char *header_code,
const char *text,
size_t text_len)
42 if (!buf || !header_code || node > 99 || (text_len && !text))
44 if (header_code[0] ==
'\0' || header_code[1] ==
'\0')
46 size_t total = 1 + 2 + 2 + text_len + 2 + 2;
52 buf[p++] = (char)(
'0' + node / 10);
53 buf[p++] = (char)(
'0' + node % 10);
54 buf[p++] = header_code[0];
55 buf[p++] = header_code[1];
58 memcpy(buf + p, text, text_len);
61 uint8_t f = hostlink_fcs(buf, p);
62 buf[p++] = hex_digit((uint8_t)(f >> 4));
63 buf[p++] = hex_digit((uint8_t)(f & 0x0F));
70bool hostlink_parse(
const char *buf,
size_t len, HostlinkFrame *out)
73 if (!buf || !out || len < 9)
75 if (buf[0] !=
'@' || buf[len - 1] !=
'\r' || buf[len - 2] !=
'*')
77 if (buf[1] <
'0' || buf[1] >
'9' || buf[2] <
'0' || buf[2] >
'9')
80 size_t fcs_pos = len - 4;
81 int hi = hex_val(buf[fcs_pos]);
82 int lo = hex_val(buf[fcs_pos + 1]);
85 uint8_t got = (uint8_t)((hi << 4) | lo);
86 if (hostlink_fcs(buf, fcs_pos) != got)
89 out->node = (uint8_t)((buf[1] -
'0') * 10 + (buf[2] -
'0'));
90 out->header_code[0] = buf[3];
91 out->header_code[1] = buf[4];
92 out->header_code[2] =
'\0';
94 out->text_len = fcs_pos - 5;
98bool hostlink_end_code(
const HostlinkFrame *f, uint8_t *code)
100 if (!f || f->text_len < 2)
102 int hi = hex_val(f->text[0]);
103 int lo = hex_val(f->text[1]);
104 if (hi < 0 || lo < 0)
107 *code = (uint8_t)((hi << 4) | lo);
Omron Host Link (C-mode) frame codec (DETWS_ENABLE_HOSTLINK) - zero-heap ASCII command/response frami...