Start the AX.25 integration into UPSAT FSK framing

This commit is contained in:
Manolis Surligas 2016-04-26 22:21:42 +03:00
parent e7893a4b98
commit 382e5a615b
10 changed files with 155 additions and 12 deletions

View File

@ -4,7 +4,7 @@
<key>satnogs_upsat_fsk_frame_acquisition</key>
<category>satnogs</category>
<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>
<name>Frame Preamble</name>
@ -60,6 +60,20 @@
</option>
</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>
<name>in</name>
<type>float</type>

View File

@ -4,7 +4,7 @@
<key>satnogs_upsat_fsk_frame_encoder</key>
<category>satnogs</category>
<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>
<name>Frame Preamble</name>
@ -74,6 +74,20 @@
</option>
</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>
<name>Number of zero settling samples</name>
<key>settling_samples</key>

View File

@ -36,6 +36,7 @@ namespace gr
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
*/
@ -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 dest_addr the destination callsign address
* @param dest_ssid the destination SSID
@ -172,9 +173,27 @@ namespace gr
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
ax25_nrz_encode(float *out, size_t *out_len,
const uint8_t *buffer, const size_t buffer_len)
ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer,
const size_t buffer_len)
{
uint8_t bit;
uint8_t prev_bit = 0;
@ -225,6 +244,77 @@ namespace gr
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 gr

View File

@ -47,18 +47,28 @@ namespace gr
/*!
* Creates the FSK frame acquisition block for the UPSAT satellite.
* @param preamble the bytes that consist the preamble of the frame
*
* @param sync_word the byte synchronization word
*
* @param whitening true if the transmitted data have been processed by
* the whitening algorithm of the CC1120 chip. False otherwise.
*
* @param manchester true if the transmitted data have been processed by
* the Manchester algorithm of the CC1120 chip. False otherwise.
*
* @param check_crc if set to true the decoder will push frames only if
* 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
make (const std::vector<uint8_t> &preamble,
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

View File

@ -64,6 +64,8 @@ namespace gr
*
* @param msb_first if set to true, the the treansmission starts from the
* 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
* 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
* delivered at the sink block out-of-sync causing the frame transmission
* to terminate sooner.
*
*/
static sptr
make (const std::vector<uint8_t>& preamble,
@ -78,6 +81,7 @@ namespace gr
bool append_crc = true,
bool whitening = false, bool manchester = false,
bool msb_first = true,
bool ax25_format = false,
size_t settling_samples = 64);
};

View File

@ -104,7 +104,7 @@ namespace gr
/* Prepare and encode the AX.25 frame */
len = ax25_prepare_frame (d_tmp_buf, info, info_len, AX25_I_FRAME,
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);
if(status != AX25_ENC_OK){
LOG_ERROR("NRZ Encoding failed");

View File

@ -37,11 +37,13 @@ namespace gr
upsat_fsk_frame_acquisition::make (const std::vector<uint8_t> &preamble,
const std::vector<uint8_t> &sync_word,
bool whitening, bool manchester,
bool check_crc)
bool check_crc,
bool ax25_format)
{
return gnuradio::get_initial_sptr (
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 (
const std::vector<uint8_t> &preamble,
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::io_signature::make (1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)),
@ -68,6 +70,7 @@ namespace gr
d_whitening(whitening),
d_manchester(manchester),
d_check_crc(check_crc),
d_is_ax25(ax25_format),
d_state (SEARCHING),
d_shifting_byte (0x0),
d_decoded_bytes (0),

View File

@ -55,6 +55,7 @@ namespace gr
const bool d_whitening;
const bool d_manchester;
const bool d_check_crc;
const bool d_is_ax25;
decoding_state_t d_state;
uint8_t d_shifting_byte;
size_t d_decoded_bytes;
@ -83,7 +84,8 @@ namespace gr
upsat_fsk_frame_acquisition_impl (const std::vector<uint8_t> &preamble,
const std::vector<uint8_t> &sync_word,
bool whitening, bool manchester,
bool check_crc);
bool check_crc,
bool ax25_format);
~upsat_fsk_frame_acquisition_impl ();
// Where all the action really happens

View File

@ -39,12 +39,14 @@ namespace gr
bool append_crc, bool whitening,
bool manchester,
bool msb_first,
bool ax25_format,
size_t settling_samples)
{
return gnuradio::get_initial_sptr (
new upsat_fsk_frame_encoder_impl (preamble, sync_word,
append_crc,
whitening, manchester, msb_first,
whitening, manchester,
msb_first, ax25_format,
settling_samples));
}
@ -56,6 +58,7 @@ namespace gr
const std::vector<uint8_t>& sync_word,
bool append_crc, bool whitening,
bool manchester, bool msb_first,
bool ax25_format,
size_t settling_samples) :
gr::sync_block ("upsat_fsk_frame_encoder",
gr::io_signature::make (0, 0, 0),
@ -68,6 +71,7 @@ namespace gr
d_whitening(whitening),
d_manchester(manchester),
d_msb_first(msb_first),
d_is_ax25(ax25_format),
d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t)
+ UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)),
d_settling_samples(settling_samples),

View File

@ -40,6 +40,7 @@ namespace gr
const bool d_whitening;
const bool d_manchester;
const bool d_msb_first;
const bool d_is_ax25;
const size_t d_max_pdu_len;
const size_t d_settling_samples;
size_t d_encoded;
@ -63,6 +64,7 @@ namespace gr
bool append_crc, bool whitening,
bool manchester,
bool msb_first,
bool ax25_format,
size_t settling_samples);
~upsat_fsk_frame_encoder_impl ();