Native serial link

Atlas on the radio’s own bytes.

A long-range serial telemetry radio moves 57 to 115 kilobits a second. On a pipe that narrow, every byte of header and every buffer Atlas cannot see decides whether a call fits at all. Where both ends of a radio pair run Atlas, [[link]] type = "serial" puts Atlas datagrams straight onto the radio’s serial port: no adapter, no pseudo-terminal, no pppd, no IP or UDP, no address plan per radio pair. Atlas writes only when the radio has room, reads the radio’s signal in-line, comes back on the first probe after a reset, and lets several radios share one channel. Everything above the frame — sessions, probes, scheduling, routing, classes — sees one more link.

ShippedSiK-family radios, RFD900-classpppd stays for PPP and IP devices
The two chains Shipped

Six stages become two.

The classic way to carry IP over a serial radio is a bridge process that owns the port and strips the radio’s own status frames, a pseudo-terminal that pppd attaches to, a PPP session with its own negotiation and liveness, an IP address per radio pair, and finally a UDP socket in the daemon. Each stage adds bytes, a buffer or a way to fail. The native link removes all of them: the daemon opens the serial device and does the four jobs that matter itself — separating the radio’s status frames, framing, pacing and liveness.

THROUGH PPP · TODAY’S CHAIN ON MOST SERIAL RADIOS Radioserial port AdapterMAVLink parse PTYpseudo-terminal pppdHDLC · LCP · IPCP IP + UDPppp0 · address plan atlasda UDP socket +28 B of IPv4 and UDP and ~5 B of PPP framing per packet · PPP renegotiates after every reset · LCP echo beside Atlas probes NATIVE · [[LINK]] TYPE = "SERIAL" Radioserial port atlasd · serial linkstatus frames out · COBS + CRC frames · pacing +4 B per packet · resumes on the first frame after a reset · no IP plan, no setuid helper, no second telemetry path
THROUGH PPPradio ⇄ adapter ⇄ pseudo-terminal ⇄ pppd ⇄ IP + UDP ⇄ atlasd: about 33 bytes added per packet
NATIVEradio ⇄ atlasd: four bytes of framing per packet
AFTER A RESETno renegotiation: traffic resumes on the first frame
Per packet

What leaves every packet

IPv4’s 20 bytes, UDP’s 8, PPP’s protocol field, frame check sequence and flag, and HDLC byte escaping — two byte values with asyncmap 0, thirty-four with pppd’s default. On a 104-byte voice datagram that is about 29 bytes, a fifth of the packet.

Per link

What leaves every radio pair

The adapter process, the pseudo-terminal, pppd and its setuid root, an IP address plan per radio pair, LCP negotiation after every reset, LCP echo running beside Atlas’s own probes, and a second telemetry path over a Unix socket.

Unchanged

What stays exactly as it is

The outer and inner Atlas headers, session sealing, sealed probes, the scheduler, shortest-path routing, transport classes, end-to-end encryption and the signed control plane. A serial link is one more member of the bond: it can carry everything alone, share traffic with a cellular modem, or stand by as the last link that still reaches. the data path ↗

On the wire Shipped

Four bytes of framing instead of thirty-three.

Each Atlas datagram is followed by a CRC-16, encoded with Consistent Overhead Byte Stuffing and closed with a single zero byte. That is the whole frame. Below, one voice packet drawn to scale both ways: the Atlas datagram is the same 104 bytes in each row; everything around it is what the radio has to carry for it.

THROUGH PPPD · ASYNCMAP 0 IPv420 B UDP8 B Atlas datagram · 104 Bouter 8 · inner 20 · voice packet 60 · AEAD tag 16 ≈137 B flag + protocol · 2 B FCS-16 + escaping · ≈3 B NATIVE SERIAL LINK IPv4 · UDP · PPP removed · 29 B Atlas datagram · 104 Bthe same bytes, untouched 108 B COBS code byte CRC-16 + 0x00 delimiter · 3 B Measured on 64 kbit/s air: 105.0 B per voice packet natively, 133.6 B through pppd with asyncmap 0, 182.6 B with pppd’s default asyncmap. Drawn to scale, 6 px per byte. A frame after a quiet line of 20 ms or more, and every addressed frame, opens with one extra 0x00.
THROUGH PPPD · ASYNCMAP 0flag + protocol 2 · IPv4 20 · UDP 8 · Atlas 104 · FCS + escaping ≈3 = about 137 B
NATIVEcode byte 1 · Atlas 104 · CRC-16 2 · 0x00 1 = 108 B
MEASURED105.0 B against 133.6 B per voice packet: 28.6 B saved, 77.6 B against pppd’s default asyncmap
COBS

