Start the AX.25 integration into UPSAT FSK framing
This commit is contained in:
parent
e7893a4b98
commit
382e5a615b
|
@ -4,7 +4,7 @@
|
||||||
<key>satnogs_upsat_fsk_frame_acquisition</key>
|
<key>satnogs_upsat_fsk_frame_acquisition</key>
|
||||||
<category>satnogs</category>
|
<category>satnogs</category>
|
||||||
<import>import satnogs</import>
|
<import>import satnogs</import>
|
||||||
<make>satnogs.upsat_fsk_frame_acquisition($preamble, $sync_word, $whitening, $manchester, $check_crc)</make>
|
<make>satnogs.upsat_fsk_frame_acquisition($preamble, $sync_word, $whitening, $manchester, $check_crc, $ax_25)</make>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Frame Preamble</name>
|
<name>Frame Preamble</name>
|
||||||
|
@ -60,6 +60,20 @@
|
||||||
</option>
|
</option>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Use AX.25 encapsulation</name>
|
||||||
|
<key>ax_25</key>
|
||||||
|
<type>enum</type>
|
||||||
|
<option>
|
||||||
|
<name>No</name>
|
||||||
|
<key>False</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Yes</name>
|
||||||
|
<key>True</key>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
|
||||||
<sink>
|
<sink>
|
||||||
<name>in</name>
|
<name>in</name>
|
||||||
<type>float</type>
|
<type>float</type>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<key>satnogs_upsat_fsk_frame_encoder</key>
|
<key>satnogs_upsat_fsk_frame_encoder</key>
|
||||||
<category>satnogs</category>
|
<category>satnogs</category>
|
||||||
<import>import satnogs</import>
|
<import>import satnogs</import>
|
||||||
<make>satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $settling_samples)</make>
|
<make>satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $ax_25, $settling_samples)</make>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Frame Preamble</name>
|
<name>Frame Preamble</name>
|
||||||
|
@ -74,6 +74,20 @@
|
||||||
</option>
|
</option>
|
||||||
</param>
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Use AX.25 encapsulation</name>
|
||||||
|
<key>ax_25</key>
|
||||||
|
<type>enum</type>
|
||||||
|
<option>
|
||||||
|
<name>No</name>
|
||||||
|
<key>False</key>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Yes</name>
|
||||||
|
<key>True</key>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
|
||||||
<param>
|
<param>
|
||||||
<name>Number of zero settling samples</name>
|
<name>Number of zero settling samples</name>
|
||||||
<key>settling_samples</key>
|
<key>settling_samples</key>
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace gr
|
||||||
const uint8_t AX25_SYNC_FLAG = 0x7E;
|
const uint8_t AX25_SYNC_FLAG = 0x7E;
|
||||||
const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
|
const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
|
||||||
const float AX25_SYNC_FLAG_MAP[8] = {-1, 1, 1, 1, 1, 1, 1, -1};
|
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
|
* AX.25 Frame types
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +81,7 @@ namespace gr
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Createst the header field of the AX.25 frame
|
* Creates the header field of the AX.25 frame
|
||||||
* @param out the output buffer with enough memory to hold the address field
|
* @param out the output buffer with enough memory to hold the address field
|
||||||
* @param dest_addr the destination callsign address
|
* @param dest_addr the destination callsign address
|
||||||
* @param dest_ssid the destination SSID
|
* @param dest_ssid the destination SSID
|
||||||
|
@ -172,9 +173,27 @@ namespace gr
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* buffer should be enough, such that the extra stuffed bits are fitting
|
||||||
|
* on the allocated space.
|
||||||
|
*
|
||||||
|
* @param out_len due to bit stuffing the output size can vary. This
|
||||||
|
* pointer will hold the resulting frame size after bit stuffing.
|
||||||
|
*
|
||||||
|
* @param buffer buffer holding the data that should be encoded.
|
||||||
|
* Note that this buffer SHOULD contain the leading and trailing
|
||||||
|
* synchronization flag, all necessary headers and the CRC.
|
||||||
|
*
|
||||||
|
* @param buffer_len the length of the input buffer.
|
||||||
|
*
|
||||||
|
* @return the resulting status of the encoding
|
||||||
|
*/
|
||||||
static inline ax25_encode_status_t
|
static inline ax25_encode_status_t
|
||||||
ax25_nrz_encode(float *out, size_t *out_len,
|
ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer,
|
||||||
const uint8_t *buffer, const size_t buffer_len)
|
const size_t buffer_len)
|
||||||
{
|
{
|
||||||
uint8_t bit;
|
uint8_t bit;
|
||||||
uint8_t prev_bit = 0;
|
uint8_t prev_bit = 0;
|
||||||
|
@ -225,6 +244,77 @@ namespace gr
|
||||||
return AX25_ENC_OK;
|
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
|
||||||
|
* buffer should be enough, such that the extra stuffed bits are fitting
|
||||||
|
* on the allocated space.
|
||||||
|
*
|
||||||
|
* @param out_len due to bit stuffing the output size can vary. This
|
||||||
|
* pointer will hold the resulting frame size after bit stuffing.
|
||||||
|
*
|
||||||
|
* @param buffer buffer holding the data that should be encoded.
|
||||||
|
* Note that this buffer SHOULD contain the leading and trailing
|
||||||
|
* synchronization flag, all necessary headers and the CRC.
|
||||||
|
*
|
||||||
|
* @param buffer_len the length of the input buffer.
|
||||||
|
*
|
||||||
|
* @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,
|
||||||
|
const size_t buffer_len)
|
||||||
|
{
|
||||||
|
uint8_t bit;
|
||||||
|
uint8_t prev_bit = 0;
|
||||||
|
size_t out_idx = 0;
|
||||||
|
size_t bit_idx;
|
||||||
|
size_t cont_1 = 0;
|
||||||
|
size_t total_cont_1 = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Leading FLAG field does not need bit stuffing */
|
||||||
|
memcpy(out, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
|
||||||
|
out_idx = 8;
|
||||||
|
|
||||||
|
/* Skip the leading and trailing FLAG field */
|
||||||
|
buffer++;
|
||||||
|
for(i = 0; i < 8 * (buffer_len - 2); i++){
|
||||||
|
bit = (buffer[i / 8] >> ( i % 8)) & 0x1;
|
||||||
|
out[out_idx++] = bit;
|
||||||
|
|
||||||
|
/* Check if bit stuffing should be applied */
|
||||||
|
if(bit & prev_bit){
|
||||||
|
cont_1++;
|
||||||
|
total_cont_1++;
|
||||||
|
if(cont_1 == 4){
|
||||||
|
out[out_idx++] = 0;
|
||||||
|
cont_1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
cont_1 = total_cont_1 = 0;
|
||||||
|
}
|
||||||
|
prev_bit = bit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the total number of continuous 1's is 15 the the frame should be
|
||||||
|
* dropped
|
||||||
|
*/
|
||||||
|
if(total_cont_1 >= 14) {
|
||||||
|
return AX25_ENC_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Trailing FLAG field does not need bit stuffing */
|
||||||
|
memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
|
||||||
|
out_idx += 8;
|
||||||
|
|
||||||
|
*out_len = out_idx;
|
||||||
|
return AX25_ENC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace satnogs
|
} // namespace satnogs
|
||||||
|
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
|
@ -47,18 +47,28 @@ namespace gr
|
||||||
/*!
|
/*!
|
||||||
* Creates the FSK frame acquisition block for the UPSAT satellite.
|
* Creates the FSK frame acquisition block for the UPSAT satellite.
|
||||||
* @param preamble the bytes that consist the preamble of the frame
|
* @param preamble the bytes that consist the preamble of the frame
|
||||||
|
*
|
||||||
* @param sync_word the byte synchronization word
|
* @param sync_word the byte synchronization word
|
||||||
|
*
|
||||||
* @param whitening true if the transmitted data have been processed by
|
* @param whitening true if the transmitted data have been processed by
|
||||||
* the whitening algorithm of the CC1120 chip. False otherwise.
|
* the whitening algorithm of the CC1120 chip. False otherwise.
|
||||||
|
*
|
||||||
* @param manchester true if the transmitted data have been processed by
|
* @param manchester true if the transmitted data have been processed by
|
||||||
* the Manchester algorithm of the CC1120 chip. False otherwise.
|
* the Manchester algorithm of the CC1120 chip. False otherwise.
|
||||||
|
*
|
||||||
* @param check_crc if set to true the decoder will push frames only if
|
* @param check_crc if set to true the decoder will push frames only if
|
||||||
* their CRC field in correct.
|
* their CRC field in correct.
|
||||||
|
*
|
||||||
|
* @param ax25_format if set to true the frame contains an AX.25
|
||||||
|
* encoded payload. Prior producing the payload, AX.25 decoding
|
||||||
|
* will be performed. If set to false, the payload will be pushed
|
||||||
|
* as it is.
|
||||||
*/
|
*/
|
||||||
static sptr
|
static sptr
|
||||||
make (const std::vector<uint8_t> &preamble,
|
make (const std::vector<uint8_t> &preamble,
|
||||||
const std::vector<uint8_t> &sync_word, bool whitening = false,
|
const std::vector<uint8_t> &sync_word, bool whitening = false,
|
||||||
bool manchester = false, bool check_crc = true);
|
bool manchester = false, bool check_crc = true,
|
||||||
|
bool ax25_format = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace satnogs
|
} // namespace satnogs
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace gr
|
||||||
*
|
*
|
||||||
* @param msb_first if set to true, the the treansmission starts from the
|
* @param msb_first if set to true, the the treansmission starts from the
|
||||||
* MSB of each byte.
|
* MSB of each byte.
|
||||||
|
* @param ax25_format if set to true the frame payload will be encoded
|
||||||
|
* using AX.25 encapsulation.
|
||||||
*
|
*
|
||||||
* @param settling_samples the number of zero samples that the encoder
|
* @param settling_samples the number of zero samples that the encoder
|
||||||
* should append after the end of the FSK frame. This is especially
|
* should append after the end of the FSK frame. This is especially
|
||||||
|
@ -71,6 +73,7 @@ namespace gr
|
||||||
* arbitrary in-out ratio of samples will cause the stream tags to be
|
* arbitrary in-out ratio of samples will cause the stream tags to be
|
||||||
* delivered at the sink block out-of-sync causing the frame transmission
|
* delivered at the sink block out-of-sync causing the frame transmission
|
||||||
* to terminate sooner.
|
* to terminate sooner.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static sptr
|
static sptr
|
||||||
make (const std::vector<uint8_t>& preamble,
|
make (const std::vector<uint8_t>& preamble,
|
||||||
|
@ -78,6 +81,7 @@ namespace gr
|
||||||
bool append_crc = true,
|
bool append_crc = true,
|
||||||
bool whitening = false, bool manchester = false,
|
bool whitening = false, bool manchester = false,
|
||||||
bool msb_first = true,
|
bool msb_first = true,
|
||||||
|
bool ax25_format = false,
|
||||||
size_t settling_samples = 64);
|
size_t settling_samples = 64);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace gr
|
||||||
/* Prepare and encode the AX.25 frame */
|
/* Prepare and encode the AX.25 frame */
|
||||||
len = ax25_prepare_frame (d_tmp_buf, info, info_len, AX25_I_FRAME,
|
len = ax25_prepare_frame (d_tmp_buf, info, info_len, AX25_I_FRAME,
|
||||||
d_addr_field, d_addr_len, 0, 1);
|
d_addr_field, d_addr_len, 0, 1);
|
||||||
status = ax25_nrz_encode(d_endoded_frame, &d_remaining, d_tmp_buf,
|
status = ax25_nrz_bit_stuffing(d_endoded_frame, &d_remaining, d_tmp_buf,
|
||||||
len);
|
len);
|
||||||
if(status != AX25_ENC_OK){
|
if(status != AX25_ENC_OK){
|
||||||
LOG_ERROR("NRZ Encoding failed");
|
LOG_ERROR("NRZ Encoding failed");
|
||||||
|
|
|
@ -37,11 +37,13 @@ namespace gr
|
||||||
upsat_fsk_frame_acquisition::make (const std::vector<uint8_t> &preamble,
|
upsat_fsk_frame_acquisition::make (const std::vector<uint8_t> &preamble,
|
||||||
const std::vector<uint8_t> &sync_word,
|
const std::vector<uint8_t> &sync_word,
|
||||||
bool whitening, bool manchester,
|
bool whitening, bool manchester,
|
||||||
bool check_crc)
|
bool check_crc,
|
||||||
|
bool ax25_format)
|
||||||
{
|
{
|
||||||
return gnuradio::get_initial_sptr (
|
return gnuradio::get_initial_sptr (
|
||||||
new upsat_fsk_frame_acquisition_impl (preamble, sync_word, whitening,
|
new upsat_fsk_frame_acquisition_impl (preamble, sync_word, whitening,
|
||||||
manchester, check_crc));
|
manchester, check_crc,
|
||||||
|
ax25_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -50,7 +52,7 @@ namespace gr
|
||||||
upsat_fsk_frame_acquisition_impl::upsat_fsk_frame_acquisition_impl (
|
upsat_fsk_frame_acquisition_impl::upsat_fsk_frame_acquisition_impl (
|
||||||
const std::vector<uint8_t> &preamble,
|
const std::vector<uint8_t> &preamble,
|
||||||
const std::vector<uint8_t> &sync_word, bool whitening, bool manchester,
|
const std::vector<uint8_t> &sync_word, bool whitening, bool manchester,
|
||||||
bool check_crc) :
|
bool check_crc, bool ax25_format) :
|
||||||
gr::sync_block ("upsat_fsk_frame_acquisition",
|
gr::sync_block ("upsat_fsk_frame_acquisition",
|
||||||
gr::io_signature::make (1, 1, sizeof(float)),
|
gr::io_signature::make (1, 1, sizeof(float)),
|
||||||
gr::io_signature::make (0, 0, 0)),
|
gr::io_signature::make (0, 0, 0)),
|
||||||
|
@ -68,6 +70,7 @@ namespace gr
|
||||||
d_whitening(whitening),
|
d_whitening(whitening),
|
||||||
d_manchester(manchester),
|
d_manchester(manchester),
|
||||||
d_check_crc(check_crc),
|
d_check_crc(check_crc),
|
||||||
|
d_is_ax25(ax25_format),
|
||||||
d_state (SEARCHING),
|
d_state (SEARCHING),
|
||||||
d_shifting_byte (0x0),
|
d_shifting_byte (0x0),
|
||||||
d_decoded_bytes (0),
|
d_decoded_bytes (0),
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace gr
|
||||||
const bool d_whitening;
|
const bool d_whitening;
|
||||||
const bool d_manchester;
|
const bool d_manchester;
|
||||||
const bool d_check_crc;
|
const bool d_check_crc;
|
||||||
|
const bool d_is_ax25;
|
||||||
decoding_state_t d_state;
|
decoding_state_t d_state;
|
||||||
uint8_t d_shifting_byte;
|
uint8_t d_shifting_byte;
|
||||||
size_t d_decoded_bytes;
|
size_t d_decoded_bytes;
|
||||||
|
@ -83,7 +84,8 @@ namespace gr
|
||||||
upsat_fsk_frame_acquisition_impl (const std::vector<uint8_t> &preamble,
|
upsat_fsk_frame_acquisition_impl (const std::vector<uint8_t> &preamble,
|
||||||
const std::vector<uint8_t> &sync_word,
|
const std::vector<uint8_t> &sync_word,
|
||||||
bool whitening, bool manchester,
|
bool whitening, bool manchester,
|
||||||
bool check_crc);
|
bool check_crc,
|
||||||
|
bool ax25_format);
|
||||||
~upsat_fsk_frame_acquisition_impl ();
|
~upsat_fsk_frame_acquisition_impl ();
|
||||||
|
|
||||||
// Where all the action really happens
|
// Where all the action really happens
|
||||||
|
|
|
@ -39,12 +39,14 @@ namespace gr
|
||||||
bool append_crc, bool whitening,
|
bool append_crc, bool whitening,
|
||||||
bool manchester,
|
bool manchester,
|
||||||
bool msb_first,
|
bool msb_first,
|
||||||
|
bool ax25_format,
|
||||||
size_t settling_samples)
|
size_t settling_samples)
|
||||||
{
|
{
|
||||||
return gnuradio::get_initial_sptr (
|
return gnuradio::get_initial_sptr (
|
||||||
new upsat_fsk_frame_encoder_impl (preamble, sync_word,
|
new upsat_fsk_frame_encoder_impl (preamble, sync_word,
|
||||||
append_crc,
|
append_crc,
|
||||||
whitening, manchester, msb_first,
|
whitening, manchester,
|
||||||
|
msb_first, ax25_format,
|
||||||
settling_samples));
|
settling_samples));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +58,7 @@ namespace gr
|
||||||
const std::vector<uint8_t>& sync_word,
|
const std::vector<uint8_t>& sync_word,
|
||||||
bool append_crc, bool whitening,
|
bool append_crc, bool whitening,
|
||||||
bool manchester, bool msb_first,
|
bool manchester, bool msb_first,
|
||||||
|
bool ax25_format,
|
||||||
size_t settling_samples) :
|
size_t settling_samples) :
|
||||||
gr::sync_block ("upsat_fsk_frame_encoder",
|
gr::sync_block ("upsat_fsk_frame_encoder",
|
||||||
gr::io_signature::make (0, 0, 0),
|
gr::io_signature::make (0, 0, 0),
|
||||||
|
@ -68,6 +71,7 @@ namespace gr
|
||||||
d_whitening(whitening),
|
d_whitening(whitening),
|
||||||
d_manchester(manchester),
|
d_manchester(manchester),
|
||||||
d_msb_first(msb_first),
|
d_msb_first(msb_first),
|
||||||
|
d_is_ax25(ax25_format),
|
||||||
d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t)
|
d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t)
|
||||||
+ UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)),
|
+ UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)),
|
||||||
d_settling_samples(settling_samples),
|
d_settling_samples(settling_samples),
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace gr
|
||||||
const bool d_whitening;
|
const bool d_whitening;
|
||||||
const bool d_manchester;
|
const bool d_manchester;
|
||||||
const bool d_msb_first;
|
const bool d_msb_first;
|
||||||
|
const bool d_is_ax25;
|
||||||
const size_t d_max_pdu_len;
|
const size_t d_max_pdu_len;
|
||||||
const size_t d_settling_samples;
|
const size_t d_settling_samples;
|
||||||
size_t d_encoded;
|
size_t d_encoded;
|
||||||
|
@ -63,6 +64,7 @@ namespace gr
|
||||||
bool append_crc, bool whitening,
|
bool append_crc, bool whitening,
|
||||||
bool manchester,
|
bool manchester,
|
||||||
bool msb_first,
|
bool msb_first,
|
||||||
|
bool ax25_format,
|
||||||
size_t settling_samples);
|
size_t settling_samples);
|
||||||
~upsat_fsk_frame_encoder_impl ();
|
~upsat_fsk_frame_encoder_impl ();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue