blob: 2a26774b8083313d64b9e25442edc60264112329 [file] [view]
<!-- Copyright 2026 The Fuchsia Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
# UART Framing Protocol Library (`uart_fpl`)
`uart_fpl` is a lightweight, transport-independent binary framing, multiplexing, and protocol negotiation library for transmitting structured packet streams over raw, byte-oriented serial (UART) links.
It provides shared, platform-independent primitives used by host-side background daemons (`ffx-uart-driver`) and target-side drivers (`fdomain-uart-driver`) to multiplex multiple concurrent logical communication channels over a single physical or virtual serial interface.
---
## 1. Architectural Overview & Component Topology
`uart_fpl` is structured into five modular layers:
```
+-------------------------------------------------------------------------+
| Client Layer |
| (Host CLI/Daemon: ffx-uart-driver, Target Runner: fdomain) |
+------------------------------------+------------------------------------+
|
+---------------------+--------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| Dynamic Negotiation | | Reliable Flow Control |
| (handshake::HostHandshake,| | (resend_sp::ResendSender, |
| handshake::TargetHandshake) | resend_sp::ResendReceiver)|
+--------------+--------------+ +--------------+--------------+
| |
+---------------------+--------------------+
|
v
+------------------------------------------+
| Framing & Checksum Engine |
| (frame::Frame, encode_frame, |
| parser::FrameParser) |
+---------------------+--------------------+
|
v
+-------------------------------------------------------------------------+
| Physical / Virtual |
| UART Byte Stream |
+-------------------------------------------------------------------------+
```
---
## 2. Logical Channel Multiplexing
A raw serial interface provides only a single flat byte stream. Without packet-level multiplexing, access to the serial link is an exclusive, single-client bottleneck:
* If a developer runs a continuous log monitor (`ffx log`) or serves package files over UART, the serial link is completely monopolized.
* Concurrent control queries (`ffx target echo`, `ffx component list`) or interactive diagnostics are blocked until the streaming command terminates.
`uart_fpl` solves this by embedding a 16-bit `Channel ID` into every frame:
```
Physical / Virtual UART Link
├── Channel 0: Control & Protocol Negotiation (Handshake)
├── Channel 1: Primary Data Channel (e.g. Diagnostic / Control RPC)
└── Channel 2+: Auxiliary streaming & diagnostic channels
```
* **Host Multiplexing**: The host-side background daemon (`ffx-uart-driver`) listens on a local UNIX domain socket. Each incoming client connection is assigned a distinct `channel_id` (channels 1 through 65535).
* **Target Demultiplexing**: The target driver (`fdomain-uart-driver`) demultiplexes incoming frames by `channel_id`, creating an independent FIDL stream socket for each active channel.
* **Granular Teardown**: When a client terminates, a `FrameType::Close` frame tears down that specific channel on the target without disrupting concurrent streams on other channels.
* **Dedicated Control Plane**: `Channel 0` is permanently reserved for transport signaling, dynamic handshake negotiation, and in-band reboot detection.
---
## 3. Documentation Index
The documentation for `uart_fpl` is divided into two focused specifications:
* **[Wire Protocol Specification (`PROTOCOL.md`)](./PROTOCOL.md)**:
* Complete 13-byte binary frame layout diagram and exact byte offsets.
* Field definitions and wire representations.
* 1-byte CRC-8 header checksum (`HdrChk`) and IEEE 802.3 CRC-32 checksum formulas.
* Dynamic handshake negotiation wire payloads (`NEGOTIATE_REQ`, `NEGOTIATE_RESP`).
* Protocol-level design decisions (session IDs, corrupted length protection, Go-Back-N wire mechanics).
* **[Rust API Reference & Integration Guide (`API.md`)](./API.md)**:
* Comprehensive public Rust API reference (`Frame`, `FrameParser`, `HostHandshake`, `TargetHandshake`, `ResendSender`, `ResendReceiver`, `AckTracker`).
* Method signatures, contracts, and error handling (`UnexpectedSeqError`).
* High-level architectural justifications (such as end-to-end backpressure without local receiver queueing).
* Runnable Rust code examples for handshake negotiation, sender loop, and receiver check-and-commit workflows.
---
## 4. Running Tests
Unit tests are defined in `BUILD.gn`:
```bash
# Run host unit tests
fx test //src/developer/lib/uart_fpl:uart_fpl_test --host
```