Format all C++ files using the astyle beautifier

This commit is contained in:
Manolis Surligas 2019-09-12 16:25:10 +03:00
parent a5caed2ca9
commit e09c180f84
125 changed files with 11718 additions and 12132 deletions

View File

@ -26,17 +26,14 @@
#include <string> #include <string>
#include <deque> #include <deque>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief AMSAT 8b10b + CCSDS RS DUV decoder * \brief AMSAT 8b10b + CCSDS RS DUV decoder
* *
*/ */
class SATNOGS_API amsat_duv_decoder : public decoder class SATNOGS_API amsat_duv_decoder : public decoder {
{
public: public:
static const size_t static const size_t
@ -46,20 +43,19 @@ public:
amsat_fox_spacecraft_id[]; amsat_fox_spacecraft_id[];
static decoder::decoder_sptr static decoder::decoder_sptr
make(const std::string& control_symbol, size_t max_frame_len = 96); make(const std::string &control_symbol, size_t max_frame_len = 96);
amsat_duv_decoder (const std::string& control_symbol, size_t max_frame_len); amsat_duv_decoder(const std::string &control_symbol, size_t max_frame_len);
~amsat_duv_decoder (); ~amsat_duv_decoder();
decoder_status_t decoder_status_t
decode (const void *in, int len); decode(const void *in, int len);
void void
reset (); reset();
private: private:
typedef enum typedef enum {
{
SEARCH_SYNC, DECODING SEARCH_SYNC, DECODING
} d_state_t; } d_state_t;
@ -80,16 +76,15 @@ private:
std::deque<uint8_t> d_bitstream; std::deque<uint8_t> d_bitstream;
bool bool
set_access_code (const std::string &control_symbol); set_access_code(const std::string &control_symbol);
void void
process_10b (uint16_t word, size_t write_pos); process_10b(uint16_t word, size_t write_pos);
inline uint16_t inline uint16_t
pack_10b_word(size_t idx); pack_10b_word(size_t idx);
int d_lookup_8b10b[2][256] = int d_lookup_8b10b[2][256] = {
{
// RD = -1 cases // RD = -1 cases
{ {
/* 00 */0x274, /* 00 */0x274,
@ -347,7 +342,8 @@ private:
/* fc */0x4ee, /* fc */0x4ee,
/* fd */0x2e1, /* fd */0x2e1,
/* fe */0x1e1, /* fe */0x1e1,
/* ff */0x2b1, }, // RD = +1 cases /* ff */0x2b1,
}, // RD = +1 cases
{ {
/* 00 */0x58b, /* 00 */0x58b,
/* 01 */0x62b, /* 01 */0x62b,
@ -604,7 +600,9 @@ private:
/* fc */0x0e1, /* fc */0x0e1,
/* fd */0x51e, /* fd */0x51e,
/* fe */0x61e, /* fe */0x61e,
/* ff */0x54e, } }; /* ff */0x54e,
}
};
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -27,45 +27,39 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
namespace gr namespace gr {
{
namespace satnogs namespace satnogs {
{ const size_t AX25_MIN_ADDR_LEN = 14;
const size_t AX25_MIN_ADDR_LEN = 14; const size_t AX25_MAX_ADDR_LEN = 28;
const size_t AX25_MAX_ADDR_LEN = 28; const size_t AX25_MIN_CTRL_LEN = 1;
const size_t AX25_MIN_CTRL_LEN = 1; const size_t AX25_MAX_CTRL_LEN = 2;
const size_t AX25_MAX_CTRL_LEN = 2; const size_t AX25_MAX_FRAME_LEN = 256;
const size_t AX25_MAX_FRAME_LEN = 256; const uint8_t AX25_SYNC_FLAG = 0x7E;
const uint8_t AX25_SYNC_FLAG = 0x7E; const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
const uint8_t AX25_CALLSIGN_MAX_LEN = 6; const float AX25_SYNC_FLAG_MAP[8] =
const float AX25_SYNC_FLAG_MAP[8] = { -1, 1, 1, 1, 1, 1, 1, -1 };
{ -1, 1, 1, 1, 1, 1, 1, -1 }; const uint8_t AX25_SYNC_FLAG_MAP_BIN[8] =
const uint8_t AX25_SYNC_FLAG_MAP_BIN[8] = { 0, 1, 1, 1, 1, 1, 1, 0 };
{ 0, 1, 1, 1, 1, 1, 1, 0 }; /**
/**
* AX.25 Frame types * AX.25 Frame types
*/ */
typedef enum typedef enum {
{
AX25_I_FRAME, //!< AX25_I_FRAME Information frame AX25_I_FRAME, //!< AX25_I_FRAME Information frame
AX25_S_FRAME, //!< AX25_S_FRAME Supervisory frame AX25_S_FRAME, //!< AX25_S_FRAME Supervisory frame
AX25_U_FRAME, //!< AX25_U_FRAME Unnumbered frame AX25_U_FRAME, //!< AX25_U_FRAME Unnumbered frame
AX25_UI_FRAME /**!< AX25_UI_FRAME Unnumbered information frame */ AX25_UI_FRAME /**!< AX25_UI_FRAME Unnumbered information frame */
} ax25_frame_type_t; } ax25_frame_type_t;
typedef enum typedef enum {
{
AX25_ENC_FAIL, AX25_ENC_OK AX25_ENC_FAIL, AX25_ENC_OK
} ax25_encode_status_t; } ax25_encode_status_t;
typedef enum typedef enum {
{
AX25_DEC_FAIL, AX25_DEC_OK AX25_DEC_FAIL, AX25_DEC_OK
} ax25_decode_status_t; } ax25_decode_status_t;
typedef struct typedef struct {
{
uint8_t address[AX25_MAX_ADDR_LEN]; uint8_t address[AX25_MAX_ADDR_LEN];
size_t address_len; size_t address_len;
uint16_t ctrl; uint16_t ctrl;
@ -74,21 +68,21 @@ namespace gr
uint8_t *info; uint8_t *info;
size_t info_len; size_t info_len;
ax25_frame_type_t type; ax25_frame_type_t type;
} ax25_frame_t; } ax25_frame_t;
/** /**
* Calculates the FCS of the AX25 frame * Calculates the FCS of the AX25 frame
* @param buffer data buffer * @param buffer data buffer
* @param len size of the buffer * @param len size of the buffer
* @return the FCS of the buffer * @return the FCS of the buffer
*/ */
static inline uint16_t static inline uint16_t
ax25_fcs (uint8_t *buffer, size_t len) ax25_fcs(uint8_t *buffer, size_t len)
{ {
return crc::crc16_ax25(buffer, len); return crc::crc16_ax25(buffer, len);
} }
/** /**
* Creates the header field of the AX.25 frame * Creates the header field of the AX.25 frame
* @param out the output buffer with enough memory to hold the address field * @param out the output buffer with enough memory to hold the address field
* @param dest_addr the destination callsign address * @param dest_addr the destination callsign address
@ -96,14 +90,14 @@ namespace gr
* @param src_addr the callsign of the source * @param src_addr the callsign of the source
* @param src_ssid the source SSID * @param src_ssid the source SSID
*/ */
static inline size_t static inline size_t
ax25_create_addr_field (uint8_t *out, std::string dest_addr, ax25_create_addr_field(uint8_t *out, std::string dest_addr,
uint8_t dest_ssid, std::string src_addr, uint8_t dest_ssid, std::string src_addr,
uint8_t src_ssid) uint8_t src_ssid)
{ {
size_t i; size_t i;
for (i = 0; i < dest_addr.length (); i++) { for (i = 0; i < dest_addr.length(); i++) {
*out++ = dest_addr[i] << 1; *out++ = dest_addr[i] << 1;
} }
/* /*
@ -117,7 +111,7 @@ namespace gr
/* FIXME: C bit is set to 0 implicitly */ /* FIXME: C bit is set to 0 implicitly */
*out++ = ((0b1111 & dest_ssid) << 1) | 0b01100000; *out++ = ((0b1111 & dest_ssid) << 1) | 0b01100000;
for (i = 0; i < src_addr.length (); i++) { for (i = 0; i < src_addr.length(); i++) {
*out++ = src_addr[i] << 1; *out++ = src_addr[i] << 1;
} }
for (; i < AX25_CALLSIGN_MAX_LEN; i++) { for (; i < AX25_CALLSIGN_MAX_LEN; i++) {
@ -129,39 +123,39 @@ namespace gr
/* FIXME: C bit is set to 0 implicitly */ /* FIXME: C bit is set to 0 implicitly */
*out++ = ((0b1111 & src_ssid) << 1) | 0b01100001; *out++ = ((0b1111 & src_ssid) << 1) | 0b01100001;
return AX25_MIN_ADDR_LEN; return AX25_MIN_ADDR_LEN;
} }
/** /**
* Gets the destination SSID of an AX.25 frame * Gets the destination SSID of an AX.25 frame
* @param in the AX.25 frame buffer * @param in the AX.25 frame buffer
* @return the destination SSID * @return the destination SSID
*/ */
static inline uint8_t static inline uint8_t
ax25_get_dest_ssid (const uint8_t *in) ax25_get_dest_ssid(const uint8_t *in)
{ {
uint8_t ret; uint8_t ret;
ret = in[AX25_CALLSIGN_MAX_LEN]; ret = in[AX25_CALLSIGN_MAX_LEN];
return (ret >> 1) & 0b1111; return (ret >> 1) & 0b1111;
} }
static inline size_t static inline size_t
ax25_prepare_frame (uint8_t *out, const uint8_t *info, size_t info_len, ax25_prepare_frame(uint8_t *out, const uint8_t *info, size_t info_len,
ax25_frame_type_t type, uint8_t *addr, size_t addr_len, ax25_frame_type_t type, uint8_t *addr, size_t addr_len,
uint16_t ctrl, size_t ctrl_len, size_t preamble_len, uint16_t ctrl, size_t ctrl_len, size_t preamble_len,
size_t postamble_len) size_t postamble_len)
{ {
uint16_t fcs; uint16_t fcs;
size_t i; size_t i;
if (info_len > AX25_MAX_FRAME_LEN) { if (info_len > AX25_MAX_FRAME_LEN) {
return 0; return 0;
} }
memset (out, AX25_SYNC_FLAG, preamble_len); memset(out, AX25_SYNC_FLAG, preamble_len);
i = preamble_len; i = preamble_len;
/* Insert address and control fields */ /* Insert address and control fields */
if (addr_len == AX25_MIN_ADDR_LEN || addr_len == AX25_MAX_ADDR_LEN) { if (addr_len == AX25_MIN_ADDR_LEN || addr_len == AX25_MAX_ADDR_LEN) {
memcpy (out + i, addr, addr_len); memcpy(out + i, addr, addr_len);
i += addr_len; i += addr_len;
} }
else { else {
@ -169,7 +163,7 @@ namespace gr
} }
if (ctrl_len == AX25_MIN_CTRL_LEN || ctrl_len == AX25_MAX_CTRL_LEN) { if (ctrl_len == AX25_MIN_CTRL_LEN || ctrl_len == AX25_MAX_CTRL_LEN) {
memcpy (out + i, &ctrl, ctrl_len); memcpy(out + i, &ctrl, ctrl_len);
i += ctrl_len; i += ctrl_len;
} }
else { else {
@ -184,23 +178,23 @@ namespace gr
if (type == AX25_I_FRAME || type == AX25_UI_FRAME) { if (type == AX25_I_FRAME || type == AX25_UI_FRAME) {
out[i++] = 0xF0; out[i++] = 0xF0;
} }
memcpy (out + i, info, info_len); memcpy(out + i, info, info_len);
i += info_len; i += info_len;
/* Compute the FCS. Ignore the first flag byte */ /* Compute the FCS. Ignore the first flag byte */
fcs = ax25_fcs (out + preamble_len, i - preamble_len); fcs = ax25_fcs(out + preamble_len, i - preamble_len);
/* The MS bits are sent first ONLY at the FCS field */ /* The MS bits are sent first ONLY at the FCS field */
out[i++] = fcs & 0xFF; out[i++] = fcs & 0xFF;
out[i++] = (fcs >> 8) & 0xFF; out[i++] = (fcs >> 8) & 0xFF;
memset (out + i, AX25_SYNC_FLAG, postamble_len); memset(out + i, AX25_SYNC_FLAG, postamble_len);
for(size_t j = preamble_len; j < i; j++) { for (size_t j = preamble_len; j < i; j++) {
printf("0x%02x ", out[j]); printf("0x%02x ", out[j]);
} }
printf("\n"); printf("\n");
return i + postamble_len; return i + postamble_len;
} }
/** /**
* Constructs an AX.25 by performing NRZ encoding and bit stuffing * Constructs an AX.25 by performing NRZ encoding and bit stuffing
* @param out the output buffer to hold the frame. Note that due to * @param out the output buffer to hold the frame. Note that due to
* the NRZ encoding the output would be [-1, 1]. Also the size of the * the NRZ encoding the output would be [-1, 1]. Also the size of the
@ -224,11 +218,11 @@ namespace gr
* *
* @return the resulting status of the encoding * @return the resulting status of the encoding
*/ */
static inline ax25_encode_status_t static inline ax25_encode_status_t
ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer, ax25_nrz_bit_stuffing(float *out, size_t *out_len, const uint8_t *buffer,
size_t buffer_len, size_t preamble_len, size_t buffer_len, size_t preamble_len,
size_t postamble_len) size_t postamble_len)
{ {
uint8_t bit; uint8_t bit;
uint8_t prev_bit = 0; uint8_t prev_bit = 0;
size_t out_idx = 0; size_t out_idx = 0;
@ -239,7 +233,7 @@ namespace gr
/* Leading FLAG field does not need bit stuffing */ /* Leading FLAG field does not need bit stuffing */
for (i = 0; i < preamble_len; i++) { for (i = 0; i < preamble_len; i++) {
memcpy (out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); memcpy(out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float));
out_idx += 8; out_idx += 8;
} }
@ -274,15 +268,15 @@ namespace gr
/* Trailing FLAG field does not need bit stuffing */ /* Trailing FLAG field does not need bit stuffing */
for (i = 0; i < postamble_len; i++) { for (i = 0; i < postamble_len; i++) {
memcpy (out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); memcpy(out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float));
out_idx += 8; out_idx += 8;
} }
*out_len = out_idx; *out_len = out_idx;
return AX25_ENC_OK; return AX25_ENC_OK;
} }
/** /**
* Constructs an AX.25 by performing bit stuffing. * Constructs an AX.25 by performing bit stuffing.
* @param out the output buffer to hold the frame. To keep it simple, * @param out the output buffer to hold the frame. To keep it simple,
* each byte of the buffer holds only one bit. Also the size of the * each byte of the buffer holds only one bit. Also the size of the
@ -306,11 +300,11 @@ namespace gr
* *
* @return the resulting status of the encoding * @return the resulting status of the encoding
*/ */
static inline ax25_encode_status_t static inline ax25_encode_status_t
ax25_bit_stuffing (uint8_t *out, size_t *out_len, const uint8_t *buffer, ax25_bit_stuffing(uint8_t *out, size_t *out_len, const uint8_t *buffer,
const size_t buffer_len, size_t preamble_len, const size_t buffer_len, size_t preamble_len,
size_t postamble_len) size_t postamble_len)
{ {
uint8_t bit; uint8_t bit;
uint8_t shift_reg = 0x0; uint8_t shift_reg = 0x0;
size_t out_idx = 0; size_t out_idx = 0;
@ -319,7 +313,7 @@ namespace gr
/* Leading FLAG field does not need bit stuffing */ /* Leading FLAG field does not need bit stuffing */
for (i = 0; i < preamble_len; i++) { for (i = 0; i < preamble_len; i++) {
memcpy (out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t)); memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
out_idx += 8; out_idx += 8;
} }
@ -339,18 +333,18 @@ namespace gr
/* Trailing FLAG field does not need bit stuffing */ /* Trailing FLAG field does not need bit stuffing */
for (i = 0; i < postamble_len; i++) { for (i = 0; i < postamble_len; i++) {
memcpy (out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t)); memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
out_idx += 8; out_idx += 8;
} }
*out_len = out_idx; *out_len = out_idx;
return AX25_ENC_OK; return AX25_ENC_OK;
} }
static inline ax25_decode_status_t static inline ax25_decode_status_t
ax25_decode (uint8_t *out, size_t *out_len, const uint8_t *ax25_frame, ax25_decode(uint8_t *out, size_t *out_len, const uint8_t *ax25_frame,
size_t len) size_t len)
{ {
size_t i; size_t i;
size_t frame_start = UINT_MAX; size_t frame_start = UINT_MAX;
size_t frame_stop = UINT_MAX; size_t frame_stop = UINT_MAX;
@ -430,7 +424,7 @@ namespace gr
} }
/* Now check the CRC */ /* Now check the CRC */
fcs = ax25_fcs (out, received_bytes - sizeof(uint16_t)); fcs = ax25_fcs(out, received_bytes - sizeof(uint16_t));
recv_fcs = (((uint16_t) out[received_bytes - 2]) << 8) recv_fcs = (((uint16_t) out[received_bytes - 2]) << 8)
| out[received_bytes - 1]; | out[received_bytes - 1];
@ -442,9 +436,9 @@ namespace gr
*out_len = received_bytes - sizeof(uint16_t); *out_len = received_bytes - sizeof(uint16_t);
return AX25_DEC_OK; return AX25_DEC_OK;
} }
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr

View File

@ -27,10 +27,8 @@
#include <deque> #include <deque>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief AX.25 decoder that supports the legacy hardware radios. * \brief AX.25 decoder that supports the legacy hardware radios.
@ -52,8 +50,7 @@ namespace satnogs
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API ax25_decoder : public decoder class SATNOGS_API ax25_decoder : public decoder {
{
public: public:
/** /**
@ -79,7 +76,7 @@ public:
* @return a shared pointer of the decoder instance * @return a shared pointer of the decoder instance
*/ */
static decoder::decoder_sptr static decoder::decoder_sptr
make (const std::string &addr, uint8_t ssid, bool promisc = false, make(const std::string &addr, uint8_t ssid, bool promisc = false,
bool descramble = true, bool crc_check = true, bool descramble = true, bool crc_check = true,
size_t max_frame_len = 512); size_t max_frame_len = 512);
@ -104,21 +101,20 @@ public:
* @param crc_check bypass the CRC check of the frame * @param crc_check bypass the CRC check of the frame
* @param max_frame_len the maximum allowed frame length * @param max_frame_len the maximum allowed frame length
*/ */
ax25_decoder (const std::string &addr, uint8_t ssid, bool promisc = false, ax25_decoder(const std::string &addr, uint8_t ssid, bool promisc = false,
bool descramble = true, bool crc_check = true, bool descramble = true, bool crc_check = true,
size_t max_frame_len = 512); size_t max_frame_len = 512);
~ax25_decoder (); ~ax25_decoder();
decoder_status_t decoder_status_t
decode (const void *in, int len); decode(const void *in, int len);
void void
reset (); reset();
private: private:
typedef enum typedef enum {
{
NO_SYNC, IN_SYNC, DECODING NO_SYNC, IN_SYNC, DECODING
} decoding_state_t; } decoding_state_t;
@ -143,21 +139,21 @@ private:
size_t d_frame_start; size_t d_frame_start;
void void
reset_state (); reset_state();
void void
enter_sync_state (); enter_sync_state();
void void
enter_decoding_state (); enter_decoding_state();
bool bool
enter_frame_end (decoder_status_t& status); enter_frame_end(decoder_status_t &status);
bool bool
_decode (decoder_status_t& status); _decode(decoder_status_t &status);
inline void inline void
decode_1b (uint8_t in); decode_1b(uint8_t in);
bool bool
frame_check (); frame_check();
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief AX.25 encoder block that supports the legacy hardware radios. * \brief AX.25 encoder block that supports the legacy hardware radios.
* *
* The block takes as inputs blob PMT messages and generates a byte stream. * The block takes as inputs blob PMT messages and generates a byte stream.
@ -39,9 +37,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API ax25_encoder_mb : virtual public gr::sync_block class SATNOGS_API ax25_encoder_mb : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<ax25_encoder_mb> sptr; typedef boost::shared_ptr<ax25_encoder_mb> sptr;
@ -64,14 +61,14 @@ namespace gr
* after bit stuffing * after bit stuffing
*/ */
static sptr static sptr
make (const std::string& dest_addr, uint8_t dest_ssid, make(const std::string &dest_addr, uint8_t dest_ssid,
const std::string& src_addr, const std::string &src_addr,
uint8_t src_ssid, size_t preamble_len =16, uint8_t src_ssid, size_t preamble_len = 16,
size_t postamble_len = 16, size_t postamble_len = 16,
bool scramble = true); bool scramble = true);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_H */ #endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_H */

View File

@ -49,13 +49,13 @@ static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789+/"; "0123456789+/";
static inline bool static inline bool
is_base64 (unsigned char c) is_base64(unsigned char c)
{ {
return (isalnum (c) || (c == '+') || (c == '/')); return (isalnum(c) || (c == '+') || (c == '/'));
} }
static std::string static std::string
base64_encode (unsigned char const *bytes_to_encode, unsigned int in_len) base64_encode(unsigned char const *bytes_to_encode, unsigned int in_len)
{ {
std::string ret; std::string ret;
int i = 0; int i = 0;
@ -73,15 +73,17 @@ base64_encode (unsigned char const *bytes_to_encode, unsigned int in_len)
+ ((char_array_3[2] & 0xc0) >> 6); + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f; char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++) for (i = 0; (i < 4); i++) {
ret += base64_chars[char_array_4[i]]; ret += base64_chars[char_array_4[i]];
}
i = 0; i = 0;
} }
} }
if (i) { if (i) {
for (j = i; j < 3; j++) for (j = i; j < 3; j++) {
char_array_3[j] = '\0'; char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) char_array_4[1] = ((char_array_3[0] & 0x03) << 4)
@ -89,11 +91,13 @@ base64_encode (unsigned char const *bytes_to_encode, unsigned int in_len)
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) char_array_4[2] = ((char_array_3[1] & 0x0f) << 2)
+ ((char_array_3[2] & 0xc0) >> 6); + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++) for (j = 0; (j < i + 1); j++) {
ret += base64_chars[char_array_4[j]]; ret += base64_chars[char_array_4[j]];
}
while ((i++ < 3)) while ((i++ < 3)) {
ret += '='; ret += '=';
}
} }
@ -102,9 +106,9 @@ base64_encode (unsigned char const *bytes_to_encode, unsigned int in_len)
} }
static std::string static std::string
base64_decode (std::string const &encoded_string) base64_decode(std::string const &encoded_string)
{ {
size_t in_len = encoded_string.size (); size_t in_len = encoded_string.size();
int i = 0; int i = 0;
int j = 0; int j = 0;
int in_ = 0; int in_ = 0;
@ -112,12 +116,13 @@ base64_decode (std::string const &encoded_string)
std::string ret; std::string ret;
while (in_len-- && (encoded_string[in_] != '=') while (in_len-- && (encoded_string[in_] != '=')
&& is_base64 (encoded_string[in_])) { && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; char_array_4[i++] = encoded_string[in_];
in_++; in_++;
if (i == 4) { if (i == 4) {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
char_array_4[i] = base64_chars.find (char_array_4[i]) & 0xff; char_array_4[i] = base64_chars.find(char_array_4[i]) & 0xff;
}
char_array_3[0] = (char_array_4[0] << 2) char_array_3[0] = (char_array_4[0] << 2)
+ ((char_array_4[1] & 0x30) >> 4); + ((char_array_4[1] & 0x30) >> 4);
@ -125,23 +130,26 @@ base64_decode (std::string const &encoded_string)
+ ((char_array_4[2] & 0x3c) >> 2); + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++) for (i = 0; (i < 3); i++) {
ret += char_array_3[i]; ret += char_array_3[i];
}
i = 0; i = 0;
} }
} }
if (i) { if (i) {
for (j = 0; j < i; j++) for (j = 0; j < i; j++) {
char_array_4[j] = base64_chars.find (char_array_4[j]) & 0xff; char_array_4[j] = base64_chars.find(char_array_4[j]) & 0xff;
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) char_array_3[1] = ((char_array_4[1] & 0xf) << 4)
+ ((char_array_4[2] & 0x3c) >> 2); + ((char_array_4[2] & 0x3c) >> 2);
for (j = 0; (j < i - 1); j++) for (j = 0; (j < i - 1); j++) {
ret += char_array_3[j]; ret += char_array_3[j];
} }
}
return ret; return ret;
} }

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block corrects the doppler effect between the ground * \brief This block corrects the doppler effect between the ground
* station and the satellite in a coarse and very simplified way. * station and the satellite in a coarse and very simplified way.
* Instead of changing the hardware center frequency, we use an NCO * Instead of changing the hardware center frequency, we use an NCO
@ -38,9 +36,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API coarse_doppler_correction_cc : virtual public gr::sync_block class SATNOGS_API coarse_doppler_correction_cc : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<coarse_doppler_correction_cc> sptr; typedef boost::shared_ptr<coarse_doppler_correction_cc> sptr;
/** /**
@ -53,10 +50,10 @@ namespace gr
* @param sampling_rate the sampling rate of the signal * @param sampling_rate the sampling rate of the signal
*/ */
static sptr static sptr
make (double target_freq, double sampling_rate); make(double target_freq, double sampling_rate);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_H */ #endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_H */

View File

