16size_t pc_hislip_build_header(uint8_t *buf,
size_t cap, HislipMsg type, uint8_t control, uint32_t parameter,
19 if (!buf || cap < PC_HISLIP_HEADER_LEN)
25 buf[2] =
static_cast<uint8_t
>(type);
29 return PC_HISLIP_HEADER_LEN;
32bool pc_hislip_parse_header(
const uint8_t *buf,
size_t len, HislipHeader *out)
34 if (!buf || !out || len < PC_HISLIP_HEADER_LEN || buf[0] !=
'H' || buf[1] !=
'S')
38 out->type =
static_cast<HislipMsg
>(buf[2]);
39 out->control = buf[3];
46static size_t build_with_payload(uint8_t *buf,
size_t cap, HislipMsg type, uint8_t control, uint32_t parameter,
47 const uint8_t *payload,
size_t payload_len)
49 if (!buf || (payload_len && !payload))
53 size_t total = PC_HISLIP_HEADER_LEN + payload_len;
58 pc_hislip_build_header(buf, cap, type, control, parameter, payload_len);
61 memcpy(buf + PC_HISLIP_HEADER_LEN, payload, payload_len);
66size_t pc_hislip_build_initialize(uint8_t *buf,
size_t cap, uint16_t protocol_version, uint16_t vendor_id,
67 const char *sub_address)
69 size_t sub_len = sub_address ? strnlen(sub_address, cap) : 0;
70 uint32_t parameter = ((uint32_t)protocol_version << 16) | vendor_id;
71 return build_with_payload(buf, cap, HislipMsg::INITIALIZE, 0, parameter, (
const uint8_t *)sub_address, sub_len);
74size_t pc_hislip_build_initialize_response(uint8_t *buf,
size_t cap, uint8_t control, uint16_t protocol_version,
77 uint32_t parameter = ((uint32_t)protocol_version << 16) | session_id;
78 return pc_hislip_build_header(buf, cap, HislipMsg::INITIALIZE_RESPONSE, control, parameter, 0);
81size_t pc_hislip_build_async_initialize(uint8_t *buf,
size_t cap, uint16_t session_id)
83 return pc_hislip_build_header(buf, cap, HislipMsg::ASYNC_INITIALIZE, 0, session_id, 0);
86size_t pc_hislip_build_async_initialize_response(uint8_t *buf,
size_t cap, uint8_t control, uint16_t server_vendor_id)
88 return pc_hislip_build_header(buf, cap, HislipMsg::ASYNC_INITIALIZE_RESPONSE, control, server_vendor_id, 0);
91size_t pc_hislip_build_data(uint8_t *buf,
size_t cap,
bool is_end, uint8_t control, uint32_t message_id,
92 const uint8_t *payload,
size_t payload_len)
94 HislipMsg type = is_end ? HislipMsg::DATA_END : HislipMsg::DATA;
95 return build_with_payload(buf, cap, type, control, message_id, payload, payload_len);
98uint32_t pc_hislip_next_message_id(uint32_t
id)
103bool pc_hislip_parse_initialize(
const uint8_t *buf,
size_t len, HislipInitialize *out)
106 if (!out || !pc_hislip_parse_header(buf, len, &h) || h.type != HislipMsg::INITIALIZE)
110 if (h.payload_len > (uint64_t)(len - PC_HISLIP_HEADER_LEN))
114 out->protocol_version = (uint16_t)(h.parameter >> 16);
115 out->vendor_id = (uint16_t)(h.parameter & 0xFFFF);
116 out->sub_address = (
const char *)(buf + PC_HISLIP_HEADER_LEN);
117 out->sub_address_len = (size_t)h.payload_len;
121bool pc_hislip_parse_initialize_response(
const uint8_t *buf,
size_t len, HislipInitializeResponse *out)
124 if (!out || !pc_hislip_parse_header(buf, len, &h) || h.type != HislipMsg::INITIALIZE_RESPONSE)
128 out->protocol_version = (uint16_t)(h.parameter >> 16);
129 out->session_id = (uint16_t)(h.parameter & 0xFFFF);
130 out->overlap = (h.control & PC_HISLIP_INITRESP_OVERLAP) != 0;
131 out->encryption_mandatory = (h.control & PC_HISLIP_INITRESP_ENC_MANDATORY) != 0;
Fixed-width integer serializers into a raw uint8_t* buffer - one source of truth.
size_t pc_wr64be(uint8_t *p, uint64_t v)
Write v big-endian at p.
uint32_t pc_rd32be(const uint8_t *p)
Read a big-endian u32 at p.
uint64_t pc_rd64be(const uint8_t *p)
Read a big-endian u64 at p.
size_t pc_wr32be(uint8_t *p, uint32_t v)
Write v big-endian at p.
HiSLIP (High-Speed LAN Instrument Protocol) message codec (PC_ENABLE_HISLIP) - a zero-heap codec for ...