A fixed, tiny cost, known before the frame is sent

Consistent Overhead Byte Stuffing removes every zero from the frame, so a zero byte can only ever be a boundary. It costs one code byte per 254 bytes — 0.4 % in the worst case — where HDLC escaping, PPP’s and SLIP’s method, doubles a frame in the worst case and adds about 13 % to encrypted bytes under pppd’s default asyncmap. Because the cost is fixed, the airtime of every frame is known before it is written, which is what the pacer and the fragment ceiling compute with. Up to 254 bytes, a datagram costs exactly four bytes: the code byte, the CRC and the delimiter.

Resync

One bad byte costs one frame

The receiver gathers non-zero bytes and decodes on the delimiter; there is no escape state to fall out of. A lost or corrupt byte damages one frame, and the next zero starts a clean one. When the port opens, everything up to the first delimiter is discarded and counted, so the tail of a frame that began before a reset never reaches the CRC. After a quiet line, and on every addressed frame, an extra leading zero closes whatever a reset radio, a replug or another node’s interleaved bytes left behind.

CRC-16

PPP’s own check, kept on purpose

The frame check is CRC-16/X-25 — PPP’s FCS-16 — so the native link keeps exactly the error detection of the path it replaces: every 1-, 2- and 3-bit error and every burst up to 16 bits in any frame Atlas sends. Two more bytes for a 32-bit check would buy nothing here. The radio already checks a CRC per air packet, so what reaches the port is mostly whole air packets or missing ones; the damage the link catches is structural — a lost air packet joining the head of one frame to the tail of the next, bytes dropped on overflow, a baud mismatch. And every Atlas datagram is authenticated above the frame: a corrupt frame that slips past the CRC is refused there and never delivered.

asyncmap

Why PPP costs more than its headers

pppd’s default asyncmap escapes the 32 control byte values as well as the flag and escape bytes. Encrypted payloads look random, and the clear headers in front of them are full of small values, so the escapes add up: 182.6 bytes per voice packet against 133.6 with asyncmap 0. Measured

Byte budgets

What each packet costs at 57.6, 64 and 115.2 kbit/s.

Three rates matter on these radios. 57.6 and 115.2 kbit/s are the common serial line rates; with a start and a stop bit, every byte costs ten bits on the line, so they carry 5 760 and 11 520 bytes a second. 64 kbit/s is a common air rate, 8 000 bytes a second. The table gives the bytes Atlas hands the radio for each kind of packet and how long each occupies the line or the air; the radio adds its own air framing on top, the same for both chains.

PacketAtlas datagramNative · pppd57.6 kbit/s line64 kbit/s air115.2 kbit/s line
Probe or probe reply44 B48 B · ≈76 B8.3 ms · 13.2 ms6.0 ms · 9.5 ms4.2 ms · 6.6 ms
Voice, 20 ms frame104 B108 B · ≈137 B18.8 ms · 23.8 ms13.5 ms · 17.1 ms9.4 ms · 11.9 ms
Voice, 20 ms + previous frame168 B172 B · ≈201 B29.9 ms · 34.9 ms21.5 ms · 25.1 ms14.9 ms · 17.4 ms
Voice, 40 ms frame136 B140 B · ≈169 B24.3 ms · 29.3 ms17.5 ms · 21.1 ms12.2 ms · 14.7 ms
Voice, 40 ms + previous frame232 B236 B · ≈266 B41.0 ms · 46.2 ms29.5 ms · 33.2 ms20.5 ms · 23.1 ms
Telemetry, a 40-byte MAVLink message112 B116 B · ≈145 B20.1 ms · 25.2 ms14.5 ms · 18.1 ms10.1 ms · 12.6 ms
Video fragment, 256-byte piece300 B305 B · ≈334 B53.0 ms · 58.0 ms38.1 ms · 41.8 ms26.5 ms · 29.0 ms

