diff --git a/.gitignore b/.gitignore
index 4e2c807..4977293 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,5 @@ apps/*.py
.cproject
.pyproject
.pydevproject
-nbproject/
\ No newline at end of file
+nbproject/
+.vscode
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 0c42bea..010e10f 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -50,7 +50,9 @@ list(APPEND enabled_blocks
satnogs_ogg_source.xml
satnogs_noaa_apt_sink.xml
satnogs_whitening.xml
+ satnogs_whitening_ccsds.xml
satnogs_ieee802_15_4_variant_decoder.xml
+ satnogs_ax100_decoder.xml
)
if(${INCLUDE_DEBUG_BLOCKS})
diff --git a/grc/satnogs_ax100_decoder.xml b/grc/satnogs_ax100_decoder.xml
new file mode 100644
index 0000000..0ba042e
--- /dev/null
+++ b/grc/satnogs_ax100_decoder.xml
@@ -0,0 +1,74 @@
+
+
+ AX.100 Decoder Definition
+ variable_ax100_decoder
+ import satnogs
+ self.$(id) = $(id) = satnogs.ax100_decoder_make($preamble, $preamble_thrsh, $sync_word, $sync_thrsh, $crc, $whitening, $rs)
+ satnogs.ax100_decoder_make($preamble, $preamble_thrsh, $sync_word, $sync_thrsh, $crc, $whitening, $rs)
+
+
+ Ignore Me
+ value
+ 'ok'
+ raw
+ all
+
+
+
+ Frame Preamble
+ preamble
+ [0x55, 0x55, 0x55, 0x55, 0x55]
+ raw
+
+
+
+ Preamble Threshold
+ preamble_thrsh
+ 5
+ int
+
+
+
+ Synchronization Word
+ sync_word
+ [0x31, 0xe5]
+ raw
+
+
+
+ Synchronization Word Threshold
+ sync_thrsh
+ 3
+ int
+
+
+
+ CRC
+ crc
+ None
+ raw
+
+
+
+ Whitening
+ whitening
+ None
+ raw
+
+
+
+ Reed Solomon
+ rs
+ True
+ enum
+
+
+
+
+
\ No newline at end of file
diff --git a/grc/satnogs_block_tree.xml b/grc/satnogs_block_tree.xml
index 19a4346..3d26ba9 100644
--- a/grc/satnogs_block_tree.xml
+++ b/grc/satnogs_block_tree.xml
@@ -5,6 +5,7 @@
variable_ax25_decoder
variable_amsat_duv_decoder
variable_ieee802_15_4_variant_decoder
+ variable_ax100_decoder
Satellites
@@ -40,5 +41,6 @@
satnogs_ax25_encoder_mb
satnogs_waterfall_sink
variable_whitening
+ variable_whitening_ccsds
satnogs_frame_decoder
\ No newline at end of file
diff --git a/grc/satnogs_whitening_ccsds.xml b/grc/satnogs_whitening_ccsds.xml
new file mode 100644
index 0000000..af64907
--- /dev/null
+++ b/grc/satnogs_whitening_ccsds.xml
@@ -0,0 +1,16 @@
+
+
+ CCSDS Whitening
+ variable_whitening_ccsds
+ import satnogs
+ self.$(id) = $(id) = satnogs.whitening.make_ccsds()
+ satnogs.whitening.make_ccsds()
+
+
+ Ignore Me
+ value
+ 'ok'
+ raw
+ all
+
+
diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt
index d8bc7d0..d846b80 100644
--- a/include/satnogs/CMakeLists.txt
+++ b/include/satnogs/CMakeLists.txt
@@ -28,6 +28,7 @@ list(APPEND DEBUG_HEADER_FILES
)
list(APPEND HEADER_FILES
+ ax100_decoder.h
amsat_duv_decoder.h
api.h
ax25.h
diff --git a/include/satnogs/ax100_decoder.h b/include/satnogs/ax100_decoder.h
new file mode 100644
index 0000000..c55db89
--- /dev/null
+++ b/include/satnogs/ax100_decoder.h
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2019, Libre Space Foundation
+ *
+ * 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 3 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 .
+ */
+
+#ifndef INCLUDED_SATNOGS_AX100_DECODER_H
+#define INCLUDED_SATNOGS_AX100_DECODER_H
+
+#include
+#include
+#include
+#include
+#include
+
+namespace gr {
+namespace satnogs {
+
+/*!
+ * \brief This decoder tries to cover all the supported framing and coding
+ * schemes of the AX100 product from GOMSpace. It also supports some variants
+ * that have appear in different missions, including excet the ASM and a
+ * repeated preamble
+ *
+ */
+class SATNOGS_API ax100_decoder : public decoder {
+public:
+ static decoder_sptr
+ make(const std::vector &preamble,
+ size_t preamble_threshold,
+ const std::vector &sync,
+ size_t sync_threshold,
+ crc::crc_t crc,
+ whitening::whitening_sptr descrambler,
+ bool enable_rs);
+
+ ax100_decoder(const std::vector &preamble,
+ size_t preamble_threshold,
+ const std::vector &sync,
+ size_t sync_threshold,
+ crc::crc_t crc,
+ whitening::whitening_sptr descrambler,
+ bool enable_rs);
+ ~ax100_decoder();
+
+ decoder_status_t
+ decode(const void *in, int len);
+
+ void
+ reset();
+
+ size_t
+ input_multiple() const;
+
+private:
+ /**
+ * Decoding FSM
+ */
+ typedef enum {
+ SEARCHING, //!< when searching for the start of the preamble
+ SEARCHING_SYNC, //!< We have preamble, search for sync
+ DECODING_FRAME_LEN, //!< Decoding the frame length
+ DECODING_PAYLOAD //!< Decoding the payload
+ } decoding_state_t;
+
+ shift_reg d_preamble;
+ shift_reg d_preamble_shift_reg;
+ const size_t d_preamble_len;
+ const size_t d_preamble_thrsh;
+ shift_reg d_sync;
+ shift_reg d_sync_shift_reg;
+ const size_t d_sync_len;
+ const size_t d_sync_thrsh;
+ crc::crc_t d_crc;
+ whitening::whitening_sptr d_descrambler;
+ const bool d_rs;
+ decoding_state_t d_state;
+ size_t d_cnt;
+ size_t d_len;
+ size_t d_length_field_len;
+ uint8_t *d_pdu;
+
+ int
+ search_preamble(const uint8_t *in, int len);
+
+ int
+ search_sync(const uint8_t *in, int len);
+
+ int
+ decode_frame_len(const uint8_t *in, int len);
+
+ void
+ decode_payload(decoder_status_t &status, const uint8_t *in, int len);
+
+ bool
+ check_crc();
+};
+
+} // namespace satnogs
+} // namespace gr
+
+#endif /* INCLUDED_SATNOGS_AX100_DECODER_H */
+
diff --git a/include/satnogs/crc.h b/include/satnogs/crc.h
index 2f71cd0..0566185 100644
--- a/include/satnogs/crc.h
+++ b/include/satnogs/crc.h
@@ -38,6 +38,7 @@ public:
CRC16_CCITT_REVERSED,
CRC16_AX25,
CRC16_IBM,
+ CRC32_C,
CRC_METHODS_NUM
} crc_t;
@@ -53,12 +54,16 @@ public:
static uint16_t
crc16_ibm(const uint8_t *data, size_t len);
+ static uint32_t
+ crc32_c(const uint8_t *data, size_t len);
+
static size_t
crc_size(crc_t t);
private:
static const uint16_t crc16_ccitt_table_reverse[256];
static const uint16_t crc16_ccitt_table[256];
+ static const uint32_t crc32_c_table[256];
};
} // namespace satnogs
diff --git a/include/satnogs/ieee802_15_4_variant_decoder.h b/include/satnogs/ieee802_15_4_variant_decoder.h
index 99778b6..48b9aa0 100644
--- a/include/satnogs/ieee802_15_4_variant_decoder.h
+++ b/include/satnogs/ieee802_15_4_variant_decoder.h
@@ -102,7 +102,7 @@ public:
private:
/**
- * Decoding FSM
+ * Decoding FSM states
*/
typedef enum {
SEARCHING, //!< when searching for the start of the preamble
diff --git a/include/satnogs/utils.h b/include/satnogs/utils.h
index c143ee2..03f76cd 100644
--- a/include/satnogs/utils.h
+++ b/include/satnogs/utils.h
@@ -200,6 +200,15 @@ crc32(const uint8_t *buf, size_t len)
return crc;
}
+static void
+print_pdu(const uint8_t *buf, size_t len)
+{
+ for (size_t i = 0; i < len; i++) {
+ printf("0x%02x ", buf[i]);
+ }
+ printf("\n");
+}
+
} // namespace satnogs
} // namespace gr
diff --git a/include/satnogs/whitening.h b/include/satnogs/whitening.h
index 9657b27..0dbb6e1 100644
--- a/include/satnogs/whitening.h
+++ b/include/satnogs/whitening.h
@@ -44,6 +44,9 @@ public:
static whitening_sptr
make(uint32_t mask, uint32_t seed, uint32_t order);
+ static whitening_sptr
+ make_ccsds();
+
whitening(uint32_t mask, uint32_t seed, uint32_t order);
~whitening();
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 9ff5782..8111a68 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -76,7 +76,8 @@ list(APPEND satnogs_sources
ax25_decoder.cc
json_converter_impl.cc
ieee802_15_4_variant_decoder.cc
- crc.cc)
+ crc.cc
+ ax100_decoder.cc)
if(${INCLUDE_DEBUG_BLOCKS})
list(APPEND satnogs_sources ${satnogs_debug_sources})
@@ -129,6 +130,7 @@ list(APPEND test_satnogs_sources
${CMAKE_CURRENT_SOURCE_DIR}/qa_golay24.cc
${CMAKE_CURRENT_SOURCE_DIR}/test_satnogs.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_satnogs.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_ax100_decoder.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_crc.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_ieee802_15_4_variant_decoder.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_json_converter.cc
diff --git a/lib/ax100_decoder.cc b/lib/ax100_decoder.cc
new file mode 100644
index 0000000..44a6b00
--- /dev/null
+++ b/lib/ax100_decoder.cc
@@ -0,0 +1,325 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2019, Libre Space Foundation
+ *
+ * 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 3 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 .
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern "C" {
+#include
+}
+
+namespace gr {
+namespace satnogs {
+
+decoder::decoder_sptr
+ax100_decoder::make(const std::vector &preamble,
+ size_t preamble_threshold,
+ const std::vector &sync, size_t sync_threshold,
+ crc::crc_t crc, whitening::whitening_sptr descrambler,
+ bool enable_rs)
+{
+ return decoder::decoder_sptr(
+ new ax100_decoder(preamble, preamble_threshold, sync, sync_threshold,
+ crc, descrambler, enable_rs));
+}
+
+ax100_decoder::ax100_decoder(const std::vector &preamble,
+ size_t preamble_threshold,
+ const std::vector &sync,
+ size_t sync_threshold,
+ crc::crc_t crc,
+ whitening::whitening_sptr descrambler,
+ bool enable_rs) :
+ decoder(sizeof(uint8_t), enable_rs ? 255 : 1024),
+ d_preamble(preamble.size() * 8),
+ d_preamble_shift_reg(preamble.size() * 8),
+ d_preamble_len(preamble.size() * 8),
+ d_preamble_thrsh(preamble_threshold),
+ d_sync(sync.size() * 8),
+ d_sync_shift_reg(sync.size() * 8),
+ d_sync_len(sync.size() * 8),
+ d_sync_thrsh(sync_threshold),
+ d_crc(crc),
+ d_descrambler(descrambler),
+ d_rs(enable_rs),
+ d_state(SEARCHING),
+ d_cnt(0),
+ d_len(0),
+ /* Coded Golay 24 bits */
+ d_length_field_len(3),
+ d_pdu(new uint8_t[1024])
+{
+ for (uint8_t b : preamble) {
+ d_preamble <<= (b >> 7);
+ d_preamble <<= ((b >> 6) & 0x1);
+ d_preamble <<= ((b >> 5) & 0x1);
+ d_preamble <<= ((b >> 4) & 0x1);
+ d_preamble <<= ((b >> 3) & 0x1);
+ d_preamble <<= ((b >> 2) & 0x1);
+ d_preamble <<= ((b >> 1) & 0x1);
+ d_preamble <<= (b & 0x1);
+ }
+ for (uint8_t b : sync) {
+ d_sync <<= (b >> 7);
+ d_sync <<= ((b >> 6) & 0x1);
+ d_sync <<= ((b >> 5) & 0x1);
+ d_sync <<= ((b >> 4) & 0x1);
+ d_sync <<= ((b >> 3) & 0x1);
+ d_sync <<= ((b >> 2) & 0x1);
+ d_sync <<= ((b >> 1) & 0x1);
+ d_sync <<= (b & 0x1);
+ }
+
+ if (d_sync_len < 8) {
+ throw std::invalid_argument("SYNC word should be at least 8 bits");
+ }
+
+ if (d_preamble_len < 2 * d_preamble_thrsh) {
+ throw std::invalid_argument(
+ "Too many error bits are allowed for the preamble."
+ "Consider lowering the threshold");
+ }
+
+ if (d_sync_len < 2 * d_sync_thrsh) {
+ throw std::invalid_argument(
+ "Too many error bits are allowed for the sync word. "
+ "Consider lowering the threshold");
+ }
+}
+
+ax100_decoder::~ax100_decoder()
+{
+ delete[] d_pdu;
+}
+
+decoder_status_t
+ax100_decoder::decode(const void *in, int len)
+{
+ decoder_status_t status;
+ switch (d_state) {
+ case SEARCHING:
+ status.consumed = search_preamble((const uint8_t *) in, len);
+ break;
+ case SEARCHING_SYNC:
+ status.consumed = search_sync((const uint8_t *) in, len);
+ break;
+ case DECODING_FRAME_LEN:
+ status.consumed = decode_frame_len((const uint8_t *) in, len);
+ break;
+ case DECODING_PAYLOAD:
+ decode_payload(status, (const uint8_t *) in, len);
+ break;
+ default:
+ throw std::runtime_error("ax100_decoder: Invalid decoding state");
+ }
+ return status;
+}
+
+void
+ax100_decoder::reset()
+{
+ if (d_descrambler) {
+ d_descrambler->reset();
+ }
+ d_cnt = 0;
+ d_state = SEARCHING;
+ d_preamble_shift_reg.reset();
+ d_sync_shift_reg.reset();
+}
+
+size_t
+ax100_decoder::input_multiple() const
+{
+ return 8;
+}
+
+int
+ax100_decoder::search_preamble(const uint8_t *in, int len)
+{
+ /* We support also cases, where a repeated preamble is not used (pure CCSDS )*/
+ if (d_preamble_len == 0) {
+ d_state = SEARCHING_SYNC;
+ return search_sync(in, len);
+ }
+
+ for (int i = 0; i < len; i++) {
+ d_preamble_shift_reg <<= in[i];
+ shift_reg tmp = d_preamble_shift_reg ^ d_preamble;
+ if (tmp.count() <= d_preamble_thrsh) {
+ d_state = SEARCHING_SYNC;
+ d_cnt = 0;
+ return i + 1;
+ }
+ }
+ return len;
+}
+
+int
+ax100_decoder::search_sync(const uint8_t *in, int len)
+{
+ for (int i = 0; i < len; i++) {
+ d_sync_shift_reg <<= in[i];
+ shift_reg tmp = d_sync_shift_reg ^ d_sync;
+ d_cnt++;
+ if (tmp.count() <= d_sync_thrsh) {
+ LOG_WARN("Decoding");
+ d_state = DECODING_FRAME_LEN;
+ d_cnt = 0;
+ return i + 1;
+ }
+
+ /* The sync word should be available by now */
+ if (d_cnt > d_preamble_len * 2 + d_sync_len) {
+ reset();
+ return i + 1;
+ }
+ }
+ return len;
+}
+
+int
+ax100_decoder::decode_frame_len(const uint8_t *in, int len)
+{
+ const int s = len / 8;
+ for (int i = 0; i < s; i++) {
+ uint8_t b = 0x0;
+ b = in[i * 8] << 7;
+ b |= in[i * 8 + 1] << 6;
+ b |= in[i * 8 + 2] << 5;
+ b |= in[i * 8 + 3] << 4;
+ b |= in[i * 8 + 4] << 3;
+ b |= in[i * 8 + 5] << 2;
+ b |= in[i * 8 + 6] << 1;
+ b |= in[i * 8 + 7];
+ d_pdu[d_cnt++] = b;
+
+ if (d_cnt == d_length_field_len) {
+ uint32_t coded_len = (d_pdu[0] << 16) | (d_pdu[1] << 8) | d_pdu[2];
+ print_pdu((const uint8_t *)&coded_len, 4);
+ uint32_t len;
+ golay24 g = golay24();
+ if (g.decode24(&len, coded_len)) {
+ d_len = len & 0xFF;
+ //d_len += crc::crc_size(d_crc);
+ LOG_WARN("Len: %u", d_len);
+ if (d_len > max_frame_len()) {
+ reset();
+ return (i + 1) * 8;
+ }
+ /* All good! Proceed with decoding */
+ d_cnt = 0;
+ d_state = DECODING_PAYLOAD;
+ memset(d_pdu, 0, max_frame_len());
+ return (i + 1) * 8;
+ }
+ else {
+ reset();
+ return (i + 1) * 8;
+ }
+ }
+ }
+ return s * 8;
+}
+
+void
+ax100_decoder::decode_payload(decoder_status_t &status,
+ const uint8_t *in, int len)
+{
+ const int s = len / 8;
+ for (int i = 0; i < s; i++) {
+ uint8_t b = 0x0;
+ b = in[i * 8] << 7;
+ b |= in[i * 8 + 1] << 6;
+ b |= in[i * 8 + 2] << 5;
+ b |= in[i * 8 + 3] << 4;
+ b |= in[i * 8 + 4] << 3;
+ b |= in[i * 8 + 5] << 2;
+ b |= in[i * 8 + 6] << 1;
+ b |= in[i * 8 + 7];
+ d_pdu[d_cnt++] = b;
+
+ if (d_cnt == d_len) {
+ if (d_descrambler) {
+ d_descrambler->descramble(d_pdu, d_pdu, d_len, false);
+ }
+ metadata::add_time_iso8601(status.data);
+ /* If RS is used tru to decode the received frame */
+ if (d_rs) {
+ int ret = decode_rs_8(d_pdu, NULL, 0, 255 - d_len);
+ /* Drop the parity */
+ d_len -= 32;
+ if (ret > - 1) {
+ metadata::add_corrected_bits(status.data, ret);
+ }
+ else {
+ reset();
+ status.consumed = (i + 1) * 8;
+ return;
+ }
+ }
+
+
+ metadata::add_time_iso8601(status.data);
+ metadata::add_pdu(status.data, d_pdu, d_len - crc::crc_size(d_crc));
+ metadata::add_crc_valid(status.data, check_crc());
+ reset();
+ status.decode_success = true;
+ status.consumed = (i + 1) * 8;
+ return;
+ }
+ }
+ status.consumed = s * 8;
+}
+
+bool
+ax100_decoder::check_crc()
+{
+ uint16_t crc16_c;
+ uint16_t crc16_received;
+ uint32_t crc32_c;
+ uint32_t crc32_received;
+ switch (d_crc) {
+ case crc::CRC_NONE:
+ return true;
+ case crc::CRC32_C:
+ crc32_c = crc::crc32_c(d_pdu, d_len - 4);
+ memcpy(&crc32_received, d_pdu + d_len - 4, 4);
+ crc32_received = ntohl(crc32_received);
+ LOG_WARN("Received: 0x%02x Computed: 0x%02x", crc32_received, crc32_c);
+ //print_pdu(d_pdu, d_len);
+ if (crc32_c == crc32_received) {
+ return true;
+ }
+ return false;
+ default:
+ throw std::runtime_error("ax100_decoder: Invalid CRC");
+ }
+}
+
+} /* namespace satnogs */
+} /* namespace gr */
diff --git a/lib/crc.cc b/lib/crc.cc
index f4eba94..2e1f942 100644
--- a/lib/crc.cc
+++ b/lib/crc.cc
@@ -93,6 +93,57 @@ const uint16_t crc::crc16_ccitt_table[256] = {
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
+/*
+ * Slicing-by-8 software
+ *
+ * The following CRC lookup table was generated automagically
+ * using the following model parameters:
+ *
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
+ */
+
+const uint32_t crc::crc32_c_table[256] = {
+ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+ 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+ 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+ 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+ 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+ 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+ 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+ 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+ 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+ 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+ 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+ 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+ 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+ 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+ 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+ 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+ 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+ 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+ 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+ 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+ 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+ 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+ 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+ 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+ 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+ 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+ 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+ 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+ 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+ 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+ 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+ 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+};
+
uint16_t
crc::crc16_ccitt_reversed(const uint8_t *data, size_t len)
{
@@ -165,11 +216,24 @@ crc::crc_size(crc_t t)
case CRC16_AX25:
case CRC16_IBM:
return sizeof(uint16_t);
+ case CRC32_C:
+ return sizeof(uint32_t);
default:
throw std::invalid_argument("crc: Invalid CRC method");
}
}
+uint32_t
+crc::crc32_c(const uint8_t *data, size_t len)
+{
+ uint32_t crc = 0xFFFFFFFF;
+ for (size_t i = 0; i < len; i++) {
+ crc = (crc >> 8) ^ crc::crc32_c_table[(crc ^ data[i]) & 0xff];
+ }
+ return crc ^ 0xFFFFFFFF;
+}
+
} /* namespace satnogs */
} /* namespace gr */
+
diff --git a/lib/ieee802_15_4_variant_decoder.cc b/lib/ieee802_15_4_variant_decoder.cc
index c7fa7ee..4e0d014 100644
--- a/lib/ieee802_15_4_variant_decoder.cc
+++ b/lib/ieee802_15_4_variant_decoder.cc
@@ -326,6 +326,8 @@ ieee802_15_4_variant_decoder::check_crc()
{
uint16_t crc16_c;
uint16_t crc16_received;
+ uint32_t crc32_c;
+ uint32_t crc32_received;
switch (d_crc) {
case crc::CRC_NONE:
return true;
@@ -351,11 +353,20 @@ ieee802_15_4_variant_decoder::check_crc()
crc16_c = crc::crc16_ibm(d_pdu, d_len + d_length_field_len - 2);
memcpy(&crc16_received, d_pdu + d_length_field_len + d_len - 2, 2);
crc16_received = ntohs(crc16_received);
- LOG_WARN("Received: 0x%02x Computed: 0x%02x", crc16_received, crc16_c);
+ LOG_DEBUG("Received: 0x%02x Computed: 0x%02x", crc16_received, crc16_c);
if (crc16_c == crc16_received) {
return true;
}
return false;
+ case crc::CRC32_C:
+ crc32_c = crc::crc32_c(d_pdu, d_len + d_length_field_len - 4);
+ memcpy(&crc32_received, d_pdu + d_length_field_len + d_len - 4, 4);
+ crc32_received = ntohl(crc32_received);
+ LOG_DEBUG("Received: 0x%02x Computed: 0x%02x", crc32_received, crc32_c);
+ if (crc32_c == crc32_received) {
+ return true;
+ }
+ return false;
default:
throw std::runtime_error("ieee802_15_4_variant_decoder: Invalid CRC");
}
diff --git a/lib/qa_ax100_decoder.cc b/lib/qa_ax100_decoder.cc
new file mode 100644
index 0000000..357db39
--- /dev/null
+++ b/lib/qa_ax100_decoder.cc
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2019, Libre Space Foundation
+ *
+ * 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 3 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
+#include
+#include "qa_ax100_decoder.h"
+#include
+
+namespace gr {
+namespace satnogs {
+
+void
+qa_ax100_decoder::t1()
+{
+ // Put test here
+}
+
+} /* namespace satnogs */
+} /* namespace gr */
+
diff --git a/lib/qa_ax100_decoder.h b/lib/qa_ax100_decoder.h
new file mode 100644
index 0000000..1202c82
--- /dev/null
+++ b/lib/qa_ax100_decoder.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2019, Libre Space Foundation
+ *
+ * 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 3 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 .
+ */
+
+#ifndef _QA_AX100_DECODER_H_
+#define _QA_AX100_DECODER_H_
+
+#include
+#include
+
+namespace gr {
+namespace satnogs {
+
+class qa_ax100_decoder : public CppUnit::TestCase {
+public:
+ CPPUNIT_TEST_SUITE(qa_ax100_decoder);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void t1();
+};
+
+} /* namespace satnogs */
+} /* namespace gr */
+
+#endif /* _QA_AX100_DECODER_H_ */
+
diff --git a/lib/qa_satnogs.cc b/lib/qa_satnogs.cc
index 392ea2d..8097c4f 100644
--- a/lib/qa_satnogs.cc
+++ b/lib/qa_satnogs.cc
@@ -24,6 +24,7 @@
#include "qa_json_converter.h"
#include "qa_ieee802_15_4_variant_decoder.h"
#include "qa_crc.h"
+#include "qa_ax100_decoder.h"
CppUnit::TestSuite *
qa_satnogs::suite()
@@ -34,5 +35,6 @@ qa_satnogs::suite()
s->addTest(gr::satnogs::qa_json_converter::suite());
s->addTest(gr::satnogs::qa_ieee802_15_4_variant_decoder::suite());
s->addTest(gr::satnogs::qa_crc::suite());
+ s->addTest(gr::satnogs::qa_ax100_decoder::suite());
return s;
}
diff --git a/lib/shift_reg.cc b/lib/shift_reg.cc
index 3c34889..84b4bd7 100644
--- a/lib/shift_reg.cc
+++ b/lib/shift_reg.cc
@@ -36,9 +36,6 @@ shift_reg::shift_reg(size_t len)
: d_len(len),
d_reg(len, 0)
{
- if (len < 1) {
- throw std::invalid_argument("Shift register should contain at least one stage");
- }
}
shift_reg::~shift_reg()
diff --git a/lib/whitening.cc b/lib/whitening.cc
index 0685e1c..0ed72d3 100644
--- a/lib/whitening.cc
+++ b/lib/whitening.cc
@@ -46,6 +46,17 @@ whitening::make(uint32_t mask, uint32_t seed, uint32_t order)
}
+/**
+ * CCSDS compliant data whitening
+ * @return shared pointer to a CCSDS compliant scrambler/descrambler
+ */
+whitening::whitening_sptr
+whitening::make_ccsds()
+{
+ return make(0xA9, 0xFF, 7);
+}
+
+
/**
* Data whitening and de-whitening class
* @param mask the polynomial mask
diff --git a/swig/satnogs_swig0.i b/swig/satnogs_swig0.i
index 5e861ba..fbd219e 100644
--- a/swig/satnogs_swig0.i
+++ b/swig/satnogs_swig0.i
@@ -15,6 +15,7 @@
%{
#include "satnogs/amsat_duv_decoder.h"
+#include "satnogs/ax100_decoder.h"
#include "satnogs/ax25_decoder.h"
#include "satnogs/morse_tree.h"
#include "satnogs/morse_decoder.h"
@@ -53,8 +54,11 @@
%include "satnogs/amsat_duv_decoder.h"
%include "satnogs/ax25_decoder.h"
%include "satnogs/metadata.h"
+
+/* crc.h should come first. All classes using it should be included afterwards */
%include "satnogs/crc.h"
%include "satnogs/ieee802_15_4_variant_decoder.h"
+%include "satnogs/ax100_decoder.h"
%include "satnogs/morse_decoder.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, morse_decoder);