diff --git a/apps/flowgraphs/upsat_afsk_transmitter.grc b/apps/flowgraphs/upsat_afsk_transmitter.grc index bd916ca..7c2f3d4 100644 --- a/apps/flowgraphs/upsat_afsk_transmitter.grc +++ b/apps/flowgraphs/upsat_afsk_transmitter.grc @@ -133,7 +133,7 @@ stop - 0.9 + 1 rangeType @@ -171,6 +171,60 @@ 1200 + + variable + + comment + + + + _enabled + True + + + _coordinate + (0, 194) + + + _rotation + 0 + + + id + gaussian_taps + + + value + filter.firdes.gaussian(1.0, samples_per_symbol_tx, 1.0, 4*samples_per_symbol_tx) + + + + variable + + comment + + + + _enabled + 1 + + + _coordinate + (0, 322) + + + _rotation + 0 + + + id + interp_taps + + + value + numpy.convolve(numpy.array(gaussian_taps), numpy.array(sq_wave)) + + variable @@ -226,6 +280,33 @@ TX sampling rate 48e3 + + variable + + comment + + + + _enabled + True + + + _coordinate + (512, 18) + + + _rotation + 0 + + + id + samples_per_symbol_tx + + + value + 40 + + variable @@ -253,6 +334,33 @@ TX sampling rate 1200.0 + + variable + + comment + + + + _enabled + 1 + + + _coordinate + (0, 258) + + + _rotation + 0 + + + id + sq_wave + + + value + (1.0, ) * samples_per_symbol_tx + + variable @@ -329,58 +437,7 @@ TX sampling rate - blocks_add_const_vxx - - alias - - - - comment - Bring the signal in the range of [0, 2] - - - const - 1.0 - - - affinity - - - - _enabled - True - - - _coordinate - (712, 242) - - - _rotation - 0 - - - id - blocks_add_const_vxx_0 - - - type - float - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - vlen - 1 - - - - blocks_float_to_int + audio_source alias @@ -393,13 +450,17 @@ TX sampling rate affinity + + device_name + + _enabled - True + 0 _coordinate - (1184, 242) + (872, 504) _rotation @@ -407,7 +468,7 @@ TX sampling rate id - blocks_float_to_int_0 + audio_source_0 maxoutbuf @@ -418,220 +479,20 @@ TX sampling rate 0 - scale + num_outputs 1 - vlen - 1 - - - - blocks_multiply_const_vxx - - alias - - - - comment - Bring the signal in the range [0, 1] - - - const - 0.5 - - - affinity - - - - _enabled + ok_to_block True - - _coordinate - (960, 242) - - - _rotation - 0 - - - id - blocks_multiply_const_vxx_1 - - - type - float - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - vlen - 1 - - - - blocks_multiply_const_vxx - - alias - - - - comment - - - - const - 1-atten - - - affinity - - - - _enabled - True - - - _coordinate - (976, 370) - - - _rotation - 180 - - - id - blocks_multiply_const_vxx_1_0 - - - type - float - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - vlen - 1 - - - - blocks_repeat - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (1392, 242) - - - _rotation - 0 - - - id - blocks_repeat_0 - - - interp - int(samp_rate_tx/baud_rate) - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - type - int - - - vlen - 1 - - - - blocks_vco_f - - amplitude - 0.1 - - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (1152, 354) - - - _rotation - 180 - - - id - blocks_vco_f_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - samp_rate - samp_rate_tx - - - sensitivity - space_freq * 2.0*math.pi + 48000 - digital_chunks_to_symbols_xx + blocks_multiply_const_vxx alias @@ -641,12 +502,12 @@ TX sampling rate - affinity - + const + 1.0-atten - dimension - 1 + affinity + _enabled @@ -654,19 +515,19 @@ TX sampling rate _coordinate - (1384, 362) + (904, 242) _rotation - 180 + 0 id - digital_chunks_to_symbols_xx_0 + blocks_multiply_const_vxx_0 - in_type - int + type + float maxoutbuf @@ -677,17 +538,9 @@ TX sampling rate 0 - num_ports + vlen 1 - - out_type - float - - - symbol_table - [mark_freq/space_freq, 1] - import @@ -721,34 +574,76 @@ TX sampling rate - qtgui_freq_sink_x - - autoscale - False - - - average - 1.0 - - - bw - 48e3 - + import alias - - fc - 0 - comment - ctrlpanel - False + _enabled + True + + + _coordinate + (16, 402) + + + _rotation + 0 + + + id + import_1 + + + import + from gnuradio import filter + + + + import + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (16, 458) + + + _rotation + 0 + + + id + import_2 + + + import + import numpy + + + + interp_fir_filter_xxx + + alias + + + + comment + affinity @@ -756,195 +651,23 @@ TX sampling rate _enabled - 0 - - - fftsize - 1024 + 1 _coordinate - (1072, 102) - - - gui_hint - + (672, 234) _rotation - 180 - - - grid - False + 0 id - qtgui_freq_sink_x_0 + interp_fir_filter_xxx_0 - legend - True - - - alpha1 - 1.0 - - - color1 - "blue" - - - label1 - - - - width1 - 1 - - - alpha10 - 1.0 - - - color10 - "dark blue" - - - label10 - - - - width10 - 1 - - - alpha2 - 1.0 - - - color2 - "red" - - - label2 - - - - width2 - 1 - - - alpha3 - 1.0 - - - color3 - "green" - - - label3 - - - - width3 - 1 - - - alpha4 - 1.0 - - - color4 - "black" - - - label4 - - - - width4 - 1 - - - alpha5 - 1.0 - - - color5 - "cyan" - - - label5 - - - - width5 - 1 - - - alpha6 - 1.0 - - - color6 - "magenta" - - - label6 - - - - width6 - 1 - - - alpha7 - 1.0 - - - color7 - "yellow" - - - label7 - - - - width7 - 1 - - - alpha8 - 1.0 - - - color8 - "dark red" - - - label8 - - - - width8 - 1 - - - alpha9 - 1.0 - - - color9 - "dark green" - - - label9 - - - - width9 - 1 + interp + samples_per_symbol_tx maxoutbuf @@ -955,56 +678,16 @@ TX sampling rate 0 - name - "" - - - nconnections - 1 - - - showports - True - - - freqhalf - True - - - tr_chan + samp_delay 0 - tr_level - 0.0 - - - tr_mode - qtgui.TRIG_MODE_FREE - - - tr_tag - "" + taps + interp_taps type - complex - - - update_time - 0.10 - - - wintype - firdes.WIN_BLACKMAN_hARRIS - - - ymax - 10 - - - ymin - -140 + fff @@ -1039,7 +722,7 @@ TX sampling rate _coordinate - (1016, 482) + (1136, 218) gui_hint @@ -1303,8 +986,367 @@ TX sampling rate name + "Out" + + + nconnections + 1 + + + size + 1024 + + + srate + samp_rate_tx + + + tr_chan + 0 + + + tr_delay + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag "" + + type + float + + + update_time + 0.10 + + + ylabel + Amplitude + + + yunit + "" + + + ymax + 1 + + + ymin + -1 + + + + qtgui_time_sink_x + + autoscale + False + + + alias + + + + comment + + + + ctrlpanel + True + + + affinity + + + + entags + True + + + _enabled + 0 + + + _coordinate + (1104, 474) + + + gui_hint + + + + _rotation + 0 + + + grid + True + + + id + qtgui_time_sink_x_0_1_0 + + + legend + True + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + -1 + + + style2 + 1 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + marker3 + -1 + + + style3 + 1 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + marker4 + -1 + + + style4 + 1 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + + + + marker5 + -1 + + + style5 + 1 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "magenta" + + + label6 + + + + marker6 + -1 + + + style6 + 1 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "yellow" + + + label7 + + + + marker7 + -1 + + + style7 + 1 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "dark red" + + + label8 + + + + marker8 + -1 + + + style8 + 1 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "dark green" + + + label9 + + + + marker9 + -1 + + + style9 + 1 + + + width9 + 1 + + + name + "In" + nconnections 1 @@ -1390,7 +1432,7 @@ TX sampling rate _coordinate - (160, 166) + (152, 146) _rotation @@ -1526,7 +1568,7 @@ similar to produce dynamic payloads. settling_samples - 0 + 512 msb_first @@ -1554,54 +1596,30 @@ similar to produce dynamic payloads. whitening - False + True - blocks_add_const_vxx_0 - blocks_multiply_const_vxx_1 + audio_source_0 + qtgui_time_sink_x_0_1_0 0 0 - blocks_float_to_int_0 - blocks_repeat_0 - 0 - 0 - - - blocks_multiply_const_vxx_1 - blocks_float_to_int_0 - 0 - 0 - - - blocks_multiply_const_vxx_1_0 + blocks_multiply_const_vxx_0 audio_sink_0_0 0 0 - blocks_multiply_const_vxx_1_0 + blocks_multiply_const_vxx_0 qtgui_time_sink_x_0_1 0 0 - blocks_repeat_0 - digital_chunks_to_symbols_xx_0 - 0 - 0 - - - blocks_vco_f_0 - blocks_multiply_const_vxx_1_0 - 0 - 0 - - - digital_chunks_to_symbols_xx_0 - blocks_vco_f_0 + interp_fir_filter_xxx_0 + blocks_multiply_const_vxx_0 0 0 @@ -1619,7 +1637,7 @@ similar to produce dynamic payloads. satnogs_upsat_fsk_frame_encoder_0 - blocks_add_const_vxx_0 + interp_fir_filter_xxx_0 0 0 diff --git a/include/satnogs/whitening.h b/include/satnogs/whitening.h index e68117f..a450016 100644 --- a/include/satnogs/whitening.h +++ b/include/satnogs/whitening.h @@ -22,6 +22,7 @@ #define INCLUDED_SATNOGS_WHITENING_H #include +#include namespace gr { @@ -36,7 +37,6 @@ namespace gr { public: whitening (uint32_t mask, uint32_t seed, uint32_t order); - ~whitening (); void reset(); @@ -44,10 +44,15 @@ namespace gr void scramble(uint8_t *out, const uint8_t *in, size_t len); void descramble(uint8_t *out, const uint8_t *in, size_t len); + void + 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, + size_t bits_num); + private: - const size_t d_lut_len; - size_t d_lut_idx; - uint8_t *d_lut; + digital::lfsr d_lfsr; }; } // namespace satnogs diff --git a/lib/upsat_fsk_frame_acquisition_impl.cc b/lib/upsat_fsk_frame_acquisition_impl.cc index 1c2249b..8edfa40 100644 --- a/lib/upsat_fsk_frame_acquisition_impl.cc +++ b/lib/upsat_fsk_frame_acquisition_impl.cc @@ -77,7 +77,7 @@ namespace gr d_decoded_bytes (0), d_decoded_bits (0), d_frame_len (0), - d_descrambler(0x21, 0x1FF, 9) + d_descrambler(0x1001, 0x1FF, 17) { size_t i; message_port_register_out (pmt::mp ("pdu")); @@ -183,6 +183,7 @@ namespace gr { size_t i; uint8_t *in = d_pdu + 1; + for(i = 0; i < len_bytes; i++){ d_ax25_tmp_buf[8*i] = (in[i] >> 7) & 0x1; d_ax25_tmp_buf[8*i + 1] = (in[i] >> 6) & 0x1; @@ -193,6 +194,13 @@ namespace gr d_ax25_tmp_buf[8*i + 6] = (in[i] >> 1) & 0x1; d_ax25_tmp_buf[8*i + 7] = in[i] & 0x1; } + + /* De-white the data if necessary */ + if (d_whitening) { + d_descrambler.descramble_one_bit_per_byte (d_ax25_tmp_buf, + d_ax25_tmp_buf, + len_bytes * 8); + } } int @@ -298,6 +306,7 @@ namespace gr if (d_decoded_bytes == d_frame_len) { if(d_is_ax25) { + unpack_ax25_bytes(d_frame_len - 1); status = ax25_decode(d_ax25_buf, &ax25_frame_len, d_ax25_tmp_buf, (d_frame_len - 1)*8); diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc index 141fde5..f283ed1 100644 --- a/lib/upsat_fsk_frame_encoder_impl.cc +++ b/lib/upsat_fsk_frame_encoder_impl.cc @@ -86,7 +86,7 @@ namespace gr d_settling_samples(settling_samples), d_encoded(0), d_pdu_len(0), - d_scrambler(0x21, 0x1FF, 9) + d_scrambler(0x1001, 0x1FF, 17) { /* Simplify the logic of the output samples handling */ set_output_multiple(8); @@ -294,6 +294,7 @@ namespace gr ax25_encode_status_t status; size_t extra_bits; size_t i; + uint8_t len_field; /* * If the whole previous frame has been successfully sent, block waiting @@ -314,6 +315,7 @@ namespace gr len = ax25_prepare_frame(d_ax25_tmp_buf, (uint8_t *) pmt::blob_data (pdu), d_pdu_len, AX25_UI_FRAME, d_ax25_addr, d_ax25_addr_len, 0x03, 1, 1, 1); + status = ax25_bit_stuffing(d_ax25_pdu, &encoded_len, d_ax25_tmp_buf, len, 1, 1); if(status != AX25_ENC_OK) { @@ -335,22 +337,23 @@ namespace gr * the address field (if exists) and the payload. Length and CRC fields * are NOT included. */ - d_pdu[d_preamble_len + d_sync_word_len] = (uint8_t) (encoded_len/8); + len_field = (uint8_t) (encoded_len/8); + + /* Apply whitening */ + if (d_whitening) { + d_scrambler.reset (); + d_scrambler.scramble(&len_field, &len_field, 1); + d_scrambler.scramble_one_bit_per_byte (d_ax25_pdu, d_ax25_pdu, + encoded_len); + } + + d_pdu[d_preamble_len + d_sync_word_len] = len_field; /* If it is necessary calculate and append the CRC */ if (d_append_crc) { LOG_WARN("AX.25 has its own CRC-16 field. Skipping..."); } - /* - * Whitening can not be applied in the AX.25 because it will alter - * the SYNC flag of the stack - */ - if (d_whitening) { - LOG_WARN("AX.25 and whitening are not compatible." - " No whitening will be performed"); - } - d_pdu_len = d_preamble_len + d_sync_word_len + 1 + encoded_len/8; /* NRZ encoding the FSK preamble with the standard method */ diff --git a/lib/whitening.cc b/lib/whitening.cc index 3c54afa..5e0ca40 100644 --- a/lib/whitening.cc +++ b/lib/whitening.cc @@ -37,33 +37,11 @@ namespace gr { * number of memory stages. */ whitening::whitening (uint32_t mask, uint32_t seed, uint32_t order) : - d_lut_len (std::pow (2, order)), - d_lut_idx (0) + d_lfsr(mask, seed, order) { - size_t i; - size_t j; - uint32_t cnt; - uint32_t shift_reg = seed; - if (order > 32) { throw std::invalid_argument ("The maximum allowed order is 32"); } - - d_lut = new uint8_t[d_lut_len]; - - for (i = 0; i < d_lut_len; i++) { - d_lut[i] = shift_reg & 0xFF; - for (j = 0; j < 8; j++) { - cnt = bit_count (shift_reg & mask) % 2; - shift_reg = shift_reg >> 1; - shift_reg |= cnt << (order - 1); - } - } - } - - whitening::~whitening() - { - delete [] d_lut; } /** @@ -73,7 +51,7 @@ namespace gr { void whitening::reset () { - d_lut_idx = 0; + d_lfsr.reset(); } /** @@ -86,10 +64,18 @@ namespace gr { whitening::scramble (uint8_t* out, const uint8_t* in, size_t len) { size_t i; + uint8_t b; for(i = 0; i < len; i++){ - out[i] = in[i] ^ d_lut[ (d_lut_idx + i ) % d_lut_len]; + b = d_lfsr.next_bit(); + b |= d_lfsr.next_bit() << 1; + b |= d_lfsr.next_bit() << 2; + b |= d_lfsr.next_bit() << 3; + b |= d_lfsr.next_bit() << 4; + b |= d_lfsr.next_bit() << 5; + b |= d_lfsr.next_bit() << 6; + b |= d_lfsr.next_bit() << 7; + out[i] = in[i] ^ b; } - d_lut_idx = (d_lut_idx + len ) % d_lut_len; } /** @@ -104,6 +90,36 @@ namespace gr { scramble(out, in, len); } + /** + * Performs data scrambling. The input and output buffer + * contain one bit per byte + * @param out the output buffer + * @param in the input buffer + * @param bits_num the number of bits to be scrambled + */ + void + whitening::scramble_one_bit_per_byte (uint8_t* out, const uint8_t* in, + size_t bits_num) + { + size_t i; + for(i = 0; i < bits_num; i++){ + out[i] = in[i] ^ d_lfsr.next_bit(); + } + } + + /** + * Performs data descrambling. The input and output buffer + * contain one bit per byte + * @param out the output buffer + * @param in the input buffer + * @param bits_num the number of bits to be descrambled + */ + void + whitening::descramble_one_bit_per_byte (uint8_t* out, const uint8_t* in, + size_t bits_num) + { + scramble_one_bit_per_byte(out, in, bits_num); + } + } /* namespace satnogs */ } /* namespace gr */ -