An Atlas datagram is the inner IP packet plus 44 bytes: 8 outer header, 20 inner header, 16 AEAD tag; a sealed probe is 44 bytes in all. Voice is a 32-byte codec frame in a 60-byte IP packet (92 bytes at 40 ms); the previous frame adds a copy of the last packet and a 4-byte trailer. The pppd column is IPv4 and UDP, PPP’s protocol field, FCS-16, one flag and the escaping of the datagram’s bytes under asyncmap 0; native counts the worst-case COBS code bytes.

Streams, as a share of each rate

Per direction. A half-duplex radio shares its air rate between both directions, so a two-way call needs the voice line twice on air; a push-to-talk net needs it once.

StreamNative · pppd57.6 kbit/s line64 kbit/s air115.2 kbit/s line
Voice, 50 frames/s43.2 · 54.8 kbit/s94 % · 119 %68 % · 86 %47 % · 59 %
Voice, 50 frames/s + previous68.8 · 80.4 kbit/s149 % · 174 %108 % · 126 %75 % · 87 %
Voice, 25 frames/s28.0 · 33.8 kbit/s61 % · 73 %44 % · 53 %30 % · 37 %
Voice, 25 frames/s + previous47.2 · 53.2 kbit/s102 % · 115 %74 % · 83 %51 % · 58 %
Telemetry, 10 messages/s9.3 · 11.6 kbit/s20 % · 25 %14 % · 18 %10 % · 13 %
Probes, one round a second0.8 · 1.2 kbit/s1.7 % · 2.6 %1.2 % · 1.9 %0.8 % · 1.3 %
Radio heartbeat, every 250 ms0.5 kbit/s · the same1.2 %0.9 %0.6 %

Kilobits are the bytes Atlas hands the radio, times eight. Shares above 100 % do not fit. The heartbeat is the 17-byte MAVLink message that makes the radio report its status; either chain writes it.

Worked examples

Voice and telemetry on one serial radio.

Three link plans, worked from the budgets above. Voice goes in the Voice class, flight commands in Control, the vehicle’s position in Position — the high band, sent first and never held — while general telemetry and video share the low band, which waits in Atlas’s own queue.

57.6 line

A call and the telemetry, on a radio at its default line rate

A radio left at 57 600 baud carries 5 760 bytes a second, whatever its air rate. Voice in 40 ms frames, ten 40-byte telemetry messages a second, one probe round and four radio heartbeats a second need 4 824 bytes a second natively — 84 % of the line — and about 5 900 through pppd, more than the line holds. The same call and the same telemetry fit natively and do not fit through PPP. With 20 ms frames the voice alone takes 94 % of the line natively and 119 % through PPP: on this radio, choose 40 ms frames or raise the line rate.

64 air

Voice beside video, on 64 kbit/s air

At 115 200 baud the line outruns the air, and the radio’s buffer is where queues form. Fifty voice frames a second take 43.2 kbit/s of the 64 natively. Offered alongside about 110 kbit/s of 1 400-byte video, paced voice arrives one-way at p95 100.6 ms with full-duplex air and 131.4 ms with half-duplex air, 97 to 100 % of frames delivered, and the video still carries about 17 kbit/s. Without pacing the same voice waits about 1.95 s and 6 % of it arrives, because the radio’s buffer fills with video and overflows. Measured

The 100 ms is airtime, not queueing. A voice frame waits at most behind the low-band frame just released plus one fragment’s airtime of queue; while a call is on the link, Atlas cuts video into fragments of about 20 ms of airtime, and a 256-byte fragment is 38 ms on 64 kbit/s air. Holding the queue tighter would starve the video entirely.

Redundancy

Previous-frame redundancy, sized to the radio

Carrying each voice frame’s predecessor in the next packet means one lost packet costs no audio. With 20 ms frames that is 68.8 kbit/s natively — more than 64 kbit/s air holds, so on that radio use 40 ms frames, at 47.2 kbit/s with redundancy, or a faster air rate. At 115.2 kbit/s the 20 ms stream with redundancy takes 75 % of the line. Through PPP the same plans cost 80.4 and 53.2 kbit/s. transport classes ↗

Telemetry

The vehicle’s data, beside the voice

A 40-byte telemetry message costs 116 bytes natively and about 145 through PPP: ten a second are 9.3 or 11.6 kbit/s. Position reports and commands ride the high band with voice and go out first; bulk telemetry and logs wait in the low band and fill what is left. Store-carry-forward and deadlines work on a serial link as on any other: what cannot cross in time is held or dropped in Atlas’s queue, never in the radio’s.

