Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/cblk/csp_if_cblk.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <csp/csp.h>
#include <param/param.h>

#include <libcblk.h>

typedef enum { CBLK_EXTHDR_NOSUPPORT = 0b00, CBLK_EXTHDR_SUPPORT = 0b01, CBLK_EXTHDR_PRESENT = 0b10} ext_hdr_e;

typedef struct __attribute__((packed))
Expand All @@ -30,6 +32,11 @@ typedef struct __attribute__((packed))
uint8_t data[]; //! Space Inventor specific data
} cblk_frame_t;

#ifdef RS_ENCODE
#define ASM_LEN 4
#define RS_CHECKSUM_LEN 32
#endif

#define CCSDS_FRAME_LEN 223
#define CBLK_DATA_LEN (CCSDS_FRAME_LEN-sizeof(cblk_hdr_t))
#define CRYPTO_PREAMP 16 /* crypto_secretbox_BOXZEROBYTES */
Expand Down
20 changes: 15 additions & 5 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ project('cblk', ['c', 'cpp'])

cblk_deps = []
cblk_args = []
conf = configuration_data()

if not meson.is_subproject()
csp_dep = dependency('csp', fallback : ['csp', 'csp_dep'], required: true).partial_dependency(links: true, includes: true)
Expand All @@ -19,6 +20,14 @@ cblk_src = files([
'src/crypto/crypto_param.c',
])

if get_option('rs_encode')
conf.set('RS_ENCODE', 1)
cblk_src += files([
'src/ccsds_randomize.c',
'src/rs_encode.c',
])
endif

nacl_impl = get_option('nacl_impl')

if nacl_impl == 'tweetnacl'
Expand All @@ -35,19 +44,20 @@ elif nacl_impl == 'sodium'
cblk_args += '-DUSE_SODIUM'
endif

cblk_inc = include_directories('src')
api = include_directories('include')
cblk_inc = include_directories('.', 'include')

libcblk_h = configure_file(output: 'libcblk.h', configuration: conf)

cblk_lib = static_library('cblk',
sources: [cblk_src],
include_directories : [cblk_inc, api],
sources: [cblk_src, libcblk_h],
include_directories : [cblk_inc],
dependencies : cblk_deps,
c_args : cblk_args,
install : false
)

cblk_dep = declare_dependency(
include_directories : api,
include_directories : cblk_inc,
link_with : cblk_lib,
dependencies: cblk_deps,
)
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ option('nacl_impl',
value: 'tweetnacl',
description: 'Which NaCl implementation to use'
)
option('rs_encode', type: 'boolean', value: false, description: 'Do Reed-Solomon encoding as part TX')
58 changes: 58 additions & 0 deletions src/ccsds_randomize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* ccsds_randomize.c
*
* Created on: 25 aug 2022
* Author: Per Henrik Michaelsen
*/

#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>

static bool _initialized = 0;
static uint8_t _mask[255] = { 0 };

bool _check()
{
// First 40 bit provided in CCSDS 131.0-B-4.
// 1111 1111 0100 1000 0000 1110 1100 0000 1001 1010
uint8_t check[] = { 0xff, 0x48, 0x0e, 0xc0, 0x9a };
bool equal = true;
for (size_t i = 0; i < sizeof(check); ++i) {
equal &= (_mask[i] == check[i]);
}
return equal;
}

static void _init()
{
uint8_t lfsr = 0xff;
uint8_t next = 0;
uint8_t val = 0;
size_t i = 0;
size_t j = 0;
for (i = 0; i < 255; ++i) {
val = 0;
for (j = 0; j < 8; ++j) {
val = (val << 1) | (lfsr & 1);
next = lfsr ^ (lfsr >> 3) ^ (lfsr >> 5) ^ (lfsr >> 7);
lfsr = (lfsr >> 1) | ((next & 1) << 7);
}
_mask[i] = val;
}

if (!_check()) {
printf("ERROR: CCSDS randomization first 40 bits are wrong.");
}
}

