DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
bus_capture.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 bus_capture.h
6 * @brief Wired field-bus listen-only capture (DETWS_ENABLE_BUS_CAPTURE) - passive CAN sniffing.
7 *
8 * The wired counterpart to the Wi-Fi promiscuous tap: put the CAN (TWAI) controller in
9 * **listen-only** mode - it receives and decodes every frame on the bus but never ACKs or
10 * transmits, so it is invisible to the other nodes - and hand each frame to a sink. Wire the sink
11 * into the forwarding plane (services/forward) to bridge captured CAN frames to another interface
12 * (e.g. stream them to a wired collector over Ethernet), exactly like the Wi-Fi capture path.
13 *
14 * The pure piece is can_to_socketcan(): format a ::CanFrame as a 16-byte Linux **SocketCAN**
15 * frame, which with the libpcap DLT_CAN_SOCKETCAN link type (shared_primitives/pcap.h) is a
16 * capture Wireshark opens directly. The TWAI bring-up (`driver/twai.h`, listen-only) is ESP32
17 * only and needs a CAN transceiver on the bus.
18 *
19 * @author Douglas Quigg (dstroy0)
20 * @date 2026
21 */
22
23#ifndef DETERMINISTICESPASYNCWEBSERVER_BUS_CAPTURE_H
24#define DETERMINISTICESPASYNCWEBSERVER_BUS_CAPTURE_H
25
26#include "ServerConfig.h"
27
28#if DETWS_ENABLE_BUS_CAPTURE
29
30#include "shared_primitives/can.h" // CanFrame
31#include "shared_primitives/pcap.h" // DET_DLT_CAN_SOCKETCAN
32#include <stddef.h>
33#include <stdint.h>
34
35/** @brief A Linux SocketCAN classic frame is 16 bytes on the wire (and in a PCAP record). */
36#define DET_SOCKETCAN_FRAME_LEN 16
37
38/** @brief SocketCAN can_id flag bits, set in the top of the big-endian can_id word. */
39#define DET_CAN_EFF_FLAG 0x80000000u ///< extended (29-bit) identifier
40#define DET_CAN_RTR_FLAG 0x40000000u ///< remote-transmission-request frame
41#define DET_CAN_ERR_FLAG 0x20000000u ///< error message frame
42
43/**
44 * @brief Format @p f as a 16-byte Linux SocketCAN frame (for a `DET_DLT_CAN_SOCKETCAN` PCAP).
45 *
46 * `can_id` (big-endian) = the identifier ORed with EFF / RTR flags; then the data length, three
47 * reserved octets, and eight data octets (RTR frames carry no data).
48 * @return ::DET_SOCKETCAN_FRAME_LEN, or 0 if @p out is null / @p cap is too small.
49 */
50size_t can_to_socketcan(const CanFrame *f, uint8_t *out, size_t cap);
51
52/** @brief Sink for one captured CAN frame (already decoded into a ::CanFrame). */
53typedef void (*bus_capture_sink_fn)(const CanFrame *frame);
54
55/**
56 * @brief Install the TWAI (CAN) controller in listen-only mode and start capturing.
57 *
58 * Listen-only means the controller never sends an ACK or a frame, so it does not disturb the bus.
59 * @param tx_pin,rx_pin the GPIOs wired to the CAN transceiver.
60 * @param bitrate bus bit rate (125000, 250000, 500000, or 1000000).
61 * @return true if the driver installed and started; false on a bad bit rate, a driver error, or a
62 * host build.
63 */
64bool bus_capture_begin(int tx_pin, int rx_pin, uint32_t bitrate, bus_capture_sink_fn sink);
65
66/** @brief Drain any received frames, calling the sink for each. Call from loop(). */
67void bus_capture_poll(void);
68
69/** @brief Stop capture and release the TWAI driver. */
70void bus_capture_end(void);
71
72#endif // DETWS_ENABLE_BUS_CAPTURE
73
74#endif // DETERMINISTICESPASYNCWEBSERVER_BUS_CAPTURE_H
User-facing configuration for DeterministicESPAsyncWebServer.
Shared CAN 2.0 frame type for the CAN-based industrial codecs (one source of truth).
libpcap file framing - the classic global + per-record headers, link-type agnostic.
Definition can.h:44