Buffer-aware pacing Shipped

Atlas decides what goes on air next.

A serial radio keeps a transmit buffer of a few kilobytes and sends it in turn, oldest first. Whatever reaches that buffer is committed: a voice frame behind two kilobytes of video waits a quarter of a second on 64 kbit/s air, and a buffer that overflows drops bytes from the middle of frames. The radio reports how full the buffer is, and the native link writes only while the bytes below Atlas stay under a small target — so the queue that decides the order is Atlas’s own, where a voice frame overtakes video.

UNPACED As fast as the port takes it the radio’s buffer fills and overflows; voice waits behind all of it BYTES BELOW ATLAS radio buffer full overflow: the radio drops what it cannot hold a voice frame enters here and reaches the air ≈1.95 s later PACED Written when the radio has room bytes below Atlas held under a target; video waits in Atlas’s queue BYTES BELOW ATLAS target: one fragment’s airtime while voice is on voice: the high band is never held — p95 100.6 ms with full-duplex air, 131.4 ms half duplex measured on 64 kbit/s air, 50 voice frames a second beside ~110 kbit/s of video offered
UNPACEDthe radio’s buffer fills with video and overflows; voice p95 ≈1.95 s, 6 % delivered
PACEDbytes below Atlas held under about one fragment’s airtime; video waits in Atlas’s queue
VOICEp95 100.6 ms with full-duplex air, 131.4 ms half duplex, 97–100 % delivered
Three queues

Everything between Atlas and the air, counted

Frames handed to the writer thread and not yet in the kernel are counted exactly. The serial line — the kernel’s tty queue, the USB adapter and the UART — drains at a tenth of the baud rate in bytes; the kernel part is read with TIOCOUTQ and the rest is integrated from what was written. The radio’s transmit buffer drains at the air rate: each status report replaces the estimate with the radio’s own figure, carried forward by what was delivered and sent since, and two reports from a busy buffer measure the air rate the radio actually gets, never above the declared one.

The target

Short while voice is on, deeper when it is not

The low band is held while the bytes below exceed the larger of the class target and a floor that lets the next frame cross the line while the radio sends the last. While the high band has been used in the last second, the floor is capped at one fragment’s airtime, 20 ms, so a voice frame waits behind at most that and the frame just released. With no high band in use, the floor is at least 100 ms of airtime, so a half-duplex radio fills its transmit windows instead of sending one short packet per turn.

One pacer

The same pacer as every other link

The sum of the three queues is handed to the low-band pacer as a queue reading, so a serial link is paced by the same code, counters and dashboard chip as an Ethernet or cellular link with a readable device queue — even though there is no queueing discipline under it. It is paced by default, with or without transport classes, because nothing else stands between Atlas and the radio. The high band — Control, Voice, Position — is never held. queues below the tunnel ↗

Flow control

With or without RTS/CTS

Without hardware flow control, the default on these radios, a radio sent more than its buffer holds drops the excess and corrupts the frames it cut — exactly what pacing prevents. With flow_control = "rtscts" the radio also stops the line when its buffer is full and the kernel holds the rest, which the model reads. A radio that never reports, a generic byte pipe, is paced on the line and the declared rate alone.

The radio’s own report Shipped

Signal and buffer, read in-line.

With MAVLink framing on, a SiK-family radio answers each heartbeat from its host with a status frame — RSSI and noise at both ends, and how full its transmit buffer is — injected into the same byte stream the data uses. The native link writes that heartbeat, four times a second by default, and pulls the radio’s answer out of the stream itself, with no adapter process.

Extraction

Out of the stream before the frames are read

The radio inserts its status frame between air packets, so it can land in the middle of an Atlas frame, and it contains zero bytes that would read as delimiters. The extractor therefore runs on the raw stream first and takes only bytes that match the exact MAVLink framing, length, message id and checksum of the two radio messages; anything else passes through untouched. On encrypted traffic a false match needs about forty random bits to line up, and a damaged match costs only the one frame it sat in. The peer’s heartbeats, which the radio forwards over the air, are stripped the same way.

Steering

Into the link score, the trend and the routing flood

