Format all C++ files using the astyle beautifier
This commit is contained in:
parent
a5caed2ca9
commit
e09c180f84
|
@ -26,17 +26,14 @@
|
|||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief AMSAT 8b10b + CCSDS RS DUV decoder
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API amsat_duv_decoder : public decoder
|
||||
{
|
||||
class SATNOGS_API amsat_duv_decoder : public decoder {
|
||||
public:
|
||||
|
||||
static const size_t
|
||||
|
@ -46,20 +43,19 @@ public:
|
|||
amsat_fox_spacecraft_id[];
|
||||
|
||||
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 ();
|
||||
amsat_duv_decoder(const std::string &control_symbol, size_t max_frame_len);
|
||||
~amsat_duv_decoder();
|
||||
|
||||
decoder_status_t
|
||||
decode (const void *in, int len);
|
||||
decode(const void *in, int len);
|
||||
|
||||
void
|
||||
reset ();
|
||||
reset();
|
||||
|
||||
private:
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
SEARCH_SYNC, DECODING
|
||||
} d_state_t;
|
||||
|
||||
|
@ -80,16 +76,15 @@ private:
|
|||
std::deque<uint8_t> d_bitstream;
|
||||
|
||||
bool
|
||||
set_access_code (const std::string &control_symbol);
|
||||
set_access_code(const std::string &control_symbol);
|
||||
|
||||
void
|
||||
process_10b (uint16_t word, size_t write_pos);
|
||||
process_10b(uint16_t word, size_t write_pos);
|
||||
|
||||
inline uint16_t
|
||||
pack_10b_word(size_t idx);
|
||||
|
||||
int d_lookup_8b10b[2][256] =
|
||||
{
|
||||
int d_lookup_8b10b[2][256] = {
|
||||
// RD = -1 cases
|
||||
{
|
||||
/* 00 */0x274,
|
||||
|
@ -347,7 +342,8 @@ private:
|
|||
/* fc */0x4ee,
|
||||
/* fd */0x2e1,
|
||||
/* fe */0x1e1,
|
||||
/* ff */0x2b1, }, // RD = +1 cases
|
||||
/* ff */0x2b1,
|
||||
}, // RD = +1 cases
|
||||
{
|
||||
/* 00 */0x58b,
|
||||
/* 01 */0x62b,
|
||||
|
@ -604,7 +600,9 @@ private:
|
|||
/* fc */0x0e1,
|
||||
/* fd */0x51e,
|
||||
/* fe */0x61e,
|
||||
/* ff */0x54e, } };
|
||||
/* ff */0x54e,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -27,45 +27,39 @@
|
|||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace gr {
|
||||
|
||||
namespace satnogs
|
||||
{
|
||||
const size_t AX25_MIN_ADDR_LEN = 14;
|
||||
const size_t AX25_MAX_ADDR_LEN = 28;
|
||||
const size_t AX25_MIN_CTRL_LEN = 1;
|
||||
const size_t AX25_MAX_CTRL_LEN = 2;
|
||||
const size_t AX25_MAX_FRAME_LEN = 256;
|
||||
const uint8_t AX25_SYNC_FLAG = 0x7E;
|
||||
const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
|
||||
const float AX25_SYNC_FLAG_MAP[8] =
|
||||
{ -1, 1, 1, 1, 1, 1, 1, -1 };
|
||||
const uint8_t AX25_SYNC_FLAG_MAP_BIN[8] =
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 0 };
|
||||
/**
|
||||
namespace satnogs {
|
||||
const size_t AX25_MIN_ADDR_LEN = 14;
|
||||
const size_t AX25_MAX_ADDR_LEN = 28;
|
||||
const size_t AX25_MIN_CTRL_LEN = 1;
|
||||
const size_t AX25_MAX_CTRL_LEN = 2;
|
||||
const size_t AX25_MAX_FRAME_LEN = 256;
|
||||
const uint8_t AX25_SYNC_FLAG = 0x7E;
|
||||
const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
|
||||
const float AX25_SYNC_FLAG_MAP[8] =
|
||||
{ -1, 1, 1, 1, 1, 1, 1, -1 };
|
||||
const uint8_t AX25_SYNC_FLAG_MAP_BIN[8] =
|
||||
{ 0, 1, 1, 1, 1, 1, 1, 0 };
|
||||
/**
|
||||
* AX.25 Frame types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
AX25_I_FRAME, //!< AX25_I_FRAME Information frame
|
||||
AX25_S_FRAME, //!< AX25_S_FRAME Supervisory frame
|
||||
AX25_U_FRAME, //!< AX25_U_FRAME Unnumbered 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_encode_status_t;
|
||||
} ax25_encode_status_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
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];
|
||||
size_t address_len;
|
||||
uint16_t ctrl;
|
||||
|
@ -74,21 +68,21 @@ namespace gr
|
|||
uint8_t *info;
|
||||
size_t info_len;
|
||||
ax25_frame_type_t type;
|
||||
} ax25_frame_t;
|
||||
} ax25_frame_t;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Calculates the FCS of the AX25 frame
|
||||
* @param buffer data buffer
|
||||
* @param len size of the buffer
|
||||
* @return the FCS of the buffer
|
||||
*/
|
||||
static inline uint16_t
|
||||
ax25_fcs (uint8_t *buffer, size_t len)
|
||||
{
|
||||
static inline uint16_t
|
||||
ax25_fcs(uint8_t *buffer, size_t len)
|
||||
{
|
||||
return crc::crc16_ax25(buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates the header field of the AX.25 frame
|
||||
* @param out the output buffer with enough memory to hold the address field
|
||||
* @param dest_addr the destination callsign address
|
||||
|
@ -96,14 +90,14 @@ namespace gr
|
|||
* @param src_addr the callsign of the source
|
||||
* @param src_ssid the source SSID
|
||||
*/
|
||||
static inline size_t
|
||||
ax25_create_addr_field (uint8_t *out, std::string dest_addr,
|
||||
static inline size_t
|
||||
ax25_create_addr_field(uint8_t *out, std::string dest_addr,
|
||||
uint8_t dest_ssid, std::string src_addr,
|
||||
uint8_t src_ssid)
|
||||
{
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < dest_addr.length (); i++) {
|
||||
for (i = 0; i < dest_addr.length(); i++) {
|
||||
*out++ = dest_addr[i] << 1;
|
||||
}
|
||||
/*
|
||||
|
@ -117,7 +111,7 @@ namespace gr
|
|||
/* FIXME: C bit is set to 0 implicitly */
|
||||
*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;
|
||||
}
|
||||
for (; i < AX25_CALLSIGN_MAX_LEN; i++) {
|
||||
|
@ -129,39 +123,39 @@ namespace gr
|
|||
/* FIXME: C bit is set to 0 implicitly */
|
||||
*out++ = ((0b1111 & src_ssid) << 1) | 0b01100001;
|
||||
return AX25_MIN_ADDR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Gets the destination SSID of an AX.25 frame
|
||||
* @param in the AX.25 frame buffer
|
||||
* @return the destination SSID
|
||||
*/
|
||||
static inline uint8_t
|
||||
ax25_get_dest_ssid (const uint8_t *in)
|
||||
{
|
||||
static inline uint8_t
|
||||
ax25_get_dest_ssid(const uint8_t *in)
|
||||
{
|
||||
uint8_t ret;
|
||||
ret = in[AX25_CALLSIGN_MAX_LEN];
|
||||
return (ret >> 1) & 0b1111;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
ax25_prepare_frame (uint8_t *out, const uint8_t *info, size_t info_len,
|
||||
static inline size_t
|
||||
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,
|
||||
uint16_t ctrl, size_t ctrl_len, size_t preamble_len,
|
||||
size_t postamble_len)
|
||||
{
|
||||
{
|
||||
uint16_t fcs;
|
||||
size_t i;
|
||||
if (info_len > AX25_MAX_FRAME_LEN) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (out, AX25_SYNC_FLAG, preamble_len);
|
||||
memset(out, AX25_SYNC_FLAG, preamble_len);
|
||||
i = preamble_len;
|
||||
|
||||
/* Insert address and control fields */
|
||||
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;
|
||||
}
|
||||
else {
|
||||
|
@ -169,7 +163,7 @@ namespace gr
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
|
@ -184,23 +178,23 @@ namespace gr
|
|||
if (type == AX25_I_FRAME || type == AX25_UI_FRAME) {
|
||||
out[i++] = 0xF0;
|
||||
}
|
||||
memcpy (out + i, info, info_len);
|
||||
memcpy(out + i, info, info_len);
|
||||
i += info_len;
|
||||
|
||||
/* 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 */
|
||||
out[i++] = fcs & 0xFF;
|
||||
out[i++] = (fcs >> 8) & 0xFF;
|
||||
memset (out + i, AX25_SYNC_FLAG, postamble_len);
|
||||
for(size_t j = preamble_len; j < i; j++) {
|
||||
memset(out + i, AX25_SYNC_FLAG, postamble_len);
|
||||
for (size_t j = preamble_len; j < i; j++) {
|
||||
printf("0x%02x ", out[j]);
|
||||
}
|
||||
printf("\n");
|
||||
return i + postamble_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an AX.25 by performing NRZ encoding and bit stuffing
|
||||
* @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
|
||||
|
@ -224,11 +218,11 @@ namespace gr
|
|||
*
|
||||
* @return the resulting status of the encoding
|
||||
*/
|
||||
static inline ax25_encode_status_t
|
||||
ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer,
|
||||
static inline ax25_encode_status_t
|
||||
ax25_nrz_bit_stuffing(float *out, size_t *out_len, const uint8_t *buffer,
|
||||
size_t buffer_len, size_t preamble_len,
|
||||
size_t postamble_len)
|
||||
{
|
||||
{
|
||||
uint8_t bit;
|
||||
uint8_t prev_bit = 0;
|
||||
size_t out_idx = 0;
|
||||
|
@ -239,7 +233,7 @@ namespace gr
|
|||
|
||||
/* Leading FLAG field does not need bit stuffing */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -274,15 +268,15 @@ namespace gr
|
|||
|
||||
/* Trailing FLAG field does not need bit stuffing */
|
||||
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_len = out_idx;
|
||||
return AX25_ENC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs an AX.25 by performing bit stuffing.
|
||||
* @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
|
||||
|
@ -306,11 +300,11 @@ namespace gr
|
|||
*
|
||||
* @return the resulting status of the encoding
|
||||
*/
|
||||
static inline ax25_encode_status_t
|
||||
ax25_bit_stuffing (uint8_t *out, size_t *out_len, const uint8_t *buffer,
|
||||
static inline ax25_encode_status_t
|
||||
ax25_bit_stuffing(uint8_t *out, size_t *out_len, const uint8_t *buffer,
|
||||
const size_t buffer_len, size_t preamble_len,
|
||||
size_t postamble_len)
|
||||
{
|
||||
{
|
||||
uint8_t bit;
|
||||
uint8_t shift_reg = 0x0;
|
||||
size_t out_idx = 0;
|
||||
|
@ -319,7 +313,7 @@ namespace gr
|
|||
|
||||
/* Leading FLAG field does not need bit stuffing */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -339,18 +333,18 @@ namespace gr
|
|||
|
||||
/* Trailing FLAG field does not need bit stuffing */
|
||||
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_len = out_idx;
|
||||
return AX25_ENC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static inline ax25_decode_status_t
|
||||
ax25_decode (uint8_t *out, size_t *out_len, const uint8_t *ax25_frame,
|
||||
static inline ax25_decode_status_t
|
||||
ax25_decode(uint8_t *out, size_t *out_len, const uint8_t *ax25_frame,
|
||||
size_t len)
|
||||
{
|
||||
{
|
||||
size_t i;
|
||||
size_t frame_start = UINT_MAX;
|
||||
size_t frame_stop = UINT_MAX;
|
||||
|
@ -430,7 +424,7 @@ namespace gr
|
|||
}
|
||||
|
||||
/* 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)
|
||||
| out[received_bytes - 1];
|
||||
|
||||
|
@ -442,9 +436,9 @@ namespace gr
|
|||
*out_len = received_bytes - sizeof(uint16_t);
|
||||
return AX25_DEC_OK;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
|
||||
} // namespace gr
|
||||
|
||||
|
|
|
@ -27,10 +27,8 @@
|
|||
|
||||
#include <deque>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief AX.25 decoder that supports the legacy hardware radios.
|
||||
|
@ -52,8 +50,7 @@ namespace satnogs
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API ax25_decoder : public decoder
|
||||
{
|
||||
class SATNOGS_API ax25_decoder : public decoder {
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -79,7 +76,7 @@ public:
|
|||
* @return a shared pointer of the decoder instance
|
||||
*/
|
||||
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,
|
||||
size_t max_frame_len = 512);
|
||||
|
||||
|
@ -104,21 +101,20 @@ public:
|
|||
* @param crc_check bypass the CRC check of the frame
|
||||
* @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,
|
||||
size_t max_frame_len = 512);
|
||||
|
||||
~ax25_decoder ();
|
||||
~ax25_decoder();
|
||||
|
||||
decoder_status_t
|
||||
decode (const void *in, int len);
|
||||
decode(const void *in, int len);
|
||||
|
||||
void
|
||||
reset ();
|
||||
reset();
|
||||
private:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
NO_SYNC, IN_SYNC, DECODING
|
||||
} decoding_state_t;
|
||||
|
||||
|
@ -143,21 +139,21 @@ private:
|
|||
size_t d_frame_start;
|
||||
|
||||
void
|
||||
reset_state ();
|
||||
reset_state();
|
||||
void
|
||||
enter_sync_state ();
|
||||
enter_sync_state();
|
||||
void
|
||||
enter_decoding_state ();
|
||||
enter_decoding_state();
|
||||
bool
|
||||
enter_frame_end (decoder_status_t& status);
|
||||
enter_frame_end(decoder_status_t &status);
|
||||
|
||||
bool
|
||||
_decode (decoder_status_t& status);
|
||||
_decode(decoder_status_t &status);
|
||||
|
||||
inline void
|
||||
decode_1b (uint8_t in);
|
||||
decode_1b(uint8_t in);
|
||||
bool
|
||||
frame_check ();
|
||||
frame_check();
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief AX.25 encoder block that supports the legacy hardware radios.
|
||||
*
|
||||
* The block takes as inputs blob PMT messages and generates a byte stream.
|
||||
|
@ -39,9 +37,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API ax25_encoder_mb : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API ax25_encoder_mb : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<ax25_encoder_mb> sptr;
|
||||
|
||||
|
||||
|
@ -64,14 +61,14 @@ namespace gr
|
|||
* after bit stuffing
|
||||
*/
|
||||
static sptr
|
||||
make (const std::string& dest_addr, uint8_t dest_ssid,
|
||||
const std::string& src_addr,
|
||||
uint8_t src_ssid, size_t preamble_len =16,
|
||||
make(const std::string &dest_addr, uint8_t dest_ssid,
|
||||
const std::string &src_addr,
|
||||
uint8_t src_ssid, size_t preamble_len = 16,
|
||||
size_t postamble_len = 16,
|
||||
bool scramble = true);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_H */
|
||||
|
|
|
@ -49,13 +49,13 @@ static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|||
"0123456789+/";
|
||||
|
||||
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
|
||||
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;
|
||||
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_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]];
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j < 3; j++)
|
||||
for (j = i; j < 3; j++) {
|
||||
char_array_3[j] = '\0';
|
||||
}
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
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_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]];
|
||||
}
|
||||
|
||||
while ((i++ < 3))
|
||||
while ((i++ < 3)) {
|
||||
ret += '=';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -102,9 +106,9 @@ base64_encode (unsigned char const *bytes_to_encode, unsigned int in_len)
|
|||
}
|
||||
|
||||
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 j = 0;
|
||||
int in_ = 0;
|
||||
|
@ -112,12 +116,13 @@ base64_decode (std::string const &encoded_string)
|
|||
std::string ret;
|
||||
|
||||
while (in_len-- && (encoded_string[in_] != '=')
|
||||
&& is_base64 (encoded_string[in_])) {
|
||||
&& is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_];
|
||||
in_++;
|
||||
if (i == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
char_array_4[i] = base64_chars.find (char_array_4[i]) & 0xff;
|
||||
for (i = 0; i < 4; i++) {
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]) & 0xff;
|
||||
}
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2)
|
||||
+ ((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_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];
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = 0; j < i; j++)
|
||||
char_array_4[j] = base64_chars.find (char_array_4[j]) & 0xff;
|
||||
for (j = 0; j < i; j++) {
|
||||
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[1] = ((char_array_4[1] & 0xf) << 4)
|
||||
+ ((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];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief This block corrects the doppler effect between the ground
|
||||
* station and the satellite in a coarse and very simplified way.
|
||||
* Instead of changing the hardware center frequency, we use an NCO
|
||||
|
@ -38,9 +36,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API coarse_doppler_correction_cc : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API coarse_doppler_correction_cc : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<coarse_doppler_correction_cc> sptr;
|
||||
|
||||
/**
|
||||
|
@ -53,10 +50,10 @@ namespace gr
|
|||
* @param sampling_rate the sampling rate of the signal
|
||||
*/
|
||||
static sptr
|
||||
make (double target_freq, double sampling_rate);
|
||||
};
|
||||
make(double target_freq, double sampling_rate);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_H */
|
||||
|
|
|
@ -25,20 +25,17 @@
|
|||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief <+description+>
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API convolutional_deinterleaver
|
||||
{
|
||||
class SATNOGS_API convolutional_deinterleaver {
|
||||
public:
|
||||
convolutional_deinterleaver (size_t branches, size_t M);
|
||||
~convolutional_deinterleaver ();
|
||||
convolutional_deinterleaver(size_t branches, size_t M);
|
||||
~convolutional_deinterleaver();
|
||||
|
||||
uint8_t
|
||||
decode_bit(uint8_t b);
|
||||
|
|
|
@ -23,17 +23,14 @@
|
|||
|
||||
#include <satnogs/api.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* CRC class providing a range of different CRC calculation static methods
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API crc
|
||||
{
|
||||
class SATNOGS_API crc {
|
||||
public:
|
||||
typedef enum crc_type {
|
||||
PDU = 0,
|
||||
|
|
|
@ -25,21 +25,18 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief CW encoder block, mainly for debugging and testing purposes.
|
||||
* It accepts a CW word via a message source port and transmits the
|
||||
* corresponding CW symbols.
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API cw_encoder : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API cw_encoder : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<cw_encoder> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -49,10 +46,10 @@ namespace gr
|
|||
* @param wpm words per minute (WPM)
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_CW_ENCODER_H */
|
||||
|
|
|
@ -27,12 +27,10 @@
|
|||
#define MIN_WPM 5
|
||||
#define MAX_WPM 50
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief The CW to Symbol block tries to translate the input signal
|
||||
* into Morse symbols. The input signal should have been already properly
|
||||
* filtered and processed. A possible DSP on the input signal may be the
|
||||
|
@ -42,9 +40,8 @@ namespace gr
|
|||
*
|
||||
* \ingroup satnogs
|
||||
*/
|
||||
class SATNOGS_API cw_to_symbol : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API cw_to_symbol : virtual public gr::sync_block {
|
||||
public:
|
||||
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.
|
||||
*/
|
||||
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 hysteresis = 0);
|
||||
|
||||
virtual void
|
||||
set_act_threshold (float thrld) = 0;
|
||||
};
|
||||
set_act_threshold(float thrld) = 0;
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,19 +24,16 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief A block for debug reasons producing specific messages
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API debug_msg_source : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API debug_msg_source : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<debug_msg_source> sptr;
|
||||
|
||||
/**
|
||||
|
@ -47,10 +44,10 @@ namespace gr
|
|||
* \p delay seconds
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_H */
|
||||
|
|
|
@ -24,21 +24,18 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief A block for debug reasons producing specific messages.
|
||||
* The input message can be anything, opposed to the \p debug_msg_source()
|
||||
* block that can accept only string messages.
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API debug_msg_source_raw : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API debug_msg_source_raw : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<debug_msg_source_raw> sptr;
|
||||
|
||||
/**
|
||||
|
@ -49,10 +46,10 @@ namespace gr
|
|||
* \p delay seconds
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_H */
|
||||
|
|
|
@ -26,22 +26,19 @@
|
|||
#include <cstdlib>
|
||||
#include <pmt/pmt.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/**
|
||||
* The status of the decoder
|
||||
*/
|
||||
class decoder_status
|
||||
{
|
||||
class decoder_status {
|
||||
public:
|
||||
int consumed; /**< The number of input items consumed */
|
||||
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 */
|
||||
|
||||
decoder_status () :
|
||||
decoder_status() :
|
||||
consumed(0),
|
||||
decode_success(false),
|
||||
data(pmt::make_dict())
|
||||
|
@ -63,18 +60,17 @@ typedef class decoder_status decoder_status_t;
|
|||
* appropriate decoder class that implements this abstract class API.
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API decoder
|
||||
{
|
||||
class SATNOGS_API decoder {
|
||||
public:
|
||||
typedef boost::shared_ptr<decoder> decoder_sptr;
|
||||
|
||||
static int base_unique_id;
|
||||
|
||||
int
|
||||
unique_id ();
|
||||
unique_id();
|
||||
|
||||
decoder (int input_item_size, size_t max_frame_len = 8192);
|
||||
virtual ~decoder ();
|
||||
decoder(int input_item_size, size_t max_frame_len = 8192);
|
||||
virtual ~decoder();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
reset () = 0;
|
||||
reset() = 0;
|
||||
|
||||
size_t
|
||||
max_frame_len() const;
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief This block corrects the doppler effect between the ground
|
||||
* station and the satellite. It takes the imput stream in baseband
|
||||
* and applies proper corrections to keep the carrier at the desired
|
||||
|
@ -39,9 +37,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API doppler_correction_cc : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API doppler_correction_cc : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<doppler_correction_cc> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -55,11 +52,11 @@ namespace gr
|
|||
* that the block should perform
|
||||
*/
|
||||
static sptr
|
||||
make (double target_freq, double sampling_rate,
|
||||
make(double target_freq, double sampling_rate,
|
||||
size_t corrections_per_sec = 1000);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_H */
|
||||
|
|
|
@ -26,35 +26,32 @@
|
|||
#include <deque>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Doppler frequency polynomial fitting tool
|
||||
* \ingroup satnogs
|
||||
*/
|
||||
class SATNOGS_API doppler_fit
|
||||
{
|
||||
public:
|
||||
doppler_fit (size_t degree);
|
||||
class SATNOGS_API doppler_fit {
|
||||
public:
|
||||
doppler_fit(size_t degree);
|
||||
|
||||
void
|
||||
fit (std::deque<freq_drift> drifts);
|
||||
fit(std::deque<freq_drift> drifts);
|
||||
|
||||
void
|
||||
predict_freqs (double *freqs, size_t ncorrections,
|
||||
predict_freqs(double *freqs, size_t ncorrections,
|
||||
size_t samples_per_correction);
|
||||
|
||||
private:
|
||||
private:
|
||||
const size_t d_degree;
|
||||
double d_last_x;
|
||||
std::vector<double> d_coeff;
|
||||
boost::mutex d_mutex;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DOPPLER_FIT_H */
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
#include <satnogs/whitening.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief A generic frame acquisition block
|
||||
|
@ -60,8 +58,7 @@ namespace satnogs
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API frame_acquisition : virtual public gr::sync_block
|
||||
{
|
||||
class SATNOGS_API frame_acquisition : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<frame_acquisition> sptr;
|
||||
|
||||
|
@ -122,9 +119,9 @@ public:
|
|||
*/
|
||||
static sptr
|
||||
make(variant_t variant,
|
||||
const std::vector<uint8_t>& preamble,
|
||||
const std::vector<uint8_t> &preamble,
|
||||
size_t preamble_threshold,
|
||||
const std::vector<uint8_t>& sync,
|
||||
const std::vector<uint8_t> &sync,
|
||||
size_t sync_threshold,
|
||||
size_t frame_size_field_len,
|
||||
size_t frame_len,
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
#include <satnogs/decoder.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief This is a generic frame decoder block. It takes as input a
|
||||
* bit stream and produces decoded frames and their metadata.
|
||||
*
|
||||
|
@ -41,9 +41,8 @@ namespace gr {
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API frame_decoder : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API frame_decoder : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<frame_decoder> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -51,9 +50,9 @@ namespace gr {
|
|||
* @param decoder_object the decoder object to use
|
||||
*/
|
||||
static sptr make(decoder::decoder_sptr decoder_object, int input_size);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FRAME_DECODER_H */
|
||||
|
|
|
@ -25,16 +25,15 @@
|
|||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API frame_encoder : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API frame_encoder : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<frame_encoder> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -45,10 +44,10 @@ namespace gr {
|
|||
* class. satnogs::frame_encoder::make is the public interface for
|
||||
* 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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FRAME_ENCODER_H */
|
||||
|
|
|
@ -24,19 +24,16 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API frame_file_sink : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API frame_file_sink : virtual public gr::block {
|
||||
public:
|
||||
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
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_H */
|
||||
|
|
|
@ -24,36 +24,33 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Class that specifies the frequency drift at a given time.
|
||||
* The time is measured in samples.
|
||||
* \ingroup satnogs
|
||||
*/
|
||||
class SATNOGS_API freq_drift
|
||||
{
|
||||
public:
|
||||
freq_drift (uint64_t x, double y);
|
||||
~freq_drift ();
|
||||
class SATNOGS_API freq_drift {
|
||||
public:
|
||||
freq_drift(uint64_t x, double y);
|
||||
~freq_drift();
|
||||
double
|
||||
get_freq_drift () const;
|
||||
get_freq_drift() const;
|
||||
void
|
||||
set_freq_drift (double freqDrift);
|
||||
set_freq_drift(double freqDrift);
|
||||
uint64_t
|
||||
get_x () const;
|
||||
get_x() const;
|
||||
void
|
||||
set_x (uint64_t x);
|
||||
set_x(uint64_t x);
|
||||
|
||||
private:
|
||||
private:
|
||||
uint64_t d_x;
|
||||
double d_freq_drift;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FREQ_DRIFT_H */
|
||||
|
|
|
@ -27,10 +27,8 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief A binary Golay (24,12,8) encoder and decoder.
|
||||
|
@ -42,11 +40,10 @@ namespace satnogs
|
|||
* John Wiley & Sons, 2006.
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API golay24
|
||||
{
|
||||
class SATNOGS_API golay24 {
|
||||
public:
|
||||
golay24 ();
|
||||
~golay24 ();
|
||||
golay24();
|
||||
~golay24();
|
||||
|
||||
static const std::vector<uint32_t> G_P;
|
||||
static const std::vector<uint32_t> G_I;
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
#include <satnogs/whitening.h>
|
||||
#include <satnogs/crc.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief A IEEE 802.15.4 like decoder
|
||||
|
@ -40,15 +38,14 @@ namespace satnogs
|
|||
* scheme.
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API ieee802_15_4_variant_decoder
|
||||
{
|
||||
class SATNOGS_API ieee802_15_4_variant_decoder {
|
||||
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,
|
||||
const std::vector<uint8_t> &sync,
|
||||
crc::crc_t crc,
|
||||
whitening::whitening_sptr descrambler);
|
||||
~ieee802_15_4_variant_decoder ();
|
||||
~ieee802_15_4_variant_decoder();
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
@ -25,12 +25,10 @@
|
|||
#include <gnuradio/sync_block.h>
|
||||
#include <gnuradio/blocks/file_sink_base.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \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
|
||||
* as a null sink block.
|
||||
|
@ -38,10 +36,9 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API iq_sink : virtual public gr::sync_block,
|
||||
virtual public gr::blocks::file_sink_base
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API iq_sink : virtual public gr::sync_block,
|
||||
virtual public gr::blocks::file_sink_base {
|
||||
public:
|
||||
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.
|
||||
*/
|
||||
static sptr make(const float scale,
|
||||
const char *filename, bool append=false,
|
||||
const char *filename, bool append = false,
|
||||
const int status = 0);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
// namespace satnogs
|
||||
// namespace satnogs
|
||||
}// namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_IQ_SINK_H */
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <string>
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief This block takes a PMT message from the SatNOGS decoders
|
||||
|
@ -36,8 +34,7 @@ namespace satnogs
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API json_converter : virtual public gr::block
|
||||
{
|
||||
class SATNOGS_API json_converter : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<json_converter> sptr;
|
||||
|
||||
|
@ -53,7 +50,7 @@ public:
|
|||
* @return shared pointer of the block instance
|
||||
*/
|
||||
static sptr
|
||||
make (const std::string& extra = "");
|
||||
make(const std::string &extra = "");
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -24,18 +24,15 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API lrpt_decoder : virtual public gr::block
|
||||
{
|
||||
class SATNOGS_API lrpt_decoder : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<lrpt_decoder> sptr;
|
||||
|
||||
|
@ -48,7 +45,7 @@ public:
|
|||
* creating new instances.
|
||||
*/
|
||||
static sptr
|
||||
make ();
|
||||
make();
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -24,18 +24,15 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API lrpt_sync : virtual public gr::sync_block
|
||||
{
|
||||
class SATNOGS_API lrpt_sync : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<lrpt_sync> sptr;
|
||||
|
||||
|
@ -48,7 +45,7 @@ public:
|
|||
* creating new instances.
|
||||
*/
|
||||
static sptr
|
||||
make (size_t threshold = 2);
|
||||
make(size_t threshold = 2);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -32,10 +32,9 @@ namespace gr {
|
|||
namespace satnogs {
|
||||
|
||||
|
||||
class SATNOGS_API metadata
|
||||
{
|
||||
class SATNOGS_API metadata {
|
||||
public:
|
||||
typedef enum key{
|
||||
typedef enum key {
|
||||
PDU = 0,
|
||||
CRC_VALID,
|
||||
FREQ_OFFSET,
|
||||
|
@ -48,7 +47,7 @@ public:
|
|||
} key_t;
|
||||
|
||||
static std::string
|
||||
value(const key_t& k);
|
||||
value(const key_t &k);
|
||||
|
||||
static std::string
|
||||
keys();
|
||||
|
@ -78,7 +77,7 @@ public:
|
|||
add_corrected_bits(pmt::pmt_t &m, uint32_t cnt);
|
||||
|
||||
static Json::Value
|
||||
to_json(const pmt::pmt_t& m);
|
||||
to_json(const pmt::pmt_t &m);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -25,21 +25,18 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief A Morse debug source block that supports injection of random
|
||||
* errors based on a Bernulli distribution with probability p.
|
||||
*
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API morse_debug_source : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API morse_debug_source : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<morse_debug_source> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -58,14 +55,14 @@ namespace gr
|
|||
* dot durations.
|
||||
*/
|
||||
static sptr
|
||||
make (const size_t wpm,
|
||||
const std::string& debug_seq,
|
||||
make(const size_t wpm,
|
||||
const std::string &debug_seq,
|
||||
bool inject_errors = false,
|
||||
float error_prob = 0.1,
|
||||
size_t seq_pause_ms = 1000);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_H */
|
||||
|
|
|
@ -25,16 +25,15 @@
|
|||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
/*!
|
||||
namespace satnogs {
|
||||
/*!
|
||||
* \brief Morse code decoder block.
|
||||
*
|
||||
* This block received messages from the previous blocks
|
||||
* and try to decode the dot and dashes into clear text.
|
||||
*/
|
||||
class SATNOGS_API morse_decoder : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API morse_decoder : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<morse_decoder> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -46,9 +45,9 @@ namespace gr {
|
|||
* false alarms
|
||||
*/
|
||||
static sptr make(char unrecognized_char = '#', size_t min_frame_len = 3);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_MORSE_DECODER_H */
|
||||
|
|
|
@ -26,41 +26,38 @@
|
|||
#include <string>
|
||||
#include <satnogs/morse.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Binary tree node containing the corresponding character
|
||||
*/
|
||||
class SATNOGS_API tree_node
|
||||
{
|
||||
private:
|
||||
class SATNOGS_API tree_node {
|
||||
private:
|
||||
const char d_char;
|
||||
tree_node *d_left;
|
||||
tree_node *d_right;
|
||||
|
||||
public:
|
||||
tree_node (char c);
|
||||
public:
|
||||
tree_node(char c);
|
||||
|
||||
void
|
||||
set_left_child (tree_node *child);
|
||||
set_left_child(tree_node *child);
|
||||
|
||||
void
|
||||
set_right_child (tree_node *child);
|
||||
set_right_child(tree_node *child);
|
||||
|
||||
tree_node*
|
||||
get_left_child ();
|
||||
tree_node *
|
||||
get_left_child();
|
||||
|
||||
tree_node*
|
||||
get_right_child ();
|
||||
tree_node *
|
||||
get_right_child();
|
||||
|
||||
char
|
||||
get_char ();
|
||||
};
|
||||
get_char();
|
||||
};
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief A Binary tree representation of the Morse coding scheme.
|
||||
* Left transitions occur when a dot is received, whereas right transitions
|
||||
* are performed during the reception of a dash.
|
||||
|
@ -68,24 +65,23 @@ namespace gr
|
|||
* The tree follows the ITU International Morse code representation
|
||||
* ITU-R M.1677-1
|
||||
*/
|
||||
class SATNOGS_API morse_tree
|
||||
{
|
||||
public:
|
||||
morse_tree ();
|
||||
morse_tree (char unrecognized);
|
||||
~morse_tree ();
|
||||
class SATNOGS_API morse_tree {
|
||||
public:
|
||||
morse_tree();
|
||||
morse_tree(char unrecognized);
|
||||
~morse_tree();
|
||||
void
|
||||
reset ();
|
||||
reset();
|
||||
bool
|
||||
received_symbol (morse_symbol_t s);
|
||||
received_symbol(morse_symbol_t s);
|
||||
std::string
|
||||
get_word ();
|
||||
get_word();
|
||||
size_t
|
||||
get_max_word_len () const;
|
||||
get_max_word_len() const;
|
||||
size_t
|
||||
get_word_len ();
|
||||
get_word_len();
|
||||
|
||||
private:
|
||||
private:
|
||||
const char d_unrecognized_symbol;
|
||||
tree_node *d_root;
|
||||
tree_node *d_current;
|
||||
|
@ -94,12 +90,12 @@ namespace gr
|
|||
std::unique_ptr<char[]> d_word_buffer;
|
||||
|
||||
void
|
||||
construct_tree ();
|
||||
construct_tree();
|
||||
void
|
||||
delete_tree (tree_node *node);
|
||||
};
|
||||
delete_tree(tree_node *node);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_MORSE_TREE_H */
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Block accepting clear text messages from various decoders.
|
||||
* Its purpose is to forward these messages at other services, programs,
|
||||
* stdout, etc,
|
||||
|
@ -37,9 +35,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API multi_format_msg_sink : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API multi_format_msg_sink : virtual public gr::block {
|
||||
public:
|
||||
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
|
||||
*/
|
||||
static sptr
|
||||
make (size_t format, bool timestamp = true,
|
||||
make(size_t format, bool timestamp = true,
|
||||
bool out_stdout = true,
|
||||
const std::string& filepath = "");
|
||||
};
|
||||
const std::string &filepath = "");
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_H */
|
||||
|
|
|
@ -24,19 +24,16 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Sink block for NOAA satellites
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API noaa_apt_sink : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API noaa_apt_sink : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<noaa_apt_sink> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -66,11 +63,11 @@ namespace gr
|
|||
*
|
||||
*/
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_H */
|
||||
|
|
|
@ -24,19 +24,16 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Ogg encoder and sink block
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API ogg_encoder : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API ogg_encoder : virtual public gr::sync_block {
|
||||
public:
|
||||
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)
|
||||
*/
|
||||
static sptr
|
||||
make (char* filename, double samp_rate, float quality);
|
||||
};
|
||||
make(char *filename, double samp_rate, float quality);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_OGG_ENCODER_H */
|
||||
|
|
|
@ -24,21 +24,18 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief OGG source block. Reads a file with an OGG audio and
|
||||
* convert it to float samples
|
||||
*
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API ogg_source : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API ogg_source : virtual public gr::sync_block {
|
||||
public:
|
||||
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.
|
||||
*/
|
||||
static sptr
|
||||
make (const std::string& filename, int channels = 1,
|
||||
make(const std::string &filename, int channels = 1,
|
||||
bool repeat = false);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_OGG_SOURCE_H */
|
||||
|
|
|
@ -24,20 +24,17 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Parses the received AX.25 and separates the
|
||||
* telecommand and control frames from the WOD frames.
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API qb50_deframer : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API qb50_deframer : virtual public gr::block {
|
||||
public:
|
||||
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
|
||||
*/
|
||||
static sptr
|
||||
make (uint8_t wod_ssid);
|
||||
};
|
||||
make(uint8_t wod_ssid);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_QB50_DEFRAMER_H */
|
||||
|
|
|
@ -25,20 +25,17 @@
|
|||
#include <deque>
|
||||
#include <ostream>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief Implements a bit shift register
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API shift_reg
|
||||
{
|
||||
class SATNOGS_API shift_reg {
|
||||
public:
|
||||
shift_reg (size_t len);
|
||||
~shift_reg ();
|
||||
shift_reg(size_t len);
|
||||
~shift_reg();
|
||||
|
||||
void
|
||||
reset();
|
||||
|
@ -56,24 +53,24 @@ public:
|
|||
count();
|
||||
|
||||
shift_reg
|
||||
operator|(const shift_reg& rhs);
|
||||
operator|(const shift_reg &rhs);
|
||||
|
||||
shift_reg
|
||||
operator&(const shift_reg& rhs);
|
||||
operator&(const shift_reg &rhs);
|
||||
|
||||
shift_reg
|
||||
operator^(const shift_reg& rhs);
|
||||
operator^(const shift_reg &rhs);
|
||||
|
||||
shift_reg&
|
||||
shift_reg &
|
||||
operator>>=(bool bit);
|
||||
|
||||
bool&
|
||||
bool &
|
||||
operator[](size_t pos);
|
||||
|
||||
bool
|
||||
operator[](size_t pos) const;
|
||||
|
||||
shift_reg&
|
||||
shift_reg &
|
||||
operator<<=(bool bit);
|
||||
|
||||
void
|
||||
|
@ -88,8 +85,8 @@ public:
|
|||
bool
|
||||
back();
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const shift_reg& reg);
|
||||
friend std::ostream &
|
||||
operator<<(std::ostream &os, const shift_reg ®);
|
||||
|
||||
private:
|
||||
const size_t d_len;
|
||||
|
|
|
@ -119,20 +119,17 @@
|
|||
#define TURN_ON 1
|
||||
#define RESET 2
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
/*!
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
/*!
|
||||
* \brief Telemetry and telecommands packet methods
|
||||
* \ingroup satnogs
|
||||
*/
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Return status codes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
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_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_ERROR = 7, //!< R_OBC_ERROR an error occured
|
||||
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;
|
||||
uint16_t cnv16[2];
|
||||
uint8_t cnv8[4];
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
/* packet id */
|
||||
uint8_t ver; /* 3 bits, should be equal to 0 */
|
||||
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 */
|
||||
|
||||
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 app_id_verification[MAX_APP_ID];
|
||||
const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES];
|
||||
const uint8_t services_verification_TC_TM[MAX_SERVICES][MAX_SUBTYPES][2];
|
||||
const uint8_t app_id_verification[MAX_APP_ID];
|
||||
const uint8_t services_verification_OBC_TC[MAX_SERVICES][MAX_SUBTYPES];
|
||||
|
||||
extern OBC_ret_state_t
|
||||
verification_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt,
|
||||
extern OBC_ret_state_t
|
||||
verification_pack_pkt_api(uint8_t *buf, tc_tm_pkt *pkt,
|
||||
uint16_t *buf_pointer);
|
||||
extern OBC_ret_state_t
|
||||
hk_pack_pkt_api (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer);
|
||||
extern OBC_ret_state_t
|
||||
hk_pack_pkt_api(uint8_t *buf, tc_tm_pkt *pkt, uint16_t *buf_pointer);
|
||||
|
||||
|
||||
static inline uint8_t
|
||||
ecss_tm_checksum (const uint8_t *data, uint16_t size)
|
||||
{
|
||||
static inline uint8_t
|
||||
ecss_tm_checksum(const uint8_t *data, uint16_t size)
|
||||
{
|
||||
uint8_t CRC = 0;
|
||||
for (int i = 0; i <= size; i++) {
|
||||
CRC = CRC ^ data[i];
|
||||
}
|
||||
return CRC;
|
||||
}
|
||||
}
|
||||
|
||||
/*Must check for endianess*/
|
||||
static inline OBC_ret_state_t
|
||||
ecss_tm_unpack_pkt (const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size)
|
||||
{
|
||||
/*Must check for endianess*/
|
||||
static inline OBC_ret_state_t
|
||||
ecss_tm_unpack_pkt(const uint8_t *buf, tc_tm_pkt *pkt, const uint16_t size)
|
||||
{
|
||||
union _cnv cnv;
|
||||
uint8_t tmp_crc[2];
|
||||
|
||||
uint8_t ver, dfield_hdr, ccsds_sec_hdr, tc_pus;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -289,25 +284,25 @@ namespace gr
|
|||
}
|
||||
|
||||
return R_OBC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Packs a TC packet into a byte buffer
|
||||
* @param buf buffer to store the data to be sent
|
||||
* @param pkt the data to be stored in the buffer
|
||||
* @param size size of the array
|
||||
* @return appropriate error code or R_OBC_OK if all operation succeed
|
||||
*/
|
||||
static inline OBC_ret_state_t
|
||||
ecss_tm_pack_pkt (uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size)
|
||||
{
|
||||
static inline OBC_ret_state_t
|
||||
ecss_tm_pack_pkt(uint8_t *buf, tc_tm_pkt *pkt, uint16_t *size)
|
||||
{
|
||||
|
||||
union _cnv cnv;
|
||||
uint8_t buf_pointer;
|
||||
|
||||
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]);
|
||||
buf[1] = cnv.cnv8[0];
|
||||
|
||||
|
@ -320,7 +315,7 @@ namespace gr
|
|||
buf[6] = ECSS_PUS_VER << 4;
|
||||
}
|
||||
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 {
|
||||
return R_OBC_ERROR;
|
||||
|
@ -366,15 +361,15 @@ namespace gr
|
|||
buf[4] = cnv.cnv8[0];
|
||||
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;
|
||||
return R_OBC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static inline OBC_ret_state_t
|
||||
ecss_tm_crt_pkt (tc_tm_pkt *pkt, uint16_t app_id, uint8_t type, uint8_t ack,
|
||||
static inline OBC_ret_state_t
|
||||
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)
|
||||
{
|
||||
{
|
||||
|
||||
pkt->type = type;
|
||||
pkt->app_id = app_id;
|
||||
|
@ -384,9 +379,9 @@ namespace gr
|
|||
pkt->ser_subtype = ser_subtype;
|
||||
|
||||
return R_OBC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_TC_TM_H */
|
||||
|
|
|
@ -24,21 +24,18 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief Block that accepts TCP messages with rigctl commands. Depending
|
||||
* the command contents this block produces an appropriate PMT message
|
||||
* to control other blocks in the flowgraph
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API tcp_rigctl_msg_source : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API tcp_rigctl_msg_source : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<tcp_rigctl_msg_source> sptr;
|
||||
|
||||
|
||||
|
@ -55,11 +52,11 @@ namespace gr
|
|||
* @return shared pointer of the block
|
||||
*/
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_TCP_RIGCTL_MSG_SOURCE_H */
|
||||
|
|
|
@ -25,16 +25,15 @@
|
|||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief <+description of block+>
|
||||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API udp_msg_sink : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API udp_msg_sink : virtual public gr::block {
|
||||
public:
|
||||
typedef boost::shared_ptr<udp_msg_sink> sptr;
|
||||
|
||||
|
||||
|
@ -44,10 +43,10 @@ namespace gr {
|
|||
* @param port the destination UDP port
|
||||
* @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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_UDP_MSG_SINK_H */
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief UDP message/command accepter.
|
||||
*
|
||||
* This block received UDP messages from localhost or other network hosts
|
||||
|
@ -38,9 +36,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API udp_msg_source : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API udp_msg_source : virtual public gr::block {
|
||||
public:
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_UDP_MSG_SOURCE_H */
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \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
|
||||
* encoding. The resulting float samples can be passed from a FM modulation
|
||||
|
@ -38,9 +36,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API upsat_fsk_frame_encoder : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API upsat_fsk_frame_encoder : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<upsat_fsk_frame_encoder> sptr;
|
||||
|
||||
/*!
|
||||
|
@ -84,15 +81,15 @@ namespace gr
|
|||
*
|
||||
*/
|
||||
static sptr
|
||||
make (const std::vector<uint8_t>& preamble,
|
||||
const std::vector<uint8_t>& sync_word, bool append_crc,
|
||||
make(const std::vector<uint8_t> &preamble,
|
||||
const std::vector<uint8_t> &sync_word, bool append_crc,
|
||||
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_src_addr, uint8_t ax25_src_ssid,
|
||||
const std::string &ax25_dest_addr, uint8_t ax25_dest_ssid,
|
||||
const std::string &ax25_src_addr, uint8_t ax25_src_ssid,
|
||||
size_t settling_samples);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ENCODER_H */
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
#include <cmath>
|
||||
#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 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
static inline unsigned int
|
||||
bit_count (unsigned int x)
|
||||
bit_count(unsigned int x)
|
||||
{
|
||||
/*
|
||||
* Some more magic from
|
||||
|
@ -60,8 +58,8 @@ bit_count (unsigned int x)
|
|||
return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
static const uint8_t _bytes_reversed[256] =
|
||||
{ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
|
||||
static const uint8_t _bytes_reversed[256] = {
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
|
||||
0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68,
|
||||
0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84,
|
||||
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,
|
||||
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F,
|
||||
0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF,
|
||||
0x7F, 0xFF };
|
||||
0x7F, 0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverse the bits of the byte b.
|
||||
* @param b the byte to be mirrored.
|
||||
*/
|
||||
static inline uint8_t
|
||||
reverse_byte (uint8_t b)
|
||||
reverse_byte(uint8_t b)
|
||||
{
|
||||
return _bytes_reversed[b];
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
reverse_uint32_bytes (uint32_t i)
|
||||
reverse_uint32_bytes(uint32_t i)
|
||||
{
|
||||
return (_bytes_reversed[i & 0xff] << 24)
|
||||
| (_bytes_reversed[(i >> 8) & 0xff] << 16)
|
||||
|
@ -106,7 +105,7 @@ reverse_uint32_bytes (uint32_t i)
|
|||
}
|
||||
|
||||
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 & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
|
||||
|
@ -124,10 +123,10 @@ reverse_uint64_bytes (uint64_t x)
|
|||
* @return the CRC-32 result
|
||||
*/
|
||||
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] =
|
||||
{ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L,
|
||||
static const uint32_t crc32_lut[256] = {
|
||||
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L,
|
||||
0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L,
|
||||
0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L,
|
||||
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,
|
||||
0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L,
|
||||
0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL,
|
||||
0x2D02EF8DL };
|
||||
0x2D02EF8DL
|
||||
};
|
||||
|
||||
register uint32_t 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#include <satnogs/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief This block computes the waterfall of the incoming signal
|
||||
* and stores the result to a file.
|
||||
*
|
||||
|
@ -39,9 +37,8 @@ namespace gr
|
|||
* \ingroup satnogs
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API waterfall_sink : virtual public gr::sync_block
|
||||
{
|
||||
public:
|
||||
class SATNOGS_API waterfall_sink : virtual public gr::sync_block {
|
||||
public:
|
||||
typedef boost::shared_ptr<waterfall_sink> sptr;
|
||||
|
||||
/**
|
||||
|
@ -65,12 +62,12 @@ namespace gr
|
|||
* @return shared pointer to the object
|
||||
*/
|
||||
static sptr
|
||||
make (double samp_rate, double center_freq,
|
||||
make(double samp_rate, double center_freq,
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_WATERFALL_SINK_H */
|
||||
|
|
|
@ -25,44 +25,41 @@
|
|||
#include <gnuradio/digital/lfsr.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
* \brief Performs data whitening and de-whitening
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API whitening
|
||||
{
|
||||
class SATNOGS_API whitening {
|
||||
public:
|
||||
static int base_unique_id;
|
||||
|
||||
int
|
||||
unique_id ();
|
||||
unique_id();
|
||||
|
||||
typedef boost::shared_ptr<whitening> whitening_sptr;
|
||||
|
||||
static whitening_sptr
|
||||
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();
|
||||
|
||||
void
|
||||
reset ();
|
||||
reset();
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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);
|
||||
|
||||
private:
|
||||
|
|
|
@ -31,10 +31,8 @@ extern "C" {
|
|||
#include <fec.h>
|
||||
}
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/**
|
||||
* 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 uint8_t amsat_duv_decoder::amsat_fox_spacecraft_id[]
|
||||
{
|
||||
const uint8_t amsat_duv_decoder::amsat_fox_spacecraft_id[] {
|
||||
0x1 /* FOX-1A */,
|
||||
0x2 /* FOX-1B */,
|
||||
0x3 /* FOX-1C */,
|
||||
0x4 /* FOX-1D */,
|
||||
0x5 /* FOX-1E */
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return decoder::decoder_sptr (
|
||||
new amsat_duv_decoder (control_symbol, max_frame_len));
|
||||
return decoder::decoder_sptr(
|
||||
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 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) :
|
||||
decoder (1, max_frame_len),
|
||||
d_erasure_cnt (0),
|
||||
d_control_symbol_pos (0),
|
||||
d_control_symbol_neg (0),
|
||||
d_data_reg (0),
|
||||
d_wrong_bits (0),
|
||||
d_wrong_bits_neg (0),
|
||||
d_nwrong (0),
|
||||
d_nwrong_neg (0),
|
||||
d_word_cnt (0),
|
||||
d_bitstream_idx (0),
|
||||
d_state (SEARCH_SYNC)
|
||||
decoder(1, max_frame_len),
|
||||
d_erasure_cnt(0),
|
||||
d_control_symbol_pos(0),
|
||||
d_control_symbol_neg(0),
|
||||
d_data_reg(0),
|
||||
d_wrong_bits(0),
|
||||
d_wrong_bits_neg(0),
|
||||
d_nwrong(0),
|
||||
d_nwrong_neg(0),
|
||||
d_word_cnt(0),
|
||||
d_bitstream_idx(0),
|
||||
d_state(SEARCH_SYNC)
|
||||
{
|
||||
d_8b_words = new uint8_t[max_frame_len];
|
||||
d_erasures_indexes = new int[max_frame_len];
|
||||
|
||||
if (!set_access_code (control_symbol)) {
|
||||
throw std::out_of_range ("control_symbol is not 10 bits");
|
||||
if (!set_access_code(control_symbol)) {
|
||||
throw std::out_of_range("control_symbol is not 10 bits");
|
||||
}
|
||||
}
|
||||
|
||||
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 (len != 10) {
|
||||
|
@ -112,14 +109,14 @@ amsat_duv_decoder::set_access_code (const std::string &control_symbol)
|
|||
return true;
|
||||
}
|
||||
|
||||
amsat_duv_decoder::~amsat_duv_decoder ()
|
||||
amsat_duv_decoder::~amsat_duv_decoder()
|
||||
{
|
||||
delete[] d_8b_words;
|
||||
delete[] d_erasures_indexes;
|
||||
}
|
||||
|
||||
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;
|
||||
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)) {
|
||||
|
||||
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) {
|
||||
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)) {
|
||||
|
||||
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) {
|
||||
min_dist = curr_dist;
|
||||
|
@ -164,7 +161,7 @@ amsat_duv_decoder::process_10b (uint16_t word, size_t write_pos)
|
|||
}
|
||||
|
||||
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)
|
||||
| (((uint16_t) d_bitstream[idx + 1] & 0x1) << 8)
|
||||
|
@ -179,7 +176,7 @@ amsat_duv_decoder::pack_10b_word (size_t idx)
|
|||
}
|
||||
|
||||
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);
|
||||
i++) {
|
||||
|
@ -191,9 +188,9 @@ is_spacecraft_valid (uint8_t id)
|
|||
}
|
||||
|
||||
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;
|
||||
int ret;
|
||||
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 */
|
||||
for (int i = 0; i < len; i++) {
|
||||
d_bitstream.push_back (input[i]);
|
||||
d_bitstream.push_back(input[i]);
|
||||
}
|
||||
status.consumed = len;
|
||||
|
||||
while (1) {
|
||||
bool cont = false;
|
||||
if(d_bitstream.size() < 11) {
|
||||
if (d_bitstream.size() < 11) {
|
||||
return status;
|
||||
}
|
||||
switch (d_state)
|
||||
{
|
||||
switch (d_state) {
|
||||
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_wrong_bits = (d_data_reg ^ d_control_symbol_pos) & 0x3FF;
|
||||
d_wrong_bits_neg = (d_data_reg ^ d_control_symbol_neg) & 0x3FF;
|
||||
d_nwrong = gr::blocks::count_bits16 (d_wrong_bits);
|
||||
d_nwrong_neg = gr::blocks::count_bits16 (d_wrong_bits_neg);
|
||||
d_nwrong = gr::blocks::count_bits16(d_wrong_bits);
|
||||
d_nwrong_neg = gr::blocks::count_bits16(d_wrong_bits_neg);
|
||||
|
||||
/* we found the controls symbol */
|
||||
if ((d_nwrong == 0) || (d_nwrong_neg == 0)) {
|
||||
d_erasure_cnt = 0;
|
||||
d_word_cnt = 0;
|
||||
d_state = DECODING;
|
||||
if(i > 10) {
|
||||
if (i > 10) {
|
||||
d_bitstream_idx = 9;
|
||||
d_bitstream.erase (d_bitstream.begin (),
|
||||
d_bitstream.begin () + i + 1 - 9);
|
||||
d_bitstream.erase(d_bitstream.begin(),
|
||||
d_bitstream.begin() + i + 1 - 9);
|
||||
}
|
||||
else {
|
||||
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 */
|
||||
d_bitstream.clear ();
|
||||
d_bitstream.clear();
|
||||
return status;
|
||||
case DECODING:
|
||||
available = d_bitstream.size() - d_bitstream_idx;
|
||||
if(available < 10) {
|
||||
if (available < 10) {
|
||||
return status;
|
||||
}
|
||||
/*
|
||||
|
@ -250,34 +246,34 @@ amsat_duv_decoder::decode (const void *in, int len)
|
|||
* in chunks of 10 bits
|
||||
*/
|
||||
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! */
|
||||
process_10b (word, d_word_cnt);
|
||||
process_10b(word, 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_data_reg = 0;
|
||||
|
||||
if (d_erasure_cnt > 0) {
|
||||
ret = decode_rs_8 (d_8b_words, d_erasures_indexes, d_erasure_cnt,
|
||||
255 - max_frame_len ());
|
||||
ret = decode_rs_8(d_8b_words, d_erasures_indexes, d_erasure_cnt,
|
||||
255 - max_frame_len());
|
||||
}
|
||||
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) {
|
||||
uint8_t fox_id = d_8b_words[0] & 0x7;
|
||||
if (is_spacecraft_valid (fox_id)) {
|
||||
metadata::add_pdu (status.data, d_8b_words,
|
||||
if (is_spacecraft_valid(fox_id)) {
|
||||
metadata::add_pdu(status.data, d_8b_words,
|
||||
amsat_fox_duv_frame_size);
|
||||
metadata::add_symbol_erasures (status.data, d_erasure_cnt);
|
||||
metadata::add_corrected_bits (status.data, ret);
|
||||
metadata::add_time_iso8601 (status.data);
|
||||
metadata::add_symbol_erasures(status.data, d_erasure_cnt);
|
||||
metadata::add_corrected_bits(status.data, ret);
|
||||
metadata::add_time_iso8601(status.data);
|
||||
status.decode_success = true;
|
||||
d_bitstream.erase (d_bitstream.begin (),
|
||||
d_bitstream.begin () + (i + 1) * 10 + 1);
|
||||
d_bitstream.erase(d_bitstream.begin(),
|
||||
d_bitstream.begin() + (i + 1) * 10 + 1);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
@ -287,24 +283,24 @@ amsat_duv_decoder::decode (const void *in, int len)
|
|||
}
|
||||
}
|
||||
|
||||
if(cont) {
|
||||
if (cont) {
|
||||
continue;
|
||||
}
|
||||
return status;
|
||||
default:
|
||||
throw std::invalid_argument (
|
||||
throw std::invalid_argument(
|
||||
"amsat_duv_decoder: Invalid decoding state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
amsat_duv_decoder::reset ()
|
||||
amsat_duv_decoder::reset()
|
||||
{
|
||||
d_erasure_cnt = 0;
|
||||
d_word_cnt = 0;
|
||||
d_state = SEARCH_SYNC;
|
||||
d_bitstream.clear ();
|
||||
d_bitstream.clear();
|
||||
d_bitstream_idx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,44 +27,42 @@
|
|||
#include <satnogs/ax25.h>
|
||||
#include <satnogs/metadata.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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)
|
||||
{
|
||||
return decoder::decoder_sptr (
|
||||
new ax25_decoder (addr, ssid, promisc, descramble, crc_check,
|
||||
return decoder::decoder_sptr(
|
||||
new ax25_decoder(addr, ssid, promisc, descramble, crc_check,
|
||||
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) :
|
||||
decoder (sizeof(uint8_t), 2 * max_frame_len * 8),
|
||||
d_promisc (promisc),
|
||||
d_descramble (descramble),
|
||||
decoder(sizeof(uint8_t), 2 * max_frame_len * 8),
|
||||
d_promisc(promisc),
|
||||
d_descramble(descramble),
|
||||
d_crc_check(crc_check),
|
||||
d_max_frame_len (max_frame_len),
|
||||
d_state (NO_SYNC),
|
||||
d_shift_reg (0x0),
|
||||
d_dec_b (0x0),
|
||||
d_prev_bit_nrzi (0),
|
||||
d_received_bytes (0),
|
||||
d_decoded_bits (0),
|
||||
d_lfsr (0x21, 0x0, 16),
|
||||
d_frame_buffer (
|
||||
d_max_frame_len(max_frame_len),
|
||||
d_state(NO_SYNC),
|
||||
d_shift_reg(0x0),
|
||||
d_dec_b(0x0),
|
||||
d_prev_bit_nrzi(0),
|
||||
d_received_bytes(0),
|
||||
d_decoded_bits(0),
|
||||
d_lfsr(0x21, 0x0, 16),
|
||||
d_frame_buffer(
|
||||
new uint8_t[max_frame_len + AX25_MAX_ADDR_LEN + AX25_MAX_CTRL_LEN
|
||||
+ sizeof(uint16_t)]),
|
||||
d_start_idx (0),
|
||||
d_start_idx(0),
|
||||
d_frame_start(0)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
decoder_status_t status;
|
||||
|
@ -73,8 +71,8 @@ ax25_decoder::decode (const void *in, int len)
|
|||
/* Perform NRZI decoding */
|
||||
uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
d_prev_bit_nrzi = input[i];
|
||||
b = d_lfsr.next_bit_descramble (b);
|
||||
d_bitstream.push_back (b);
|
||||
b = d_lfsr.next_bit_descramble(b);
|
||||
d_bitstream.push_back(b);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -82,7 +80,7 @@ ax25_decoder::decode (const void *in, int len)
|
|||
/* Perform NRZI decoding */
|
||||
uint8_t b = (~((input[i] - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
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
|
||||
ax25_decoder::reset ()
|
||||
ax25_decoder::reset()
|
||||
{
|
||||
reset_state();
|
||||
}
|
||||
|
||||
bool
|
||||
ax25_decoder::_decode (decoder_status_t& status)
|
||||
ax25_decoder::_decode(decoder_status_t &status)
|
||||
{
|
||||
while (1) {
|
||||
bool cont = false;
|
||||
switch (d_state)
|
||||
{
|
||||
switch (d_state) {
|
||||
case NO_SYNC:
|
||||
for (size_t i = 0; i < d_bitstream.size (); i++) {
|
||||
decode_1b (d_bitstream[i]);
|
||||
for (size_t i = 0; i < d_bitstream.size(); i++) {
|
||||
decode_1b(d_bitstream[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
d_bitstream.erase (d_bitstream.begin (),
|
||||
d_bitstream.begin () + i + 1);
|
||||
enter_sync_state ();
|
||||
d_bitstream.erase(d_bitstream.begin(),
|
||||
d_bitstream.begin() + i + 1);
|
||||
enter_sync_state();
|
||||
d_frame_start = i;
|
||||
d_start_idx = 0;
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cont) {
|
||||
if (cont) {
|
||||
continue;
|
||||
}
|
||||
d_bitstream.clear ();
|
||||
d_bitstream.clear();
|
||||
return false;
|
||||
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
|
||||
* scrambler to settle
|
||||
*/
|
||||
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) {
|
||||
decode_1b (d_bitstream[i]);
|
||||
for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
|
||||
decode_1b(d_bitstream[i]);
|
||||
d_decoded_bits++;
|
||||
if (d_decoded_bits == 8) {
|
||||
/* Perhaps we are in frame! */
|
||||
if (d_shift_reg != AX25_SYNC_FLAG) {
|
||||
d_start_idx = i + 1;
|
||||
enter_decoding_state ();
|
||||
enter_decoding_state();
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
d_decoded_bits = 0;
|
||||
}
|
||||
}
|
||||
if(cont) {
|
||||
if (cont) {
|
||||
continue;
|
||||
}
|
||||
d_start_idx = d_bitstream.size ();
|
||||
d_start_idx = d_bitstream.size();
|
||||
return false;
|
||||
case DECODING:
|
||||
for (size_t i = d_start_idx; i < d_bitstream.size (); i++) {
|
||||
decode_1b (d_bitstream[i]);
|
||||
for (size_t i = d_start_idx; i < d_bitstream.size(); i++) {
|
||||
decode_1b(d_bitstream[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
LOG_DEBUG("Found frame end");
|
||||
if (enter_frame_end (status)) {
|
||||
d_bitstream.erase (d_bitstream.begin (),
|
||||
d_bitstream.begin () + i + 1);
|
||||
d_start_idx = d_bitstream.size ();
|
||||
if (enter_frame_end(status)) {
|
||||
d_bitstream.erase(d_bitstream.begin(),
|
||||
d_bitstream.begin() + i + 1);
|
||||
d_start_idx = d_bitstream.size();
|
||||
return true;
|
||||
}
|
||||
cont = true;
|
||||
|
@ -170,7 +167,7 @@ ax25_decoder::_decode (decoder_status_t& status)
|
|||
}
|
||||
else if ((d_shift_reg & 0xfe) == 0xfe) {
|
||||
LOG_DEBUG("Invalid shift register value %u", d_received_bytes);
|
||||
reset_state ();
|
||||
reset_state();
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
|
@ -183,34 +180,34 @@ ax25_decoder::_decode (decoder_status_t& status)
|
|||
/*Check if the frame limit was reached */
|
||||
if (d_received_bytes >= d_max_frame_len) {
|
||||
LOG_DEBUG("Wrong size");
|
||||
reset_state ();
|
||||
reset_state();
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(cont) {
|
||||
if (cont) {
|
||||
continue;
|
||||
}
|
||||
d_start_idx = d_bitstream.size ();
|
||||
d_start_idx = d_bitstream.size();
|
||||
return false;
|
||||
default:
|
||||
LOG_ERROR("Invalid decoding state");
|
||||
reset_state ();
|
||||
reset_state();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ax25_decoder::~ax25_decoder ()
|
||||
ax25_decoder::~ax25_decoder()
|
||||
{
|
||||
delete[] d_frame_buffer;
|
||||
}
|
||||
|
||||
void
|
||||
ax25_decoder::reset_state ()
|
||||
ax25_decoder::reset_state()
|
||||
{
|
||||
d_state = NO_SYNC;
|
||||
d_dec_b = 0x0;
|
||||
|
@ -220,7 +217,7 @@ ax25_decoder::reset_state ()
|
|||
}
|
||||
|
||||
void
|
||||
ax25_decoder::enter_sync_state ()
|
||||
ax25_decoder::enter_sync_state()
|
||||
{
|
||||
d_state = IN_SYNC;
|
||||
d_dec_b = 0x0;
|
||||
|
@ -230,7 +227,7 @@ ax25_decoder::enter_sync_state ()
|
|||
}
|
||||
|
||||
void
|
||||
ax25_decoder::enter_decoding_state ()
|
||||
ax25_decoder::enter_decoding_state()
|
||||
{
|
||||
uint8_t tmp;
|
||||
d_state = DECODING;
|
||||
|
@ -254,14 +251,14 @@ ax25_decoder::enter_decoding_state ()
|
|||
}
|
||||
|
||||
bool
|
||||
ax25_decoder::enter_frame_end (decoder_status_t& status)
|
||||
ax25_decoder::enter_frame_end(decoder_status_t &status)
|
||||
{
|
||||
uint16_t fcs;
|
||||
uint16_t recv_fcs = 0x0;
|
||||
|
||||
/* First check if the size of the frame is valid */
|
||||
if (d_received_bytes < AX25_MIN_ADDR_LEN + sizeof(uint16_t)) {
|
||||
reset_state ();
|
||||
reset_state();
|
||||
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
|
||||
* 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_time_iso8601(status.data);
|
||||
metadata::add_crc_valid(status.data, true);
|
||||
metadata::add_sample_start(status.data, d_frame_start);
|
||||
status.decode_success = true;
|
||||
reset_state ();
|
||||
reset_state();
|
||||
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_time_iso8601(status.data);
|
||||
metadata::add_crc_valid(status.data, false);
|
||||
status.decode_success = true;
|
||||
LOG_DEBUG("Wrong crc");
|
||||
reset_state ();
|
||||
reset_state();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -292,7 +289,7 @@ ax25_decoder::enter_frame_end (decoder_status_t& status)
|
|||
|
||||
|
||||
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 */
|
||||
|
@ -301,14 +298,14 @@ ax25_decoder::decode_1b (uint8_t in)
|
|||
}
|
||||
|
||||
bool
|
||||
ax25_decoder::frame_check ()
|
||||
ax25_decoder::frame_check()
|
||||
{
|
||||
uint16_t fcs;
|
||||
uint16_t recv_fcs = 0x0;
|
||||
uint8_t orig_byte;
|
||||
|
||||
/* 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)
|
||||
| d_frame_buffer[d_received_bytes - 2];
|
||||
if (fcs == recv_fcs) {
|
||||
|
|
|
@ -28,70 +28,68 @@
|
|||
#include <satnogs/log.h>
|
||||
#include <satnogs/ax25.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
ax25_encoder_mb::sptr
|
||||
ax25_encoder_mb::make (const std::string& dest_addr, uint8_t dest_ssid,
|
||||
const std::string& src_addr, uint8_t src_ssid,
|
||||
ax25_encoder_mb::sptr
|
||||
ax25_encoder_mb::make(const std::string &dest_addr, uint8_t dest_ssid,
|
||||
const std::string &src_addr, uint8_t src_ssid,
|
||||
size_t preamble_len, size_t postamble_len,
|
||||
bool scramble)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new ax25_encoder_mb_impl (dest_addr, dest_ssid, src_addr, src_ssid,
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new ax25_encoder_mb_impl(dest_addr, dest_ssid, src_addr, src_ssid,
|
||||
preamble_len, postamble_len, scramble));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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,
|
||||
const std::string& src_addr,
|
||||
const std::string &src_addr,
|
||||
uint8_t src_ssid,
|
||||
size_t preamble_len,
|
||||
size_t postabmle_len,
|
||||
bool scramble) :
|
||||
gr::sync_block ("ax25_encoder_mb", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (1, 1, sizeof(uint8_t))),
|
||||
d_preamble_len (preamble_len),
|
||||
d_postamble_len (postabmle_len),
|
||||
d_scramble (scramble),
|
||||
d_remaining (0),
|
||||
d_produced (0),
|
||||
d_prev_bit (0x0),
|
||||
d_encoded_frame (
|
||||
gr::sync_block("ax25_encoder_mb", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 1, sizeof(uint8_t))),
|
||||
d_preamble_len(preamble_len),
|
||||
d_postamble_len(postabmle_len),
|
||||
d_scramble(scramble),
|
||||
d_remaining(0),
|
||||
d_produced(0),
|
||||
d_prev_bit(0x0),
|
||||
d_encoded_frame(
|
||||
new uint8_t[(preamble_len + postabmle_len
|
||||
+ (AX25_MAX_FRAME_LEN * 2)) * 8]),
|
||||
d_tmp_buf (
|
||||
d_tmp_buf(
|
||||
new uint8_t[preamble_len + postabmle_len
|
||||
+ (AX25_MAX_FRAME_LEN * 2)]),
|
||||
d_addr_field (new uint8_t[AX25_MAX_ADDR_LEN]),
|
||||
d_lfsr (0x21, 0x0, 16)
|
||||
{
|
||||
d_addr_field(new uint8_t[AX25_MAX_ADDR_LEN]),
|
||||
d_lfsr(0x21, 0x0, 16)
|
||||
{
|
||||
/* Input is a blob message containing the info field data */
|
||||
message_port_register_in (pmt::mp ("info"));
|
||||
d_addr_len = ax25_create_addr_field (d_addr_field, dest_addr, dest_ssid,
|
||||
message_port_register_in(pmt::mp("info"));
|
||||
d_addr_len = ax25_create_addr_field(d_addr_field, dest_addr, dest_ssid,
|
||||
src_addr, src_ssid);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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_tmp_buf;
|
||||
delete [] d_addr_field;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ax25_encoder_mb_impl::work (int noutput_items,
|
||||
int
|
||||
ax25_encoder_mb_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
const uint8_t *info;
|
||||
size_t info_len;
|
||||
size_t max_avail;
|
||||
|
@ -106,20 +104,20 @@ namespace gr
|
|||
if (d_remaining == 0) {
|
||||
d_produced = 0;
|
||||
d_prev_bit = 0x0;
|
||||
d_lfsr.reset ();
|
||||
d_lfsr.reset();
|
||||
|
||||
/* Block waiting from a new message from users */
|
||||
msg = delete_head_blocking (pmt::mp ("info"));
|
||||
info = (const uint8_t *) pmt::blob_data (msg);
|
||||
info_len = pmt::blob_length (msg);
|
||||
msg = delete_head_blocking(pmt::mp("info"));
|
||||
info = (const uint8_t *) pmt::blob_data(msg);
|
||||
info_len = pmt::blob_length(msg);
|
||||
|
||||
/* 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_preamble_len, d_postamble_len);
|
||||
|
||||
/* 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);
|
||||
if (status != AX25_ENC_OK) {
|
||||
LOG_ERROR("AX.25 encoding failed");
|
||||
|
@ -130,12 +128,12 @@ namespace gr
|
|||
/*Perform scrambling if the user asked for it */
|
||||
if (d_scramble) {
|
||||
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 */
|
||||
d_remaining += 16;
|
||||
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 */
|
||||
|
@ -145,9 +143,9 @@ namespace gr
|
|||
|
||||
/* If this is the first part of the frame add the start of burst tag*/
|
||||
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 */
|
||||
for (i = 0; i < max_avail; i++) {
|
||||
|
@ -158,30 +156,30 @@ namespace gr
|
|||
d_remaining -= max_avail;
|
||||
d_produced += max_avail;
|
||||
if (d_remaining == 0) {
|
||||
add_eob (nitems_written (0) + max_avail);
|
||||
add_eob(nitems_written(0) + max_avail);
|
||||
}
|
||||
return (int) max_avail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ax25_encoder_mb_impl::add_sob (uint64_t item)
|
||||
{
|
||||
static const pmt::pmt_t sob_key = pmt::string_to_symbol ("tx_sob");
|
||||
void
|
||||
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 value = pmt::PMT_T;
|
||||
static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ());
|
||||
add_item_tag (0, item, sob_key, value, srcid);
|
||||
}
|
||||
static const pmt::pmt_t srcid = pmt::string_to_symbol(alias());
|
||||
add_item_tag(0, item, sob_key, value, srcid);
|
||||
}
|
||||
|
||||
void
|
||||
ax25_encoder_mb_impl::add_eob (uint64_t item)
|
||||
{
|
||||
static const pmt::pmt_t eob_key = pmt::string_to_symbol ("tx_eob");
|
||||
void
|
||||
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 value = pmt::PMT_T;
|
||||
static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ());
|
||||
add_item_tag (0, item, eob_key, value, srcid);
|
||||
}
|
||||
static const pmt::pmt_t srcid = pmt::string_to_symbol(alias());
|
||||
add_item_tag(0, item, eob_key, value, srcid);
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -25,14 +25,11 @@
|
|||
#include <satnogs/ax25_encoder_mb.h>
|
||||
#include <gnuradio/digital/lfsr.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class ax25_encoder_mb_impl : public ax25_encoder_mb
|
||||
{
|
||||
private:
|
||||
class ax25_encoder_mb_impl : public ax25_encoder_mb {
|
||||
private:
|
||||
const size_t d_preamble_len;
|
||||
const size_t d_postamble_len;
|
||||
const bool d_scramble;
|
||||
|
@ -46,24 +43,24 @@ namespace gr
|
|||
digital::lfsr d_lfsr;
|
||||
|
||||
void
|
||||
add_sob (uint64_t item);
|
||||
add_sob(uint64_t item);
|
||||
void
|
||||
add_eob (uint64_t item);
|
||||
add_eob(uint64_t item);
|
||||
|
||||
public:
|
||||
ax25_encoder_mb_impl (const std::string& dest_addr, uint8_t dest_ssid,
|
||||
const std::string& src_addr, uint8_t src_ssid,
|
||||
public:
|
||||
ax25_encoder_mb_impl(const std::string &dest_addr, uint8_t dest_ssid,
|
||||
const std::string &src_addr, uint8_t src_ssid,
|
||||
size_t preamble_len, size_t postamble_len,
|
||||
bool scramble);
|
||||
~ax25_encoder_mb_impl ();
|
||||
~ax25_encoder_mb_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H */
|
||||
|
|
|
@ -27,34 +27,32 @@
|
|||
#include <volk/volk.h>
|
||||
#include <satnogs/log.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
coarse_doppler_correction_cc::sptr
|
||||
coarse_doppler_correction_cc::make (double target_freq,
|
||||
coarse_doppler_correction_cc::sptr
|
||||
coarse_doppler_correction_cc::make(double target_freq,
|
||||
double sampling_rate)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new coarse_doppler_correction_cc_impl (target_freq, sampling_rate));
|
||||
}
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new coarse_doppler_correction_cc_impl(target_freq, sampling_rate));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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) :
|
||||
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))),
|
||||
d_target_freq (target_freq),
|
||||
d_samp_rate (sampling_rate),
|
||||
d_buf_items (std::min ((size_t)8192UL, (size_t) (d_samp_rate / 4))),
|
||||
d_freq_diff (0),
|
||||
d_nco ()
|
||||
{
|
||||
message_port_register_in (pmt::mp ("freq"));
|
||||
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))),
|
||||
d_target_freq(target_freq),
|
||||
d_samp_rate(sampling_rate),
|
||||
d_buf_items(std::min((size_t)8192UL, (size_t)(d_samp_rate / 4))),
|
||||
d_freq_diff(0),
|
||||
d_nco()
|
||||
{
|
||||
message_port_register_in(pmt::mp("freq"));
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
|
@ -65,65 +63,65 @@ namespace gr
|
|||
* This is taken into consideration due to the fact that the work()
|
||||
* and the input message handler are NOT reentrant.
|
||||
*/
|
||||
set_max_noutput_items (d_samp_rate / 4.0);
|
||||
set_alignment (8);
|
||||
set_max_noutput_items(d_samp_rate / 4.0);
|
||||
set_alignment(8);
|
||||
|
||||
set_msg_handler (
|
||||
pmt::mp ("freq"),
|
||||
boost::bind (&coarse_doppler_correction_cc_impl::new_freq, this, _1));
|
||||
set_msg_handler(
|
||||
pmt::mp("freq"),
|
||||
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 */
|
||||
d_nco_buff = (gr_complex *) volk_malloc (
|
||||
d_nco_buff = (gr_complex *) volk_malloc(
|
||||
(d_samp_rate / 4) * sizeof(gr_complex), 32);
|
||||
if (!d_nco_buff) {
|
||||
throw std::runtime_error ("Could not allocate NCO memory");
|
||||
}
|
||||
throw std::runtime_error("Could not allocate NCO memory");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
coarse_doppler_correction_cc_impl::new_freq (pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock (d_mutex);
|
||||
void
|
||||
coarse_doppler_correction_cc_impl::new_freq(pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(d_mutex);
|
||||
double new_freq;
|
||||
new_freq = pmt::to_double (msg);
|
||||
new_freq = pmt::to_double(msg);
|
||||
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.
|
||||
*/
|
||||
coarse_doppler_correction_cc_impl::~coarse_doppler_correction_cc_impl ()
|
||||
{
|
||||
volk_free (d_nco_buff);
|
||||
}
|
||||
coarse_doppler_correction_cc_impl::~coarse_doppler_correction_cc_impl()
|
||||
{
|
||||
volk_free(d_nco_buff);
|
||||
}
|
||||
|
||||
int
|
||||
coarse_doppler_correction_cc_impl::work (
|
||||
int
|
||||
coarse_doppler_correction_cc_impl::work(
|
||||
int noutput_items, gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
|
||||
/* Perform the correction */
|
||||
d_nco.sincos (d_nco_buff, noutput_items, 1.0);
|
||||
volk_32fc_x2_multiply_32fc (out, in, d_nco_buff, noutput_items);
|
||||
d_nco.sincos(d_nco_buff, noutput_items, 1.0);
|
||||
volk_32fc_x2_multiply_32fc(out, in, d_nco_buff, noutput_items);
|
||||
|
||||
// Tell runtime system how many output items we produced.
|
||||
return noutput_items;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
coarse_doppler_correction_cc_impl::set_target_freq (double freq)
|
||||
{
|
||||
boost::mutex::scoped_lock lock (d_mutex);
|
||||
void
|
||||
coarse_doppler_correction_cc_impl::set_target_freq(double freq)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(d_mutex);
|
||||
d_target_freq = freq;
|
||||
d_freq_diff = 0.0;
|
||||
d_nco.set_freq (0);
|
||||
}
|
||||
d_nco.set_freq(0);
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -24,14 +24,11 @@
|
|||
#include <satnogs/coarse_doppler_correction_cc.h>
|
||||
#include <gnuradio/fxpt_nco.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class coarse_doppler_correction_cc_impl : public coarse_doppler_correction_cc
|
||||
{
|
||||
private:
|
||||
class coarse_doppler_correction_cc_impl : public coarse_doppler_correction_cc {
|
||||
private:
|
||||
double d_target_freq;
|
||||
const double d_samp_rate;
|
||||
const size_t d_buf_items;
|
||||
|
@ -42,23 +39,23 @@ namespace gr
|
|||
boost::mutex d_mutex;
|
||||
|
||||
void
|
||||
new_freq (pmt::pmt_t msg);
|
||||
new_freq(pmt::pmt_t msg);
|
||||
|
||||
public:
|
||||
coarse_doppler_correction_cc_impl (double target_freq,
|
||||
public:
|
||||
coarse_doppler_correction_cc_impl(double target_freq,
|
||||
double sampling_rate);
|
||||
~coarse_doppler_correction_cc_impl ();
|
||||
~coarse_doppler_correction_cc_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
|
||||
void
|
||||
set_target_freq (double freq);
|
||||
};
|
||||
set_target_freq(double freq);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_COARSE_DOPPLER_CORRECTION_CC_IMPL_H */
|
||||
|
|
|
@ -25,28 +25,26 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include <satnogs/convolutional_deinterleaver.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
convolutional_deinterleaver::convolutional_deinterleaver (size_t branches,
|
||||
convolutional_deinterleaver::convolutional_deinterleaver(size_t branches,
|
||||
size_t M) :
|
||||
d_nbranches (branches),
|
||||
d_M (M),
|
||||
d_nbranches(branches),
|
||||
d_M(M),
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
convolutional_deinterleaver::~convolutional_deinterleaver ()
|
||||
convolutional_deinterleaver::~convolutional_deinterleaver()
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t
|
||||
convolutional_deinterleaver::decode_bit (uint8_t b)
|
||||
convolutional_deinterleaver::decode_bit(uint8_t b)
|
||||
{
|
||||
uint8_t ret;
|
||||
d_branches[d_idx].push_back(b);
|
||||
|
@ -57,7 +55,7 @@ convolutional_deinterleaver::decode_bit (uint8_t b)
|
|||
}
|
||||
|
||||
uint8_t
|
||||
convolutional_deinterleaver::decode_byte (uint8_t b)
|
||||
convolutional_deinterleaver::decode_byte(uint8_t b)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
ret = decode_bit(b >> 7) << 7;
|
||||
|
@ -72,10 +70,10 @@ convolutional_deinterleaver::decode_byte (uint8_t b)
|
|||
}
|
||||
|
||||
void
|
||||
convolutional_deinterleaver::reset ()
|
||||
convolutional_deinterleaver::reset()
|
||||
{
|
||||
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_idx = 0;
|
||||
|
|
29
lib/crc.cc
29
lib/crc.cc
|
@ -25,14 +25,12 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include <satnogs/crc.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
|
||||
const uint16_t crc::crc16_ccitt_table_reverse[256] =
|
||||
{ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48,
|
||||
const uint16_t crc::crc16_ccitt_table_reverse[256] = {
|
||||
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48,
|
||||
0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 0x1081, 0x0108,
|
||||
0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, 0x9CC9, 0x8D40, 0xBFDB,
|
||||
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,
|
||||
0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 0xF78F, 0xE606, 0xD49D,
|
||||
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] =
|
||||
{ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
|
||||
const uint16_t crc::crc16_ccitt_table[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
|
||||
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
|
||||
0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
|
||||
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,
|
||||
0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
|
||||
0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
|
||||
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 };
|
||||
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
|
||||
uint16_t
|
||||
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
|
||||
crc::crc16_ccitt (const uint8_t *data, size_t len)
|
||||
crc::crc16_ccitt(const uint8_t *data, size_t len)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
while (len-- != 0) {
|
||||
|
@ -124,7 +124,7 @@ crc::crc16_ax25(const uint8_t *data, size_t len)
|
|||
}
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
|
@ -143,8 +143,9 @@ uint16_t
|
|||
crc::crc16_ibm(const uint8_t *data, size_t len)
|
||||
{
|
||||
uint16_t crc = 0xFFFF;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
crc = update_crc16_ibm (data[i], crc);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
crc = update_crc16_ibm(data[i], crc);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,32 +28,32 @@
|
|||
#include "cw_encoder_impl.h"
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
cw_encoder::sptr
|
||||
cw_encoder::make(double samp_rate, double cw_freq, size_t wpm)
|
||||
{
|
||||
cw_encoder::sptr
|
||||
cw_encoder::make(double samp_rate, double cw_freq, size_t wpm)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new cw_encoder_impl(samp_rate, cw_freq, wpm));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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)
|
||||
: gr::sync_block("cw_encoder",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_samp_rate (samp_rate),
|
||||
d_cw_freq (cw_freq),
|
||||
d_wpm (wpm),
|
||||
d_dot_samples ((1.2 / wpm) / (1.0 / samp_rate)),
|
||||
d_window_size (0),
|
||||
d_windows_remaining (0),
|
||||
d_cw_symbol (MORSE_L_SPACE),
|
||||
d_nco ()
|
||||
{
|
||||
d_samp_rate(samp_rate),
|
||||
d_cw_freq(cw_freq),
|
||||
d_wpm(wpm),
|
||||
d_dot_samples((1.2 / wpm) / (1.0 / samp_rate)),
|
||||
d_window_size(0),
|
||||
d_windows_remaining(0),
|
||||
d_cw_symbol(MORSE_L_SPACE),
|
||||
d_nco()
|
||||
{
|
||||
message_port_register_in(pmt::mp("symbol"));
|
||||
|
||||
/*
|
||||
|
@ -62,46 +62,46 @@ namespace gr {
|
|||
*/
|
||||
size_t i = 10;
|
||||
d_window_size = d_dot_samples / i;
|
||||
while(d_window_size > 200) {
|
||||
while (d_window_size > 200) {
|
||||
i += 10;
|
||||
d_window_size = d_dot_samples / i;
|
||||
}
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
cw_encoder_impl::~cw_encoder_impl()
|
||||
{
|
||||
}
|
||||
cw_encoder_impl::~cw_encoder_impl()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
cw_encoder_impl::work(int noutput_items,
|
||||
int
|
||||
cw_encoder_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
size_t available;
|
||||
size_t i;
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
|
||||
if(noutput_items < 0) {
|
||||
if (noutput_items < 0) {
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
if(d_windows_remaining == 0) {
|
||||
if (d_windows_remaining == 0) {
|
||||
pmt::pmt_t symbol = delete_head_blocking(pmt::mp("symbol"));
|
||||
d_cw_symbol = (morse_symbol_t) pmt::to_long(symbol);
|
||||
/* Reset NCO so the amplitude starts from zero */
|
||||
d_nco.set_freq ((2 * M_PI * d_cw_freq) / d_samp_rate);
|
||||
switch(d_cw_symbol) {
|
||||
d_nco.set_freq((2 * M_PI * d_cw_freq) / d_samp_rate);
|
||||
switch (d_cw_symbol) {
|
||||
case MORSE_DOT:
|
||||
case MORSE_INTRA_SPACE:
|
||||
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++) {
|
||||
switch(d_cw_symbol){
|
||||
for (i = 0; i < (size_t)noutput_items / d_window_size; i++) {
|
||||
switch (d_cw_symbol) {
|
||||
case MORSE_S_SPACE:
|
||||
case MORSE_L_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));
|
||||
break;
|
||||
case MORSE_DOT:
|
||||
|
@ -133,13 +133,13 @@ namespace gr {
|
|||
break;
|
||||
}
|
||||
d_windows_remaining--;
|
||||
if(d_windows_remaining == 0) {
|
||||
if (d_windows_remaining == 0) {
|
||||
return (i + 1) * d_window_size;
|
||||
}
|
||||
}
|
||||
return i * d_window_size;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -28,14 +28,11 @@
|
|||
#include <satnogs/morse.h>
|
||||
#include <gnuradio/fxpt_nco.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class cw_encoder_impl : public cw_encoder
|
||||
{
|
||||
private:
|
||||
class cw_encoder_impl : public cw_encoder {
|
||||
private:
|
||||
const double d_samp_rate;
|
||||
const double d_cw_freq;
|
||||
const size_t d_wpm;
|
||||
|
@ -50,17 +47,17 @@ namespace gr
|
|||
std::string
|
||||
get_cw_symbol(char c);
|
||||
|
||||
public:
|
||||
cw_encoder_impl (double samp_rate, double cw_freq, size_t wpm);
|
||||
~cw_encoder_impl ();
|
||||
public:
|
||||
cw_encoder_impl(double samp_rate, double cw_freq, size_t wpm);
|
||||
~cw_encoder_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_CW_ENCODER_IMPL_H */
|
||||
|
|
|
@ -37,65 +37,63 @@
|
|||
#endif
|
||||
#include <volk/volk.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new cw_to_symbol_impl (sampling_rate, threshold, conf_level, wpm,
|
||||
return gnuradio::get_initial_sptr(
|
||||
new cw_to_symbol_impl(sampling_rate, threshold, conf_level, wpm,
|
||||
hysteresis));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
size_t hysteresis) :
|
||||
gr::sync_block ("cw_to_symbol",
|
||||
gr::io_signature::make (1, 1, sizeof(float)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_sampling_rate (sampling_rate),
|
||||
d_act_thrshld (threshold),
|
||||
d_confidence_level (conf_level),
|
||||
d_dot_samples ((1.2 / wpm) * sampling_rate),
|
||||
d_window_size (0),
|
||||
d_window_cnt (0),
|
||||
d_idle_cnt (0),
|
||||
d_dot_windows_num (0),
|
||||
d_dec_state (NO_SYNC),
|
||||
d_prev_space_symbol (true)
|
||||
gr::sync_block("cw_to_symbol",
|
||||
gr::io_signature::make(1, 1, sizeof(float)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_sampling_rate(sampling_rate),
|
||||
d_act_thrshld(threshold),
|
||||
d_confidence_level(conf_level),
|
||||
d_dot_samples((1.2 / wpm) * sampling_rate),
|
||||
d_window_size(0),
|
||||
d_window_cnt(0),
|
||||
d_idle_cnt(0),
|
||||
d_dot_windows_num(0),
|
||||
d_dec_state(NO_SYNC),
|
||||
d_prev_space_symbol(true)
|
||||
{
|
||||
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) {
|
||||
throw std::invalid_argument (
|
||||
throw std::invalid_argument(
|
||||
"Decoder can not handle such high WPM setting");
|
||||
}
|
||||
|
||||
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]");
|
||||
}
|
||||
|
||||
if(hysteresis > d_dot_samples / 4) {
|
||||
throw std::invalid_argument ("Too large hysteresis value");
|
||||
if (hysteresis > d_dot_samples / 4) {
|
||||
throw std::invalid_argument("Too large hysteresis value");
|
||||
}
|
||||
|
||||
message_port_register_in (pmt::mp ("act_threshold"));
|
||||
message_port_register_out (pmt::mp ("out"));
|
||||
message_port_register_in(pmt::mp("act_threshold"));
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
/* Register the message handlers */
|
||||
set_msg_handler (
|
||||
pmt::mp ("act_threshold"),
|
||||
boost::bind (&cw_to_symbol_impl::set_act_threshold_msg_handler, this,
|
||||
set_msg_handler(
|
||||
pmt::mp("act_threshold"),
|
||||
boost::bind(&cw_to_symbol_impl::set_act_threshold_msg_handler, this,
|
||||
_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_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));
|
||||
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),
|
||||
volk_get_alignment ());
|
||||
d_tmp = (float *) volk_malloc (d_window_size * sizeof(float),
|
||||
volk_get_alignment ());
|
||||
d_out = (int32_t *) volk_malloc (d_window_size * sizeof(int32_t),
|
||||
volk_get_alignment ());
|
||||
d_const_val = (float *) volk_malloc(d_window_size * sizeof(float),
|
||||
volk_get_alignment());
|
||||
d_tmp = (float *) volk_malloc(d_window_size * sizeof(float),
|
||||
volk_get_alignment());
|
||||
d_out = (int32_t *) volk_malloc(d_window_size * sizeof(int32_t),
|
||||
volk_get_alignment());
|
||||
|
||||
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++) {
|
||||
d_const_val[i] = threshold;
|
||||
}
|
||||
set_history (d_window_size);
|
||||
set_history(d_window_size);
|
||||
}
|
||||
|
||||
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) {
|
||||
d_prev_space_symbol = true;
|
||||
|
@ -161,11 +159,11 @@ cw_to_symbol_impl::send_symbol_msg (morse_symbol_t s)
|
|||
else {
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
@ -173,15 +171,15 @@ cw_to_symbol_impl::check_conf_level (size_t cnt, size_t target)
|
|||
/*
|
||||
* 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_tmp);
|
||||
volk_free (d_out);
|
||||
volk_free(d_const_val);
|
||||
volk_free(d_tmp);
|
||||
volk_free(d_out);
|
||||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_idle ()
|
||||
cw_to_symbol_impl::set_idle()
|
||||
{
|
||||
d_dec_state = NO_SYNC;
|
||||
d_window_cnt = 0;
|
||||
|
@ -189,42 +187,42 @@ cw_to_symbol_impl::set_idle ()
|
|||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_short_on ()
|
||||
cw_to_symbol_impl::set_short_on()
|
||||
{
|
||||
d_dec_state = SEARCH_DOT;
|
||||
d_window_cnt = 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_long_on ()
|
||||
cw_to_symbol_impl::set_long_on()
|
||||
{
|
||||
d_dec_state = SEARCH_DASH;
|
||||
}
|
||||
|
||||
inline void
|
||||
cw_to_symbol_impl::set_search_space ()
|
||||
cw_to_symbol_impl::set_search_space()
|
||||
{
|
||||
d_dec_state = SEARCH_SPACE;
|
||||
d_window_cnt = 1;
|
||||
}
|
||||
|
||||
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)) {
|
||||
set_act_threshold (pmt::to_double (pmt::cdr (msg)));
|
||||
if (pmt::is_pair(msg)) {
|
||||
set_act_threshold(pmt::to_double(pmt::cdr(msg)));
|
||||
}
|
||||
}
|
||||
|
||||
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_void_star &output_items)
|
||||
{
|
||||
bool triggered;
|
||||
size_t i;
|
||||
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) {
|
||||
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
|
||||
* 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) {
|
||||
LOG_DEBUG("Triggered!");
|
||||
set_short_on ();
|
||||
set_short_on();
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
d_idle_cnt += noutput_items / d_window_size;
|
||||
if(d_idle_cnt > 10 * d_long_pause_windows_num) {
|
||||
send_symbol_msg (MORSE_END_MSG_SPACE);
|
||||
if (d_idle_cnt > 10 * d_long_pause_windows_num) {
|
||||
send_symbol_msg(MORSE_END_MSG_SPACE);
|
||||
d_idle_cnt = 0;
|
||||
}
|
||||
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 */
|
||||
for (i = 0; i < (size_t) noutput_items / d_window_size; i++) {
|
||||
triggered = is_triggered (in + i * d_window_size, d_window_size);
|
||||
switch (d_dec_state)
|
||||
{
|
||||
triggered = is_triggered(in + i * d_window_size, d_window_size);
|
||||
switch (d_dec_state) {
|
||||
case SEARCH_DOT:
|
||||
if (triggered) {
|
||||
d_window_cnt++;
|
||||
if (d_window_cnt > d_dot_windows_num) {
|
||||
set_long_on ();
|
||||
set_long_on();
|
||||
LOG_DEBUG("Going to search for long sequence");
|
||||
}
|
||||
}
|
||||
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");
|
||||
send_symbol_msg (MORSE_DOT);
|
||||
send_symbol_msg(MORSE_DOT);
|
||||
}
|
||||
LOG_DEBUG("Going to search for space: win cnt %lu", d_window_cnt);
|
||||
set_search_space ();
|
||||
set_search_space();
|
||||
}
|
||||
break;
|
||||
case SEARCH_DASH:
|
||||
|
@ -279,37 +276,37 @@ cw_to_symbol_impl::work (int noutput_items,
|
|||
d_window_cnt++;
|
||||
}
|
||||
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");
|
||||
send_symbol_msg (MORSE_DASH);
|
||||
send_symbol_msg(MORSE_DASH);
|
||||
}
|
||||
else {
|
||||
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");
|
||||
}
|
||||
break;
|
||||
case SEARCH_SPACE:
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
}
|
||||
else {
|
||||
d_window_cnt++;
|
||||
if (d_window_cnt > d_long_pause_windows_num) {
|
||||
LOG_DEBUG("LONG SPACE");
|
||||
send_symbol_msg (MORSE_L_SPACE);
|
||||
set_idle ();
|
||||
send_symbol_msg(MORSE_L_SPACE);
|
||||
set_idle();
|
||||
LOG_DEBUG("Going to idle");
|
||||
return (i + 1) * d_window_size;
|
||||
}
|
||||
|
@ -327,7 +324,7 @@ cw_to_symbol_impl::work (int noutput_items,
|
|||
* @param thrhld the new threshold.
|
||||
*/
|
||||
void
|
||||
cw_to_symbol_impl::set_act_threshold (float thrhld)
|
||||
cw_to_symbol_impl::set_act_threshold(float 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
|
||||
*/
|
||||
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_binary_slicer_32i (d_out, d_tmp, len);
|
||||
volk_32f_x2_subtract_32f(d_tmp, in, d_const_val, len);
|
||||
volk_32f_binary_slicer_32i(d_out, d_tmp, len);
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
hadd (const int32_t* in, size_t len)
|
||||
hadd(const int32_t *in, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int32_t cnt = 0;
|
||||
|
@ -359,12 +356,12 @@ hadd (const int32_t* in, size_t len)
|
|||
}
|
||||
|
||||
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;
|
||||
clamp_input (d_out, in, len);
|
||||
cnt = hadd (d_out, len);
|
||||
return (cnt >= (int32_t) (d_window_size * d_confidence_level)) ? true : false;
|
||||
clamp_input(d_out, in, len);
|
||||
cnt = hadd(d_out, len);
|
||||
return (cnt >= (int32_t)(d_window_size * d_confidence_level)) ? true : false;
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
|
|
|
@ -25,20 +25,16 @@
|
|||
#include <satnogs/morse.h>
|
||||
#include <satnogs/cw_to_symbol.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
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
|
||||
} cw_dec_state_t;
|
||||
|
||||
private:
|
||||
private:
|
||||
const double d_sampling_rate;
|
||||
float d_act_thrshld;
|
||||
const float d_confidence_level;
|
||||
|
@ -57,47 +53,47 @@ namespace gr
|
|||
int32_t *d_out;
|
||||
|
||||
inline void
|
||||
set_idle ();
|
||||
set_idle();
|
||||
|
||||
inline void
|
||||
set_short_on ();
|
||||
set_short_on();
|
||||
|
||||
inline void
|
||||
set_long_on ();
|
||||
set_long_on();
|
||||
|
||||
inline void
|
||||
set_search_space ();
|
||||
set_search_space();
|
||||
|
||||
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
|
||||
is_triggered (const float *in, size_t len);
|
||||
is_triggered(const float *in, size_t len);
|
||||
|
||||
inline void
|
||||
send_symbol_msg (morse_symbol_t s);
|
||||
send_symbol_msg(morse_symbol_t s);
|
||||
|
||||
inline bool
|
||||
check_conf_level(size_t cnt, size_t target);
|
||||
|
||||
void
|
||||
set_act_threshold_msg_handler (pmt::pmt_t msg);
|
||||
set_act_threshold_msg_handler(pmt::pmt_t msg);
|
||||
|
||||
public:
|
||||
cw_to_symbol_impl (double sampling_rate, float threshold,
|
||||
public:
|
||||
cw_to_symbol_impl(double sampling_rate, float threshold,
|
||||
float conf_level, size_t wpm, size_t hysteresis);
|
||||
~cw_to_symbol_impl ();
|
||||
~cw_to_symbol_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
|
||||
void
|
||||
set_act_threshold (float thrhld);
|
||||
};
|
||||
set_act_threshold(float thrhld);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_CW_TO_SYMBOL_IMPL_H */
|
||||
|
|
|
@ -26,66 +26,64 @@
|
|||
#include "debug_msg_source_impl.h"
|
||||
#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
|
||||
*/
|
||||
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) :
|
||||
gr::block ("debug_msg_source", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_buf_len (msg.length ()),
|
||||
d_delay (delay),
|
||||
d_repeat (repeat),
|
||||
d_running (true)
|
||||
{
|
||||
d_buf = new uint8_t[msg.length ()];
|
||||
memcpy (d_buf, msg.c_str (), msg.length ());
|
||||
message_port_register_out (pmt::mp ("msg"));
|
||||
gr::block("debug_msg_source", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_buf_len(msg.length()),
|
||||
d_delay(delay),
|
||||
d_repeat(repeat),
|
||||
d_running(true)
|
||||
{
|
||||
d_buf = new uint8_t[msg.length()];
|
||||
memcpy(d_buf, msg.c_str(), msg.length());
|
||||
message_port_register_out(pmt::mp("msg"));
|
||||
boost::shared_ptr<boost::thread> (
|
||||
new boost::thread (
|
||||
boost::bind (&debug_msg_source_impl::msg_sender, this)));
|
||||
}
|
||||
new boost::thread(
|
||||
boost::bind(&debug_msg_source_impl::msg_sender, this)));
|
||||
}
|
||||
|
||||
void
|
||||
debug_msg_source_impl::msg_sender ()
|
||||
{
|
||||
pmt::pmt_t msg = pmt::make_blob (d_buf, d_buf_len);
|
||||
void
|
||||
debug_msg_source_impl::msg_sender()
|
||||
{
|
||||
pmt::pmt_t msg = pmt::make_blob(d_buf, d_buf_len);
|
||||
if (d_repeat) {
|
||||
while (d_running) {
|
||||
boost::this_thread::sleep_for (
|
||||
boost::chrono::milliseconds ((size_t) (d_delay * 1e3)));
|
||||
message_port_pub (pmt::mp ("msg"), msg);
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
|
||||
message_port_pub(pmt::mp("msg"), msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
boost::this_thread::sleep_for (
|
||||
boost::chrono::milliseconds ((size_t) (d_delay * 1e3)));
|
||||
message_port_pub (pmt::mp ("msg"), msg);
|
||||
}
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
|
||||
message_port_pub(pmt::mp("msg"), msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
debug_msg_source_impl::~debug_msg_source_impl ()
|
||||
{
|
||||
debug_msg_source_impl::~debug_msg_source_impl()
|
||||
{
|
||||
d_running = false;
|
||||
d_thread->join ();
|
||||
d_thread->join();
|
||||
delete[] d_buf;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -24,14 +24,11 @@
|
|||
#include <satnogs/debug_msg_source.h>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class debug_msg_source_impl : public debug_msg_source
|
||||
{
|
||||
private:
|
||||
class debug_msg_source_impl : public debug_msg_source {
|
||||
private:
|
||||
const size_t d_buf_len;
|
||||
const double d_delay;
|
||||
const bool d_repeat;
|
||||
|
@ -42,13 +39,13 @@ namespace gr
|
|||
void
|
||||
msg_sender();
|
||||
|
||||
public:
|
||||
debug_msg_source_impl (const std::string &msg, double delay, bool repeat);
|
||||
~debug_msg_source_impl ();
|
||||
public:
|
||||
debug_msg_source_impl(const std::string &msg, double delay, bool repeat);
|
||||
~debug_msg_source_impl();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_IMPL_H */
|
||||
|
|
|
@ -25,67 +25,65 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include "debug_msg_source_raw_impl.h"
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
debug_msg_source_raw::sptr
|
||||
debug_msg_source_raw::make (const std::vector<uint8_t> &msg, double delay,
|
||||
debug_msg_source_raw::sptr
|
||||
debug_msg_source_raw::make(const std::vector<uint8_t> &msg, double delay,
|
||||
bool repeat)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new debug_msg_source_raw_impl (msg, delay, repeat));
|
||||
}
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new debug_msg_source_raw_impl(msg, delay, repeat));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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) :
|
||||
gr::block ("debug_msg_source_raw", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_buf_len (msg.size ()),
|
||||
d_delay (delay),
|
||||
d_repeat (repeat),
|
||||
d_running (true)
|
||||
{
|
||||
gr::block("debug_msg_source_raw", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_buf_len(msg.size()),
|
||||
d_delay(delay),
|
||||
d_repeat(repeat),
|
||||
d_running(true)
|
||||
{
|
||||
d_buf = new uint8_t[msg.size()];
|
||||
memcpy (d_buf, msg.data(), msg.size());
|
||||
message_port_register_out (pmt::mp ("msg"));
|
||||
memcpy(d_buf, msg.data(), msg.size());
|
||||
message_port_register_out(pmt::mp("msg"));
|
||||
boost::shared_ptr<boost::thread> (
|
||||
new boost::thread (
|
||||
boost::bind (&debug_msg_source_raw_impl::msg_sender, this)));
|
||||
}
|
||||
new boost::thread(
|
||||
boost::bind(&debug_msg_source_raw_impl::msg_sender, this)));
|
||||
}
|
||||
|
||||
void
|
||||
debug_msg_source_raw_impl::msg_sender ()
|
||||
{
|
||||
pmt::pmt_t msg = pmt::make_blob (d_buf, d_buf_len);
|
||||
void
|
||||
debug_msg_source_raw_impl::msg_sender()
|
||||
{
|
||||
pmt::pmt_t msg = pmt::make_blob(d_buf, d_buf_len);
|
||||
if (d_repeat) {
|
||||
while (d_running) {
|
||||
boost::this_thread::sleep_for (
|
||||
boost::chrono::milliseconds ((size_t) (d_delay * 1e3)));
|
||||
message_port_pub (pmt::mp ("msg"), msg);
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
|
||||
message_port_pub(pmt::mp("msg"), msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
boost::this_thread::sleep_for (
|
||||
boost::chrono::milliseconds ((size_t) (d_delay * 1e3)));
|
||||
message_port_pub (pmt::mp ("msg"), msg);
|
||||
}
|
||||
boost::this_thread::sleep_for(
|
||||
boost::chrono::milliseconds((size_t)(d_delay * 1e3)));
|
||||
message_port_pub(pmt::mp("msg"), msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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_thread->join ();
|
||||
d_thread->join();
|
||||
delete[] d_buf;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -23,14 +23,11 @@
|
|||
|
||||
#include <satnogs/debug_msg_source_raw.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class debug_msg_source_raw_impl : public debug_msg_source_raw
|
||||
{
|
||||
private:
|
||||
class debug_msg_source_raw_impl : public debug_msg_source_raw {
|
||||
private:
|
||||
const size_t d_buf_len;
|
||||
const double d_delay;
|
||||
const bool d_repeat;
|
||||
|
@ -39,16 +36,16 @@ namespace gr
|
|||
uint8_t *d_buf;
|
||||
|
||||
void
|
||||
msg_sender ();
|
||||
msg_sender();
|
||||
|
||||
|
||||
public:
|
||||
debug_msg_source_raw_impl (const std::vector<uint8_t> &msg, double delay,
|
||||
public:
|
||||
debug_msg_source_raw_impl(const std::vector<uint8_t> &msg, double delay,
|
||||
bool repeat);
|
||||
~debug_msg_source_raw_impl ();
|
||||
};
|
||||
~debug_msg_source_raw_impl();
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DEBUG_MSG_SOURCE_RAW_IMPL_H */
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include <satnogs/decoder.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
int decoder::base_unique_id = 1;
|
||||
|
||||
|
@ -37,7 +35,7 @@ int decoder::base_unique_id = 1;
|
|||
* @return the unique id of the decoder object
|
||||
*/
|
||||
int
|
||||
decoder::unique_id ()
|
||||
decoder::unique_id()
|
||||
{
|
||||
return d_id;
|
||||
}
|
||||
|
@ -68,7 +66,7 @@ decoder::max_frame_len() const
|
|||
}
|
||||
|
||||
int
|
||||
decoder::sizeof_input_item () const
|
||||
decoder::sizeof_input_item() const
|
||||
{
|
||||
return d_sizeof_in;
|
||||
}
|
||||
|
|
|
@ -27,44 +27,42 @@
|
|||
#include <satnogs/log.h>
|
||||
#include <volk/volk.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
doppler_correction_cc::sptr
|
||||
doppler_correction_cc::make (double target_freq, double sampling_rate,
|
||||
doppler_correction_cc::sptr
|
||||
doppler_correction_cc::make(double target_freq, double sampling_rate,
|
||||
size_t corrections_per_sec)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new doppler_correction_cc_impl (target_freq, sampling_rate,
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new doppler_correction_cc_impl(target_freq, sampling_rate,
|
||||
corrections_per_sec));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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) :
|
||||
gr::sync_block ("doppler_correction_cc",
|
||||
gr::io_signature::make (1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make (1, 1, sizeof(gr_complex))),
|
||||
d_target_freq (target_freq),
|
||||
d_samp_rate (sampling_rate),
|
||||
d_update_period (sampling_rate / (double) corrections_per_sec),
|
||||
d_est_thrhld (7),
|
||||
d_corrections_per_sec (corrections_per_sec),
|
||||
d_nco (),
|
||||
gr::sync_block("doppler_correction_cc",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex))),
|
||||
d_target_freq(target_freq),
|
||||
d_samp_rate(sampling_rate),
|
||||
d_update_period(sampling_rate / (double) corrections_per_sec),
|
||||
d_est_thrhld(7),
|
||||
d_corrections_per_sec(corrections_per_sec),
|
||||
d_nco(),
|
||||
/* A 3-rd order polynomial curve fitting is more than enough */
|
||||
d_doppler_fit_engine (3),
|
||||
d_freq_diff (0.0),
|
||||
d_have_est (false),
|
||||
d_freq_est_num (0),
|
||||
d_corrections (0),
|
||||
d_corrected_samples (0)
|
||||
{
|
||||
message_port_register_in (pmt::mp ("freq"));
|
||||
message_port_register_in (pmt::mp ("reset"));
|
||||
d_doppler_fit_engine(3),
|
||||
d_freq_diff(0.0),
|
||||
d_have_est(false),
|
||||
d_freq_est_num(0),
|
||||
d_corrections(0),
|
||||
d_corrected_samples(0)
|
||||
{
|
||||
message_port_register_in(pmt::mp("freq"));
|
||||
message_port_register_in(pmt::mp("reset"));
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
|
@ -75,85 +73,85 @@ namespace gr
|
|||
* This is taken into consideration due to the fact that the work()
|
||||
* and the input message handler are NOT reentrant.
|
||||
*/
|
||||
set_max_noutput_items (d_samp_rate / 2.0);
|
||||
set_alignment (8);
|
||||
set_max_noutput_items(d_samp_rate / 2.0);
|
||||
set_alignment(8);
|
||||
|
||||
set_msg_handler (
|
||||
pmt::mp ("freq"),
|
||||
boost::bind (&doppler_correction_cc_impl::new_freq, this, _1));
|
||||
set_msg_handler (
|
||||
pmt::mp ("reset"),
|
||||
boost::bind (&doppler_correction_cc_impl::reset, this, _1));
|
||||
set_msg_handler(
|
||||
pmt::mp("freq"),
|
||||
boost::bind(&doppler_correction_cc_impl::new_freq, this, _1));
|
||||
set_msg_handler(
|
||||
pmt::mp("reset"),
|
||||
boost::bind(&doppler_correction_cc_impl::reset, this, _1));
|
||||
|
||||
/* Allocate the buffer that will hold the predicted frequency differences */
|
||||
d_predicted_freqs = new double[d_corrections_per_sec];
|
||||
|
||||
/* 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);
|
||||
if (!d_nco_buff) {
|
||||
throw std::runtime_error ("Could not allocate NCO memory");
|
||||
}
|
||||
throw std::runtime_error("Could not allocate NCO memory");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
doppler_correction_cc_impl::new_freq (pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock (d_mutex);
|
||||
void
|
||||
doppler_correction_cc_impl::new_freq(pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(d_mutex);
|
||||
double new_freq;
|
||||
new_freq = pmt::to_double (msg);
|
||||
new_freq = pmt::to_double(msg);
|
||||
d_freq_diff = new_freq - d_target_freq;
|
||||
if (!d_have_est) {
|
||||
d_freq_est_num++;
|
||||
d_doppler_freqs.push_back (
|
||||
freq_drift (nitems_written (0), d_freq_diff));
|
||||
d_doppler_freqs.push_back(
|
||||
freq_drift(nitems_written(0), d_freq_diff));
|
||||
if (d_freq_est_num > d_est_thrhld - 1) {
|
||||
d_doppler_fit_engine.fit (d_doppler_freqs);
|
||||
d_doppler_fit_engine.predict_freqs (d_predicted_freqs,
|
||||
d_doppler_fit_engine.fit(d_doppler_freqs);
|
||||
d_doppler_fit_engine.predict_freqs(d_predicted_freqs,
|
||||
d_corrections_per_sec,
|
||||
d_update_period);
|
||||
d_have_est = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
d_doppler_freqs.pop_front ();
|
||||
d_doppler_freqs.push_back (
|
||||
freq_drift (nitems_written (0), d_freq_diff));
|
||||
d_doppler_freqs.pop_front();
|
||||
d_doppler_freqs.push_back(
|
||||
freq_drift(nitems_written(0), d_freq_diff));
|
||||
|
||||
/* 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 */
|
||||
d_doppler_fit_engine.predict_freqs (d_predicted_freqs,
|
||||
d_doppler_fit_engine.predict_freqs(d_predicted_freqs,
|
||||
d_corrections_per_sec,
|
||||
d_update_period);
|
||||
d_corrections = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
doppler_correction_cc_impl::reset (pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock (d_mutex);
|
||||
d_doppler_freqs.clear ();
|
||||
void
|
||||
doppler_correction_cc_impl::reset(pmt::pmt_t msg)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(d_mutex);
|
||||
d_doppler_freqs.clear();
|
||||
d_freq_est_num = 0;
|
||||
d_corrections = 0;
|
||||
d_have_est = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
doppler_correction_cc_impl::~doppler_correction_cc_impl ()
|
||||
{
|
||||
doppler_correction_cc_impl::~doppler_correction_cc_impl()
|
||||
{
|
||||
delete[] d_predicted_freqs;
|
||||
volk_free (d_nco_buff);
|
||||
}
|
||||
volk_free(d_nco_buff);
|
||||
}
|
||||
|
||||
int
|
||||
doppler_correction_cc_impl::work (int noutput_items,
|
||||
int
|
||||
doppler_correction_cc_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
gr_complex *out = (gr_complex *) output_items[0];
|
||||
int produced = 0;
|
||||
|
@ -171,9 +169,9 @@ namespace gr
|
|||
* compute and store the NCO buffer with the corresponding frequency
|
||||
*/
|
||||
if (d_corrected_samples == 0) {
|
||||
d_nco.set_freq (
|
||||
d_nco.set_freq(
|
||||
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++;
|
||||
|
||||
/*
|
||||
|
@ -181,17 +179,17 @@ namespace gr
|
|||
* should continue using the predicted frequencies
|
||||
*/
|
||||
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_update_period);
|
||||
d_corrections = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cnt = std::min (d_update_period - d_corrected_samples,
|
||||
(size_t) (noutput_items - produced));
|
||||
cnt = std::min(d_update_period - d_corrected_samples,
|
||||
(size_t)(noutput_items - produced));
|
||||
/* 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);
|
||||
|
||||
/* Make the proper advances */
|
||||
|
@ -204,12 +202,12 @@ namespace gr
|
|||
}
|
||||
}
|
||||
else {
|
||||
memcpy (out, in, noutput_items * sizeof(gr_complex));
|
||||
memcpy(out, in, noutput_items * sizeof(gr_complex));
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -27,14 +27,11 @@
|
|||
#include <gnuradio/fxpt_nco.h>
|
||||
#include <deque>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class doppler_correction_cc_impl : public doppler_correction_cc
|
||||
{
|
||||
private:
|
||||
class doppler_correction_cc_impl : public doppler_correction_cc {
|
||||
private:
|
||||
const double d_target_freq;
|
||||
const double d_samp_rate;
|
||||
const size_t d_update_period;
|
||||
|
@ -54,23 +51,23 @@ namespace gr
|
|||
boost::mutex d_mutex;
|
||||
|
||||
void
|
||||
new_freq (pmt::pmt_t msg);
|
||||
new_freq(pmt::pmt_t msg);
|
||||
|
||||
void
|
||||
reset (pmt::pmt_t msg);
|
||||
reset(pmt::pmt_t msg);
|
||||
|
||||
public:
|
||||
doppler_correction_cc_impl (double target_freq, double sampling_rate,
|
||||
public:
|
||||
doppler_correction_cc_impl(double target_freq, double sampling_rate,
|
||||
size_t corrections_per_sec);
|
||||
~doppler_correction_cc_impl ();
|
||||
~doppler_correction_cc_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_DOPPLER_CORRECTION_CC_IMPL_H */
|
||||
|
|
|
@ -27,22 +27,20 @@
|
|||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/numeric/ublas/lu.hpp>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates a polynomial fitting routine.
|
||||
* @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_last_x(0.0)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* This method calculates the coefficients of the polynomial that will
|
||||
* be used by the predict_freqs() method to produce simulated frequency
|
||||
* differences
|
||||
|
@ -50,9 +48,9 @@ namespace gr
|
|||
* corresponding timings that these frequencies diffrences occured. Time is
|
||||
* measured in samples since the start of the flowgraph execution.
|
||||
*/
|
||||
void
|
||||
doppler_fit::fit (std::deque<freq_drift> drifts)
|
||||
{
|
||||
void
|
||||
doppler_fit::fit(std::deque<freq_drift> drifts)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t s;
|
||||
|
@ -60,34 +58,34 @@ namespace gr
|
|||
double val;
|
||||
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);
|
||||
|
||||
for(i = 0; i < s; i++){
|
||||
for (i = 0; i < s; i++) {
|
||||
y_matrix(i, 0) = drifts[i].get_freq_drift();
|
||||
}
|
||||
|
||||
for(i = 0; i < s; i++){
|
||||
for (i = 0; i < s; i++) {
|
||||
val = 1.0;
|
||||
for(j = 0; j < d_degree + 1; j++) {
|
||||
for (j = 0; j < d_degree + 1; j++) {
|
||||
x_matrix(i, j) = val;
|
||||
val *= drifts[i].get_x();
|
||||
}
|
||||
}
|
||||
|
||||
/* Transpose the matrix with the x values */
|
||||
boost::numeric::ublas::matrix<double> tx_matrix (
|
||||
boost::numeric::ublas::trans (x_matrix));
|
||||
boost::numeric::ublas::matrix<double> tx_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::matrix<double> txy_matrix (
|
||||
boost::numeric::ublas::matrix<double> txy_matrix(
|
||||
boost::numeric::ublas::prec_prod(tx_matrix, y_matrix));
|
||||
|
||||
boost::numeric::ublas::permutation_matrix<int> perm(txx_matrix.size1());
|
||||
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);
|
||||
|
||||
|
@ -99,9 +97,9 @@ namespace gr
|
|||
d_coeff = std::vector<double> (txy_matrix.data().begin(),
|
||||
txy_matrix.data().end());
|
||||
d_last_x = drifts[s - 1].get_x();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates a number of frequency differences predictions using polynomial
|
||||
* curve fitting.
|
||||
* @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
|
||||
* correction.
|
||||
*/
|
||||
void
|
||||
doppler_fit::predict_freqs (double *freqs, size_t ncorrections,
|
||||
void
|
||||
doppler_fit::predict_freqs(double *freqs, size_t ncorrections,
|
||||
size_t samples_per_correction)
|
||||
{
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
double predicted_freq_diff;
|
||||
double x;
|
||||
double xT;
|
||||
boost::mutex::scoped_lock lock(d_mutex);
|
||||
for(i = 0; i < ncorrections; i++){
|
||||
for (i = 0; i < ncorrections; i++) {
|
||||
predicted_freq_diff = 0.0;
|
||||
xT = 1.0;
|
||||
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;
|
||||
xT *= x;
|
||||
}
|
||||
|
@ -138,8 +136,8 @@ namespace gr
|
|||
* fitness of the polynomial. For this reason we alter the last x
|
||||
*/
|
||||
d_last_x = d_last_x + (ncorrections + 1) * samples_per_correction;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -31,16 +31,14 @@
|
|||
#include <satnogs/utils.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
frame_acquisition::sptr
|
||||
frame_acquisition::make (variant_t variant,
|
||||
const std::vector<uint8_t>& preamble,
|
||||
frame_acquisition::make(variant_t variant,
|
||||
const std::vector<uint8_t> &preamble,
|
||||
size_t preamble_threshold,
|
||||
const std::vector<uint8_t>& sync,
|
||||
const std::vector<uint8_t> &sync,
|
||||
size_t sync_threshold,
|
||||
size_t frame_size_field_len,
|
||||
size_t frame_len,
|
||||
|
@ -48,8 +46,8 @@ frame_acquisition::make (variant_t variant,
|
|||
whitening::whitening_sptr descrambler,
|
||||
size_t max_frame_len)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new frame_acquisition_impl (variant,
|
||||
return gnuradio::get_initial_sptr(
|
||||
new frame_acquisition_impl(variant,
|
||||
preamble,
|
||||
preamble_threshold,
|
||||
sync,
|
||||
|
@ -61,19 +59,19 @@ frame_acquisition::make (variant_t variant,
|
|||
max_frame_len));
|
||||
}
|
||||
|
||||
frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
|
||||
const std::vector<uint8_t>& preamble,
|
||||
frame_acquisition_impl::frame_acquisition_impl(variant_t variant,
|
||||
const std::vector<uint8_t> &preamble,
|
||||
size_t preamble_threshold,
|
||||
const std::vector<uint8_t>& sync,
|
||||
const std::vector<uint8_t> &sync,
|
||||
size_t sync_threshold,
|
||||
size_t frame_size_field_len,
|
||||
size_t frame_len,
|
||||
checksum_t crc,
|
||||
whitening::whitening_sptr descrambler,
|
||||
size_t max_frame_len) :
|
||||
gr::sync_block ("frame_acquisition",
|
||||
gr::io_signature::make (1, 1, sizeof(uint8_t)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
gr::sync_block("frame_acquisition",
|
||||
gr::io_signature::make(1, 1, sizeof(uint8_t)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_variant(variant),
|
||||
d_preamble(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)
|
||||
{
|
||||
set_output_multiple(8);
|
||||
for(uint8_t b : preamble) {
|
||||
for (uint8_t b : preamble) {
|
||||
d_preamble <<= (b >> 7);
|
||||
d_preamble <<= ((b >> 6) & 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 & 0x1);
|
||||
}
|
||||
for(uint8_t b : sync) {
|
||||
for (uint8_t b : sync) {
|
||||
d_sync <<= (b >> 7);
|
||||
d_sync <<= ((b >> 6) & 0x1);
|
||||
d_sync <<= ((b >> 5) & 0x1);
|
||||
|
@ -116,44 +114,44 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
|
|||
|
||||
/* Parameters checking */
|
||||
if (max_frame_len == 0) {
|
||||
throw std::invalid_argument (
|
||||
throw std::invalid_argument(
|
||||
"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");
|
||||
}
|
||||
|
||||
if(d_preamble_len < 8) {
|
||||
if (d_preamble_len < 8) {
|
||||
throw std::invalid_argument("Preamble should be at least 8 bits");
|
||||
}
|
||||
|
||||
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."
|
||||
"Consider lowering the threshold");
|
||||
}
|
||||
|
||||
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. "
|
||||
"Consider lowering the threshold");
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Set the CRC length */
|
||||
switch(d_crc) {
|
||||
switch (d_crc) {
|
||||
case CRC16_CCITT:
|
||||
d_crc_len = 2;
|
||||
break;
|
||||
|
@ -180,7 +178,7 @@ frame_acquisition_impl::frame_acquisition_impl (variant_t variant,
|
|||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
frame_acquisition_impl::~frame_acquisition_impl ()
|
||||
frame_acquisition_impl::~frame_acquisition_impl()
|
||||
{
|
||||
delete [] d_pdu;
|
||||
}
|
||||
|
@ -188,14 +186,13 @@ frame_acquisition_impl::~frame_acquisition_impl ()
|
|||
|
||||
|
||||
int
|
||||
frame_acquisition_impl::work (int noutput_items,
|
||||
frame_acquisition_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
const uint8_t *in = (const uint8_t *) input_items[0];
|
||||
|
||||
switch(d_state)
|
||||
{
|
||||
switch (d_state) {
|
||||
case SEARCHING:
|
||||
return searching_preamble(in, noutput_items);
|
||||
case SEARCHING_SYNC:
|
||||
|
@ -212,31 +209,31 @@ frame_acquisition_impl::work (int noutput_items,
|
|||
}
|
||||
|
||||
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];
|
||||
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");
|
||||
d_state = SEARCHING_SYNC;
|
||||
d_cnt = 0;
|
||||
return i+1;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
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++) {
|
||||
d_sync_shift_reg <<= in[i];
|
||||
shift_reg tmp = d_sync_shift_reg ^ d_sync;
|
||||
d_cnt++;
|
||||
if (tmp.count () <= d_sync_thrsh) {
|
||||
if (tmp.count() <= d_sync_thrsh) {
|
||||
LOG_DEBUG("Found SYNC");
|
||||
switch(d_variant) {
|
||||
switch (d_variant) {
|
||||
case GENERIC_CONSTANT_FRAME_LEN:
|
||||
d_state = DECODING_PAYLOAD;
|
||||
break;
|
||||
|
@ -253,7 +250,7 @@ frame_acquisition_impl::searching_sync (const uint8_t* in, int len)
|
|||
}
|
||||
|
||||
/* 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();
|
||||
return i + 1;
|
||||
}
|
||||
|
@ -262,10 +259,10 @@ frame_acquisition_impl::searching_sync (const uint8_t* in, int len)
|
|||
}
|
||||
|
||||
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);
|
||||
for(int i = 0; i < s; i++) {
|
||||
for (int i = 0; i < s; i++) {
|
||||
uint8_t b = 0x0;
|
||||
b |= in[i * 8] << 7;
|
||||
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 |= b;
|
||||
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 */
|
||||
if(d_whitening) {
|
||||
if (d_whitening) {
|
||||
uint32_t descrambled = 0x0;
|
||||
d_whitening->descramble((uint8_t *)&descrambled,
|
||||
(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);
|
||||
|
||||
/* 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_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 */
|
||||
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;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
reset();
|
||||
return (i + 1) * 8;
|
||||
}
|
||||
|
@ -316,12 +313,12 @@ frame_acquisition_impl::dec_generic_frame_len (const uint8_t* in, int len)
|
|||
}
|
||||
|
||||
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 */
|
||||
const int s = std::min(len / 8, 3);
|
||||
d_frame_len = 0;
|
||||
for(int i = 0; i < s; i++) {
|
||||
for (int i = 0; i < s; i++) {
|
||||
uint8_t b = 0x0;
|
||||
b |= in[i * 8] << 7;
|
||||
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 */
|
||||
if (d_cnt == 3) {
|
||||
LOG_WARN("Len coded %u", d_frame_len);
|
||||
if(d_whitening) {
|
||||
if (d_whitening) {
|
||||
uint32_t descrambled = 0x0;
|
||||
d_whitening->descramble((uint8_t *) &descrambled,
|
||||
(const uint8_t *)&d_frame_len, 3, false);
|
||||
d_frame_len = descrambled;
|
||||
}
|
||||
d_frame_len = ((d_frame_len & 0xFFF) << 12) | (d_frame_len >> 12);
|
||||
golay24 g = golay24 ();
|
||||
golay24 g = golay24();
|
||||
uint32_t tmp = 0;
|
||||
if (g.decode24 (&tmp, d_frame_len)) {
|
||||
if (g.decode24(&tmp, d_frame_len)) {
|
||||
d_frame_len = tmp >> 12;
|
||||
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;
|
||||
|
||||
/* 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();
|
||||
return (i + 1) * 8;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
d_state = DECODING_PAYLOAD;
|
||||
}
|
||||
}
|
||||
else {
|
||||
reset ();
|
||||
reset();
|
||||
return (i + 1) * 8;
|
||||
}
|
||||
d_cnt = 0;
|
||||
|
@ -375,10 +372,10 @@ frame_acquisition_impl::dec_golay24_frame_len (const uint8_t* in, int len)
|
|||
}
|
||||
|
||||
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;
|
||||
for(int i = 0; i < s; i++) {
|
||||
for (int i = 0; i < s; i++) {
|
||||
uint8_t b = 0x0;
|
||||
b = in[i * 8] << 7;
|
||||
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 + 7];
|
||||
d_pdu[d_cnt++] = b;
|
||||
if(d_cnt == d_frame_len) {
|
||||
if(d_whitening) {
|
||||
if (d_cnt == d_frame_len) {
|
||||
if (d_whitening) {
|
||||
d_whitening->descramble(d_pdu + d_frame_size_field_len,
|
||||
d_pdu + d_frame_size_field_len,
|
||||
d_frame_len - d_frame_size_field_len, false);
|
||||
}
|
||||
|
||||
if (check_crc ()) {
|
||||
message_port_pub (
|
||||
pmt::mp ("out"),
|
||||
pmt::make_blob (d_pdu + d_frame_size_field_len,
|
||||
if (check_crc()) {
|
||||
message_port_pub(
|
||||
pmt::mp("out"),
|
||||
pmt::make_blob(d_pdu + d_frame_size_field_len,
|
||||
d_frame_len - d_crc_len - d_frame_size_field_len));
|
||||
}
|
||||
reset();
|
||||
return (i+1) * 8;
|
||||
return (i + 1) * 8;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
frame_acquisition_impl::reset ()
|
||||
frame_acquisition_impl::reset()
|
||||
{
|
||||
if(d_whitening) {
|
||||
if (d_whitening) {
|
||||
d_whitening->reset();
|
||||
}
|
||||
d_cnt = 0;
|
||||
|
@ -422,13 +419,13 @@ frame_acquisition_impl::reset ()
|
|||
}
|
||||
|
||||
bool
|
||||
frame_acquisition_impl::check_crc ()
|
||||
frame_acquisition_impl::check_crc()
|
||||
{
|
||||
uint16_t crc16_c;
|
||||
uint16_t crc16_received;
|
||||
uint32_t crc32_c;
|
||||
uint32_t crc32_received;
|
||||
switch(d_crc){
|
||||
switch (d_crc) {
|
||||
case CRC_NONE:
|
||||
return true;
|
||||
case CRC16_CCITT:
|
||||
|
@ -436,7 +433,7 @@ frame_acquisition_impl::check_crc ()
|
|||
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
|
||||
crc16_received = ntohs(crc16_received);
|
||||
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 false;
|
||||
|
@ -445,7 +442,7 @@ frame_acquisition_impl::check_crc ()
|
|||
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
|
||||
crc16_received = ntohs(crc16_received);
|
||||
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 false;
|
||||
|
@ -454,7 +451,7 @@ frame_acquisition_impl::check_crc ()
|
|||
memcpy(&crc16_received, d_pdu + d_frame_len - 2, 2);
|
||||
crc16_received = ntohs(crc16_received);
|
||||
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 false;
|
||||
|
@ -462,7 +459,7 @@ frame_acquisition_impl::check_crc ()
|
|||
crc32_c = crc32(d_pdu, d_frame_len - 4);
|
||||
memcpy(&crc32_received, d_pdu + d_frame_len - 4, 4);
|
||||
crc32_received = ntohl(crc32_received);
|
||||
if(crc32_c == crc32_received) {
|
||||
if (crc32_c == crc32_received) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -24,19 +24,16 @@
|
|||
#include <satnogs/shift_reg.h>
|
||||
#include <satnogs/frame_acquisition.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class frame_acquisition_impl : public frame_acquisition
|
||||
{
|
||||
class frame_acquisition_impl : public frame_acquisition {
|
||||
|
||||
public:
|
||||
frame_acquisition_impl (variant_t variant,
|
||||
const std::vector<uint8_t>& preamble,
|
||||
frame_acquisition_impl(variant_t variant,
|
||||
const std::vector<uint8_t> &preamble,
|
||||
size_t preamble_threshold,
|
||||
const std::vector<uint8_t>& sync,
|
||||
const std::vector<uint8_t> &sync,
|
||||
size_t sync_threshold,
|
||||
size_t frame_size_field_len,
|
||||
size_t frame_len,
|
||||
|
@ -44,19 +41,18 @@ public:
|
|||
whitening::whitening_sptr descrambler,
|
||||
size_t max_frame_len);
|
||||
|
||||
~frame_acquisition_impl ();
|
||||
~frame_acquisition_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Decoding FSM
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
SEARCHING, //!< when searching for the start of the preamble
|
||||
SEARCHING_SYNC,
|
||||
DECODING_GENERIC_FRAME_LEN,
|
||||
|
|
|
@ -25,63 +25,61 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include "frame_decoder_impl.h"
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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) :
|
||||
gr::sync_block ("frame_decoder",
|
||||
gr::io_signature::make (1, 1, input_size),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_decoder (decoder_object)
|
||||
gr::sync_block("frame_decoder",
|
||||
gr::io_signature::make(1, 1, input_size),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_decoder(decoder_object)
|
||||
{
|
||||
if (input_size != decoder_object->sizeof_input_item ()) {
|
||||
throw std::invalid_argument (
|
||||
if (input_size != decoder_object->sizeof_input_item()) {
|
||||
throw std::invalid_argument(
|
||||
"frame_decoder: Size mismatch between the block input and the decoder");
|
||||
}
|
||||
|
||||
message_port_register_in (pmt::mp ("reset"));
|
||||
message_port_register_out (pmt::mp ("out"));
|
||||
message_port_register_in(pmt::mp("reset"));
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
set_msg_handler (pmt::mp ("reset"),
|
||||
boost::bind (&frame_decoder_impl::reset, this, _1));
|
||||
set_msg_handler(pmt::mp("reset"),
|
||||
boost::bind(&frame_decoder_impl::reset, this, _1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
frame_decoder_impl::~frame_decoder_impl ()
|
||||
frame_decoder_impl::~frame_decoder_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
frame_decoder_impl::reset (pmt::pmt_t m)
|
||||
frame_decoder_impl::reset(pmt::pmt_t m)
|
||||
{
|
||||
d_decoder->reset();
|
||||
}
|
||||
|
||||
int
|
||||
frame_decoder_impl::work (int noutput_items,
|
||||
frame_decoder_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
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) {
|
||||
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.
|
||||
|
|
|
@ -23,21 +23,18 @@
|
|||
|
||||
#include <satnogs/frame_decoder.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class frame_decoder_impl : public frame_decoder
|
||||
{
|
||||
class frame_decoder_impl : public frame_decoder {
|
||||
|
||||
public:
|
||||
frame_decoder_impl (decoder::decoder_sptr decoder_object, int input_size);
|
||||
~frame_decoder_impl ();
|
||||
frame_decoder_impl(decoder::decoder_sptr decoder_object, int input_size);
|
||||
~frame_decoder_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -25,53 +25,51 @@
|
|||
#include <gnuradio/io_signature.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
|
||||
{
|
||||
|
||||
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,
|
||||
return gnuradio::get_initial_sptr(
|
||||
new frame_encoder_impl(append_preamble, ecss_encap, dest_addr,
|
||||
dest_ssid, src_addr, src_ssid));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
frame_encoder_impl::frame_encoder_impl (bool append_preamble,
|
||||
frame_encoder_impl::frame_encoder_impl(bool append_preamble,
|
||||
bool ecss_encap,
|
||||
const std::string& dest_addr,
|
||||
const std::string &dest_addr,
|
||||
uint8_t dest_ssid,
|
||||
const std::string& src_addr,
|
||||
const std::string &src_addr,
|
||||
uint8_t src_ssid) :
|
||||
gr::sync_block ("frame_encoder", gr::io_signature::make (0, 0, 0),
|
||||
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))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
frame_encoder_impl::~frame_encoder_impl ()
|
||||
{
|
||||
}
|
||||
frame_encoder_impl::~frame_encoder_impl()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
frame_encoder_impl::work (int noutput_items,
|
||||
int
|
||||
frame_encoder_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
// Do <+signal processing+>
|
||||
|
||||
// Tell runtime system how many output items we produced.
|
||||
return noutput_items;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -23,29 +23,26 @@
|
|||
|
||||
#include <satnogs/frame_encoder.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class frame_encoder_impl : public frame_encoder
|
||||
{
|
||||
private:
|
||||
class frame_encoder_impl : public frame_encoder {
|
||||
private:
|
||||
// Nothing to declare in this block.
|
||||
|
||||
public:
|
||||
frame_encoder_impl (bool append_preamble, bool ecss_encap,
|
||||
const std::string& dest_addr, uint8_t dest_ssid,
|
||||
const std::string& src_addr, uint8_t src_ssid);
|
||||
~frame_encoder_impl ();
|
||||
public:
|
||||
frame_encoder_impl(bool append_preamble, bool ecss_encap,
|
||||
const std::string &dest_addr, uint8_t dest_ssid,
|
||||
const std::string &src_addr, uint8_t src_ssid);
|
||||
~frame_encoder_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FRAME_ENCODER_IMPL_H */
|
||||
|
|
|
@ -25,124 +25,116 @@
|
|||
#include <gnuradio/io_signature.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
|
||||
*/
|
||||
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) :
|
||||
gr::block ("frame_file_sink", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_prefix_name (prefix_name),
|
||||
d_output_type (output_type),
|
||||
gr::block("frame_file_sink", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_prefix_name(prefix_name),
|
||||
d_output_type(output_type),
|
||||
d_filename_prev(""),
|
||||
d_counter(0)
|
||||
{
|
||||
message_port_register_in (pmt::mp ("frame"));
|
||||
set_msg_handler (
|
||||
pmt::mp ("frame"),
|
||||
boost::bind (&frame_file_sink_impl::msg_handler_frame, this, _1));
|
||||
{
|
||||
message_port_register_in(pmt::mp("frame"));
|
||||
set_msg_handler(
|
||||
pmt::mp("frame"),
|
||||
boost::bind(&frame_file_sink_impl::msg_handler_frame, this, _1));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
frame_file_sink_impl::~frame_file_sink_impl ()
|
||||
{
|
||||
}
|
||||
frame_file_sink_impl::~frame_file_sink_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
frame_file_sink_impl::msg_handler_frame (pmt::pmt_t msg)
|
||||
{
|
||||
void
|
||||
frame_file_sink_impl::msg_handler_frame(pmt::pmt_t msg)
|
||||
{
|
||||
|
||||
/* check for the current UTC time */
|
||||
std::chrono::system_clock::time_point p2 =
|
||||
std::chrono::system_clock::now ();
|
||||
std::chrono::system_clock::now();
|
||||
|
||||
char buffer[30];
|
||||
std::time_t t2 = std::chrono::system_clock::to_time_t (p2);
|
||||
struct tm * timeinfo;
|
||||
timeinfo = std::gmtime (&t2);
|
||||
struct tm *timeinfo;
|
||||
timeinfo = std::gmtime(&t2);
|
||||
|
||||
std::strftime (buffer, 30, "%FT%H-%M-%S", timeinfo);
|
||||
std::strftime(buffer, 30, "%FT%H-%M-%S", timeinfo);
|
||||
//puts (buffer);
|
||||
|
||||
/* create name of the file according prefix and timestamp */
|
||||
std::string filename;
|
||||
filename.append (d_prefix_name);
|
||||
filename.append ("_");
|
||||
filename.append (buffer);
|
||||
filename.append(d_prefix_name);
|
||||
filename.append("_");
|
||||
filename.append(buffer);
|
||||
|
||||
|
||||
if (filename.compare(d_filename_prev)==0)
|
||||
{
|
||||
if (filename.compare(d_filename_prev) == 0) {
|
||||
d_filename_prev.assign(filename);
|
||||
filename.append ("_");
|
||||
filename.append("_");
|
||||
d_counter++;
|
||||
filename.append(std::to_string(d_counter));
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
d_filename_prev.assign(filename);
|
||||
d_counter=0;
|
||||
d_counter = 0;
|
||||
}
|
||||
|
||||
uint8_t *su;
|
||||
|
||||
switch (d_output_type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
switch (d_output_type) {
|
||||
case 0: {
|
||||
/* Binary form */
|
||||
std::ofstream fd (filename.c_str ());
|
||||
fd.write ((const char *) pmt::blob_data (msg),
|
||||
pmt::blob_length (msg));
|
||||
fd.close ();
|
||||
std::ofstream fd(filename.c_str());
|
||||
fd.write((const char *) pmt::blob_data(msg),
|
||||
pmt::blob_length(msg));
|
||||
fd.close();
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
case 1: {
|
||||
/* aHex annotated, dd .txt to filename */
|
||||
filename.append (".txt");
|
||||
std::ofstream fd (filename.c_str ());
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
fd << "0x" << std::hex << std::setw (2) << std::setfill ('0')
|
||||
filename.append(".txt");
|
||||
std::ofstream fd(filename.c_str());
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
fd << "0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (uint32_t) su[i] << " ";
|
||||
}
|
||||
fd.close ();
|
||||
fd.close();
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
case 2: {
|
||||
/* Binary annotated, add .txt to filename */
|
||||
filename.append (".txt");
|
||||
std::ofstream fd (filename.c_str ());
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
filename.append(".txt");
|
||||
std::ofstream fd(filename.c_str());
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
fd << "0b" << std::bitset<8> (su[i]) << " ";
|
||||
}
|
||||
fd.close ();
|
||||
fd.close();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::invalid_argument ("Invalid format");
|
||||
throw std::invalid_argument("Invalid format");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -26,28 +26,25 @@
|
|||
#include <fstream>
|
||||
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class frame_file_sink_impl : public frame_file_sink
|
||||
{
|
||||
private:
|
||||
class frame_file_sink_impl : public frame_file_sink {
|
||||
private:
|
||||
const std::string d_prefix_name;
|
||||
int d_output_type;
|
||||
std::string d_filename_prev;
|
||||
int d_counter;
|
||||
|
||||
public:
|
||||
frame_file_sink_impl (const std::string& prefix_name, int output_type);
|
||||
~frame_file_sink_impl ();
|
||||
public:
|
||||
frame_file_sink_impl(const std::string &prefix_name, int output_type);
|
||||
~frame_file_sink_impl();
|
||||
|
||||
void
|
||||
msg_handler_frame (pmt::pmt_t msg);
|
||||
};
|
||||
msg_handler_frame(pmt::pmt_t msg);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_FRAME_FILE_SINK_IMPL_H */
|
||||
|
|
|
@ -25,45 +25,43 @@
|
|||
#include <gnuradio/io_signature.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) :
|
||||
d_x (x),
|
||||
d_freq_drift (y)
|
||||
{
|
||||
}
|
||||
freq_drift::~freq_drift()
|
||||
{
|
||||
}
|
||||
|
||||
freq_drift::~freq_drift ()
|
||||
{
|
||||
}
|
||||
|
||||
double
|
||||
freq_drift::get_freq_drift () const
|
||||
{
|
||||
double
|
||||
freq_drift::get_freq_drift() const
|
||||
{
|
||||
return d_freq_drift;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
freq_drift::set_freq_drift (double freq_drift)
|
||||
{
|
||||
void
|
||||
freq_drift::set_freq_drift(double freq_drift)
|
||||
{
|
||||
d_freq_drift = freq_drift;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
freq_drift::get_x () const
|
||||
{
|
||||
uint64_t
|
||||
freq_drift::get_x() const
|
||||
{
|
||||
return d_x;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
freq_drift::set_x (uint64_t x)
|
||||
{
|
||||
void
|
||||
freq_drift::set_x(uint64_t x)
|
||||
{
|
||||
d_x = x;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -28,10 +28,8 @@
|
|||
|
||||
#include <satnogs/utils.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*
|
||||
* Matrix P was retrieved by:
|
||||
|
@ -40,19 +38,21 @@ namespace satnogs
|
|||
* Matrix mentioned by Morelos-Zaragoza, Robert H. "The art of error correcting coding."
|
||||
* John Wiley & Sons, 2006 was not suitable.
|
||||
*/
|
||||
const std::vector<uint32_t> golay24::G_P =
|
||||
{0x8ED, 0x1DB, 0x3B5, 0x769, 0xED1, 0xDA3, 0xB47, 0x68F, 0xD1D, 0xA3B, 0x477,
|
||||
0xFFE};
|
||||
const std::vector<uint32_t> golay24::G_P = {
|
||||
0x8ED, 0x1DB, 0x3B5, 0x769, 0xED1, 0xDA3, 0xB47, 0x68F, 0xD1D, 0xA3B, 0x477,
|
||||
0xFFE
|
||||
};
|
||||
|
||||
const std::vector<uint32_t> golay24::G_I =
|
||||
{ 0x800, 0x400, 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002,
|
||||
0x001 };
|
||||
const std::vector<uint32_t> golay24::G_I = {
|
||||
0x800, 0x400, 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002,
|
||||
0x001
|
||||
};
|
||||
|
||||
golay24::golay24 ()
|
||||
golay24::golay24()
|
||||
{
|
||||
}
|
||||
|
||||
golay24::~golay24 ()
|
||||
golay24::~golay24()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ static inline uint32_t
|
|||
syndrome(uint16_t x, uint16_t y)
|
||||
{
|
||||
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 ^= 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
|
||||
*/
|
||||
uint32_t
|
||||
golay24::encode12 (uint16_t in, bool lsb_parity)
|
||||
golay24::encode12(uint16_t in, bool lsb_parity)
|
||||
{
|
||||
uint32_t c[2] =
|
||||
{ 0x0, 0x0 };
|
||||
|
@ -94,7 +94,7 @@ golay24::encode12 (uint16_t in, bool lsb_parity)
|
|||
}
|
||||
c[1] = (c[1] << 1) ^ tmp;
|
||||
}
|
||||
if(lsb_parity) {
|
||||
if (lsb_parity) {
|
||||
return ((c[0] & 0xFFF) << 12) | (c[1] & 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[1] = in & 0xFFF;
|
||||
s = syndrome(r[0], r[1]);
|
||||
if(weight(s) <= 3) {
|
||||
if (weight(s) <= 3) {
|
||||
*out = ((r[0] ^ s) << 12) | (r[1]);
|
||||
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];
|
||||
if(weight(tmp) <= 2) {
|
||||
if (weight(tmp) <= 2) {
|
||||
*out = ((r[0] ^ tmp) << 12) | (r[1] ^ G_I[i]);
|
||||
return true;
|
||||
}
|
||||
|
@ -136,17 +136,17 @@ golay24::decode24(uint32_t *out, const uint32_t in)
|
|||
|
||||
/* Compute the sP vector */
|
||||
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);
|
||||
}
|
||||
if(weight(sP) == 2 || weight(sP) == 3) {
|
||||
if (weight(sP) == 2 || weight(sP) == 3) {
|
||||
*out = (r[0] << 12) | (r[1] ^ sP);
|
||||
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];
|
||||
if(weight(tmp) == 2) {
|
||||
if (weight(tmp) == 2) {
|
||||
*out = ((r[0] ^ G_I[i]) << 12) | (r[1] ^ tmp);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,19 +26,17 @@
|
|||
#include <satnogs/ieee802_15_4_variant_decoder.h>
|
||||
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
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> &sync, crc::crc_t crc,
|
||||
whitening::whitening_sptr descrambler)
|
||||
{
|
||||
}
|
||||
|
||||
ieee802_15_4_variant_decoder::~ieee802_15_4_variant_decoder ()
|
||||
ieee802_15_4_variant_decoder::~ieee802_15_4_variant_decoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -27,81 +27,78 @@
|
|||
#include <volk/volk.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
iq_sink::sptr
|
||||
iq_sink::make (const float scale, const char *filename, bool append,
|
||||
iq_sink::sptr
|
||||
iq_sink::make(const float scale, const char *filename, bool append,
|
||||
const int status)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new iq_sink_impl (scale, filename, append, status));
|
||||
}
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new iq_sink_impl(scale, filename, append, status));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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) :
|
||||
gr::sync_block ("iq_sink",
|
||||
gr::io_signature::make (1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
file_sink_base (filename, true, append),
|
||||
d_scale (scale),
|
||||
d_num_points (16384),
|
||||
d_status ((iq_sink_status_t) status)
|
||||
{
|
||||
set_max_noutput_items (d_num_points);
|
||||
unsigned int alignment = volk_get_alignment ();
|
||||
d_out = (int16_t*) volk_malloc (sizeof(int16_t) * d_num_points * 2,
|
||||
gr::sync_block("iq_sink",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
file_sink_base(filename, true, append),
|
||||
d_scale(scale),
|
||||
d_num_points(16384),
|
||||
d_status((iq_sink_status_t) status)
|
||||
{
|
||||
set_max_noutput_items(d_num_points);
|
||||
unsigned int alignment = volk_get_alignment();
|
||||
d_out = (int16_t *) volk_malloc(sizeof(int16_t) * d_num_points * 2,
|
||||
alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
iq_sink_impl::~iq_sink_impl ()
|
||||
{
|
||||
volk_free (d_out);
|
||||
}
|
||||
iq_sink_impl::~iq_sink_impl()
|
||||
{
|
||||
volk_free(d_out);
|
||||
}
|
||||
|
||||
int
|
||||
iq_sink_impl::work (int noutput_items,
|
||||
int
|
||||
iq_sink_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_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;
|
||||
switch (d_status)
|
||||
{
|
||||
case IQ_SINK_STATUS_NULL:
|
||||
{
|
||||
switch (d_status) {
|
||||
case IQ_SINK_STATUS_NULL: {
|
||||
return noutput_items;
|
||||
}
|
||||
case IQ_SINK_STATUS_ACTIVE:
|
||||
{
|
||||
case IQ_SINK_STATUS_ACTIVE: {
|
||||
/* update d_fp is required */
|
||||
do_update ();
|
||||
do_update();
|
||||
|
||||
if (!d_fp)
|
||||
/* drop output on the floor */
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
if (count == 0) {
|
||||
if (ferror (d_fp)) {
|
||||
if (ferror(d_fp)) {
|
||||
std::cout << count << std::endl;
|
||||
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;
|
||||
throw std::runtime_error (s.str ());
|
||||
throw std::runtime_error(s.str());
|
||||
}
|
||||
/* if EOF */
|
||||
else {
|
||||
|
@ -115,8 +112,8 @@ namespace gr
|
|||
}
|
||||
/* Should never reach here */
|
||||
return noutput_items;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -25,19 +25,15 @@
|
|||
#include <chrono>
|
||||
#include <fstream>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class iq_sink_impl : public iq_sink
|
||||
{
|
||||
private:
|
||||
class iq_sink_impl : public iq_sink {
|
||||
private:
|
||||
/**
|
||||
* 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_ACTIVE = 1, //!< IQ_SINK_STATUS_ACTIVE IQ sink block is active
|
||||
} iq_sink_status_t;
|
||||
|
@ -47,17 +43,17 @@ namespace gr
|
|||
float d_scale;
|
||||
int16_t *d_out;
|
||||
|
||||
public:
|
||||
iq_sink_impl (const float scale, const char *filename, bool append,
|
||||
public:
|
||||
iq_sink_impl(const float scale, const char *filename, bool append,
|
||||
const int status);
|
||||
~iq_sink_impl ();
|
||||
~iq_sink_impl();
|
||||
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_IQ_SINK_IMPL_H */
|
||||
|
|
|
@ -28,45 +28,43 @@
|
|||
#include <json/json.h>
|
||||
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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
|
||||
*/
|
||||
json_converter_impl::json_converter_impl (const std::string& extra) :
|
||||
gr::block ("json_converter", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
json_converter_impl::json_converter_impl(const std::string &extra) :
|
||||
gr::block("json_converter", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_extra(extra)
|
||||
{
|
||||
message_port_register_in(pmt::mp("in"));
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
|
||||
set_msg_handler (pmt::mp ("in"),
|
||||
boost::bind (&json_converter_impl::convert, this, _1));
|
||||
set_msg_handler(pmt::mp("in"),
|
||||
boost::bind(&json_converter_impl::convert, this, _1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
json_converter_impl::~json_converter_impl ()
|
||||
json_converter_impl::~json_converter_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
json_converter_impl::convert (pmt::pmt_t m)
|
||||
json_converter_impl::convert(pmt::pmt_t m)
|
||||
{
|
||||
Json::Value root = metadata::to_json(m);
|
||||
root["extra"] = d_extra;
|
||||
const std::string& s = root.toStyledString();
|
||||
const std::string &s = root.toStyledString();
|
||||
const char *c = s.c_str();
|
||||
message_port_pub(pmt::mp("out"), pmt::make_blob(c, s.length()));
|
||||
}
|
||||
|
|
|
@ -23,17 +23,14 @@
|
|||
|
||||
#include <satnogs/json_converter.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class json_converter_impl : public json_converter
|
||||
{
|
||||
class json_converter_impl : public json_converter {
|
||||
|
||||
public:
|
||||
json_converter_impl (const std::string &extra);
|
||||
~json_converter_impl ();
|
||||
json_converter_impl(const std::string &extra);
|
||||
~json_converter_impl();
|
||||
|
||||
void
|
||||
convert(pmt::pmt_t m);
|
||||
|
|
|
@ -29,25 +29,23 @@
|
|||
|
||||
|
||||
extern "C" {
|
||||
#include <fec.h>
|
||||
#include <fec.h>
|
||||
}
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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
|
||||
*/
|
||||
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)),
|
||||
/*
|
||||
|
@ -57,7 +55,7 @@ lrpt_decoder_impl::lrpt_decoder_impl()
|
|||
* Thus, they dropped the check symbols at the end of the frame.
|
||||
*/
|
||||
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_scrambler(0x2A9, 0xFF, 7),
|
||||
d_have_mpdu(false)
|
||||
|
@ -65,12 +63,12 @@ lrpt_decoder_impl::lrpt_decoder_impl()
|
|||
message_port_register_in(pmt::mp("cadu"));
|
||||
message_port_register_out(pmt::mp("frame"));
|
||||
|
||||
set_msg_handler (
|
||||
pmt::mp ("cadu"),
|
||||
boost::bind (&lrpt_decoder_impl::decode, this, _1));
|
||||
set_msg_handler(
|
||||
pmt::mp("cadu"),
|
||||
boost::bind(&lrpt_decoder_impl::decode, this, _1));
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -86,7 +84,7 @@ lrpt_decoder_impl::lrpt_decoder_impl()
|
|||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
lrpt_decoder_impl::~lrpt_decoder_impl ()
|
||||
lrpt_decoder_impl::~lrpt_decoder_impl()
|
||||
{
|
||||
|
||||
delete [] d_cadu;
|
||||
|
@ -95,17 +93,17 @@ lrpt_decoder_impl::~lrpt_decoder_impl ()
|
|||
}
|
||||
|
||||
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);
|
||||
if(pmt::blob_length(m) != d_coded_cadu_len) {
|
||||
if (pmt::blob_length(m) != d_coded_cadu_len) {
|
||||
LOG_ERROR("Wrong CADU size");
|
||||
return;
|
||||
}
|
||||
|
||||
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 + 1] = 0xFF * ((coded_cadu[i] >> 6) & 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)
|
||||
{
|
||||
/* Check first the VCDU version and if encryption is off */
|
||||
if( (cvcdu[0] >> 6) != 0x1) {
|
||||
if ((cvcdu[0] >> 6) != 0x1) {
|
||||
return;
|
||||
}
|
||||
if(cvcdu[6] != 0x0 || cvcdu[7] != 0x0) {
|
||||
if (cvcdu[6] != 0x0 || cvcdu[7] != 0x0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -147,7 +145,7 @@ lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu)
|
|||
/* Check CCSDS packet version and type */
|
||||
//if( (mpdu[0] >> 5) != 0x0) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
uint32_t vcdu_seq = 0;
|
||||
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];
|
||||
|
||||
/* Try to find the start of a MPDU */
|
||||
if(!d_have_mpdu) {
|
||||
if(hdr_ptr != 0) {
|
||||
if (!d_have_mpdu) {
|
||||
if (hdr_ptr != 0) {
|
||||
return;
|
||||
}
|
||||
d_have_mpdu = true;
|
||||
|
|
|
@ -25,17 +25,14 @@
|
|||
#include <satnogs/convolutional_deinterleaver.h>
|
||||
#include <satnogs/whitening.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class lrpt_decoder_impl : public lrpt_decoder
|
||||
{
|
||||
class lrpt_decoder_impl : public lrpt_decoder {
|
||||
|
||||
public:
|
||||
lrpt_decoder_impl ();
|
||||
~lrpt_decoder_impl ();
|
||||
lrpt_decoder_impl();
|
||||
~lrpt_decoder_impl();
|
||||
|
||||
private:
|
||||
const size_t d_cadu_len;
|
||||
|
|
|
@ -30,24 +30,22 @@
|
|||
#include <volk/volk.h>
|
||||
#include <gnuradio/blocks/count_bits.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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
|
||||
*/
|
||||
lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
||||
gr::sync_block ("lrpt_sync",
|
||||
gr::io_signature::make (1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
lrpt_sync_impl::lrpt_sync_impl(size_t threshold) :
|
||||
gr::sync_block("lrpt_sync",
|
||||
gr::io_signature::make(1, 1, sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_thresh(threshold),
|
||||
d_asm_coded(0xd49c24ff2686b),
|
||||
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
|
||||
* 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*/
|
||||
/*
|
||||
* 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.
|
||||
* 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_received(0),
|
||||
d_rotate(1.0, 0.0),
|
||||
|
@ -76,32 +74,32 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
|||
d_shift_reg3(0x0)
|
||||
{
|
||||
set_output_multiple(d_window);
|
||||
const int alignment_multiple = volk_get_alignment () / sizeof(gr_complex);
|
||||
set_alignment (std::max (1, alignment_multiple));
|
||||
d_rotate_pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_pi2) {
|
||||
const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
|
||||
set_alignment(std::max(1, alignment_multiple));
|
||||
d_rotate_pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
|
||||
volk_get_alignment());
|
||||
if (!d_rotate_pi2) {
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_rotate_2pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_2pi2) {
|
||||
d_rotate_2pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
|
||||
volk_get_alignment());
|
||||
if (!d_rotate_2pi2) {
|
||||
volk_free(d_rotate_pi2);
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_rotate_3pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_3pi2) {
|
||||
d_rotate_3pi2 = (gr_complex *) volk_malloc(d_window * sizeof(gr_complex),
|
||||
volk_get_alignment());
|
||||
if (!d_rotate_3pi2) {
|
||||
volk_free(d_rotate_pi2);
|
||||
volk_free(d_rotate_2pi2);
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_corrected = (gr_complex *)volk_malloc(d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_corrected) {
|
||||
volk_get_alignment());
|
||||
if (!d_corrected) {
|
||||
volk_free(d_rotate_pi2);
|
||||
volk_free(d_rotate_2pi2);
|
||||
volk_free(d_rotate_3pi2);
|
||||
|
@ -119,19 +117,19 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
|||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
lrpt_sync_impl::~lrpt_sync_impl ()
|
||||
lrpt_sync_impl::~lrpt_sync_impl()
|
||||
{
|
||||
volk_free (d_rotate_pi2);
|
||||
volk_free (d_rotate_2pi2);
|
||||
volk_free (d_rotate_3pi2);
|
||||
volk_free (d_corrected);
|
||||
volk_free(d_rotate_pi2);
|
||||
volk_free(d_rotate_2pi2);
|
||||
volk_free(d_rotate_3pi2);
|
||||
volk_free(d_corrected);
|
||||
delete [] d_coded_cadu;
|
||||
}
|
||||
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -141,7 +139,7 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
|
|||
{
|
||||
uint32_t bits;
|
||||
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,
|
||||
gr_complex(0.0, 1.0), 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
|
||||
* 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_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
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_frame_sync = true;
|
||||
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_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
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_frame_sync = true;
|
||||
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_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
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_frame_sync = true;
|
||||
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_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
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_frame_sync = true;
|
||||
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;
|
||||
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,
|
||||
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 = d_qpsk->decision_maker(d_corrected + j) << 6;
|
||||
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);
|
||||
|
||||
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_frame_sync = false;
|
||||
message_port_pub (pmt::mp ("cadu"),
|
||||
pmt::make_blob (d_coded_cadu, d_coded_cadu_len));
|
||||
message_port_pub(pmt::mp("cadu"),
|
||||
pmt::make_blob(d_coded_cadu, d_coded_cadu_len));
|
||||
return i * d_window + j + 4;
|
||||
}
|
||||
}
|
||||
|
@ -231,13 +229,13 @@ lrpt_sync_impl::work_sync(const gr_complex *in, int noutput_items)
|
|||
|
||||
|
||||
int
|
||||
lrpt_sync_impl::work (int noutput_items,
|
||||
lrpt_sync_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
const gr_complex *in = (const gr_complex *) input_items[0];
|
||||
uint32_t bits;
|
||||
if(!d_frame_sync) {
|
||||
if (!d_frame_sync) {
|
||||
return work_no_sync(in, noutput_items);
|
||||
}
|
||||
return work_sync(in, noutput_items);
|
||||
|
|
|
@ -25,19 +25,16 @@
|
|||
#include <satnogs/convolutional_deinterleaver.h>
|
||||
#include <gnuradio/digital/constellation.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class lrpt_sync_impl : public lrpt_sync
|
||||
{
|
||||
class lrpt_sync_impl : public lrpt_sync {
|
||||
public:
|
||||
lrpt_sync_impl (size_t threshold);
|
||||
~lrpt_sync_impl ();
|
||||
lrpt_sync_impl(size_t threshold);
|
||||
~lrpt_sync_impl();
|
||||
|
||||
int
|
||||
work (int noutput_items,
|
||||
work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
|
@ -56,11 +53,11 @@ private:
|
|||
uint64_t d_shift_reg1;
|
||||
uint64_t d_shift_reg2;
|
||||
uint64_t d_shift_reg3;
|
||||
gr_complex* d_rotate_pi2;
|
||||
gr_complex* d_rotate_2pi2;
|
||||
gr_complex* d_rotate_3pi2;
|
||||
gr_complex* d_corrected;
|
||||
uint8_t* d_coded_cadu;
|
||||
gr_complex *d_rotate_pi2;
|
||||
gr_complex *d_rotate_2pi2;
|
||||
gr_complex *d_rotate_3pi2;
|
||||
gr_complex *d_corrected;
|
||||
uint8_t *d_coded_cadu;
|
||||
|
||||
int
|
||||
work_no_sync(const gr_complex *in, int noutput_items);
|
||||
|
|
|
@ -32,7 +32,7 @@ std::string
|
|||
metadata::keys()
|
||||
{
|
||||
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(", ");
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ metadata::keys()
|
|||
* @return string corresponding to the key @a k value
|
||||
*/
|
||||
std::string
|
||||
metadata::value(const key_t& k)
|
||||
metadata::value(const key_t &k)
|
||||
{
|
||||
switch(k) {
|
||||
switch (k) {
|
||||
case PDU:
|
||||
return "pdu";
|
||||
case CRC_VALID:
|
||||
|
@ -81,7 +81,7 @@ metadata::time_iso8601()
|
|||
{
|
||||
/* check for the current UTC time */
|
||||
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));
|
||||
}
|
||||
|
@ -137,39 +137,39 @@ metadata::add_corrected_bits(pmt::pmt_t &m, uint32_t cnt)
|
|||
}
|
||||
|
||||
Json::Value
|
||||
metadata::to_json(const pmt::pmt_t& m)
|
||||
metadata::to_json(const pmt::pmt_t &m)
|
||||
{
|
||||
Json::Value root;
|
||||
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);
|
||||
size_t len = pmt::blob_length(v);
|
||||
root[value(PDU)] = base64_encode(b, len);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
v = pmt::dict_ref (m, pmt::mp (value (CRC_VALID)), pmt::PMT_NIL);
|
||||
if (!pmt::equal (v, pmt::PMT_NIL)) {
|
||||
root[value (CRC_VALID)] = pmt::to_bool (v);
|
||||
v = pmt::dict_ref(m, pmt::mp(value(CRC_VALID)), pmt::PMT_NIL);
|
||||
if (!pmt::equal(v, pmt::PMT_NIL)) {
|
||||
root[value(CRC_VALID)] = pmt::to_bool(v);
|
||||
}
|
||||
|
||||
v = pmt::dict_ref (m, pmt::mp (value (SAMPLE_START)), pmt::PMT_NIL);
|
||||
if (!pmt::equal (v, pmt::PMT_NIL)) {
|
||||
root[value (SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64 (v));
|
||||
v = pmt::dict_ref(m, pmt::mp(value(SAMPLE_START)), pmt::PMT_NIL);
|
||||
if (!pmt::equal(v, pmt::PMT_NIL)) {
|
||||
root[value(SAMPLE_START)] = Json::Value::UInt64(pmt::to_uint64(v));
|
||||
}
|
||||
|
||||
v = pmt::dict_ref (m, pmt::mp (value (SYMBOL_ERASURES)), pmt::PMT_NIL);
|
||||
if (!pmt::equal (v, pmt::PMT_NIL)) {
|
||||
root[value (SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64 (v));
|
||||
v = pmt::dict_ref(m, pmt::mp(value(SYMBOL_ERASURES)), pmt::PMT_NIL);
|
||||
if (!pmt::equal(v, pmt::PMT_NIL)) {
|
||||
root[value(SYMBOL_ERASURES)] = Json::Value::UInt64(pmt::to_uint64(v));
|
||||
}
|
||||
|
||||
v = pmt::dict_ref (m, pmt::mp (value (CORRECTED_BITS)), pmt::PMT_NIL);
|
||||
if (!pmt::equal (v, pmt::PMT_NIL)) {
|
||||
root[value (CORRECTED_BITS)] = Json::Value::UInt64(pmt::to_uint64 (v));
|
||||
v = pmt::dict_ref(m, pmt::mp(value(CORRECTED_BITS)), pmt::PMT_NIL);
|
||||
if (!pmt::equal(v, pmt::PMT_NIL)) {
|
||||
root[value(CORRECTED_BITS)] = Json::Value::UInt64(pmt::to_uint64(v));
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -28,57 +28,55 @@
|
|||
#include <satnogs/morse.h>
|
||||
#include <random>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
morse_debug_source::sptr
|
||||
morse_debug_source::make (const size_t wpm,
|
||||
const std::string& debug_seq, bool inject_errors,
|
||||
morse_debug_source::sptr
|
||||
morse_debug_source::make(const size_t wpm,
|
||||
const std::string &debug_seq, bool inject_errors,
|
||||
float error_prob,
|
||||
size_t seq_pause_ms)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new morse_debug_source_impl (wpm, debug_seq, inject_errors,
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new morse_debug_source_impl(wpm, debug_seq, inject_errors,
|
||||
error_prob, seq_pause_ms));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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,
|
||||
bool inject_errors,
|
||||
float error_prob,
|
||||
size_t seq_pause_ms) :
|
||||
gr::block ("morse_debug_source",
|
||||
gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_wpm (wpm),
|
||||
d_inject_errors (inject_errors),
|
||||
d_p (error_prob),
|
||||
d_seq_pause_ms (seq_pause_ms),
|
||||
d_run (true),
|
||||
d_chars
|
||||
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
gr::block("morse_debug_source",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_wpm(wpm),
|
||||
d_inject_errors(inject_errors),
|
||||
d_p(error_prob),
|
||||
d_seq_pause_ms(seq_pause_ms),
|
||||
d_run(true),
|
||||
d_chars {
|
||||
'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',
|
||||
'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' },
|
||||
d_symbols
|
||||
{ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
|
||||
d_symbols {
|
||||
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
|
||||
".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
|
||||
".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--",
|
||||
"--..", ".----", "..---", "...--", "....-", ".....", "-....",
|
||||
"--...", "---..", "----.", "-----" }
|
||||
{
|
||||
message_port_register_out (pmt::mp ("out"));
|
||||
d_thread = std::thread (&morse_debug_source_impl::send_debug_msg, this,
|
||||
{
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
d_thread = std::thread(&morse_debug_source_impl::send_debug_msg, this,
|
||||
debug_seq);
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
find_char_idx (const char* characters, size_t len, char c)
|
||||
{
|
||||
static inline size_t
|
||||
find_char_idx(const char *characters, size_t len, char c)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (characters[i] == c) {
|
||||
|
@ -86,88 +84,88 @@ namespace gr
|
|||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morse_debug_source_impl::send_debug_msg (std::string sentence)
|
||||
{
|
||||
void
|
||||
morse_debug_source_impl::send_debug_msg(std::string sentence)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t idx;
|
||||
std::string s;
|
||||
char c;
|
||||
std::random_device rd;
|
||||
std::mt19937 gen (rd ());
|
||||
std::bernoulli_distribution error_distr (d_p);
|
||||
std::mt19937 gen(rd());
|
||||
std::bernoulli_distribution error_distr(d_p);
|
||||
bool inject_error;
|
||||
size_t len = sentence.length ();
|
||||
pmt::pmt_t port = pmt::mp ("out");
|
||||
size_t len = sentence.length();
|
||||
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) {
|
||||
/* Not the best approach, but hey, this is only for debug */
|
||||
for (i = 0; i < len; i++) {
|
||||
c = std::toupper (sentence[i]);
|
||||
c = std::toupper(sentence[i]);
|
||||
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)) {
|
||||
|
||||
s = d_symbols[idx];
|
||||
/* Get from the random distribution if an error should be injected */
|
||||
inject_error = d_inject_errors && error_distr (gen);
|
||||
for (j = 0; j < s.length (); j++) {
|
||||
inject_error = d_inject_errors && error_distr(gen);
|
||||
for (j = 0; j < s.length(); j++) {
|
||||
if (s[j] == '.') {
|
||||
if (inject_error) {
|
||||
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_DASH));
|
||||
message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
|
||||
|
||||
}
|
||||
else {
|
||||
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_DOT));
|
||||
message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (inject_error) {
|
||||
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_DOT));
|
||||
message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
|
||||
}
|
||||
else {
|
||||
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_DASH));
|
||||
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 */
|
||||
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++) {
|
||||
message_port_pub (port, pmt::from_long (MORSE_INTRA_SPACE));
|
||||
for (i = 0; i < d_seq_pause_ms / (1200 / d_wpm); i++) {
|
||||
message_port_pub(port, pmt::from_long(MORSE_INTRA_SPACE));
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
morse_debug_source_impl::~morse_debug_source_impl ()
|
||||
{
|
||||
morse_debug_source_impl::~morse_debug_source_impl()
|
||||
{
|
||||
d_run = false;
|
||||
d_thread.join ();
|
||||
}
|
||||
d_thread.join();
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -27,14 +27,11 @@
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class morse_debug_source_impl : public morse_debug_source
|
||||
{
|
||||
private:
|
||||
class morse_debug_source_impl : public morse_debug_source {
|
||||
private:
|
||||
const size_t d_wpm;
|
||||
const bool d_inject_errors;
|
||||
const float d_p;
|
||||
|
@ -45,16 +42,16 @@ namespace gr
|
|||
std::thread d_thread;
|
||||
|
||||
void
|
||||
send_debug_msg (std::string sentence);
|
||||
send_debug_msg(std::string sentence);
|
||||
|
||||
public:
|
||||
morse_debug_source_impl (const size_t wpm, std::string debug_seq,
|
||||
public:
|
||||
morse_debug_source_impl(const size_t wpm, std::string debug_seq,
|
||||
bool inject_errors,
|
||||
float error_prob, size_t seq_pause_ms);
|
||||
~morse_debug_source_impl ();
|
||||
};
|
||||
~morse_debug_source_impl();
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_MORSE_DEBUG_SOURCE_IMPL_H */
|
||||
|
|
|
@ -26,31 +26,28 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include "morse_decoder_impl.h"
|
||||
#include <satnogs/log.h>
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
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 (
|
||||
new morse_decoder_impl (unrecognized_char, min_frame_len));
|
||||
return gnuradio::get_initial_sptr(
|
||||
new morse_decoder_impl(unrecognized_char, min_frame_len));
|
||||
}
|
||||
|
||||
void
|
||||
morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
|
||||
morse_decoder_impl::symbol_msg_handler(pmt::pmt_t msg)
|
||||
{
|
||||
bool res = false;
|
||||
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_DASH:
|
||||
case MORSE_S_SPACE:
|
||||
res = d_morse_tree.received_symbol (s);
|
||||
res = d_morse_tree.received_symbol(s);
|
||||
break;
|
||||
/*
|
||||
* 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
|
||||
* 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 */
|
||||
if (d_morse_tree.get_word_len () == 0) {
|
||||
if (d_morse_tree.get_word_len() == 0) {
|
||||
res = true;
|
||||
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_morse_tree.reset ();
|
||||
d_morse_tree.reset();
|
||||
break;
|
||||
case MORSE_INTRA_SPACE:
|
||||
/*Ignore it */
|
||||
break;
|
||||
case MORSE_END_MSG_SPACE:
|
||||
if (d_str.length () > d_min_frame_len) {
|
||||
d_morse_tree.reset ();
|
||||
message_port_pub (pmt::mp ("out"),
|
||||
pmt::make_blob (d_str.c_str (), d_str.length ()));
|
||||
if (d_str.length() > d_min_frame_len) {
|
||||
d_morse_tree.reset();
|
||||
message_port_pub(pmt::mp("out"),
|
||||
pmt::make_blob(d_str.c_str(), d_str.length()));
|
||||
d_str = "";
|
||||
}
|
||||
break;
|
||||
|
@ -92,11 +89,11 @@ morse_decoder_impl::symbol_msg_handler (pmt::pmt_t msg)
|
|||
* character situation occurred or the maximum word limit reached
|
||||
*/
|
||||
if (!res) {
|
||||
if (d_morse_tree.get_max_word_len () == d_morse_tree.get_word_len ()) {
|
||||
d_str = d_morse_tree.get_word ();
|
||||
d_morse_tree.reset ();
|
||||
message_port_pub (pmt::mp ("out"),
|
||||
pmt::make_blob (d_str.c_str (), d_str.length ()));
|
||||
if (d_morse_tree.get_max_word_len() == d_morse_tree.get_word_len()) {
|
||||
d_str = d_morse_tree.get_word();
|
||||
d_morse_tree.reset();
|
||||
message_port_pub(pmt::mp("out"),
|
||||
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
|
||||
*/
|
||||
morse_decoder_impl::morse_decoder_impl (char unrecognized_char,
|
||||
morse_decoder_impl::morse_decoder_impl(char unrecognized_char,
|
||||
size_t min_frame_len) :
|
||||
gr::block ("morse_decoder", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_morse_tree (unrecognized_char),
|
||||
d_min_frame_len (min_frame_len),
|
||||
gr::block("morse_decoder", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_morse_tree(unrecognized_char),
|
||||
d_min_frame_len(min_frame_len),
|
||||
d_str("")
|
||||
|
||||
{
|
||||
/* Register the input and output msg handler */
|
||||
message_port_register_in (pmt::mp ("in"));
|
||||
message_port_register_out (pmt::mp ("out"));
|
||||
set_msg_handler (
|
||||
pmt::mp ("in"),
|
||||
boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1));
|
||||
message_port_register_in(pmt::mp("in"));
|
||||
message_port_register_out(pmt::mp("out"));
|
||||
set_msg_handler(
|
||||
pmt::mp("in"),
|
||||
boost::bind(&morse_decoder_impl::symbol_msg_handler, this, _1));
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
|
|
|
@ -24,16 +24,13 @@
|
|||
#include <satnogs/morse_decoder.h>
|
||||
#include <satnogs/morse_tree.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class morse_decoder_impl : public morse_decoder
|
||||
{
|
||||
class morse_decoder_impl : public morse_decoder {
|
||||
|
||||
public:
|
||||
morse_decoder_impl (char unrecognized_char, size_t min_frame_len);
|
||||
morse_decoder_impl(char unrecognized_char, size_t min_frame_len);
|
||||
|
||||
private:
|
||||
morse_tree d_morse_tree;
|
||||
|
@ -41,7 +38,7 @@ private:
|
|||
std::string d_str;
|
||||
|
||||
void
|
||||
symbol_msg_handler (pmt::pmt_t msg);
|
||||
symbol_msg_handler(pmt::pmt_t msg);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -28,192 +28,189 @@
|
|||
#include <satnogs/log.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs a Morse code tree for Morse code decoding
|
||||
*/
|
||||
morse_tree::morse_tree () :
|
||||
d_unrecognized_symbol ('#'),
|
||||
d_root (new tree_node (0)),
|
||||
d_current (d_root),
|
||||
d_buff_len (4096),
|
||||
d_word_len (0),
|
||||
d_word_buffer (new char[d_buff_len])
|
||||
{
|
||||
construct_tree ();
|
||||
}
|
||||
morse_tree::morse_tree() :
|
||||
d_unrecognized_symbol('#'),
|
||||
d_root(new tree_node(0)),
|
||||
d_current(d_root),
|
||||
d_buff_len(4096),
|
||||
d_word_len(0),
|
||||
d_word_buffer(new char[d_buff_len])
|
||||
{
|
||||
construct_tree();
|
||||
}
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs a Morse code tree for Morse code decoding
|
||||
* @param unrecognized the character that will be placed
|
||||
* in the place of unrecognized symbols
|
||||
*/
|
||||
morse_tree::morse_tree (char unrecognized) :
|
||||
d_unrecognized_symbol (unrecognized),
|
||||
d_root (new tree_node (0)),
|
||||
d_current (d_root),
|
||||
d_buff_len (4096),
|
||||
d_word_len (0),
|
||||
d_word_buffer (new char[d_buff_len])
|
||||
{
|
||||
construct_tree ();
|
||||
}
|
||||
morse_tree::morse_tree(char unrecognized) :
|
||||
d_unrecognized_symbol(unrecognized),
|
||||
d_root(new tree_node(0)),
|
||||
d_current(d_root),
|
||||
d_buff_len(4096),
|
||||
d_word_len(0),
|
||||
d_word_buffer(new char[d_buff_len])
|
||||
{
|
||||
construct_tree();
|
||||
}
|
||||
|
||||
morse_tree::~morse_tree ()
|
||||
{
|
||||
morse_tree::~morse_tree()
|
||||
{
|
||||
delete_tree(d_root);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Resets the pointer to the initial root node
|
||||
*/
|
||||
void
|
||||
morse_tree::reset ()
|
||||
{
|
||||
void
|
||||
morse_tree::reset()
|
||||
{
|
||||
d_current = d_root;
|
||||
d_word_len = 0;
|
||||
memset(d_word_buffer.get(), 0, d_buff_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Creates and initializes the Morse code decoder tree
|
||||
*/
|
||||
void
|
||||
morse_tree::construct_tree ()
|
||||
{
|
||||
tree_node *e = new tree_node ('E');
|
||||
tree_node *t = new tree_node ('T');
|
||||
tree_node *i = new tree_node ('I');
|
||||
tree_node *a = new tree_node ('A');
|
||||
tree_node *n = new tree_node ('N');
|
||||
tree_node *m = new tree_node ('M');
|
||||
tree_node *s = new tree_node ('S');
|
||||
tree_node *u = new tree_node ('U');
|
||||
tree_node *r = new tree_node ('R');
|
||||
tree_node *w = new tree_node ('W');
|
||||
tree_node *d = new tree_node ('D');
|
||||
tree_node *k = new tree_node ('K');
|
||||
tree_node *g = new tree_node ('G');
|
||||
tree_node *o = new tree_node ('O');
|
||||
tree_node *h = new tree_node ('H');
|
||||
tree_node *v = new tree_node ('V');
|
||||
tree_node *f = new tree_node ('F');
|
||||
tree_node *u_u = new tree_node ('U');
|
||||
tree_node *l = new tree_node ('L');
|
||||
tree_node *u_a = new tree_node ('A');
|
||||
tree_node *p = new tree_node ('P');
|
||||
tree_node *j = new tree_node ('J');
|
||||
tree_node *b = new tree_node ('B');
|
||||
tree_node *x = new tree_node ('X');
|
||||
tree_node *c = new tree_node ('C');
|
||||
tree_node *y = new tree_node ('Y');
|
||||
tree_node *z = new tree_node ('Z');
|
||||
tree_node *q = new tree_node ('Q');
|
||||
tree_node *u_o = new tree_node ('O');
|
||||
tree_node *null0 = new tree_node (0);
|
||||
tree_node *n5 = new tree_node ('5');
|
||||
tree_node *n4 = new tree_node ('4');
|
||||
tree_node *a_s = new tree_node ('S');
|
||||
tree_node *n3 = new tree_node ('3');
|
||||
tree_node *a_e = new tree_node ('E');
|
||||
tree_node *d_d = new tree_node ('D');
|
||||
tree_node *n2 = new tree_node ('2');
|
||||
tree_node *d_e = new tree_node ('E');
|
||||
tree_node *plus = new tree_node ('+');
|
||||
tree_node *d_a = new tree_node ('A');
|
||||
tree_node *d_j = new tree_node ('J');
|
||||
tree_node *n1 = new tree_node ('1');
|
||||
tree_node *n6 = new tree_node ('6');
|
||||
tree_node *eq = new tree_node ('=');
|
||||
tree_node *slash = new tree_node ('/');
|
||||
tree_node *null1 = new tree_node (0);
|
||||
tree_node *n7 = new tree_node ('7');
|
||||
tree_node *null2 = new tree_node (0);
|
||||
tree_node *n8 = new tree_node ('8');
|
||||
tree_node *n9 = new tree_node ('9');
|
||||
tree_node *n0 = new tree_node ('0');
|
||||
void
|
||||
morse_tree::construct_tree()
|
||||
{
|
||||
tree_node *e = new tree_node('E');
|
||||
tree_node *t = new tree_node('T');
|
||||
tree_node *i = new tree_node('I');
|
||||
tree_node *a = new tree_node('A');
|
||||
tree_node *n = new tree_node('N');
|
||||
tree_node *m = new tree_node('M');
|
||||
tree_node *s = new tree_node('S');
|
||||
tree_node *u = new tree_node('U');
|
||||
tree_node *r = new tree_node('R');
|
||||
tree_node *w = new tree_node('W');
|
||||
tree_node *d = new tree_node('D');
|
||||
tree_node *k = new tree_node('K');
|
||||
tree_node *g = new tree_node('G');
|
||||
tree_node *o = new tree_node('O');
|
||||
tree_node *h = new tree_node('H');
|
||||
tree_node *v = new tree_node('V');
|
||||
tree_node *f = new tree_node('F');
|
||||
tree_node *u_u = new tree_node('U');
|
||||
tree_node *l = new tree_node('L');
|
||||
tree_node *u_a = new tree_node('A');
|
||||
tree_node *p = new tree_node('P');
|
||||
tree_node *j = new tree_node('J');
|
||||
tree_node *b = new tree_node('B');
|
||||
tree_node *x = new tree_node('X');
|
||||
tree_node *c = new tree_node('C');
|
||||
tree_node *y = new tree_node('Y');
|
||||
tree_node *z = new tree_node('Z');
|
||||
tree_node *q = new tree_node('Q');
|
||||
tree_node *u_o = new tree_node('O');
|
||||
tree_node *null0 = new tree_node(0);
|
||||
tree_node *n5 = new tree_node('5');
|
||||
tree_node *n4 = new tree_node('4');
|
||||
tree_node *a_s = new tree_node('S');
|
||||
tree_node *n3 = new tree_node('3');
|
||||
tree_node *a_e = new tree_node('E');
|
||||
tree_node *d_d = new tree_node('D');
|
||||
tree_node *n2 = new tree_node('2');
|
||||
tree_node *d_e = new tree_node('E');
|
||||
tree_node *plus = new tree_node('+');
|
||||
tree_node *d_a = new tree_node('A');
|
||||
tree_node *d_j = new tree_node('J');
|
||||
tree_node *n1 = new tree_node('1');
|
||||
tree_node *n6 = new tree_node('6');
|
||||
tree_node *eq = new tree_node('=');
|
||||
tree_node *slash = new tree_node('/');
|
||||
tree_node *null1 = new tree_node(0);
|
||||
tree_node *n7 = new tree_node('7');
|
||||
tree_node *null2 = new tree_node(0);
|
||||
tree_node *n8 = new tree_node('8');
|
||||
tree_node *n9 = new tree_node('9');
|
||||
tree_node *n0 = new tree_node('0');
|
||||
|
||||
d_root->set_left_child (e);
|
||||
d_root->set_right_child (t);
|
||||
d_root->set_left_child(e);
|
||||
d_root->set_right_child(t);
|
||||
|
||||
e->set_left_child (i);
|
||||
e->set_right_child (a);
|
||||
t->set_left_child (n);
|
||||
t->set_right_child (m);
|
||||
e->set_left_child(i);
|
||||
e->set_right_child(a);
|
||||
t->set_left_child(n);
|
||||
t->set_right_child(m);
|
||||
|
||||
i->set_left_child (s);
|
||||
i->set_right_child (u);
|
||||
a->set_left_child (r);
|
||||
a->set_right_child (w);
|
||||
n->set_left_child (d);
|
||||
n->set_right_child (k);
|
||||
m->set_left_child (g);
|
||||
m->set_right_child (o);
|
||||
i->set_left_child(s);
|
||||
i->set_right_child(u);
|
||||
a->set_left_child(r);
|
||||
a->set_right_child(w);
|
||||
n->set_left_child(d);
|
||||
n->set_right_child(k);
|
||||
m->set_left_child(g);
|
||||
m->set_right_child(o);
|
||||
|
||||
s->set_left_child (h);
|
||||
s->set_right_child (v);
|
||||
u->set_left_child (f);
|
||||
u->set_right_child (u_u);
|
||||
r->set_left_child (l);
|
||||
r->set_right_child (u_a);
|
||||
w->set_left_child (p);
|
||||
w->set_right_child (j);
|
||||
d->set_left_child (b);
|
||||
d->set_right_child (x);
|
||||
k->set_left_child (c);
|
||||
k->set_right_child (y);
|
||||
g->set_left_child (z);
|
||||
g->set_right_child (q);
|
||||
o->set_left_child (u_o);
|
||||
o->set_right_child (null0);
|
||||
s->set_left_child(h);
|
||||
s->set_right_child(v);
|
||||
u->set_left_child(f);
|
||||
u->set_right_child(u_u);
|
||||
r->set_left_child(l);
|
||||
r->set_right_child(u_a);
|
||||
w->set_left_child(p);
|
||||
w->set_right_child(j);
|
||||
d->set_left_child(b);
|
||||
d->set_right_child(x);
|
||||
k->set_left_child(c);
|
||||
k->set_right_child(y);
|
||||
g->set_left_child(z);
|
||||
g->set_right_child(q);
|
||||
o->set_left_child(u_o);
|
||||
o->set_right_child(null0);
|
||||
|
||||
h->set_left_child (n5);
|
||||
h->set_right_child (n4);
|
||||
v->set_left_child (a_s);
|
||||
v->set_right_child (n3);
|
||||
f->set_left_child (a_e);
|
||||
u_u->set_left_child (d_d);
|
||||
u_u->set_right_child (n2);
|
||||
l->set_right_child (d_e);
|
||||
u_a->set_left_child (plus);
|
||||
p->set_right_child (d_a);
|
||||
j->set_left_child (d_j);
|
||||
j->set_right_child (n1);
|
||||
b->set_left_child (n6);
|
||||
b->set_right_child (eq);
|
||||
x->set_left_child (slash);
|
||||
c->set_right_child (null1);
|
||||
z->set_left_child (n7);
|
||||
z->set_right_child (null2);
|
||||
u_o->set_left_child (n8);
|
||||
null0->set_left_child (n9);
|
||||
null0->set_right_child (n0);
|
||||
}
|
||||
h->set_left_child(n5);
|
||||
h->set_right_child(n4);
|
||||
v->set_left_child(a_s);
|
||||
v->set_right_child(n3);
|
||||
f->set_left_child(a_e);
|
||||
u_u->set_left_child(d_d);
|
||||
u_u->set_right_child(n2);
|
||||
l->set_right_child(d_e);
|
||||
u_a->set_left_child(plus);
|
||||
p->set_right_child(d_a);
|
||||
j->set_left_child(d_j);
|
||||
j->set_right_child(n1);
|
||||
b->set_left_child(n6);
|
||||
b->set_right_child(eq);
|
||||
x->set_left_child(slash);
|
||||
c->set_right_child(null1);
|
||||
z->set_left_child(n7);
|
||||
z->set_right_child(null2);
|
||||
u_o->set_left_child(n8);
|
||||
null0->set_left_child(n9);
|
||||
null0->set_right_child(n0);
|
||||
}
|
||||
|
||||
bool
|
||||
morse_tree::received_symbol (morse_symbol_t s)
|
||||
{
|
||||
bool
|
||||
morse_tree::received_symbol(morse_symbol_t s)
|
||||
{
|
||||
char c = 0;
|
||||
bool ret = false;
|
||||
/* Check for overflow */
|
||||
if (d_word_len == d_buff_len) {
|
||||
return false;
|
||||
}
|
||||
switch (s)
|
||||
{
|
||||
switch (s) {
|
||||
case MORSE_DOT:
|
||||
if (d_current->get_left_child ()) {
|
||||
d_current = d_current->get_left_child ();
|
||||
if (d_current->get_left_child()) {
|
||||
d_current = d_current->get_left_child();
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
case MORSE_DASH:
|
||||
if (d_current->get_right_child ()) {
|
||||
d_current = d_current->get_right_child ();
|
||||
if (d_current->get_right_child()) {
|
||||
d_current = d_current->get_right_child();
|
||||
ret = true;
|
||||
}
|
||||
break;
|
||||
|
@ -225,7 +222,7 @@ namespace gr
|
|||
if (d_current == d_root) {
|
||||
return true;
|
||||
}
|
||||
c = d_current->get_char ();
|
||||
c = d_current->get_char();
|
||||
d_current = d_root;
|
||||
/*
|
||||
* Some nodes are null transitions and do not correspond to
|
||||
|
@ -242,73 +239,73 @@ namespace gr
|
|||
return false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
morse_tree::get_word ()
|
||||
{
|
||||
std::string
|
||||
morse_tree::get_word()
|
||||
{
|
||||
return std::string(d_word_buffer.get(), d_word_len);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
morse_tree::get_max_word_len () const
|
||||
{
|
||||
size_t
|
||||
morse_tree::get_max_word_len() const
|
||||
{
|
||||
return d_buff_len;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
morse_tree::get_word_len ()
|
||||
{
|
||||
size_t
|
||||
morse_tree::get_word_len()
|
||||
{
|
||||
return d_word_len;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morse_tree::delete_tree (tree_node *node)
|
||||
{
|
||||
void
|
||||
morse_tree::delete_tree(tree_node *node)
|
||||
{
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
delete_tree (node->get_left_child ());
|
||||
delete_tree (node->get_right_child ());
|
||||
delete_tree(node->get_left_child());
|
||||
delete_tree(node->get_right_child());
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
tree_node::tree_node (char c) :
|
||||
d_char (c),
|
||||
d_left (NULL),
|
||||
d_right (NULL)
|
||||
{
|
||||
}
|
||||
tree_node::tree_node(char c) :
|
||||
d_char(c),
|
||||
d_left(NULL),
|
||||
d_right(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
tree_node::set_left_child (tree_node* child)
|
||||
{
|
||||
void
|
||||
tree_node::set_left_child(tree_node *child)
|
||||
{
|
||||
d_left = child;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tree_node::set_right_child (tree_node* child)
|
||||
{
|
||||
void
|
||||
tree_node::set_right_child(tree_node *child)
|
||||
{
|
||||
d_right = child;
|
||||
}
|
||||
}
|
||||
|
||||
tree_node*
|
||||
tree_node::get_left_child ()
|
||||
{
|
||||
tree_node *
|
||||
tree_node::get_left_child()
|
||||
{
|
||||
return d_left;
|
||||
}
|
||||
}
|
||||
|
||||
tree_node*
|
||||
tree_node::get_right_child ()
|
||||
{
|
||||
tree_node *
|
||||
tree_node::get_right_child()
|
||||
{
|
||||
return d_right;
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
tree_node::get_char ()
|
||||
{
|
||||
char
|
||||
tree_node::get_char()
|
||||
{
|
||||
return d_char;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -28,53 +28,50 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
multi_format_msg_sink::sptr
|
||||
multi_format_msg_sink::make (size_t format,
|
||||
multi_format_msg_sink::sptr
|
||||
multi_format_msg_sink::make(size_t format,
|
||||
bool timestamp,
|
||||
bool out_stdout,
|
||||
const std::string& filepath)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new multi_format_msg_sink_impl (format, timestamp,
|
||||
const std::string &filepath)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new multi_format_msg_sink_impl(format, timestamp,
|
||||
out_stdout, filepath));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
multi_format_msg_sink_impl::msg_handler_file (pmt::pmt_t msg)
|
||||
{
|
||||
void
|
||||
multi_format_msg_sink_impl::msg_handler_file(pmt::pmt_t msg)
|
||||
{
|
||||
uint8_t *su;
|
||||
char buf[256];
|
||||
std::string s ((const char *) pmt::blob_data (msg),
|
||||
pmt::blob_length (msg));
|
||||
std::string s((const char *) pmt::blob_data(msg),
|
||||
pmt::blob_length(msg));
|
||||
|
||||
if(d_timestamp) {
|
||||
if (d_timestamp) {
|
||||
std::time_t t = std::time(nullptr);
|
||||
std::tm tm = *std::localtime(&t);
|
||||
strftime(buf, sizeof(buf), "%F %T %z", &tm);
|
||||
d_fos << "[" << buf << "]";
|
||||
}
|
||||
|
||||
switch (d_format)
|
||||
{
|
||||
switch (d_format) {
|
||||
case 0:
|
||||
d_fos << s << std::endl;
|
||||
break;
|
||||
case 1:
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
d_fos << "0x" << std::hex << std::setw (2) << std::setfill ('0')
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
d_fos << "0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (uint32_t) su[i] << " ";
|
||||
}
|
||||
d_fos << std::endl;
|
||||
break;
|
||||
case 2:
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
d_fos << "0b" << std::bitset<8> (su[i]) << " ";
|
||||
}
|
||||
d_fos << std::endl;
|
||||
|
@ -82,42 +79,41 @@ namespace gr
|
|||
default:
|
||||
throw std::invalid_argument("Invalid format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
multi_format_msg_sink_impl::msg_handler_stdout (pmt::pmt_t msg)
|
||||
{
|
||||
void
|
||||
multi_format_msg_sink_impl::msg_handler_stdout(pmt::pmt_t msg)
|
||||
{
|
||||
uint8_t *su;
|
||||
char buf[256];
|
||||
std::string s ((const char *) pmt::blob_data (msg),
|
||||
pmt::blob_length (msg));
|
||||
std::string s((const char *) pmt::blob_data(msg),
|
||||
pmt::blob_length(msg));
|
||||
|
||||
if(d_timestamp) {
|
||||
if (d_timestamp) {
|
||||
std::time_t t = std::time(nullptr);
|
||||
std::tm tm = *std::localtime(&t);
|
||||
strftime(buf, sizeof(buf), "%F %T %z", &tm);
|
||||
std::cout << "[" << buf << "]";
|
||||
}
|
||||
|
||||
switch (d_format)
|
||||
{
|
||||
switch (d_format) {
|
||||
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 << std::endl;
|
||||
break;
|
||||
case 1: // hex annotated
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
std::cout << "0x" << std::hex << std::setw (2) << std::setfill ('0')
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< (uint32_t) su[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
break;
|
||||
case 2: // binary annotated
|
||||
su = (uint8_t *) pmt::blob_data (msg);
|
||||
for (size_t i = 0; i < pmt::blob_length (msg); i++) {
|
||||
su = (uint8_t *) pmt::blob_data(msg);
|
||||
for (size_t i = 0; i < pmt::blob_length(msg); i++) {
|
||||
std::cout << "0b" << std::bitset<8> (su[i]) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
@ -125,44 +121,44 @@ namespace gr
|
|||
default:
|
||||
throw std::invalid_argument("Invalid format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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,
|
||||
const std::string& filepath) :
|
||||
gr::block ("multi_format_msg_sink",
|
||||
gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_format (format),
|
||||
d_timestamp (timestamp),
|
||||
d_stdout (out_stdout)
|
||||
{
|
||||
message_port_register_in (pmt::mp ("in"));
|
||||
if(out_stdout) {
|
||||
set_msg_handler (
|
||||
pmt::mp ("in"),
|
||||
boost::bind (&multi_format_msg_sink_impl::msg_handler_stdout,
|
||||
const std::string &filepath) :
|
||||
gr::block("multi_format_msg_sink",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_format(format),
|
||||
d_timestamp(timestamp),
|
||||
d_stdout(out_stdout)
|
||||
{
|
||||
message_port_register_in(pmt::mp("in"));
|
||||
if (out_stdout) {
|
||||
set_msg_handler(
|
||||
pmt::mp("in"),
|
||||
boost::bind(&multi_format_msg_sink_impl::msg_handler_stdout,
|
||||
this, _1));
|
||||
}
|
||||
else{
|
||||
else {
|
||||
d_fos.open(filepath);
|
||||
set_msg_handler (
|
||||
pmt::mp ("in"),
|
||||
boost::bind (&multi_format_msg_sink_impl::msg_handler_file,
|
||||
set_msg_handler(
|
||||
pmt::mp("in"),
|
||||
boost::bind(&multi_format_msg_sink_impl::msg_handler_file,
|
||||
this, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
multi_format_msg_sink_impl::~multi_format_msg_sink_impl ()
|
||||
{
|
||||
if(!d_stdout) {
|
||||
multi_format_msg_sink_impl::~multi_format_msg_sink_impl()
|
||||
{
|
||||
if (!d_stdout) {
|
||||
d_fos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -24,33 +24,30 @@
|
|||
#include <satnogs/multi_format_msg_sink.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class multi_format_msg_sink_impl : public multi_format_msg_sink
|
||||
{
|
||||
private:
|
||||
class multi_format_msg_sink_impl : public multi_format_msg_sink {
|
||||
private:
|
||||
void
|
||||
msg_handler_stdout (pmt::pmt_t msg);
|
||||
msg_handler_stdout(pmt::pmt_t msg);
|
||||
void
|
||||
msg_handler_file (pmt::pmt_t msg);
|
||||
msg_handler_file(pmt::pmt_t msg);
|
||||
|
||||
const size_t d_format;
|
||||
const bool d_timestamp;
|
||||
const bool d_stdout;
|
||||
std::ofstream d_fos;
|
||||
|
||||
public:
|
||||
multi_format_msg_sink_impl (size_t format, bool timestamp,
|
||||
bool out_stdout, const std::string& filepath);
|
||||
public:
|
||||
multi_format_msg_sink_impl(size_t format, bool timestamp,
|
||||
bool out_stdout, const std::string &filepath);
|
||||
|
||||
~multi_format_msg_sink_impl ();
|
||||
~multi_format_msg_sink_impl();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_multi_format_MSG_SINK_IMPL_H */
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
// Noaa apt sync pattern A
|
||||
// (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
|
||||
const bool noaa_apt_sink_impl::synca_seq[] = {false, false, false, false,
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
// Noaa apt sync pattern A
|
||||
// (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 2
|
||||
true, true, false, false, // Pulse 3
|
||||
|
@ -42,11 +40,12 @@ namespace gr
|
|||
true, true, false, false, // Pulse 6
|
||||
true, true, false, false, // Pulse 7
|
||||
false, false, false, false,
|
||||
false, false, false, false};
|
||||
false, false, false, false
|
||||
};
|
||||
|
||||
// Noaa apt sync pattern B
|
||||
// (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
|
||||
const bool noaa_apt_sink_impl::syncb_seq[] = {false, false, false, false,
|
||||
// Noaa apt sync pattern B
|
||||
// (see https://sourceforge.isae.fr/attachments/download/1813/apt_synch.gif)
|
||||
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,
|
||||
|
@ -54,55 +53,56 @@ namespace gr
|
|||
true, true, true, false, false,
|
||||
true, true, true, false, false,
|
||||
true, true, true, false, false,
|
||||
false};
|
||||
false
|
||||
};
|
||||
|
||||
|
||||
|
||||
noaa_apt_sink::sptr
|
||||
noaa_apt_sink::make (const char *filename_png, size_t width, size_t height,
|
||||
noaa_apt_sink::sptr
|
||||
noaa_apt_sink::make(const char *filename_png, size_t width, size_t height,
|
||||
bool sync, bool flip)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new noaa_apt_sink_impl (filename_png, width, height, sync,
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new noaa_apt_sink_impl(filename_png, width, height, sync,
|
||||
flip));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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,
|
||||
bool sync, bool flip) :
|
||||
gr::sync_block ("noaa_apt_sink",
|
||||
gr::io_signature::make (1, 1, sizeof(float)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
f_average_alpha (0.25),
|
||||
d_filename_png (filename_png),
|
||||
d_width (width),
|
||||
d_height (height),
|
||||
d_synchronize_opt (sync),
|
||||
d_flip (flip),
|
||||
d_history_length (40),
|
||||
d_has_sync (false),
|
||||
gr::sync_block("noaa_apt_sink",
|
||||
gr::io_signature::make(1, 1, sizeof(float)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
f_average_alpha(0.25),
|
||||
d_filename_png(filename_png),
|
||||
d_width(width),
|
||||
d_height(height),
|
||||
d_synchronize_opt(sync),
|
||||
d_flip(flip),
|
||||
d_history_length(40),
|
||||
d_has_sync(false),
|
||||
d_image_received(false),
|
||||
d_current_x (0),
|
||||
d_current_y (0),
|
||||
d_num_images (0),
|
||||
d_current_x(0),
|
||||
d_current_y(0),
|
||||
d_num_images(0),
|
||||
f_max_level(0.0),
|
||||
f_min_level(1.0),
|
||||
f_average(0.0)
|
||||
{
|
||||
{
|
||||
set_history(d_history_length);
|
||||
d_full_image = png::image<png::gray_pixel>(d_width, d_height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
noaa_apt_sink_impl::write_image (png::image<png::gray_pixel> image,
|
||||
void
|
||||
noaa_apt_sink_impl::write_image(png::image<png::gray_pixel> image,
|
||||
std::string filename)
|
||||
{
|
||||
{
|
||||
// In case the flip option is set
|
||||
if(d_flip) {
|
||||
if (d_flip) {
|
||||
size_t width = image.get_width();
|
||||
size_t height = image.get_height();
|
||||
|
||||
|
@ -110,8 +110,8 @@ namespace gr
|
|||
png::image<png::gray_pixel> flipped(width, height);
|
||||
|
||||
// ... and all the lines are copied over reverse order
|
||||
for(size_t y = 0; y < height; y++) {
|
||||
for(size_t x = 0; x < width; x++) {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
png::gray_pixel pixel = image.get_pixel(x, height - y - 1);
|
||||
flipped.set_pixel(x, y, pixel);
|
||||
}
|
||||
|
@ -124,22 +124,25 @@ namespace gr
|
|||
// Write out the original
|
||||
image.write(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
noaa_apt_sink_impl::~noaa_apt_sink_impl () {
|
||||
noaa_apt_sink_impl::~noaa_apt_sink_impl()
|
||||
{
|
||||
|
||||
}
|
||||
bool
|
||||
noaa_apt_sink_impl::stop(){
|
||||
if(!d_image_received){
|
||||
}
|
||||
bool
|
||||
noaa_apt_sink_impl::stop()
|
||||
{
|
||||
if (!d_image_received) {
|
||||
write_image(d_full_image, d_filename_png);
|
||||
}
|
||||
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
|
||||
if(std::isnan(sample)) {
|
||||
if (std::isnan(sample)) {
|
||||
sample = 0.0;
|
||||
}
|
||||
|
||||
|
@ -147,32 +150,34 @@ namespace gr
|
|||
sample = (sample - f_min_level) / (f_max_level - f_min_level) * 255;
|
||||
// Set the pixel in the full image
|
||||
d_full_image.set_pixel(x, y, sample);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
noaa_apt_sink_impl::skip_to (size_t new_x, size_t pos, const float *samples) {
|
||||
void
|
||||
noaa_apt_sink_impl::skip_to(size_t new_x, size_t pos, const float *samples)
|
||||
{
|
||||
// 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 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);
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
// Jump to new location
|
||||
d_current_x = new_x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
noaa_apt_sync_marker
|
||||
noaa_apt_sink_impl::is_marker(size_t pos, const float *samples) {
|
||||
noaa_apt_sync_marker
|
||||
noaa_apt_sink_impl::is_marker(size_t pos, const float *samples)
|
||||
{
|
||||
// Initialize counters for 'hacky' correlation
|
||||
size_t count_a = 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
|
||||
// -> start 39 samples in the past
|
||||
float sample = samples[pos - 39 + i];
|
||||
|
@ -180,35 +185,35 @@ namespace gr
|
|||
sample = sample - f_average;
|
||||
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
else if(count_b > 35) {
|
||||
else if (count_b > 35) {
|
||||
return noaa_apt_sync_marker::SYNC_B;
|
||||
}
|
||||
else {
|
||||
return noaa_apt_sync_marker::NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
noaa_apt_sink_impl::work (int noutput_items,
|
||||
int
|
||||
noaa_apt_sink_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
const float *in = (const float *) input_items[0];
|
||||
/* If we have already produced one image, ignore the remaining observation*/
|
||||
if(d_image_received){
|
||||
if (d_image_received) {
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
|
@ -222,7 +227,7 @@ namespace gr
|
|||
float sample = in[i];
|
||||
|
||||
// For some reason the first sample on a Raspberry Pi can be NaN
|
||||
if(std::isnan(sample)) {
|
||||
if (std::isnan(sample)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -234,27 +239,27 @@ namespace gr
|
|||
f_average = f_average_alpha * sample + (1.0 - f_average_alpha) * f_average;
|
||||
|
||||
// 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
|
||||
noaa_apt_sync_marker marker = is_marker(i, in);
|
||||
|
||||
// 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(39, i, in);
|
||||
// If this is the first sync, reset min and max
|
||||
if(!d_has_sync) {
|
||||
if (!d_has_sync) {
|
||||
f_max_level = 0.0;
|
||||
f_min_level = 1.0;
|
||||
d_has_sync = true;
|
||||
}
|
||||
}
|
||||
// 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(d_width / 2 + 39, i, in);
|
||||
// If this is the first sync, reset min and max
|
||||
if(!d_has_sync) {
|
||||
if (!d_has_sync) {
|
||||
f_max_level = 0.0;
|
||||
f_min_level = 1.0;
|
||||
d_has_sync = true;
|
||||
|
@ -268,14 +273,14 @@ namespace gr
|
|||
// Increment x position
|
||||
d_current_x += 1;
|
||||
// If we are beyond the end of line
|
||||
if(d_current_x >= d_width) {
|
||||
if (d_current_x >= d_width) {
|
||||
// Increment y position
|
||||
d_current_y += 1;
|
||||
// Reset x position to line start
|
||||
d_current_x = 0;
|
||||
|
||||
// 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_num_images += 1;
|
||||
// Write out the full image
|
||||
|
@ -287,7 +292,7 @@ namespace gr
|
|||
|
||||
// Tell gnu radio how many samples were consumed
|
||||
return noutput_items;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -28,15 +28,12 @@
|
|||
|
||||
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
enum class noaa_apt_sync_marker {SYNC_A, SYNC_B, NONE};
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
enum class noaa_apt_sync_marker {SYNC_A, SYNC_B, NONE};
|
||||
|
||||
class noaa_apt_sink_impl : public noaa_apt_sink
|
||||
{
|
||||
private:
|
||||
class noaa_apt_sink_impl : public noaa_apt_sink {
|
||||
private:
|
||||
// Factor exponential smoothing average,
|
||||
// which is used for sync pattern detection
|
||||
const float f_average_alpha;
|
||||
|
@ -67,44 +64,44 @@ namespace gr
|
|||
float f_min_level;
|
||||
float f_average;
|
||||
|
||||
public:
|
||||
noaa_apt_sink_impl (const char *filename_png, size_t width, size_t height,
|
||||
public:
|
||||
noaa_apt_sink_impl(const char *filename_png, size_t width, size_t height,
|
||||
bool sync, bool flip);
|
||||
~noaa_apt_sink_impl ();
|
||||
~noaa_apt_sink_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
|
||||
bool
|
||||
stop();
|
||||
private:
|
||||
private:
|
||||
|
||||
/*
|
||||
* Checks if the history portion of the input contains a sync marker.
|
||||
* Matches the 40 samples before pos against the patterns.
|
||||
*/
|
||||
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)
|
||||
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,
|
||||
* while using historical samples to fill any resulting gaps in the images.
|
||||
*/
|
||||
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
|
||||
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
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_NOAA_APT_SINK_IMPL_H */
|
||||
|
|
|
@ -31,107 +31,109 @@
|
|||
#include <time.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
|
||||
*/
|
||||
ogg_encoder_impl::ogg_encoder_impl (char* filename, double samp_rate,
|
||||
ogg_encoder_impl::ogg_encoder_impl(char *filename, double samp_rate,
|
||||
float quality) :
|
||||
gr::sync_block ("ogg_encoder",
|
||||
gr::io_signature::make (1, 1, sizeof(float)),
|
||||
gr::io_signature::make (0, 0, 0))
|
||||
{
|
||||
gr::sync_block("ogg_encoder",
|
||||
gr::io_signature::make(1, 1, sizeof(float)),
|
||||
gr::io_signature::make(0, 0, 0))
|
||||
{
|
||||
d_quality = quality;
|
||||
d_out = fopen (filename, "wb");
|
||||
d_out = fopen(filename, "wb");
|
||||
d_samp_rate = samp_rate;
|
||||
vorbis_info_init (&d_vi);
|
||||
int ret = vorbis_encode_init_vbr (&d_vi, 1, d_samp_rate, d_quality);
|
||||
if (ret)
|
||||
exit (1);
|
||||
vorbis_info_init(&d_vi);
|
||||
int ret = vorbis_encode_init_vbr(&d_vi, 1, d_samp_rate, d_quality);
|
||||
if (ret) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vorbis_comment_init (&d_vc);
|
||||
vorbis_comment_add_tag (&d_vc, "ENCODER", "satnogs ogg encoder");
|
||||
vorbis_comment_init(&d_vc);
|
||||
vorbis_comment_add_tag(&d_vc, "ENCODER", "satnogs ogg encoder");
|
||||
|
||||
vorbis_analysis_init (&d_vd, &d_vi);
|
||||
vorbis_block_init (&d_vd, &d_vb);
|
||||
vorbis_analysis_init(&d_vd, &d_vi);
|
||||
vorbis_block_init(&d_vd, &d_vb);
|
||||
|
||||
srand (time (NULL));
|
||||
ogg_stream_init (&d_os, rand ());
|
||||
srand(time(NULL));
|
||||
ogg_stream_init(&d_os, rand());
|
||||
|
||||
ogg_packet header;
|
||||
ogg_packet header_comm;
|
||||
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);
|
||||
ogg_stream_packetin (&d_os, &header);
|
||||
ogg_stream_packetin (&d_os, &header_comm);
|
||||
ogg_stream_packetin (&d_os, &header_code);
|
||||
ogg_stream_packetin(&d_os, &header);
|
||||
ogg_stream_packetin(&d_os, &header_comm);
|
||||
ogg_stream_packetin(&d_os, &header_code);
|
||||
int result = 1;
|
||||
while (result) {
|
||||
result = ogg_stream_flush (&d_os, &d_og);
|
||||
if (result == 0)
|
||||
result = ogg_stream_flush(&d_os, &d_og);
|
||||
if (result == 0) {
|
||||
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 ()
|
||||
{
|
||||
vorbis_analysis_wrote (&d_vd, 0);
|
||||
ogg_stream_clear (&d_os);
|
||||
vorbis_block_clear (&d_vb);
|
||||
vorbis_dsp_clear (&d_vd);
|
||||
vorbis_comment_clear (&d_vc);
|
||||
vorbis_info_clear (&d_vi);
|
||||
fclose (d_out);
|
||||
}
|
||||
ogg_encoder_impl::~ogg_encoder_impl()
|
||||
{
|
||||
vorbis_analysis_wrote(&d_vd, 0);
|
||||
ogg_stream_clear(&d_os);
|
||||
vorbis_block_clear(&d_vb);
|
||||
vorbis_dsp_clear(&d_vd);
|
||||
vorbis_comment_clear(&d_vc);
|
||||
vorbis_info_clear(&d_vi);
|
||||
fclose(d_out);
|
||||
}
|
||||
|
||||
int
|
||||
ogg_encoder_impl::work (int noutput_items,
|
||||
int
|
||||
ogg_encoder_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
const char *in = (const char *) input_items[0];
|
||||
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));
|
||||
|
||||
vorbis_analysis_wrote (&d_vd, noutput_items);
|
||||
vorbis_analysis_wrote(&d_vd, noutput_items);
|
||||
|
||||
while (vorbis_analysis_blockout (&d_vd, &d_vb) == 1) {
|
||||
vorbis_analysis (&d_vb, NULL);
|
||||
vorbis_bitrate_addblock (&d_vb);
|
||||
while (vorbis_analysis_blockout(&d_vd, &d_vb) == 1) {
|
||||
vorbis_analysis(&d_vb, NULL);
|
||||
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;
|
||||
while (result) {
|
||||
int result = ogg_stream_pageout (&d_os, &d_og);
|
||||
if (result == 0)
|
||||
int result = ogg_stream_pageout(&d_os, &d_og);
|
||||
if (result == 0) {
|
||||
break;
|
||||
fwrite (d_og.header, 1, d_og.header_len, d_out);
|
||||
fwrite (d_og.body, 1, d_og.body_len, d_out);
|
||||
if (ogg_page_eos (&d_og))
|
||||
}
|
||||
fwrite(d_og.header, 1, d_og.header_len, d_out);
|
||||
fwrite(d_og.body, 1, d_og.body_len, d_out);
|
||||
if (ogg_page_eos(&d_og)) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return noutput_items;
|
||||
}
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -24,14 +24,11 @@
|
|||
#include <satnogs/ogg_encoder.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class ogg_encoder_impl : public ogg_encoder
|
||||
{
|
||||
private:
|
||||
class ogg_encoder_impl : public ogg_encoder {
|
||||
private:
|
||||
// Nothing to declare in this block.
|
||||
ogg_stream_state d_os;
|
||||
ogg_page d_og;
|
||||
|
@ -42,21 +39,21 @@ namespace gr
|
|||
|
||||
vorbis_dsp_state d_vd;
|
||||
vorbis_block d_vb;
|
||||
FILE* d_out;
|
||||
FILE *d_out;
|
||||
double d_samp_rate;
|
||||
float d_quality;
|
||||
|
||||
public:
|
||||
ogg_encoder_impl (char* filename, double samp_rate, float quality);
|
||||
~ogg_encoder_impl ();
|
||||
public:
|
||||
ogg_encoder_impl(char *filename, double samp_rate, float quality);
|
||||
~ogg_encoder_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_OGG_ENCODER_IMPL_H */
|
||||
|
|
|
@ -33,88 +33,88 @@
|
|||
#define PCM_BUF_SIZE 4096
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
ogg_source::sptr
|
||||
ogg_source::make (const std::string& filename, int channels, bool repeat)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new ogg_source_impl (filename, channels, repeat));
|
||||
}
|
||||
ogg_source::sptr
|
||||
ogg_source::make(const std::string &filename, int channels, bool repeat)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(
|
||||
new ogg_source_impl(filename, channels, repeat));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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) :
|
||||
gr::sync_block (
|
||||
"ogg_source", gr::io_signature::make (0, 0, 0),
|
||||
gr::io_signature::make (channels, channels, sizeof(float))),
|
||||
d_channels (channels),
|
||||
d_repeat (repeat)
|
||||
{
|
||||
gr::sync_block(
|
||||
"ogg_source", gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(channels, channels, sizeof(float))),
|
||||
d_channels(channels),
|
||||
d_repeat(repeat)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
if (ov_fopen (filename.c_str (), &d_ogvorb_f) < 0) {
|
||||
throw std::invalid_argument ("Invalid .ogg file");
|
||||
if (ov_fopen(filename.c_str(), &d_ogvorb_f) < 0) {
|
||||
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) {
|
||||
throw std::invalid_argument (
|
||||
std::string ("Channels number specified (")
|
||||
+ std::to_string (channels)
|
||||
throw std::invalid_argument(
|
||||
std::string("Channels number specified (")
|
||||
+ std::to_string(channels)
|
||||
+ ") 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);
|
||||
set_alignment (std::max (1, alignment_multiple));
|
||||
set_max_noutput_items (PCM_BUF_SIZE);
|
||||
const int alignment_multiple = volk_get_alignment() / sizeof(float);
|
||||
set_alignment(std::max(1, alignment_multiple));
|
||||
set_max_noutput_items(PCM_BUF_SIZE);
|
||||
|
||||
d_in_buffer = (int16_t *) volk_malloc (PCM_BUF_SIZE * sizeof(int16_t),
|
||||
volk_get_alignment ());
|
||||
d_out_buffer = (float *) volk_malloc (PCM_BUF_SIZE * sizeof(float),
|
||||
volk_get_alignment ());
|
||||
if(!d_in_buffer || !d_out_buffer) {
|
||||
d_in_buffer = (int16_t *) volk_malloc(PCM_BUF_SIZE * sizeof(int16_t),
|
||||
volk_get_alignment());
|
||||
d_out_buffer = (float *) volk_malloc(PCM_BUF_SIZE * sizeof(float),
|
||||
volk_get_alignment());
|
||||
if (!d_in_buffer || !d_out_buffer) {
|
||||
throw std::runtime_error("Could not allocate memory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
ogg_source_impl::~ogg_source_impl()
|
||||
{
|
||||
ogg_source_impl::~ogg_source_impl()
|
||||
{
|
||||
ov_clear(&d_ogvorb_f);
|
||||
volk_free(d_in_buffer);
|
||||
volk_free(d_out_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ogg_source_impl::work(int noutput_items,
|
||||
int
|
||||
ogg_source_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
{
|
||||
long int ret;
|
||||
int section = 0;
|
||||
int available = (noutput_items / d_channels);
|
||||
int available_samples = 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),
|
||||
0, sizeof(int16_t), 1, §ion);
|
||||
if(ret <= 0) {
|
||||
if (ret <= 0) {
|
||||
/*
|
||||
* If return value is EOF and the repeat mode is set seek back to the
|
||||
* start of the ogg stream
|
||||
*/
|
||||
if(ret == 0 && d_repeat) {
|
||||
if(ov_seekable(&d_ogvorb_f)){
|
||||
if (ret == 0 && d_repeat) {
|
||||
if (ov_seekable(&d_ogvorb_f)) {
|
||||
ov_time_seek(&d_ogvorb_f, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -125,19 +125,19 @@ namespace gr {
|
|||
|
||||
available_samples = ret / sizeof(int16_t);
|
||||
/* 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);
|
||||
|
||||
/* De-interleave the available channels */
|
||||
for(int i = 0; i < available_samples; i += d_channels, produced++) {
|
||||
for(int chan = 0; chan < d_channels; chan++){
|
||||
for (int i = 0; i < available_samples; i += d_channels, produced++) {
|
||||
for (int chan = 0; chan < d_channels; chan++) {
|
||||
((float *)output_items[chan])[produced] = d_out_buffer[i * d_channels + chan];
|
||||
}
|
||||
}
|
||||
|
||||
return produced;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
|
|
|
@ -25,14 +25,11 @@
|
|||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
class ogg_source_impl : public ogg_source
|
||||
{
|
||||
private:
|
||||
class ogg_source_impl : public ogg_source {
|
||||
private:
|
||||
const int d_channels;
|
||||
const bool d_repeat;
|
||||
OggVorbis_File d_ogvorb_f;
|
||||
|
@ -40,18 +37,18 @@ namespace gr
|
|||
int16_t *d_in_buffer;
|
||||
float *d_out_buffer;
|
||||
|
||||
public:
|
||||
ogg_source_impl (const std::string& filename, int channels,
|
||||
public:
|
||||
ogg_source_impl(const std::string &filename, int channels,
|
||||
bool repeat);
|
||||
~ogg_source_impl ();
|
||||
~ogg_source_impl();
|
||||
|
||||
// Where all the action really happens
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H */
|
||||
|
|
|
@ -23,13 +23,11 @@
|
|||
#include "qa_ax25_decoder.h"
|
||||
#include <satnogs/ax25_decoder.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
void
|
||||
qa_ax25_decoder::t1 ()
|
||||
qa_ax25_decoder::t1()
|
||||
{
|
||||
// Put test here
|
||||
}
|
||||
|
|
|
@ -25,20 +25,19 @@
|
|||
#include <cppunit/TestCase.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
namespace satnogs {
|
||||
|
||||
class qa_ax25_decoder : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
class qa_ax25_decoder : public CppUnit::TestCase {
|
||||
public:
|
||||
CPPUNIT_TEST_SUITE(qa_ax25_decoder);
|
||||
CPPUNIT_TEST(t1);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
private:
|
||||
void t1();
|
||||
};
|
||||
};
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* _QA_AX25_DECODER_H_ */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue