udptl 0.1.0

UDPTL (UDP Transport Layer) codec and socket for T.38 fax
Documentation

udptl

UDPTL (UDP Transport Layer) codec and socket for T.38 fax over IP.

Implements the UDPTL packet format defined in ITU-T T.38 with both redundancy and FEC error recovery modes. Wire-compatible with SpanDSP.

Usage

[dependencies]
udptl = "0.1"

Async (tokio, default)

use udptl::AsyncUdptlSocket;

let socket = tokio::net::UdpSocket::bind("0.0.0.0:0").await?;
let udptl = AsyncUdptlSocket::new(socket);
udptl.connect("192.168.1.100:9000".parse()?);

// Send an IFP packet (redundancy added automatically)
udptl.send_ifp(&ifp_data).await?;

// Receive
let packet = udptl.recv_packet().await?;
println!("{}", packet); // UDPTL seq=0 primary=128B redundant=3

Sync

[dependencies]
udptl = { version = "0.1", default-features = false }
use udptl::UdptlSocket;

let socket = std::net::UdpSocket::bind("0.0.0.0:0")?;
let udptl = UdptlSocket::new(socket);
udptl.connect("192.168.1.100:9000".parse()?);

udptl.send_ifp(&ifp_data)?;
let packet = udptl.recv_packet()?;

Codec only

Encode and decode packets without a socket:

use udptl::{UdptlPacket, ErrorRecovery};

// Decode
let packet = UdptlPacket::decode(&wire_bytes)?;

// Encode
let packet = UdptlPacket::with_redundancy(0, ifp_data, redundant_packets);
let bytes = packet.encode();

// FEC mode
let packet = UdptlPacket::with_fec(0, ifp_data, 3, fec_entries);
let bytes = packet.encode();

Configuration

use udptl::{UdptlSocket, UdptlConfig, ErrorCorrectionScheme};

let config = UdptlConfig {
    error_correction: ErrorCorrectionScheme::Redundancy,
    max_redundancy: 3,
    fec_span: 3,
    fec_entries: 3,
    max_packet_size: 512,
};
let udptl = UdptlSocket::with_config(socket, config);

License

MIT

AI DISCLAIMER

Bro this is slop city deluxe. I heavily supervised the model but it's 2026, get real. No warranties express or implied etc etc.