-
Notifications
You must be signed in to change notification settings - Fork 3
CommunicationsStackOverview
The Raft communications stack lets a single REST API endpoint (or stream/file transfer) be reached over any connected transport — HTTP, BLE, serial, sockets, WebSocket, etc. This page describes the layers involved and traces a request end-to-end.
For per-layer detail see:
- Comms Channels — channel registration, inbound/outbound message flow, transport settings
- ProtocolExchange — the SysMod that decodes RICREST messages and dispatches them
- RICREST Protocol — wire formats used over non-HTTP transports
- Adding REST API Endpoints — registering endpoints from a SysMod
- File Download Protocol (OKTO) — stream/file-block transfer that runs through this stack
-
Real-Time Streams — open-ended
rtstreamsessions over RICRESTFILEBLOCKframes
┌────────────────────────────────────────────────────────────────────┐
│ Transports (interfaces): WiFi/HTTP, BLE GATT, UART, sockets, ... │
└────────────────────────────────────────────────────────────────────┘
│ raw bytes
▼
┌────────────────────────────────────────────────────────────────────┐
│ Comms Channels (CommsChannelManager / CommsCoreIF) │
│ ─ each channel has a name, an interface name, and a protocol │
│ ─ owns inbound/outbound queues + per-channel settings │
└────────────────────────────────────────────────────────────────────┘
│ framed messages
▼
┌────────────────────────────────────────────────────────────────────┐
│ Protocol Codecs (ProtocolBase implementations) │
│ ─ RICSerial (HDLC-framed binary) — used for serial / BLE │
│ ─ RICFrame (length-prefixed framing) — used for sockets │
│ ─ RICJSON (JSON-only) │
│ ─ ROSSerial (ROS serial; legacy) │
└────────────────────────────────────────────────────────────────────┘
│ CommsChannelMsg
▼
┌────────────────────────────────────────────────────────────────────┐
│ ProtocolExchange (SysMod) │
│ ─ decodes RICREST messages (URL / Body / CmdRespJSON / ...) │
│ ─ owns FileStream sessions for upload / download / FW update │
│ ─ routes URL requests to the REST API endpoint manager │
└────────────────────────────────────────────────────────────────────┘
│ request string + APISourceInfo
▼
┌────────────────────────────────────────────────────────────────────┐
│ RestAPIEndpointManager │
│ ─ matches the request to a registered endpoint │
│ ─ calls the endpoint's handler │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ Your SysMod's API handler │
└────────────────────────────────────────────────────────────────────┘
The same RestAPIEndpointManager is also used directly by the HTTP server (RaftWebServer) — HTTP requests bypass ProtocolExchange and go straight to the endpoint manager (channel ID CHANNEL_ID_REST_API).
| Term | Meaning |
|---|---|
| Interface | A physical/logical transport (e.g. BLE, Serial1, Sockets). Multiple channels can share one interface. |
| Channel | A bidirectional message pipe through an interface. Identified by a channelID allocated by CommsChannelManager::registerChannel(). |
| Protocol codec | A ProtocolBase subclass that knows how to frame/unframe bytes for one wire format (RICSerial, RICFrame, RICJSON). |
| CommsChannelMsg | Decoded message: channel ID + protocol + type (command/response/publish/report) + msg number + payload bytes. |
| RICREST message | A CommsChannelMsg whose protocol is MSG_PROTOCOL_RICREST and whose payload begins with a one-byte RICRESTElemCode (URL, Body, CmdRespJSON, CommandFrame, FileBlock). |
| Endpoint | A REST entry point registered via RestAPIEndpointManager::addEndpoint(). Identified by its first path segment. |
| Subscription | A per-channel publish-rate registration created via the subscription REST endpoint. |
When a transport SysMod (BLEManager, CommandSerial, RaftWebServer, etc.) starts up, it registers one or more channels by calling CommsChannelManager::registerChannel(). The call provides:
-
protocolName— which codec to attach (e.g."RICSerial","RICFrame","RICJSON") -
interfaceName— the underlying interface (e.g."BLE","CommandSerial") -
channelName— a unique channel name within that interface -
outboundHandleMsgCB— function the channel calls to push bytes out of the device -
outboundCanAcceptCB— flow-control callback - A
CommsChannelSettingsobject controlling block sizes and queue depths
The manager returns a channelID that the transport stores and uses for inbound calls (inboundHandleMsg).
The protocol codecs themselves are added separately (typically by ProtocolExchange and other SysMods in their addCommsChannels() overrides) via CommsCoreIF::addProtocol(). The first time a channel needs its codec, CommsChannelManager looks up the protocol name from the channel and instantiates the matching codec.
See Comms Channels for the full channel API.
This walks one BLE-delivered REST request through the stack to make the layering concrete.
Scenario: a mobile app calls subscription?action=update&topic=devjson&rateHz=10 over BLE.
-
Transport (BLEManager /
BLEGapServer) receives a GATT write on the RICREST characteristic. The manager has previously registered a channel withprotocolName = "RICSerial",interfaceName = "BLE",channelName = "BLE". It callscommsCoreIF.inboundHandleMsg(channelID, pBytes, len)with the raw GATT payload. -
CommsChannelManager queues the bytes into the channel's inbound queue and, on its loop, hands them to the channel's protocol codec via
addRxData(). -
ProtocolRICSerial uses
MiniHDLCto deframe the bytes. Once a complete HDLC frame is decoded it calls_msgRxCB(registered byProtocolExchange) with a fully-populatedCommsChannelMsg. The message hasprotocol = MSG_PROTOCOL_RICRESTand a payload whose first byte is the RICREST element code. -
ProtocolExchange (in
processEndpointMsg) seesMSG_PROTOCOL_RICREST, decodes the innerRICRESTMsg, switches on the element code:-
URL→processRICRESTURL()— request string is the URL itself, e.g."subscription?action=update&topic=devjson&rateHz=10". -
Body→processRICRESTBody()— used for chunked POST-style data. -
CmdRespJSON→ response message (other end's reply). -
CommandFrame→ JSON command frame (cmdName+ arbitrary fields). -
FileBlock→ a chunk of a file/stream session.
-
-
RestAPIEndpointManager::handleApiRequest is called with the request string and an
APISourceInfo(channelID). It splits the request on/, looks up the first segment (subscription) in its endpoint table, and invokes the matchingRestAPIFunctioncallback. -
The endpoint handler (in
StatePublisherforsubscription) does its work and writes a JSON response intorespStr. -
ProtocolExchange wraps the response in a
RICRESTMsgwith element codeCmdRespJSON, sets it as a response to the original message (endpointMsg.setAsResponse(cmdMsg)— which copies channelID and msgNumber so the response goes back to the right place), and callsgetCommsCore()->outboundHandleMsg(endpointMsg). -
CommsChannelManager routes the outbound message to the channel matching
channelID, which encodes it via its protocol codec (encodeTxMsgAndSend()) and calls the channel'soutboundHandleMsgCB. In our case this isBLEGapServer::sendBLEMsg, which writes the bytes to the GATT notify characteristic.
The same handler — subscription — would have been reached if the same request arrived as an HTTP GET, a serial RICSerial frame, or a CommandFrame JSON {"cmdName":"subscription", …} over BLE. The channelID differs, so subsequent publish messages are sent only to the channel that originated the subscription.
HTTP requests do not flow through ProtocolExchange:
-
RaftWebServerreceives the request and matches it against its internal handlers. - The
RaftWebHandlerRestAPIhandler callsRestAPIEndpointManager::handleApiRequest()directly, withAPISourceInfo(CHANNEL_ID_REST_API). - The response string returned by the endpoint handler is sent back as the HTTP response body.
POST bodies and chunked uploads use additional callbacks on the registered endpoint (callbackBody, callbackChunk); see Adding REST API Endpoints.
A bridge connects two channels so that messages from one are forwarded to the other. This is used (for example) to attach a peripheral device on a serial channel to a BLE-connected host. Bridges are registered via CommsCoreIF::bridgeRegister() and use the special MSG_PROTOCOL_BRIDGE_RICREST envelope so the bridged message keeps its original framing intact.
See Comms Channels for details.
| Class / file | Repo | Role |
|---|---|---|
CommsCoreIF, CommsChannelSettings, ProtocolCodecFactoryHelper
|
RaftCore/components/comms/CommsCoreIF | Public interface to the comms core |
CommsChannelManager, CommsChannel, CommsChannelBridge
|
RaftCore/components/comms/CommsChannels | Channel registration and queues |
CommsChannelMsg, CommsBridgeMsg
|
RaftCore/components/comms/CommsChannelMsg, CommsBridgeMsg | Message containers |
ProtocolBase, ProtocolRICSerial, ProtocolRICFrame, ProtocolRICJSON, ProtocolRawMsg, ProtocolOverAscii
|
RaftCore/components/comms/Protocol* | Wire-format codecs |
RICRESTMsg |
RaftCore/components/comms/RICRESTMsg | RICREST message encoder/decoder |
ProtocolExchange, FileStreamSession
|
RaftCore/components/comms/ProtocolExchange | Dispatch hub and stream sessions |
RestAPIEndpointManager, RestAPIEndpoint
|
RaftCore/components/core/RestAPIEndpoints | Endpoint registration and dispatch |
MiniHDLC |
RaftCore/components/core/MiniHDLC | HDLC framer used by RICSerial |
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
- PlatformIO / Arduino
Scaffolding & Building
- Raft CLI
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
Helpers
Reference