ezsp 5.2.0

Ember ZNet Serial Protocol
# ezsp

Rust implementation of the EmberZNet Serial Protocol (EZSP).

## Protocol documentation

- <https://docs.silabs.com/zigbee/latest/sisdk-ezsp-reference-guide/>
- <https://docs.silabs.com/zigbee/6.6/em35x/>

## Features

- `ashv2`: enables the ASHv2 serial transport (`uart::Uart`).
- `apis-saltans`: enables Zigbee host integration (`apis_saltans::EzspNetworkManager`) and pulls in `apis-saltans` APS/core/hardware/ZDP crates.
- `semver`: enables `semver` support for EZSP version APIs.

## Core API

The crate is transport-first:

- `Transport` defines the low-level async connection and request/response primitives.
- EZSP command traits (`Configuration`, `Messaging`, `Networking`, `Security`, ...) are blanket-implemented for any `T: Transport`.
- `Ezsp` is a convenience trait that combines all command traits.
- Protocol types are exposed through `ember`, `ezsp`, and the typed frame/parameter model.

Implementing `Transport` gives access to the full typed command surface.

## `ashv2` transport

The crate currently ships one concrete transport implementation: `uart::Uart` (`feature = "ashv2"`).

`Uart` provides:

- protocol negotiation through `Transport::connect()` / `Transport::ensure_connection()`
- typed EZSP request/response handling over ASHv2 payload framing
- response/callback demultiplexing
- serial constructors:
  - `Uart::open(path, flow_control, protocol_version, &ChannelSizes)`
  - `Uart::from_serial_port(serial_port, protocol_version, &ChannelSizes)`
  - `Uart::new(proxy, ash_rx, callbacks_tx, protocol_version, channel_size)` (advanced integration)
- `Uart::abort()` for aborting the background splitter task

Additional types:

- `uart::ChannelSizes` to tune queue capacities for `Uart::open` / `from_serial_port`
- `uart::Buffers` for ASHv2 queue sizing in integration helper constructors

### Minimal `ashv2` usage

```rust
use ezsp::uart::{ChannelSizes, Uart};
use ezsp::{Transport, Utilities};

// Requires feature = "ashv2"
// Requires a Tokio runtime.
async fn example() -> Result<(), ezsp::Error> {
    let serial_port = /* your serial port implementing ashv2::SerialPort */;
    let sizes = ChannelSizes::default();

    let (mut uart, _ash_tasks, _callbacks) =
        Uart::from_serial_port(serial_port, ezsp::MIN_NON_LEGACY_VERSION, &sizes)?;

    uart.ensure_connection().await?;
    let _eui64 = uart.get_eui64().await?;
    Ok(())
}
```

## `apis-saltans` integration (`apis-saltans` feature)

When `apis-saltans` is enabled, the crate exposes `apis_saltans::EzspNetworkManager<T>`.

- `EzspNetworkManager<T>: apis_saltans_hw::NcpDriver` when
  `T: Configuration + Security + Messaging + Networking + Utilities + Send + Sync`.
- `EzspNetworkManager::build(transport, callbacks)` returns `Builder<T>`.
- `Builder<T>: apis_saltans_hw::Start` when `T: Transport + Sync + 'static`.
- `Start::start(...)` configures the NCP, starts callback translation, and returns
  `(apis_saltans_hw::NcpHandle, tokio::sync::mpsc::Receiver<apis_saltans_hw::Event>)`.
- `EzspNetworkManager::terminate()` stops the event handler and returns the underlying transport.

The integration layer translates EZSP callbacks into `apis_saltans_hw::Event`, including network-up/down/open/closed events, child join/leave events, trust-center join/rejoin/leave events, and incoming APS messages. It separately aggregates scan callbacks for `NcpDriver` scan calls and correlates `MessageSent` callbacks with outgoing message tags.

If both `apis-saltans` and `ashv2` are enabled, convenience constructors are available:

- `apis_saltans::EzspNetworkManager::ashv2(serial_port)`

## Legal

This project is free software and is not affiliated with Silicon Labs.

## Contribution guidelines

- Format: `cargo +nightly fmt`
- Lint: `cargo clippy`