ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ws.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ws.h
6 * @brief Layer 5 (Session) - opening and closing a WebSocket connection.
7 *
8 * RFC 4254 sec 5 states the shape: "Multiple channels are multiplexed into a single connection",
9 * either side "allocates a local number for the channel" to open one, and a party "may then reuse
10 * the channel number" once it is closed. Sequencing that open and that close is this layer's.
11 *
12 * RFC 9293 sec 3.6 MUST-12 is why the close is one call rather than each caller's checklist: "If
13 * the local TCP connection is closed by the remote side due to a FIN or RST received from the
14 * remote side, then the local application MUST be informed whether it closed normally or was
15 * aborted." A close that releases the number without informing the application leaves that
16 * application holding state for a connection that no longer exists.
17 *
18 * @author Douglas Quigg (dstroy0)
19 * @date 2026
20 */
21
22#ifndef PROTOCORE_SESSION_WS_H
23#define PROTOCORE_SESSION_WS_H
24
25#include "protocore_config.h"
26
27#if PROTOCORE_ENABLE_WEBSOCKET
28
30
31/**
32 * @brief Opening and closing one WebSocket connection.
33 *
34 * @var SessionWsNs::ok whether the channel opened, or whether a close had one to release
35 * @var SessionWsNs::open take a channel for the named connection and run the route's connect
36 * @var SessionWsNs::close run the route's close, then release the channel for reuse
37 *
38 * No storage and no members naming the connection: the caller has already named it on ::Ws, and
39 * this sequences what happens to it. A second copy would be a second answer to "which connection".
40 */
41typedef struct
42{
43 proto_bool ok; ///< whether the channel opened, or whether a close had one to release
44} SessionWsVars;
45
46/** @brief The operands and the outcome. */
47extern SessionWsVars SessionWsV;
48
49/** @brief The entries. */
50typedef struct
51{
52 void (*const open)(uint8_t *work);
53 void (*const close)(uint8_t *work);
54} SessionWsNs;
55
56// What the table binds, defined once in the .c and taking one parameter each: everything
57// else an entry needs is an operand in SessionWsV or a region of the borrow at a fixed offset.
58void protocore_session_ws_open(uint8_t *work);
59void protocore_session_ws_close(uint8_t *work);
60
61// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
62// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
63// `SessionWs.open(work)` resolves to a named function and becomes a DIRECT call. An extern table
64// leaves the call indirect and the symbol live at every level, -O2 -flto included.
65static const SessionWsNs SessionWs __attribute__((unused)) = {
66 .open = protocore_session_ws_open,
67 .close = protocore_session_ws_close,
68};
69
71
72#endif // PROTOCORE_ENABLE_WEBSOCKET
73
74#endif
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97