@ -25,20 +25,17 @@
#include <vector> #include <vector>
#include <deque> #include <deque>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief <+description+> * \brief <+description+>
* *
*/ */
class SATNOGS_API convolutional_deinterleaver class SATNOGS_API convolutional_deinterleaver {
{
public: public:
convolutional_deinterleaver (size_t branches, size_t M); convolutional_deinterleaver(size_t branches, size_t M);
~convolutional_deinterleaver (); ~convolutional_deinterleaver();
uint8_t uint8_t
decode_bit(uint8_t b); decode_bit(uint8_t b);

View File

@ -23,17 +23,14 @@
#include <satnogs/api.h> #include <satnogs/api.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* CRC class providing a range of different CRC calculation static methods * CRC class providing a range of different CRC calculation static methods
* *
*/ */
class SATNOGS_API crc class SATNOGS_API crc {
{
public: public:
typedef enum crc_type { typedef enum crc_type {
PDU = 0, PDU = 0,

View File

@ -25,21 +25,18 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief CW encoder block, mainly for debugging and testing purposes. * \brief CW encoder block, mainly for debugging and testing purposes.
* It accepts a CW word via a message source port and transmits the * It accepts a CW word via a message source port and transmits the
* corresponding CW symbols. * corresponding CW symbols.
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API cw_encoder : virtual public gr::sync_block class SATNOGS_API cw_encoder : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<cw_encoder> sptr; typedef boost::shared_ptr<cw_encoder> sptr;
/*! /*!
@ -49,10 +46,10 @@ namespace gr
* @param wpm words per minute (WPM) * @param wpm words per minute (WPM)
*/ */
static sptr static sptr
make (double samp_rate, double cw_freq = 700, size_t wpm = 20); make(double samp_rate, double cw_freq = 700, size_t wpm = 20);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_CW_ENCODER_H */ #endif /* INCLUDED_SATNOGS_CW_ENCODER_H */

View File

@ -27,12 +27,10 @@
#define MIN_WPM 5 #define MIN_WPM 5
#define MAX_WPM 50 #define MAX_WPM 50
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief The CW to Symbol block tries to translate the input signal * \brief The CW to Symbol block tries to translate the input signal
* into Morse symbols. The input signal should have been already properly * into Morse symbols. The input signal should have been already properly
* filtered and processed. A possible DSP on the input signal may be the * filtered and processed. A possible DSP on the input signal may be the
@ -42,9 +40,8 @@ namespace gr
* *
* \ingroup satnogs * \ingroup satnogs
*/ */
class SATNOGS_API cw_to_symbol : virtual public gr::sync_block class SATNOGS_API cw_to_symbol : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<cw_to_symbol> sptr; typedef boost::shared_ptr<cw_to_symbol> sptr;
/*! /*!
@ -78,15 +75,15 @@ namespace gr
* If no such a filter is used, the hysteresis value should be set to zero. * If no such a filter is used, the hysteresis value should be set to zero.
*/ */
static cw_to_symbol::sptr static cw_to_symbol::sptr
make (double sampling_rate, float threshold, float conf_level = 0.9, make(double sampling_rate, float threshold, float conf_level = 0.9,
size_t wpm = 20, size_t wpm = 20,
size_t hysteresis = 0); size_t hysteresis = 0);
virtual void virtual void
set_act_threshold (float thrld) = 0; set_act_threshold(float thrld) = 0;
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_H */ #endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_H */

File diff suppressed because it is too large Load Diff

View File

@ -24,19 +24,16 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A block for debug reasons producing specific messages * \brief A block for debug reasons producing specific messages
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API debug_msg_source : virtual public gr::block class SATNOGS_API debug_msg_source : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<debug_msg_source> sptr; typedef boost::shared_ptr<debug_msg_source> sptr;
/** /**
@ -47,10 +44,10 @@ namespace gr
* \p delay seconds * \p delay seconds
*/ */
static sptr static sptr
make (const std::string &msg, double delay, bool repeat = true); make(const std::string &msg, double delay, bool repeat = true);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_H */ #endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_H */

View File

@ -24,21 +24,18 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A block for debug reasons producing specific messages. * \brief A block for debug reasons producing specific messages.
* The input message can be anything, opposed to the \p debug_msg_source() * The input message can be anything, opposed to the \p debug_msg_source()
* block that can accept only string messages. * block that can accept only string messages.
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API debug_msg_source_raw : virtual public gr::block class SATNOGS_API debug_msg_source_raw : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<debug_msg_source_raw> sptr; typedef boost::shared_ptr<debug_msg_source_raw> sptr;
/** /**
@ -49,10 +46,10 @@ namespace gr
* \p delay seconds * \p delay seconds
*/ */
static sptr static sptr
make (const std::vector<uint8_t> &msg, double delay, bool repeat); make(const std::vector<uint8_t> &msg, double delay, bool repeat);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_H */ #endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_H */

View File

@ -26,22 +26,19 @@
#include <cstdlib> #include <cstdlib>
#include <pmt/pmt.h> #include <pmt/pmt.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/** /**
* The status of the decoder * The status of the decoder
*/ */
class decoder_status class decoder_status {
{
public: public:
int consumed; /**< The number of input items consumed */ int consumed; /**< The number of input items consumed */
bool decode_success; /**< Indicated if there was a successful decoding */ bool decode_success; /**< Indicated if there was a successful decoding */
pmt::pmt_t data; /**< a dictionary with the PDU with of decoded data and the corresponding metadata for the decoded frame */ pmt::pmt_t data; /**< a dictionary with the PDU with of decoded data and the corresponding metadata for the decoded frame */
decoder_status () : decoder_status() :
consumed(0), consumed(0),
decode_success(false), decode_success(false),
data(pmt::make_dict()) data(pmt::make_dict())
@ -63,18 +60,17 @@ typedef class decoder_status decoder_status_t;
* appropriate decoder class that implements this abstract class API. * appropriate decoder class that implements this abstract class API.
* *
*/ */
class SATNOGS_API decoder class SATNOGS_API decoder {
{
public: public:
typedef boost::shared_ptr<decoder> decoder_sptr; typedef boost::shared_ptr<decoder> decoder_sptr;
static int base_unique_id; static int base_unique_id;
int int
unique_id (); unique_id();
decoder (int input_item_size, size_t max_frame_len = 8192); decoder(int input_item_size, size_t max_frame_len = 8192);
virtual ~decoder (); virtual ~decoder();
/** /**
* Decodes a buffer. The difference with the decoder::decode_once() is that * Decodes a buffer. The difference with the decoder::decode_once() is that
@ -95,7 +91,7 @@ public:
* If an error occurred an appropriate negative error code is returned * If an error occurred an appropriate negative error code is returned
*/ */
virtual decoder_status_t virtual decoder_status_t
decode (const void *in, int len) = 0; decode(const void *in, int len) = 0;
/** /**
@ -103,7 +99,7 @@ public:
* *
*/ */
virtual void virtual void
reset () = 0; reset() = 0;
size_t size_t
max_frame_len() const; max_frame_len() const;

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block corrects the doppler effect between the ground * \brief This block corrects the doppler effect between the ground
* station and the satellite. It takes the imput stream in baseband * station and the satellite. It takes the imput stream in baseband
* and applies proper corrections to keep the carrier at the desired * and applies proper corrections to keep the carrier at the desired
@ -39,9 +37,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API doppler_correction_cc : virtual public gr::sync_block class SATNOGS_API doppler_correction_cc : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<doppler_correction_cc> sptr; typedef boost::shared_ptr<doppler_correction_cc> sptr;
/*! /*!
@ -55,11 +52,11 @@ namespace gr
* that the block should perform * that the block should perform
*/ */
static sptr static sptr
make (double target_freq, double sampling_rate, make(double target_freq, double sampling_rate,
size_t corrections_per_sec = 1000); size_t corrections_per_sec = 1000);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H */ #endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H */

View File

@ -26,35 +26,32 @@
#include <deque> #include <deque>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Doppler frequency polynomial fitting tool * \brief Doppler frequency polynomial fitting tool
* \ingroup satnogs * \ingroup satnogs
*/ */
class SATNOGS_API doppler_fit class SATNOGS_API doppler_fit {
{ public:
public: doppler_fit(size_t degree);
doppler_fit (size_t degree);
void void
fit (std::deque<freq_drift> drifts); fit(std::deque<freq_drift> drifts);
void void
predict_freqs (double *freqs, size_t ncorrections, predict_freqs(double *freqs, size_t ncorrections,
size_t samples_per_correction); size_t samples_per_correction);
private: private:
const size_t d_degree; const size_t d_degree;
double d_last_x; double d_last_x;
std::vector<double> d_coeff; std::vector<double> d_coeff;
boost::mutex d_mutex; boost::mutex d_mutex;
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DOPPLER_FIT_H */ #endif /* INCLUDED_SATNOGS_DOPPLER_FIT_H */

View File

@ -25,10 +25,8 @@
#include <satnogs/whitening.h> #include <satnogs/whitening.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A generic frame acquisition block * \brief A generic frame acquisition block
@ -60,8 +58,7 @@ namespace satnogs
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API frame_acquisition : virtual public gr::sync_block class SATNOGS_API frame_acquisition : virtual public gr::sync_block {
{
public: public:
typedef boost::shared_ptr<frame_acquisition> sptr; typedef boost::shared_ptr<frame_acquisition> sptr;
@ -122,9 +119,9 @@ public:
*/ */
static sptr static sptr
make(variant_t variant, make(variant_t variant,
const std::vector<uint8_t>& preamble, const std::vector<uint8_t> &preamble,
size_t preamble_threshold, size_t preamble_threshold,
const std::vector<uint8_t>& sync, const std::vector<uint8_t> &sync,
size_t sync_threshold, size_t sync_threshold,
size_t frame_size_field_len, size_t frame_size_field_len,
size_t frame_len, size_t frame_len,

View File

@ -26,9 +26,9 @@
#include <satnogs/decoder.h> #include <satnogs/decoder.h>
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
/*! /*!
* \brief This is a generic frame decoder block. It takes as input a * \brief This is a generic frame decoder block. It takes as input a
* bit stream and produces decoded frames and their metadata. * bit stream and produces decoded frames and their metadata.
* *
@ -41,9 +41,8 @@ namespace gr {
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API frame_decoder : virtual public gr::sync_block class SATNOGS_API frame_decoder : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<frame_decoder> sptr; typedef boost::shared_ptr<frame_decoder> sptr;
/*! /*!
@ -51,9 +50,9 @@ namespace gr {
* @param decoder_object the decoder object to use * @param decoder_object the decoder object to use
*/ */
static sptr make(decoder::decoder_sptr decoder_object, int input_size); static sptr make(decoder::decoder_sptr decoder_object, int input_size);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FRAME_DECODER_H */ #endif /* INCLUDED_SATNOGS_FRAME_DECODER_H */

View File

@ -25,16 +25,15 @@
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
/*! /*!
* \brief <+description of block+> * \brief <+description of block+>
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API frame_encoder : virtual public gr::sync_block class SATNOGS_API frame_encoder : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<frame_encoder> sptr; typedef boost::shared_ptr<frame_encoder> sptr;
/*! /*!
@ -45,10 +44,10 @@ namespace gr {
* class. satnogs::frame_encoder::make is the public interface for * class. satnogs::frame_encoder::make is the public interface for
* creating new instances. * creating new instances.
*/ */
static sptr make(bool append_preamble, bool ecss_encap, const std::string& dest_addr, uint8_t dest_ssid, const std::string& src_addr, uint8_t src_ssid); static sptr make(bool append_preamble, bool ecss_encap, const std::string &dest_addr, uint8_t dest_ssid, const std::string &src_addr, uint8_t src_ssid);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FRAME_ENCODER_H */ #endif /* INCLUDED_SATNOGS_FRAME_ENCODER_H */

View File

@ -24,19 +24,16 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief <+description of block+> * \brief <+description of block+>
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API frame_file_sink : virtual public gr::block class SATNOGS_API frame_file_sink : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<frame_file_sink> sptr; typedef boost::shared_ptr<frame_file_sink> sptr;
/*! /*!
@ -45,10 +42,10 @@ namespace gr
* @param output_type Format type of the output file, txt, hex, bin * @param output_type Format type of the output file, txt, hex, bin
*/ */
static sptr static sptr
make (const std::string& prefix_name, int output_type); make(const std::string &prefix_name, int output_type);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_H */ #endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_H */

View File

@ -24,36 +24,33 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <stdint.h> #include <stdint.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Class that specifies the frequency drift at a given time. * \brief Class that specifies the frequency drift at a given time.
* The time is measured in samples. * The time is measured in samples.
* \ingroup satnogs * \ingroup satnogs
*/ */
class SATNOGS_API freq_drift class SATNOGS_API freq_drift {
{ public:
public: freq_drift(uint64_t x, double y);
freq_drift (uint64_t x, double y); ~freq_drift();
~freq_drift ();
double double
get_freq_drift () const; get_freq_drift() const;
void void
set_freq_drift (double freqDrift); set_freq_drift(double freqDrift);
uint64_t uint64_t
get_x () const; get_x() const;
void void
set_x (uint64_t x); set_x(uint64_t x);
private: private:
uint64_t d_x; uint64_t d_x;
double d_freq_drift; double d_freq_drift;
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FREQ_DRIFT_H */ #endif /* INCLUDED_SATNOGS_FREQ_DRIFT_H */

View File

@ -27,10 +27,8 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A binary Golay (24,12,8) encoder and decoder. * \brief A binary Golay (24,12,8) encoder and decoder.
@ -42,11 +40,10 @@ namespace satnogs
* John Wiley & Sons, 2006. * John Wiley & Sons, 2006.
* *
*/ */
class SATNOGS_API golay24 class SATNOGS_API golay24 {
{
public: public:
golay24 (); golay24();
~golay24 (); ~golay24();
static const std::vector<uint32_t> G_P; static const std::vector<uint32_t> G_P;
static const std::vector<uint32_t> G_I; static const std::vector<uint32_t> G_I;

View File

@ -25,10 +25,8 @@
#include <satnogs/whitening.h> #include <satnogs/whitening.h>
#include <satnogs/crc.h> #include <satnogs/crc.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A IEEE 802.15.4 like decoder * \brief A IEEE 802.15.4 like decoder
@ -40,15 +38,14 @@ namespace satnogs
* scheme. * scheme.
* *
*/ */
class SATNOGS_API ieee802_15_4_variant_decoder class SATNOGS_API ieee802_15_4_variant_decoder {
{
public: public:
ieee802_15_4_variant_decoder (const std::vector<uint8_t> &preamble, ieee802_15_4_variant_decoder(const std::vector<uint8_t> &preamble,
size_t preamble_threshold, size_t preamble_threshold,
const std::vector<uint8_t> &sync, const std::vector<uint8_t> &sync,
crc::crc_t crc, crc::crc_t crc,
whitening::whitening_sptr descrambler); whitening::whitening_sptr descrambler);
~ieee802_15_4_variant_decoder (); ~ieee802_15_4_variant_decoder();
private: private:
}; };

View File

@ -25,12 +25,10 @@
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
#include <gnuradio/blocks/file_sink_base.h> #include <gnuradio/blocks/file_sink_base.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block converts a complex float input stream to short and stores * \brief This block converts a complex float input stream to short and stores
* it to a file. If the value of status argument is zero the block behaves * it to a file. If the value of status argument is zero the block behaves
* as a null sink block. * as a null sink block.
@ -38,10 +36,9 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API iq_sink : virtual public gr::sync_block, class SATNOGS_API iq_sink : virtual public gr::sync_block,
virtual public gr::blocks::file_sink_base virtual public gr::blocks::file_sink_base {
{ public:
public:
typedef boost::shared_ptr<iq_sink> sptr; typedef boost::shared_ptr<iq_sink> sptr;
/** /**
@ -60,12 +57,12 @@ namespace gr
* @return a shared_ptr to a new instance of satnogs::iq_sink. * @return a shared_ptr to a new instance of satnogs::iq_sink.
*/ */
static sptr make(const float scale, static sptr make(const float scale,
const char *filename, bool append=false, const char *filename, bool append = false,
const int status = 0); const int status = 0);
}; };
} }
// namespace satnogs // namespace satnogs
}// namespace gr }// namespace gr
#endif /* INCLUDED_SATNOGS_IQ_SINK_H */ #endif /* INCLUDED_SATNOGS_IQ_SINK_H */

View File

@ -24,10 +24,8 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
#include <string> #include <string>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block takes a PMT message from the SatNOGS decoders * \brief This block takes a PMT message from the SatNOGS decoders
@ -36,8 +34,7 @@ namespace satnogs
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API json_converter : virtual public gr::block class SATNOGS_API json_converter : virtual public gr::block {
{
public: public:
typedef boost::shared_ptr<json_converter> sptr; typedef boost::shared_ptr<json_converter> sptr;
@ -53,7 +50,7 @@ public:
* @return shared pointer of the block instance * @return shared pointer of the block instance
*/ */
static sptr static sptr
make (const std::string& extra = ""); make(const std::string &extra = "");
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -24,18 +24,15 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief <+description of block+> * \brief <+description of block+>
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API lrpt_decoder : virtual public gr::block class SATNOGS_API lrpt_decoder : virtual public gr::block {
{
public: public:
typedef boost::shared_ptr<lrpt_decoder> sptr; typedef boost::shared_ptr<lrpt_decoder> sptr;
@ -48,7 +45,7 @@ public:
* creating new instances. * creating new instances.
*/ */
static sptr static sptr
make (); make();
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -24,18 +24,15 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief <+description of block+> * \brief <+description of block+>
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API lrpt_sync : virtual public gr::sync_block class SATNOGS_API lrpt_sync : virtual public gr::sync_block {
{
public: public:
typedef boost::shared_ptr<lrpt_sync> sptr; typedef boost::shared_ptr<lrpt_sync> sptr;
@ -48,7 +45,7 @@ public:
* creating new instances. * creating new instances.
*/ */
static sptr static sptr
make (size_t threshold = 2); make(size_t threshold = 2);
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -32,10 +32,9 @@ namespace gr {
namespace satnogs { namespace satnogs {
class SATNOGS_API metadata class SATNOGS_API metadata {
{
public: public:
typedef enum key{ typedef enum key {
PDU = 0, PDU = 0,
CRC_VALID, CRC_VALID,
FREQ_OFFSET, FREQ_OFFSET,
@ -48,7 +47,7 @@ public:
} key_t; } key_t;
static std::string static std::string
value(const key_t& k); value(const key_t &k);
static std::string static std::string
keys(); keys();
@ -78,7 +77,7 @@ public:
add_corrected_bits(pmt::pmt_t &m, uint32_t cnt); add_corrected_bits(pmt::pmt_t &m, uint32_t cnt);
static Json::Value static Json::Value
to_json(const pmt::pmt_t& m); to_json(const pmt::pmt_t &m);
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -25,21 +25,18 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief A Morse debug source block that supports injection of random * \brief A Morse debug source block that supports injection of random
* errors based on a Bernulli distribution with probability p. * errors based on a Bernulli distribution with probability p.
* *
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API morse_debug_source : virtual public gr::block class SATNOGS_API morse_debug_source : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<morse_debug_source> sptr; typedef boost::shared_ptr<morse_debug_source> sptr;
/*! /*!
@ -58,14 +55,14 @@ namespace gr
* dot durations. * dot durations.
*/ */
static sptr static sptr
make (const size_t wpm, make(const size_t wpm,
const std::string& debug_seq, const std::string &debug_seq,
bool inject_errors = false, bool inject_errors = false,
float error_prob = 0.1, float error_prob = 0.1,
size_t seq_pause_ms = 1000); size_t seq_pause_ms = 1000);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_H */ #endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_H */

View File

@ -25,16 +25,15 @@
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
/*! /*!
* \brief Morse code decoder block. * \brief Morse code decoder block.
* *
* This block received messages from the previous blocks * This block received messages from the previous blocks
* and try to decode the dot and dashes into clear text. * and try to decode the dot and dashes into clear text.
*/ */
class SATNOGS_API morse_decoder : virtual public gr::block class SATNOGS_API morse_decoder : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<morse_decoder> sptr; typedef boost::shared_ptr<morse_decoder> sptr;
/*! /*!
@ -46,9 +45,9 @@ namespace gr {
* false alarms * false alarms
*/ */
static sptr make(char unrecognized_char = '#', size_t min_frame_len = 3); static sptr make(char unrecognized_char = '#', size_t min_frame_len = 3);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_MORSE_DECODER_H */ #endif /* INCLUDED_SATNOGS_MORSE_DECODER_H */

View File

@ -26,41 +26,38 @@
#include <string> #include <string>
#include <satnogs/morse.h> #include <satnogs/morse.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Binary tree node containing the corresponding character * \brief Binary tree node containing the corresponding character
*/ */
class SATNOGS_API tree_node class SATNOGS_API tree_node {
{ private:
private:
const char d_char; const char d_char;
tree_node *d_left; tree_node *d_left;
tree_node *d_right; tree_node *d_right;
public: public:
tree_node (char c); tree_node(char c);
void void
set_left_child (tree_node *child); set_left_child(tree_node *child);
void void
set_right_child (tree_node *child); set_right_child(tree_node *child);
tree_node* tree_node *
get_left_child (); get_left_child();
tree_node* tree_node *
get_right_child (); get_right_child();
char char
get_char (); get_char();
}; };
/*! /*!
* \brief A Binary tree representation of the Morse coding scheme. * \brief A Binary tree representation of the Morse coding scheme.
* Left transitions occur when a dot is received, whereas right transitions * Left transitions occur when a dot is received, whereas right transitions
* are performed during the reception of a dash. * are performed during the reception of a dash.
@ -68,24 +65,23 @@ namespace gr
* The tree follows the ITU International Morse code representation * The tree follows the ITU International Morse code representation
* ITU-R M.1677-1 * ITU-R M.1677-1
*/ */
class SATNOGS_API morse_tree class SATNOGS_API morse_tree {
{ public:
public: morse_tree();
morse_tree (); morse_tree(char unrecognized);
morse_tree (char unrecognized); ~morse_tree();
~morse_tree ();
void void
reset (); reset();
bool bool
received_symbol (morse_symbol_t s); received_symbol(morse_symbol_t s);
std::string std::string
get_word (); get_word();
size_t size_t
get_max_word_len () const; get_max_word_len() const;
size_t size_t
get_word_len (); get_word_len();
private: private:
const char d_unrecognized_symbol; const char d_unrecognized_symbol;
tree_node *d_root; tree_node *d_root;
tree_node *d_current; tree_node *d_current;
@ -94,12 +90,12 @@ namespace gr
std::unique_ptr<char[]> d_word_buffer; std::unique_ptr<char[]> d_word_buffer;
void void
construct_tree (); construct_tree();
void void
delete_tree (tree_node *node); delete_tree(tree_node *node);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_MORSE_TREE_H */ #endif /* INCLUDED_SATNOGS_MORSE_TREE_H */

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Block accepting clear text messages from various decoders. * \brief Block accepting clear text messages from various decoders.
* Its purpose is to forward these messages at other services, programs, * Its purpose is to forward these messages at other services, programs,
* stdout, etc, * stdout, etc,
@ -37,9 +35,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API multi_format_msg_sink : virtual public gr::block class SATNOGS_API multi_format_msg_sink : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<multi_format_msg_sink> sptr; typedef boost::shared_ptr<multi_format_msg_sink> sptr;
/*! /*!
@ -59,12 +56,12 @@ namespace gr
* @param filepath specifies the file path of the text file * @param filepath specifies the file path of the text file
*/ */
static sptr static sptr
make (size_t format, bool timestamp = true, make(size_t format, bool timestamp = true,
bool out_stdout = true, bool out_stdout = true,
const std::string& filepath = ""); const std::string &filepath = "");
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_H */ #endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_H */

View File

@ -24,19 +24,16 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* Sink block for NOAA satellites * Sink block for NOAA satellites
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API noaa_apt_sink : virtual public gr::sync_block class SATNOGS_API noaa_apt_sink : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<noaa_apt_sink> sptr; typedef boost::shared_ptr<noaa_apt_sink> sptr;
/*! /*!
@ -66,11 +63,11 @@ namespace gr
* *
*/ */
static sptr static sptr
make (const char *filename_png, size_t width, size_t height, make(const char *filename_png, size_t width, size_t height,
bool sync, bool flip); bool sync, bool flip);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_H */ #endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_H */

View File

@ -24,19 +24,16 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Ogg encoder and sink block * \brief Ogg encoder and sink block
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API ogg_encoder : virtual public gr::sync_block class SATNOGS_API ogg_encoder : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<ogg_encoder> sptr; typedef boost::shared_ptr<ogg_encoder> sptr;
/*! /*!
@ -46,10 +43,10 @@ namespace gr
* @param quality the quality of the output file. [0.1 - 1.0] (worst - best) * @param quality the quality of the output file. [0.1 - 1.0] (worst - best)
*/ */
static sptr static sptr
make (char* filename, double samp_rate, float quality); make(char *filename, double samp_rate, float quality);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_OGG_ENCODER_H */ #endif /* INCLUDED_SATNOGS_OGG_ENCODER_H */

View File

@ -24,21 +24,18 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief OGG source block. Reads a file with an OGG audio and * \brief OGG source block. Reads a file with an OGG audio and
* convert it to float samples * convert it to float samples
* *
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API ogg_source : virtual public gr::sync_block class SATNOGS_API ogg_source : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<ogg_source> sptr; typedef boost::shared_ptr<ogg_source> sptr;
/*! /*!
@ -51,11 +48,11 @@ namespace gr
* will continue to output samples from the beginning of the OGG file. * will continue to output samples from the beginning of the OGG file.
*/ */
static sptr static sptr
make (const std::string& filename, int channels = 1, make(const std::string &filename, int channels = 1,
bool repeat = false); bool repeat = false);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_OGG_SOURCE_H */ #endif /* INCLUDED_SATNOGS_OGG_SOURCE_H */

View File

@ -24,20 +24,17 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Parses the received AX.25 and separates the * \brief Parses the received AX.25 and separates the
* telecommand and control frames from the WOD frames. * telecommand and control frames from the WOD frames.
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API qb50_deframer : virtual public gr::block class SATNOGS_API qb50_deframer : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<qb50_deframer> sptr; typedef boost::shared_ptr<qb50_deframer> sptr;
/*! /*!
@ -47,10 +44,10 @@ namespace gr
* @param wod_ssid the SSID that separates the WOD frames from the others * @param wod_ssid the SSID that separates the WOD frames from the others
*/ */
static sptr static sptr
make (uint8_t wod_ssid); make(uint8_t wod_ssid);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_QB50_DEFRAMER_H */ #endif /* INCLUDED_SATNOGS_QB50_DEFRAMER_H */

View File

@ -25,20 +25,17 @@
#include <deque> #include <deque>
#include <ostream> #include <ostream>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Implements a bit shift register * \brief Implements a bit shift register
* *
*/ */
class SATNOGS_API shift_reg class SATNOGS_API shift_reg {
{
public: public:
shift_reg (size_t len); shift_reg(size_t len);
~shift_reg (); ~shift_reg();
void void
reset(); reset();
@ -56,24 +53,24 @@ public:
count(); count();
shift_reg shift_reg
operator|(const shift_reg& rhs); operator|(const shift_reg &rhs);
shift_reg shift_reg
operator&(const shift_reg& rhs); operator&(const shift_reg &rhs);
shift_reg shift_reg
operator^(const shift_reg& rhs); operator^(const shift_reg &rhs);
shift_reg& shift_reg &
operator>>=(bool bit); operator>>=(bool bit);
bool& bool &
operator[](size_t pos); operator[](size_t pos);
bool bool
operator[](size_t pos) const; operator[](size_t pos) const;
shift_reg& shift_reg &
operator<<=(bool bit); operator<<=(bool bit);
void void
@ -88,8 +85,8 @@ public:
bool bool
back(); back();
friend std::ostream& friend std::ostream &
operator<<(std::ostream& os, const shift_reg& reg); operator<<(std::ostream &os, const shift_reg &reg);
private: private:
const size_t d_len; const size_t d_len;

View File

@ -119,20 +119,17 @@
#define TURN_ON 1 #define TURN_ON 1
#define RESET 2 #define RESET 2
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs /*!
{
/*!
* \brief Telemetry and telecommands packet methods * \brief Telemetry and telecommands packet methods
* \ingroup satnogs * \ingroup satnogs
*/ */
/*! /*!
* Return status codes * Return status codes
*/ */
typedef enum typedef enum {
{
R_OBC_PKT_ILLEGAL_APPID = 0, //!< R_OBC_PKT_ILLEGAL_APPID illegal application ID R_OBC_PKT_ILLEGAL_APPID = 0, //!< R_OBC_PKT_ILLEGAL_APPID illegal application ID
R_OBC_PKT_INV_LEN = 1, //!< R_OBC_PKT_INV_LEN invalid length R_OBC_PKT_INV_LEN = 1, //!< R_OBC_PKT_INV_LEN invalid length
R_OBC_PKT_INC_CRC = 2, //!< R_OBC_PKT_INC_CRC incorrect CRC R_OBC_PKT_INC_CRC = 2, //!< R_OBC_PKT_INC_CRC incorrect CRC
@ -142,17 +139,15 @@ namespace gr
R_OBC_OK = 6, //!< R_OBC_OK All ok R_OBC_OK = 6, //!< R_OBC_OK All ok
R_OBC_ERROR = 7, //!< R_OBC_ERROR an error occured R_OBC_ERROR = 7, //!< R_OBC_ERROR an error occured
R_OBC_EOT = 8, //!< R_OBC_EOT End-of-transfer R_OBC_EOT = 8, //!< R_OBC_EOT End-of-transfer
} OBC_ret_state_t; } OBC_ret_state_t;
union _cnv union _cnv {
{
uint32_t cnv32; uint32_t cnv32;
uint16_t cnv16[2]; uint16_t cnv16[2];
uint8_t cnv8[4]; uint8_t cnv8[4];
}; };
typedef struct typedef struct {
{
/* packet id */ /* packet id */
uint8_t ver; /* 3 bits, should be equal to 0 */ uint8_t ver; /* 3 bits, should be equal to 0 */
uint8_t data_field_hdr; /* 1 bit, data_field_hdr exists in data = 1 */ uint8_t data_field_hdr; /* 1 bit, data_field_hdr exists in data = 1 */
@ -177,41 +172,41 @@ namespace gr
uint8_t padding; /* x bits, padding for word alligment */ uint8_t padding; /* x bits, padding for word alligment */
uint16_t crc; /* CRC or checksum, mission specific*/ uint16_t crc; /* CRC or checksum, mission specific*/
} tc_tm_pkt; } tc_tm_pkt;
const uint8_t services_verification_TC_TM[MAX_SERVICES][MAX_SUBTYPES][2]; const uint8_t services_verification_TC_TM[MAX_SERVICES][MAX_SUBTYPES][2];
const uint8_t app_id_verification[MAX_APP_ID]; const uint8_t app_id_verification[MAX_APP_ID];
const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES]; const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES];
extern OBC_ret_state_t extern OBC_ret_state_t
verification_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, verification_pack_pkt_api(uint8_t *buf, tc_tm_pkt *pkt,
uint16_t *buf_pointer); uint16_t *buf_pointer);
extern OBC_ret_state_t extern OBC_ret_state_t
hk_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer); hk_pack_pkt_api(uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer);
static inline uint8_t static inline uint8_t
ecss_tm_checksum (const uint8_t *data, uint16_t size) ecss_tm_checksum(const uint8_t *data, uint16_t size)
{ {
uint8_t CRC = 0; uint8_t CRC = 0;
for (int i = 0; i <= size; i++) { for (int i = 0; i <= size; i++) {
CRC = CRC ^ data[i]; CRC = CRC ^ data[i];
} }
return CRC; return CRC;
} }
/*Must check for endianess*/ /*Must check for endianess*/
static inline OBC_ret_state_t static inline OBC_ret_state_t
ecss_tm_unpack_pkt (const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size) ecss_tm_unpack_pkt(const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size)
{ {
union _cnv cnv; union _cnv cnv;
uint8_t tmp_crc[2]; uint8_t tmp_crc[2];
uint8_t ver, dfield_hdr, ccsds_sec_hdr, tc_pus; uint8_t ver, dfield_hdr, ccsds_sec_hdr, tc_pus;
tmp_crc[0] = buf[size - 1]; tmp_crc[0] = buf[size - 1];
tmp_crc[1] = ecss_tm_checksum (buf, size - 2); tmp_crc[1] = ecss_tm_checksum(buf, size - 2);
ver = buf[0] >> 5; ver = buf[0] >> 5;
@ -289,25 +284,25 @@ namespace gr
} }
return R_OBC_OK; return R_OBC_OK;
} }
/** /**
* Packs a TC packet into a byte buffer * Packs a TC packet into a byte buffer
* @param buf buffer to store the data to be sent * @param buf buffer to store the data to be sent
* @param pkt the data to be stored in the buffer * @param pkt the data to be stored in the buffer
* @param size size of the array * @param size size of the array
* @return appropriate error code or R_OBC_OK if all operation succeed * @return appropriate error code or R_OBC_OK if all operation succeed
*/ */
static inline OBC_ret_state_t static inline OBC_ret_state_t
ecss_tm_pack_pkt (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size) ecss_tm_pack_pkt(uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size)
{ {
union _cnv cnv; union _cnv cnv;
uint8_t buf_pointer; uint8_t buf_pointer;
cnv.cnv16[0] = pkt->app_id; cnv.cnv16[0] = pkt->app_id;
buf[0] = ( ECSS_VER_NUMBER << 5 | pkt->type << 4 buf[0] = (ECSS_VER_NUMBER << 5 | pkt->type << 4
| ECSS_DATA_FIELD_HDR_FLG << 3 | cnv.cnv8[1]); | ECSS_DATA_FIELD_HDR_FLG << 3 | cnv.cnv8[1]);
buf[1] = cnv.cnv8[0]; buf[1] = cnv.cnv8[0];
@ -320,7 +315,7 @@ namespace gr
buf[6] = ECSS_PUS_VER << 4; buf[6] = ECSS_PUS_VER << 4;
} }
else if (pkt->type == TC) { else if (pkt->type == TC) {
buf[6] = ( ECSS_SEC_HDR_FIELD_FLG << 7 | ECSS_PUS_VER << 4 | pkt->ack); buf[6] = (ECSS_SEC_HDR_FIELD_FLG << 7 | ECSS_PUS_VER << 4 | pkt->ack);
} }
else { else {
return R_OBC_ERROR; return R_OBC_ERROR;
@ -366,15 +361,15 @@ namespace gr
buf[4] = cnv.cnv8[0]; buf[4] = cnv.cnv8[0];
buf[5] = cnv.cnv8[1]; buf[5] = cnv.cnv8[1];
buf[buf_pointer] = ecss_tm_checksum (buf, buf_pointer - 1); buf[buf_pointer] = ecss_tm_checksum(buf, buf_pointer - 1);
*size = buf_pointer; *size = buf_pointer;
return R_OBC_OK; return R_OBC_OK;
} }
static inline OBC_ret_state_t static inline OBC_ret_state_t
ecss_tm_crt_pkt (tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack, ecss_tm_crt_pkt(tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack,
uint8_t ser_type, uint8_t ser_subtype, uint16_t dest_id) uint8_t ser_type, uint8_t ser_subtype, uint16_t dest_id)
{ {
pkt->type = type; pkt->type = type;
pkt->app_id = app_id; pkt->app_id = app_id;
@ -384,9 +379,9 @@ namespace gr
pkt->ser_subtype = ser_subtype; pkt->ser_subtype = ser_subtype;
return R_OBC_OK; return R_OBC_OK;
} }
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_TC_TM_H */ #endif /* INCLUDED_SATNOGS_TC_TM_H */

View File

@ -24,21 +24,18 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Block that accepts TCP messages with rigctl commands. Depending * \brief Block that accepts TCP messages with rigctl commands. Depending
* the command contents this block produces an appropriate PMT message * the command contents this block produces an appropriate PMT message
* to control other blocks in the flowgraph * to control other blocks in the flowgraph
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API tcp_rigctl_msg_source : virtual public gr::block class SATNOGS_API tcp_rigctl_msg_source : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<tcp_rigctl_msg_source> sptr; typedef boost::shared_ptr<tcp_rigctl_msg_source> sptr;
@ -55,11 +52,11 @@ namespace gr
* @return shared pointer of the block * @return shared pointer of the block
*/ */
static sptr static sptr
make (const std::string& addr, uint16_t port, bool server_mode, make(const std::string &addr, uint16_t port, bool server_mode,
size_t interval_ms = 1000, size_t mtu = 1500); size_t interval_ms = 1000, size_t mtu = 1500);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H */ #endif /* INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H */

View File

@ -25,16 +25,15 @@
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
/*! /*!
* \brief <+description of block+> * \brief <+description of block+>
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API udp_msg_sink : virtual public gr::block class SATNOGS_API udp_msg_sink : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<udp_msg_sink> sptr; typedef boost::shared_ptr<udp_msg_sink> sptr;
@ -44,10 +43,10 @@ namespace gr {
* @param port the destination UDP port * @param port the destination UDP port
* @param mtu the maximum MTU * @param mtu the maximum MTU
*/ */
static sptr make(const std::string& addr, uint16_t port, size_t mtu); static sptr make(const std::string &addr, uint16_t port, size_t mtu);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_UDP_MSG_SINK_H */ #endif /* INCLUDED_SATNOGS_UDP_MSG_SINK_H */

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/block.h> #include <gnuradio/block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief UDP message/command accepter. * \brief UDP message/command accepter.
* *
* This block received UDP messages from localhost or other network hosts * This block received UDP messages from localhost or other network hosts
@ -38,9 +36,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API udp_msg_source : virtual public gr::block class SATNOGS_API udp_msg_source : virtual public gr::block {
{ public:
public:
typedef boost::shared_ptr<udp_msg_source> sptr; typedef boost::shared_ptr<udp_msg_source> sptr;
/** /**
@ -52,11 +49,11 @@ namespace gr
* bytes, 1 to 32-bit signed integers and 2 to 3 bit unsigned integers. * bytes, 1 to 32-bit signed integers and 2 to 3 bit unsigned integers.
*/ */
static sptr static sptr
make (const std::string& addr, uint16_t port, size_t mtu = 1500, make(const std::string &addr, uint16_t port, size_t mtu = 1500,
size_t type = 0); size_t type = 0);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_UDP_MSG_SOURCE_H */ #endif /* INCLUDED_SATNOGS_UDP_MSG_SOURCE_H */

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block implements a FSK frame encoder for the UPSAT satellite. * \brief This block implements a FSK frame encoder for the UPSAT satellite.
* It takes as input a message containing the PDU and performs the NRZ * It takes as input a message containing the PDU and performs the NRZ
* encoding. The resulting float samples can be passed from a FM modulation * encoding. The resulting float samples can be passed from a FM modulation
@ -38,9 +36,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API upsat_fsk_frame_encoder : virtual public gr::sync_block class SATNOGS_API upsat_fsk_frame_encoder : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<upsat_fsk_frame_encoder> sptr; typedef boost::shared_ptr<upsat_fsk_frame_encoder> sptr;
/*! /*!
@ -84,15 +81,15 @@ namespace gr
* *
*/ */
static sptr static sptr
make (const std::vector<uint8_t>& preamble, make(const std::vector<uint8_t> &preamble,
const std::vector<uint8_t>& sync_word, bool append_crc, const std::vector<uint8_t> &sync_word, bool append_crc,
bool whitening, bool manchester, bool msb_first, bool ax25_format, bool whitening, bool manchester, bool msb_first, bool ax25_format,
const std::string& ax25_dest_addr, uint8_t ax25_dest_ssid, const std::string &ax25_dest_addr, uint8_t ax25_dest_ssid,
const std::string& ax25_src_addr, uint8_t ax25_src_ssid, const std::string &ax25_src_addr, uint8_t ax25_src_ssid,
size_t settling_samples); size_t settling_samples);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ENCODER_H */ #endif /* INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ENCODER_H */

View File

@ -25,11 +25,9 @@
#include <cmath> #include <cmath>
#include <arpa/inet.h> #include <arpa/inet.h>
namespace gr namespace gr {
{
namespace satnogs namespace satnogs {
{
#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
@ -40,16 +38,16 @@ namespace satnogs
* @return the mean absolute percentage error * @return the mean absolute percentage error
*/ */
static inline double static inline double
mape (double ref, double estimation) mape(double ref, double estimation)
{ {
return std::abs (ref - estimation) / ref; return std::abs(ref - estimation) / ref;
} }
/** /**
* Counts the number of active bits in x * Counts the number of active bits in x
*/ */
static inline unsigned int static inline unsigned int
bit_count (unsigned int x) bit_count(unsigned int x)
{ {
/* /*
* Some more magic from * Some more magic from
@ -60,8 +58,8 @@ bit_count (unsigned int x)
return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
} }
static const uint8_t _bytes_reversed[256] = static const uint8_t _bytes_reversed[256] = {
{ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68,
0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84,
0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34,
@ -84,20 +82,21 @@ static const uint8_t _bytes_reversed[256] =
0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F,
0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF,
0x7F, 0xFF }; 0x7F, 0xFF
};
/** /**
* Reverse the bits of the byte b. * Reverse the bits of the byte b.
* @param b the byte to be mirrored. * @param b the byte to be mirrored.
*/ */
static inline uint8_t static inline uint8_t
reverse_byte (uint8_t b) reverse_byte(uint8_t b)
{ {
return _bytes_reversed[b]; return _bytes_reversed[b];
} }
static inline uint32_t static inline uint32_t
reverse_uint32_bytes (uint32_t i) reverse_uint32_bytes(uint32_t i)
{ {
return (_bytes_reversed[i & 0xff] << 24) return (_bytes_reversed[i & 0xff] << 24)
| (_bytes_reversed[(i >> 8) & 0xff] << 16) | (_bytes_reversed[(i >> 8) & 0xff] << 16)
@ -106,7 +105,7 @@ reverse_uint32_bytes (uint32_t i)
} }
static inline uint64_t static inline uint64_t
reverse_uint64_bytes (uint64_t x) reverse_uint64_bytes(uint64_t x)
{ {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32; x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
@ -124,10 +123,10 @@ reverse_uint64_bytes (uint64_t x)
* @return the CRC-32 result * @return the CRC-32 result
*/ */
static inline uint32_t static inline uint32_t
update_crc32 (uint32_t crc, const uint8_t *data, size_t len) update_crc32(uint32_t crc, const uint8_t *data, size_t len)
{ {
static const uint32_t crc32_lut[256] = static const uint32_t crc32_lut[256] = {
{ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L,
0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L,
0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L,
0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
@ -178,7 +177,8 @@ update_crc32 (uint32_t crc, const uint8_t *data, size_t len)
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L, 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L,
0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L,
0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL,
0x2D02EF8DL }; 0x2D02EF8DL
};
register uint32_t i; register uint32_t i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
@ -194,9 +194,9 @@ update_crc32 (uint32_t crc, const uint8_t *data, size_t len)
* @return the CRC-32 of the buffer * @return the CRC-32 of the buffer
*/ */
static inline uint32_t static inline uint32_t
crc32 (const uint8_t *buf, size_t len) crc32(const uint8_t *buf, size_t len)
{ {
unsigned int crc = update_crc32 (0xffffffff, buf, len) ^ 0xffffffff; unsigned int crc = update_crc32(0xffffffff, buf, len) ^ 0xffffffff;
return crc; return crc;
} }

View File

@ -24,12 +24,10 @@
#include <satnogs/api.h> #include <satnogs/api.h>
#include <gnuradio/sync_block.h> #include <gnuradio/sync_block.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief This block computes the waterfall of the incoming signal * \brief This block computes the waterfall of the incoming signal
* and stores the result to a file. * and stores the result to a file.
* *
@ -39,9 +37,8 @@ namespace gr
* \ingroup satnogs * \ingroup satnogs
* *
*/ */
class SATNOGS_API waterfall_sink : virtual public gr::sync_block class SATNOGS_API waterfall_sink : virtual public gr::sync_block {
{ public:
public:
typedef boost::shared_ptr<waterfall_sink> sptr; typedef boost::shared_ptr<waterfall_sink> sptr;
/** /**
@ -65,12 +62,12 @@ namespace gr
* @return shared pointer to the object * @return shared pointer to the object
*/ */
static sptr static sptr
make (double samp_rate, double center_freq, make(double samp_rate, double center_freq,
double pps, size_t fft_size, double pps, size_t fft_size,
const std::string& filename, int mode = 0); const std::string &filename, int mode = 0);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_WATERFALL_SINK_H */ #endif /* INCLUDED_SATNOGS_WATERFALL_SINK_H */

View File

@ -25,44 +25,41 @@
#include <gnuradio/digital/lfsr.h> #include <gnuradio/digital/lfsr.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* \brief Performs data whitening and de-whitening * \brief Performs data whitening and de-whitening
* *
*/ */
class SATNOGS_API whitening class SATNOGS_API whitening {
{
public: public:
static int base_unique_id; static int base_unique_id;
int int
unique_id (); unique_id();
typedef boost::shared_ptr<whitening> whitening_sptr; typedef boost::shared_ptr<whitening> whitening_sptr;
static whitening_sptr static whitening_sptr
make(uint32_t mask, uint32_t seed, uint32_t order); make(uint32_t mask, uint32_t seed, uint32_t order);
whitening (uint32_t mask, uint32_t seed, uint32_t order); whitening(uint32_t mask, uint32_t seed, uint32_t order);
~whitening(); ~whitening();
void void
reset (); reset();
void void
scramble (uint8_t *out, const uint8_t *in, size_t len, bool msb = false); scramble(uint8_t *out, const uint8_t *in, size_t len, bool msb = false);
void void
descramble (uint8_t *out, const uint8_t *in, size_t len, bool msb = false); descramble(uint8_t *out, const uint8_t *in, size_t len, bool msb = false);
void void
scramble_one_bit_per_byte (uint8_t *out, const uint8_t *in, size_t bits_num); scramble_one_bit_per_byte(uint8_t *out, const uint8_t *in, size_t bits_num);
void void
descramble_one_bit_per_byte (uint8_t *out, const uint8_t *in, descramble_one_bit_per_byte(uint8_t *out, const uint8_t *in,
size_t bits_num); size_t bits_num);
private: private:

View File

@ -31,10 +31,8 @@ extern "C" {
#include <fec.h> #include <fec.h>
} }
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/** /**
* Actual frame size without RS padding and parity. * Actual frame size without RS padding and parity.
@ -42,14 +40,13 @@ namespace satnogs
*/ */
const size_t amsat_duv_decoder::amsat_fox_duv_frame_size = 6 + 58; const size_t amsat_duv_decoder::amsat_fox_duv_frame_size = 6 + 58;
const uint8_t amsat_duv_decoder::amsat_fox_spacecraft_id[] const uint8_t amsat_duv_decoder::amsat_fox_spacecraft_id[] {
{
0x1 /* FOX-1A */, 0x1 /* FOX-1A */,
0x2 /* FOX-1B */, 0x2 /* FOX-1B */,
0x3 /* FOX-1C */, 0x3 /* FOX-1C */,
0x4 /* FOX-1D */, 0x4 /* FOX-1D */,
0x5 /* FOX-1E */ 0x5 /* FOX-1E */
}; };
/** /**
* Creates a shared pointer to a amsat_duv_decoder object * Creates a shared pointer to a amsat_duv_decoder object
@ -58,11 +55,11 @@ const uint8_t amsat_duv_decoder::amsat_fox_spacecraft_id[]
* @return a shared pointer to a amsat_duv_decoder object * @return a shared pointer to a amsat_duv_decoder object
*/ */
decoder::decoder_sptr decoder::decoder_sptr
amsat_duv_decoder::make (const std::string &control_symbol, amsat_duv_decoder::make(const std::string &control_symbol,
size_t max_frame_len) size_t max_frame_len)
{ {
return decoder::decoder_sptr ( return decoder::decoder_sptr(
new amsat_duv_decoder (control_symbol, max_frame_len)); new amsat_duv_decoder(control_symbol, max_frame_len));
} }
/** /**
@ -71,33 +68,33 @@ amsat_duv_decoder::make (const std::string &control_symbol,
* @param control_symbol the control symbol indicating the start of a frame * @param control_symbol the control symbol indicating the start of a frame
* @param max_frame_len the maximum frame length * @param max_frame_len the maximum frame length
*/ */
amsat_duv_decoder::amsat_duv_decoder (const std::string &control_symbol, amsat_duv_decoder::amsat_duv_decoder(const std::string &control_symbol,
size_t max_frame_len) : size_t max_frame_len) :
decoder (1, max_frame_len), decoder(1, max_frame_len),
d_erasure_cnt (0), d_erasure_cnt(0),
d_control_symbol_pos (0), d_control_symbol_pos(0),
d_control_symbol_neg (0), d_control_symbol_neg(0),
d_data_reg (0), d_data_reg(0),
d_wrong_bits (0), d_wrong_bits(0),
d_wrong_bits_neg (0), d_wrong_bits_neg(0),
d_nwrong (0), d_nwrong(0),
d_nwrong_neg (0), d_nwrong_neg(0),
d_word_cnt (0), d_word_cnt(0),
d_bitstream_idx (0), d_bitstream_idx(0),
d_state (SEARCH_SYNC) d_state(SEARCH_SYNC)
{ {
d_8b_words = new uint8_t[max_frame_len]; d_8b_words = new uint8_t[max_frame_len];
d_erasures_indexes = new int[max_frame_len]; d_erasures_indexes = new int[max_frame_len];
if (!set_access_code (control_symbol)) { if (!set_access_code(control_symbol)) {
throw std::out_of_range ("control_symbol is not 10 bits"); throw std::out_of_range("control_symbol is not 10 bits");
} }
} }
bool bool
amsat_duv_decoder::set_access_code (const std::string &control_symbol) amsat_duv_decoder::set_access_code(const std::string &control_symbol)
{ {
unsigned len = control_symbol.length (); // # of bytes in string unsigned len = control_symbol.length(); // # of bytes in string
/* if the control sequence is not 10-bit then throw exception */ /* if the control sequence is not 10-bit then throw exception */
if (len != 10) { if (len != 10) {
@ -112,14 +109,14 @@ amsat_duv_decoder::set_access_code (const std::string &control_symbol)
return true; return true;
} }
amsat_duv_decoder::~amsat_duv_decoder () amsat_duv_decoder::~amsat_duv_decoder()
{ {
delete[] d_8b_words; delete[] d_8b_words;
delete[] d_erasures_indexes; delete[] d_erasures_indexes;
} }
void void
amsat_duv_decoder::process_10b (uint16_t word, size_t write_pos) amsat_duv_decoder::process_10b(uint16_t word, size_t write_pos)
{ {
uint16_t diff_bits = 0; uint16_t diff_bits = 0;
uint8_t min_pos = 0; uint8_t min_pos = 0;
@ -131,7 +128,7 @@ amsat_duv_decoder::process_10b (uint16_t word, size_t write_pos)
while ((i < 256) && (min_dist > 0)) { while ((i < 256) && (min_dist > 0)) {
diff_bits = (word ^ (d_lookup_8b10b[0][i])) & 0x3FF; diff_bits = (word ^ (d_lookup_8b10b[0][i])) & 0x3FF;
curr_dist = gr::blocks::count_bits16 (diff_bits); curr_dist = gr::blocks::count_bits16(diff_bits);
if (curr_dist < min_dist) { if (curr_dist < min_dist) {
min_dist = curr_dist; min_dist = curr_dist;
@ -145,7 +142,7 @@ amsat_duv_decoder::process_10b (uint16_t word, size_t write_pos)
while ((i < 256) && (min_dist > 0)) { while ((i < 256) && (min_dist > 0)) {
diff_bits = (word ^ (d_lookup_8b10b[1][i])) & 0x3FF; diff_bits = (word ^ (d_lookup_8b10b[1][i])) & 0x3FF;
curr_dist = gr::blocks::count_bits16 (diff_bits); curr_dist = gr::blocks::count_bits16(diff_bits);
if (curr_dist < min_dist) { if (curr_dist < min_dist) {
min_dist = curr_dist; min_dist = curr_dist;
@ -164,7 +161,7 @@ amsat_duv_decoder::process_10b (uint16_t word, size_t write_pos)
} }
inline uint16_t inline uint16_t
amsat_duv_decoder::pack_10b_word (size_t idx) amsat_duv_decoder::pack_10b_word(size_t idx)
{ {
return (((uint16_t) d_bitstream[idx] & 0x1) << 9) return (((uint16_t) d_bitstream[idx] & 0x1) << 9)
| (((uint16_t) d_bitstream[idx + 1] & 0x1) << 8) | (((uint16_t) d_bitstream[idx + 1] & 0x1) << 8)
@ -179,7 +176,7 @@ amsat_duv_decoder::pack_10b_word (size_t idx)
} }
static inline bool static inline bool
is_spacecraft_valid (uint8_t id) is_spacecraft_valid(uint8_t id)
{ {
for (size_t i = 0; i < sizeof(amsat_duv_decoder::amsat_fox_spacecraft_id); for (size_t i = 0; i < sizeof(amsat_duv_decoder::amsat_fox_spacecraft_id);
i++) { i++) {
@ -191,9 +188,9 @@ is_spacecraft_valid (uint8_t id)
} }
decoder_status_t decoder_status_t
amsat_duv_decoder::decode (const void *in, int len) amsat_duv_decoder::decode(const void *in, int len)
{ {
const uint8_t *input = (const uint8_t*) in; const uint8_t *input = (const uint8_t *) in;
decoder_status_t status; decoder_status_t status;
int ret; int ret;
uint16_t word; uint16_t word;
@ -201,34 +198,33 @@ amsat_duv_decoder::decode (const void *in, int len)
/* Due to internal buffering we consume all the availabele symbols */ /* Due to internal buffering we consume all the availabele symbols */
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
d_bitstream.push_back (input[i]); d_bitstream.push_back(input[i]);
} }
status.consumed = len; status.consumed = len;
while (1) { while (1) {
bool cont = false; bool cont = false;
if(d_bitstream.size() < 11) { if (d_bitstream.size() < 11) {
return status; return status;
} }
switch (d_state) switch (d_state) {
{
case SEARCH_SYNC: case SEARCH_SYNC:
for (size_t i = 0; i < d_bitstream.size (); i++) { for (size_t i = 0; i < d_bitstream.size(); i++) {
d_data_reg = (d_data_reg << 1) | (d_bitstream[i] & 0x1); d_data_reg = (d_data_reg << 1) | (d_bitstream[i] & 0x1);
d_wrong_bits = (d_data_reg ^ d_control_symbol_pos) & 0x3FF; d_wrong_bits = (d_data_reg ^ d_control_symbol_pos) & 0x3FF;
d_wrong_bits_neg = (d_data_reg ^ d_control_symbol_neg) & 0x3FF; d_wrong_bits_neg = (d_data_reg ^ d_control_symbol_neg) & 0x3FF;
d_nwrong = gr::blocks::count_bits16 (d_wrong_bits); d_nwrong = gr::blocks::count_bits16(d_wrong_bits);
d_nwrong_neg = gr::blocks::count_bits16 (d_wrong_bits_neg); d_nwrong_neg = gr::blocks::count_bits16(d_wrong_bits_neg);
/* we found the controls symbol */ /* we found the controls symbol */
if ((d_nwrong == 0) || (d_nwrong_neg == 0)) { if ((d_nwrong == 0) || (d_nwrong_neg == 0)) {
d_erasure_cnt = 0; d_erasure_cnt = 0;
d_word_cnt = 0; d_word_cnt = 0;
d_state = DECODING; d_state = DECODING;
if(i > 10) { if (i > 10) {
d_bitstream_idx = 9; d_bitstream_idx = 9;
d_bitstream.erase (d_bitstream.begin (), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin () + i + 1 - 9); d_bitstream.begin() + i + 1 - 9);
} }
else { else {
d_bitstream_idx = i; d_bitstream_idx = i;
@ -238,11 +234,11 @@ amsat_duv_decoder::decode (const void *in, int len)
} }
} }
/* No SYNC found on the entire buffer. Clear it and return */ /* No SYNC found on the entire buffer. Clear it and return */
d_bitstream.clear (); d_bitstream.clear();
return status; return status;
case DECODING: case DECODING:
available = d_bitstream.size() - d_bitstream_idx; available = d_bitstream.size() - d_bitstream_idx;
if(available < 10) { if (available < 10) {
return status; return status;
} }
/* /*
@ -250,34 +246,34 @@ amsat_duv_decoder::decode (const void *in, int len)
* in chunks of 10 bits * in chunks of 10 bits
*/ */
for (size_t i = 0; i < available / 10; i++, d_bitstream_idx += 10) { for (size_t i = 0; i < available / 10; i++, d_bitstream_idx += 10) {
word = pack_10b_word (d_bitstream_idx); word = pack_10b_word(d_bitstream_idx);
/* Revert 10b to 8b and accumulate! */ /* Revert 10b to 8b and accumulate! */
process_10b (word, d_word_cnt); process_10b(word, d_word_cnt);
d_word_cnt++; d_word_cnt++;
if (d_word_cnt == max_frame_len ()) { if (d_word_cnt == max_frame_len()) {
d_state = SEARCH_SYNC; d_state = SEARCH_SYNC;
d_data_reg = 0; d_data_reg = 0;
if (d_erasure_cnt > 0) { if (d_erasure_cnt > 0) {
ret = decode_rs_8 (d_8b_words, d_erasures_indexes, d_erasure_cnt, ret = decode_rs_8(d_8b_words, d_erasures_indexes, d_erasure_cnt,
255 - max_frame_len ()); 255 - max_frame_len());
} }
else { else {
ret = decode_rs_8 (d_8b_words, NULL, 0, 255 - max_frame_len ()); ret = decode_rs_8(d_8b_words, NULL, 0, 255 - max_frame_len());
} }
if (ret > -1) { if (ret > -1) {
uint8_t fox_id = d_8b_words[0] & 0x7; uint8_t fox_id = d_8b_words[0] & 0x7;
if (is_spacecraft_valid (fox_id)) { if (is_spacecraft_valid(fox_id)) {
metadata::add_pdu (status.data, d_8b_words, metadata::add_pdu(status.data, d_8b_words,
amsat_fox_duv_frame_size); amsat_fox_duv_frame_size);
metadata::add_symbol_erasures (status.data, d_erasure_cnt); metadata::add_symbol_erasures(status.data, d_erasure_cnt);
metadata::add_corrected_bits (status.data, ret); metadata::add_corrected_bits(status.data, ret);
metadata::add_time_iso8601 (status.data); metadata::add_time_iso8601(status.data);
status.decode_success = true; status.decode_success = true;
d_bitstream.erase (d_bitstream.begin (), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin () + (i + 1) * 10 + 1); d_bitstream.begin() + (i + 1) * 10 + 1);
return status; return status;
} }
} }
@ -287,24 +283,24 @@ amsat_duv_decoder::decode (const void *in, int len)
} }
} }
if(cont) { if (cont) {
continue; continue;
} }
return status; return status;
default: default:
throw std::invalid_argument ( throw std::invalid_argument(
"amsat_duv_decoder: Invalid decoding state"); "amsat_duv_decoder: Invalid decoding state");
} }
} }
} }
void void
amsat_duv_decoder::reset () amsat_duv_decoder::reset()
{ {
d_erasure_cnt = 0; d_erasure_cnt = 0;
d_word_cnt = 0; d_word_cnt = 0;
d_state = SEARCH_SYNC; d_state = SEARCH_SYNC;
d_bitstream.clear (); d_bitstream.clear();
d_bitstream_idx = 0; d_bitstream_idx = 0;
} }

View File

@ -27,44 +27,42 @@
#include <satnogs/ax25.h> #include <satnogs/ax25.h>
#include <satnogs/metadata.h> #include <satnogs/metadata.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
decoder::decoder_sptr decoder::decoder_sptr
ax25_decoder::make (const std::string &addr, uint8_t ssid, bool promisc, ax25_decoder::make(const std::string &addr, uint8_t ssid, bool promisc,
bool descramble, bool crc_check, size_t max_frame_len) bool descramble, bool crc_check, size_t max_frame_len)
{ {
return decoder::decoder_sptr ( return decoder::decoder_sptr(
new ax25_decoder (addr, ssid, promisc, descramble, crc_check, new ax25_decoder(addr, ssid, promisc, descramble, crc_check,
max_frame_len)); max_frame_len));
} }
ax25_decoder::ax25_decoder (const std::string &addr, uint8_t ssid, bool promisc, ax25_decoder::ax25_decoder(const std::string &addr, uint8_t ssid, bool promisc,
bool descramble, bool crc_check, size_t max_frame_len) : bool descramble, bool crc_check, size_t max_frame_len) :
decoder (sizeof(uint8_t), 2 * max_frame_len * 8), decoder(sizeof(uint8_t), 2 * max_frame_len * 8),
d_promisc (promisc), d_promisc(promisc),
d_descramble (descramble), d_descramble(descramble),
d_crc_check(crc_check), d_crc_check(crc_check),
d_max_frame_len (max_frame_len), d_max_frame_len(max_frame_len),
d_state (NO_SYNC), d_state(NO_SYNC),
d_shift_reg (0x0), d_shift_reg(0x0),
d_dec_b (0x0), d_dec_b(0x0),
d_prev_bit_nrzi (0), d_prev_bit_nrzi(0),
d_received_bytes (0), d_received_bytes(0),
d_decoded_bits (0), d_decoded_bits(0),
d_lfsr (0x21, 0x0, 16), d_lfsr(0x21, 0x0, 16),
d_frame_buffer ( d_frame_buffer(
new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN
+ sizeof(uint16_t)]), + sizeof(uint16_t)]),
d_start_idx (0), d_start_idx(0),
d_frame_start(0) d_frame_start(0)
{ {
} }
decoder_status_t decoder_status_t
ax25_decoder::decode (const void *in, int len) ax25_decoder::decode(const void *in, int len)
{ {
const uint8_t *input = (const uint8_t *) in; const uint8_t *input = (const uint8_t *) in;
decoder_status_t status; decoder_status_t status;
@ -73,8 +71,8 @@ ax25_decoder::decode (const void *in, int len)
/* Perform NRZI decoding */ /* Perform NRZI decoding */
uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1; uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = input[i]; d_prev_bit_nrzi = input[i];
b = d_lfsr.next_bit_descramble (b); b = d_lfsr.next_bit_descramble(b);
d_bitstream.push_back (b); d_bitstream.push_back(b);
} }
} }
else { else {
@ -82,7 +80,7 @@ ax25_decoder::decode (const void *in, int len)
/* Perform NRZI decoding */ /* Perform NRZI decoding */
uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1; uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1;
d_prev_bit_nrzi = input[i]; d_prev_bit_nrzi = input[i];
d_bitstream.push_back (b); d_bitstream.push_back(b);
} }
} }
/* /*
@ -95,35 +93,34 @@ ax25_decoder::decode (const void *in, int len)
} }
void void
ax25_decoder::reset () ax25_decoder::reset()
{ {
reset_state(); reset_state();
} }
bool bool
ax25_decoder::_decode (decoder_status_t& status) ax25_decoder::_decode(decoder_status_t &status)
{ {
while (1) { while (1) {
bool cont = false; bool cont = false;
switch (d_state) switch (d_state) {
{
case NO_SYNC: case NO_SYNC:
for (size_t i = 0; i < d_bitstream.size (); i++) { for (size_t i = 0; i < d_bitstream.size(); i++) {
decode_1b (d_bitstream[i]); decode_1b(d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) { if (d_shift_reg == AX25_SYNC_FLAG) {
d_bitstream.erase (d_bitstream.begin (), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin () + i + 1); d_bitstream.begin() + i + 1);
enter_sync_state (); enter_sync_state();
d_frame_start = i; d_frame_start = i;
d_start_idx = 0; d_start_idx = 0;
cont = true; cont = true;
break; break;
} }
} }
if(cont) { if (cont) {
continue; continue;
} }
d_bitstream.clear (); d_bitstream.clear();
return false; return false;
case IN_SYNC: case IN_SYNC:
/* /*
@ -131,34 +128,34 @@ ax25_decoder::_decode (decoder_status_t& status)
* In case of G3RUH this is mandatory to allow the self synchronizing * In case of G3RUH this is mandatory to allow the self synchronizing
* scrambler to settle * scrambler to settle
*/ */
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) { for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
decode_1b (d_bitstream[i]); decode_1b(d_bitstream[i]);
d_decoded_bits++; d_decoded_bits++;
if (d_decoded_bits == 8) { if (d_decoded_bits == 8) {
/* Perhaps we are in frame! */ /* Perhaps we are in frame! */
if (d_shift_reg != AX25_SYNC_FLAG) { if (d_shift_reg != AX25_SYNC_FLAG) {
d_start_idx = i + 1; d_start_idx = i + 1;
enter_decoding_state (); enter_decoding_state();
cont = true; cont = true;
break; break;
} }
d_decoded_bits = 0; d_decoded_bits = 0;
} }
} }
if(cont) { if (cont) {
continue; continue;
} }
d_start_idx = d_bitstream.size (); d_start_idx = d_bitstream.size();
return false; return false;
case DECODING: case DECODING:
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) { for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
decode_1b (d_bitstream[i]); decode_1b(d_bitstream[i]);
if (d_shift_reg == AX25_SYNC_FLAG) { if (d_shift_reg == AX25_SYNC_FLAG) {
LOG_DEBUG("Found frame end"); LOG_DEBUG("Found frame end");
if (enter_frame_end (status)) { if (enter_frame_end(status)) {
d_bitstream.erase (d_bitstream.begin (), d_bitstream.erase(d_bitstream.begin(),
d_bitstream.begin () + i + 1); d_bitstream.begin() + i + 1);
d_start_idx = d_bitstream.size (); d_start_idx = d_bitstream.size();
return true; return true;
} }
cont = true; cont = true;
@ -170,7 +167,7 @@ ax25_decoder::_decode (decoder_status_t& status)
} }
else if ((d_shift_reg & 0xfe) == 0xfe) { else if ((d_shift_reg & 0xfe) == 0xfe) {
LOG_DEBUG("Invalid shift register value %u", d_received_bytes); LOG_DEBUG("Invalid shift register value %u", d_received_bytes);
reset_state (); reset_state();
cont = true; cont = true;
break; break;
} }
@ -183,34 +180,34 @@ ax25_decoder::_decode (decoder_status_t& status)
/*Check if the frame limit was reached */ /*Check if the frame limit was reached */
if (d_received_bytes >= d_max_frame_len) { if (d_received_bytes >= d_max_frame_len) {
LOG_DEBUG("Wrong size"); LOG_DEBUG("Wrong size");
reset_state (); reset_state();
cont = true; cont = true;
break; break;
} }
} }
} }
} }
if(cont) { if (cont) {
continue; continue;
} }
d_start_idx = d_bitstream.size (); d_start_idx = d_bitstream.size();
return false; return false;
default: default:
LOG_ERROR("Invalid decoding state"); LOG_ERROR("Invalid decoding state");
reset_state (); reset_state();
return false; return false;
} }
} }
} }
ax25_decoder::~ax25_decoder () ax25_decoder::~ax25_decoder()
{ {
delete[] d_frame_buffer; delete[] d_frame_buffer;
} }
void void
ax25_decoder::reset_state () ax25_decoder::reset_state()
{ {
d_state = NO_SYNC; d_state = NO_SYNC;
d_dec_b = 0x0; d_dec_b = 0x0;
@ -220,7 +217,7 @@ ax25_decoder::reset_state ()
} }
void void
ax25_decoder::enter_sync_state () ax25_decoder::enter_sync_state()
{ {
d_state = IN_SYNC; d_state = IN_SYNC;
d_dec_b = 0x0; d_dec_b = 0x0;
@ -230,7 +227,7 @@ ax25_decoder::enter_sync_state ()
} }
void void
ax25_decoder::enter_decoding_state () ax25_decoder::enter_decoding_state()
{ {
uint8_t tmp; uint8_t tmp;
d_state = DECODING; d_state = DECODING;
@ -254,14 +251,14 @@ ax25_decoder::enter_decoding_state ()
} }
bool bool
ax25_decoder::enter_frame_end (decoder_status_t& status) ax25_decoder::enter_frame_end(decoder_status_t &status)
{ {
uint16_t fcs; uint16_t fcs;
uint16_t recv_fcs = 0x0; uint16_t recv_fcs = 0x0;
/* First check if the size of the frame is valid */ /* First check if the size of the frame is valid */
if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) { if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) {
reset_state (); reset_state();
return false; return false;
} }
@ -269,22 +266,22 @@ ax25_decoder::enter_frame_end (decoder_status_t& status)
* Check if the frame is correct using the FCS field * Check if the frame is correct using the FCS field
* Using this field also try to correct up to 2 error bits * Using this field also try to correct up to 2 error bits
*/ */
if (frame_check ()) { if (frame_check()) {
metadata::add_pdu(status.data, d_frame_buffer, d_received_bytes - sizeof(uint16_t)); metadata::add_pdu(status.data, d_frame_buffer, d_received_bytes - sizeof(uint16_t));
metadata::add_time_iso8601(status.data); metadata::add_time_iso8601(status.data);
metadata::add_crc_valid(status.data, true); metadata::add_crc_valid(status.data, true);
metadata::add_sample_start(status.data, d_frame_start); metadata::add_sample_start(status.data, d_frame_start);
status.decode_success = true; status.decode_success = true;
reset_state (); reset_state();
return true; return true;
} }
else if(!d_crc_check){ else if (!d_crc_check) {
metadata::add_pdu(status.data, d_frame_buffer, d_received_bytes - sizeof(uint16_t)); metadata::add_pdu(status.data, d_frame_buffer, d_received_bytes - sizeof(uint16_t));
metadata::add_time_iso8601(status.data); metadata::add_time_iso8601(status.data);
metadata::add_crc_valid(status.data, false); metadata::add_crc_valid(status.data, false);
status.decode_success = true; status.decode_success = true;
LOG_DEBUG("Wrong crc"); LOG_DEBUG("Wrong crc");
reset_state (); reset_state();
return false; return false;
} }
return false; return false;
@ -292,7 +289,7 @@ ax25_decoder::enter_frame_end (decoder_status_t& status)
inline void inline void
ax25_decoder::decode_1b (uint8_t in) ax25_decoder::decode_1b(uint8_t in)
{ {
/* In AX.25 the LS bit is sent first */ /* In AX.25 the LS bit is sent first */
@ -301,14 +298,14 @@ ax25_decoder::decode_1b (uint8_t in)
} }
bool bool
ax25_decoder::frame_check () ax25_decoder::frame_check()
{ {
uint16_t fcs; uint16_t fcs;
uint16_t recv_fcs = 0x0; uint16_t recv_fcs = 0x0;
uint8_t orig_byte; uint8_t orig_byte;
/* Check if the frame is correct using the FCS field */ /* Check if the frame is correct using the FCS field */
fcs = ax25_fcs (d_frame_buffer, d_received_bytes - sizeof(uint16_t)); fcs = ax25_fcs(d_frame_buffer, d_received_bytes - sizeof(uint16_t));
recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8) recv_fcs = (((uint16_t) d_frame_buffer[d_received_bytes - 1]) << 8)
| d_frame_buffer[d_received_bytes - 2]; | d_frame_buffer[d_received_bytes - 2];
if (fcs == recv_fcs) { if (fcs == recv_fcs) {

View File

@ -28,70 +28,68 @@
#include <satnogs/log.h> #include <satnogs/log.h>
#include <satnogs/ax25.h> #include <satnogs/ax25.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
ax25_encoder_mb::sptr ax25_encoder_mb::sptr
ax25_encoder_mb::make (const std::string& dest_addr, uint8_t dest_ssid, ax25_encoder_mb::make(const std::string &dest_addr, uint8_t dest_ssid,
const std::string& src_addr, uint8_t src_ssid, const std::string &src_addr, uint8_t src_ssid,
size_t preamble_len, size_t postamble_len, size_t preamble_len, size_t postamble_len,
bool scramble) bool scramble)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new ax25_encoder_mb_impl (dest_addr, dest_ssid, src_addr, src_ssid, new ax25_encoder_mb_impl(dest_addr, dest_ssid, src_addr, src_ssid,
preamble_len, postamble_len, scramble)); preamble_len, postamble_len, scramble));
} }
/* /*
* The private constructor * The private constructor
*/ */
ax25_encoder_mb_impl::ax25_encoder_mb_impl (const std::string& dest_addr, ax25_encoder_mb_impl::ax25_encoder_mb_impl(const std::string &dest_addr,
uint8_t dest_ssid, uint8_t dest_ssid,
const std::string& src_addr, const std::string &src_addr,
uint8_t src_ssid, uint8_t src_ssid,
size_t preamble_len, size_t preamble_len,
size_t postabmle_len, size_t postabmle_len,
bool scramble) : bool scramble) :
gr::sync_block ("ax25_encoder_mb", gr::io_signature::make (0, 0, 0), gr::sync_block("ax25_encoder_mb", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (1, 1, sizeof(uint8_t))), gr::io_signature::make(1, 1, sizeof(uint8_t))),
d_preamble_len (preamble_len), d_preamble_len(preamble_len),
d_postamble_len (postabmle_len), d_postamble_len(postabmle_len),
d_scramble (scramble), d_scramble(scramble),
d_remaining (0), d_remaining(0),
d_produced (0), d_produced(0),
d_prev_bit (0x0), d_prev_bit(0x0),
d_encoded_frame ( d_encoded_frame(
new uint8_t[(preamble_len + postabmle_len new uint8_t[(preamble_len + postabmle_len
+ (AX25_MAX_FRAME_LEN * 2)) * 8]), + (AX25_MAX_FRAME_LEN * 2)) * 8]),
d_tmp_buf ( d_tmp_buf(
new uint8_t[preamble_len + postabmle_len new uint8_t[preamble_len + postabmle_len
+ (AX25_MAX_FRAME_LEN * 2)]), + (AX25_MAX_FRAME_LEN * 2)]),
d_addr_field (new uint8_t[AX25_MAX_ADDR_LEN]), d_addr_field(new uint8_t[AX25_MAX_ADDR_LEN]),
d_lfsr (0x21, 0x0, 16) d_lfsr(0x21, 0x0, 16)
{ {
/* Input is a blob message containing the info field data */ /* Input is a blob message containing the info field data */
message_port_register_in (pmt::mp ("info")); message_port_register_in(pmt::mp("info"));
d_addr_len = ax25_create_addr_field (d_addr_field, dest_addr, dest_ssid, d_addr_len = ax25_create_addr_field(d_addr_field, dest_addr, dest_ssid,
src_addr, src_ssid); src_addr, src_ssid);
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
ax25_encoder_mb_impl::~ax25_encoder_mb_impl () ax25_encoder_mb_impl::~ax25_encoder_mb_impl()
{ {
delete [] d_encoded_frame; delete [] d_encoded_frame;
delete [] d_tmp_buf; delete [] d_tmp_buf;
delete [] d_addr_field; delete [] d_addr_field;
} }
int int
ax25_encoder_mb_impl::work (int noutput_items, ax25_encoder_mb_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const uint8_t *info; const uint8_t *info;
size_t info_len; size_t info_len;
size_t max_avail; size_t max_avail;
@ -106,20 +104,20 @@ namespace gr
if (d_remaining == 0) { if (d_remaining == 0) {
d_produced = 0; d_produced = 0;
d_prev_bit = 0x0; d_prev_bit = 0x0;
d_lfsr.reset (); d_lfsr.reset();
/* Block waiting from a new message from users */ /* Block waiting from a new message from users */
msg = delete_head_blocking (pmt::mp ("info")); msg = delete_head_blocking(pmt::mp("info"));
info = (const uint8_t *) pmt::blob_data (msg); info = (const uint8_t *) pmt::blob_data(msg);
info_len = pmt::blob_length (msg); info_len = pmt::blob_length(msg);
/* Prepare and encode the AX.25 frame */ /* Prepare and encode the AX.25 frame */
len = ax25_prepare_frame (d_tmp_buf, info, info_len, AX25_I_FRAME, len = ax25_prepare_frame(d_tmp_buf, info, info_len, AX25_I_FRAME,
d_addr_field, d_addr_len, 0, 1, d_addr_field, d_addr_len, 0, 1,
d_preamble_len, d_postamble_len); d_preamble_len, d_postamble_len);
/* Perform bit stuffing */ /* Perform bit stuffing */
status = ax25_bit_stuffing (d_encoded_frame, &d_remaining, d_tmp_buf, status = ax25_bit_stuffing(d_encoded_frame, &d_remaining, d_tmp_buf,
len, d_preamble_len, d_postamble_len); len, d_preamble_len, d_postamble_len);
if (status != AX25_ENC_OK) { if (status != AX25_ENC_OK) {
LOG_ERROR("AX.25 encoding failed"); LOG_ERROR("AX.25 encoding failed");
@ -130,12 +128,12 @@ namespace gr
/*Perform scrambling if the user asked for it */ /*Perform scrambling if the user asked for it */
if (d_scramble) { if (d_scramble) {
for (i = 0; i < d_remaining; i++) { for (i = 0; i < d_remaining; i++) {
d_encoded_frame[i] = d_lfsr.next_bit_scramble (d_encoded_frame[i]); d_encoded_frame[i] = d_lfsr.next_bit_scramble(d_encoded_frame[i]);
} }
/* Allow the LFSR to pop all its bits */ /* Allow the LFSR to pop all its bits */
d_remaining += 16; d_remaining += 16;
for (; i < d_remaining; i++) { for (; i < d_remaining; i++) {
d_encoded_frame[i] = d_lfsr.next_bit_scramble (0x0); d_encoded_frame[i] = d_lfsr.next_bit_scramble(0x0);
} }
} }
/* Append a zero byte at the end */ /* Append a zero byte at the end */
@ -145,9 +143,9 @@ namespace gr
/* If this is the first part of the frame add the start of burst tag*/ /* If this is the first part of the frame add the start of burst tag*/
if (d_produced == 0) { if (d_produced == 0) {
add_sob (nitems_written (0)); add_sob(nitems_written(0));
} }
max_avail = std::min (d_remaining, (size_t) noutput_items); max_avail = std::min(d_remaining, (size_t) noutput_items);
/* Perform NRZI encoding */ /* Perform NRZI encoding */
for (i = 0; i < max_avail; i++) { for (i = 0; i < max_avail; i++) {
@ -158,30 +156,30 @@ namespace gr
d_remaining -= max_avail; d_remaining -= max_avail;
d_produced += max_avail; d_produced += max_avail;
if (d_remaining == 0) { if (d_remaining == 0) {
add_eob (nitems_written (0) + max_avail); add_eob(nitems_written(0) + max_avail);
} }
return (int) max_avail; return (int) max_avail;
} }
void void
ax25_encoder_mb_impl::add_sob (uint64_t item) ax25_encoder_mb_impl::add_sob(uint64_t item)
{ {
static const pmt::pmt_t sob_key = pmt::string_to_symbol ("tx_sob"); static const pmt::pmt_t sob_key = pmt::string_to_symbol("tx_sob");
static const pmt::pmt_t value = pmt::PMT_T; static const pmt::pmt_t value = pmt::PMT_T;
static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); static const pmt::pmt_t srcid = pmt::string_to_symbol(alias());
add_item_tag (0, item, sob_key, value, srcid); add_item_tag(0, item, sob_key, value, srcid);
} }
void void
ax25_encoder_mb_impl::add_eob (uint64_t item) ax25_encoder_mb_impl::add_eob(uint64_t item)
{ {
static const pmt::pmt_t eob_key = pmt::string_to_symbol ("tx_eob"); static const pmt::pmt_t eob_key = pmt::string_to_symbol("tx_eob");
static const pmt::pmt_t value = pmt::PMT_T; static const pmt::pmt_t value = pmt::PMT_T;
static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); static const pmt::pmt_t srcid = pmt::string_to_symbol(alias());
add_item_tag (0, item, eob_key, value, srcid); add_item_tag(0, item, eob_key, value, srcid);
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -25,14 +25,11 @@
#include <satnogs/ax25_encoder_mb.h> #include <satnogs/ax25_encoder_mb.h>
#include <gnuradio/digital/lfsr.h> #include <gnuradio/digital/lfsr.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class ax25_encoder_mb_impl : public ax25_encoder_mb class ax25_encoder_mb_impl : public ax25_encoder_mb {
{ private:
private:
const size_t d_preamble_len; const size_t d_preamble_len;
const size_t d_postamble_len; const size_t d_postamble_len;
const bool d_scramble; const bool d_scramble;
@ -46,24 +43,24 @@ namespace gr
digital::lfsr d_lfsr; digital::lfsr d_lfsr;
void void
add_sob (uint64_t item); add_sob(uint64_t item);
void void
add_eob (uint64_t item); add_eob(uint64_t item);
public: public:
ax25_encoder_mb_impl (const std::string& dest_addr, uint8_t dest_ssid, ax25_encoder_mb_impl(const std::string &dest_addr, uint8_t dest_ssid,
const std::string& src_addr, uint8_t src_ssid, const std::string &src_addr, uint8_t src_ssid,
size_t preamble_len, size_t postamble_len, size_t preamble_len, size_t postamble_len,
bool scramble); bool scramble);
~ax25_encoder_mb_impl (); ~ax25_encoder_mb_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H */ #endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H */

View File

@ -27,34 +27,32 @@
#include <volk/volk.h> #include <volk/volk.h>
#include <satnogs/log.h> #include <satnogs/log.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
coarse_doppler_correction_cc::sptr coarse_doppler_correction_cc::sptr
coarse_doppler_correction_cc::make (double target_freq, coarse_doppler_correction_cc::make(double target_freq,
double sampling_rate) double sampling_rate)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new coarse_doppler_correction_cc_impl (target_freq, sampling_rate)); new coarse_doppler_correction_cc_impl(target_freq, sampling_rate));
} }
/* /*
* The private constructor * The private constructor
*/ */
coarse_doppler_correction_cc_impl::coarse_doppler_correction_cc_impl ( coarse_doppler_correction_cc_impl::coarse_doppler_correction_cc_impl(
double target_freq, double sampling_rate) : double target_freq, double sampling_rate) :
gr::sync_block ("coarse_doppler_correction_cc", gr::sync_block("coarse_doppler_correction_cc",
gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make (1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_target_freq (target_freq), d_target_freq(target_freq),
d_samp_rate (sampling_rate), d_samp_rate(sampling_rate),
d_buf_items (std::min ((size_t)8192UL, (size_t) (d_samp_rate / 4))), d_buf_items(std::min((size_t)8192UL, (size_t)(d_samp_rate / 4))),
d_freq_diff (0), d_freq_diff(0),
d_nco () d_nco()
{ {
message_port_register_in (pmt::mp ("freq")); message_port_register_in(pmt::mp("freq"));
/* /*
* NOTE: * NOTE:
@ -65,65 +63,65 @@ namespace gr
* This is taken into consideration due to the fact that the work() * This is taken into consideration due to the fact that the work()
* and the input message handler are NOT reentrant. * and the input message handler are NOT reentrant.
*/ */
set_max_noutput_items (d_samp_rate / 4.0); set_max_noutput_items(d_samp_rate / 4.0);
set_alignment (8); set_alignment(8);
set_msg_handler ( set_msg_handler(
pmt::mp ("freq"), pmt::mp("freq"),
boost::bind (&coarse_doppler_correction_cc_impl::new_freq, this, _1)); boost::bind(&coarse_doppler_correction_cc_impl::new_freq, this, _1));
d_nco.set_freq (0); d_nco.set_freq(0);
/* Allocate aligned memory for the NCO */ /* Allocate aligned memory for the NCO */
d_nco_buff = (gr_complex *) volk_malloc ( d_nco_buff = (gr_complex *) volk_malloc(
(d_samp_rate / 4) * sizeof(gr_complex), 32); (d_samp_rate / 4) * sizeof(gr_complex), 32);
if (!d_nco_buff) { if (!d_nco_buff) {
throw std::runtime_error ("Could not allocate NCO memory"); throw std::runtime_error("Could not allocate NCO memory");
}
} }
}
void void
coarse_doppler_correction_cc_impl::new_freq (pmt::pmt_t msg) coarse_doppler_correction_cc_impl::new_freq(pmt::pmt_t msg)
{ {
boost::mutex::scoped_lock lock (d_mutex); boost::mutex::scoped_lock lock(d_mutex);
double new_freq; double new_freq;
new_freq = pmt::to_double (msg); new_freq = pmt::to_double(msg);
d_freq_diff = new_freq - d_target_freq; d_freq_diff = new_freq - d_target_freq;
d_nco.set_freq ((2 * M_PI * (-d_freq_diff)) / d_samp_rate); d_nco.set_freq((2 * M_PI * (-d_freq_diff)) / d_samp_rate);
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
coarse_doppler_correction_cc_impl::~coarse_doppler_correction_cc_impl () coarse_doppler_correction_cc_impl::~coarse_doppler_correction_cc_impl()
{ {
volk_free (d_nco_buff); volk_free(d_nco_buff);
} }
int int
coarse_doppler_correction_cc_impl::work ( coarse_doppler_correction_cc_impl::work(
int noutput_items, gr_vector_const_void_star &input_items, int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const gr_complex *in = (const gr_complex *) input_items[0]; const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0]; gr_complex *out = (gr_complex *) output_items[0];
/* Perform the correction */ /* Perform the correction */
d_nco.sincos (d_nco_buff, noutput_items, 1.0); d_nco.sincos(d_nco_buff, noutput_items, 1.0);
volk_32fc_x2_multiply_32fc (out, in, d_nco_buff, noutput_items); volk_32fc_x2_multiply_32fc(out, in, d_nco_buff, noutput_items);
// Tell runtime system how many output items we produced. // Tell runtime system how many output items we produced.
return noutput_items; return noutput_items;
} }
void void
coarse_doppler_correction_cc_impl::set_target_freq (double freq) coarse_doppler_correction_cc_impl::set_target_freq(double freq)
{ {
boost::mutex::scoped_lock lock (d_mutex); boost::mutex::scoped_lock lock(d_mutex);
d_target_freq = freq; d_target_freq = freq;
d_freq_diff = 0.0; d_freq_diff = 0.0;
d_nco.set_freq (0); d_nco.set_freq(0);
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -24,14 +24,11 @@
#include <satnogs/coarse_doppler_correction_cc.h> #include <satnogs/coarse_doppler_correction_cc.h>
#include <gnuradio/fxpt_nco.h> #include <gnuradio/fxpt_nco.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class coarse_doppler_correction_cc_impl : public coarse_doppler_correction_cc class coarse_doppler_correction_cc_impl : public coarse_doppler_correction_cc {
{ private:
private:
double d_target_freq; double d_target_freq;
const double d_samp_rate; const double d_samp_rate;
const size_t d_buf_items; const size_t d_buf_items;
@ -42,23 +39,23 @@ namespace gr
boost::mutex d_mutex; boost::mutex d_mutex;
void void
new_freq (pmt::pmt_t msg); new_freq(pmt::pmt_t msg);
public: public:
coarse_doppler_correction_cc_impl (double target_freq, coarse_doppler_correction_cc_impl(double target_freq,
double sampling_rate); double sampling_rate);
~coarse_doppler_correction_cc_impl (); ~coarse_doppler_correction_cc_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
void void
set_target_freq (double freq); set_target_freq(double freq);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_IMPL_H */ #endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_IMPL_H */

View File

@ -25,28 +25,26 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <satnogs/convolutional_deinterleaver.h> #include <satnogs/convolutional_deinterleaver.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
convolutional_deinterleaver::convolutional_deinterleaver (size_t branches, convolutional_deinterleaver::convolutional_deinterleaver(size_t branches,
size_t M) : size_t M) :
d_nbranches (branches), d_nbranches(branches),
d_M (M), d_M(M),
d_idx(0) d_idx(0)
{ {
for(size_t i = 0; i < d_nbranches; i++) { for (size_t i = 0; i < d_nbranches; i++) {
d_branches.push_back(std::deque<uint8_t>((d_nbranches - 1 - i) * M, 0)); d_branches.push_back(std::deque<uint8_t>((d_nbranches - 1 - i) * M, 0));
} }
} }
convolutional_deinterleaver::~convolutional_deinterleaver () convolutional_deinterleaver::~convolutional_deinterleaver()
{ {
} }
uint8_t uint8_t
convolutional_deinterleaver::decode_bit (uint8_t b) convolutional_deinterleaver::decode_bit(uint8_t b)
{ {
uint8_t ret; uint8_t ret;
d_branches[d_idx].push_back(b); d_branches[d_idx].push_back(b);
@ -57,7 +55,7 @@ convolutional_deinterleaver::decode_bit (uint8_t b)
} }
uint8_t uint8_t
convolutional_deinterleaver::decode_byte (uint8_t b) convolutional_deinterleaver::decode_byte(uint8_t b)
{ {
uint8_t ret = 0; uint8_t ret = 0;
ret = decode_bit(b >> 7) << 7; ret = decode_bit(b >> 7) << 7;
@ -72,10 +70,10 @@ convolutional_deinterleaver::decode_byte (uint8_t b)
} }
void void
convolutional_deinterleaver::reset () convolutional_deinterleaver::reset()
{ {
d_branches.clear(); d_branches.clear();
for(size_t i = 0; i < d_nbranches; i++) { for (size_t i = 0; i < d_nbranches; i++) {
d_branches.push_back(std::deque<uint8_t>((d_nbranches - 1 - i) * d_M, 0)); d_branches.push_back(std::deque<uint8_t>((d_nbranches - 1 - i) * d_M, 0));
} }
d_idx = 0; d_idx = 0;

View File

@ -25,14 +25,12 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <satnogs/crc.h> #include <satnogs/crc.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
const uint16_t crc::crc16_ccitt_table_reverse[256] = const uint16_t crc::crc16_ccitt_table_reverse[256] = {
{ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48, 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48,
0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 0x1081, 0x0108, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 0x1081, 0x0108,
0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, 0x9CC9, 0x8D40, 0xBFDB, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, 0x9CC9, 0x8D40, 0xBFDB,
0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, 0x2102, 0x308B, 0x0210, 0x1399, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, 0x2102, 0x308B, 0x0210, 0x1399,
@ -60,10 +58,11 @@ const uint16_t crc::crc16_ccitt_table_reverse[256] =
0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, 0x6B46, 0x7ACF, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, 0x6B46, 0x7ACF,
0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 0xF78F, 0xE606, 0xD49D, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 0xF78F, 0xE606, 0xD49D,
0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, 0x7BC7, 0x6A4E, 0x58D5, 0x495C,
0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 }; 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
const uint16_t crc::crc16_ccitt_table[256] = const uint16_t crc::crc16_ccitt_table[256] = {
{ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
@ -91,7 +90,8 @@ const uint16_t crc::crc16_ccitt_table[256] =
0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 }; 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
uint16_t uint16_t
crc::crc16_ccitt_reversed(const uint8_t *data, size_t len) crc::crc16_ccitt_reversed(const uint8_t *data, size_t len)
@ -104,7 +104,7 @@ crc::crc16_ccitt_reversed(const uint8_t *data, size_t len)
} }
uint16_t uint16_t
crc::crc16_ccitt (const uint8_t *data, size_t len) crc::crc16_ccitt(const uint8_t *data, size_t len)
{ {
uint16_t crc = 0; uint16_t crc = 0;
while (len-- != 0) { while (len-- != 0) {
@ -124,7 +124,7 @@ crc::crc16_ax25(const uint8_t *data, size_t len)
} }
static uint16_t static uint16_t
update_crc16_ibm (uint8_t crc, uint16_t reg) update_crc16_ibm(uint8_t crc, uint16_t reg)
{ {
const uint16_t crc_poly = 0x8005; const uint16_t crc_poly = 0x8005;
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
@ -143,8 +143,9 @@ uint16_t
crc::crc16_ibm(const uint8_t *data, size_t len) crc::crc16_ibm(const uint8_t *data, size_t len)
{ {
uint16_t crc = 0xFFFF; uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; i++) for (size_t i = 0; i < len; i++) {
crc = update_crc16_ibm (data[i], crc); crc = update_crc16_ibm(data[i], crc);
}
return crc; return crc;
} }

View File

@ -28,32 +28,32 @@
#include "cw_encoder_impl.h" #include "cw_encoder_impl.h"
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
cw_encoder::sptr cw_encoder::sptr
cw_encoder::make(double samp_rate, double cw_freq, size_t wpm) cw_encoder::make(double samp_rate, double cw_freq, size_t wpm)
{ {
return gnuradio::get_initial_sptr return gnuradio::get_initial_sptr
(new cw_encoder_impl(samp_rate, cw_freq, wpm)); (new cw_encoder_impl(samp_rate, cw_freq, wpm));
} }
/* /*
* The private constructor * The private constructor
*/ */
cw_encoder_impl::cw_encoder_impl(double samp_rate, double cw_freq, cw_encoder_impl::cw_encoder_impl(double samp_rate, double cw_freq,
size_t wpm) size_t wpm)
: gr::sync_block("cw_encoder", : gr::sync_block("cw_encoder",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_samp_rate (samp_rate), d_samp_rate(samp_rate),
d_cw_freq (cw_freq), d_cw_freq(cw_freq),
d_wpm (wpm), d_wpm(wpm),
d_dot_samples ((1.2 / wpm) / (1.0 / samp_rate)), d_dot_samples((1.2 / wpm) / (1.0 / samp_rate)),
d_window_size (0), d_window_size(0),
d_windows_remaining (0), d_windows_remaining(0),
d_cw_symbol (MORSE_L_SPACE), d_cw_symbol(MORSE_L_SPACE),
d_nco () d_nco()
{ {
message_port_register_in(pmt::mp("symbol")); message_port_register_in(pmt::mp("symbol"));
/* /*
@ -62,46 +62,46 @@ namespace gr {
*/ */
size_t i = 10; size_t i = 10;
d_window_size = d_dot_samples / i; d_window_size = d_dot_samples / i;
while(d_window_size > 200) { while (d_window_size > 200) {
i += 10; i += 10;
d_window_size = d_dot_samples / i; d_window_size = d_dot_samples / i;
} }
/* NOTE: The dot duration should be a perfect multiple of the window */ /* NOTE: The dot duration should be a perfect multiple of the window */
while(d_dot_samples % d_window_size != 0) { while (d_dot_samples % d_window_size != 0) {
d_window_size++; d_window_size++;
} }
set_output_multiple(d_window_size); set_output_multiple(d_window_size);
d_nco.set_freq ((2 * M_PI * cw_freq) / samp_rate); d_nco.set_freq((2 * M_PI * cw_freq) / samp_rate);
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
cw_encoder_impl::~cw_encoder_impl() cw_encoder_impl::~cw_encoder_impl()
{ {
} }
int int
cw_encoder_impl::work(int noutput_items, cw_encoder_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
size_t available; size_t available;
size_t i; size_t i;
gr_complex *out = (gr_complex *) output_items[0]; gr_complex *out = (gr_complex *) output_items[0];
if(noutput_items < 0) { if (noutput_items < 0) {
return noutput_items; return noutput_items;
} }
if(d_windows_remaining == 0) { if (d_windows_remaining == 0) {
pmt::pmt_t symbol = delete_head_blocking(pmt::mp("symbol")); pmt::pmt_t symbol = delete_head_blocking(pmt::mp("symbol"));
d_cw_symbol = (morse_symbol_t) pmt::to_long(symbol); d_cw_symbol = (morse_symbol_t) pmt::to_long(symbol);
/* Reset NCO so the amplitude starts from zero */ /* Reset NCO so the amplitude starts from zero */
d_nco.set_freq ((2 * M_PI * d_cw_freq) / d_samp_rate); d_nco.set_freq((2 * M_PI * d_cw_freq) / d_samp_rate);
switch(d_cw_symbol) { switch (d_cw_symbol) {
case MORSE_DOT: case MORSE_DOT:
case MORSE_INTRA_SPACE: case MORSE_INTRA_SPACE:
d_windows_remaining = d_dot_samples / d_window_size; d_windows_remaining = d_dot_samples / d_window_size;
@ -119,12 +119,12 @@ namespace gr {
} }
} }
for(i = 0; i < (size_t)noutput_items / d_window_size; i++) { for (i = 0; i < (size_t)noutput_items / d_window_size; i++) {
switch(d_cw_symbol){ switch (d_cw_symbol) {
case MORSE_S_SPACE: case MORSE_S_SPACE:
case MORSE_L_SPACE: case MORSE_L_SPACE:
case MORSE_INTRA_SPACE: case MORSE_INTRA_SPACE:
memset (out + i * d_window_size, 0, memset(out + i * d_window_size, 0,
d_window_size * sizeof(gr_complex)); d_window_size * sizeof(gr_complex));
break; break;
case MORSE_DOT: case MORSE_DOT:
@ -133,13 +133,13 @@ namespace gr {
break; break;
} }
d_windows_remaining--; d_windows_remaining--;
if(d_windows_remaining == 0) { if (d_windows_remaining == 0) {
return (i + 1) * d_window_size; return (i + 1) * d_window_size;
} }
} }
return i * d_window_size; return i * d_window_size;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -28,14 +28,11 @@
#include <satnogs/morse.h> #include <satnogs/morse.h>
#include <gnuradio/fxpt_nco.h> #include <gnuradio/fxpt_nco.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class cw_encoder_impl : public cw_encoder class cw_encoder_impl : public cw_encoder {
{ private:
private:
const double d_samp_rate; const double d_samp_rate;
const double d_cw_freq; const double d_cw_freq;
const size_t d_wpm; const size_t d_wpm;
@ -50,17 +47,17 @@ namespace gr
std::string std::string
get_cw_symbol(char c); get_cw_symbol(char c);
public: public:
cw_encoder_impl (double samp_rate, double cw_freq, size_t wpm); cw_encoder_impl(double samp_rate, double cw_freq, size_t wpm);
~cw_encoder_impl (); ~cw_encoder_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_CW_ENCODER_IMPL_H */ #endif /* INCLUDED_SATNOGS_CW_ENCODER_IMPL_H */

View File

@ -37,65 +37,63 @@
#endif #endif
#include <volk/volk.h> #include <volk/volk.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
cw_to_symbol::sptr cw_to_symbol::sptr
cw_to_symbol::make (double sampling_rate, float threshold, float conf_level, cw_to_symbol::make(double sampling_rate, float threshold, float conf_level,
size_t wpm, size_t hysteresis) size_t wpm, size_t hysteresis)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm, new cw_to_symbol_impl(sampling_rate, threshold, conf_level, wpm,
hysteresis)); hysteresis));
} }
/* /*
* The private constructor * The private constructor
*/ */
cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold, cw_to_symbol_impl::cw_to_symbol_impl(double sampling_rate, float threshold,
float conf_level, size_t wpm, float conf_level, size_t wpm,
size_t hysteresis) : size_t hysteresis) :
gr::sync_block ("cw_to_symbol", gr::sync_block("cw_to_symbol",
gr::io_signature::make (1, 1, sizeof(float)), gr::io_signature::make(1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_sampling_rate (sampling_rate), d_sampling_rate(sampling_rate),
d_act_thrshld (threshold), d_act_thrshld(threshold),
d_confidence_level (conf_level), d_confidence_level(conf_level),
d_dot_samples ((1.2 / wpm) * sampling_rate), d_dot_samples((1.2 / wpm) * sampling_rate),
d_window_size (0), d_window_size(0),
d_window_cnt (0), d_window_cnt(0),
d_idle_cnt (0), d_idle_cnt(0),
d_dot_windows_num (0), d_dot_windows_num(0),
d_dec_state (NO_SYNC), d_dec_state(NO_SYNC),
d_prev_space_symbol (true) d_prev_space_symbol(true)
{ {
if (wpm < MIN_WPM) { if (wpm < MIN_WPM) {
throw std::invalid_argument ("Decoder can not handle such low WPM setting"); throw std::invalid_argument("Decoder can not handle such low WPM setting");
} }
if (wpm > MAX_WPM) { if (wpm > MAX_WPM) {
throw std::invalid_argument ( throw std::invalid_argument(
"Decoder can not handle such high WPM setting"); "Decoder can not handle such high WPM setting");
} }
if (conf_level > 1.0 || conf_level < 0.5) { if (conf_level > 1.0 || conf_level < 0.5) {
throw std::invalid_argument ( throw std::invalid_argument(
"Confidence level should be in the range [0.5, 1.0]"); "Confidence level should be in the range [0.5, 1.0]");
} }
if(hysteresis > d_dot_samples / 4) { if (hysteresis > d_dot_samples / 4) {
throw std::invalid_argument ("Too large hysteresis value"); throw std::invalid_argument("Too large hysteresis value");
} }
message_port_register_in (pmt::mp ("act_threshold")); message_port_register_in(pmt::mp("act_threshold"));
message_port_register_out (pmt::mp ("out")); message_port_register_out(pmt::mp("out"));
/* Register the message handlers */ /* Register the message handlers */
set_msg_handler ( set_msg_handler(
pmt::mp ("act_threshold"), pmt::mp("act_threshold"),
boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this, boost::bind(&cw_to_symbol_impl::set_act_threshold_msg_handler, this,
_1)); _1));
/* /*
@ -131,29 +129,29 @@ cw_to_symbol_impl::cw_to_symbol_impl (double sampling_rate, float threshold,
d_short_pause_windows_num = d_dash_windows_num; d_short_pause_windows_num = d_dash_windows_num;
d_long_pause_windows_num = 7 * d_dot_windows_num; d_long_pause_windows_num = 7 * d_dot_windows_num;
const int alignment_multiple = volk_get_alignment () const int alignment_multiple = volk_get_alignment()
/ (d_window_size * sizeof(float)); / (d_window_size * sizeof(float));
set_alignment (std::max (1, alignment_multiple)); set_alignment(std::max(1, alignment_multiple));
d_const_val = (float *) volk_malloc (d_window_size * sizeof(float), d_const_val = (float *) volk_malloc(d_window_size * sizeof(float),
volk_get_alignment ()); volk_get_alignment());
d_tmp = (float *) volk_malloc (d_window_size * sizeof(float), d_tmp = (float *) volk_malloc(d_window_size * sizeof(float),
volk_get_alignment ()); volk_get_alignment());
d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t), d_out = (int32_t *) volk_malloc(d_window_size * sizeof(int32_t),
volk_get_alignment ()); volk_get_alignment());
if (!d_const_val || !d_tmp || !d_out) { if (!d_const_val || !d_tmp || !d_out) {
throw std::runtime_error ("cw_to_symbol: Could not allocate memory"); throw std::runtime_error("cw_to_symbol: Could not allocate memory");
} }
for (i = 0; i < d_window_size; i++) { for (i = 0; i < d_window_size; i++) {
d_const_val[i] = threshold; d_const_val[i] = threshold;
} }
set_history (d_window_size); set_history(d_window_size);
} }
inline void inline void
cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s) cw_to_symbol_impl::send_symbol_msg(morse_symbol_t s)
{ {
if (s == MORSE_S_SPACE || s == MORSE_L_SPACE) { if (s == MORSE_S_SPACE || s == MORSE_L_SPACE) {
d_prev_space_symbol = true; d_prev_space_symbol = true;
@ -161,11 +159,11 @@ cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s)
else { else {
d_prev_space_symbol = false; d_prev_space_symbol = false;
} }
message_port_pub (pmt::mp ("out"), pmt::from_long (s)); message_port_pub(pmt::mp("out"), pmt::from_long(s));
} }
inline bool inline bool
cw_to_symbol_impl::check_conf_level (size_t cnt, size_t target) cw_to_symbol_impl::check_conf_level(size_t cnt, size_t target)
{ {
return ((float) cnt > target * d_confidence_level); return ((float) cnt > target * d_confidence_level);
} }
@ -173,15 +171,15 @@ cw_to_symbol_impl::check_conf_level (size_t cnt, size_t target)
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
cw_to_symbol_impl::~cw_to_symbol_impl () cw_to_symbol_impl::~cw_to_symbol_impl()
{ {
volk_free (d_const_val); volk_free(d_const_val);
volk_free (d_tmp); volk_free(d_tmp);
volk_free (d_out); volk_free(d_out);
} }
inline void inline void
cw_to_symbol_impl::set_idle () cw_to_symbol_impl::set_idle()
{ {
d_dec_state = NO_SYNC; d_dec_state = NO_SYNC;
d_window_cnt = 0; d_window_cnt = 0;
@ -189,42 +187,42 @@ cw_to_symbol_impl::set_idle ()
} }
inline void inline void
cw_to_symbol_impl::set_short_on () cw_to_symbol_impl::set_short_on()
{ {
d_dec_state = SEARCH_DOT; d_dec_state = SEARCH_DOT;
d_window_cnt = 1; d_window_cnt = 1;
} }
inline void inline void
cw_to_symbol_impl::set_long_on () cw_to_symbol_impl::set_long_on()
{ {
d_dec_state = SEARCH_DASH; d_dec_state = SEARCH_DASH;
} }
inline void inline void
cw_to_symbol_impl::set_search_space () cw_to_symbol_impl::set_search_space()
{ {
d_dec_state = SEARCH_SPACE; d_dec_state = SEARCH_SPACE;
d_window_cnt = 1; d_window_cnt = 1;
} }
void void
cw_to_symbol_impl::set_act_threshold_msg_handler (pmt::pmt_t msg) cw_to_symbol_impl::set_act_threshold_msg_handler(pmt::pmt_t msg)
{ {
if (pmt::is_pair (msg)) { if (pmt::is_pair(msg)) {
set_act_threshold (pmt::to_double (pmt::cdr (msg))); set_act_threshold(pmt::to_double(pmt::cdr(msg)));
} }
} }
int int
cw_to_symbol_impl::work (int noutput_items, cw_to_symbol_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
bool triggered; bool triggered;
size_t i; size_t i;
const float *in_old = (const float *) input_items[0]; const float *in_old = (const float *) input_items[0];
const float *in = in_old + history () - 1; const float *in = in_old + history() - 1;
if (noutput_items < 0) { if (noutput_items < 0) {
return noutput_items; return noutput_items;
@ -237,16 +235,16 @@ cw_to_symbol_impl::work (int noutput_items,
* Clamp the input so the window mean is not affected by strong spikes * Clamp the input so the window mean is not affected by strong spikes
* Good luck understanding this black magic shit! * Good luck understanding this black magic shit!
*/ */
triggered = is_triggered (in_old + i, d_window_size); triggered = is_triggered(in_old + i, d_window_size);
if (triggered) { if (triggered) {
LOG_DEBUG("Triggered!"); LOG_DEBUG("Triggered!");
set_short_on (); set_short_on();
return i + 1; return i + 1;
} }
} }
d_idle_cnt += noutput_items / d_window_size; d_idle_cnt += noutput_items / d_window_size;
if(d_idle_cnt > 10 * d_long_pause_windows_num) { if (d_idle_cnt > 10 * d_long_pause_windows_num) {
send_symbol_msg (MORSE_END_MSG_SPACE); send_symbol_msg(MORSE_END_MSG_SPACE);
d_idle_cnt = 0; d_idle_cnt = 0;
} }
return noutput_items; return noutput_items;
@ -254,24 +252,23 @@ cw_to_symbol_impl::work (int noutput_items,
/* From now one, we handle the input in multiples of a window */ /* From now one, we handle the input in multiples of a window */
for (i = 0; i < (size_t) noutput_items / d_window_size; i++) { for (i = 0; i < (size_t) noutput_items / d_window_size; i++) {
triggered = is_triggered (in + i * d_window_size, d_window_size); triggered = is_triggered(in + i * d_window_size, d_window_size);
switch (d_dec_state) switch (d_dec_state) {
{
case SEARCH_DOT: case SEARCH_DOT:
if (triggered) { if (triggered) {
d_window_cnt++; d_window_cnt++;
if (d_window_cnt > d_dot_windows_num) { if (d_window_cnt > d_dot_windows_num) {
set_long_on (); set_long_on();
LOG_DEBUG("Going to search for long sequence"); LOG_DEBUG("Going to search for long sequence");
} }
} }
else { else {
if (check_conf_level (d_window_cnt, d_dot_windows_num)) { if (check_conf_level(d_window_cnt, d_dot_windows_num)) {
LOG_DEBUG("DOT"); LOG_DEBUG("DOT");
send_symbol_msg (MORSE_DOT); send_symbol_msg(MORSE_DOT);
} }
LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt); LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt);
set_search_space (); set_search_space();
} }
break; break;
case SEARCH_DASH: case SEARCH_DASH:
@ -279,37 +276,37 @@ cw_to_symbol_impl::work (int noutput_items,
d_window_cnt++; d_window_cnt++;
} }
else { else {
if (check_conf_level (d_window_cnt, d_dash_windows_num)) { if (check_conf_level(d_window_cnt, d_dash_windows_num)) {
LOG_DEBUG("DASH"); LOG_DEBUG("DASH");
send_symbol_msg (MORSE_DASH); send_symbol_msg(MORSE_DASH);
} }
else { else {
LOG_DEBUG("DOT"); LOG_DEBUG("DOT");
send_symbol_msg (MORSE_DOT); send_symbol_msg(MORSE_DOT);
} }
set_search_space (); set_search_space();
LOG_DEBUG("Going to search for space"); LOG_DEBUG("Going to search for space");
} }
break; break;
case SEARCH_SPACE: case SEARCH_SPACE:
if (triggered) { if (triggered) {
if (check_conf_level (d_window_cnt, d_long_pause_windows_num)) { if (check_conf_level(d_window_cnt, d_long_pause_windows_num)) {
LOG_DEBUG("LONG SPACE"); LOG_DEBUG("LONG SPACE");
send_symbol_msg (MORSE_L_SPACE); send_symbol_msg(MORSE_L_SPACE);
} }
else if (check_conf_level (d_window_cnt, d_short_pause_windows_num)) { else if (check_conf_level(d_window_cnt, d_short_pause_windows_num)) {
LOG_DEBUG("SHORT SPACE"); LOG_DEBUG("SHORT SPACE");
send_symbol_msg (MORSE_S_SPACE); send_symbol_msg(MORSE_S_SPACE);
} }
set_short_on (); set_short_on();
LOG_DEBUG("Going to search for dot"); LOG_DEBUG("Going to search for dot");
} }
else { else {
d_window_cnt++; d_window_cnt++;
if (d_window_cnt > d_long_pause_windows_num) { if (d_window_cnt > d_long_pause_windows_num) {
LOG_DEBUG("LONG SPACE"); LOG_DEBUG("LONG SPACE");
send_symbol_msg (MORSE_L_SPACE); send_symbol_msg(MORSE_L_SPACE);
set_idle (); set_idle();
LOG_DEBUG("Going to idle"); LOG_DEBUG("Going to idle");
return (i + 1) * d_window_size; return (i + 1) * d_window_size;
} }
@ -327,7 +324,7 @@ cw_to_symbol_impl::work (int noutput_items,
* @param thrhld the new threshold. * @param thrhld the new threshold.
*/ */
void void
cw_to_symbol_impl::set_act_threshold (float thrhld) cw_to_symbol_impl::set_act_threshold(float thrhld)
{ {
d_act_thrshld = thrhld; d_act_thrshld = thrhld;
} }
@ -341,14 +338,14 @@ cw_to_symbol_impl::set_act_threshold (float thrhld)
* @param len number of samples to process * @param len number of samples to process
*/ */
inline void inline void
cw_to_symbol_impl::clamp_input (int32_t* out, const float* in, size_t len) cw_to_symbol_impl::clamp_input(int32_t *out, const float *in, size_t len)
{ {
volk_32f_x2_subtract_32f (d_tmp, in, d_const_val, len); volk_32f_x2_subtract_32f(d_tmp, in, d_const_val, len);
volk_32f_binary_slicer_32i (d_out, d_tmp, len); volk_32f_binary_slicer_32i(d_out, d_tmp, len);
} }
static inline int32_t static inline int32_t
hadd (const int32_t* in, size_t len) hadd(const int32_t *in, size_t len)
{ {
size_t i; size_t i;
int32_t cnt = 0; int32_t cnt = 0;
@ -359,12 +356,12 @@ hadd (const int32_t* in, size_t len)
} }
inline bool inline bool
cw_to_symbol_impl::is_triggered (const float* in, size_t len) cw_to_symbol_impl::is_triggered(const float *in, size_t len)
{ {
int32_t cnt; int32_t cnt;
clamp_input (d_out, in, len); clamp_input(d_out, in, len);
cnt = hadd (d_out, len); cnt = hadd(d_out, len);
return (cnt >= (int32_t) (d_window_size * d_confidence_level)) ? true : false; return (cnt >= (int32_t)(d_window_size * d_confidence_level)) ? true : false;
} }
} /* namespace satnogs */ } /* namespace satnogs */

View File

@ -25,20 +25,16 @@
#include <satnogs/morse.h> #include <satnogs/morse.h>
#include <satnogs/cw_to_symbol.h> #include <satnogs/cw_to_symbol.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class cw_to_symbol_impl : public cw_to_symbol class cw_to_symbol_impl : public cw_to_symbol {
{
typedef enum typedef enum {
{
NO_SYNC, SEARCH_DOT, SEARCH_DASH, SEARCH_SPACE NO_SYNC, SEARCH_DOT, SEARCH_DASH, SEARCH_SPACE
} cw_dec_state_t; } cw_dec_state_t;
private: private:
const double d_sampling_rate; const double d_sampling_rate;
float d_act_thrshld; float d_act_thrshld;
const float d_confidence_level; const float d_confidence_level;
@ -57,47 +53,47 @@ namespace gr
int32_t *d_out; int32_t *d_out;
inline void inline void
set_idle (); set_idle();
inline void inline void
set_short_on (); set_short_on();
inline void inline void
set_long_on (); set_long_on();
inline void inline void
set_search_space (); set_search_space();
inline void inline void
clamp_input (int32_t *out, const float *in, size_t len); clamp_input(int32_t *out, const float *in, size_t len);
inline bool inline bool
is_triggered (const float *in, size_t len); is_triggered(const float *in, size_t len);
inline void inline void
send_symbol_msg (morse_symbol_t s); send_symbol_msg(morse_symbol_t s);
inline bool inline bool
check_conf_level(size_t cnt, size_t target); check_conf_level(size_t cnt, size_t target);
void void
set_act_threshold_msg_handler (pmt::pmt_t msg); set_act_threshold_msg_handler(pmt::pmt_t msg);
public: public:
cw_to_symbol_impl (double sampling_rate, float threshold, cw_to_symbol_impl(double sampling_rate, float threshold,
float conf_level, size_t wpm, size_t hysteresis); float conf_level, size_t wpm, size_t hysteresis);
~cw_to_symbol_impl (); ~cw_to_symbol_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
void void
set_act_threshold (float thrhld); set_act_threshold(float thrhld);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_IMPL_H */ #endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_IMPL_H */

View File

@ -26,66 +26,64 @@
#include "debug_msg_source_impl.h" #include "debug_msg_source_impl.h"
#include <boost/chrono.hpp> #include <boost/chrono.hpp>
namespace gr namespace gr {
namespace satnogs {
debug_msg_source::sptr
debug_msg_source::make(const std::string &msg, double delay, bool repeat)
{ {
namespace satnogs return gnuradio::get_initial_sptr(
{ new debug_msg_source_impl(msg, delay, repeat));
}
debug_msg_source::sptr /*
debug_msg_source::make (const std::string &msg, double delay, bool repeat)
{
return gnuradio::get_initial_sptr (
new debug_msg_source_impl (msg, delay, repeat));
}
/*
* The private constructor * The private constructor
*/ */
debug_msg_source_impl::debug_msg_source_impl (const std::string &msg, debug_msg_source_impl::debug_msg_source_impl(const std::string &msg,
double delay, bool repeat) : double delay, bool repeat) :
gr::block ("debug_msg_source", gr::io_signature::make (0, 0, 0), gr::block("debug_msg_source", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_buf_len (msg.length ()), d_buf_len(msg.length()),
d_delay (delay), d_delay(delay),
d_repeat (repeat), d_repeat(repeat),
d_running (true) d_running(true)
{ {
d_buf = new uint8_t[msg.length ()]; d_buf = new uint8_t[msg.length()];
memcpy (d_buf, msg.c_str (), msg.length ()); memcpy(d_buf, msg.c_str(), msg.length());
message_port_register_out (pmt::mp ("msg")); message_port_register_out(pmt::mp("msg"));
boost::shared_ptr<boost::thread> ( boost::shared_ptr<boost::thread> (
new boost::thread ( new boost::thread(
boost::bind (&debug_msg_source_impl::msg_sender, this))); boost::bind(&debug_msg_source_impl::msg_sender, this)));
} }
void void
debug_msg_source_impl::msg_sender () debug_msg_source_impl::msg_sender()
{ {
pmt::pmt_t msg = pmt::make_blob (d_buf, d_buf_len); pmt::pmt_t msg = pmt::make_blob(d_buf, d_buf_len);
if (d_repeat) { if (d_repeat) {
while (d_running) { while (d_running) {
boost::this_thread::sleep_for ( boost::this_thread::sleep_for(
boost::chrono::milliseconds ((size_t) (d_delay * 1e3))); boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
message_port_pub (pmt::mp ("msg"), msg); message_port_pub(pmt::mp("msg"), msg);
} }
} }
else { else {
boost::this_thread::sleep_for ( boost::this_thread::sleep_for(
boost::chrono::milliseconds ((size_t) (d_delay * 1e3))); boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
message_port_pub (pmt::mp ("msg"), msg); message_port_pub(pmt::mp("msg"), msg);
}
} }
}
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
debug_msg_source_impl::~debug_msg_source_impl () debug_msg_source_impl::~debug_msg_source_impl()
{ {
d_running = false; d_running = false;
d_thread->join (); d_thread->join();
delete[] d_buf; delete[] d_buf;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -24,14 +24,11 @@
#include <satnogs/debug_msg_source.h> #include <satnogs/debug_msg_source.h>
#include <boost/thread.hpp> #include <boost/thread.hpp>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class debug_msg_source_impl : public debug_msg_source class debug_msg_source_impl : public debug_msg_source {
{ private:
private:
const size_t d_buf_len; const size_t d_buf_len;
const double d_delay; const double d_delay;
const bool d_repeat; const bool d_repeat;
@ -42,13 +39,13 @@ namespace gr
void void
msg_sender(); msg_sender();
public: public:
debug_msg_source_impl (const std::string &msg, double delay, bool repeat); debug_msg_source_impl(const std::string &msg, double delay, bool repeat);
~debug_msg_source_impl (); ~debug_msg_source_impl();
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_IMPL_H */ #endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_IMPL_H */

View File

@ -25,67 +25,65 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "debug_msg_source_raw_impl.h" #include "debug_msg_source_raw_impl.h"
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
debug_msg_source_raw::sptr debug_msg_source_raw::sptr
debug_msg_source_raw::make (const std::vector<uint8_t> &msg, double delay, debug_msg_source_raw::make(const std::vector<uint8_t> &msg, double delay,
bool repeat) bool repeat)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new debug_msg_source_raw_impl (msg, delay, repeat)); new debug_msg_source_raw_impl(msg, delay, repeat));
} }
/* /*
* The private constructor * The private constructor
*/ */
debug_msg_source_raw_impl::debug_msg_source_raw_impl ( debug_msg_source_raw_impl::debug_msg_source_raw_impl(
const std::vector<uint8_t> &msg, double delay, bool repeat) : const std::vector<uint8_t> &msg, double delay, bool repeat) :
gr::block ("debug_msg_source_raw", gr::io_signature::make (0, 0, 0), gr::block("debug_msg_source_raw", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_buf_len (msg.size ()), d_buf_len(msg.size()),
d_delay (delay), d_delay(delay),
d_repeat (repeat), d_repeat(repeat),
d_running (true) d_running(true)
{ {
d_buf = new uint8_t[msg.size()]; d_buf = new uint8_t[msg.size()];
memcpy (d_buf, msg.data(), msg.size()); memcpy(d_buf, msg.data(), msg.size());
message_port_register_out (pmt::mp ("msg")); message_port_register_out(pmt::mp("msg"));
boost::shared_ptr<boost::thread> ( boost::shared_ptr<boost::thread> (
new boost::thread ( new boost::thread(
boost::bind (&debug_msg_source_raw_impl::msg_sender, this))); boost::bind(&debug_msg_source_raw_impl::msg_sender, this)));
} }
void void
debug_msg_source_raw_impl::msg_sender () debug_msg_source_raw_impl::msg_sender()
{ {
pmt::pmt_t msg = pmt::make_blob (d_buf, d_buf_len); pmt::pmt_t msg = pmt::make_blob(d_buf, d_buf_len);
if (d_repeat) { if (d_repeat) {
while (d_running) { while (d_running) {
boost::this_thread::sleep_for ( boost::this_thread::sleep_for(
boost::chrono::milliseconds ((size_t) (d_delay * 1e3))); boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
message_port_pub (pmt::mp ("msg"), msg); message_port_pub(pmt::mp("msg"), msg);
} }
} }
else { else {
boost::this_thread::sleep_for ( boost::this_thread::sleep_for(
boost::chrono::milliseconds ((size_t) (d_delay * 1e3))); boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
message_port_pub (pmt::mp ("msg"), msg); message_port_pub(pmt::mp("msg"), msg);
}
} }
}
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
debug_msg_source_raw_impl::~debug_msg_source_raw_impl () debug_msg_source_raw_impl::~debug_msg_source_raw_impl()
{ {
d_running = false; d_running = false;
d_thread->join (); d_thread->join();
delete[] d_buf; delete[] d_buf;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -23,14 +23,11 @@
#include <satnogs/debug_msg_source_raw.h> #include <satnogs/debug_msg_source_raw.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class debug_msg_source_raw_impl : public debug_msg_source_raw class debug_msg_source_raw_impl : public debug_msg_source_raw {
{ private:
private:
const size_t d_buf_len; const size_t d_buf_len;
const double d_delay; const double d_delay;
const bool d_repeat; const bool d_repeat;
@ -39,16 +36,16 @@ namespace gr
uint8_t *d_buf; uint8_t *d_buf;
void void
msg_sender (); msg_sender();
public: public:
debug_msg_source_raw_impl (const std::vector<uint8_t> &msg, double delay, debug_msg_source_raw_impl(const std::vector<uint8_t> &msg, double delay,
bool repeat); bool repeat);
~debug_msg_source_raw_impl (); ~debug_msg_source_raw_impl();
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_IMPL_H */ #endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_IMPL_H */

View File

@ -25,10 +25,8 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <satnogs/decoder.h> #include <satnogs/decoder.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
int decoder::base_unique_id = 1; int decoder::base_unique_id = 1;
@ -37,7 +35,7 @@ int decoder::base_unique_id = 1;
* @return the unique id of the decoder object * @return the unique id of the decoder object
*/ */
int int
decoder::unique_id () decoder::unique_id()
{ {
return d_id; return d_id;
} }
@ -68,7 +66,7 @@ decoder::max_frame_len() const
} }
int int
decoder::sizeof_input_item () const decoder::sizeof_input_item() const
{ {
return d_sizeof_in; return d_sizeof_in;
} }

View File

@ -27,44 +27,42 @@
#include <satnogs/log.h> #include <satnogs/log.h>
#include <volk/volk.h> #include <volk/volk.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
doppler_correction_cc::sptr doppler_correction_cc::sptr
doppler_correction_cc::make (double target_freq, double sampling_rate, doppler_correction_cc::make(double target_freq, double sampling_rate,
size_t corrections_per_sec) size_t corrections_per_sec)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new doppler_correction_cc_impl (target_freq, sampling_rate, new doppler_correction_cc_impl(target_freq, sampling_rate,
corrections_per_sec)); corrections_per_sec));
} }
/* /*
* The private constructor * The private constructor
*/ */
doppler_correction_cc_impl::doppler_correction_cc_impl ( doppler_correction_cc_impl::doppler_correction_cc_impl(
double target_freq, double sampling_rate, size_t corrections_per_sec) : double target_freq, double sampling_rate, size_t corrections_per_sec) :
gr::sync_block ("doppler_correction_cc", gr::sync_block("doppler_correction_cc",
gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make (1, 1, sizeof(gr_complex))), gr::io_signature::make(1, 1, sizeof(gr_complex))),
d_target_freq (target_freq), d_target_freq(target_freq),
d_samp_rate (sampling_rate), d_samp_rate(sampling_rate),
d_update_period (sampling_rate / (double) corrections_per_sec), d_update_period(sampling_rate / (double) corrections_per_sec),
d_est_thrhld (7), d_est_thrhld(7),
d_corrections_per_sec (corrections_per_sec), d_corrections_per_sec(corrections_per_sec),
d_nco (), d_nco(),
/* A 3-rd order polynomial curve fitting is more than enough */ /* A 3-rd order polynomial curve fitting is more than enough */
d_doppler_fit_engine (3), d_doppler_fit_engine(3),
d_freq_diff (0.0), d_freq_diff(0.0),
d_have_est (false), d_have_est(false),
d_freq_est_num (0), d_freq_est_num(0),
d_corrections (0), d_corrections(0),
d_corrected_samples (0) d_corrected_samples(0)
{ {
message_port_register_in (pmt::mp ("freq")); message_port_register_in(pmt::mp("freq"));
message_port_register_in (pmt::mp ("reset")); message_port_register_in(pmt::mp("reset"));
/* /*
* NOTE: * NOTE:
@ -75,85 +73,85 @@ namespace gr
* This is taken into consideration due to the fact that the work() * This is taken into consideration due to the fact that the work()
* and the input message handler are NOT reentrant. * and the input message handler are NOT reentrant.
*/ */
set_max_noutput_items (d_samp_rate / 2.0); set_max_noutput_items(d_samp_rate / 2.0);
set_alignment (8); set_alignment(8);
set_msg_handler ( set_msg_handler(
pmt::mp ("freq"), pmt::mp("freq"),
boost::bind (&doppler_correction_cc_impl::new_freq, this, _1)); boost::bind(&doppler_correction_cc_impl::new_freq, this, _1));
set_msg_handler ( set_msg_handler(
pmt::mp ("reset"), pmt::mp("reset"),
boost::bind (&doppler_correction_cc_impl::reset, this, _1)); boost::bind(&doppler_correction_cc_impl::reset, this, _1));
/* Allocate the buffer that will hold the predicted frequency differences */ /* Allocate the buffer that will hold the predicted frequency differences */
d_predicted_freqs = new double[d_corrections_per_sec]; d_predicted_freqs = new double[d_corrections_per_sec];
/* Allocate aligned memory for the NCO */ /* Allocate aligned memory for the NCO */
d_nco_buff = (gr_complex *) volk_malloc ( d_nco_buff = (gr_complex *) volk_malloc(
d_update_period * sizeof(gr_complex), 32); d_update_period * sizeof(gr_complex), 32);
if (!d_nco_buff) { if (!d_nco_buff) {
throw std::runtime_error ("Could not allocate NCO memory"); throw std::runtime_error("Could not allocate NCO memory");
}
} }
}
void void
doppler_correction_cc_impl::new_freq (pmt::pmt_t msg) doppler_correction_cc_impl::new_freq(pmt::pmt_t msg)
{ {
boost::mutex::scoped_lock lock (d_mutex); boost::mutex::scoped_lock lock(d_mutex);
double new_freq; double new_freq;
new_freq = pmt::to_double (msg); new_freq = pmt::to_double(msg);
d_freq_diff = new_freq - d_target_freq; d_freq_diff = new_freq - d_target_freq;
if (!d_have_est) { if (!d_have_est) {
d_freq_est_num++; d_freq_est_num++;
d_doppler_freqs.push_back ( d_doppler_freqs.push_back(
freq_drift (nitems_written (0), d_freq_diff)); freq_drift(nitems_written(0), d_freq_diff));
if (d_freq_est_num > d_est_thrhld - 1) { if (d_freq_est_num > d_est_thrhld - 1) {
d_doppler_fit_engine.fit (d_doppler_freqs); d_doppler_fit_engine.fit(d_doppler_freqs);
d_doppler_fit_engine.predict_freqs (d_predicted_freqs, d_doppler_fit_engine.predict_freqs(d_predicted_freqs,
d_corrections_per_sec, d_corrections_per_sec,
d_update_period); d_update_period);
d_have_est = true; d_have_est = true;
} }
} }
else { else {
d_doppler_freqs.pop_front (); d_doppler_freqs.pop_front();
d_doppler_freqs.push_back ( d_doppler_freqs.push_back(
freq_drift (nitems_written (0), d_freq_diff)); freq_drift(nitems_written(0), d_freq_diff));
/* Fit the doppler drift based on the new estimated frequency */ /* Fit the doppler drift based on the new estimated frequency */
d_doppler_fit_engine.fit (d_doppler_freqs); d_doppler_fit_engine.fit(d_doppler_freqs);
/* Predict the frequency differences for the near future */ /* Predict the frequency differences for the near future */
d_doppler_fit_engine.predict_freqs (d_predicted_freqs, d_doppler_fit_engine.predict_freqs(d_predicted_freqs,
d_corrections_per_sec, d_corrections_per_sec,
d_update_period); d_update_period);
d_corrections = 0; d_corrections = 0;
} }
} }
void void
doppler_correction_cc_impl::reset (pmt::pmt_t msg) doppler_correction_cc_impl::reset(pmt::pmt_t msg)
{ {
boost::mutex::scoped_lock lock (d_mutex); boost::mutex::scoped_lock lock(d_mutex);
d_doppler_freqs.clear (); d_doppler_freqs.clear();
d_freq_est_num = 0; d_freq_est_num = 0;
d_corrections = 0; d_corrections = 0;
d_have_est = false; d_have_est = false;
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
doppler_correction_cc_impl::~doppler_correction_cc_impl () doppler_correction_cc_impl::~doppler_correction_cc_impl()
{ {
delete[] d_predicted_freqs; delete[] d_predicted_freqs;
volk_free (d_nco_buff); volk_free(d_nco_buff);
} }
int int
doppler_correction_cc_impl::work (int noutput_items, doppler_correction_cc_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const gr_complex *in = (const gr_complex *) input_items[0]; const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0]; gr_complex *out = (gr_complex *) output_items[0];
int produced = 0; int produced = 0;
@ -171,9 +169,9 @@ namespace gr
* compute and store the NCO buffer with the corresponding frequency * compute and store the NCO buffer with the corresponding frequency
*/ */
if (d_corrected_samples == 0) { if (d_corrected_samples == 0) {
d_nco.set_freq ( d_nco.set_freq(
2 * M_PI * (-d_predicted_freqs[d_corrections]) / d_samp_rate); 2 * M_PI * (-d_predicted_freqs[d_corrections]) / d_samp_rate);
d_nco.sincos (d_nco_buff, d_update_period, 1.0); d_nco.sincos(d_nco_buff, d_update_period, 1.0);
d_corrections++; d_corrections++;
/* /*
@ -181,17 +179,17 @@ namespace gr
* should continue using the predicted frequencies * should continue using the predicted frequencies
*/ */
if (d_corrections == d_corrections_per_sec) { if (d_corrections == d_corrections_per_sec) {
d_doppler_fit_engine.predict_freqs (d_predicted_freqs, d_doppler_fit_engine.predict_freqs(d_predicted_freqs,
d_corrections_per_sec, d_corrections_per_sec,
d_update_period); d_update_period);
d_corrections = 0; d_corrections = 0;
} }
} }
cnt = std::min (d_update_period - d_corrected_samples, cnt = std::min(d_update_period - d_corrected_samples,
(size_t) (noutput_items - produced)); (size_t)(noutput_items - produced));
/* Perform the doppler shift correction */ /* Perform the doppler shift correction */
volk_32fc_x2_multiply_32fc (out + produced, in + produced, volk_32fc_x2_multiply_32fc(out + produced, in + produced,
d_nco_buff + d_corrected_samples, cnt); d_nco_buff + d_corrected_samples, cnt);
/* Make the proper advances */ /* Make the proper advances */
@ -204,12 +202,12 @@ namespace gr
} }
} }
else { else {
memcpy (out, in, noutput_items * sizeof(gr_complex)); memcpy(out, in, noutput_items * sizeof(gr_complex));
} }
return noutput_items; return noutput_items;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -27,14 +27,11 @@
#include <gnuradio/fxpt_nco.h> #include <gnuradio/fxpt_nco.h>
#include <deque> #include <deque>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class doppler_correction_cc_impl : public doppler_correction_cc class doppler_correction_cc_impl : public doppler_correction_cc {
{ private:
private:
const double d_target_freq; const double d_target_freq;
const double d_samp_rate; const double d_samp_rate;
const size_t d_update_period; const size_t d_update_period;
@ -54,23 +51,23 @@ namespace gr
boost::mutex d_mutex; boost::mutex d_mutex;
void void
new_freq (pmt::pmt_t msg); new_freq(pmt::pmt_t msg);
void void
reset (pmt::pmt_t msg); reset(pmt::pmt_t msg);
public: public:
doppler_correction_cc_impl (double target_freq, double sampling_rate, doppler_correction_cc_impl(double target_freq, double sampling_rate,
size_t corrections_per_sec); size_t corrections_per_sec);
~doppler_correction_cc_impl (); ~doppler_correction_cc_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H */ #endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H */

View File

@ -27,22 +27,20 @@
#include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/lu.hpp> #include <boost/numeric/ublas/lu.hpp>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/** /**
* Creates a polynomial fitting routine. * Creates a polynomial fitting routine.
* @param degree the degree of the polynomial * @param degree the degree of the polynomial
*/ */
doppler_fit::doppler_fit (size_t degree) : doppler_fit::doppler_fit(size_t degree) :
d_degree(degree), d_degree(degree),
d_last_x(0.0) d_last_x(0.0)
{ {
} }
/** /**
* This method calculates the coefficients of the polynomial that will * This method calculates the coefficients of the polynomial that will
* be used by the predict_freqs() method to produce simulated frequency * be used by the predict_freqs() method to produce simulated frequency
* differences * differences
@ -50,9 +48,9 @@ namespace gr
* corresponding timings that these frequencies diffrences occured. Time is * corresponding timings that these frequencies diffrences occured. Time is
* measured in samples since the start of the flowgraph execution. * measured in samples since the start of the flowgraph execution.
*/ */
void void
doppler_fit::fit (std::deque<freq_drift> drifts) doppler_fit::fit(std::deque<freq_drift> drifts)
{ {
size_t i; size_t i;
size_t j; size_t j;
size_t s; size_t s;
@ -60,34 +58,34 @@ namespace gr
double val; double val;
s = drifts.size(); s = drifts.size();
boost::numeric::ublas::matrix<double> x_matrix(s, d_degree+1); boost::numeric::ublas::matrix<double> x_matrix(s, d_degree + 1);
boost::numeric::ublas::matrix<double> y_matrix(s, 1); boost::numeric::ublas::matrix<double> y_matrix(s, 1);
for(i = 0; i < s; i++){ for (i = 0; i < s; i++) {
y_matrix(i, 0) = drifts[i].get_freq_drift(); y_matrix(i, 0) = drifts[i].get_freq_drift();
} }
for(i = 0; i < s; i++){ for (i = 0; i < s; i++) {
val = 1.0; val = 1.0;
for(j = 0; j < d_degree + 1; j++) { for (j = 0; j < d_degree + 1; j++) {
x_matrix(i, j) = val; x_matrix(i, j) = val;
val *= drifts[i].get_x(); val *= drifts[i].get_x();
} }
} }
/* Transpose the matrix with the x values */ /* Transpose the matrix with the x values */
boost::numeric::ublas::matrix<double> tx_matrix ( boost::numeric::ublas::matrix<double> tx_matrix(
boost::numeric::ublas::trans (x_matrix)); boost::numeric::ublas::trans(x_matrix));
boost::numeric::ublas::matrix<double> txx_matrix ( boost::numeric::ublas::matrix<double> txx_matrix(
boost::numeric::ublas::prec_prod(tx_matrix, x_matrix)); boost::numeric::ublas::prec_prod(tx_matrix, x_matrix));
boost::numeric::ublas::matrix<double> txy_matrix ( boost::numeric::ublas::matrix<double> txy_matrix(
boost::numeric::ublas::prec_prod(tx_matrix, y_matrix)); boost::numeric::ublas::prec_prod(tx_matrix, y_matrix));
boost::numeric::ublas::permutation_matrix<int> perm(txx_matrix.size1()); boost::numeric::ublas::permutation_matrix<int> perm(txx_matrix.size1());
singular = boost::numeric::ublas::lu_factorize(txx_matrix, perm); singular = boost::numeric::ublas::lu_factorize(txx_matrix, perm);
BOOST_ASSERT( singular == 0 ); BOOST_ASSERT(singular == 0);
boost::numeric::ublas::lu_substitute(txx_matrix, perm, txy_matrix); boost::numeric::ublas::lu_substitute(txx_matrix, perm, txy_matrix);
@ -99,9 +97,9 @@ namespace gr
d_coeff = std::vector<double> (txy_matrix.data().begin(), d_coeff = std::vector<double> (txy_matrix.data().begin(),
txy_matrix.data().end()); txy_matrix.data().end());
d_last_x = drifts[s - 1].get_x(); d_last_x = drifts[s - 1].get_x();
} }
/** /**
* Creates a number of frequency differences predictions using polynomial * Creates a number of frequency differences predictions using polynomial
* curve fitting. * curve fitting.
* @param freqs buffer that will hold the predicted frequency differences. * @param freqs buffer that will hold the predicted frequency differences.
@ -112,21 +110,21 @@ namespace gr
* @param samples_per_correction the number of samples elapsed between each * @param samples_per_correction the number of samples elapsed between each
* correction. * correction.
*/ */
void void
doppler_fit::predict_freqs (double *freqs, size_t ncorrections, doppler_fit::predict_freqs(double *freqs, size_t ncorrections,
size_t samples_per_correction) size_t samples_per_correction)
{ {
size_t i; size_t i;
size_t j; size_t j;
double predicted_freq_diff; double predicted_freq_diff;
double x; double x;
double xT; double xT;
boost::mutex::scoped_lock lock(d_mutex); boost::mutex::scoped_lock lock(d_mutex);
for(i = 0; i < ncorrections; i++){ for (i = 0; i < ncorrections; i++) {
predicted_freq_diff = 0.0; predicted_freq_diff = 0.0;
xT = 1.0; xT = 1.0;
x = d_last_x + i * samples_per_correction; x = d_last_x + i * samples_per_correction;
for(j = 0; j < d_degree + 1; j++){ for (j = 0; j < d_degree + 1; j++) {
predicted_freq_diff += d_coeff[j] * xT; predicted_freq_diff += d_coeff[j] * xT;
xT *= x; xT *= x;
} }
@ -138,8 +136,8 @@ namespace gr
* fitness of the polynomial. For this reason we alter the last x * fitness of the polynomial. For this reason we alter the last x
*/ */
d_last_x = d_last_x + (ncorrections + 1) * samples_per_correction; d_last_x = d_last_x + (ncorrections + 1) * samples_per_correction;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -31,16 +31,14 @@
#include <satnogs/utils.h> #include <satnogs/utils.h>
#include <arpa/inet.h> #include <arpa/inet.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
frame_acquisition::sptr frame_acquisition::sptr
frame_acquisition::make (variant_t variant, frame_acquisition::make(variant_t variant,
const std::vector<uint8_t>& preamble, const std::vector<uint8_t> &preamble,
size_t preamble_threshold, size_t preamble_threshold,
const std::vector<uint8_t>& sync, const std::vector<uint8_t> &sync,
size_t sync_threshold, size_t sync_threshold,
size_t frame_size_field_len, size_t frame_size_field_len,
size_t frame_len, size_t frame_len,
@ -48,8 +46,8 @@ frame_acquisition::make (variant_t variant,
whitening::whitening_sptr descrambler, whitening::whitening_sptr descrambler,
size_t max_frame_len) size_t max_frame_len)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new frame_acquisition_impl (variant, new frame_acquisition_impl(variant,
preamble, preamble,
preamble_threshold, preamble_threshold,
sync, sync,
@ -61,19 +59,19 @@ frame_acquisition::make (variant_t variant,
max_frame_len)); max_frame_len));
} }
frame_acquisition_impl::frame_acquisition_impl (variant_t variant, frame_acquisition_impl::frame_acquisition_impl(variant_t variant,
const std::vector<uint8_t>& preamble, const std::vector<uint8_t> &preamble,
size_t preamble_threshold, size_t preamble_threshold,
const std::vector<uint8_t>& sync, const std::vector<uint8_t> &sync,
size_t sync_threshold, size_t sync_threshold,
size_t frame_size_field_len, size_t frame_size_field_len,
size_t frame_len, size_t frame_len,
checksum_t crc, checksum_t crc,
whitening::whitening_sptr descrambler, whitening::whitening_sptr descrambler,
size_t max_frame_len) : size_t max_frame_len) :
gr::sync_block ("frame_acquisition", gr::sync_block("frame_acquisition",
gr::io_signature::make (1, 1, sizeof(uint8_t)), gr::io_signature::make(1, 1, sizeof(uint8_t)),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_variant(variant), d_variant(variant),
d_preamble(preamble.size() * 8), d_preamble(preamble.size() * 8),
d_preamble_shift_reg(preamble.size() * 8), d_preamble_shift_reg(preamble.size() * 8),
@ -93,7 +91,7 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
d_whitening(descrambler) d_whitening(descrambler)
{ {
set_output_multiple(8); set_output_multiple(8);
for(uint8_t b : preamble) { for (uint8_t b : preamble) {
d_preamble <<= (b >> 7); d_preamble <<= (b >> 7);
d_preamble <<= ((b >> 6) & 0x1); d_preamble <<= ((b >> 6) & 0x1);
d_preamble <<= ((b >> 5) & 0x1); d_preamble <<= ((b >> 5) & 0x1);
@ -103,7 +101,7 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
d_preamble <<= ((b >> 1) & 0x1); d_preamble <<= ((b >> 1) & 0x1);
d_preamble <<= (b & 0x1); d_preamble <<= (b & 0x1);
} }
for(uint8_t b : sync) { for (uint8_t b : sync) {
d_sync <<= (b >> 7); d_sync <<= (b >> 7);
d_sync <<= ((b >> 6) & 0x1); d_sync <<= ((b >> 6) & 0x1);
d_sync <<= ((b >> 5) & 0x1); d_sync <<= ((b >> 5) & 0x1);
@ -116,44 +114,44 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
/* Parameters checking */ /* Parameters checking */
if (max_frame_len == 0) { if (max_frame_len == 0) {
throw std::invalid_argument ( throw std::invalid_argument(
"The maximum frame size should be at least 1 byte"); "The maximum frame size should be at least 1 byte");
} }
if(d_sync_len < 8) { if (d_sync_len < 8) {
throw std::invalid_argument("SYNC word should be at least 8 bits"); throw std::invalid_argument("SYNC word should be at least 8 bits");
} }
if(d_preamble_len < 8) { if (d_preamble_len < 8) {
throw std::invalid_argument("Preamble should be at least 8 bits"); throw std::invalid_argument("Preamble should be at least 8 bits");
} }
if (d_preamble_len < 2 * d_preamble_thrsh) { if (d_preamble_len < 2 * d_preamble_thrsh) {
throw std::invalid_argument ( throw std::invalid_argument(
"Too many error bits are allowed for the preamble." "Too many error bits are allowed for the preamble."
"Consider lowering the threshold"); "Consider lowering the threshold");
} }
if (d_sync_len < 2 * d_sync_thrsh) { if (d_sync_len < 2 * d_sync_thrsh) {
throw std::invalid_argument ( throw std::invalid_argument(
"Too many error bits are allowed for the sync word. " "Too many error bits are allowed for the sync word. "
"Consider lowering the threshold"); "Consider lowering the threshold");
} }
if (d_frame_size_field_len > 4) { if (d_frame_size_field_len > 4) {
throw std::invalid_argument ("Frame length field can be up to 4 bytes"); throw std::invalid_argument("Frame length field can be up to 4 bytes");
} }
if (d_frame_size_field_len == 0 && d_variant != GENERIC_CONSTANT_FRAME_LEN) { if (d_frame_size_field_len == 0 && d_variant != GENERIC_CONSTANT_FRAME_LEN) {
throw std::invalid_argument ("Frame length field cannot be 0"); throw std::invalid_argument("Frame length field cannot be 0");
} }
if(d_variant == GENERIC_CONSTANT_FRAME_LEN) { if (d_variant == GENERIC_CONSTANT_FRAME_LEN) {
d_frame_size_field_len = 0; d_frame_size_field_len = 0;
} }
/* Set the CRC length */ /* Set the CRC length */
switch(d_crc) { switch (d_crc) {
case CRC16_CCITT: case CRC16_CCITT:
d_crc_len = 2; d_crc_len = 2;
break; break;
@ -180,7 +178,7 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
frame_acquisition_impl::~frame_acquisition_impl () frame_acquisition_impl::~frame_acquisition_impl()
{ {
delete [] d_pdu; delete [] d_pdu;
} }
@ -188,14 +186,13 @@ frame_acquisition_impl::~frame_acquisition_impl ()
int int
frame_acquisition_impl::work (int noutput_items, frame_acquisition_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const uint8_t *in = (const uint8_t *) input_items[0]; const uint8_t *in = (const uint8_t *) input_items[0];
switch(d_state) switch (d_state) {
{
case SEARCHING: case SEARCHING:
return searching_preamble(in, noutput_items); return searching_preamble(in, noutput_items);
case SEARCHING_SYNC: case SEARCHING_SYNC:
@ -212,31 +209,31 @@ frame_acquisition_impl::work (int noutput_items,
} }
int int
frame_acquisition_impl::searching_preamble (const uint8_t* in, int len) frame_acquisition_impl::searching_preamble(const uint8_t *in, int len)
{ {
for(int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
d_preamble_shift_reg <<= in[i]; d_preamble_shift_reg <<= in[i];
shift_reg tmp = d_preamble_shift_reg ^ d_preamble; shift_reg tmp = d_preamble_shift_reg ^ d_preamble;
if(tmp.count() <= d_preamble_thrsh) { if (tmp.count() <= d_preamble_thrsh) {
LOG_DEBUG("Found PREAMBLE"); LOG_DEBUG("Found PREAMBLE");
d_state = SEARCHING_SYNC; d_state = SEARCHING_SYNC;
d_cnt = 0; d_cnt = 0;
return i+1; return i + 1;
} }
} }
return len; return len;
} }
int int
frame_acquisition_impl::searching_sync (const uint8_t* in, int len) frame_acquisition_impl::searching_sync(const uint8_t *in, int len)
{ {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
d_sync_shift_reg <<= in[i]; d_sync_shift_reg <<= in[i];
shift_reg tmp = d_sync_shift_reg ^ d_sync; shift_reg tmp = d_sync_shift_reg ^ d_sync;
d_cnt++; d_cnt++;
if (tmp.count () <= d_sync_thrsh) { if (tmp.count() <= d_sync_thrsh) {
LOG_DEBUG("Found SYNC"); LOG_DEBUG("Found SYNC");
switch(d_variant) { switch (d_variant) {
case GENERIC_CONSTANT_FRAME_LEN: case GENERIC_CONSTANT_FRAME_LEN:
d_state = DECODING_PAYLOAD; d_state = DECODING_PAYLOAD;
break; break;
@ -253,7 +250,7 @@ frame_acquisition_impl::searching_sync (const uint8_t* in, int len)
} }
/* The sync word should be available by now */ /* The sync word should be available by now */
if(d_cnt > d_preamble_len * 2 + d_sync_len) { if (d_cnt > d_preamble_len * 2 + d_sync_len) {
reset(); reset();
return i + 1; return i + 1;
} }
@ -262,10 +259,10 @@ frame_acquisition_impl::searching_sync (const uint8_t* in, int len)
} }
int int
frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len) frame_acquisition_impl::dec_generic_frame_len(const uint8_t *in, int len)
{ {
const int s = std::min(len / 8, (int) d_frame_size_field_len); const int s = std::min(len / 8, (int) d_frame_size_field_len);
for(int i = 0; i < s; i++) { for (int i = 0; i < s; i++) {
uint8_t b = 0x0; uint8_t b = 0x0;
b |= in[i * 8] << 7; b |= in[i * 8] << 7;
b |= in[i * 8 + 1] << 6; b |= in[i * 8 + 1] << 6;
@ -278,9 +275,9 @@ frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len)
d_frame_len <<= 8; d_frame_len <<= 8;
d_frame_len |= b; d_frame_len |= b;
d_cnt++; d_cnt++;
if(d_cnt == d_frame_size_field_len) { if (d_cnt == d_frame_size_field_len) {
/* Most of the available modems apply whitening on the frame length too */ /* Most of the available modems apply whitening on the frame length too */
if(d_whitening) { if (d_whitening) {
uint32_t descrambled = 0x0; uint32_t descrambled = 0x0;
d_whitening->descramble((uint8_t *)&descrambled, d_whitening->descramble((uint8_t *)&descrambled,
(const uint8_t *)&d_frame_len, (const uint8_t *)&d_frame_len,
@ -293,7 +290,7 @@ frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len)
LOG_DEBUG("Found frame length: %u", d_frame_len); LOG_DEBUG("Found frame length: %u", d_frame_len);
/* Length field is needed for the CRC calculation */ /* Length field is needed for the CRC calculation */
for(uint32_t j = 0; j < d_frame_size_field_len; j++) { for (uint32_t j = 0; j < d_frame_size_field_len; j++) {
d_pdu[j] = (d_frame_len >> ((d_frame_size_field_len - 1 - j) * 8)) & 0xFF; d_pdu[j] = (d_frame_len >> ((d_frame_size_field_len - 1 - j) * 8)) & 0xFF;
} }
d_frame_len += d_frame_size_field_len; d_frame_len += d_frame_size_field_len;
@ -301,10 +298,10 @@ frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len)
/* Append the CRC length if any */ /* Append the CRC length if any */
d_frame_len += d_crc_len; d_frame_len += d_crc_len;
if(d_frame_len < d_max_frame_len) { if (d_frame_len < d_max_frame_len) {
d_state = DECODING_PAYLOAD; d_state = DECODING_PAYLOAD;
} }
else{ else {
reset(); reset();
return (i + 1) * 8; return (i + 1) * 8;
} }
@ -316,12 +313,12 @@ frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len)
} }
int int
frame_acquisition_impl::dec_golay24_frame_len (const uint8_t* in, int len) frame_acquisition_impl::dec_golay24_frame_len(const uint8_t *in, int len)
{ {
/* Golay24 needs 3 bytes to decode */ /* Golay24 needs 3 bytes to decode */
const int s = std::min(len / 8, 3); const int s = std::min(len / 8, 3);
d_frame_len = 0; d_frame_len = 0;
for(int i = 0; i < s; i++) { for (int i = 0; i < s; i++) {
uint8_t b = 0x0; uint8_t b = 0x0;
b |= in[i * 8] << 7; b |= in[i * 8] << 7;
b |= in[i * 8 + 1] << 6; b |= in[i * 8 + 1] << 6;
@ -338,16 +335,16 @@ frame_acquisition_impl::dec_golay24_frame_len (const uint8_t* in, int len)
/* Try to decode the frame length */ /* Try to decode the frame length */
if (d_cnt == 3) { if (d_cnt == 3) {
LOG_WARN("Len coded %u", d_frame_len); LOG_WARN("Len coded %u", d_frame_len);
if(d_whitening) { if (d_whitening) {
uint32_t descrambled = 0x0; uint32_t descrambled = 0x0;
d_whitening->descramble((uint8_t *) &descrambled, d_whitening->descramble((uint8_t *) &descrambled,
(const uint8_t *)&d_frame_len, 3, false); (const uint8_t *)&d_frame_len, 3, false);
d_frame_len = descrambled; d_frame_len = descrambled;
} }
d_frame_len = ((d_frame_len & 0xFFF) << 12) | (d_frame_len >> 12); d_frame_len = ((d_frame_len & 0xFFF) << 12) | (d_frame_len >> 12);
golay24 g = golay24 (); golay24 g = golay24();
uint32_t tmp = 0; uint32_t tmp = 0;
if (g.decode24 (&tmp, d_frame_len)) { if (g.decode24(&tmp, d_frame_len)) {
d_frame_len = tmp >> 12; d_frame_len = tmp >> 12;
LOG_WARN("Len %u", d_frame_len); LOG_WARN("Len %u", d_frame_len);
@ -355,16 +352,16 @@ frame_acquisition_impl::dec_golay24_frame_len (const uint8_t* in, int len)
d_frame_len += d_crc_len; d_frame_len += d_crc_len;
/* Check if the payload can fit in the buffer */ /* Check if the payload can fit in the buffer */
if(d_frame_len > d_max_frame_len) { if (d_frame_len > d_max_frame_len) {
reset(); reset();
return (i + 1) * 8; return (i + 1) * 8;
} }
else{ else {
d_state = DECODING_PAYLOAD; d_state = DECODING_PAYLOAD;
} }
} }
else { else {
reset (); reset();
return (i + 1) * 8; return (i + 1) * 8;
} }
d_cnt = 0; d_cnt = 0;
@ -375,10 +372,10 @@ frame_acquisition_impl::dec_golay24_frame_len (const uint8_t* in, int len)
} }
int int
frame_acquisition_impl::decoding (const uint8_t* in, int len) frame_acquisition_impl::decoding(const uint8_t *in, int len)
{ {
const int s = len / 8; const int s = len / 8;
for(int i = 0; i < s; i++) { for (int i = 0; i < s; i++) {
uint8_t b = 0x0; uint8_t b = 0x0;
b = in[i * 8] << 7; b = in[i * 8] << 7;
b |= in[i * 8 + 1] << 6; b |= in[i * 8 + 1] << 6;
@ -389,30 +386,30 @@ frame_acquisition_impl::decoding (const uint8_t* in, int len)
b |= in[i * 8 + 6] << 1; b |= in[i * 8 + 6] << 1;
b |= in[i * 8 + 7]; b |= in[i * 8 + 7];
d_pdu[d_cnt++] = b; d_pdu[d_cnt++] = b;
if(d_cnt == d_frame_len) { if (d_cnt == d_frame_len) {
if(d_whitening) { if (d_whitening) {
d_whitening->descramble(d_pdu + d_frame_size_field_len, d_whitening->descramble(d_pdu + d_frame_size_field_len,
d_pdu + d_frame_size_field_len, d_pdu + d_frame_size_field_len,
d_frame_len - d_frame_size_field_len, false); d_frame_len - d_frame_size_field_len, false);
} }
if (check_crc ()) { if (check_crc()) {
message_port_pub ( message_port_pub(
pmt::mp ("out"), pmt::mp("out"),
pmt::make_blob (d_pdu + d_frame_size_field_len, pmt::make_blob(d_pdu + d_frame_size_field_len,
d_frame_len - d_crc_len - d_frame_size_field_len)); d_frame_len - d_crc_len - d_frame_size_field_len));
} }
reset(); reset();
return (i+1) * 8; return (i + 1) * 8;
} }
} }
return len; return len;
} }
void void
frame_acquisition_impl::reset () frame_acquisition_impl::reset()
{ {
if(d_whitening) { if (d_whitening) {
d_whitening->reset(); d_whitening->reset();
} }
d_cnt = 0; d_cnt = 0;
@ -422,13 +419,13 @@ frame_acquisition_impl::reset ()
} }
bool bool
frame_acquisition_impl::check_crc () frame_acquisition_impl::check_crc()
{ {
uint16_t crc16_c; uint16_t crc16_c;
uint16_t crc16_received; uint16_t crc16_received;
uint32_t crc32_c; uint32_t crc32_c;
uint32_t crc32_received; uint32_t crc32_received;
switch(d_crc){ switch (d_crc) {
case CRC_NONE: case CRC_NONE:
return true; return true;
case CRC16_CCITT: case CRC16_CCITT:
@ -436,7 +433,7 @@ frame_acquisition_impl::check_crc ()
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2); memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
crc16_received = ntohs(crc16_received); crc16_received = ntohs(crc16_received);
LOG_DEBUG("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) { if (crc16_c == crc16_received) {
return true; return true;
} }
return false; return false;
@ -445,7 +442,7 @@ frame_acquisition_impl::check_crc ()
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2); memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
crc16_received = ntohs(crc16_received); crc16_received = ntohs(crc16_received);
LOG_DEBUG("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) { if (crc16_c == crc16_received) {
return true; return true;
} }
return false; return false;
@ -454,7 +451,7 @@ frame_acquisition_impl::check_crc ()
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2); memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
crc16_received = ntohs(crc16_received); crc16_received = ntohs(crc16_received);
LOG_WARN("Received: 0x%02x Computed: 0x%02x", crc16_received, crc16_c); LOG_WARN("Received: 0x%02x Computed: 0x%02x", crc16_received, crc16_c);
if(crc16_c == crc16_received) { if (crc16_c == crc16_received) {
return true; return true;
} }
return false; return false;
@ -462,7 +459,7 @@ frame_acquisition_impl::check_crc ()
crc32_c = crc32(d_pdu, d_frame_len - 4); crc32_c = crc32(d_pdu, d_frame_len - 4);
memcpy(&crc32_received, d_pdu + d_frame_len - 4, 4); memcpy(&crc32_received, d_pdu + d_frame_len - 4, 4);
crc32_received = ntohl(crc32_received); crc32_received = ntohl(crc32_received);
if(crc32_c == crc32_received) { if (crc32_c == crc32_received) {
return true; return true;
} }
return false; return false;

View File

@ -24,19 +24,16 @@
#include <satnogs/shift_reg.h> #include <satnogs/shift_reg.h>
#include <satnogs/frame_acquisition.h> #include <satnogs/frame_acquisition.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class frame_acquisition_impl : public frame_acquisition class frame_acquisition_impl : public frame_acquisition {
{
public: public:
frame_acquisition_impl (variant_t variant, frame_acquisition_impl(variant_t variant,
const std::vector<uint8_t>& preamble, const std::vector<uint8_t> &preamble,
size_t preamble_threshold, size_t preamble_threshold,
const std::vector<uint8_t>& sync, const std::vector<uint8_t> &sync,
size_t sync_threshold, size_t sync_threshold,
size_t frame_size_field_len, size_t frame_size_field_len,
size_t frame_len, size_t frame_len,
@ -44,19 +41,18 @@ public:
whitening::whitening_sptr descrambler, whitening::whitening_sptr descrambler,
size_t max_frame_len); size_t max_frame_len);
~frame_acquisition_impl (); ~frame_acquisition_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
private: private:
/** /**
* Decoding FSM * Decoding FSM
*/ */
typedef enum typedef enum {
{
SEARCHING, //!< when searching for the start of the preamble SEARCHING, //!< when searching for the start of the preamble
SEARCHING_SYNC, SEARCHING_SYNC,
DECODING_GENERIC_FRAME_LEN, DECODING_GENERIC_FRAME_LEN,

View File

@ -25,63 +25,61 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "frame_decoder_impl.h" #include "frame_decoder_impl.h"
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
frame_decoder::sptr frame_decoder::sptr
frame_decoder::make (decoder::decoder_sptr decoder_object, int input_size) frame_decoder::make(decoder::decoder_sptr decoder_object, int input_size)
{ {
return gnuradio::get_initial_sptr (new frame_decoder_impl (decoder_object, return gnuradio::get_initial_sptr(new frame_decoder_impl(decoder_object,
input_size)); input_size));
} }
/* /*
* The private constructor * The private constructor
*/ */
frame_decoder_impl::frame_decoder_impl (decoder::decoder_sptr decoder_object, frame_decoder_impl::frame_decoder_impl(decoder::decoder_sptr decoder_object,
int input_size) : int input_size) :
gr::sync_block ("frame_decoder", gr::sync_block("frame_decoder",
gr::io_signature::make (1, 1, input_size), gr::io_signature::make(1, 1, input_size),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_decoder (decoder_object) d_decoder(decoder_object)
{ {
if (input_size != decoder_object->sizeof_input_item ()) { if (input_size != decoder_object->sizeof_input_item()) {
throw std::invalid_argument ( throw std::invalid_argument(
"frame_decoder: Size mismatch between the block input and the decoder"); "frame_decoder: Size mismatch between the block input and the decoder");
} }
message_port_register_in (pmt::mp ("reset")); message_port_register_in(pmt::mp("reset"));
message_port_register_out (pmt::mp ("out")); message_port_register_out(pmt::mp("out"));
set_msg_handler (pmt::mp ("reset"), set_msg_handler(pmt::mp("reset"),
boost::bind (&frame_decoder_impl::reset, this, _1)); boost::bind(&frame_decoder_impl::reset, this, _1));
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
frame_decoder_impl::~frame_decoder_impl () frame_decoder_impl::~frame_decoder_impl()
{ {
} }
void void
frame_decoder_impl::reset (pmt::pmt_t m) frame_decoder_impl::reset(pmt::pmt_t m)
{ {
d_decoder->reset(); d_decoder->reset();
} }
int int
frame_decoder_impl::work (int noutput_items, frame_decoder_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const void *in = input_items[0]; const void *in = input_items[0];
decoder_status_t status = d_decoder->decode (in, noutput_items); decoder_status_t status = d_decoder->decode(in, noutput_items);
if (status.decode_success) { if (status.decode_success) {
message_port_pub (pmt::mp ("out"), status.data); message_port_pub(pmt::mp("out"), status.data);
} }
// Tell runtime system how many output items we produced. // Tell runtime system how many output items we produced.

View File

@ -23,21 +23,18 @@
#include <satnogs/frame_decoder.h> #include <satnogs/frame_decoder.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class frame_decoder_impl : public frame_decoder class frame_decoder_impl : public frame_decoder {
{
public: public:
frame_decoder_impl (decoder::decoder_sptr decoder_object, int input_size); frame_decoder_impl(decoder::decoder_sptr decoder_object, int input_size);
~frame_decoder_impl (); ~frame_decoder_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);

View File

@ -25,53 +25,51 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "frame_encoder_impl.h" #include "frame_encoder_impl.h"
namespace gr namespace gr {
namespace satnogs {
frame_encoder::sptr
frame_encoder::make(bool append_preamble, bool ecss_encap,
const std::string &dest_addr, uint8_t dest_ssid,
const std::string &src_addr, uint8_t src_ssid)
{ {
namespace satnogs return gnuradio::get_initial_sptr(
{ new frame_encoder_impl(append_preamble, ecss_encap, dest_addr,
frame_encoder::sptr
frame_encoder::make (bool append_preamble, bool ecss_encap,
const std::string& dest_addr, uint8_t dest_ssid,
const std::string& src_addr, uint8_t src_ssid)
{
return gnuradio::get_initial_sptr (
new frame_encoder_impl (append_preamble, ecss_encap, dest_addr,
dest_ssid, src_addr, src_ssid)); dest_ssid, src_addr, src_ssid));
} }
/* /*
* The private constructor * The private constructor
*/ */
frame_encoder_impl::frame_encoder_impl (bool append_preamble, frame_encoder_impl::frame_encoder_impl(bool append_preamble,
bool ecss_encap, bool ecss_encap,
const std::string& dest_addr, const std::string &dest_addr,
uint8_t dest_ssid, uint8_t dest_ssid,
const std::string& src_addr, const std::string &src_addr,
uint8_t src_ssid) : uint8_t src_ssid) :
gr::sync_block ("frame_encoder", gr::io_signature::make (0, 0, 0), gr::sync_block("frame_encoder", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)) gr::io_signature::make(0, 0, 0))
{ {
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
frame_encoder_impl::~frame_encoder_impl () frame_encoder_impl::~frame_encoder_impl()
{ {
} }
int int
frame_encoder_impl::work (int noutput_items, frame_encoder_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
// Do <+signal processing+> // Do <+signal processing+>
// Tell runtime system how many output items we produced. // Tell runtime system how many output items we produced.
return noutput_items; return noutput_items;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -23,29 +23,26 @@
#include <satnogs/frame_encoder.h> #include <satnogs/frame_encoder.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class frame_encoder_impl : public frame_encoder class frame_encoder_impl : public frame_encoder {
{ private:
private:
// Nothing to declare in this block. // Nothing to declare in this block.
public: public:
frame_encoder_impl (bool append_preamble, bool ecss_encap, frame_encoder_impl(bool append_preamble, bool ecss_encap,
const std::string& dest_addr, uint8_t dest_ssid, const std::string &dest_addr, uint8_t dest_ssid,
const std::string& src_addr, uint8_t src_ssid); const std::string &src_addr, uint8_t src_ssid);
~frame_encoder_impl (); ~frame_encoder_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FRAME_ENCODER_IMPL_H */ #endif /* INCLUDED_SATNOGS_FRAME_ENCODER_IMPL_H */

View File

@ -25,124 +25,116 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "frame_file_sink_impl.h" #include "frame_file_sink_impl.h"
namespace gr namespace gr {
namespace satnogs {
frame_file_sink::sptr
frame_file_sink::make(const std::string &prefix_name, int output_type)
{ {
namespace satnogs return gnuradio::get_initial_sptr(
{ new frame_file_sink_impl(prefix_name, output_type));
}
frame_file_sink::sptr /*
frame_file_sink::make (const std::string& prefix_name, int output_type)
{
return gnuradio::get_initial_sptr (
new frame_file_sink_impl (prefix_name, output_type));
}
/*
* The private constructor * The private constructor
*/ */
frame_file_sink_impl::frame_file_sink_impl (const std::string& prefix_name, frame_file_sink_impl::frame_file_sink_impl(const std::string &prefix_name,
int output_type) : int output_type) :
gr::block ("frame_file_sink", gr::io_signature::make (0, 0, 0), gr::block("frame_file_sink", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_prefix_name (prefix_name), d_prefix_name(prefix_name),
d_output_type (output_type), d_output_type(output_type),
d_filename_prev(""), d_filename_prev(""),
d_counter(0) d_counter(0)
{ {
message_port_register_in (pmt::mp ("frame")); message_port_register_in(pmt::mp("frame"));
set_msg_handler ( set_msg_handler(
pmt::mp ("frame"), pmt::mp("frame"),
boost::bind (&frame_file_sink_impl::msg_handler_frame, this, _1)); boost::bind(&frame_file_sink_impl::msg_handler_frame, this, _1));
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
frame_file_sink_impl::~frame_file_sink_impl () frame_file_sink_impl::~frame_file_sink_impl()
{ {
} }
void void
frame_file_sink_impl::msg_handler_frame (pmt::pmt_t msg) frame_file_sink_impl::msg_handler_frame(pmt::pmt_t msg)
{ {
/* check for the current UTC time */ /* check for the current UTC time */
std::chrono::system_clock::time_point p2 = std::chrono::system_clock::time_point p2 =
std::chrono::system_clock::now (); std::chrono::system_clock::now();
char buffer[30]; char buffer[30];
std::time_t t2 = std::chrono::system_clock::to_time_t (p2); std::time_t t2 = std::chrono::system_clock::to_time_t (p2);
struct tm * timeinfo; struct tm *timeinfo;
timeinfo = std::gmtime (&t2); timeinfo = std::gmtime(&t2);
std::strftime (buffer, 30, "%FT%H-%M-%S", timeinfo); std::strftime(buffer, 30, "%FT%H-%M-%S", timeinfo);
//puts (buffer); //puts (buffer);
/* create name of the file according prefix and timestamp */ /* create name of the file according prefix and timestamp */
std::string filename; std::string filename;
filename.append (d_prefix_name); filename.append(d_prefix_name);
filename.append ("_"); filename.append("_");
filename.append (buffer); filename.append(buffer);
if (filename.compare(d_filename_prev)==0) if (filename.compare(d_filename_prev) == 0) {
{
d_filename_prev.assign(filename); d_filename_prev.assign(filename);
filename.append ("_"); filename.append("_");
d_counter++; d_counter++;
filename.append(std::to_string(d_counter)); filename.append(std::to_string(d_counter));
} }
else else {
{
d_filename_prev.assign(filename); d_filename_prev.assign(filename);
d_counter=0; d_counter = 0;
} }
uint8_t *su; uint8_t *su;
switch (d_output_type) switch (d_output_type) {
{ case 0: {
case 0:
{
/* Binary form */ /* Binary form */
std::ofstream fd (filename.c_str ()); std::ofstream fd(filename.c_str());
fd.write ((const char *) pmt::blob_data (msg), fd.write((const char *) pmt::blob_data(msg),
pmt::blob_length (msg)); pmt::blob_length(msg));
fd.close (); fd.close();
break; break;
} }
case 1: case 1: {
{
/* aHex annotated, dd .txt to filename */ /* aHex annotated, dd .txt to filename */
filename.append (".txt"); filename.append(".txt");
std::ofstream fd (filename.c_str ()); std::ofstream fd(filename.c_str());
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
fd << "0x" << std::hex << std::setw (2) << std::setfill ('0') fd << "0x" << std::hex << std::setw(2) << std::setfill('0')
<< (uint32_t) su[i] << " "; << (uint32_t) su[i] << " ";
} }
fd.close (); fd.close();
break; break;
} }
case 2: case 2: {
{
/* Binary annotated, add .txt to filename */ /* Binary annotated, add .txt to filename */
filename.append (".txt"); filename.append(".txt");
std::ofstream fd (filename.c_str ()); std::ofstream fd(filename.c_str());
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
fd << "0b" << std::bitset<8> (su[i]) << " "; fd << "0b" << std::bitset<8> (su[i]) << " ";
} }
fd.close (); fd.close();
break; break;
} }
default: default:
throw std::invalid_argument ("Invalid format"); throw std::invalid_argument("Invalid format");
} }
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -26,28 +26,25 @@
#include <fstream> #include <fstream>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class frame_file_sink_impl : public frame_file_sink class frame_file_sink_impl : public frame_file_sink {
{ private:
private:
const std::string d_prefix_name; const std::string d_prefix_name;
int d_output_type; int d_output_type;
std::string d_filename_prev; std::string d_filename_prev;
int d_counter; int d_counter;
public: public:
frame_file_sink_impl (const std::string& prefix_name, int output_type); frame_file_sink_impl(const std::string &prefix_name, int output_type);
~frame_file_sink_impl (); ~frame_file_sink_impl();
void void
msg_handler_frame (pmt::pmt_t msg); msg_handler_frame(pmt::pmt_t msg);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_IMPL_H */ #endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_IMPL_H */

View File

@ -25,45 +25,43 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <satnogs/freq_drift.h> #include <satnogs/freq_drift.h>
namespace gr namespace gr {
namespace satnogs {
freq_drift::freq_drift(uint64_t x, double y) :
d_x(x),
d_freq_drift(y)
{ {
namespace satnogs }
{
freq_drift::freq_drift (uint64_t x, double y) : freq_drift::~freq_drift()
d_x (x), {
d_freq_drift (y) }
{
}
freq_drift::~freq_drift () double
{ freq_drift::get_freq_drift() const
} {
double
freq_drift::get_freq_drift () const
{
return d_freq_drift; return d_freq_drift;
} }
void void
freq_drift::set_freq_drift (double freq_drift) freq_drift::set_freq_drift(double freq_drift)
{ {
d_freq_drift = freq_drift; d_freq_drift = freq_drift;
} }
uint64_t uint64_t
freq_drift::get_x () const freq_drift::get_x() const
{ {
return d_x; return d_x;
} }
void void
freq_drift::set_x (uint64_t x) freq_drift::set_x(uint64_t x)
{ {
d_x = x; d_x = x;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -28,10 +28,8 @@
#include <satnogs/utils.h> #include <satnogs/utils.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/* /*
* Matrix P was retrieved by: * Matrix P was retrieved by:
@ -40,19 +38,21 @@ namespace satnogs
* Matrix mentioned by Morelos-Zaragoza, Robert H. "The art of error correcting coding." * Matrix mentioned by Morelos-Zaragoza, Robert H. "The art of error correcting coding."
* John Wiley & Sons, 2006 was not suitable. * John Wiley & Sons, 2006 was not suitable.
*/ */
const std::vector<uint32_t> golay24::G_P = const std::vector<uint32_t> golay24::G_P = {
{0x8ED, 0x1DB, 0x3B5, 0x769, 0xED1, 0xDA3, 0xB47, 0x68F, 0xD1D, 0xA3B, 0x477, 0x8ED, 0x1DB, 0x3B5, 0x769, 0xED1, 0xDA3, 0xB47, 0x68F, 0xD1D, 0xA3B, 0x477,
0xFFE}; 0xFFE
};
const std::vector<uint32_t> golay24::G_I = const std::vector<uint32_t> golay24::G_I = {
{ 0x800, 0x400, 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002, 0x800, 0x400, 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002,
0x001 }; 0x001
};
golay24::golay24 () golay24::golay24()
{ {
} }
golay24::~golay24 () golay24::~golay24()
{ {
} }
@ -66,7 +66,7 @@ static inline uint32_t
syndrome(uint16_t x, uint16_t y) syndrome(uint16_t x, uint16_t y)
{ {
uint32_t s = 0; uint32_t s = 0;
for(size_t i = 0; i < 12; i++) { for (size_t i = 0; i < 12; i++) {
s = (s << 1) | (weight(y & golay24::G_P[i]) % 2); s = (s << 1) | (weight(y & golay24::G_P[i]) % 2);
} }
s ^= x; s ^= x;
@ -82,7 +82,7 @@ syndrome(uint16_t x, uint16_t y)
* @return the coded 24-bit message. The message is placed at the 24 LS bits * @return the coded 24-bit message. The message is placed at the 24 LS bits
*/ */
uint32_t uint32_t
golay24::encode12 (uint16_t in, bool lsb_parity) golay24::encode12(uint16_t in, bool lsb_parity)
{ {
uint32_t c[2] = uint32_t c[2] =
{ 0x0, 0x0 }; { 0x0, 0x0 };
@ -94,7 +94,7 @@ golay24::encode12 (uint16_t in, bool lsb_parity)
} }
c[1] = (c[1] << 1) ^ tmp; c[1] = (c[1] << 1) ^ tmp;
} }
if(lsb_parity) { if (lsb_parity) {
return ((c[0] & 0xFFF) << 12) | (c[1] & 0xFFF); return ((c[0] & 0xFFF) << 12) | (c[1] & 0xFFF);
} }
return ((c[1] & 0xFFF) << 12) | (c[0] & 0xFFF); return ((c[1] & 0xFFF) << 12) | (c[0] & 0xFFF);
@ -121,14 +121,14 @@ golay24::decode24(uint32_t *out, const uint32_t in)
r[0] = (in >> 12) & 0xFFF; r[0] = (in >> 12) & 0xFFF;
r[1] = in & 0xFFF; r[1] = in & 0xFFF;
s = syndrome(r[0], r[1]); s = syndrome(r[0], r[1]);
if(weight(s) <= 3) { if (weight(s) <= 3) {
*out = ((r[0] ^ s) << 12) | (r[1]); *out = ((r[0] ^ s) << 12) | (r[1]);
return true; return true;
} }
for(size_t i = 0; i < 12; i++) { for (size_t i = 0; i < 12; i++) {
const uint16_t tmp = s ^ G_P[i]; const uint16_t tmp = s ^ G_P[i];
if(weight(tmp) <= 2) { if (weight(tmp) <= 2) {
*out = ((r[0] ^ tmp) << 12) | (r[1] ^ G_I[i]); *out = ((r[0] ^ tmp) << 12) | (r[1] ^ G_I[i]);
return true; return true;
} }
@ -136,17 +136,17 @@ golay24::decode24(uint32_t *out, const uint32_t in)
/* Compute the sP vector */ /* Compute the sP vector */
uint32_t sP = 0; uint32_t sP = 0;
for(size_t i = 0; i < 12; i++) { for (size_t i = 0; i < 12; i++) {
sP = (sP << 1) | (weight(s & G_P[i]) % 2); sP = (sP << 1) | (weight(s & G_P[i]) % 2);
} }
if(weight(sP) == 2 || weight(sP) == 3) { if (weight(sP) == 2 || weight(sP) == 3) {
*out = (r[0] << 12) | (r[1] ^ sP); *out = (r[0] << 12) | (r[1] ^ sP);
return true; return true;
} }
for(size_t i = 0; i < 12; i++) { for (size_t i = 0; i < 12; i++) {
const uint16_t tmp = sP ^ G_P[i]; const uint16_t tmp = sP ^ G_P[i];
if(weight(tmp) == 2) { if (weight(tmp) == 2) {
*out = ((r[0] ^ G_I[i]) << 12) | (r[1] ^ tmp); *out = ((r[0] ^ G_I[i]) << 12) | (r[1] ^ tmp);
return true; return true;
} }

View File

@ -26,19 +26,17 @@
#include <satnogs/ieee802_15_4_variant_decoder.h> #include <satnogs/ieee802_15_4_variant_decoder.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
ieee802_15_4_variant_decoder::ieee802_15_4_variant_decoder ( ieee802_15_4_variant_decoder::ieee802_15_4_variant_decoder(
const std::vector<uint8_t> &preamble, size_t preamble_threshold, const std::vector<uint8_t> &preamble, size_t preamble_threshold,
const std::vector<uint8_t> &sync, crc::crc_t crc, const std::vector<uint8_t> &sync, crc::crc_t crc,
whitening::whitening_sptr descrambler) whitening::whitening_sptr descrambler)
{ {
} }
ieee802_15_4_variant_decoder::~ieee802_15_4_variant_decoder () ieee802_15_4_variant_decoder::~ieee802_15_4_variant_decoder()
{ {
} }

View File

@ -27,81 +27,78 @@
#include <volk/volk.h> #include <volk/volk.h>
#include <stdexcept> #include <stdexcept>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
iq_sink::sptr iq_sink::sptr
iq_sink::make (const float scale, const char *filename, bool append, iq_sink::make(const float scale, const char *filename, bool append,
const int status) const int status)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new iq_sink_impl (scale, filename, append, status)); new iq_sink_impl(scale, filename, append, status));
} }
/* /*
* The private constructor * The private constructor
*/ */
iq_sink_impl::iq_sink_impl (const float scale, const char *filename, iq_sink_impl::iq_sink_impl(const float scale, const char *filename,
bool append, const int status) : bool append, const int status) :
gr::sync_block ("iq_sink", gr::sync_block("iq_sink",
gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
file_sink_base (filename, true, append), file_sink_base(filename, true, append),
d_scale (scale), d_scale(scale),
d_num_points (16384), d_num_points(16384),
d_status ((iq_sink_status_t) status) d_status((iq_sink_status_t) status)
{ {
set_max_noutput_items (d_num_points); set_max_noutput_items(d_num_points);
unsigned int alignment = volk_get_alignment (); unsigned int alignment = volk_get_alignment();
d_out = (int16_t*) volk_malloc (sizeof(int16_t) * d_num_points * 2, d_out = (int16_t *) volk_malloc(sizeof(int16_t) * d_num_points * 2,
alignment); alignment);
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
iq_sink_impl::~iq_sink_impl () iq_sink_impl::~iq_sink_impl()
{ {
volk_free (d_out); volk_free(d_out);
} }
int int
iq_sink_impl::work (int noutput_items, iq_sink_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
gr_complex *inbuf = (gr_complex*) input_items[0]; gr_complex *inbuf = (gr_complex *) input_items[0];
int nwritten = 0; int nwritten = 0;
switch (d_status) switch (d_status) {
{ case IQ_SINK_STATUS_NULL: {
case IQ_SINK_STATUS_NULL:
{
return noutput_items; return noutput_items;
} }
case IQ_SINK_STATUS_ACTIVE: case IQ_SINK_STATUS_ACTIVE: {
{
/* update d_fp is required */ /* update d_fp is required */
do_update (); do_update();
if (!d_fp) if (!d_fp)
/* drop output on the floor */ /* drop output on the floor */
{
return noutput_items; return noutput_items;
}
volk_32f_s32f_convert_16i (d_out, (float*) inbuf, d_scale, volk_32f_s32f_convert_16i(d_out, (float *) inbuf, d_scale,
noutput_items * 2); noutput_items * 2);
while (nwritten < noutput_items) { while (nwritten < noutput_items) {
int count = fwrite (d_out, 2 * sizeof(int16_t), int count = fwrite(d_out, 2 * sizeof(int16_t),
noutput_items - nwritten, d_fp); noutput_items - nwritten, d_fp);
if (count == 0) { if (count == 0) {
if (ferror (d_fp)) { if (ferror(d_fp)) {
std::cout << count << std::endl; std::cout << count << std::endl;
std::stringstream s; std::stringstream s;
s << "file_sink write failed with error " << fileno (d_fp) s << "file_sink write failed with error " << fileno(d_fp)
<< std::endl; << std::endl;
throw std::runtime_error (s.str ()); throw std::runtime_error(s.str());
} }
/* if EOF */ /* if EOF */
else { else {
@ -115,8 +112,8 @@ namespace gr
} }
/* Should never reach here */ /* Should never reach here */
return noutput_items; return noutput_items;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -25,19 +25,15 @@
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class iq_sink_impl : public iq_sink class iq_sink_impl : public iq_sink {
{ private:
private:
/** /**
* The different values for iq sink status * The different values for iq sink status
*/ */
typedef enum typedef enum {
{
IQ_SINK_STATUS_NULL = 0, //!< IQ_SINK_STATUS_NULL IQ sink block behaves just like a null sink IQ_SINK_STATUS_NULL = 0, //!< IQ_SINK_STATUS_NULL IQ sink block behaves just like a null sink
IQ_SINK_STATUS_ACTIVE = 1, //!< IQ_SINK_STATUS_ACTIVE IQ sink block is active IQ_SINK_STATUS_ACTIVE = 1, //!< IQ_SINK_STATUS_ACTIVE IQ sink block is active
} iq_sink_status_t; } iq_sink_status_t;
@ -47,17 +43,17 @@ namespace gr
float d_scale; float d_scale;
int16_t *d_out; int16_t *d_out;
public: public:
iq_sink_impl (const float scale, const char *filename, bool append, iq_sink_impl(const float scale, const char *filename, bool append,
const int status); const int status);
~iq_sink_impl (); ~iq_sink_impl();
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_IQ_SINK_IMPL_H */ #endif /* INCLUDED_SATNOGS_IQ_SINK_IMPL_H */

View File

@ -28,45 +28,43 @@
#include <json/json.h> #include <json/json.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
json_converter::sptr json_converter::sptr
json_converter::make (const std::string& extra) json_converter::make(const std::string &extra)
{ {
return gnuradio::get_initial_sptr (new json_converter_impl (extra)); return gnuradio::get_initial_sptr(new json_converter_impl(extra));
} }
/* /*
* The private constructor * The private constructor
*/ */
json_converter_impl::json_converter_impl (const std::string& extra) : json_converter_impl::json_converter_impl(const std::string &extra) :
gr::block ("json_converter", gr::io_signature::make (0, 0, 0), gr::block("json_converter", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_extra(extra) d_extra(extra)
{ {
message_port_register_in(pmt::mp("in")); message_port_register_in(pmt::mp("in"));
message_port_register_out(pmt::mp("out")); message_port_register_out(pmt::mp("out"));
set_msg_handler (pmt::mp ("in"), set_msg_handler(pmt::mp("in"),
boost::bind (&json_converter_impl::convert, this, _1)); boost::bind(&json_converter_impl::convert, this, _1));
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
json_converter_impl::~json_converter_impl () json_converter_impl::~json_converter_impl()
{ {
} }
void void
json_converter_impl::convert (pmt::pmt_t m) json_converter_impl::convert(pmt::pmt_t m)
{ {
Json::Value root = metadata::to_json(m); Json::Value root = metadata::to_json(m);
root["extra"] = d_extra; root["extra"] = d_extra;
const std::string& s = root.toStyledString(); const std::string &s = root.toStyledString();
const char *c = s.c_str(); const char *c = s.c_str();
message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length())); message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length()));
} }

View File

@ -23,17 +23,14 @@
#include <satnogs/json_converter.h> #include <satnogs/json_converter.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class json_converter_impl : public json_converter class json_converter_impl : public json_converter {
{
public: public:
json_converter_impl (const std::string &extra); json_converter_impl(const std::string &extra);
~json_converter_impl (); ~json_converter_impl();
void void
convert(pmt::pmt_t m); convert(pmt::pmt_t m);

View File

@ -29,25 +29,23 @@
extern "C" { extern "C" {
#include <fec.h> #include <fec.h>
} }
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
lrpt_decoder::sptr lrpt_decoder::sptr
lrpt_decoder::make () lrpt_decoder::make()
{ {
return gnuradio::get_initial_sptr (new lrpt_decoder_impl ()); return gnuradio::get_initial_sptr(new lrpt_decoder_impl());
} }
/* /*
* The private constructor * The private constructor
*/ */
lrpt_decoder_impl::lrpt_decoder_impl() lrpt_decoder_impl::lrpt_decoder_impl()
: gr::block("lrpt_decoder", : gr::block("lrpt_decoder",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)), gr::io_signature::make(0, 0, 0)),
/* /*
@ -57,7 +55,7 @@ lrpt_decoder_impl::lrpt_decoder_impl()
* Thus, they dropped the check symbols at the end of the frame. * Thus, they dropped the check symbols at the end of the frame.
*/ */
d_cadu_len(1020 + 4 - 128), d_cadu_len(1020 + 4 - 128),
d_coded_cadu_len(1020 * 2 + 4*2 - 128 * 2), d_coded_cadu_len(1020 * 2 + 4 * 2 - 128 * 2),
d_mpdu_max_len(59400), d_mpdu_max_len(59400),
d_scrambler(0x2A9, 0xFF, 7), d_scrambler(0x2A9, 0xFF, 7),
d_have_mpdu(false) d_have_mpdu(false)
@ -65,12 +63,12 @@ lrpt_decoder_impl::lrpt_decoder_impl()
message_port_register_in(pmt::mp("cadu")); message_port_register_in(pmt::mp("cadu"));
message_port_register_out(pmt::mp("frame")); message_port_register_out(pmt::mp("frame"));
set_msg_handler ( set_msg_handler(
pmt::mp ("cadu"), pmt::mp("cadu"),
boost::bind (&lrpt_decoder_impl::decode, this, _1)); boost::bind(&lrpt_decoder_impl::decode, this, _1));
d_vt = create_viterbi27(d_cadu_len * 8); d_vt = create_viterbi27(d_cadu_len * 8);
if(!d_vt) { if (!d_vt) {
throw std::runtime_error("lrpt_decoder: Failed to init Viterbi decoder"); throw std::runtime_error("lrpt_decoder: Failed to init Viterbi decoder");
} }
@ -86,7 +84,7 @@ lrpt_decoder_impl::lrpt_decoder_impl()
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
lrpt_decoder_impl::~lrpt_decoder_impl () lrpt_decoder_impl::~lrpt_decoder_impl()
{ {
delete [] d_cadu; delete [] d_cadu;
@ -95,17 +93,17 @@ lrpt_decoder_impl::~lrpt_decoder_impl ()
} }
void void
lrpt_decoder_impl::decode (pmt::pmt_t m) lrpt_decoder_impl::decode(pmt::pmt_t m)
{ {
const uint8_t *coded_cadu = (const uint8_t *)pmt::blob_data(m); const uint8_t *coded_cadu = (const uint8_t *)pmt::blob_data(m);
if(pmt::blob_length(m) != d_coded_cadu_len) { if (pmt::blob_length(m) != d_coded_cadu_len) {
LOG_ERROR("Wrong CADU size"); LOG_ERROR("Wrong CADU size");
return; return;
} }
init_viterbi27(d_vt, 0); init_viterbi27(d_vt, 0);
for(size_t i = 0; i < d_coded_cadu_len; i++) { for (size_t i = 0; i < d_coded_cadu_len; i++) {
d_coded_cadu_syms[i * 8] = 0xFF * (coded_cadu[i] >> 7); d_coded_cadu_syms[i * 8] = 0xFF * (coded_cadu[i] >> 7);
d_coded_cadu_syms[i * 8 + 1] = 0xFF * ((coded_cadu[i] >> 6) & 0x1); d_coded_cadu_syms[i * 8 + 1] = 0xFF * ((coded_cadu[i] >> 6) & 0x1);
d_coded_cadu_syms[i * 8 + 2] = 0xFF * ((coded_cadu[i] >> 5) & 0x1); d_coded_cadu_syms[i * 8 + 2] = 0xFF * ((coded_cadu[i] >> 5) & 0x1);
@ -131,10 +129,10 @@ void
lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu) lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu)
{ {
/* Check first the VCDU version and if encryption is off */ /* Check first the VCDU version and if encryption is off */
if( (cvcdu[0] >> 6) != 0x1) { if ((cvcdu[0] >> 6) != 0x1) {
return; return;
} }
if(cvcdu[6] != 0x0 || cvcdu[7] != 0x0) { if (cvcdu[6] != 0x0 || cvcdu[7] != 0x0) {
return; return;
} }
@ -147,7 +145,7 @@ lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu)
/* Check CCSDS packet version and type */ /* Check CCSDS packet version and type */
//if( (mpdu[0] >> 5) != 0x0) { //if( (mpdu[0] >> 5) != 0x0) {
// return; // return;
// } // }
uint32_t vcdu_seq = 0; uint32_t vcdu_seq = 0;
vcdu_seq = cvcdu[2]; vcdu_seq = cvcdu[2];
@ -159,8 +157,8 @@ lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu)
hdr_ptr = (hdr_ptr << 8) | cvcdu[9]; hdr_ptr = (hdr_ptr << 8) | cvcdu[9];
/* Try to find the start of a MPDU */ /* Try to find the start of a MPDU */
if(!d_have_mpdu) { if (!d_have_mpdu) {
if(hdr_ptr != 0) { if (hdr_ptr != 0) {
return; return;
} }
d_have_mpdu = true; d_have_mpdu = true;

View File

@ -25,17 +25,14 @@
#include <satnogs/convolutional_deinterleaver.h> #include <satnogs/convolutional_deinterleaver.h>
#include <satnogs/whitening.h> #include <satnogs/whitening.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class lrpt_decoder_impl : public lrpt_decoder class lrpt_decoder_impl : public lrpt_decoder {
{
public: public:
lrpt_decoder_impl (); lrpt_decoder_impl();
~lrpt_decoder_impl (); ~lrpt_decoder_impl();
private: private:
const size_t d_cadu_len; const size_t d_cadu_len;

View File

@ -30,24 +30,22 @@
#include <volk/volk.h> #include <volk/volk.h>
#include <gnuradio/blocks/count_bits.h> #include <gnuradio/blocks/count_bits.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
lrpt_sync::sptr lrpt_sync::sptr
lrpt_sync::make (size_t threshold) lrpt_sync::make(size_t threshold)
{ {
return gnuradio::get_initial_sptr (new lrpt_sync_impl (threshold)); return gnuradio::get_initial_sptr(new lrpt_sync_impl(threshold));
} }
/* /*
* The private constructor * The private constructor
*/ */
lrpt_sync_impl::lrpt_sync_impl (size_t threshold) : lrpt_sync_impl::lrpt_sync_impl(size_t threshold) :
gr::sync_block ("lrpt_sync", gr::sync_block("lrpt_sync",
gr::io_signature::make (1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_thresh(threshold), d_thresh(threshold),
d_asm_coded(0xd49c24ff2686b), d_asm_coded(0xd49c24ff2686b),
d_asm_coded_len(52), d_asm_coded_len(52),
@ -56,7 +54,7 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
* We process the data in a multiple of 2 frames and a UW * We process the data in a multiple of 2 frames and a UW
* sync word * sync word
*/ */
d_window((72 + 8)/2), d_window((72 + 8) / 2),
/* Each CADU has the 4 byte ASM and a VCDU of 1020 bytes*/ /* Each CADU has the 4 byte ASM and a VCDU of 1020 bytes*/
/* /*
* NOTE: * NOTE:
@ -65,7 +63,7 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
* For some unknown reasons, it seems that the RS encoding is not performed. * For some unknown reasons, it seems that the RS encoding is not performed.
* Thus, they dropped the check symbols at the end of the frame. * Thus, they dropped the check symbols at the end of the frame.
*/ */
d_coded_cadu_len(1020 * 2 + 4*2 - 128 * 2), d_coded_cadu_len(1020 * 2 + 4 * 2 - 128 * 2),
d_frame_sync(false), d_frame_sync(false),
d_received(0), d_received(0),
d_rotate(1.0, 0.0), d_rotate(1.0, 0.0),
@ -76,32 +74,32 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
d_shift_reg3(0x0) d_shift_reg3(0x0)
{ {
set_output_multiple(d_window); set_output_multiple(d_window);
const int alignment_multiple = volk_get_alignment () / sizeof(gr_complex); const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
set_alignment (std::max (1, alignment_multiple)); set_alignment(std::max(1, alignment_multiple));
d_rotate_pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex), d_rotate_pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
volk_get_alignment ()); volk_get_alignment());
if(!d_rotate_pi2) { if (!d_rotate_pi2) {
throw std::runtime_error("lrpt_sync: Could not allocate memory"); throw std::runtime_error("lrpt_sync: Could not allocate memory");
} }
d_rotate_2pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex), d_rotate_2pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
volk_get_alignment ()); volk_get_alignment());
if(!d_rotate_2pi2) { if (!d_rotate_2pi2) {
volk_free(d_rotate_pi2); volk_free(d_rotate_pi2);
throw std::runtime_error("lrpt_sync: Could not allocate memory"); throw std::runtime_error("lrpt_sync: Could not allocate memory");
} }
d_rotate_3pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex), d_rotate_3pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
volk_get_alignment ()); volk_get_alignment());
if(!d_rotate_3pi2) { if (!d_rotate_3pi2) {
volk_free(d_rotate_pi2); volk_free(d_rotate_pi2);
volk_free(d_rotate_2pi2); volk_free(d_rotate_2pi2);
throw std::runtime_error("lrpt_sync: Could not allocate memory"); throw std::runtime_error("lrpt_sync: Could not allocate memory");
} }
d_corrected = (gr_complex *)volk_malloc(d_window * sizeof(gr_complex), d_corrected = (gr_complex *)volk_malloc(d_window * sizeof(gr_complex),
volk_get_alignment ()); volk_get_alignment());
if(!d_corrected) { if (!d_corrected) {
volk_free(d_rotate_pi2); volk_free(d_rotate_pi2);
volk_free(d_rotate_2pi2); volk_free(d_rotate_2pi2);
volk_free(d_rotate_3pi2); volk_free(d_rotate_3pi2);
@ -119,19 +117,19 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
lrpt_sync_impl::~lrpt_sync_impl () lrpt_sync_impl::~lrpt_sync_impl()
{ {
volk_free (d_rotate_pi2); volk_free(d_rotate_pi2);
volk_free (d_rotate_2pi2); volk_free(d_rotate_2pi2);
volk_free (d_rotate_3pi2); volk_free(d_rotate_3pi2);
volk_free (d_corrected); volk_free(d_corrected);
delete [] d_coded_cadu; delete [] d_coded_cadu;
} }
bool bool
lrpt_sync_impl::found_sync(uint64_t reg) lrpt_sync_impl::found_sync(uint64_t reg)
{ {
return blocks::count_bits64 ((reg ^ d_asm_coded) & d_asm_coded_mask) return blocks::count_bits64((reg ^ d_asm_coded) & d_asm_coded_mask)
<= d_thresh; <= d_thresh;
} }
@ -141,7 +139,7 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
{ {
uint32_t bits; uint32_t bits;
int multiple = noutput_items / d_window; int multiple = noutput_items / d_window;
for(int i = 0; i < multiple; i++) { for (int i = 0; i < multiple; i++) {
volk_32fc_s32fc_multiply_32fc(d_rotate_pi2, in + i * d_window, volk_32fc_s32fc_multiply_32fc(d_rotate_pi2, in + i * d_window,
gr_complex(0.0, 1.0), d_window); gr_complex(0.0, 1.0), d_window);
volk_32fc_s32fc_multiply_32fc(d_rotate_2pi2, in + i * d_window, volk_32fc_s32fc_multiply_32fc(d_rotate_2pi2, in + i * d_window,
@ -152,11 +150,11 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
* Search for the sync pattern, rotating the QPSK constellation on * Search for the sync pattern, rotating the QPSK constellation on
* all possible positions * all possible positions
*/ */
for(int j = 0; j < d_window; j++) { for (int j = 0; j < d_window; j++) {
bits = d_qpsk->decision_maker(in + i * d_window + j); bits = d_qpsk->decision_maker(in + i * d_window + j);
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1); //bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
d_shift_reg0 = (d_shift_reg0 << 2) | bits; d_shift_reg0 = (d_shift_reg0 << 2) | bits;
if(found_sync(d_shift_reg0)) { if (found_sync(d_shift_reg0)) {
d_rotate = gr_complex(1.0, 0.0); d_rotate = gr_complex(1.0, 0.0);
d_frame_sync = true; d_frame_sync = true;
uint64_t asm_coded = htonll(d_shift_reg0); uint64_t asm_coded = htonll(d_shift_reg0);
@ -167,7 +165,7 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
bits = d_qpsk->decision_maker(d_rotate_pi2 + j); bits = d_qpsk->decision_maker(d_rotate_pi2 + j);
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1); //bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
d_shift_reg1 = (d_shift_reg1 << 2) | bits; d_shift_reg1 = (d_shift_reg1 << 2) | bits;
if(found_sync(d_shift_reg1)) { if (found_sync(d_shift_reg1)) {
d_rotate = gr_complex(0.0, 1.0); d_rotate = gr_complex(0.0, 1.0);
d_frame_sync = true; d_frame_sync = true;
uint64_t asm_coded = htonll(d_shift_reg1); uint64_t asm_coded = htonll(d_shift_reg1);
@ -178,7 +176,7 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
bits = d_qpsk->decision_maker(d_rotate_2pi2 + j); bits = d_qpsk->decision_maker(d_rotate_2pi2 + j);
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1); //bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
d_shift_reg2 = (d_shift_reg2 << 2) | bits; d_shift_reg2 = (d_shift_reg2 << 2) | bits;
if(found_sync(d_shift_reg2)) { if (found_sync(d_shift_reg2)) {
d_rotate = gr_complex(-1.0, 0.0); d_rotate = gr_complex(-1.0, 0.0);
d_frame_sync = true; d_frame_sync = true;
uint64_t asm_coded = htonll(d_shift_reg2); uint64_t asm_coded = htonll(d_shift_reg2);
@ -189,7 +187,7 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
bits = d_qpsk->decision_maker(d_rotate_3pi2 + j); bits = d_qpsk->decision_maker(d_rotate_3pi2 + j);
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1); //bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
d_shift_reg3 = (d_shift_reg3 << 2) | bits; d_shift_reg3 = (d_shift_reg3 << 2) | bits;
if(found_sync(d_shift_reg3)) { if (found_sync(d_shift_reg3)) {
d_rotate = gr_complex(0.0, -1.0); d_rotate = gr_complex(0.0, -1.0);
d_frame_sync = true; d_frame_sync = true;
uint64_t asm_coded = htonll(d_shift_reg3); uint64_t asm_coded = htonll(d_shift_reg3);
@ -206,10 +204,10 @@ lrpt_sync_impl::work_sync(const gr_complex *in, int noutput_items)
{ {
uint8_t b; uint8_t b;
int multiple = noutput_items / d_window; int multiple = noutput_items / d_window;
for(int i = 0; i < multiple; i++) { for (int i = 0; i < multiple; i++) {
volk_32fc_s32fc_multiply_32fc(d_corrected, in + i * d_window, volk_32fc_s32fc_multiply_32fc(d_corrected, in + i * d_window,
d_rotate, d_window); d_rotate, d_window);
for(int j = 0; j < d_window; j += 4) { for (int j = 0; j < d_window; j += 4) {
b = 0; b = 0;
b = d_qpsk->decision_maker(d_corrected + j) << 6; b = d_qpsk->decision_maker(d_corrected + j) << 6;
b |= d_qpsk->decision_maker(d_corrected + j + 1) << 4; b |= d_qpsk->decision_maker(d_corrected + j + 1) << 4;
@ -217,11 +215,11 @@ lrpt_sync_impl::work_sync(const gr_complex *in, int noutput_items)
b |= d_qpsk->decision_maker(d_corrected + j + 3); b |= d_qpsk->decision_maker(d_corrected + j + 3);
d_coded_cadu[d_received++] = b; d_coded_cadu[d_received++] = b;
if(d_received == d_coded_cadu_len) { if (d_received == d_coded_cadu_len) {
d_received = sizeof(uint64_t); d_received = sizeof(uint64_t);
d_frame_sync = false; d_frame_sync = false;
message_port_pub (pmt::mp ("cadu"), message_port_pub(pmt::mp("cadu"),
pmt::make_blob (d_coded_cadu, d_coded_cadu_len)); pmt::make_blob(d_coded_cadu, d_coded_cadu_len));
return i * d_window + j + 4; return i * d_window + j + 4;
} }
} }
@ -231,13 +229,13 @@ lrpt_sync_impl::work_sync(const gr_complex *in, int noutput_items)
int int
lrpt_sync_impl::work (int noutput_items, lrpt_sync_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const gr_complex *in = (const gr_complex *) input_items[0]; const gr_complex *in = (const gr_complex *) input_items[0];
uint32_t bits; uint32_t bits;
if(!d_frame_sync) { if (!d_frame_sync) {
return work_no_sync(in, noutput_items); return work_no_sync(in, noutput_items);
} }
return work_sync(in, noutput_items); return work_sync(in, noutput_items);

View File

@ -25,19 +25,16 @@
#include <satnogs/convolutional_deinterleaver.h> #include <satnogs/convolutional_deinterleaver.h>
#include <gnuradio/digital/constellation.h> #include <gnuradio/digital/constellation.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class lrpt_sync_impl : public lrpt_sync class lrpt_sync_impl : public lrpt_sync {
{
public: public:
lrpt_sync_impl (size_t threshold); lrpt_sync_impl(size_t threshold);
~lrpt_sync_impl (); ~lrpt_sync_impl();
int int
work (int noutput_items, work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
@ -56,11 +53,11 @@ private:
uint64_t d_shift_reg1; uint64_t d_shift_reg1;
uint64_t d_shift_reg2; uint64_t d_shift_reg2;
uint64_t d_shift_reg3; uint64_t d_shift_reg3;
gr_complex* d_rotate_pi2; gr_complex *d_rotate_pi2;
gr_complex* d_rotate_2pi2; gr_complex *d_rotate_2pi2;
gr_complex* d_rotate_3pi2; gr_complex *d_rotate_3pi2;
gr_complex* d_corrected; gr_complex *d_corrected;
uint8_t* d_coded_cadu; uint8_t *d_coded_cadu;
int int
work_no_sync(const gr_complex *in, int noutput_items); work_no_sync(const gr_complex *in, int noutput_items);

View File

@ -32,7 +32,7 @@ std::string
metadata::keys() metadata::keys()
{ {
std::string s = "["; std::string s = "[";
for(size_t i = 0; i < KEYS_NUM - 1; i++) { for (size_t i = 0; i < KEYS_NUM - 1; i++) {
s.append(value((key_t) i)); s.append(value((key_t) i));
s.append(", "); s.append(", ");
} }
@ -48,9 +48,9 @@ metadata::keys()
* @return string corresponding to the key @a k value * @return string corresponding to the key @a k value
*/ */
std::string std::string
metadata::value(const key_t& k) metadata::value(const key_t &k)
{ {
switch(k) { switch (k) {
case PDU: case PDU:
return "pdu"; return "pdu";
case CRC_VALID: case CRC_VALID:
@ -81,7 +81,7 @@ metadata::time_iso8601()
{ {
/* check for the current UTC time */ /* check for the current UTC time */
std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point tp =
std::chrono::system_clock::now (); std::chrono::system_clock::now();
return date::format("%FT%TZ", date::floor<std::chrono::microseconds>(tp)); return date::format("%FT%TZ", date::floor<std::chrono::microseconds>(tp));
} }
@ -137,39 +137,39 @@ metadata::add_corrected_bits(pmt::pmt_t &m, uint32_t cnt)
} }
Json::Value Json::Value
metadata::to_json(const pmt::pmt_t& m) metadata::to_json(const pmt::pmt_t &m)
{ {
Json::Value root; Json::Value root;
pmt::pmt_t v = pmt::dict_ref(m, pmt::mp(value(PDU)), pmt::PMT_NIL); pmt::pmt_t v = pmt::dict_ref(m, pmt::mp(value(PDU)), pmt::PMT_NIL);
if(!pmt::equal(v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
uint8_t *b = (uint8_t *) pmt::blob_data(v); uint8_t *b = (uint8_t *) pmt::blob_data(v);
size_t len = pmt::blob_length(v); size_t len = pmt::blob_length(v);
root[value(PDU)] = base64_encode(b, len); root[value(PDU)] = base64_encode(b, len);
} }
v = pmt::dict_ref(m, pmt::mp(value(TIME)), pmt::PMT_NIL); v = pmt::dict_ref(m, pmt::mp(value(TIME)), pmt::PMT_NIL);
if(!pmt::equal(v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value(TIME)] = pmt::symbol_to_string(v); root[value(TIME)] = pmt::symbol_to_string(v);
} }
v = pmt::dict_ref (m, pmt::mp (value (CRC_VALID)), pmt::PMT_NIL); v = pmt::dict_ref(m, pmt::mp(value(CRC_VALID)), pmt::PMT_NIL);
if (!pmt::equal (v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value (CRC_VALID)] = pmt::to_bool (v); root[value(CRC_VALID)] = pmt::to_bool(v);
} }
v = pmt::dict_ref (m, pmt::mp (value (SAMPLE_START)), pmt::PMT_NIL); v = pmt::dict_ref(m, pmt::mp(value(SAMPLE_START)), pmt::PMT_NIL);
if (!pmt::equal (v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value (SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64 (v)); root[value(SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64(v));
} }
v = pmt::dict_ref (m, pmt::mp (value (SYMBOL_ERASURES)), pmt::PMT_NIL); v = pmt::dict_ref(m, pmt::mp(value(SYMBOL_ERASURES)), pmt::PMT_NIL);
if (!pmt::equal (v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value (SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64 (v)); root[value(SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64(v));
} }
v = pmt::dict_ref (m, pmt::mp (value (CORRECTED_BITS)), pmt::PMT_NIL); v = pmt::dict_ref(m, pmt::mp(value(CORRECTED_BITS)), pmt::PMT_NIL);
if (!pmt::equal (v, pmt::PMT_NIL)) { if (!pmt::equal(v, pmt::PMT_NIL)) {
root[value (CORRECTED_BITS)] = Json::Value::UInt64(pmt::to_uint64 (v)); root[value(CORRECTED_BITS)] = Json::Value::UInt64(pmt::to_uint64(v));
} }
return root; return root;
} }

View File

@ -28,57 +28,55 @@
#include <satnogs/morse.h> #include <satnogs/morse.h>
#include <random> #include <random>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
morse_debug_source::sptr morse_debug_source::sptr
morse_debug_source::make (const size_t wpm, morse_debug_source::make(const size_t wpm,
const std::string& debug_seq, bool inject_errors, const std::string &debug_seq, bool inject_errors,
float error_prob, float error_prob,
size_t seq_pause_ms) size_t seq_pause_ms)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new morse_debug_source_impl (wpm, debug_seq, inject_errors, new morse_debug_source_impl(wpm, debug_seq, inject_errors,
error_prob, seq_pause_ms)); error_prob, seq_pause_ms));
} }
/* /*
* The private constructor * The private constructor
*/ */
morse_debug_source_impl::morse_debug_source_impl (const size_t wpm, morse_debug_source_impl::morse_debug_source_impl(const size_t wpm,
std::string debug_seq, std::string debug_seq,
bool inject_errors, bool inject_errors,
float error_prob, float error_prob,
size_t seq_pause_ms) : size_t seq_pause_ms) :
gr::block ("morse_debug_source", gr::block("morse_debug_source",
gr::io_signature::make (0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_wpm (wpm), d_wpm(wpm),
d_inject_errors (inject_errors), d_inject_errors(inject_errors),
d_p (error_prob), d_p(error_prob),
d_seq_pause_ms (seq_pause_ms), d_seq_pause_ms(seq_pause_ms),
d_run (true), d_run(true),
d_chars d_chars {
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' }, 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' },
d_symbols d_symbols {
{ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--",
"--..", ".----", "..---", "...--", "....-", ".....", "-....", "--..", ".----", "..---", "...--", "....-", ".....", "-....",
"--...", "---..", "----.", "-----" } "--...", "---..", "----.", "-----" }
{ {
message_port_register_out (pmt::mp ("out")); message_port_register_out(pmt::mp("out"));
d_thread = std::thread (&morse_debug_source_impl::send_debug_msg, this, d_thread = std::thread(&morse_debug_source_impl::send_debug_msg, this,
debug_seq); debug_seq);
} }
static inline size_t static inline size_t
find_char_idx (const char* characters, size_t len, char c) find_char_idx(const char *characters, size_t len, char c)
{ {
size_t i; size_t i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (characters[i] == c) { if (characters[i] == c) {
@ -86,88 +84,88 @@ namespace gr
} }
} }
return len; return len;
} }
void void
morse_debug_source_impl::send_debug_msg (std::string sentence) morse_debug_source_impl::send_debug_msg(std::string sentence)
{ {
size_t i; size_t i;
size_t j; size_t j;
size_t idx; size_t idx;
std::string s; std::string s;
char c; char c;
std::random_device rd; std::random_device rd;
std::mt19937 gen (rd ()); std::mt19937 gen(rd());
std::bernoulli_distribution error_distr (d_p); std::bernoulli_distribution error_distr(d_p);
bool inject_error; bool inject_error;
size_t len = sentence.length (); size_t len = sentence.length();
pmt::pmt_t port = pmt::mp ("out"); pmt::pmt_t port = pmt::mp("out");
std::this_thread::sleep_for (std::chrono::milliseconds (1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
while (d_run) { while (d_run) {
/* Not the best approach, but hey, this is only for debug */ /* Not the best approach, but hey, this is only for debug */
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
c = std::toupper (sentence[i]); c = std::toupper(sentence[i]);
if (c == ' ') { if (c == ' ') {
message_port_pub (port, pmt::from_long (MORSE_L_SPACE)); message_port_pub(port, pmt::from_long(MORSE_L_SPACE));
} }
idx = find_char_idx (d_chars, sizeof(d_chars), c); idx = find_char_idx(d_chars, sizeof(d_chars), c);
if (idx != sizeof(d_chars)) { if (idx != sizeof(d_chars)) {
s = d_symbols[idx]; s = d_symbols[idx];
/* Get from the random distribution if an error should be injected */ /* Get from the random distribution if an error should be injected */
inject_error = d_inject_errors && error_distr (gen); inject_error = d_inject_errors && error_distr(gen);
for (j = 0; j < s.length (); j++) { for (j = 0; j < s.length(); j++) {
if (s[j] == '.') { if (s[j] == '.') {
if (inject_error) { if (inject_error) {
message_port_pub (port, pmt::from_long (MORSE_DASH)); message_port_pub(port, pmt::from_long(MORSE_DASH));
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE)); message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
} }
else { else {
message_port_pub (port, pmt::from_long (MORSE_DOT)); message_port_pub(port, pmt::from_long(MORSE_DOT));
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE)); message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
} }
} }
else { else {
if (inject_error) { if (inject_error) {
message_port_pub (port, pmt::from_long (MORSE_DOT)); message_port_pub(port, pmt::from_long(MORSE_DOT));
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE)); message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
} }
else { else {
message_port_pub (port, pmt::from_long (MORSE_DASH)); message_port_pub(port, pmt::from_long(MORSE_DASH));
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE)); message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
} }
} }
std::this_thread::sleep_for (std::chrono::milliseconds (100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
/* Send also a character delimiter */ /* Send also a character delimiter */
message_port_pub (port, pmt::from_long (MORSE_S_SPACE)); message_port_pub(port, pmt::from_long(MORSE_S_SPACE));
} }
} }
message_port_pub (port, pmt::from_long (MORSE_L_SPACE)); message_port_pub(port, pmt::from_long(MORSE_L_SPACE));
for(i = 0; i < d_seq_pause_ms / (1200/d_wpm); i++) { for (i = 0; i < d_seq_pause_ms / (1200 / d_wpm); i++) {
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE)); message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
} }
/* Perform a true sleep, to avoid message overload */ /* Perform a true sleep, to avoid message overload */
std::this_thread::sleep_for (std::chrono::milliseconds (d_seq_pause_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(d_seq_pause_ms));
}
} }
}
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
morse_debug_source_impl::~morse_debug_source_impl () morse_debug_source_impl::~morse_debug_source_impl()
{ {
d_run = false; d_run = false;
d_thread.join (); d_thread.join();
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -27,14 +27,11 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class morse_debug_source_impl : public morse_debug_source class morse_debug_source_impl : public morse_debug_source {
{ private:
private:
const size_t d_wpm; const size_t d_wpm;
const bool d_inject_errors; const bool d_inject_errors;
const float d_p; const float d_p;
@ -45,16 +42,16 @@ namespace gr
std::thread d_thread; std::thread d_thread;
void void
send_debug_msg (std::string sentence); send_debug_msg(std::string sentence);
public: public:
morse_debug_source_impl (const size_t wpm, std::string debug_seq, morse_debug_source_impl(const size_t wpm, std::string debug_seq,
bool inject_errors, bool inject_errors,
float error_prob, size_t seq_pause_ms); float error_prob, size_t seq_pause_ms);
~morse_debug_source_impl (); ~morse_debug_source_impl();
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_IMPL_H */ #endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_IMPL_H */

View File

@ -26,31 +26,28 @@
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include "morse_decoder_impl.h" #include "morse_decoder_impl.h"
#include <satnogs/log.h> #include <satnogs/log.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
morse_decoder::sptr morse_decoder::sptr
morse_decoder::make (char unrecognized_char, size_t min_frame_len) morse_decoder::make(char unrecognized_char, size_t min_frame_len)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new morse_decoder_impl (unrecognized_char, min_frame_len)); new morse_decoder_impl(unrecognized_char, min_frame_len));
} }
void void
morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg) morse_decoder_impl::symbol_msg_handler(pmt::pmt_t msg)
{ {
bool res = false; bool res = false;
morse_symbol_t s; morse_symbol_t s;
s = (morse_symbol_t) pmt::to_long (msg); s = (morse_symbol_t) pmt::to_long(msg);
switch (s) switch (s) {
{
case MORSE_DOT: case MORSE_DOT:
case MORSE_DASH: case MORSE_DASH:
case MORSE_S_SPACE: case MORSE_S_SPACE:
res = d_morse_tree.received_symbol (s); res = d_morse_tree.received_symbol(s);
break; break;
/* /*
* If a word separator occurs it is a good time to retrieve the decoded * If a word separator occurs it is a good time to retrieve the decoded
@ -61,24 +58,24 @@ morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
* Inject a character separator, for the morse decoder to commit * Inject a character separator, for the morse decoder to commit
* the outstanding character * the outstanding character
*/ */
res = d_morse_tree.received_symbol (MORSE_S_SPACE); res = d_morse_tree.received_symbol(MORSE_S_SPACE);
/* Just ignore the word separator if no word is yet decoded */ /* Just ignore the word separator if no word is yet decoded */
if (d_morse_tree.get_word_len () == 0) { if (d_morse_tree.get_word_len() == 0) {
res = true; res = true;
break; break;
} }
d_str = d_str.append(d_morse_tree.get_word ()); d_str = d_str.append(d_morse_tree.get_word());
d_str = d_str.append(" "); d_str = d_str.append(" ");
d_morse_tree.reset (); d_morse_tree.reset();
break; break;
case MORSE_INTRA_SPACE: case MORSE_INTRA_SPACE:
/*Ignore it */ /*Ignore it */
break; break;
case MORSE_END_MSG_SPACE: case MORSE_END_MSG_SPACE:
if (d_str.length () > d_min_frame_len) { if (d_str.length() > d_min_frame_len) {
d_morse_tree.reset (); d_morse_tree.reset();
message_port_pub (pmt::mp ("out"), message_port_pub(pmt::mp("out"),
pmt::make_blob (d_str.c_str (), d_str.length ())); pmt::make_blob(d_str.c_str(), d_str.length()));
d_str = ""; d_str = "";
} }
break; break;
@ -92,11 +89,11 @@ morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
* character situation occurred or the maximum word limit reached * character situation occurred or the maximum word limit reached
*/ */
if (!res) { if (!res) {
if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) { if (d_morse_tree.get_max_word_len() == d_morse_tree.get_word_len()) {
d_str = d_morse_tree.get_word (); d_str = d_morse_tree.get_word();
d_morse_tree.reset (); d_morse_tree.reset();
message_port_pub (pmt::mp ("out"), message_port_pub(pmt::mp("out"),
pmt::make_blob (d_str.c_str (), d_str.length ())); pmt::make_blob(d_str.c_str(), d_str.length()));
} }
} }
} }
@ -104,21 +101,21 @@ morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
/* /*
* The private constructor * The private constructor
*/ */
morse_decoder_impl::morse_decoder_impl (char unrecognized_char, morse_decoder_impl::morse_decoder_impl(char unrecognized_char,
size_t min_frame_len) : size_t min_frame_len) :
gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0), gr::block("morse_decoder", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_morse_tree (unrecognized_char), d_morse_tree(unrecognized_char),
d_min_frame_len (min_frame_len), d_min_frame_len(min_frame_len),
d_str("") d_str("")
{ {
/* Register the input and output msg handler */ /* Register the input and output msg handler */
message_port_register_in (pmt::mp ("in")); message_port_register_in(pmt::mp("in"));
message_port_register_out (pmt::mp ("out")); message_port_register_out(pmt::mp("out"));
set_msg_handler ( set_msg_handler(
pmt::mp ("in"), pmt::mp("in"),
boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1)); boost::bind(&morse_decoder_impl::symbol_msg_handler, this, _1));
} }
} /* namespace satnogs */ } /* namespace satnogs */

View File

@ -24,16 +24,13 @@
#include <satnogs/morse_decoder.h> #include <satnogs/morse_decoder.h>
#include <satnogs/morse_tree.h> #include <satnogs/morse_tree.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class morse_decoder_impl : public morse_decoder class morse_decoder_impl : public morse_decoder {
{
public: public:
morse_decoder_impl (char unrecognized_char, size_t min_frame_len); morse_decoder_impl(char unrecognized_char, size_t min_frame_len);
private: private:
morse_tree d_morse_tree; morse_tree d_morse_tree;
@ -41,7 +38,7 @@ private:
std::string d_str; std::string d_str;
void void
symbol_msg_handler (pmt::pmt_t msg); symbol_msg_handler(pmt::pmt_t msg);
}; };
} // namespace satnogs } // namespace satnogs

View File

@ -28,192 +28,189 @@
#include <satnogs/log.h> #include <satnogs/log.h>
#include <string.h> #include <string.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
/*! /*!
* Constructs a Morse code tree for Morse code decoding * Constructs a Morse code tree for Morse code decoding
*/ */
morse_tree::morse_tree () : morse_tree::morse_tree() :
d_unrecognized_symbol ('#'), d_unrecognized_symbol('#'),
d_root (new tree_node (0)), d_root(new tree_node(0)),
d_current (d_root), d_current(d_root),
d_buff_len (4096), d_buff_len(4096),
d_word_len (0), d_word_len(0),
d_word_buffer (new char[d_buff_len]) d_word_buffer(new char[d_buff_len])
{ {
construct_tree (); construct_tree();
} }
/*! /*!
* Constructs a Morse code tree for Morse code decoding * Constructs a Morse code tree for Morse code decoding
* @param unrecognized the character that will be placed * @param unrecognized the character that will be placed
* in the place of unrecognized symbols * in the place of unrecognized symbols
*/ */
morse_tree::morse_tree (char unrecognized) : morse_tree::morse_tree(char unrecognized) :
d_unrecognized_symbol (unrecognized), d_unrecognized_symbol(unrecognized),
d_root (new tree_node (0)), d_root(new tree_node(0)),
d_current (d_root), d_current(d_root),
d_buff_len (4096), d_buff_len(4096),
d_word_len (0), d_word_len(0),
d_word_buffer (new char[d_buff_len]) d_word_buffer(new char[d_buff_len])
{ {
construct_tree (); construct_tree();
} }
morse_tree::~morse_tree () morse_tree::~morse_tree()
{ {
delete_tree(d_root); delete_tree(d_root);
} }
/*! /*!
* Resets the pointer to the initial root node * Resets the pointer to the initial root node
*/ */
void void
morse_tree::reset () morse_tree::reset()
{ {
d_current = d_root; d_current = d_root;
d_word_len = 0; d_word_len = 0;
memset(d_word_buffer.get(), 0, d_buff_len); memset(d_word_buffer.get(), 0, d_buff_len);
} }
/*! /*!
* Creates and initializes the Morse code decoder tree * Creates and initializes the Morse code decoder tree
*/ */
void void
morse_tree::construct_tree () morse_tree::construct_tree()
{ {
tree_node *e = new tree_node ('E'); tree_node *e = new tree_node('E');
tree_node *t = new tree_node ('T'); tree_node *t = new tree_node('T');
tree_node *i = new tree_node ('I'); tree_node *i = new tree_node('I');
tree_node *a = new tree_node ('A'); tree_node *a = new tree_node('A');
tree_node *n = new tree_node ('N'); tree_node *n = new tree_node('N');
tree_node *m = new tree_node ('M'); tree_node *m = new tree_node('M');
tree_node *s = new tree_node ('S'); tree_node *s = new tree_node('S');
tree_node *u = new tree_node ('U'); tree_node *u = new tree_node('U');
tree_node *r = new tree_node ('R'); tree_node *r = new tree_node('R');
tree_node *w = new tree_node ('W'); tree_node *w = new tree_node('W');
tree_node *d = new tree_node ('D'); tree_node *d = new tree_node('D');
tree_node *k = new tree_node ('K'); tree_node *k = new tree_node('K');
tree_node *g = new tree_node ('G'); tree_node *g = new tree_node('G');
tree_node *o = new tree_node ('O'); tree_node *o = new tree_node('O');
tree_node *h = new tree_node ('H'); tree_node *h = new tree_node('H');
tree_node *v = new tree_node ('V'); tree_node *v = new tree_node('V');
tree_node *f = new tree_node ('F'); tree_node *f = new tree_node('F');
tree_node *u_u = new tree_node ('U'); tree_node *u_u = new tree_node('U');
tree_node *l = new tree_node ('L'); tree_node *l = new tree_node('L');
tree_node *u_a = new tree_node ('A'); tree_node *u_a = new tree_node('A');
tree_node *p = new tree_node ('P'); tree_node *p = new tree_node('P');
tree_node *j = new tree_node ('J'); tree_node *j = new tree_node('J');
tree_node *b = new tree_node ('B'); tree_node *b = new tree_node('B');
tree_node *x = new tree_node ('X'); tree_node *x = new tree_node('X');
tree_node *c = new tree_node ('C'); tree_node *c = new tree_node('C');
tree_node *y = new tree_node ('Y'); tree_node *y = new tree_node('Y');
tree_node *z = new tree_node ('Z'); tree_node *z = new tree_node('Z');
tree_node *q = new tree_node ('Q'); tree_node *q = new tree_node('Q');
tree_node *u_o = new tree_node ('O'); tree_node *u_o = new tree_node('O');
tree_node *null0 = new tree_node (0); tree_node *null0 = new tree_node(0);
tree_node *n5 = new tree_node ('5'); tree_node *n5 = new tree_node('5');
tree_node *n4 = new tree_node ('4'); tree_node *n4 = new tree_node('4');
tree_node *a_s = new tree_node ('S'); tree_node *a_s = new tree_node('S');
tree_node *n3 = new tree_node ('3'); tree_node *n3 = new tree_node('3');
tree_node *a_e = new tree_node ('E'); tree_node *a_e = new tree_node('E');
tree_node *d_d = new tree_node ('D'); tree_node *d_d = new tree_node('D');
tree_node *n2 = new tree_node ('2'); tree_node *n2 = new tree_node('2');
tree_node *d_e = new tree_node ('E'); tree_node *d_e = new tree_node('E');
tree_node *plus = new tree_node ('+'); tree_node *plus = new tree_node('+');
tree_node *d_a = new tree_node ('A'); tree_node *d_a = new tree_node('A');
tree_node *d_j = new tree_node ('J'); tree_node *d_j = new tree_node('J');
tree_node *n1 = new tree_node ('1'); tree_node *n1 = new tree_node('1');
tree_node *n6 = new tree_node ('6'); tree_node *n6 = new tree_node('6');
tree_node *eq = new tree_node ('='); tree_node *eq = new tree_node('=');
tree_node *slash = new tree_node ('/'); tree_node *slash = new tree_node('/');
tree_node *null1 = new tree_node (0); tree_node *null1 = new tree_node(0);
tree_node *n7 = new tree_node ('7'); tree_node *n7 = new tree_node('7');
tree_node *null2 = new tree_node (0); tree_node *null2 = new tree_node(0);
tree_node *n8 = new tree_node ('8'); tree_node *n8 = new tree_node('8');
tree_node *n9 = new tree_node ('9'); tree_node *n9 = new tree_node('9');
tree_node *n0 = new tree_node ('0'); tree_node *n0 = new tree_node('0');
d_root->set_left_child (e); d_root->set_left_child(e);
d_root->set_right_child (t); d_root->set_right_child(t);
e->set_left_child (i); e->set_left_child(i);
e->set_right_child (a); e->set_right_child(a);
t->set_left_child (n); t->set_left_child(n);
t->set_right_child (m); t->set_right_child(m);
i->set_left_child (s); i->set_left_child(s);
i->set_right_child (u); i->set_right_child(u);
a->set_left_child (r); a->set_left_child(r);
a->set_right_child (w); a->set_right_child(w);
n->set_left_child (d); n->set_left_child(d);
n->set_right_child (k); n->set_right_child(k);
m->set_left_child (g); m->set_left_child(g);
m->set_right_child (o); m->set_right_child(o);
s->set_left_child (h); s->set_left_child(h);
s->set_right_child (v); s->set_right_child(v);
u->set_left_child (f); u->set_left_child(f);
u->set_right_child (u_u); u->set_right_child(u_u);
r->set_left_child (l); r->set_left_child(l);
r->set_right_child (u_a); r->set_right_child(u_a);
w->set_left_child (p); w->set_left_child(p);
w->set_right_child (j); w->set_right_child(j);
d->set_left_child (b); d->set_left_child(b);
d->set_right_child (x); d->set_right_child(x);
k->set_left_child (c); k->set_left_child(c);
k->set_right_child (y); k->set_right_child(y);
g->set_left_child (z); g->set_left_child(z);
g->set_right_child (q); g->set_right_child(q);
o->set_left_child (u_o); o->set_left_child(u_o);
o->set_right_child (null0); o->set_right_child(null0);
h->set_left_child (n5); h->set_left_child(n5);
h->set_right_child (n4); h->set_right_child(n4);
v->set_left_child (a_s); v->set_left_child(a_s);
v->set_right_child (n3); v->set_right_child(n3);
f->set_left_child (a_e); f->set_left_child(a_e);
u_u->set_left_child (d_d); u_u->set_left_child(d_d);
u_u->set_right_child (n2); u_u->set_right_child(n2);
l->set_right_child (d_e); l->set_right_child(d_e);
u_a->set_left_child (plus); u_a->set_left_child(plus);
p->set_right_child (d_a); p->set_right_child(d_a);
j->set_left_child (d_j); j->set_left_child(d_j);
j->set_right_child (n1); j->set_right_child(n1);
b->set_left_child (n6); b->set_left_child(n6);
b->set_right_child (eq); b->set_right_child(eq);
x->set_left_child (slash); x->set_left_child(slash);
c->set_right_child (null1); c->set_right_child(null1);
z->set_left_child (n7); z->set_left_child(n7);
z->set_right_child (null2); z->set_right_child(null2);
u_o->set_left_child (n8); u_o->set_left_child(n8);
null0->set_left_child (n9); null0->set_left_child(n9);
null0->set_right_child (n0); null0->set_right_child(n0);
} }
bool bool
morse_tree::received_symbol (morse_symbol_t s) morse_tree::received_symbol(morse_symbol_t s)
{ {
char c = 0; char c = 0;
bool ret = false; bool ret = false;
/* Check for overflow */ /* Check for overflow */
if (d_word_len == d_buff_len) { if (d_word_len == d_buff_len) {
return false; return false;
} }
switch (s) switch (s) {
{
case MORSE_DOT: case MORSE_DOT:
if (d_current->get_left_child ()) { if (d_current->get_left_child()) {
d_current = d_current->get_left_child (); d_current = d_current->get_left_child();
ret = true; ret = true;
} }
break; break;
case MORSE_DASH: case MORSE_DASH:
if (d_current->get_right_child ()) { if (d_current->get_right_child()) {
d_current = d_current->get_right_child (); d_current = d_current->get_right_child();
ret = true; ret = true;
} }
break; break;
@ -225,7 +222,7 @@ namespace gr
if (d_current == d_root) { if (d_current == d_root) {
return true; return true;
} }
c = d_current->get_char (); c = d_current->get_char();
d_current = d_root; d_current = d_root;
/* /*
* Some nodes are null transitions and do not correspond to * Some nodes are null transitions and do not correspond to
@ -242,73 +239,73 @@ namespace gr
return false; return false;
} }
return ret; return ret;
} }
std::string std::string
morse_tree::get_word () morse_tree::get_word()
{ {
return std::string(d_word_buffer.get(), d_word_len); return std::string(d_word_buffer.get(), d_word_len);
} }
size_t size_t
morse_tree::get_max_word_len () const morse_tree::get_max_word_len() const
{ {
return d_buff_len; return d_buff_len;
} }
size_t size_t
morse_tree::get_word_len () morse_tree::get_word_len()
{ {
return d_word_len; return d_word_len;
} }
void void
morse_tree::delete_tree (tree_node *node) morse_tree::delete_tree(tree_node *node)
{ {
if (!node) { if (!node) {
return; return;
} }
delete_tree (node->get_left_child ()); delete_tree(node->get_left_child());
delete_tree (node->get_right_child ()); delete_tree(node->get_right_child());
delete node; delete node;
} }
tree_node::tree_node (char c) : tree_node::tree_node(char c) :
d_char (c), d_char(c),
d_left (NULL), d_left(NULL),
d_right (NULL) d_right(NULL)
{ {
} }
void void
tree_node::set_left_child (tree_node* child) tree_node::set_left_child(tree_node *child)
{ {
d_left = child; d_left = child;
} }
void void
tree_node::set_right_child (tree_node* child) tree_node::set_right_child(tree_node *child)
{ {
d_right = child; d_right = child;
} }
tree_node* tree_node *
tree_node::get_left_child () tree_node::get_left_child()
{ {
return d_left; return d_left;
} }
tree_node* tree_node *
tree_node::get_right_child () tree_node::get_right_child()
{ {
return d_right; return d_right;
} }
char char
tree_node::get_char () tree_node::get_char()
{ {
return d_char; return d_char;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -28,53 +28,50 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
multi_format_msg_sink::sptr multi_format_msg_sink::sptr
multi_format_msg_sink::make (size_t format, multi_format_msg_sink::make(size_t format,
bool timestamp, bool timestamp,
bool out_stdout, bool out_stdout,
const std::string& filepath) const std::string &filepath)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new multi_format_msg_sink_impl (format, timestamp, new multi_format_msg_sink_impl(format, timestamp,
out_stdout, filepath)); out_stdout, filepath));
} }
void void
multi_format_msg_sink_impl::msg_handler_file (pmt::pmt_t msg) multi_format_msg_sink_impl::msg_handler_file(pmt::pmt_t msg)
{ {
uint8_t *su; uint8_t *su;
char buf[256]; char buf[256];
std::string s ((const char *) pmt::blob_data (msg), std::string s((const char *) pmt::blob_data(msg),
pmt::blob_length (msg)); pmt::blob_length(msg));
if(d_timestamp) { if (d_timestamp) {
std::time_t t = std::time(nullptr); std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t); std::tm tm = *std::localtime(&t);
strftime(buf, sizeof(buf), "%F %T %z", &tm); strftime(buf, sizeof(buf), "%F %T %z", &tm);
d_fos << "[" << buf << "]"; d_fos << "[" << buf << "]";
} }
switch (d_format) switch (d_format) {
{
case 0: case 0:
d_fos << s << std::endl; d_fos << s << std::endl;
break; break;
case 1: case 1:
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
d_fos << "0x" << std::hex << std::setw (2) << std::setfill ('0') d_fos << "0x" << std::hex << std::setw(2) << std::setfill('0')
<< (uint32_t) su[i] << " "; << (uint32_t) su[i] << " ";
} }
d_fos << std::endl; d_fos << std::endl;
break; break;
case 2: case 2:
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
d_fos << "0b" << std::bitset<8> (su[i]) << " "; d_fos << "0b" << std::bitset<8> (su[i]) << " ";
} }
d_fos << std::endl; d_fos << std::endl;
@ -82,42 +79,41 @@ namespace gr
default: default:
throw std::invalid_argument("Invalid format"); throw std::invalid_argument("Invalid format");
} }
} }
void void
multi_format_msg_sink_impl::msg_handler_stdout (pmt::pmt_t msg) multi_format_msg_sink_impl::msg_handler_stdout(pmt::pmt_t msg)
{ {
uint8_t *su; uint8_t *su;
char buf[256]; char buf[256];
std::string s ((const char *) pmt::blob_data (msg), std::string s((const char *) pmt::blob_data(msg),
pmt::blob_length (msg)); pmt::blob_length(msg));
if(d_timestamp) { if (d_timestamp) {
std::time_t t = std::time(nullptr); std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t); std::tm tm = *std::localtime(&t);
strftime(buf, sizeof(buf), "%F %T %z", &tm); strftime(buf, sizeof(buf), "%F %T %z", &tm);
std::cout << "[" << buf << "]"; std::cout << "[" << buf << "]";
} }
switch (d_format) switch (d_format) {
{
case 0: // binary case 0: // binary
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
std::cout << s[i]; std::cout << s[i];
} }
std::cout << std::endl; std::cout << std::endl;
break; break;
case 1: // hex annotated case 1: // hex annotated
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
std::cout << "0x" << std::hex << std::setw (2) << std::setfill ('0') std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0')
<< (uint32_t) su[i] << " "; << (uint32_t) su[i] << " ";
} }
std::cout << std::endl; std::cout << std::endl;
break; break;
case 2: // binary annotated case 2: // binary annotated
su = (uint8_t *) pmt::blob_data (msg); su = (uint8_t *) pmt::blob_data(msg);
for (size_t i = 0; i < pmt::blob_length (msg); i++) { for (size_t i = 0; i < pmt::blob_length(msg); i++) {
std::cout << "0b" << std::bitset<8> (su[i]) << " "; std::cout << "0b" << std::bitset<8> (su[i]) << " ";
} }
std::cout << std::endl; std::cout << std::endl;
@ -125,44 +121,44 @@ namespace gr
default: default:
throw std::invalid_argument("Invalid format"); throw std::invalid_argument("Invalid format");
} }
} }
/* /*
* The private constructor * The private constructor
*/ */
multi_format_msg_sink_impl::multi_format_msg_sink_impl ( multi_format_msg_sink_impl::multi_format_msg_sink_impl(
size_t format, bool timestamp, bool out_stdout, size_t format, bool timestamp, bool out_stdout,
const std::string& filepath) : const std::string &filepath) :
gr::block ("multi_format_msg_sink", gr::block("multi_format_msg_sink",
gr::io_signature::make (0, 0, 0), gr::io_signature::make(0, 0, 0),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
d_format (format), d_format(format),
d_timestamp (timestamp), d_timestamp(timestamp),
d_stdout (out_stdout) d_stdout(out_stdout)
{ {
message_port_register_in (pmt::mp ("in")); message_port_register_in(pmt::mp("in"));
if(out_stdout) { if (out_stdout) {
set_msg_handler ( set_msg_handler(
pmt::mp ("in"), pmt::mp("in"),
boost::bind (&multi_format_msg_sink_impl::msg_handler_stdout, boost::bind(&multi_format_msg_sink_impl::msg_handler_stdout,
this, _1)); this, _1));
} }
else{ else {
d_fos.open(filepath); d_fos.open(filepath);
set_msg_handler ( set_msg_handler(
pmt::mp ("in"), pmt::mp("in"),
boost::bind (&multi_format_msg_sink_impl::msg_handler_file, boost::bind(&multi_format_msg_sink_impl::msg_handler_file,
this, _1)); this, _1));
} }
} }
multi_format_msg_sink_impl::~multi_format_msg_sink_impl () multi_format_msg_sink_impl::~multi_format_msg_sink_impl()
{ {
if(!d_stdout) { if (!d_stdout) {
d_fos.close(); d_fos.close();
} }
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -24,33 +24,30 @@
#include <satnogs/multi_format_msg_sink.h> #include <satnogs/multi_format_msg_sink.h>
#include <fstream> #include <fstream>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class multi_format_msg_sink_impl : public multi_format_msg_sink class multi_format_msg_sink_impl : public multi_format_msg_sink {
{ private:
private:
void void
msg_handler_stdout (pmt::pmt_t msg); msg_handler_stdout(pmt::pmt_t msg);
void void
msg_handler_file (pmt::pmt_t msg); msg_handler_file(pmt::pmt_t msg);
const size_t d_format; const size_t d_format;
const bool d_timestamp; const bool d_timestamp;
const bool d_stdout; const bool d_stdout;
std::ofstream d_fos; std::ofstream d_fos;
public: public:
multi_format_msg_sink_impl (size_t format, bool timestamp, multi_format_msg_sink_impl(size_t format, bool timestamp,
bool out_stdout, const std::string& filepath); bool out_stdout, const std::string &filepath);
~multi_format_msg_sink_impl (); ~multi_format_msg_sink_impl();
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_IMPL_H */ #endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_IMPL_H */

View File

@ -27,13 +27,11 @@
#include <cmath> #include <cmath>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs // Noaa apt sync pattern A
{ // (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
// Noaa apt sync pattern A const bool noaa_apt_sink_impl::synca_seq[] = {false, false, false, false,
// (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
const bool noaa_apt_sink_impl::synca_seq[] = {false, false, false, false,
true, true, false, false, // Pulse 1 true, true, false, false, // Pulse 1
true, true, false, false, // Pulse 2 true, true, false, false, // Pulse 2
true, true, false, false, // Pulse 3 true, true, false, false, // Pulse 3
@ -42,11 +40,12 @@ namespace gr
true, true, false, false, // Pulse 6 true, true, false, false, // Pulse 6
true, true, false, false, // Pulse 7 true, true, false, false, // Pulse 7
false, false, false, false, false, false, false, false,
false, false, false, false}; false, false, false, false
};
// Noaa apt sync pattern B // Noaa apt sync pattern B
// (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif) // (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
const bool noaa_apt_sink_impl::syncb_seq[] = {false, false, false, false, const bool noaa_apt_sink_impl::syncb_seq[] = {false, false, false, false,
true, true, true, false, false, true, true, true, false, false,
true, true, true, false, false, true, true, true, false, false,
true, true, true, false, false, true, true, true, false, false,
@ -54,55 +53,56 @@ namespace gr
true, true, true, false, false, true, true, true, false, false,
true, true, true, false, false, true, true, true, false, false,
true, true, true, false, false, true, true, true, false, false,
false}; false
};
noaa_apt_sink::sptr noaa_apt_sink::sptr
noaa_apt_sink::make (const char *filename_png, size_t width, size_t height, noaa_apt_sink::make(const char *filename_png, size_t width, size_t height,
bool sync, bool flip) bool sync, bool flip)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new noaa_apt_sink_impl (filename_png, width, height, sync, new noaa_apt_sink_impl(filename_png, width, height, sync,
flip)); flip));
} }
/* /*
* The private constructor * The private constructor
*/ */
noaa_apt_sink_impl::noaa_apt_sink_impl (const char *filename_png, noaa_apt_sink_impl::noaa_apt_sink_impl(const char *filename_png,
size_t width, size_t height, size_t width, size_t height,
bool sync, bool flip) : bool sync, bool flip) :
gr::sync_block ("noaa_apt_sink", gr::sync_block("noaa_apt_sink",
gr::io_signature::make (1, 1, sizeof(float)), gr::io_signature::make(1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)), gr::io_signature::make(0, 0, 0)),
f_average_alpha (0.25), f_average_alpha(0.25),
d_filename_png (filename_png), d_filename_png(filename_png),
d_width (width), d_width(width),
d_height (height), d_height(height),
d_synchronize_opt (sync), d_synchronize_opt(sync),
d_flip (flip), d_flip(flip),
d_history_length (40), d_history_length(40),
d_has_sync (false), d_has_sync(false),
d_image_received(false), d_image_received(false),
d_current_x (0), d_current_x(0),
d_current_y (0), d_current_y(0),
d_num_images (0), d_num_images(0),
f_max_level(0.0), f_max_level(0.0),
f_min_level(1.0), f_min_level(1.0),
f_average(0.0) f_average(0.0)
{ {
set_history(d_history_length); set_history(d_history_length);
d_full_image = png::image<png::gray_pixel>(d_width, d_height); d_full_image = png::image<png::gray_pixel>(d_width, d_height);
} }
void void
noaa_apt_sink_impl::write_image (png::image<png::gray_pixel> image, noaa_apt_sink_impl::write_image(png::image<png::gray_pixel> image,
std::string filename) std::string filename)
{ {
// In case the flip option is set // In case the flip option is set
if(d_flip) { if (d_flip) {
size_t width = image.get_width(); size_t width = image.get_width();
size_t height = image.get_height(); size_t height = image.get_height();
@ -110,8 +110,8 @@ namespace gr
png::image<png::gray_pixel> flipped(width, height); png::image<png::gray_pixel> flipped(width, height);
// ... and all the lines are copied over reverse order // ... and all the lines are copied over reverse order
for(size_t y = 0; y < height; y++) { for (size_t y = 0; y < height; y++) {
for(size_t x = 0; x < width; x++) { for (size_t x = 0; x < width; x++) {
png::gray_pixel pixel = image.get_pixel(x, height - y - 1); png::gray_pixel pixel = image.get_pixel(x, height - y - 1);
flipped.set_pixel(x, y, pixel); flipped.set_pixel(x, y, pixel);
} }
@ -124,22 +124,25 @@ namespace gr
// Write out the original // Write out the original
image.write(filename); image.write(filename);
} }
} }
noaa_apt_sink_impl::~noaa_apt_sink_impl () { noaa_apt_sink_impl::~noaa_apt_sink_impl()
{
} }
bool bool
noaa_apt_sink_impl::stop(){ noaa_apt_sink_impl::stop()
if(!d_image_received){ {
if (!d_image_received) {
write_image(d_full_image, d_filename_png); write_image(d_full_image, d_filename_png);
} }
return true; return true;
} }
void noaa_apt_sink_impl::set_pixel (size_t x, size_t y, float sample) { void noaa_apt_sink_impl::set_pixel(size_t x, size_t y, float sample)
{
// We can encounter NaN here since skip_to read the history whithout checking // We can encounter NaN here since skip_to read the history whithout checking
if(std::isnan(sample)) { if (std::isnan(sample)) {
sample = 0.0; sample = 0.0;
} }
@ -147,32 +150,34 @@ namespace gr
sample = (sample - f_min_level) / (f_max_level - f_min_level) * 255; sample = (sample - f_min_level) / (f_max_level - f_min_level) * 255;
// Set the pixel in the full image // Set the pixel in the full image
d_full_image.set_pixel(x, y, sample); d_full_image.set_pixel(x, y, sample);
} }
void void
noaa_apt_sink_impl::skip_to (size_t new_x, size_t pos, const float *samples) { noaa_apt_sink_impl::skip_to(size_t new_x, size_t pos, const float *samples)
{
// Check if the skip is forward or backward // Check if the skip is forward or backward
if(new_x > d_current_x) { if (new_x > d_current_x) {
// In case it is forward there will be a new_x - d_current_x sized hole // In case it is forward there will be a new_x - d_current_x sized hole
// in the image. Holes up 39 pixels can be filled from the modules history // in the image. Holes up 39 pixels can be filled from the modules history
size_t dist = std::min(size_t(39), new_x - d_current_x); size_t dist = std::min(size_t(39), new_x - d_current_x);
// Fill the hole using the previous samples of pos // Fill the hole using the previous samples of pos
for(size_t i = 0; i < dist; i++) { for (size_t i = 0; i < dist; i++) {
set_pixel(new_x - dist + i, d_current_y, samples[pos - dist + i]); set_pixel(new_x - dist + i, d_current_y, samples[pos - dist + i]);
} }
} }
// Jump to new location // Jump to new location
d_current_x = new_x; d_current_x = new_x;
} }
noaa_apt_sync_marker noaa_apt_sync_marker
noaa_apt_sink_impl::is_marker(size_t pos, const float *samples) { noaa_apt_sink_impl::is_marker(size_t pos, const float *samples)
{
// Initialize counters for 'hacky' correlation // Initialize counters for 'hacky' correlation
size_t count_a = 0; size_t count_a = 0;
size_t count_b = 0; size_t count_b = 0;
for(size_t i = 0; i < 40; i++) { for (size_t i = 0; i < 40; i++) {
// history of previous 39 samples + current one // history of previous 39 samples + current one
// -> start 39 samples in the past // -> start 39 samples in the past
float sample = samples[pos - 39 + i]; float sample = samples[pos - 39 + i];
@ -180,35 +185,35 @@ namespace gr
sample = sample - f_average; sample = sample - f_average;
// Very basic 1/0 correlation between pattern constan and history // Very basic 1/0 correlation between pattern constan and history
if((sample > 0 && synca_seq[i]) || (sample < 0 && !synca_seq[i])) { if ((sample > 0 && synca_seq[i]) || (sample < 0 && !synca_seq[i])) {
count_a += 1; count_a += 1;
} }
if((sample > 0 && syncb_seq[i]) || (sample < 0 && !syncb_seq[i])) { if ((sample > 0 && syncb_seq[i]) || (sample < 0 && !syncb_seq[i])) {
count_b += 1; count_b += 1;
} }
} }
// Prefer sync pattern a as it is detected more reliable // Prefer sync pattern a as it is detected more reliable
if(count_a > 35) { if (count_a > 35) {
return noaa_apt_sync_marker::SYNC_A; return noaa_apt_sync_marker::SYNC_A;
} }
else if(count_b > 35) { else if (count_b > 35) {
return noaa_apt_sync_marker::SYNC_B; return noaa_apt_sync_marker::SYNC_B;
} }
else { else {
return noaa_apt_sync_marker::NONE; return noaa_apt_sync_marker::NONE;
} }
} }
int int
noaa_apt_sink_impl::work (int noutput_items, noaa_apt_sink_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const float *in = (const float *) input_items[0]; const float *in = (const float *) input_items[0];
/* If we have already produced one image, ignore the remaining observation*/ /* If we have already produced one image, ignore the remaining observation*/
if(d_image_received){ if (d_image_received) {
return noutput_items; return noutput_items;
} }
@ -222,7 +227,7 @@ namespace gr
float sample = in[i]; float sample = in[i];
// For some reason the first sample on a Raspberry Pi can be NaN // For some reason the first sample on a Raspberry Pi can be NaN
if(std::isnan(sample)) { if (std::isnan(sample)) {
continue; continue;
} }
@ -234,27 +239,27 @@ namespace gr
f_average = f_average_alpha * sample + (1.0 - f_average_alpha) * f_average; f_average = f_average_alpha * sample + (1.0 - f_average_alpha) * f_average;
// If line sync is enabled // If line sync is enabled
if(d_synchronize_opt) { if (d_synchronize_opt) {
// Check if the history for the current sample is a sync pattern // Check if the history for the current sample is a sync pattern
noaa_apt_sync_marker marker = is_marker(i, in); noaa_apt_sync_marker marker = is_marker(i, in);
// For pattern a // For pattern a
if(marker == noaa_apt_sync_marker::SYNC_A) { if (marker == noaa_apt_sync_marker::SYNC_A) {
// Skip to right location, pattern starts 40 samples in the past // Skip to right location, pattern starts 40 samples in the past
skip_to(39, i, in); skip_to(39, i, in);
// If this is the first sync, reset min and max // If this is the first sync, reset min and max
if(!d_has_sync) { if (!d_has_sync) {
f_max_level = 0.0; f_max_level = 0.0;
f_min_level = 1.0; f_min_level = 1.0;
d_has_sync = true; d_has_sync = true;
} }
} }
// For pattern b // For pattern b
else if(marker == noaa_apt_sync_marker::SYNC_B) { else if (marker == noaa_apt_sync_marker::SYNC_B) {
// Skip to right location, pattern starts 40 samples in the past // Skip to right location, pattern starts 40 samples in the past
skip_to(d_width / 2 + 39, i, in); skip_to(d_width / 2 + 39, i, in);
// If this is the first sync, reset min and max // If this is the first sync, reset min and max
if(!d_has_sync) { if (!d_has_sync) {
f_max_level = 0.0; f_max_level = 0.0;
f_min_level = 1.0; f_min_level = 1.0;
d_has_sync = true; d_has_sync = true;
@ -268,14 +273,14 @@ namespace gr
// Increment x position // Increment x position
d_current_x += 1; d_current_x += 1;
// If we are beyond the end of line // If we are beyond the end of line
if(d_current_x >= d_width) { if (d_current_x >= d_width) {
// Increment y position // Increment y position
d_current_y += 1; d_current_y += 1;
// Reset x position to line start // Reset x position to line start
d_current_x = 0; d_current_x = 0;
// Split the image if there are enough lines decoded // Split the image if there are enough lines decoded
if(d_current_y >= d_height) { if (d_current_y >= d_height) {
d_current_y = 0; d_current_y = 0;
d_num_images += 1; d_num_images += 1;
// Write out the full image // Write out the full image
@ -287,7 +292,7 @@ namespace gr
// Tell gnu radio how many samples were consumed // Tell gnu radio how many samples were consumed
return noutput_items; return noutput_items;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -28,15 +28,12 @@
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs enum class noaa_apt_sync_marker {SYNC_A, SYNC_B, NONE};
{
enum class noaa_apt_sync_marker {SYNC_A, SYNC_B, NONE};
class noaa_apt_sink_impl : public noaa_apt_sink class noaa_apt_sink_impl : public noaa_apt_sink {
{ private:
private:
// Factor exponential smoothing average, // Factor exponential smoothing average,
// which is used for sync pattern detection // which is used for sync pattern detection
const float f_average_alpha; const float f_average_alpha;
@ -67,44 +64,44 @@ namespace gr
float f_min_level; float f_min_level;
float f_average; float f_average;
public: public:
noaa_apt_sink_impl (const char *filename_png, size_t width, size_t height, noaa_apt_sink_impl(const char *filename_png, size_t width, size_t height,
bool sync, bool flip); bool sync, bool flip);
~noaa_apt_sink_impl (); ~noaa_apt_sink_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
bool bool
stop(); stop();
private: private:
/* /*
* Checks if the history portion of the input contains a sync marker. * Checks if the history portion of the input contains a sync marker.
* Matches the 40 samples before pos against the patterns. * Matches the 40 samples before pos against the patterns.
*/ */
noaa_apt_sync_marker noaa_apt_sync_marker
is_marker (size_t pos, const float *samples); is_marker(size_t pos, const float *samples);
// Sets the pixel indicated by coordinates in the images (both full and split) // Sets the pixel indicated by coordinates in the images (both full and split)
void void
set_pixel (size_t x, size_t y, float sample); set_pixel(size_t x, size_t y, float sample);
/* /*
* Updates d_current_x to new_x, * Updates d_current_x to new_x,
* while using historical samples to fill any resulting gaps in the images. * while using historical samples to fill any resulting gaps in the images.
*/ */
void void
skip_to (size_t new_x, size_t pos, const float *samples); skip_to(size_t new_x, size_t pos, const float *samples);
// Writes a single image to disk, also takes care of flipping // Writes a single image to disk, also takes care of flipping
void void
write_image (png::image<png::gray_pixel> image, std::string filename); write_image(png::image<png::gray_pixel> image, std::string filename);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_IMPL_H */ #endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_IMPL_H */

View File

@ -31,107 +31,109 @@
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
namespace gr namespace gr {
namespace satnogs {
ogg_encoder::sptr
ogg_encoder::make(char *filename, double samp_rate, float quality)
{ {
namespace satnogs return gnuradio::get_initial_sptr(
{ new ogg_encoder_impl(filename, samp_rate, quality));
}
ogg_encoder::sptr /*
ogg_encoder::make (char* filename, double samp_rate, float quality)
{
return gnuradio::get_initial_sptr (
new ogg_encoder_impl (filename, samp_rate, quality));
}
/*
* The private constructor * The private constructor
*/ */
ogg_encoder_impl::ogg_encoder_impl (char* filename, double samp_rate, ogg_encoder_impl::ogg_encoder_impl(char *filename, double samp_rate,
float quality) : float quality) :
gr::sync_block ("ogg_encoder", gr::sync_block("ogg_encoder",
gr::io_signature::make (1, 1, sizeof(float)), gr::io_signature::make(1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)) gr::io_signature::make(0, 0, 0))
{ {
d_quality = quality; d_quality = quality;
d_out = fopen (filename, "wb"); d_out = fopen(filename, "wb");
d_samp_rate = samp_rate; d_samp_rate = samp_rate;
vorbis_info_init (&d_vi); vorbis_info_init(&d_vi);
int ret = vorbis_encode_init_vbr (&d_vi, 1, d_samp_rate, d_quality); int ret = vorbis_encode_init_vbr(&d_vi, 1, d_samp_rate, d_quality);
if (ret) if (ret) {
exit (1); exit(1);
}
vorbis_comment_init (&d_vc); vorbis_comment_init(&d_vc);
vorbis_comment_add_tag (&d_vc, "ENCODER", "satnogs ogg encoder"); vorbis_comment_add_tag(&d_vc, "ENCODER", "satnogs ogg encoder");
vorbis_analysis_init (&d_vd, &d_vi); vorbis_analysis_init(&d_vd, &d_vi);
vorbis_block_init (&d_vd, &d_vb); vorbis_block_init(&d_vd, &d_vb);
srand (time (NULL)); srand(time(NULL));
ogg_stream_init (&d_os, rand ()); ogg_stream_init(&d_os, rand());
ogg_packet header; ogg_packet header;
ogg_packet header_comm; ogg_packet header_comm;
ogg_packet header_code; ogg_packet header_code;
vorbis_analysis_headerout (&d_vd, &d_vc, &header, &header_comm, vorbis_analysis_headerout(&d_vd, &d_vc, &header, &header_comm,
&header_code); &header_code);
ogg_stream_packetin (&d_os, &header); ogg_stream_packetin(&d_os, &header);
ogg_stream_packetin (&d_os, &header_comm); ogg_stream_packetin(&d_os, &header_comm);
ogg_stream_packetin (&d_os, &header_code); ogg_stream_packetin(&d_os, &header_code);
int result = 1; int result = 1;
while (result) { while (result) {
result = ogg_stream_flush (&d_os, &d_og); result = ogg_stream_flush(&d_os, &d_og);
if (result == 0) if (result == 0) {
break; break;
fwrite (d_og.header, 1, d_og.header_len, d_out);
fwrite (d_og.body, 1, d_og.body_len, d_out);
} }
fwrite(d_og.header, 1, d_og.header_len, d_out);
fwrite(d_og.body, 1, d_og.body_len, d_out);
} }
}
ogg_encoder_impl::~ogg_encoder_impl () ogg_encoder_impl::~ogg_encoder_impl()
{ {
vorbis_analysis_wrote (&d_vd, 0); vorbis_analysis_wrote(&d_vd, 0);
ogg_stream_clear (&d_os); ogg_stream_clear(&d_os);
vorbis_block_clear (&d_vb); vorbis_block_clear(&d_vb);
vorbis_dsp_clear (&d_vd); vorbis_dsp_clear(&d_vd);
vorbis_comment_clear (&d_vc); vorbis_comment_clear(&d_vc);
vorbis_info_clear (&d_vi); vorbis_info_clear(&d_vi);
fclose (d_out); fclose(d_out);
} }
int int
ogg_encoder_impl::work (int noutput_items, ogg_encoder_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
const char *in = (const char *) input_items[0]; const char *in = (const char *) input_items[0];
int i; int i;
float **buffer = vorbis_analysis_buffer (&d_vd, noutput_items); float **buffer = vorbis_analysis_buffer(&d_vd, noutput_items);
memcpy(buffer[0], in, noutput_items * sizeof(float)); memcpy(buffer[0], in, noutput_items * sizeof(float));
vorbis_analysis_wrote (&d_vd, noutput_items); vorbis_analysis_wrote(&d_vd, noutput_items);
while (vorbis_analysis_blockout (&d_vd, &d_vb) == 1) { while (vorbis_analysis_blockout(&d_vd, &d_vb) == 1) {
vorbis_analysis (&d_vb, NULL); vorbis_analysis(&d_vb, NULL);
vorbis_bitrate_addblock (&d_vb); vorbis_bitrate_addblock(&d_vb);
while (vorbis_bitrate_flushpacket (&d_vd, &d_op)) { while (vorbis_bitrate_flushpacket(&d_vd, &d_op)) {
ogg_stream_packetin (&d_os, &d_op); ogg_stream_packetin(&d_os, &d_op);
int result = 1; int result = 1;
while (result) { while (result) {
int result = ogg_stream_pageout (&d_os, &d_og); int result = ogg_stream_pageout(&d_os, &d_og);
if (result == 0) if (result == 0) {
break; break;
fwrite (d_og.header, 1, d_og.header_len, d_out); }
fwrite (d_og.body, 1, d_og.body_len, d_out); fwrite(d_og.header, 1, d_og.header_len, d_out);
if (ogg_page_eos (&d_og)) fwrite(d_og.body, 1, d_og.body_len, d_out);
if (ogg_page_eos(&d_og)) {
result = 1; result = 1;
} }
} }
} }
return noutput_items;
} }
return noutput_items;
}
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -24,14 +24,11 @@
#include <satnogs/ogg_encoder.h> #include <satnogs/ogg_encoder.h>
#include <vorbis/vorbisenc.h> #include <vorbis/vorbisenc.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class ogg_encoder_impl : public ogg_encoder class ogg_encoder_impl : public ogg_encoder {
{ private:
private:
// Nothing to declare in this block. // Nothing to declare in this block.
ogg_stream_state d_os; ogg_stream_state d_os;
ogg_page d_og; ogg_page d_og;
@ -42,21 +39,21 @@ namespace gr
vorbis_dsp_state d_vd; vorbis_dsp_state d_vd;
vorbis_block d_vb; vorbis_block d_vb;
FILE* d_out; FILE *d_out;
double d_samp_rate; double d_samp_rate;
float d_quality; float d_quality;
public: public:
ogg_encoder_impl (char* filename, double samp_rate, float quality); ogg_encoder_impl(char *filename, double samp_rate, float quality);
~ogg_encoder_impl (); ~ogg_encoder_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_OGG_ENCODER_IMPL_H */ #endif /* INCLUDED_SATNOGS_OGG_ENCODER_IMPL_H */

View File

@ -33,88 +33,88 @@
#define PCM_BUF_SIZE 4096 #define PCM_BUF_SIZE 4096
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
ogg_source::sptr ogg_source::sptr
ogg_source::make (const std::string& filename, int channels, bool repeat) ogg_source::make(const std::string &filename, int channels, bool repeat)
{ {
return gnuradio::get_initial_sptr ( return gnuradio::get_initial_sptr(
new ogg_source_impl (filename, channels, repeat)); new ogg_source_impl(filename, channels, repeat));
} }
/* /*
* The private constructor * The private constructor
*/ */
ogg_source_impl::ogg_source_impl (const std::string& filename, ogg_source_impl::ogg_source_impl(const std::string &filename,
int channels, bool repeat) : int channels, bool repeat) :
gr::sync_block ( gr::sync_block(
"ogg_source", gr::io_signature::make (0, 0, 0), "ogg_source", gr::io_signature::make(0, 0, 0),
gr::io_signature::make (channels, channels, sizeof(float))), gr::io_signature::make(channels, channels, sizeof(float))),
d_channels (channels), d_channels(channels),
d_repeat (repeat) d_repeat(repeat)
{ {
if (channels < 1) { if (channels < 1) {
throw std::invalid_argument ("At least one output channels should" throw std::invalid_argument("At least one output channels should"
" be specified"); " be specified");
} }
if (ov_fopen (filename.c_str (), &d_ogvorb_f) < 0) { if (ov_fopen(filename.c_str(), &d_ogvorb_f) < 0) {
throw std::invalid_argument ("Invalid .ogg file"); throw std::invalid_argument("Invalid .ogg file");
} }
vorbis_info *vi = ov_info (&d_ogvorb_f, -1); vorbis_info *vi = ov_info(&d_ogvorb_f, -1);
if (vi->channels != (int) channels) { if (vi->channels != (int) channels) {
throw std::invalid_argument ( throw std::invalid_argument(
std::string ("Channels number specified (") std::string("Channels number specified (")
+ std::to_string (channels) + std::to_string(channels)
+ ") does not match the channels of " + ") does not match the channels of "
"the ogg stream (" + std::to_string (vi->channels) + ")"); "the ogg stream (" + std::to_string(vi->channels) + ")");
} }
const int alignment_multiple = volk_get_alignment () / sizeof(float); const int alignment_multiple = volk_get_alignment() / sizeof(float);
set_alignment (std::max (1, alignment_multiple)); set_alignment(std::max(1, alignment_multiple));
set_max_noutput_items (PCM_BUF_SIZE); set_max_noutput_items(PCM_BUF_SIZE);
d_in_buffer = (int16_t *) volk_malloc (PCM_BUF_SIZE * sizeof(int16_t), d_in_buffer = (int16_t *) volk_malloc(PCM_BUF_SIZE * sizeof(int16_t),
volk_get_alignment ()); volk_get_alignment());
d_out_buffer = (float *) volk_malloc (PCM_BUF_SIZE * sizeof(float), d_out_buffer = (float *) volk_malloc(PCM_BUF_SIZE * sizeof(float),
volk_get_alignment ()); volk_get_alignment());
if(!d_in_buffer || !d_out_buffer) { if (!d_in_buffer || !d_out_buffer) {
throw std::runtime_error("Could not allocate memory"); throw std::runtime_error("Could not allocate memory");
} }
} }
/* /*
* Our virtual destructor. * Our virtual destructor.
*/ */
ogg_source_impl::~ogg_source_impl() ogg_source_impl::~ogg_source_impl()
{ {
ov_clear(&d_ogvorb_f); ov_clear(&d_ogvorb_f);
volk_free(d_in_buffer); volk_free(d_in_buffer);
volk_free(d_out_buffer); volk_free(d_out_buffer);
} }
int int
ogg_source_impl::work(int noutput_items, ogg_source_impl::work(int noutput_items,
gr_vector_const_void_star &input_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items) gr_vector_void_star &output_items)
{ {
long int ret; long int ret;
int section = 0; int section = 0;
int available = (noutput_items / d_channels); int available = (noutput_items / d_channels);
int available_samples = 0; int available_samples = 0;
int produced = 0; int produced = 0;
ret = ov_read (&d_ogvorb_f, (char *)d_in_buffer, ret = ov_read(&d_ogvorb_f, (char *)d_in_buffer,
available * sizeof(int16_t), available * sizeof(int16_t),
0, sizeof(int16_t), 1, &section); 0, sizeof(int16_t), 1, &section);
if(ret <= 0) { if (ret <= 0) {
/* /*
* If return value is EOF and the repeat mode is set seek back to the * If return value is EOF and the repeat mode is set seek back to the
* start of the ogg stream * start of the ogg stream
*/ */
if(ret == 0 && d_repeat) { if (ret == 0 && d_repeat) {
if(ov_seekable(&d_ogvorb_f)){ if (ov_seekable(&d_ogvorb_f)) {
ov_time_seek(&d_ogvorb_f, 0); ov_time_seek(&d_ogvorb_f, 0);
return 0; return 0;
} }
@ -125,19 +125,19 @@ namespace gr {
available_samples = ret / sizeof(int16_t); available_samples = ret / sizeof(int16_t);
/* Convert to float the signed-short audio samples */ /* Convert to float the signed-short audio samples */
volk_16i_s32f_convert_32f (d_out_buffer, d_in_buffer, 2 << 15, volk_16i_s32f_convert_32f(d_out_buffer, d_in_buffer, 2 << 15,
available_samples); available_samples);
/* De-interleave the available channels */ /* De-interleave the available channels */
for(int i = 0; i < available_samples; i += d_channels, produced++) { for (int i = 0; i < available_samples; i += d_channels, produced++) {
for(int chan = 0; chan < d_channels; chan++){ for (int chan = 0; chan < d_channels; chan++) {
((float *)output_items[chan])[produced] = d_out_buffer[i * d_channels + chan]; ((float *)output_items[chan])[produced] = d_out_buffer[i * d_channels + chan];
} }
} }
return produced; return produced;
} }
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */

View File

@ -25,14 +25,11 @@
#include <vorbis/codec.h> #include <vorbis/codec.h>
#include <vorbis/vorbisfile.h> #include <vorbis/vorbisfile.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
class ogg_source_impl : public ogg_source class ogg_source_impl : public ogg_source {
{ private:
private:
const int d_channels; const int d_channels;
const bool d_repeat; const bool d_repeat;
OggVorbis_File d_ogvorb_f; OggVorbis_File d_ogvorb_f;
@ -40,18 +37,18 @@ namespace gr
int16_t *d_in_buffer; int16_t *d_in_buffer;
float *d_out_buffer; float *d_out_buffer;
public: public:
ogg_source_impl (const std::string& filename, int channels, ogg_source_impl(const std::string &filename, int channels,
bool repeat); bool repeat);
~ogg_source_impl (); ~ogg_source_impl();
// Where all the action really happens // Where all the action really happens
int int
work (int noutput_items, gr_vector_const_void_star &input_items, work(int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items); gr_vector_void_star &output_items);
}; };
} // namespace satnogs } // namespace satnogs
} // namespace gr } // namespace gr
#endif /* INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H */ #endif /* INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H */

View File

@ -23,13 +23,11 @@
#include "qa_ax25_decoder.h" #include "qa_ax25_decoder.h"
#include <satnogs/ax25_decoder.h> #include <satnogs/ax25_decoder.h>
namespace gr namespace gr {
{ namespace satnogs {
namespace satnogs
{
void void
qa_ax25_decoder::t1 () qa_ax25_decoder::t1()
{ {
// Put test here // Put test here
} }

View File

@ -25,20 +25,19 @@
#include <cppunit/TestCase.h> #include <cppunit/TestCase.h>
namespace gr { namespace gr {
namespace satnogs { namespace satnogs {
class qa_ax25_decoder : public CppUnit::TestCase class qa_ax25_decoder : public CppUnit::TestCase {
{ public:
public:
CPPUNIT_TEST_SUITE(qa_ax25_decoder); CPPUNIT_TEST_SUITE(qa_ax25_decoder);
CPPUNIT_TEST(t1); CPPUNIT_TEST(t1);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
void t1(); void t1();
}; };
} /* namespace satnogs */ } /* namespace satnogs */
} /* namespace gr */ } /* namespace gr */
#endif /* _QA_AX25_DECODER_H_ */ #endif /* _QA_AX25_DECODER_H_ */

Some files were not shown because too many files have changed in this diff Show More