15size_t pc_tpkt_build(uint8_t *buf,
size_t cap,
const uint8_t *payload,
size_t payload_len)
17 if (!buf || (payload_len && !payload))
21 size_t total = TPKT_HEADER_SIZE + payload_len;
22 if (total > 0xFFFF || total > cap)
26 buf[0] = TPKT_VERSION;
28 buf[2] = (uint8_t)(total >> 8);
29 buf[3] = (uint8_t)(total & 0xFF);
32 memcpy(buf + TPKT_HEADER_SIZE, payload, payload_len);
37bool pc_tpkt_parse(
const uint8_t *buf,
size_t len,
const uint8_t **payload,
size_t *payload_len,
size_t *consumed)
39 if (!buf || len < TPKT_HEADER_SIZE)
43 if (buf[0] != TPKT_VERSION)
47 size_t total = ((size_t)buf[2] << 8) | buf[3];
48 if (total < TPKT_HEADER_SIZE || total > len)
54 *payload = buf + TPKT_HEADER_SIZE;
58 *payload_len = total - TPKT_HEADER_SIZE;
67size_t pc_cotp_build_dt(uint8_t *buf,
size_t cap,
const uint8_t *data,
size_t data_len,
bool eot)
69 if (!buf || (data_len && !data))
73 size_t total = COTP_DT_HEADER_LEN + data_len;
78 buf[0] = COTP_DT_HEADER_LEN - 1;
80 buf[2] = (uint8_t)(eot ? COTP_EOT : 0);
83 memcpy(buf + COTP_DT_HEADER_LEN, data, data_len);
88size_t pc_cotp_build_cr(uint8_t *buf,
size_t cap, uint16_t src_ref, uint8_t tpdu_size_code,
const uint8_t *extra_params,
91 if (!buf || (extra_len && !extra_params))
97 size_t after_li = 1 + 2 + 2 + 1 + 3 + extra_len;
98 size_t total = 1 + after_li;
99 if (after_li > 0xFF || total > cap)
104 buf[p++] = (uint8_t)after_li;
108 buf[p++] = (uint8_t)(src_ref >> 8);
109 buf[p++] = (uint8_t)(src_ref & 0xFF);
111 buf[p++] = COTP_PARAM_TPDU_SIZE;
113 buf[p++] = tpdu_size_code;
116 memcpy(buf + p, extra_params, extra_len);
122size_t pc_cotp_build_cc(uint8_t *buf,
size_t cap, uint16_t dst_ref, uint16_t src_ref, uint8_t tpdu_size_code,
123 const uint8_t *extra_params,
size_t extra_len)
125 if (!buf || (extra_len && !extra_params))
131 size_t after_li = 1 + 2 + 2 + 1 + 3 + extra_len;
132 size_t total = 1 + after_li;
133 if (after_li > 0xFF || total > cap)
138 buf[p++] = (uint8_t)after_li;
140 buf[p++] = (uint8_t)(dst_ref >> 8);
141 buf[p++] = (uint8_t)(dst_ref & 0xFF);
142 buf[p++] = (uint8_t)(src_ref >> 8);
143 buf[p++] = (uint8_t)(src_ref & 0xFF);
145 buf[p++] = COTP_PARAM_TPDU_SIZE;
147 buf[p++] = tpdu_size_code;
150 memcpy(buf + p, extra_params, extra_len);
156bool pc_cotp_parse(
const uint8_t *buf,
size_t len, CotpHeader *out)
158 if (!buf || !out || len < 2)
163 size_t header = (size_t)li + 1;
164 if (header > len || li < 1)
169 out->code = (uint8_t)(buf[1] & 0xF0);
176 if (out->code == COTP_DT)
182 out->eot = (buf[2] & COTP_EOT) != 0;
183 out->data = buf + header;
184 out->data_len = len - header;
187 if (out->code == COTP_CR || out->code == COTP_CC)
193 out->dst_ref = (uint16_t)((buf[2] << 8) | buf[3]);
194 out->src_ref = (uint16_t)((buf[4] << 8) | buf[5]);
TPKT (RFC 1006) + COTP / ISO 8073 X.224 class-0 frame codec (PC_ENABLE_COTP) - zero-heap "ISO transpo...