void ccsds_randomize(uint8_t * block)
{
if (!_initialized) {
_init();
_initialized = 1;
}
for (size_t i = 0; i < 255; ++i) {
block[i] ^= _mask[i];
}
}
27 changes: 27 additions & 0 deletions src/ccsds_randomize.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* ccsds_randomize.h
*
* Created on: 25 nov 2022
* Author: Per Henrik Michaelsen
*/
#ifndef CCSDA_RANDOMIZE_H_
#define CCSDS_RANDOMIZE_H_

#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>

/**
* Randomization is a mask xor'ed on a Reed-Solomon (255,223) block,
* which is the data that comes after the ASM in a CADU frame.
*/

/**
* @brief CCSDS randomize
* Aplly the CCSDS randomization mask on a single Reed-Solomon block.
*
* @param block The block
*/
void ccsds_randomize(uint8_t * block);

#endif // CCSDS_RANDOMIZE_H_
14 changes: 14 additions & 0 deletions src/csp_if_cblk.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include "crypto/crypto.h"
#include <param/param.h>

#ifdef RS_ENCODE
#include "rs.h"
#include "ccsds_randomize.h"
#endif

uint8_t _cblk_rx_debug = 0;
uint8_t _cblk_tx_debug = 0;

Expand Down Expand Up @@ -101,6 +106,15 @@ int csp_if_cblk_tx(csp_iface_t * iface, uint16_t via, csp_packet_t *packet, int
memcpy(tx_ccsds_buf->data, frame_begin+(frame_length-bytes_remain), segment_len);
bytes_remain -= segment_len;

#ifdef RS_ENCODE
/* In case RS encoding is enabled, the driver is expected to allocate additional space around the CCSDS frame */
uint32_t *frame_asm = &(*(((uint32_t*)tx_ccsds_buf)-1));
*frame_asm = htobe32(0x1ACFFC1D);

encode_rs_ccsds((uint8_t *)tx_ccsds_buf, ((uint8_t *)tx_ccsds_buf)+CCSDS_FRAME_LEN, 0);
ccsds_randomize((uint8_t *)tx_ccsds_buf);
#endif

if (ifdata->cblk_tx_send(iface, tx_ccsds_buf) < 0) {
ifdata->cblk_tx_unlock(iface);
csp_buffer_free(packet);
Expand Down
133 changes: 133 additions & 0 deletions src/rs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* rs.h
*
* @author Phil-Karn
* Copyright Feb 2004, Phil Karn, KA9Q
* May be used under the terms of the GNU Lesser General Public License (LGPL)
*
* Created on: Jul 5, 2018
* Author: johan
*/

#ifndef SRC_CODING_RS_H_
#define SRC_CODING_RS_H_

typedef unsigned char data_t;

#define RS_BLOCK_LENGTH 255
#define RS_CHECK_LENGTH 32

static inline int mod255(int x){
while (x >= 255) {
x -= 255;
x = (x >> 8) + (x & 255);
}
return x;
}
#define MODNN(x) mod255(x)

static const data_t CCSDS_alpha_to[] = {
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4,
0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd,
0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67,
0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b,
0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26,
0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba,
0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0,
0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a,
0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44,
0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85,
0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf,
0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58,
0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24,
0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64,
0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda,
0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00,
};

static const data_t CCSDS_index_of[] = {
255, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42,
4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243,
5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180,
103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56,
6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72,
202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21,
104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16,
110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59,
7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90,
209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235,
203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175,
192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134,
105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220,
130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68,
111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151,
46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183,
};

static const data_t CCSDS_poly[] = {
0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5,
24, 5,170, 66, 50,213, 3, 30, 97,251,126, 43, 4, 66, 59,249,
0,
};

static const data_t TalToDualBasis[] = {
0x00,0x7b,0xaf,0xd4,0x99,0xe2,0x36,0x4d,0xfa,0x81,0x55,0x2e,0x63,0x18,0xcc,0xb7,
0x86,0xfd,0x29,0x52,0x1f,0x64,0xb0,0xcb,0x7c,0x07,0xd3,0xa8,0xe5,0x9e,0x4a,0x31,
0xec,0x97,0x43,0x38,0x75,0x0e,0xda,0xa1,0x16,0x6d,0xb9,0xc2,0x8f,0xf4,0x20,0x5b,
0x6a,0x11,0xc5,0xbe,0xf3,0x88,0x5c,0x27,0x90,0xeb,0x3f,0x44,0x09,0x72,0xa6,0xdd,
0xef,0x94,0x40,0x3b,0x76,0x0d,0xd9,0xa2,0x15,0x6e,0xba,0xc1,0x8c,0xf7,0x23,0x58,
0x69,0x12,0xc6,0xbd,0xf0,0x8b,0x5f,0x24,0x93,0xe8,0x3c,0x47,0x0a,0x71,0xa5,0xde,
0x03,0x78,0xac,0xd7,0x9a,0xe1,0x35,0x4e,0xf9,0x82,0x56,0x2d,0x60,0x1b,0xcf,0xb4,
0x85,0xfe,0x2a,0x51,0x1c,0x67,0xb3,0xc8,0x7f,0x04,0xd0,0xab,0xe6,0x9d,0x49,0x32,
0x8d,0xf6,0x22,0x59,0x14,0x6f,0xbb,0xc0,0x77,0x0c,0xd8,0xa3,0xee,0x95,0x41,0x3a,
0x0b,0x70,0xa4,0xdf,0x92,0xe9,0x3d,0x46,0xf1,0x8a,0x5e,0x25,0x68,0x13,0xc7,0xbc,
0x61,0x1a,0xce,0xb5,0xf8,0x83,0x57,0x2c,0x9b,0xe0,0x34,0x4f,0x02,0x79,0xad,0xd6,
0xe7,0x9c,0x48,0x33,0x7e,0x05,0xd1,0xaa,0x1d,0x66,0xb2,0xc9,0x84,0xff,0x2b,0x50,
0x62,0x19,0xcd,0xb6,0xfb,0x80,0x54,0x2f,0x98,0xe3,0x37,0x4c,0x01,0x7a,0xae,0xd5,
0xe4,0x9f,0x4b,0x30,0x7d,0x06,0xd2,0xa9,0x1e,0x65,0xb1,0xca,0x87,0xfc,0x28,0x53,
0x8e,0xf5,0x21,0x5a,0x17,0x6c,0xb8,0xc3,0x74,0x0f,0xdb,0xa0,0xed,0x96,0x42,0x39,
0x08,0x73,0xa7,0xdc,0x91,0xea,0x3e,0x45,0xf2,0x89,0x5d,0x26,0x6b,0x10,0xc4,0xbf
};

static const data_t TalToConventional[] = {
0x00,0xcc,0xac,0x60,0x79,0xb5,0xd5,0x19,0xf0,0x3c,0x5c,0x90,0x89,0x45,0x25,0xe9,
0xfd,0x31,0x51,0x9d,0x84,0x48,0x28,0xe4,0x0d,0xc1,0xa1,0x6d,0x74,0xb8,0xd8,0x14,
0x2e,0xe2,0x82,0x4e,0x57,0x9b,0xfb,0x37,0xde,0x12,0x72,0xbe,0xa7,0x6b,0x0b,0xc7,
0xd3,0x1f,0x7f,0xb3,0xaa,0x66,0x06,0xca,0x23,0xef,0x8f,0x43,0x5a,0x96,0xf6,0x3a,
0x42,0x8e,0xee,0x22,0x3b,0xf7,0x97,0x5b,0xb2,0x7e,0x1e,0xd2,0xcb,0x07,0x67,0xab,
0xbf,0x73,0x13,0xdf,0xc6,0x0a,0x6a,0xa6,0x4f,0x83,0xe3,0x2f,0x36,0xfa,0x9a,0x56,
0x6c,0xa0,0xc0,0x0c,0x15,0xd9,0xb9,0x75,0x9c,0x50,0x30,0xfc,0xe5,0x29,0x49,0x85,
0x91,0x5d,0x3d,0xf1,0xe8,0x24,0x44,0x88,0x61,0xad,0xcd,0x01,0x18,0xd4,0xb4,0x78,
0xc5,0x09,0x69,0xa5,0xbc,0x70,0x10,0xdc,0x35,0xf9,0x99,0x55,0x4c,0x80,0xe0,0x2c,
0x38,0xf4,0x94,0x58,0x41,0x8d,0xed,0x21,0xc8,0x04,0x64,0xa8,0xb1,0x7d,0x1d,0xd1,
0xeb,0x27,0x47,0x8b,0x92,0x5e,0x3e,0xf2,0x1b,0xd7,0xb7,0x7b,0x62,0xae,0xce,0x02,
0x16,0xda,0xba,0x76,0x6f,0xa3,0xc3,0x0f,0xe6,0x2a,0x4a,0x86,0x9f,0x53,0x33,0xff,
0x87,0x4b,0x2b,0xe7,0xfe,0x32,0x52,0x9e,0x77,0xbb,0xdb,0x17,0x0e,0xc2,0xa2,0x6e,
0x7a,0xb6,0xd6,0x1a,0x03,0xcf,0xaf,0x63,0x8a,0x46,0x26,0xea,0xf3,0x3f,0x5f,0x93,
0xa9,0x65,0x05,0xc9,0xd0,0x1c,0x7c,0xb0,0x59,0x95,0xf5,0x39,0x20,0xec,0x8c,0x40,
0x54,0x98,0xf8,0x34,0x2d,0xe1,0x81,0x4d,0xa4,0x68,0x08,0xc4,0xdd,0x11,0x71,0xbd
};

#define MM 8
#define NN 255
#define ALPHA_TO CCSDS_alpha_to
#define INDEX_OF CCSDS_index_of
#define GENPOLY CCSDS_poly
#define NROOTS 32
#define FCR 112
#define PRIM 11
#define IPRIM 116
#define PAD pad

#undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#undef A0
#define A0 (NN)

/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
* symbol representation
*/
void encode_rs_ccsds(unsigned char *data,unsigned char *parity,int pad);
int decode_rs_ccsds(data_t *data,int *eras_pos,int no_eras,int pad);

#endif /* SRC_CODING_RS_H_ */
73 changes: 73 additions & 0 deletions src/rs_encode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* rs-encode.c
*
* @author Phil-Karn
* Copyright Feb 2004, Phil Karn, KA9Q
* May be used under the terms of the GNU Lesser General Public License (LGPL)
*
* Created on: Jul 5, 2018
* Author: johan
*/

#include <string.h>
#include "rs.h"

/* Portable C version */
void encode_rs_ccsds(data_t *data, data_t *parity,int pad) {

/* The guts of the Reed-Solomon encoder, meant to be #included
* into a function body with the following typedefs, macros and variables supplied
* according to the code parameters:

* data_t - a typedef for the data symbol
* data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded
* data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols
* NROOTS - the number of roots in the RS code generator polynomial,
* which is the same as the number of parity symbols in a block.
* Integer variable or literal.

* NN - the total number of symbols in a RS block. Integer variable or literal.
* PAD - the number of pad symbols in a block. Integer variable or literal.
* ALPHA_TO - The address of an array of NN elements to convert Galois field
* elements in index (log) form to polynomial form. Read only.
* INDEX_OF - The address of an array of NN elements to convert Galois field
* elements in polynomial form to index (log) form. Read only.
* MODNN - a function to reduce its argument modulo NN. May be inline or a macro.
* GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form

* The memset() and memmove() functions are used. The appropriate header
* file declaring these functions (usually <string.h>) must be included by the calling
* program.

* Copyright 2004, Phil Karn, KA9Q
* May be used under the terms of the GNU Lesser General Public License (LGPL)
*/

int i, j;
data_t feedback;

memset(parity,0,NROOTS*sizeof(data_t));

for(i=0;i<NN-NROOTS-PAD;i++){
feedback = INDEX_OF[TalToConventional[data[i]] ^ parity[0]];
if(feedback != A0){ /* feedback term is non-zero */
#ifdef UNNORMALIZED
/* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
* always be for the polynomials constructed by init_rs()
*/
feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
#endif
for(j=1;j<NROOTS;j++)
parity[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
}
/* Shift */
memmove(&parity[0],&parity[1],sizeof(data_t)*(NROOTS-1));
if(feedback != A0)
parity[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
else
parity[NROOTS-1] = 0;
}

for(j=0;j<NROOTS;j++)
parity[j] = TalToDualBasis[parity[j]];
}
Loading