npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ccsds-spp

v0.1.0

Published

CSDS Space Packet Protocol implementation for Node.js

Readme

CCSDS SPP: Space Packet Protocol for Node.js

Overview

CCSDS SPP is a comprehensive Node.js library that implements the Consultative Committee for Space Data Systems (CCSDS) Space Packet Protocol (SPP). This implementation provides tools for encoding, transmitting, receiving, and decoding spacecraft telemetry and command packets according to the international CCSDS-133.0-B-2 standard. The library enables satellite ground stations, mission control centers, and space-based systems to reliably exchange structured data over multiple transport protocols while maintaining full compliance with space industry standards.

What is Space Packet Protocol?

The Space Packet Protocol is an international standard used by space agencies worldwide to structure telemetry and command data exchanged with spacecraft. It defines a common format for packaging data with essential metadata including:

  • APID (Application Process Identifier): Identifies the originating or destination application, depending on individual mission configuration (0-2047)
  • Packet Type: Distinguishes between telemetry (TM) and telecommand (TC) packets
  • Sequence Flags: Enables reassembly of segmented packets
  • Packet Counting: Tracks packet ordering and detects losses
  • Optional Secondary Headers: Support for time codes and ancillary data

The protocol is widely adopted by space organizations including NASA, ESA, JAXA, and ISRO for deep space missions, Earth observation satellites, and the International Space Station.

Key Features

Multi-Transport Support

The library seamlessly handles four different transport mechanisms:

  • TCP: Reliable, connection-oriented communication
  • UDP: Low-latency, connectionless protocol
  • WebSocket: Browser-compatible transport for web-based mission control interfaces
  • MQTT: IoT-friendly publish-subscribe model for distributed systems

Each transport is independently configurable and can be selected via configuration file or command-line arguments.

Packet Segmentation & Reassembly

Large transfer datasets that exceed the packet size limits are automatically divided into smaller packets and marked with sequence flags. The library handles reassembly transparently:

  • Unsegmented packets: Single self-contained packets (sequence flag = 3)
  • Segmented packets: Multi-packet messages with start (flag 1), continuation (flag 0), and end (flag 2) markers
  • Out-of-order handling: Packets may arrive out-of-order; the library buffers and reassembles intelligently
  • Automatic extraction mode: Optionally reassemble packets on the receive side before processing

Multiple Time Code Standards

The library implements four CCSDS time code formats, each optionally using the preamble byte, to support mission requirements:

  • CDS (CCSDS Day Segmented):
    • CDS: 6 bytes (16-bit day, 32-bit millisecond)
    • CDS_P: 7 bytes (includes preamble byte)
  • CCS (CCSDS Segmented):
    • CCS_DAY: 9 bytes (day-of-year format)
    • CCS_DAY_P: 10 bytes (with preamble)
    • CCS_MON: 9 bytes (month/day-of-month format)
    • CCS_MON_P: 10 bytes (with preamble)
  • ASCII Time Code:
    • ASCII: 24 bytes (human-readable ASCII format: YYYY-MM-DDThh:mm:ss.dddZ)
    • ASCII_P: 24 bytes (same as ASCII; preamble argument ignored)

When using these optional format flags, time codes will be automatically generated when packets are sent, and inserted correctly into the secondary header.

Protocol Wrapping

For advanced use cases, SPP packets can be wrapped with additional framing protocols:

  • AX.25: Amateur radio packet format, commonly used in cubesat and educational missions
  • KISS (Keep It Simple, Stupid): Serial line framing protocol for radio modem interfaces

Both wrappers add necessary framing while maintaining SPP compliance.

Type-Safe API

Built entirely in TypeScript, the library provides:

  • Full type definitions exported for integration with type-safe applications
  • Strict validation of packet structure and parameters
  • Compile-time checking of configuration objects

Installation

npm install ccsds-spp

Or with yarn:

yarn add ccsds-spp

Quick Start

Basic Usage: Sending Telemetry

import SpacePacketProtocol, { UDPTX } from 'ccsds-spp';

// Create a UDP transport
const transport = new UDPTX({
  transport: 'udp',
  version: 'udp4',
  remoteAddress: 'localhost',
  remotePort: 5000,
  localPort: 5001
});

// Create SPP instance
const spp = new SpacePacketProtocol({
  tx: transport,
  extract: false // Don't extract on receive; get raw packets
});

// Send telemetry from APID 100
const userData = JSON.stringify({
  apid: 100,
  packetType: 'TM',
  userData: 'Hello from spacecraft'
});