Local and remote RSSI, noise and buffer fill go straight into the link monitor through the same call the telemetry socket uses, so the link score, RSSI-trend prediction and the per-link signal carried in each link-state advert all work as they do with an adapter. A radio whose signal is diving moves traffic off the link before its probes start to miss. The heartbeat costs 17 bytes four times a second: 0.9 % of 64 kbit/s. prediction ↗

Multipoint Shipped

Several radios, one channel.

PPP is point to point by definition. SiK-family radios with multipoint firmware can broadcast on one channel, so every radio hears every other — and with a node address in each frame, one radio reaches several peers. Setting address on a link switches it to addressed frames: three bytes in front of the datagram, a marker, the destination and the source.

ONE BROADCASTING CHANNEL one radio channel every radio hears every frame node · address 1sends to address 2 node · address 2keeps it: addressed to 2 node · address 3hears it, drops it: not for us AN ADDRESSED FRAME 0x00 0xA0 dst src Atlas datagram CRC-16 0x00 marker, destination and source: 3 bytes; 255 is broadcast Keptthe destination is this node, or 255 Counted and droppedthe destination is another node: not_for_us Refusedthe source is 0, 255 or this node’s own address Measured: three radios on one channel, every pair reachable. A peer missing from peer_addresses is learned from its first authenticated frame.
ONE CHANNELevery radio hears every frame; three address bytes say who it is for
RECEIVERSkeep frames for themselves or 255, count the rest as not for us, refuse impossible sources
MEASUREDthree radios on one channel, every pair reachable
Addresses

Configured where it matters, learned where it does not

Each node takes an address from 1 to 254 on the channel. peer_addresses tells a node where a peer sits before it has heard from it, which the side that starts a session needs; any other peer is learned from its first authenticated frame, the way endpoint roaming learns a UDP address. The marker byte can never open an Atlas datagram, so a receiver tells addressed and point-to-point frames apart without a negotiated mode.

Mesh

A real mesh over long-range radios

Every peer on the channel is an ordinary neighbour to the routing layer: link-state adverts cross the channel, shortest paths run over it, and a node that also holds a cellular or Wi-Fi link can carry traffic between the radio net and the rest of the fleet. One radio replaces a stack of point-to-point pairs, each with its own PPP session and address plan.

Liveness and recovery Shipped

Back on the first probe.

Atlas probes are the liveness check on a serial link, as on every link: dead after the configured number of misses, alive again on the next completed round trip. There is no LCP and no second state machine. Sessions belong to peers, not links, so a link that returns carries traffic at once — there is nothing to renegotiate. Traffic resumed 53 ms after a radio reset and 194 ms after a radio was unplugged and plugged back in. Measured

FailureWhat the link doesWhat the operator sees
Radio resetProbes miss, the link goes dead; the first frame after the radio is back is delivered.Alive false, then true — traffic back 53 ms after the radio.
Unplug and replugThe reader sees the hang-up, closes the device and reopens it every 500 ms; a /dev/serial/by-id/ path finds the same radio again.Open false with the last error, then a reopen count and a journal event — back 194 ms after the device reappears.
Baud mismatchBytes arrive as noise and no frame survives the CRC.CRC, framing and resync counters climb while received frames stay flat; UART frame errors on a real port.
Garbage, partial frames, bit errorsThe damaged frame is dropped; the next delimiter resynchronises.The CRC, framing and resync counters.
Radio buffer overflowPacing keeps the buffer short; what would have been dropped is estimated.Estimated overflow bytes and the radio’s buffer free, in percent.
A forgotten pppd on the portThe link opens the device exclusively, so a later opener is refused instead of splitting the byte stream.Open false, last error “device or resource busy”, until the other process lets go.

Every figure appears per link in the stats snapshot, and on the dashboard’s link card under a serial chip with the line rate. The dashboard reads them like any other link.

Native or pppd

The comparison, row by row.

Both chains are supported. The native link is for radios with Atlas at both ends; pppd is for everything else. The difference is in what each one can see and what each one costs on a narrow pipe.

