Getting Started

Prerequisites

  • CMake 3.10+
  • C11-compatible compiler (gcc / clang)
  • libcsp v1.6
  • (Optional) Python 3 + pyzmq for ZMQHUB-based testing
  • (Optional) Rust toolchain for Rust bindings

Building

git clone https://github.com/dtn-mtp/cspcl.git
cd cspcl
mkdir build && cd build
cmake ..
make
ctest --verbose

CMake Options

Option Default Description
CSPCL_BUILD_TESTS ON Build unit tests
CSPCL_BUILD_EXAMPLES ON Build example applications
CSPCL_USE_FREERTOS OFF Target FreeRTOS instead of POSIX
CSPCL_DEBUG OFF Enable verbose debug output

Using a custom libcsp location

cmake -DCSP_PATH=/path/to/libcsp ..

C — First Bundle Transfer

1. Initialize

#include "cspcl.h"

cspcl_t cspcl;

// Initialize with local CSP node address
cspcl_error_t err = cspcl_init(&cspcl, 1);

// Open receive socket (bind to BP port once)
err = cspcl_open_rx_socket(&cspcl);

2. Send a bundle

uint8_t bundle[] = { /* serialized BP7 bundle */ };

err = cspcl_send_bundle(&cspcl, bundle, sizeof(bundle), 2 /* dest CSP addr */);
if (err != CSPCL_OK) {
    fprintf(stderr, "send error: %s\n", cspcl_strerror(err));
}

Large bundles are automatically fragmented using CSP’s SFP — no extra work required.

3. Receive a bundle

uint8_t buf[CSPCL_MAX_BUNDLE_SIZE];
size_t  buf_len = sizeof(buf);
uint8_t src_addr;

err = cspcl_recv_bundle(&cspcl, buf, &buf_len, &src_addr, 5000 /* ms */);
if (err == CSPCL_OK) {
    printf("Received %zu bytes from CSP addr %u\n", buf_len, src_addr);
}

4. Cleanup

cspcl_cleanup(&cspcl);

Rust — First Bundle Transfer

Add the dependency:

[dependencies]
cspcl = "0.4"
futures = "0.3"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use cspcl::{CspAddress, Cspcl, Interface};
use futures::StreamExt;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let local = CspAddress { addr: 1, port: 10 };
    let node = Arc::new(Cspcl::new(local, Interface::Loopback)?);

    // Send
    let bundle: Vec<u8> = vec![/* BP7 bundle bytes */];
    let remote = CspAddress { addr: 2, port: 10 };
    node.send_bundle(&bundle, remote)?;

    // Receive from the inbound bundle stream.
    let mut inbound = Arc::clone(&node).inbound();
    while let Some(bundle) = inbound.next().await {
        let bundle = bundle?;
        println!(
            "Received {} bytes from CSP {}:{}",
            bundle.data.len(),
            bundle.src_addr,
            bundle.src_port
        );
    }

    Ok(())
}

Next Steps


University of Montpellier Space Center