spp.write(userData);

// Receive packets
spp.on('data', (packet) => {
  console.log('Received packet:', packet);
});

With Time Codes

// Send telemetry with automatic timestamp
const telemWithTime = JSON.stringify({
  apid: 200,
  packetType: 'TELEMETRY',
  userData: 'Temperature: 25.3C',
  timeCodeFn: 'CDS' // Automatic Unix Epoch timestamp
});

spp.write(telemWithTime);

TCP Transport with Configuration File

Create mission-config.json:

{
  "transport": "tcp",
  "host": "mission-control.example.com",
  "port": 5000
}

In your application:

import SpacePacketProtocol, { TCPTX } from 'ccsds-spp';
import * as fs from 'node:fs/promises';

const config = JSON.parse(
  await fs.readFile('mission-config.json', 'utf8')
);

const tcpTransport = new TCPTX(config);
const spp = new SpacePacketProtocol({ tx: tcpTransport });

// Use as normal
spp.write(JSON.stringify({
  apid: 300,
  packetType: 'TC',
  userData: 'Execute command 42'
}));

Command Packets

// Send telecommand (packet type = 1)
const command = JSON.stringify({
  apid: 50,
  packetType: 'TC', // or 'TELECOMMAND' or 1
  userData: 'POWER_ON_HEATER'
});

spp.write(command);

Extraction Mode: Automatic Reassembly

const spp = new SpacePacketProtocol({
  tx: myTransport,
  extract: true // Automatically reassemble segmented packets
});

spp.on('data', (extractedPacket) => {
  // Packet is reassembled even if it arrived segmented
  console.log('APID:', extractedPacket.apid);
  console.log('Assembled from', extractedPacket.assembledPackets, 'segments');
  console.log('User data:', extractedPacket.userDataRaw);
});

Advanced: AX.25 Wrapping for Amateur Radio

{
  "transport": "udp",
  "version": "udp4",
  "remoteAddress": "192.168.1.100",
  "remotePort": 4000,
  "localPort": 4000,
  "ax25": true,
  "myCall": "W5XYZ",
  "remoteCall": "N0CALL",
  "layer3": "NO_LAYER_3_PROTOCOL",
  "useFlags": true
}

The AX.25 wrapper automatically frames all SPP packets with amateur radio protocol overhead, enabling transmission over radio modems and repeater networks.

MQTT Transport for Distributed Systems

{
  "transport": "mqtt",
  "url": "mqtt://broker.example.com:1883",
  "sendTopic": "spacecraft/telemetry",
  "recvTopic": "mission-control/commands",
  "mqttUsername": "operator",
  "mqttPassword": "secure-password"
}

This configuration publishes all outgoing SPP packets to an MQTT topic and subscribes to receive incoming commands, enabling multi-client mission control architectures.

API Reference

SpacePacketProtocol (Main Class)

Constructor

new SpacePacketProtocol(init: SpacePacketProtocolInitArgs)

Parameters:

  • tx or {xmit, recv}: Transport stream(s) for sending and receiving
  • extract (optional): Enable automatic packet reassembly (default: false)
  • decoding (optional): Buffer encoding for userDataEnc field (e.g., 'utf8', 'hex')
  • maxPDSize (optional): Maximum packet data size in bytes (default: 65536)
  • timeCodeFn (optional): Default time code function name for secondary headers

Methods

write(chunk: string | Buffer): void

Sends a packet. Input can be a JSON string representing a UserPacket or a Buffer.

on('data', callback: (packet: SpacePacket | ExtractedSpacePacket) => void): void

Listens for received packets. Emits either raw SpacePacket (extract=false) or ExtractedSpacePacket (extract=true) objects.

UserPacket (Input Format)

interface UserPacket {
  apid: number;                    // 0-2047
  packetType: 'TM' | 'TC' |        // Telemetry or Telecommand
             'TELEMETRY' | 'TELECOMMAND' |
             0 | 1;
  userData?: string;                // Payload data (base64 or string)
  timeCodeFn?: TimeCodeKey;         // Optional: CDS, CDS_P, CCS_DAY, etc.
  ancillaryData?: string;           // Optional: secondary header data
  dataEncoding?: 'utf8' | 'hex' |   // Input encoding for userData
                 'base64' | ...;
}

SpacePacket (Output Format)

