Skip to content

0x1abin/nanortc

Repository files navigation

NanoRTC

A Sans I/O, pure C WebRTC implementation for RTOS and embedded systems.

AI-native implementation: Every line of code in this repository — library source, tests, build system, CI, documentation, and examples — is written by AI coding agents. Humans steer architecture and verify correctness; agents execute. See How this project is built for details.

What is NanoRTC?

NanoRTC is a WebRTC protocol stack designed from the ground up for resource-constrained microcontrollers running FreeRTOS, Zephyr, RT-Thread, and other RTOS platforms.

Sans I/O architecture — Inspired by str0m (Rust), NanoRTC is a pure state machine. It never touches sockets, threads, memory allocation, or clocks. Your application owns the event loop and all I/O. This makes NanoRTC portable to any platform and testable without a network.

                     ┌─────────────────────────┐
  UDP bytes ────────►│                         │──────► bytes to send
  monotonic time ───►│  nanortc_t              │──────► application events
  user commands ────►│  (pure state machine)   │──────► next timeout (ms)
                     │                         │
                     │  No sockets. No threads.│
                     │  No malloc. No clocks.  │
                     └─────────────────────────┘

Features

  • Orthogonal feature flags — Include only what you need:
Configuration Flash (.text) RAM (sizeof) Flags
Core only 29.0 KB 10.2 KB DC=OFF AUDIO=OFF VIDEO=OFF
DataChannel 38.8 KB 19.4 KB DC=ON
Audio only 40.8 KB 20.6 KB DC=OFF AUDIO=ON
DataChannel + Audio 50.6 KB 29.9 KB DC=ON AUDIO=ON
Media only (no DC) 45.3 KB 51.0 KB DC=OFF AUDIO=ON VIDEO=ON
Full media 55.0 KB 60.3 KB DC=ON AUDIO=ON VIDEO=ON

Measured on ESP32-P4 (RISC-V HP), ESP-IDF 5.5 mbedTLS, -Os (CONFIG_COMPILER_OPTIMIZATION_SIZE=y). sizeof(nanortc_t) is the full per-connection RAM — no heap allocation. Flash figures count only nanortc library code (libnanortc.a .text); mbedTLS and lwIP are separate and typically shared with the rest of the firmware. Sizes reflect the ESP-IDF Kconfig defaults — IoT-grade buffer/queue sizing baked in, full ICE stack intact (TURN relay, srflx discovery, IPv6 host candidates, TWCC/BWE perception, RFC 8445 hardening). Reproduce with ./scripts/measure-sizes.sh --esp32 esp32p4; tune further via idf.py menuconfig or NANORTC_CONFIG_FILE.

Any combination works — audio without DataChannel, video without audio, etc.

  • ICE — Controlled (answerer) and controlling (offerer) roles, trickle ICE, ICE restart
  • DTLS 1.2 — Via pluggable crypto provider (mbedtls or OpenSSL)
  • SCTP — Minimal subset for WebRTC DataChannels (reliable + unreliable)
  • DataChannel — DCEP protocol, reliable and unreliable modes
  • RTP/RTCP/SRTP — Audio and video media transport, H.264 FU-A packetization
  • SDP — Offer/answer negotiation, multi-track media
  • NAT traversal — STUN server-reflexive discovery + TURN relay client (optional, NANORTC_FEATURE_TURN)
  • Bandwidth estimation — REMB-based receiver BWE for adaptive video
  • Single external dependency — Only mbedtls (built-in on ESP-IDF, Zephyr, RT-Thread, STM32)

Quick Start

# Build (Linux/macOS) — default: DataChannel only
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j$(nproc)
ctest --test-dir build --output-on-failure

# Enable audio + video
cmake -B build -DNANORTC_FEATURE_AUDIO=ON -DNANORTC_FEATURE_VIDEO=ON

# With OpenSSL (for Linux host development)
cmake -B build -DNANORTC_CRYPTO=openssl

# Build examples (full media)
cmake -B build -DNANORTC_FEATURE_DATACHANNEL=ON -DNANORTC_FEATURE_AUDIO=ON \
      -DNANORTC_FEATURE_VIDEO=ON -DNANORTC_CRYPTO=openssl -DNANORTC_BUILD_EXAMPLES=ON
cmake --build build

# ESP-IDF
idf.py build

Usage

Signatures below are simplified for readability — optional out-parameters are omitted. See include/nanortc.h for the full API.

Configure, negotiate, drive:

#include "nanortc.h"

nanortc_t rtc;
nanortc_init(&rtc, &(nanortc_config_t){
    .crypto = nanortc_crypto_mbedtls(),   // or nanortc_crypto_openssl()
    .role   = NANORTC_ROLE_CONTROLLED,    // or _CONTROLLING to offer
});
nanortc_add_local_candidate(&rtc, local_ip, local_port);

