15size_t dmx_build(uint8_t *buf,
size_t cap, uint8_t start_code,
const uint8_t *channels, uint16_t n)
17 if (!buf || n > DMX_MAX_CHANNELS || (n && !channels))
19 size_t total = (size_t)1 + n;
24 memcpy(buf + 1, channels, n);
28uint8_t dmx_get_channel(
const uint8_t *buf,
size_t len, uint16_t ch)
30 if (!buf || ch < 1 || ch > DMX_MAX_CHANNELS || (
size_t)ch >= len)
35uint64_t rdm_uid(uint16_t manufacturer, uint32_t device)
37 return ((uint64_t)manufacturer << 32) | device;
40uint16_t rdm_checksum(
const uint8_t *buf,
size_t len)
43 for (
size_t i = 0; i < len; i++)
44 s = (uint16_t)(s + buf[i]);
49static void put_uid(uint8_t *p, uint64_t uid)
51 p[0] = (uint8_t)(uid >> 40);
52 p[1] = (uint8_t)(uid >> 32);
53 p[2] = (uint8_t)(uid >> 24);
54 p[3] = (uint8_t)(uid >> 16);
55 p[4] = (uint8_t)(uid >> 8);
59static uint64_t get_uid(
const uint8_t *p)
61 return ((uint64_t)p[0] << 40) | ((uint64_t)p[1] << 32) | ((uint64_t)p[2] << 24) | ((uint64_t)p[3] << 16) |
62 ((uint64_t)p[4] << 8) | (uint64_t)p[5];
65size_t rdm_build(uint8_t *buf,
size_t cap,
const RdmPacket *p,
const uint8_t *pdata, uint8_t pdl)
67 if (!buf || !p || (pdl && !pdata))
69 uint8_t ml = (uint8_t)(24 + pdl);
70 size_t total = (size_t)ml + 2;
76 put_uid(buf + 3, p->dest_uid);
77 put_uid(buf + 9, p->src_uid);
80 buf[17] = p->msg_count;
81 buf[18] = (uint8_t)(p->sub_device >> 8);
82 buf[19] = (uint8_t)p->sub_device;
84 buf[21] = (uint8_t)(p->pid >> 8);
85 buf[22] = (uint8_t)p->pid;
88 memcpy(buf + 24, pdata, pdl);
89 uint16_t cs = rdm_checksum(buf, ml);
90 buf[ml] = (uint8_t)(cs >> 8);
91 buf[ml + 1] = (uint8_t)cs;
95bool rdm_parse(
const uint8_t *buf,
size_t len, RdmPacket *out,
size_t *consumed)
97 if (!buf || !out || len < RDM_OVERHEAD)
99 if (buf[0] != RDM_SC || buf[1] != RDM_SUB_SC)
104 uint8_t pdl = buf[23];
105 if (ml != (uint8_t)(24 + pdl))
107 size_t total = (size_t)ml + 2;
110 uint16_t cs = (uint16_t)((buf[ml] << 8) | buf[ml + 1]);
111 if (cs != rdm_checksum(buf, ml))
114 out->dest_uid = get_uid(buf + 3);
115 out->src_uid = get_uid(buf + 9);
117 out->port_id = buf[16];
118 out->msg_count = buf[17];
119 out->sub_device = (uint16_t)((buf[18] << 8) | buf[19]);
121 out->pid = (uint16_t)((buf[21] << 8) | buf[22]);
123 out->pdata = pdl ? buf + 24 :
nullptr;
DMX512 framing + RDM (ANSI E1.20) management codec (DETWS_ENABLE_DMX).