From 366e0ab6e0ca0b7fddd6ccf6dfcb7ab79cb70526 Mon Sep 17 00:00:00 2001 From: wb2osz Date: Mon, 3 Jan 2022 15:36:07 +0000 Subject: [PATCH] Clean up --- src/il2p.h-bak16 | 150 ------ src/il2p_codec.c-bak16 | 265 ---------- src/il2p_payload.c-bak16 | 317 ------------ src/il2p_scramble.c-bak16 | 194 ------- src/il2p_test.c-bak16 | 1030 ------------------------------------- 5 files changed, 1956 deletions(-) delete mode 100644 src/il2p.h-bak16 delete mode 100644 src/il2p_codec.c-bak16 delete mode 100644 src/il2p_payload.c-bak16 delete mode 100644 src/il2p_scramble.c-bak16 delete mode 100644 src/il2p_test.c-bak16 diff --git a/src/il2p.h-bak16 b/src/il2p.h-bak16 deleted file mode 100644 index 6a77318..0000000 --- a/src/il2p.h-bak16 +++ /dev/null @@ -1,150 +0,0 @@ - - -#ifndef IL2P_H -#define IL2P_H 1 - - -#define IL2P_PREAMBLE 0x55 - -#define IL2P_SYNC_WORD 0xF15E48 - -#define IL2P_SYNC_WORD_SIZE 3 -#define IL2P_HEADER_SIZE 13 // Does not include 2 parity. -#define IL2P_HEADER_PARITY 2 - -#define IL2P_MAX_PAYLOAD_SIZE 1023 -#define IL2P_MAX_PAYLOAD_BLOCKS 5 -#define IL2P_MAX_PARITY_SYMBOLS 16 // For payload only. -#define IL2P_MAX_ENCODED_SIZE (IL2P_MAX_PAYLOAD_SIZE + IL2P_MAX_PAYLOAD_BLOCKS * IL2P_MAX_PARITY_SYMBOLS) -// FIXME: above & below IL2P_MAX_ENCODED_PAYLOAD_SIZE - -#define IL2P_MAX_PACKET_SIZE (IL2P_SYNC_WORD_SIZE + IL2P_HEADER_SIZE + IL2P_HEADER_PARITY + IL2P_MAX_ENCODED_SIZE) - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_init.c -// -/////////////////////////////////////////////////////////////////////////////// - - -// Init must be called at start of application. - -extern void il2p_init (int debug); - -#include "fx25.h" // For Reed Solomon stuff. e.g. struct rs - // Maybe rearrange someday because RS now used another place. - -extern struct rs *il2p_find_rs(int nparity); // Internal later? - -extern void il2p_encode_rs (unsigned char *tx_data, int data_size, int num_parity, unsigned char *parity_out); - -extern int il2p_decode_rs (unsigned char *rec_block, int data_size, int num_parity, unsigned char *out); - -extern int il2p_get_debug(void); -extern void il2p_set_debug(int debug); - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_rec.c -// -/////////////////////////////////////////////////////////////////////////////// - -// Receives a bit stream from demodulator. - -extern void il2p_rec_bit (int chan, int subchan, int slice, int dbit); - - - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_send.c -// -/////////////////////////////////////////////////////////////////////////////// - -#include "ax25_pad.h" // For packet object. - -// Send bit stream to modulator. - -int il2p_send_frame (int chan, packet_t pp, int max_fec, int polarity); - - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_codec.c -// -/////////////////////////////////////////////////////////////////////////////// - -#include "ax25_pad.h" - -extern int il2p_encode_frame (packet_t pp, int max_fec, unsigned char *iout); - -packet_t il2p_decode_frame (unsigned char *irec); - -packet_t il2p_decode_header_payload (unsigned char* uhdr, unsigned char *epayload, int *symbols_corrected); - - - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_header.c -// -/////////////////////////////////////////////////////////////////////////////// - - -extern int il2p_type_1_header (packet_t pp, int max_fec, unsigned char *hdr); - -extern packet_t il2p_decode_header_type_1 (unsigned char *hdr, int num_sym_changed); - - -extern int il2p_type_0_header (packet_t pp, int max_fec, unsigned char *hdr); - -extern int il2p_clarify_header(unsigned char *rec_hdr, unsigned char *corrected_unscrambled_hdr); - - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_scramble.c -// -/////////////////////////////////////////////////////////////////////////////// - -extern void il2p_scramble_reset (int *lsfr_state); - -extern void il2p_scramble_block (unsigned char *in, unsigned char *out, int len, int *lsfr_state); - -extern void il2p_descramble_reset (int *lsfr_state); - -extern void il2p_descramble_block (unsigned char *in, unsigned char *out, int len, int *lsfr_state); - - -/////////////////////////////////////////////////////////////////////////////// -// -// il2p_payload.c -// -/////////////////////////////////////////////////////////////////////////////// - - -typedef struct { - int payload_byte_count; // Total size, 0 thru 1023 - int payload_block_count; - int small_block_size; - int large_block_size; - int large_block_count; - int small_block_count; - int parity_symbols_per_block; // 2, 4, 6, 8, 16 -} il2p_payload_properties_t; - -extern int il2p_payload_compute (il2p_payload_properties_t *p, int payload_size, int max_fec); - -extern int il2p_encode_payload (unsigned char *payload, int payload_size, int max_fec, unsigned char *enc); - -extern int il2p_decode_payload (unsigned char *received, int payload_size, int max_fec, unsigned char *payload_out, int *symbols_corrected); - -extern int il2p_get_header_attributes (unsigned char *hdr, int *hdr_type, int *max_fec); - -#endif diff --git a/src/il2p_codec.c-bak16 b/src/il2p_codec.c-bak16 deleted file mode 100644 index de2c05a..0000000 --- a/src/il2p_codec.c-bak16 +++ /dev/null @@ -1,265 +0,0 @@ -// -// This file is part of Dire Wolf, an amateur radio packet TNC. -// -// Copyright (C) 2021 John Langner, WB2OSZ -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#include "direwolf.h" - -#include -#include -#include -#include - -#include "il2p.h" -#include "textcolor.h" -#include "demod.h" - - -/*------------------------------------------------------------- - * - * File: il2p_codec.c - * - * Purpose: Convert IL2P encoded format from and to direwolf internal packet format. - * - *--------------------------------------------------------------*/ - - -/*------------------------------------------------------------- - * - * Name: il2p_encode_frame - * - * Purpose: Convert AX.25 frame to IL2P encoding. - * - * Inputs: chan - Audio channel number, 0 = first. - * - * pp - Packet object pointer. - * - * max_fec - 1 to send maximum FEC size rather than automatic. - * - * Outputs: iout - Encoded result, excluding the 3 byte sync word. - * Caller should provide IL2P_MAX_PACKET_SIZE bytes. - * - * Returns: Number of bytes for transmission. - * -1 is returned for failure. - * - * Description: Encode into IL2P format. - * - * Errors: If something goes wrong, return -1. - * - * Most likely reason is that the frame is too large. - * IL2P has a max payload size of 1023 bytes. - * For a type 1 header, this is the maximum AX.25 Information part size. - * For a type 0 header, this is the entire AX.25 frame. - * - *--------------------------------------------------------------*/ - -int il2p_encode_frame (packet_t pp, int max_fec, unsigned char *iout) -{ - -// Can a type 1 header be used? - - unsigned char hdr[IL2P_HEADER_SIZE + IL2P_HEADER_PARITY]; - int e; - int tx_lfsr_state; - il2p_scramble_reset(&tx_lfsr_state); - int out_len = 0; - - e = il2p_type_1_header (pp, max_fec, hdr); - if (e >= 0) { - il2p_scramble_block (hdr, iout, IL2P_HEADER_SIZE, &tx_lfsr_state); - il2p_encode_rs (iout, IL2P_HEADER_SIZE, IL2P_HEADER_PARITY, iout+IL2P_HEADER_SIZE); - out_len = IL2P_HEADER_SIZE + IL2P_HEADER_PARITY; - - if (e == 0) { - // Sucess. No info part. - return (out_len); - } - - // Payload is AX.25 info part. - unsigned char *pinfo; - int info_len; - info_len = ax25_get_info (pp, &pinfo); - - int k = il2p_encode_payload (pinfo, info_len, max_fec, iout+out_len); - if (k > 0) { - out_len += k; - // Success. Info part was <= 1023 bytes. - return (out_len); - } - - // Something went wrong with the payload encoding. - return (-1); - } - else if (e == -1) { - -// Could not use type 1 header for some reason. -// e.g. More than 2 addresses, extended (mod 128) sequence numbers, etc. - - e = il2p_type_0_header (pp, max_fec, hdr); - if (e > 0) { - - il2p_scramble_block (hdr, iout, IL2P_HEADER_SIZE, &tx_lfsr_state); - il2p_encode_rs (iout, IL2P_HEADER_SIZE, IL2P_HEADER_PARITY, iout+IL2P_HEADER_SIZE); - out_len = IL2P_HEADER_SIZE + IL2P_HEADER_PARITY; - - // Payload is entire AX.25 frame. - - unsigned char *frame_data_ptr = ax25_get_frame_data_ptr (pp); - int frame_len = ax25_get_frame_len (pp); - int k = il2p_encode_payload (frame_data_ptr, frame_len, max_fec, iout+out_len); - if (k > 0) { - out_len += k; - // Success. Entire AX.25 frame <= 1023 bytes. - return (out_len); - } - // Something went wrong with the payload encoding. - return (-1); - } - else if (e == 0) { - // Impossible condition. Type 0 header must have payload. - return (-1); - } - else { - // AX.25 frame is too large. - return (-1); - } - } - - // AX.25 Information part is too large. - return (-1); -} - - - -/*------------------------------------------------------------- - * - * Name: il2p_decode_frame - * - * Purpose: Convert IL2P encoding to AX.25 frame. - * This is only used during testing, with a whole encoded frame. - * During reception, the header would have FEC and descrambling - * applied first so we would know how much to collect for the payload. - * - * Inputs: irec - Received IL2P frame excluding the 3 byte sync word. - * - * Future Out: Number of symbols corrected. - * - * Returns: Packet pointer or NULL for error. - * - *--------------------------------------------------------------*/ - -packet_t il2p_decode_frame (unsigned char *irec) -{ - unsigned char uhdr[IL2P_HEADER_SIZE]; // After FEC and descrambling. - int e = il2p_clarify_header (irec, uhdr); - -// FIXME: for symmetry we might want to clarify the payload before combining. - - return (il2p_decode_header_payload(uhdr, irec + IL2P_HEADER_SIZE + IL2P_HEADER_PARITY, &e)); -} - - -/*------------------------------------------------------------- - * - * Name: il2p_decode_header_payload - * - * Purpose: Convert IL2P encoding to AX.25 frame - * - * Inputs: uhdr - Received header after FEC and descrambling. - * epayload - Encoded payload. - * - * In/Out: symbols_corrected - Symbols (bytes) corrected in the header. - * Should be 0 or 1 because it has 2 parity symbols. - * Here we add number of corrections for the payload. - * - * Returns: Packet pointer or NULL for error. - * - *--------------------------------------------------------------*/ - -packet_t il2p_decode_header_payload (unsigned char* uhdr, unsigned char *epayload, int *symbols_corrected) -{ - int hdr_type; - int max_fec; - int payload_len = il2p_get_header_attributes (uhdr, &hdr_type, &max_fec); - - packet_t pp = NULL; - - if (hdr_type == 1) { - -// Header type 1. Any payload is the AX.25 Information part. - - pp = il2p_decode_header_type_1 (uhdr, *symbols_corrected); - if (pp == NULL) { - // Failed for some reason. - return (NULL); - } - - if (payload_len > 0) { - // This is the AX.25 Information part. - - unsigned char extracted[IL2P_MAX_PAYLOAD_SIZE]; - int e = il2p_decode_payload (epayload, payload_len, max_fec, extracted, symbols_corrected); - - // It would be possible to have a good header but too many errors in the payload. - - if (e <= 0) { - ax25_delete (pp); - pp = NULL; - return (pp); - } - - if (e != payload_len) { - text_color_set(DW_COLOR_ERROR); - dw_printf ("IL2P Internal Error: %s(): hdr_type=%d, max_fec=%d, payload_len=%d, e=%d.\n", __func__, hdr_type, max_fec, payload_len, e); - } - - ax25_set_info (pp, extracted, payload_len); - } - return (pp); - } - else { - -// Header type 0. The payload is the entire AX.25 frame. - - unsigned char extracted[IL2P_MAX_PAYLOAD_SIZE]; - int e = il2p_decode_payload (epayload, payload_len, max_fec, extracted, symbols_corrected); - - if (e <= 0) { // Payload was not received correctly. - return (NULL); - } - - if (e != payload_len) { - text_color_set(DW_COLOR_ERROR); - dw_printf ("IL2P Internal Error: %s(): hdr_type=%d, e=%d, payload_len=%d\n", __func__, hdr_type, e, payload_len); - return (NULL); - } - - alevel_t alevel; - memset (&alevel, 0, sizeof(alevel)); - //alevel = demod_get_audio_level (chan, subchan); // What TODO? We don't know channel here. - // I think alevel gets filled in somewhere later making - // this redundant. - - pp = ax25_from_frame (extracted, payload_len, alevel); - return (pp); - } - -} // end il2p_decode_header_payload - -// end il2p_codec.c - - diff --git a/src/il2p_payload.c-bak16 b/src/il2p_payload.c-bak16 deleted file mode 100644 index d17444a..0000000 --- a/src/il2p_payload.c-bak16 +++ /dev/null @@ -1,317 +0,0 @@ -// -// This file is part of Dire Wolf, an amateur radio packet TNC. -// -// Copyright (C) 2021 John Langner, WB2OSZ -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#include "direwolf.h" - -#include -#include -#include -#include - -#include "textcolor.h" -#include "il2p.h" - - -/*-------------------------------------------------------------------------------- - * - * File: il2p_payload.c - * - * Purpose: Functions dealing with the payload. - * - *--------------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_payload_compute - * - * Purpose: Compute number and sizes of data blocks based on total size. - * - * Inputs: payload_size 0 to 1023. (IL2P_MAX_PAYLOAD_SIZE) - * max_fec true for 16 parity symbols, false for automatic. - * - * Outputs: *p Payload block sizes and counts. - * Number of parity symbols per block. - * - * Returns: Number of bytes in the encoded format. - * Could be 0 for no payload blocks. - * -1 for error (i.e. invalid unencoded size: <0 or >1023) - * - *--------------------------------------------------------------------------------*/ - -int il2p_payload_compute (il2p_payload_properties_t *p, int payload_size, int max_fec) -{ - memset (p, 0, sizeof(il2p_payload_properties_t)); - - if (payload_size < 0 || payload_size > IL2P_MAX_PAYLOAD_SIZE) { - return (-1); - } - if (payload_size == 0) { - return (0); - } - - if (max_fec) { - p->payload_byte_count = payload_size; - p->payload_block_count = (p->payload_byte_count + 238) / 239; - p->small_block_size = p->payload_byte_count / p->payload_block_count; - p->large_block_size = p->small_block_size + 1; - p->large_block_count = p->payload_byte_count - (p->payload_block_count * p->small_block_size); - p->small_block_count = p->payload_block_count - p->large_block_count; - p->parity_symbols_per_block = 16; - } - else { - p->payload_byte_count = payload_size; - p->payload_block_count = (p->payload_byte_count + 246) / 247; - p->small_block_size = p->payload_byte_count / p->payload_block_count; - p->large_block_size = p->small_block_size + 1; - p->large_block_count = p->payload_byte_count - (p->payload_block_count * p->small_block_size); - p->small_block_count = p->payload_block_count - p->large_block_count; - //p->parity_symbols_per_block = (p->small_block_size / 32) + 2; // Looks like error in documentation - - // It would work if the number of parity symbols was based on large block size. - - if (p->small_block_size <= 61) p->parity_symbols_per_block = 2; - else if (p->small_block_size <= 123) p->parity_symbols_per_block = 4; - else if (p->small_block_size <= 185) p->parity_symbols_per_block = 6; - else if (p->small_block_size <= 247) p->parity_symbols_per_block = 8; - else { - // Should not happen. But just in case... - text_color_set(DW_COLOR_ERROR); - dw_printf ("IL2P parity symbol per payload block error. small_block_size = %d\n", p->small_block_size); - return (-1); - } - } - - // Return the total size for the encoded format. - - return (p->small_block_count * (p->small_block_size + p->parity_symbols_per_block) + - p->large_block_count * (p->large_block_size + p->parity_symbols_per_block)); - -} // end il2p_payload_compute - - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_encode_payload - * - * Purpose: Split payload into multiple blocks such that each set - * of data and parity symbols fit into a 255 byte RS block. - * - * Inputs: *payload Array of bytes. - * payload_size 0 to 1023. (IL2P_MAX_PAYLOAD_SIZE) - * max_fec true for 16 parity symbols, false for automatic. - * - * Outputs: *enc Encoded payload for transmission. - * Up to IL2P_MAX_ENCODED_SIZE bytes. - * - * Returns: -1 for error (i.e. invalid size) - * 0 for no blocks. (i.e. size zero) - * Number of bytes generated. Maximum IL2P_MAX_ENCODED_SIZE. - * - * Note: I interpretted the protocol spec as saying the LFSR state is retained - * between data blocks. During interoperability testing, I found that - * was not the case. It is reset for each data block. - * - *--------------------------------------------------------------------------------*/ - - -int il2p_encode_payload (unsigned char *payload, int payload_size, int max_fec, unsigned char *enc) -{ - if (payload_size > IL2P_MAX_PAYLOAD_SIZE) return (-1); - if (payload_size == 0) return (0); - - int tx_lsfr_state; - il2p_scramble_reset(&tx_lsfr_state); - -// Determine number of blocks and sizes. - - il2p_payload_properties_t ipp; - int e; - e = il2p_payload_compute (&ipp, payload_size, max_fec); - if (e <= 0) { - return (e); - } - - unsigned char *pin = payload; - unsigned char *pout = enc; - int encoded_length = 0; - unsigned char scram[256]; - unsigned char parity[IL2P_MAX_PARITY_SYMBOLS]; - -// First the large blocks. - - for (int b = 0; b < ipp.large_block_count; b++) { - - -// FIXME experiment -il2p_scramble_reset(&tx_lsfr_state); - - il2p_scramble_block (pin, scram, ipp.large_block_size, &tx_lsfr_state); - memcpy (pout, scram, ipp.large_block_size); - pin += ipp.large_block_size; - pout += ipp.large_block_size; - encoded_length += ipp.large_block_size; - il2p_encode_rs (scram, ipp.large_block_size, ipp.parity_symbols_per_block, parity); - memcpy (pout, parity, ipp.parity_symbols_per_block); - pout += ipp.parity_symbols_per_block; - encoded_length += ipp.parity_symbols_per_block; - } - -// Then the small blocks. - - for (int b = 0; b < ipp.small_block_count; b++) { - -// FIXME experiment -- works - no need to pass lfsr state in and out of scramble block. -il2p_scramble_reset(&tx_lsfr_state); - - il2p_scramble_block (pin, scram, ipp.small_block_size, &tx_lsfr_state); - memcpy (pout, scram, ipp.small_block_size); - pin += ipp.small_block_size; - pout += ipp.small_block_size; - encoded_length += ipp.small_block_size; - il2p_encode_rs (scram, ipp.small_block_size, ipp.parity_symbols_per_block, parity); - memcpy (pout, parity, ipp.parity_symbols_per_block); - pout += ipp.parity_symbols_per_block; - encoded_length += ipp.parity_symbols_per_block; - } - - return (encoded_length); - -} // end il2p_encode_payload - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_decode_payload - * - * Purpose: Extract original data from encoded payload. - * - * Inputs: received Array of bytes. Size is unknown but in practice it - * must not exceeed IL2P_MAX_ENCODED_SIZE. - * payload_size 0 to 1023. (IL2P_MAX_PAYLOAD_SIZE) - * Expected result size based on header. - * max_fec true for 16 parity symbols, false for automatic. - * - * Outputs: payload_out Recovered payload. - * - * In/Out: symbols_corrected Number of symbols corrected. - * - * - * Returns: Number of bytes extracted. Should be same as payload_size going in. - * -3 for unexpected internal inconsistency. - * -2 for unable to recover from signal corruption. - * -1 for invalid size. - * 0 for no blocks. (i.e. size zero) - * - * Description: Each block is scrambled separately but the LSFR state is carried - * from the first payload block to the next. - * - *--------------------------------------------------------------------------------*/ - -int il2p_decode_payload (unsigned char *received, int payload_size, int max_fec, unsigned char *payload_out, int *symbols_corrected) -{ -// Determine number of blocks and sizes. - - il2p_payload_properties_t ipp; - int e; - e = il2p_payload_compute (&ipp, payload_size, max_fec); - if (e <= 0) { - return (e); - } - - unsigned char *pin = received; - unsigned char *pout = payload_out; - int decoded_length = 0; - int failed = 0; - int rx_lfsr_state; - il2p_descramble_reset(&rx_lfsr_state); - - -// First the large blocks. - - for (int b = 0; b < ipp.large_block_count; b++) { - unsigned char corrected_block[255]; - int e = il2p_decode_rs (pin, ipp.large_block_size, ipp.parity_symbols_per_block, corrected_block); - - // dw_printf ("%s:%d: large block decode_rs returned status = %d\n", __FILE__, __LINE__, e); - - if (e < 0) failed = 1; - *symbols_corrected += e; - -// FIXME - simplify -il2p_descramble_reset(&rx_lfsr_state); - - il2p_descramble_block (corrected_block, pout, ipp.large_block_size, &rx_lfsr_state); - - if (il2p_get_debug() >= 2) { - text_color_set(DW_COLOR_DEBUG); - dw_printf ("Descrambled large payload block, %d bytes:\n", ipp.large_block_size); - fx_hex_dump(pout, ipp.large_block_size); - } - - pin += ipp.large_block_size + ipp.parity_symbols_per_block; - pout += ipp.large_block_size; - decoded_length += ipp.large_block_size; - } - -// Then the small blocks. - - for (int b = 0; b < ipp.small_block_count; b++) { - unsigned char corrected_block[255]; - int e = il2p_decode_rs (pin, ipp.small_block_size, ipp.parity_symbols_per_block, corrected_block); - - // dw_printf ("%s:%d: small block decode_rs returned status = %d\n", __FILE__, __LINE__, e); - - if (e < 0) failed = 1; - *symbols_corrected += e; - -// FIXME - just reset in descramble block - no need to pass around as argument. -il2p_descramble_reset(&rx_lfsr_state); - - il2p_descramble_block (corrected_block, pout, ipp.small_block_size, &rx_lfsr_state); - - if (il2p_get_debug() >= 2) { - text_color_set(DW_COLOR_DEBUG); - dw_printf ("Descrambled small payload block, %d bytes:\n", ipp.small_block_size); - fx_hex_dump(pout, ipp.small_block_size); - } - - pin += ipp.small_block_size + ipp.parity_symbols_per_block; - pout += ipp.small_block_size; - decoded_length += ipp.small_block_size; - } - - if (failed) { - //dw_printf ("%s:%d: failed = %0x\n", __FILE__, __LINE__, failed); - return (-2); - } - - if (decoded_length != payload_size) { - text_color_set(DW_COLOR_ERROR); - dw_printf ("IL2P Internal error: decoded_length = %d, payload_size = %d\n", decoded_length, payload_size); - return (-3); - } - - return (decoded_length); - -} // end il2p_decode_payload - -// end il2p_payload.c - diff --git a/src/il2p_scramble.c-bak16 b/src/il2p_scramble.c-bak16 deleted file mode 100644 index fc4bf05..0000000 --- a/src/il2p_scramble.c-bak16 +++ /dev/null @@ -1,194 +0,0 @@ -// -// This file is part of Dire Wolf, an amateur radio packet TNC. -// -// Copyright (C) 2021 John Langner, WB2OSZ -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -// FIXME: be consistent about descramble or descramble. not unscramble. - -/*-------------------------------------------------------------------------------- - * - * File: il2p_scramble.c - * - * Purpose: Scramble / descramble data as specified in the IL2P protocol specification. - * - *--------------------------------------------------------------------------------*/ - - -#include "direwolf.h" - -#include -#include -#include -#include - -#include "il2p.h" - - -// Scramble bits for il2p transmit. - -// Note that there is a delay of 5 until the first bit comes out. -// So we need to need to ignore the first 5 out and stick in -// an extra 5 filler bits to flush at the end. - -#define INIT_TX_LSFR 0x00f - -static inline int scramble_bit (int in, int *state) -{ - int out = ((*state >> 4) ^ *state) & 1; - *state = ( (((in ^ *state) & 1) << 9) | (*state ^ ((*state & 1) << 4)) ) >> 1; - return (out); -} - - -// Undo data scrambling for il2p receive. - -#define INIT_RX_LSFR 0x1f0 - -static inline int descramble_bit (int in, int *state) -{ - int out = (in ^ *state) & 1; - *state = ((*state >> 1) | ((in & 1) << 8)) ^ ((in & 1) << 3); - return (out); -} - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_scramble_reset - * - * Purpose: Reset the TX LFSR register at the beginning of a packet or payload. - * - * Outputs: lfsr_state Current state of transmit LFSR. - * This is reset at the start of the packet and is - * cummulative across the header and data blocks. - * - *--------------------------------------------------------------------------------*/ - -void il2p_scramble_reset (int *lfsr_state) -{ - *lfsr_state = INIT_TX_LSFR; -} - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_scramble_block - * - * Purpose: Scramble a block before adding RS parity. - * - * Inputs: in Array of bytes. - * len Number of bytes both in and out. - * - * Outputs: out Array of bytes. - * - * In/Out: lfsr_state Current state of transmit LFSR. ---- FIXME --- remove this - * - *--------------------------------------------------------------------------------*/ - -void il2p_scramble_block (unsigned char *in, unsigned char *out, int len, int *lfsr_state) -{ - il2p_scramble_reset (lfsr_state); - - memset (out, 0, len); - - int skipping = 1; // Discard the first 5 out. - int ob = 0; // Index to output byte. - int om = 0x80; // Output bit mask; - for (int ib = 0; ib < len; ib++) { - for (int im = 0x80; im != 0; im >>= 1) { - int s = scramble_bit((in[ib] & im) != 0, lfsr_state); - if (ib == 0 && im == 0x04) skipping = 0; - if ( ! skipping) { - if (s) { - out[ob] |= om; - } - om >>= 1; - if (om == 0) { - om = 0x80; - ob++; - } - } - } - } - // Flush it. - - // Preserve the LSFR state from before flushing. - // This might be needed as the initial state for later payload blocks. - int x = *lfsr_state; - for (int n = 0; n < 5; n++) { - int s = scramble_bit(0, &x); - if (s) { - out[ob] |= om; - } - om >>=1; - if (om == 0) { - om = 0x80; - ob++; - } - } - -} // end il2p_scramble_block - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_descramble_reset - * - * Purpose: Reset the RX LFSR register at the beginning of a packet or payload. - * - * Outputs: lfsr_state Current state of transmit LFSR. - * This is cummulative across the payload data blocks. - * - *--------------------------------------------------------------------------------*/ - -void il2p_descramble_reset (int *lfsr_state) -{ - *lfsr_state = INIT_RX_LSFR; -} - - - -/*-------------------------------------------------------------------------------- - * - * Function: il2p_descramble_block - * - * Purpose: Unscramble a block after removing RS parity. - * - * Inputs: in Array of bytes. - * len Number of bytes both in and out. - * - * Outputs: out Array of bytes. - * - * In/Out: lfsr_state Current state of receive LSFR. --- FIXME - remove this. - * - *--------------------------------------------------------------------------------*/ - -void il2p_descramble_block (unsigned char *in, unsigned char *out, int len, int *lfsr_state) -{ - memset (out, 0, len); - - for (int b = 0; b < len; b++) { - for (int m = 0x80; m != 0; m >>= 1) { - int d = descramble_bit((in[b] & m) != 0, lfsr_state); - if (d) { - out[b] |= m; - } - } - } -} - -// end il2p_scramble.c diff --git a/src/il2p_test.c-bak16 b/src/il2p_test.c-bak16 deleted file mode 100644 index c66b488..0000000 --- a/src/il2p_test.c-bak16 +++ /dev/null @@ -1,1030 +0,0 @@ -// -// This file is part of Dire Wolf, an amateur radio packet TNC. -// -// Copyright (C) 2021 John Langner, WB2OSZ -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#include "direwolf.h" - -#include -#include -#include -#include - -#include "textcolor.h" -#include "il2p.h" -#include "ax25_pad.h" -#include "ax25_pad2.h" -#include "multi_modem.h" - - -static void test_scramble(void); -static void test_rs(void); -static void test_payload(void); -static void test_example_headers(void); -static void all_frame_types(void); -static void test_serdes(void); -static void decode_bitstream(void); - -/*------------------------------------------------------------- - * - * Name: il2p_test.c - * - * Purpose: Unit tests for IL2P protocol functions. - * - * Errors: Die if anything goes wrong. - * - *--------------------------------------------------------------*/ - - -int main () -{ - int enable_color = 1; - text_color_init (enable_color); - - int enable_debug_out = 0; - il2p_init(enable_debug_out); - - text_color_set(DW_COLOR_INFO); - dw_printf ("Begin IL2P unit tests.\n"); - -// These start simple and later complex cases build upon earlier successes. - -// Test scramble and descramble. - - test_scramble(); - -// Test Reed Solomon error correction. - - test_rs(); - -// Test payload functions. - - test_payload(); - -// Try encoding the example headers in the protocol spec. - - test_example_headers(); - -// Convert all of the AX.25 frame types to IL2P and back again. - - all_frame_types(); - -// Use same serialize / deserialize functions used on the air. - - test_serdes (); - -// Decode bitstream from demodulator if data file is available. -// TODO: Very large info parts. Appropriate error if too long. -// TODO: More than 2 addresses. - - decode_bitstream(); - - text_color_set(DW_COLOR_REC); - dw_printf ("\n----------\n\n"); - dw_printf ("\nSUCCESS!\n"); - - return (EXIT_SUCCESS); -} - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test scrambling and descrambling. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -static void test_scramble(void) -{ - text_color_set(DW_COLOR_INFO); - dw_printf ("Test scrambling...\n"); - -// First an example from the protocol specification to make sure I'm compatible. - - static unsigned char scramin1[] = { 0x63, 0xf1, 0x40, 0x40, 0x40, 0x00, 0x6b, 0x2b, 0x54, 0x28, 0x25, 0x2a, 0x0f }; - static unsigned char scramout1[] = { 0x6a, 0xea, 0x9c, 0xc2, 0x01, 0x11, 0xfc, 0x14, 0x1f, 0xda, 0x6e, 0xf2, 0x53 }; - unsigned char scramout[sizeof(scramin1)]; - - int tx_lsfr; - il2p_scramble_reset (&tx_lsfr); - il2p_scramble_block (scramin1, scramout, sizeof(scramin1), &tx_lsfr); - assert (memcmp(scramout, scramout, sizeof(scramout1)) == 0); - -// Now try multiple blocks with LSFR state carried over. --- FIXME -no carry over - - static unsigned char msg1[] = "The quick brown fox jumps over the lazy dog."; - static unsigned char msg2[] = "The rain in Spain stays mainly on the plain."; - static unsigned char msg3[] = "Peter Piper picked a peck of pickled peppers."; - - unsigned char scram1[sizeof(msg1)]; - unsigned char scram2[sizeof(msg2)]; - unsigned char scram3[sizeof(msg3)]; - il2p_scramble_reset (&tx_lsfr); - il2p_scramble_block (msg1, scram1, sizeof(msg1), &tx_lsfr); - il2p_scramble_reset (&tx_lsfr); - il2p_scramble_block (msg2, scram2, sizeof(msg2), &tx_lsfr); - il2p_scramble_reset (&tx_lsfr); - il2p_scramble_block (msg3, scram3, sizeof(msg3), &tx_lsfr); - - int rx_lsfr; - unsigned char un1[sizeof(msg1)]; - unsigned char un2[sizeof(msg2)]; - unsigned char un3[sizeof(msg3)]; - il2p_descramble_reset (&rx_lsfr); - il2p_descramble_block (scram1, un1, sizeof(msg1), &rx_lsfr); - il2p_descramble_reset (&rx_lsfr); - il2p_descramble_block (scram2, un2, sizeof(msg2), &rx_lsfr); - il2p_descramble_reset (&rx_lsfr); - il2p_descramble_block (scram3, un3, sizeof(msg3), &rx_lsfr); - - //dw_printf ("%s\n", un1); - //dw_printf ("%s\n", un2); - //dw_printf ("%s\n", un3); - - assert (strcmp((char*)msg1,(char*)un1) == 0); - assert (strcmp((char*)msg2,(char*)un2) == 0); - assert (strcmp((char*)msg3,(char*)un3) == 0); - -} // end test_scramble. - - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test Reed Solomon encode/decode examples found in the protocol spec. -// The data part is scrambled but that does not matter here because. -// We are only concerned abound adding the parity and verifying. -// -///////////////////////////////////////////////////////////////////////////////////////////// - - -static void test_rs() -{ - text_color_set(DW_COLOR_INFO); - dw_printf ("Test Reed Solomon functions...\n"); - - static unsigned char example_s[] = { 0x26, 0x57, 0x4d, 0x57, 0xf1, 0x96, 0xcc, 0x85, 0x42, 0xe7, 0x24, 0xf7, 0x2e, - 0x8a, 0x97 }; - unsigned char parity_out[2]; - il2p_encode_rs (example_s, 13, 2, parity_out); - //dw_printf ("DEBUG RS encode %02x %02x\n", parity_out[0], parity_out[1]); - assert (memcmp(parity_out, example_s + 13, 2) == 0); - - - static unsigned char example_u[] = { 0x6a, 0xea, 0x9c, 0xc2, 0x01, 0x11, 0xfc, 0x14, 0x1f, 0xda, 0x6e, 0xf2, 0x53, - 0x91, 0xbd }; - il2p_encode_rs (example_u, 13, 2, parity_out); - //dw_printf ("DEBUG RS encode %02x %02x\n", parity_out[0], parity_out[1]); - assert (memcmp(parity_out, example_u + 13, 2) == 0); - - // See if we can go the other way. - // FIXME: see if clobbered byte was fixed. - - unsigned char received[15]; - unsigned char corrected[15]; - int e; - - e = il2p_decode_rs (example_s, 13, 2, corrected); - assert (e == 0); - assert (memcmp(example_s, corrected, 13) == 0); - - memcpy (received, example_s, 15); - received[0] = '?'; - e = il2p_decode_rs (received, 13, 2, corrected); - assert (e == 1); - assert (memcmp(example_s, corrected, 13) == 0); - - e = il2p_decode_rs (example_u, 13, 2, corrected); - assert (e == 0); - assert (memcmp(example_u, corrected, 13) == 0); - - memcpy (received, example_u, 15); - received[12] = '?'; - e = il2p_decode_rs (received, 13, 2, corrected); - assert (e == 1); - assert (memcmp(example_u, corrected, 13) == 0); - - received[1] = '?'; - received[2] = '?'; - e = il2p_decode_rs (received, 13, 2, corrected); - assert (e == -1); -} - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test payload functions. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -static void test_payload(void) -{ - text_color_set(DW_COLOR_INFO); - dw_printf ("Test payload functions...\n"); - - il2p_payload_properties_t ipp; - int e; - -// Examples in specification. - - e = il2p_payload_compute (&ipp, 100, 0); - assert (ipp.small_block_size == 100); - assert (ipp.large_block_size == 101); - assert (ipp.large_block_count == 0); - assert (ipp.small_block_count == 1); - assert (ipp.parity_symbols_per_block == 4); - - e = il2p_payload_compute (&ipp, 236, 0); - assert (ipp.small_block_size == 236); - assert (ipp.large_block_size == 237); - assert (ipp.large_block_count == 0); - assert (ipp.small_block_count == 1); - assert (ipp.parity_symbols_per_block == 8); - - e = il2p_payload_compute (&ipp, 512, 0); - assert (ipp.small_block_size == 170); - assert (ipp.large_block_size == 171); - assert (ipp.large_block_count == 2); - assert (ipp.small_block_count == 1); - assert (ipp.parity_symbols_per_block == 6); - - e = il2p_payload_compute (&ipp, 1023, 0); - assert (ipp.small_block_size == 204); - assert (ipp.large_block_size == 205); - assert (ipp.large_block_count == 3); - assert (ipp.small_block_count == 2); - assert (ipp.parity_symbols_per_block == 8); - -// Now try all possible sizes for Baseline FEC Parity. - - for (int n = 1; n <= IL2P_MAX_PAYLOAD_SIZE; n++) { - e = il2p_payload_compute (&ipp, n, 0); - //dw_printf ("bytecount=%d, smallsize=%d, largesize=%d, largecount=%d, smallcount=%d\n", n, - // ipp.small_block_size, ipp.large_block_size, - // ipp.large_block_count, ipp.small_block_count); - //fflush (stdout); - - assert (ipp.payload_block_count >= 1 && ipp.payload_block_count <= IL2P_MAX_PAYLOAD_BLOCKS); - assert (ipp.payload_block_count == ipp.small_block_count + ipp.large_block_count); - assert (ipp.small_block_count * ipp.small_block_size + - ipp.large_block_count * ipp.large_block_size == n); - assert (ipp.parity_symbols_per_block == 2 || - ipp.parity_symbols_per_block == 4 || - ipp.parity_symbols_per_block == 6 || - ipp.parity_symbols_per_block == 8); - - // Data and parity must fit in RS block size of 255. - // Size test does not apply if block count is 0. - assert (ipp.small_block_count == 0 || ipp.small_block_size + ipp.parity_symbols_per_block <= 255); - assert (ipp.large_block_count == 0 || ipp.large_block_size + ipp.parity_symbols_per_block <= 255); - } - -// All sizes for MAX FEC. - - for (int n = 1; n <= IL2P_MAX_PAYLOAD_SIZE; n++) { - e = il2p_payload_compute (&ipp, n, 1); // 1 for max fec. - //dw_printf ("bytecount=%d, smallsize=%d, largesize=%d, largecount=%d, smallcount=%d\n", n, - // ipp.small_block_size, ipp.large_block_size, - // ipp.large_block_count, ipp.small_block_count); - //fflush (stdout); - - assert (ipp.payload_block_count >= 1 && ipp.payload_block_count <= IL2P_MAX_PAYLOAD_BLOCKS); - assert (ipp.payload_block_count == ipp.small_block_count + ipp.large_block_count); - assert (ipp.small_block_count * ipp.small_block_size + - ipp.large_block_count * ipp.large_block_size == n); - assert (ipp.parity_symbols_per_block == 16); - - // Data and parity must fit in RS block size of 255. - // Size test does not apply if block count is 0. - assert (ipp.small_block_count == 0 || ipp.small_block_size + ipp.parity_symbols_per_block <= 255); - assert (ipp.large_block_count == 0 || ipp.large_block_size + ipp.parity_symbols_per_block <= 255); - } - -// Now let's try encoding payloads and extracting original again. -// This will also provide exercise for scrambling and Reed Solomon under more conditions. - - unsigned char original_payload[IL2P_MAX_PAYLOAD_SIZE]; - for (int n = 0; n < IL2P_MAX_PAYLOAD_SIZE; n++) { - original_payload[n] = n & 0xff; - } - for (int max_fec = 0; max_fec <= 1; max_fec++) { - for (int payload_length = 1; payload_length <= IL2P_MAX_PAYLOAD_SIZE; payload_length++) { - //dw_printf ("\n--------- max_fec = %d, payload_length = %d\n", max_fec, payload_length); - int tx_lsfr_state; - il2p_scramble_reset(&tx_lsfr_state); - unsigned char encoded[IL2P_MAX_ENCODED_SIZE]; - int k = il2p_encode_payload (original_payload, payload_length, max_fec, encoded); - - //dw_printf ("payload length %d %s -> %d\n", payload_length, max_fec ? "M" : "", k); - assert (k > payload_length && k <= IL2P_MAX_ENCODED_SIZE); - - // Now extract. - - //int rx_lsfr_state; - //il2p_descramble_reset(&rx_lsfr_state); - unsigned char extracted[IL2P_MAX_PAYLOAD_SIZE]; - int symbols_corrected = 0; - int e = il2p_decode_payload (encoded, payload_length, max_fec, extracted, &symbols_corrected); - //dw_printf ("e = %d, payload_length = %d\n", e, payload_length); - assert (e == payload_length); - - // if (memcmp (original_payload, extracted, payload_length) != 0) { - // dw_printf ("********** Received message not as expected. **********\n"); - // fx_hex_dump(extracted, payload_length); - // } - assert (memcmp (original_payload, extracted, payload_length) == 0); - } - } - (void)e; -} // end test_payload - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test header examples found in protocol specification. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -static void test_example_headers() -{ - -//----------- Example 1: AX.25 S-Frame -------------- - -// This frame sample only includes a 15 byte header, without PID field. -// Destination Callsign: ?KA2DEW-2 -// Source Callsign: ?KK4HEJ-7 -// N(R): 5 -// P/F: 1 -// C: 1 -// Control Opcode: 00 (Receive Ready) -// -// AX.25 data: -// 96 82 64 88 8a ae e4 96 96 68 90 8a 94 6f b1 -// -// IL2P Data Prior to Scrambling and RS Encoding: -// 2b a1 12 24 25 77 6b 2b 54 68 25 2a 27 -// -// IL2P Data After Scrambling and RS Encoding: -// 26 57 4d 57 f1 96 cc 85 42 e7 24 f7 2e 8a 97 - - text_color_set(DW_COLOR_INFO); - dw_printf ("Example 1: AX.25 S-Frame...\n"); - - static unsigned char example1[] = {0x96, 0x82, 0x64, 0x88, 0x8a, 0xae, 0xe4, 0x96, 0x96, 0x68, 0x90, 0x8a, 0x94, 0x6f, 0xb1}; - static unsigned char header1[] = {0x2b, 0xa1, 0x12, 0x24, 0x25, 0x77, 0x6b, 0x2b, 0x54, 0x68, 0x25, 0x2a, 0x27 }; - unsigned char header[IL2P_HEADER_SIZE]; - unsigned char sresult[32]; - memset (header, 0, sizeof(header)); - memset (sresult, 0, sizeof(sresult)); - unsigned char check[2]; - alevel_t alevel; - memset(&alevel, 0, sizeof(alevel)); - - packet_t pp = ax25_from_frame (example1, sizeof(example1), alevel); - assert (pp != NULL); - int e; - e = il2p_type_1_header (pp, 0, header); - assert (e == 0); - ax25_delete(pp); - - //dw_printf ("Example 1 header:\n"); - //for (int i = 0 ; i < sizeof(header); i++) { - // dw_printf (" %02x", header[i]); - //} - ///dw_printf ("\n"); - - assert (memcmp(header, header1, sizeof(header)) == 0); - - int tx_lsfr_state; - il2p_scramble_reset(&tx_lsfr_state); - il2p_scramble_block (header, sresult, 13, &tx_lsfr_state); - //dw_printf ("Expect scrambled 26 57 4d 57 f1 96 cc 85 42 e7 24 f7 2e\n"); - //for (int i = 0 ; i < sizeof(sresult); i++) { - // dw_printf (" %02x", sresult[i]); - //} - //dw_printf ("\n"); - - il2p_encode_rs (sresult, 13, 2, check); - - //dw_printf ("expect checksum = 8a 97\n"); - //dw_printf ("check = "); - //for (int i = 0 ; i < sizeof(check); i++) { - // dw_printf (" %02x", check[i]); - //} - //dw_printf ("\n"); - assert (check[0] == 0x8a); - assert (check[1] == 0x97); - -// Can we go from IL2P back to AX.25? - - pp = il2p_decode_header_type_1 (header, 0); - assert (pp != NULL); - - char dst_addr[AX25_MAX_ADDR_LEN]; - char src_addr[AX25_MAX_ADDR_LEN]; - - ax25_get_addr_with_ssid (pp, AX25_DESTINATION, dst_addr); - ax25_get_addr_with_ssid (pp, AX25_SOURCE, src_addr); - - ax25_frame_type_t frame_type; - cmdres_t cr; // command or response. - char description[64]; - int pf; // Poll/Final. - int nr, ns; // Sequence numbers. - - frame_type = ax25_frame_type (pp, &cr, description, &pf, &nr, &ns); - (void)frame_type; -#if 1 - dw_printf ("%s(): %s>%s: %s\n", __func__, src_addr, dst_addr, description); -#endif -// TODO: compare binary. - ax25_delete (pp); - -// FIXME: continue - - dw_printf ("Example 1 header OK\n"); - - -// -------------- Example 2 - UI frame, no info part ------------------ - -// This is an AX.25 Unnumbered Information frame, such as APRS. -// Destination Callsign: ?CQ -0 -// Source Callsign: ?KK4HEJ-15 -// P/F: 0 -// C: 0 -// Control Opcode: 3 Unnumbered Information -// PID: 0xF0 No L3 -// -// AX.25 Data: -// 86 a2 40 40 40 40 60 96 96 68 90 8a 94 7f 03 f0 -// -// IL2P Data Prior to Scrambling and RS Encoding: -// 63 f1 40 40 40 00 6b 2b 54 28 25 2a 0f -// -// IL2P Data After Scrambling and RS Encoding: -// 6a ea 9c c2 01 11 fc 14 1f da 6e f2 53 91 bd - - - //dw_printf ("---------- example 2 ------------\n"); - static unsigned char example2[] = { 0x86, 0xa2, 0x40, 0x40, 0x40, 0x40, 0x60, 0x96, 0x96, 0x68, 0x90, 0x8a, 0x94, 0x7f, 0x03, 0xf0 }; - static unsigned char header2[] = { 0x63, 0xf1, 0x40, 0x40, 0x40, 0x00, 0x6b, 0x2b, 0x54, 0x28, 0x25, 0x2a, 0x0f }; - memset (header, 0, sizeof(header)); - memset (sresult, 0, sizeof(sresult)); - memset(&alevel, 0, sizeof(alevel)); - - pp = ax25_from_frame (example2, sizeof(example2), alevel); - assert (pp != NULL); - e = il2p_type_1_header (pp, 0, header); - assert (e == 0); - ax25_delete(pp); - - //dw_printf ("Example 2 header:\n"); - //for (int i = 0 ; i < sizeof(header); i++) { - // dw_printf (" %02x", header[i]); - //} - //dw_printf ("\n"); - - assert (memcmp(header, header2, sizeof(header2)) == 0); - - il2p_scramble_reset(&tx_lsfr_state); - il2p_scramble_block (header, sresult, 13, &tx_lsfr_state); - //dw_printf ("Expect scrambled 6a ea 9c c2 01 11 fc 14 1f da 6e f2 53\n"); - //for (int i = 0 ; i < sizeof(sresult); i++) { - // dw_printf (" %02x", sresult[i]); - //} - //dw_printf ("\n"); - - il2p_encode_rs (sresult, 13, 2, check); - - //dw_printf ("expect checksum = 91 bd\n"); - //dw_printf ("check = "); - //for (int i = 0 ; i < sizeof(check); i++) { - // dw_printf (" %02x", check[i]); - //} - //dw_printf ("\n"); - assert (check[0] == 0x91); - assert (check[1] == 0xbd); - -// Can we go from IL2P back to AX.25? - - pp = il2p_decode_header_type_1 (header, 0); - assert (pp != NULL); - - ax25_get_addr_with_ssid (pp, AX25_DESTINATION, dst_addr); - ax25_get_addr_with_ssid (pp, AX25_SOURCE, src_addr); - - frame_type = ax25_frame_type (pp, &cr, description, &pf, &nr, &ns); - (void)frame_type; -#if 1 - dw_printf ("%s(): %s>%s: %s\n", __func__, src_addr, dst_addr, description); -#endif -// TODO: compare binary. - - ax25_delete (pp); -// FIXME: continue - - dw_printf ("Example 2 header OK\n"); - - -// -------------- Example 3 - I Frame ------------------ - -// This is an AX.25 I-Frame with 9 bytes of information after the 16 byte header. -// -// Destination Callsign: ?KA2DEW-2 -// Source Callsign: ?KK4HEJ-2 -// P/F: 1 -// C: 1 -// N(R): 5 -// N(S): 4 -// AX.25 PID: 0xCF TheNET -// IL2P Payload Byte Count: 9 -// -// AX.25 Data: -// 96 82 64 88 8a ae e4 96 96 68 90 8a 94 65 b8 cf 30 31 32 33 34 35 36 37 38 -// -// IL2P Scrambled and Encoded Data: -// 26 13 6d 02 8c fe fb e8 aa 94 2d 6a 34 43 35 3c 69 9f 0c 75 5a 38 a1 7f f3 fc - - - //dw_printf ("---------- example 3 ------------\n"); - static unsigned char example3[] = { 0x96, 0x82, 0x64, 0x88, 0x8a, 0xae, 0xe4, 0x96, 0x96, 0x68, 0x90, 0x8a, 0x94, 0x65, 0xb8, 0xcf, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 }; - static unsigned char header3[] = { 0x2b, 0xe1, 0x52, 0x64, 0x25, 0x77, 0x6b, 0x2b, 0xd4, 0x68, 0x25, 0xaa, 0x22 }; - static unsigned char complete3[] = { 0x26, 0x13, 0x6d, 0x02, 0x8c, 0xfe, 0xfb, 0xe8, 0xaa, 0x94, 0x2d, 0x6a, 0x34, 0x43, 0x35, 0x3c, 0x69, 0x9f, 0x0c, 0x75, 0x5a, 0x38, 0xa1, 0x7f, 0xf3, 0xfc }; - memset (header, 0, sizeof(header)); - memset (sresult, 0, sizeof(sresult)); - memset(&alevel, 0, sizeof(alevel)); - - pp = ax25_from_frame (example3, sizeof(example3), alevel); - assert (pp != NULL); - e = il2p_type_1_header (pp, 0, header); - assert (e == 9); - ax25_delete(pp); - - //dw_printf ("Example 3 header:\n"); - //for (int i = 0 ; i < sizeof(header); i++) { - // dw_printf (" %02x", header[i]); - //} - //dw_printf ("\n"); - - assert (memcmp(header, header3, sizeof(header)) == 0); - - il2p_scramble_reset(&tx_lsfr_state); - il2p_scramble_block (header, sresult, 13, &tx_lsfr_state); - //dw_printf ("Expect scrambled 26 13 6d 02 8c fe fb e8 aa 94 2d 6a 34\n"); - //for (int i = 0 ; i < sizeof(sresult); i++) { - // dw_printf (" %02x", sresult[i]); - //} - //dw_printf ("\n"); - - il2p_encode_rs (sresult, 13, 2, check); - - //dw_printf ("expect checksum = 43 35\n"); - //dw_printf ("check = "); - //for (int i = 0 ; i < sizeof(check); i++) { - // dw_printf (" %02x", check[i]); - //} - //dw_printf ("\n"); - - assert (check[0] == 0x43); - assert (check[1] == 0x35); - - // That was only the header. We will get to the info part in a later test. - -// Can we go from IL2P back to AX.25? - - pp = il2p_decode_header_type_1 (header, 0); - assert (pp != NULL); - - ax25_get_addr_with_ssid (pp, AX25_DESTINATION, dst_addr); - ax25_get_addr_with_ssid (pp, AX25_SOURCE, src_addr); - - frame_type = ax25_frame_type (pp, &cr, description, &pf, &nr, &ns); - (void)frame_type; -#if 1 - dw_printf ("%s(): %s>%s: %s\n", __func__, src_addr, dst_addr, description); -#endif -// TODO: compare binary. - - ax25_delete (pp); -// FIXME: continue - dw_printf ("Example 3 header OK\n"); - -// Example 3 again, this time the Information part is included. - - pp = ax25_from_frame (example3, sizeof(example3), alevel); - assert (pp != NULL); - - int max_fec = 0; - unsigned char iout[IL2P_MAX_PACKET_SIZE]; - e = il2p_encode_frame (pp, max_fec, iout); - - //dw_printf ("expected for example 3:\n"); - //fx_hex_dump(complete3, sizeof(complete3)); - //dw_printf ("actual result for example 3:\n"); - //fx_hex_dump(iout, e); - // Does it match the example in the protocol spec? - assert (e == sizeof(complete3)); - assert (memcmp(iout, complete3, sizeof(complete3)) == 0); - ax25_delete (pp); - - dw_printf ("Example 3 with info OK\n"); - -} // end test_example_headers - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test all of the frame types. -// -// Encode to IL2P format, decode, and verify that the result is the same as the original. -// -///////////////////////////////////////////////////////////////////////////////////////////// - - -static void enc_dec_compare (packet_t pp1) -{ - for (int max_fec = 0; max_fec <= 1; max_fec++) { - - unsigned char encoded[IL2P_MAX_PACKET_SIZE]; - int enc_len; - enc_len = il2p_encode_frame (pp1, max_fec, encoded); - assert (enc_len >= 0); - -// FIXME: add something like: hdr_type=1, max_fec=0, payload_len=44, encoded_payload=99 - - packet_t pp2; - pp2 = il2p_decode_frame (encoded); - assert (pp2 != NULL); - -// Is it the same after encoding to IL2P and then decoding? - - int len1 = ax25_get_frame_len (pp1); - unsigned char *data1 = ax25_get_frame_data_ptr (pp1); - - int len2 = ax25_get_frame_len (pp2); - unsigned char *data2 = ax25_get_frame_data_ptr (pp2); - - if (len1 != len2 || memcmp(data1, data2, len1) != 0) { - - dw_printf ("\nEncode/Decode Error. Original:\n"); - ax25_hex_dump (pp1); - - dw_printf ("IL2P encoded as:\n"); - fx_hex_dump(encoded, enc_len); - - dw_printf ("Got turned into this:\n"); - ax25_hex_dump (pp2); - } - - assert (len1 == len2 && memcmp(data1, data2, len1) == 0); - - ax25_delete (pp2); - } -// FIXME repeat with max_fec=1 - -} - -static void all_frame_types(void) -{ - char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN]; - int num_addr = 2; - cmdres_t cr; - ax25_frame_type_t ftype; - int pf = 0; - int pid = 0xf0; - int modulo; - int nr, ns; - unsigned char *pinfo = NULL; - int info_len = 0; - packet_t pp; - - strcpy (addrs[0], "W2UB"); - strcpy (addrs[1], "WB2OSZ-12"); - num_addr = 2; - - text_color_set(DW_COLOR_INFO); - dw_printf ("Testing all frame types.\n"); - -/* U frame */ - - dw_printf ("\nU frames...\n"); - - for (ftype = frame_type_U_SABME; ftype <= frame_type_U_TEST; ftype++) { - - for (pf = 0; pf <= 1; pf++) { - - int cmin = 0, cmax = 1; - - switch (ftype) { - // 0 = response, 1 = command - case frame_type_U_SABME: cmin = 1; cmax = 1; break; - case frame_type_U_SABM: cmin = 1; cmax = 1; break; - case frame_type_U_DISC: cmin = 1; cmax = 1; break; - case frame_type_U_DM: cmin = 0; cmax = 0; break; - case frame_type_U_UA: cmin = 0; cmax = 0; break; - case frame_type_U_FRMR: cmin = 0; cmax = 0; break; - case frame_type_U_UI: cmin = 0; cmax = 1; break; - case frame_type_U_XID: cmin = 0; cmax = 1; break; - case frame_type_U_TEST: cmin = 0; cmax = 1; break; - default: break; // avoid compiler warning. - } - - for (cr = cmin; cr <= cmax; cr++) { - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct U frame, cr=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_u_frame (addrs, num_addr, cr, ftype, pf, pid, pinfo, info_len); - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - } - } - - -/* S frame */ - - //strcpy (addrs[2], "DIGI1-1"); - //num_addr = 3; - - dw_printf ("\nS frames...\n"); - - for (ftype = frame_type_S_RR; ftype <= frame_type_S_SREJ; ftype++) { - - for (pf = 0; pf <= 1; pf++) { - - modulo = 8; - nr = modulo / 2 + 1; - - // SREJ can only be response. - - for (cr = 0; cr <= (int)(ftype!=frame_type_S_SREJ); cr++) { - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct S frame, cmd=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_s_frame (addrs, num_addr, cr, ftype, modulo, nr, pf, NULL, 0); - - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - - modulo = 128; - nr = modulo / 2 + 1; - - for (cr = 0; cr <= (int)(ftype!=frame_type_S_SREJ); cr++) { - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct S frame, cmd=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_s_frame (addrs, num_addr, cr, ftype, modulo, nr, pf, NULL, 0); - - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - } - } - -/* SREJ is only S frame which can have information part. */ - - static unsigned char srej_info[] = { 1<<1, 2<<1, 3<<1, 4<<1 }; - - ftype = frame_type_S_SREJ; - for (pf = 0; pf <= 1; pf++) { - - modulo = 128; - nr = 127; - cr = cr_res; - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct Multi-SREJ S frame, cmd=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_s_frame (addrs, num_addr, cr, ftype, modulo, nr, pf, srej_info, (int)(sizeof(srej_info))); - - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - - -/* I frame */ - - dw_printf ("\nI frames...\n"); - - pinfo = (unsigned char*)"The rain in Spain stays mainly on the plain."; - info_len = strlen((char*)pinfo); - - for (pf = 0; pf <= 1; pf++) { - - modulo = 8; - nr = 0x55 & (modulo - 1); - ns = 0xaa & (modulo - 1); - - for (cr = 1; cr <= 1; cr++) { // can only be command - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct I frame, cmd=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_i_frame (addrs, num_addr, cr, modulo, nr, ns, pf, pid, pinfo, info_len); - - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - - modulo = 128; - nr = 0x55 & (modulo - 1); - ns = 0xaa & (modulo - 1); - - for (cr = 1; cr <= 1; cr++) { - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nConstruct I frame, cmd=%d, ftype=%d, pid=0x%02x\n", cr, ftype, pid); - - pp = ax25_i_frame (addrs, num_addr, cr, modulo, nr, ns, pf, pid, pinfo, info_len); - - ax25_hex_dump (pp); - enc_dec_compare (pp); - ax25_delete (pp); - } - } - -} // end all_frame_types - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test bitstream tapped off from demodulator. -// -// 5 frames were sent to Nino TNC and a recording was made. -// This was demodulated and the resulting bit stream saved to a file. -// -// No automatic test here - must be done manually with audio recording. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -static int decoding_bitstream = 0; - -static void decode_bitstream(void) -{ - dw_printf("-----\nReading il2p-bitstream.txt if available...\n"); - - FILE *fp = fopen ("il2p-bitstream.txt", "r"); - if (fp == NULL) { - dw_printf ("Bitstream test file not available.\n"); - return; - } - - decoding_bitstream = 1; - int save_previous = il2p_get_debug(); - il2p_set_debug (1); - - int ch; - while ( (ch = fgetc(fp)) != EOF) { - - if (ch == '0' || ch == '1') { - il2p_rec_bit (0, 0, 0, ch - '0'); - } - } - fclose(fp); - il2p_set_debug (save_previous); - decoding_bitstream = 0; - -} // end decode_bitstream - - - - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Test serialize / deserialize. -// -// This uses same functions used on the air. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -static char addrs2[] = "AA1AAA-1>ZZ9ZZZ-9"; -static char addrs3[] = "AA1AAA-1>ZZ9ZZZ-9,DIGI*"; -static char text[] = - "'... As I was saying, that seems to be done right - though I haven't time to look it over thoroughly just now - and that shows that there are three hundred and sixty-four days when you might get un-birthday presents -'" - "\n" - "'Certainly,' said Alice." - "\n" - "'And only one for birthday presents, you know. There's glory for you!'" - "\n" - "'I don't know what you mean by \"glory\",' Alice said." - "\n" - "Humpty Dumpty smiled contemptuously. 'Of course you don't - till I tell you. I meant \"there's a nice knock-down argument for you!\"'" - "\n" - "'But \"glory\" doesn't mean \"a nice knock-down argument\",' Alice objected." - "\n" - "'When I use a word,' Humpty Dumpty said, in rather a scornful tone, 'it means just what I choose it to mean - neither more nor less.'" - "\n" - "'The question is,' said Alice, 'whether you can make words mean so many different things.'" - "\n" - "'The question is,' said Humpty Dumpty, 'which is to be master - that's all.'" - "\n" ; - - -static int rec_count = -1; // disable deserialized packet test. -static int polarity = 0; - -static void test_serdes (void) -{ - text_color_set(DW_COLOR_INFO); - dw_printf ("\nTest serialize / deserialize...\n"); - rec_count = 0; - - int max_fec = 1; - - // try combinations of header type, max_fec, polarity, errors. - - for (int hdr_type = 0; hdr_type <= 1; hdr_type++) { - char packet[1024]; - snprintf (packet, sizeof(packet), "%s:%s", hdr_type ? addrs2 : addrs3, text); - packet_t pp = ax25_from_text (packet, 1); - assert (pp != NULL); - - int chan = 0; - - - for (max_fec = 0; max_fec <= 1; max_fec++) { - for (polarity = 0; polarity <= 2; polarity++) { // 2 means throw in some errors. - int num_bits_sent = il2p_send_frame (chan, pp, max_fec, polarity); - dw_printf ("%d bits sent.\n", num_bits_sent); - - // Need extra bit at end to flush out state machine. - il2p_rec_bit (0, 0, 0, 0); - } - } - ax25_delete(pp); - } - - dw_printf ("Serdes receive count = %d\n", rec_count); - assert (rec_count == 12); - rec_count = -1; // disable deserialized packet test. -} - - -// Serializing calls this which then simulates the demodulator output. - -void tone_gen_put_bit (int chan, int data) -{ - il2p_rec_bit (chan, 0, 0, data); -} - -// This is called when a complete frame has been deserialized. - -void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, int is_fx25) -{ - if (rec_count < 0) return; // Skip check before serdes test. - - rec_count++; - - // Does it have the the expected content? - - unsigned char *pinfo; - int len = ax25_get_info(pp, &pinfo); - assert (len == strlen(text)); - assert (strcmp(text, (char*)pinfo) == 0); - - dw_printf ("Number of symbols corrected: %d\n", retries); - if (polarity == 2) { // expecting errors corrrected. - assert (retries == 10); - } - else { // should be no errors. - assert (retries == 0); - } - - ax25_delete (pp); -} - -alevel_t demod_get_audio_level (int chan, int subchan) -{ - alevel_t alevel; - memset (&alevel, 0, sizeof(alevel)); - return (alevel); -} - -// end il2p_test.c \ No newline at end of file