char sdp[4096];
nanortc_accept_offer(&rtc, remote_offer, sdp);
// Offerer: create_datachannel("chat") → create_offer(sdp) → accept_answer(remote_answer)

The event loop is symmetric — drain outputs, feed inputs. You own the socket and clock:

for (;;) {
    nanortc_output_t out;
    while (nanortc_poll_output(&rtc, &out) == NANORTC_OK)
        handle_output(&out);              // send UDP, fire app event, note next wake-up

    size_t len = recv_udp(fd, buf, sizeof buf, &src, wake_ms);
    nanortc_handle_input(&rtc, &(nanortc_input_t){
        .now_ms = now_ms(), .data = buf, .len = len, .src = src,
    });
}

One input struct in, one output struct out. No hidden state, no background threads.

For complete runnable examples — browser interop, macOS camera streaming, ESP32 DataChannel — see examples/.

Platform Support

Platform Status Notes
Linux / macOS Host development & testing OpenSSL or mbedtls
ESP-IDF (ESP32) Primary embedded target Built-in mbedtls, lwIP
Zephyr Supported Built-in mbedtls, lwIP
RT-Thread Supported mbedtls package, lwIP
STM32 + FreeRTOS Supported ST-distributed mbedtls, lwIP
NuttX Supported POSIX-compatible sockets

Project Structure

include/nanortc.h          Single public API header
src/                        Protocol modules (Sans I/O, no platform deps)
crypto/                     Pluggable crypto providers (mbedtls, openssl)
tests/                      Unit tests + end-to-end tests (no network needed)
tests/interop/              Interop tests against libdatachannel (C++)
examples/                   Application templates
  common/                   Reusable event loop, signaling, media source
  browser_interop/          DataChannel + media browser harness
  macos_camera/             macOS camera/mic → browser streaming
  esp32_{datachannel,audio,video,camera}/   ESP-IDF targets
  rk3588_uvc_camera/        RK3588 UVC camera demo
  tools/                    Dev utilities
  sample_data/              Media samples (git submodule)
docs/                       Design docs, execution plans, engineering standards

See ARCHITECTURE.md for the module dependency graph and data flow.

How This Project Is Built

NanoRTC is an experiment in AI-native software engineering, inspired by Harness Engineering. The entire codebase is generated by AI coding agents, following the principle: humans steer, agents execute.

What this means in practice:

  • Architecture & design — Human decisions, captured in docs/design-docs/
  • All code — Written by AI agents: library source, tests, CI, build system, documentation
  • Quality gates — Mechanically enforced via CI: forbidden includes, no malloc, symbol naming, format checks, 7-combo feature flag build matrix, AddressSanitizer
  • RFC compliance — Protocol implementations follow RFCs as the authoritative standard, not reference code
  • Continuous verification./scripts/ci-check.sh runs the same checks locally that run in GitHub Actions. Auto-detects ccache, keeps build dirs across runs for incremental compilation, and exposes --fast for tight pre-push loops (skips low-yield combos and the libdatachannel interop suite — seconds rather than minutes)

The repository structure itself is designed for agent legibility: AGENTS.md serves as the entry point, with progressive disclosure into deeper documentation. Constraints are enforced by code, not by convention.

Documentation

Document Description
AGENTS.md Agent entry point — build commands, mandatory rules
Build Guide Build commands, feature flags, fuzz, coverage, ESP-IDF
ARCHITECTURE.md Module dependency graph, layer model, data flow
Design Specification Full authoritative design reference
Core Beliefs Non-negotiable design principles
Execution Plans Active and completed implementation plans
Quality Score Per-module quality grades
Memory Profiles RAM usage by configuration, tuning guide
Coding Standards Naming, style, RFC testing requirements
Safe C Guidelines Banned functions, buffer safety rules
RFC Index Protocol specification references

Contributing

NanoRTC is in active development. The core protocol stack — DataChannel, Audio, Video/H.264, ICE+STUN+TURN with RFC 8445 compliance, SRTP, and TWCC/BWE perception — is code-complete and interop-verified against libdatachannel and Chromium. Phase 8 continued-optimization and Phase 3.5 H.265 are in flight; see docs/PLANS.md for current phase status. All 18 library modules at A grade — fuzz-tested, browser-verified, libdatachannel-interop-verified, 80%+ coverage.

Contributions welcome. Please read AGENTS.md for build instructions and mandatory rules before submitting changes.

License

MIT

About

(Experimental) A Sans I/O, pure C WebRTC implementation for RTOS and embedded systems.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors