| <!-- 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 | |
| ``` |