DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
sse.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 sse.cpp
6 * @brief Server-Sent Events connection pool implementation.
7 */
8
9#include "sse.h"
11#include <stdio.h>
12#include <string.h>
13
15
17{
18 for (int i = 0; i < MAX_SSE_CONNS; i++)
19 {
20 sse_pool[i] = {};
21 sse_pool[i].sse_id = (uint8_t)i;
22 }
23}
24
25SseConn *sse_alloc(uint8_t slot_id, const char *path)
26{
27 for (int i = 0; i < MAX_SSE_CONNS; i++)
28 {
29 if (!sse_pool[i].active)
30 {
31 sse_pool[i] = {};
32 sse_pool[i].sse_id = (uint8_t)i;
33 sse_pool[i].slot_id = slot_id;
34 sse_pool[i].active = true;
35 strncpy(sse_pool[i].path, path, MAX_PATH_LEN - 1);
36 sse_pool[i].path[MAX_PATH_LEN - 1] = '\0';
37 return &sse_pool[i];
38 }
39 }
40 return nullptr;
41}
42
43SseConn *sse_find(uint8_t slot_id)
44{
45 for (int i = 0; i < MAX_SSE_CONNS; i++)
46 {
47 if (sse_pool[i].active && sse_pool[i].slot_id == slot_id)
48 return &sse_pool[i];
49 }
50 return nullptr;
51}
52
53void sse_free(uint8_t slot_id)
54{
55 for (int i = 0; i < MAX_SSE_CONNS; i++)
56 {
57 if (sse_pool[i].active && sse_pool[i].slot_id == slot_id)
58 {
59 sse_pool[i] = {};
60 sse_pool[i].sse_id = (uint8_t)i;
61 return;
62 }
63 }
64}
65
66int sse_format(char *buf, size_t n, const char *data, const char *event, const char *id)
67{
68 if (!data || n == 0)
69 return 0;
70
71 int pos = 0;
72 int rem = (int)n;
73
74 // pos starts at 0 here, so the first field needs no remaining-space guard; the
75 // later fields do, since a truncated snprintf advances pos toward (or past) rem.
76 if (event)
77 pos += snprintf(buf + pos, (size_t)(rem - pos), "event: %s\n", event);
78 if (id && pos < rem)
79 pos += snprintf(buf + pos, (size_t)(rem - pos), "id: %s\n", id);
80 if (pos < rem)
81 pos += snprintf(buf + pos, (size_t)(rem - pos), "data: %s\n\n", data);
82
83 if (pos <= 0 || pos >= rem)
84 return 0;
85 return pos;
86}
87
88bool sse_write(SseConn *sse, const char *data, const char *event, const char *id)
89{
90 if (!det_conn_active(sse->slot_id))
91 return false;
92
93 char buf[SSE_BUF_SIZE];
94 int pos = sse_format(buf, sizeof(buf), data, event, id);
95 if (pos <= 0)
96 return false;
97
98 det_conn_send(sse->slot_id, buf, (u16_t)pos);
99 return true;
100}
#define MAX_PATH_LEN
Maximum URL path length (including leading /).
#define MAX_SSE_CONNS
Maximum simultaneous SSE connections.
#define SSE_BUF_SIZE
Output buffer size in bytes for a single SSE event.
void sse_init()
Initialize all SSE pool slots to inactive.
Definition sse.cpp:16
bool sse_write(SseConn *sse, const char *data, const char *event, const char *id)
Write one SSE event record to a client.
Definition sse.cpp:88
SseConn sse_pool[MAX_SSE_CONNS]
Pool of SSE connection state, one per MAX_SSE_CONNS.
Definition sse.cpp:14
SseConn * sse_find(uint8_t slot_id)
Find the SseConn for a given TCP slot, or nullptr.
Definition sse.cpp:43
int sse_format(char *buf, size_t n, const char *data, const char *event, const char *id)
Format one SSE event record into a caller buffer (no transport).
Definition sse.cpp:66
SseConn * sse_alloc(uint8_t slot_id, const char *path)
Allocate an SseConn and bind it to a TCP slot.
Definition sse.cpp:25
void sse_free(uint8_t slot_id)
Free the SseConn associated with a TCP slot.
Definition sse.cpp:53
Layer 6 (Presentation) – Server-Sent Events connection pool.
SSE connection state stored in sse_pool[].
Definition sse.h:46
char path[MAX_PATH_LEN]
Definition sse.h:52
uint8_t sse_id
Index into sse_pool[] (set at init).
Definition sse.h:47
bool active
True when this entry is in use.
Definition sse.h:49
uint8_t slot_id
Owning TCP slot in conn_pool[].
Definition sse.h:48
bool det_conn_send(uint8_t slot, const void *data, u16_t len)
Send len bytes on connection slot (copies data; TLS-aware).
Definition tcp.cpp:362
Layer 4 (Transport) - TCP connection pool, ring buffers, and lwIP integration.