DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
bacnet.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 bacnet.h
6 * @brief BACnet/IP BVLC + NPDU codec (DETWS_ENABLE_BACNET) - zero-heap framing for the
7 * ASHRAE 135 building-automation network layer over UDP (default port 47808).
8 *
9 * Two stacked layers:
10 * - BVLC (Annex J): `Type(1)=0x81 Function(1) Length(2, big-endian, whole BVLL)` then the
11 * NPDU. Functions include Original-Unicast-NPDU (0x0A) and Original-Broadcast-NPDU (0x0B).
12 * - NPDU (Clause 6): `Version(1)=0x01 NPCI-Control(1)` then optional addressing. The NPCI
13 * control bits: 0x80 = network-layer message (else APDU), 0x20 = destination present
14 * (DNET(2) DLEN(1) DADR(DLEN); DLEN 0 = remote broadcast), 0x08 = source present (SNET(2)
15 * SLEN(1) SADR), 0x04 = expecting reply, low 2 bits = priority. A hop count octet follows
16 * the source fields when a destination is present. The APDU is whatever remains.
17 *
18 * The builders frame an APDU into a caller buffer (fail-closed); the parsers validate and
19 * report the slices. Layout verified against ASHRAE 135 Annex J / Clause 6.
20 *
21 * @author Douglas Quigg (dstroy0)
22 * @date 2026
23 */
24
25#ifndef DETERMINISTICESPASYNCWEBSERVER_BACNET_H
26#define DETERMINISTICESPASYNCWEBSERVER_BACNET_H
27
28#include "ServerConfig.h"
29
30#if DETWS_ENABLE_BACNET
31
32#include <stddef.h>
33#include <stdint.h>
34
35#define BVLC_TYPE_BIP 0x81 ///< BVLC Type: BACnet/IP
36#define BVLC_HEADER_SIZE 4 ///< type + function + 2-octet length
37
38// BVLC functions (Annex J).
39#define BVLC_FUNC_RESULT 0x00
40#define BVLC_FUNC_WRITE_BDT 0x01
41#define BVLC_FUNC_FORWARDED_NPDU 0x04
42#define BVLC_FUNC_REGISTER_FD 0x05
43#define BVLC_FUNC_ORIGINAL_UNICAST 0x0A
44#define BVLC_FUNC_ORIGINAL_BROADCAST 0x0B
45
46#define NPDU_VERSION 0x01 ///< ASCII 1, the only defined protocol version
47
48// NPCI control-octet bits (Clause 6.2.2).
49#define NPCI_NETWORK_MSG 0x80 ///< NSDU is a network-layer message (else an APDU)
50#define NPCI_DEST_PRESENT 0x20 ///< DNET / DLEN / DADR present
51#define NPCI_SRC_PRESENT 0x08 ///< SNET / SLEN / SADR present
52#define NPCI_EXPECTING_REPLY 0x04 ///< a reply is expected
53#define NPCI_PRIORITY_MASK 0x03 ///< message priority (low 2 bits)
54
55// Message priorities.
56#define NPDU_PRIO_NORMAL 0x00
57#define NPDU_PRIO_URGENT 0x01
58#define NPDU_PRIO_CRITICAL 0x02
59#define NPDU_PRIO_LIFE_SAFETY 0x03
60
61// ---- BVLC ----
62
63/** @brief Wrap an NPDU in a BVLC envelope. Returns total octets, or 0 on overflow. */
64size_t bvlc_build(uint8_t *buf, size_t cap, uint8_t function, const uint8_t *npdu, size_t npdu_len);
65
66/** @brief Parse a BVLC envelope; reports the function and the NPDU slice. */
67bool bvlc_parse(const uint8_t *buf, size_t len, uint8_t *function, const uint8_t **npdu, size_t *npdu_len);
68
69// ---- NPDU ----
70
71/**
72 * @brief Build an NPDU carrying @p apdu. With @p has_dest, the destination addressing
73 * (DNET / DLEN / DADR) and the hop count are emitted (DLEN 0 + @p dnet 0xFFFF is a
74 * remote/global broadcast).
75 */
76size_t npdu_build(uint8_t *buf, size_t cap, bool expecting_reply, uint8_t priority, bool has_dest, uint16_t dnet,
77 const uint8_t *dadr, uint8_t dadr_len, uint8_t hop_count, const uint8_t *apdu, size_t apdu_len);
78
79/** @brief A parsed NPDU. @ref apdu points INTO the source buffer. */
80struct NpduInfo
81{
82 uint8_t control;
83 bool network_message; ///< control & 0x80
84 bool dest_present;
85 uint16_t dnet;
86 bool src_present;
87 uint16_t snet;
88 uint8_t hop_count; ///< valid when dest_present
89 const uint8_t *apdu;
90 size_t apdu_len;
91};
92
93/** @brief Parse + validate an NPDU (version, control, optional addressing) and slice the APDU. */
94bool npdu_parse(const uint8_t *buf, size_t len, NpduInfo *out);
95
96#endif // DETWS_ENABLE_BACNET
97
98#endif // DETERMINISTICESPASYNCWEBSERVER_BACNET_H
User-facing configuration for DeterministicESPAsyncWebServer.