20bool is_reserved(uint8_t b)
22 return b == 0x7E || b == 0x7D || b == 0x11 || b == 0x13 || b == 0x18 || b == 0x1A;
26bool put_stuffed(uint8_t *out, uint16_t *p, uint16_t cap, uint8_t b)
34 out[(*p)++] = Ash::ASH_ESCAPE;
35 out[(*p)++] = (uint8_t)(b ^ 0x20);
49uint16_t pc_ash_crc16(
const uint8_t *buf, uint16_t len)
57uint16_t pc_ash_frame_encode(uint8_t control,
const uint8_t *payload, uint16_t len, uint8_t *out, uint16_t cap)
71 if (!put_stuffed(out, &p, cap, control))
75 for (uint16_t i = 0; i < len; i++)
77 if (!put_stuffed(out, &p, cap, payload[i]))
82 if (!put_stuffed(out, &p, cap, (uint8_t)(crc >> 8)) || !put_stuffed(out, &p, cap, (uint8_t)(crc & 0xFF)))
90 out[p++] = Ash::ASH_FLAG;
94int pc_ash_frame_decode(
const uint8_t *raw, uint16_t len, uint8_t *control, uint8_t *payload, uint16_t pay_cap,
103 while (flag < len && raw[flag] != Ash::ASH_FLAG)
115 for (uint16_t i = 0; i < flag; i++)
118 if (b == Ash::ASH_ESCAPE)
124 b = (uint8_t)(raw[i] ^ 0x20);
136 uint16_t body = (uint16_t)(n - 2);
137 uint16_t crc = pc_ash_crc16(un, body);
138 if ((uint16_t)((un[n - 2] << 8) | un[n - 1]) != crc)
143 uint16_t plen = (uint16_t)(body - 1);
152 for (uint16_t i = 0; i < plen; i++)
154 payload[i] = un[1 + i];
160 return (
int)(flag + 1);
Parameterized CRC engine - one source of truth for every cyclic redundancy check.
uint32_t pc_crc_final(const pc_crc_params *p, uint32_t crc)
Finish a CRC: apply the output reflection and the final XOR.
uint32_t pc_crc_begin(const pc_crc_params *p)
Start a CRC.
constexpr pc_crc_params PC_CRC16_IBM_3740
CRC-16/IBM-3740 (often called CCITT-FALSE). check = 0x29B1.
uint32_t pc_crc(const pc_crc_params *p, const uint8_t *data, size_t len)
One-shot CRC of len octets at data.
uint32_t pc_crc_update(const pc_crc_params *p, uint32_t crc, const uint8_t *data, size_t len)
Fold len octets at data into the running register crc.
#define PC_ZIGBEE_MAX_DATA
Max ASH payload bytes (an EZSP frame; the ASH data field caps near 128).
Zigbee EZSP / ASH framing codec (PC_ENABLE_ZIGBEE) - Silicon Labs NCP.