pppd on both endsNative serial link
Works withAnything that speaks IP: any application, dial-up modems, satellite terminals, tactical radios with PPP or IP portsAtlas to Atlas
Bytes per small packetProbe ≈76, voice ≈137 with asyncmap 0; more with the default asyncmapProbe 48, voice 108
Radio buffer and signalBehind pppd and the kernel; the signal arrives over a separate adapterRead in-line: writes paced on the radio’s buffer, RSSI and noise into routing
Recovery after a replugPPP negotiation, secondsThe first frame after the port reopens
TopologyPoint to pointPoint to point, or several radios on one channel
AddressingAn IP address plan per radio pairNone point to point; one byte per node on a shared channel
ProcessesAdapter, pseudo-terminal, pppd running setuid rootTwo threads inside the daemon
DebuggingStandard tools: ping the far end, capture on ppp0Atlas’s own counters, snapshot, dashboard and journal
StandingThirty years of PPP; accreditors know itCOBS framing with PPP’s own CRC; every datagram authenticated above it
When to keep pppd

The PPP path stays, for the cases it is built for.

The SiK adapter and pppd remain a supported way to put a serial radio in the bond. Atlas encrypts everything on either path, so security never depends on the choice.

The far end is not Atlas

A ground station, a gateway or a vendor box that expects IP over the radio. The native frame means something only to another Atlas node.

The device offers PPP or IP only

Dial-up and satellite modems, tactical radios with PPP or IP ports: they hand you an IP interface, and Atlas bonds it as an ordinary link.

Other traffic needs the radio’s IP

When something outside the tunnel has to reach the far radio by address, the PPP link provides that address. Inside the tunnel, everything already has one.

The accreditation names PPP

Where an approved configuration specifies the standard path, keep it — and set asyncmap 0 on both ends: the default escapes 32 byte values and adds about 12 % to every encrypted packet.

Both ends of a serial link run the native framing or neither does. Moving a radio pair over is one change to its [[link]] on both nodes, with the adapter and pppd stopped there.

config.toml — a radio pair, then three nodes on one channel
# Point to point: an RFD900-class pair, Atlas on both ends.
[[link]]
name = "rfd"
type = "serial"
device = "/dev/serial/by-id/usb-FTDI_FT231X_USB_UART_D30A1B2C-if00-port0"
baud = 57600            # must match the radio
radio = "rfd900"         # rfd900 | sik | generic
air_rate = "64 kbps"     # capacity = the lower of line and air
flow_control = "none"    # or "rtscts"
probe_interval_ms = 1000  # radios are slow and half duplex

# Several nodes on one broadcasting channel: add an address.
# address = 1
# peer_addresses = { "10.0.100.2" = 2, "10.0.100.3" = 3 }

Defaults: 57 600 baud; a heartbeat every 250 ms for rfd900 and sik, none for generic; a 2 048-byte radio buffer; pacing on. A serial link takes no bind_device; two serial links on one device, a reserved or duplicate address, or peer_addresses without an own address are refused by name when the configuration loads.

Boundaries

What the native link is, and is not.

Stated in the same font size as everything above.

Both ends

Atlas to Atlas only

The frame carries Atlas datagrams and nothing else. A radio whose far end is not an Atlas node, or a device that offers only PPP or IP, stays on the adapter and pppd. Both nodes of a pair must run a build with the serial link.

Shared channel

One copy per peer, and interleaving

On a shared channel the engine sends link-state floods and gossip as one unicast copy per peer, where one broadcast frame would reach all of them. When a radio’s transmit slot ends mid-frame, frames from two senders can interleave at a receiver: the split frame is lost and counted as a framing error, and the next one survives on its leading delimiter.

Air

Half-duplex air is shared

SiK-family radios talk in turns, and both directions share the air rate. The pacer measures the rate one direction actually gets from the radio’s reports, but it cannot create air: a two-way call needs its budget twice. Round trips include the other side’s turn, so a radio link wants a probe interval of 500 to 1 000 ms.

The radio

Configured by you, not by Atlas

Atlas does not send AT commands. MAVLink framing, line rate, air rate, flow control and multipoint settings are set on the radio with its own tools. The radio’s buffer size is a link setting, radio_buffer_bytes, 2 048 bytes by default, and turns the reported fill into bytes.

Voice

Airtime sets the floor

On 64 kbit/s air a voice frame can still wait behind the low-band frame just released and one fragment’s airtime of queue, which is where the 100 ms comes from. Previous-frame redundancy with 20 ms frames needs more than 64 kbit/s of air.

Request an evaluation

Running serial radios today?

Bring the radios, their line and air rates and what has to cross them. The answer is a link plan with the byte budget of every stream on it.