interface SpacePacket {
  apid: number;
  packetId: string;                 // Hex-formatted packet ID (e.g., "0x1a2b")
  rawPacketId: number;
  version: number;                  // SPP version (always 1 for CCSDS)
  packetType: 'TELEM' | 'COMMAND';
  packetDataLength: number;
  userDataRaw: string;              // Hex-encoded payload
  userDataEnc?: string;             // Optional decoded data (if decoding set)
  fullPacketRaw: string;            // Hex-encoded entire packet
  secondaryHeader: boolean;
  sequenceFlag: 0 | 1 | 2 | 3;     // 0=continuation, 1=start, 2=end, 3=unsegmented
}

ExtractedSpacePacket (Reassembled Output)

interface ExtractedSpacePacket {
  apid: number;
  version: number;
  firstPacketId: string;
  rawFirstPacketId: number;
  assembledPackets: number;         // Number of segments merged
  packetType: 'TELEM' | 'COMMAND';
  userDataRaw: string;              // Complete payload
  userDataEnc?: string;
  secondaryHeader: boolean;
}

Command-Line Interface

A CLI tool is available in apps/command-line/app.ts for development and testing. Supported options include:

  • -c, --conf <path>: Load configuration from JSON file
  • -t, --transport <mqtt|tcp|udp|ws>: Transport type
  • -u, --url <url>: Remote host URL/IP
  • -p, --port <number>: Remote host port
  • --lp, --local-port <number>: Local port
  • --lh, --local-host <url>: Local host URL/IP
  • --un, --user-name <string>: Username (for MQTT)
  • --up, --user-password <string>: Password (for MQTT)
  • --wk, --wrap-kiss: Enable KISS framing
  • --wx, --wrap-ax25: Enable AX.25 framing

The CLI accepts JSON on stdin and writes received packets to stdout.

Real-World Examples

Example 1: Ground Station Receiver

import SpacePacketProtocol, { TCPTX } from 'ccsds-spp';
import * as fs from 'node:fs';

const spp = new SpacePacketProtocol({
  tx: new TCPTX({
    transport: 'tcp',
    host: '192.168.1.1',
    port: 9000
  }),
  extract: true, // Reassemble segmented packets
  decoding: 'utf8'
});

spp.on('data', (packet) => {
  const timestamp = new Date().toISOString();
  const log = `[${timestamp}] APID=${packet.apid} Data=${packet.userDataEnc}\n`;
  fs.appendFileSync('telemetry.log', log);
});

Example 2: Spacecraft Command Handler

import SpacePacketProtocol, { UDPTX } from 'ccsds-spp';

const spp = new SpacePacketProtocol({
  tx: new UDPTX({
    transport: 'udp',
    version: 'udp4',
    remoteAddress: 'spacecraft.local',
    remotePort: 10000,
    localPort: 10000
  }),
  timeCodeFn: 'CDS' // All packets include timestamp
});

// Send commands with time code
spp.write(JSON.stringify({
  apid: 1,
  packetType: 'TC',
  userData: 'RTC_SYNC',
  timeCodeFn: 'CDS'
}));

Example 3: Integration with TypeScript

import SpacePacketProtocol, {
  type SpacePacket,
  MAX_APID
} from 'ccsds-spp';

const spp = new SpacePacketProtocol({ tx: transport });

function handlePacket(packet: SpacePacket) {
  if (packet.apid >= 0 && packet.apid < MAX_APID) {
    const payload = Buffer.from(packet.userDataRaw, 'hex');
    console.log(`Got ${payload.length} bytes from APID ${packet.apid}`);
  }
}

spp.on('data', handlePacket);

Configuration Schema

The library includes a JSON schema (transport-config.json) for validating configuration files in IDEs and build tools. Use it for autocomplete and validation:

{
  "$schema": "./schemata/transport-config.json",
  "transport": "tcp",
  "host": "example.com",
  "port": 5000
}

Performance Considerations

  • Packet Size: The library supports packets up to 65,536 bytes of data. Configure maxPDSize to match your transport MTU (e.g., 1500 for Ethernet).
  • Extraction Overhead: Packet reassembly requires in-memory buffering. For high-volume, real-time telemetry, consider disabling extraction and handling segmentation at the application layer.

Standards Compliance

This implementation conforms to:

  • CCSDS 133.0-B-2: Space Packet Protocol
  • CCSDS 301.0-B-4: CCSDS Time Code Formats

License

ISC

Contributing

Contributions are welcome. Please ensure code includes type definitions and follows the existing style.

See Also