DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
dds.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file dds.cpp
6 * @brief DDS / RTPS wire-protocol framing codec (see dds.h).
7 */
8
9#include "services/dds/dds.h"
10
11#if DETWS_ENABLE_DDS
12
13#include <string.h>
14
15const uint8_t RTPS_VERSION[2] = {2, 4};
16
17size_t detws_rtps_header(const uint8_t *guid_prefix, const uint8_t *vendor_id, uint8_t *out, size_t cap)
18{
19 if (!guid_prefix || !vendor_id || !out || cap < Rtps::RTPS_HEADER_LEN)
20 return 0;
21 out[0] = 'R';
22 out[1] = 'T';
23 out[2] = 'P';
24 out[3] = 'S';
25 out[4] = RTPS_VERSION[0];
26 out[5] = RTPS_VERSION[1];
27 out[6] = vendor_id[0];
28 out[7] = vendor_id[1];
29 memcpy(out + 8, guid_prefix, Rtps::RTPS_GUIDPREFIX_LEN);
30 return Rtps::RTPS_HEADER_LEN;
31}
32
33size_t detws_rtps_submessage(uint8_t id, uint8_t flags, const uint8_t *body, uint16_t body_len, uint8_t *out,
34 size_t cap)
35{
36 if (!out || (body_len && !body))
37 return 0;
38 size_t n = 4 + (size_t)body_len;
39 if (n > cap)
40 return 0;
41 out[0] = id;
42 out[1] = flags;
43 // octetsToNextHeader is written in the submessage's own byte order (the E flag).
44 if (flags & Rtps::RTPS_FLAG_ENDIAN)
45 {
46 out[2] = (uint8_t)body_len;
47 out[3] = (uint8_t)(body_len >> 8);
48 }
49 else
50 {
51 out[2] = (uint8_t)(body_len >> 8);
52 out[3] = (uint8_t)body_len;
53 }
54 if (body_len)
55 memcpy(out + 4, body, body_len);
56 return n;
57}
58
59bool detws_rtps_parse(const uint8_t *msg, size_t len, DetwsRtpsCb cb, void *arg)
60{
61 if (!msg || len < Rtps::RTPS_HEADER_LEN)
62 return false;
63 if (msg[0] != 'R' || msg[1] != 'T' || msg[2] != 'P' || msg[3] != 'S')
64 return false;
65 // Accept any peer whose protocol version is <= ours (RTPS is backward compatible).
66 if (msg[4] != RTPS_VERSION[0] || msg[5] > RTPS_VERSION[1])
67 return false;
68
69 size_t off = Rtps::RTPS_HEADER_LEN;
70 while (off + 4 <= len)
71 {
72 uint8_t id = msg[off];
73 uint8_t flags = msg[off + 1];
74 uint16_t oth = (flags & Rtps::RTPS_FLAG_ENDIAN) ? (uint16_t)(msg[off + 2] | (msg[off + 3] << 8))
75 : (uint16_t)((msg[off + 2] << 8) | msg[off + 3]);
76 size_t body = oth ? oth : (len - (off + 4)); // 0 = extends to end of message
77 if (off + 4 + body > len)
78 return false;
79 if (cb)
80 cb(id, flags, body ? (msg + off + 4) : nullptr, body, arg);
81 off += 4 + body;
82 if (oth == 0)
83 break; // a 0-length terminates the message
84 }
85 return true;
86}
87
88#endif // DETWS_ENABLE_DDS
DDS / RTPS wire-protocol codec (DETWS_ENABLE_DDS).