DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
nats.h
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 nats.h
6 * @brief NATS client protocol codec (DETWS_ENABLE_NATS) - zero-heap builder + parser for the
7 * text-based NATS pub/sub protocol, so a device can be a NATS client over the shipped
8 * outbound client transport.
9 *
10 * NATS is a small, line-oriented protocol; every control line ends with CRLF and fields are
11 * space-separated:
12 * @code
13 * CONNECT {json} // client -> server
14 * PUB <subject> [reply-to] <#bytes>\r\n<payload> // client -> server
15 * SUB <subject> [queue] <sid> // client -> server
16 * UNSUB <sid> [max] // client -> server
17 * MSG <subject> <sid> [reply-to] <#bytes>\r\n<payload> // server -> client
18 * PING / PONG / +OK / -ERR <msg> / INFO {json}
19 * @endcode
20 * Only PUB and MSG carry a payload (the byte count precedes a CRLF, then that many payload
21 * octets, then a trailing CRLF).
22 *
23 * The builders write a control line (plus payload) into a caller buffer; the parser decodes
24 * one inbound message at the buffer head and reports the bytes consumed. Line formats per the
25 * NATS client protocol reference.
26 *
27 * @author Douglas Quigg (dstroy0)
28 * @date 2026
29 */
30
31#ifndef DETERMINISTICESPASYNCWEBSERVER_NATS_H
32#define DETERMINISTICESPASYNCWEBSERVER_NATS_H
33
34#include "ServerConfig.h"
35
36#if DETWS_ENABLE_NATS
37
38#include <stddef.h>
39#include <stdint.h>
40
41// ---- builders (return bytes written, or 0 on overflow / bad input) ----
42
43/** @brief CONNECT: `CONNECT <options_json>\r\n`. */
44size_t nats_build_connect(char *buf, size_t cap, const char *options_json);
45
46/** @brief PUB: `PUB <subject> [reply_to] <len>\r\n<payload>\r\n` (@p reply_to may be null). */
47size_t nats_build_pub(char *buf, size_t cap, const char *subject, const char *reply_to, const uint8_t *payload,
48 size_t payload_len);
49
50/** @brief SUB: `SUB <subject> [queue] <sid>\r\n` (@p queue may be null). */
51size_t nats_build_sub(char *buf, size_t cap, const char *subject, const char *queue, const char *sid);
52
53/** @brief UNSUB: `UNSUB <sid> [max]\r\n` (@p with_max controls the optional max-messages field). */
54size_t nats_build_unsub(char *buf, size_t cap, const char *sid, uint32_t max_msgs, bool with_max);
55
56/** @brief PING: `PING\r\n`. */
57size_t nats_build_ping(char *buf, size_t cap);
58
59/** @brief PONG: `PONG\r\n`. */
60size_t nats_build_pong(char *buf, size_t cap);
61
62/** @brief Inbound message kind. */
63enum class NatsMsgType : uint8_t
64{
65 NATS_MSG, ///< a delivered message (subject/sid/reply/payload set)
66 NATS_INFO, ///< server INFO (arg = the JSON)
67 NATS_PING,
68 NATS_PONG,
69 NATS_OK, ///< +OK
70 NATS_ERR, ///< -ERR (arg = the message)
71 NATS_UNKNOWN, ///< unrecognized verb
72};
73
74/** @brief One parsed inbound protocol message. String/payload fields point INTO the buffer. */
75struct NatsMsg
76{
77 NatsMsgType type;
78 const char *subject; ///< MSG only
79 size_t subject_len;
80 const char *sid; ///< MSG only
81 size_t sid_len;
82 const char *reply; ///< MSG reply-to (may be empty)
83 size_t reply_len;
84 const uint8_t *payload; ///< MSG payload
85 size_t payload_len;
86 const char *arg; ///< INFO / -ERR argument (the rest of the control line)
87 size_t arg_len;
88};
89
90/**
91 * @brief Parse one inbound message at the head of [buf, buf+len).
92 * @param consumed receives the message length (control line + any payload) so the caller can advance.
93 * @return true on a complete message; false if the control line or the MSG payload is not yet buffered.
94 */
95bool nats_parse(const char *buf, size_t len, NatsMsg *out, size_t *consumed);
96
97#endif // DETWS_ENABLE_NATS
98
99#endif // DETERMINISTICESPASYNCWEBSERVER_NATS_H
User-facing configuration for DeterministicESPAsyncWebServer.