diff --git a/apps/grlora_analyze.py b/apps/grlora_analyze.py index fb287bd..25b57f7 100755 --- a/apps/grlora_analyze.py +++ b/apps/grlora_analyze.py @@ -22,6 +22,27 @@ def fetch(l, num): del l[0:num] return fet +def iphase(cpx): + return np.unwrap(np.angle(cpx)) + +def ifreq(cpx): + global fs + + iphase_signal = iphase(cpx) + return np.diff(iphase_signal) + +def add_plot_complex(fig, pos, value, title='', grid=False, grid_spacing=8192): + ax = fig.add_subplot(pos) + ax.set_title(title) + ax.plot(np.arange(len(value)), np.real(value), "b", np.arange(len(value)), np.imag(value), "g") + if grid: + ax.grid(color='r', linestyle='-', linewidth=2, markevery=grid_spacing, axis='x', which='minor', alpha=0.5) + minor_ticks = np.arange(0, len(value), grid_spacing) + ax.set_xticks(minor_ticks, minor=True) + ax.set_xlim([0, len(value)]) + ax.set_xlabel("samples") + return ax + class State: READ_HEADER = 0 READ_DATA = 1 @@ -68,6 +89,7 @@ class Plotter(Thread): data = bytearray() data_len = 0 draw_over = False + fig = plt.figure() while True: plt.pause(0.0001) @@ -86,7 +108,9 @@ class Plotter(Thread): plot_data = np.frombuffer(fetch(data, data_len), dtype=np.complex64) if not draw_over: plt.gcf().clear() - plt.plot(np.arange(len(plot_data)), np.real(plot_data), "b", np.arange(len(plot_data)), np.imag(plot_data), "g") + add_plot_complex(fig, 211, plot_data, grid=True) + add_plot_complex(fig, 212, ifreq(plot_data), grid=True) + #plt.plot(np.arange(len(plot_data)), np.real(plot_data), "b", np.arange(len(plot_data)), np.imag(plot_data), "g") self.state = State.READ_HEADER except ConnectionResetError: print("[gr-lora analyzer]: connection reset") diff --git a/lib/decoder_impl.cc b/lib/decoder_impl.cc index 7fba769..dbf34a9 100644 --- a/lib/decoder_impl.cc +++ b/lib/decoder_impl.cc @@ -65,7 +65,13 @@ namespace gr { } // Set whitening sequence - this->d_whitening_sequence = gr::lora::prng_payload; + if(sf == 11) { + this->d_whitening_sequence = gr::lora::prng_payload_sf11; + } else if(sf == 12) { + this->d_whitening_sequence = gr::lora::prng_payload_sf12; + } else { + this->d_whitening_sequence = gr::lora::prng_payload; + } if (sf == 6) { std::cerr << "[LoRa Decoder] WARNING : Spreading factor wrapped around to 12 due to incompatibility in hardware!" << std::endl; @@ -77,6 +83,10 @@ namespace gr { this->d_debug.open("/tmp/grlora_debug_txt", std::ios::out); #endif + #ifndef NDEBUG + d_dbg.attach(); + #endif + this->d_bw = 125000u; this->d_cr = 4; this->d_samples_per_second = samp_rate; @@ -135,9 +145,6 @@ namespace gr { // Whitening empty file // DBGR_QUICK_TO_FILE("/tmp/whitening_out", false, g, -1, ""); - #ifndef NDEBUG - d_dbg.attach(); - #endif d_fine_sync = 0; } @@ -164,7 +171,10 @@ namespace gr { this->d_upchirp.resize(this->d_samples_per_symbol); this->d_downchirp_ifreq.resize(this->d_samples_per_symbol); this->d_upchirp_ifreq.resize(this->d_samples_per_symbol); + gr_complex tmp[this->d_samples_per_symbol*3]; this->d_upchirp_ifreq_v.resize(this->d_samples_per_symbol*3); + this->d_upchirp_stored.resize(this->d_samples_per_symbol*3); + this->d_downchirp_stored.resize(this->d_samples_per_symbol); const double T = -0.5 * this->d_bw * this->d_symbols_per_second; const double f0 = (this->d_bw / 2.0); @@ -188,9 +198,10 @@ namespace gr { samples_to_file("/tmp/upchirp", &this->d_upchirp[0], this->d_upchirp.size(), sizeof(gr_complex)); // Values - memcpy(&d_upchirp_ifreq_v[0], &d_upchirp_ifreq[0], sizeof(float) * this->d_samples_per_symbol); - memcpy(&d_upchirp_ifreq_v[0]+this->d_samples_per_symbol, &d_upchirp_ifreq[0], sizeof(float) * this->d_samples_per_symbol); - memcpy(&d_upchirp_ifreq_v[0]+this->d_samples_per_symbol*2, &d_upchirp_ifreq[0], sizeof(float) * this->d_samples_per_symbol); + memcpy(tmp, &d_upchirp[0], sizeof(gr_complex) * this->d_samples_per_symbol); + memcpy(tmp+this->d_samples_per_symbol, &d_upchirp[0], sizeof(gr_complex) * this->d_samples_per_symbol); + memcpy(tmp+this->d_samples_per_symbol*2, &d_upchirp[0], sizeof(gr_complex) * this->d_samples_per_symbol); + this->instantaneous_frequency(tmp, &this->d_upchirp_ifreq_v[0], this->d_samples_per_symbol*3); } void decoder_impl::values_to_file(const std::string path, const unsigned char *v, const uint32_t length, const uint32_t ppm) { @@ -304,6 +315,12 @@ namespace gr { return result; } + float decoder_impl::cross_correlate_fast(const gr_complex *samples, const gr_complex *ideal_chirp, const uint32_t window) { + gr_complex result = 0; + volk_32fc_x2_conjugate_dot_prod_32fc(&result, samples, ideal_chirp, window); + return abs(result); + } + /** * Currently unused. */ @@ -340,10 +357,9 @@ namespace gr { return result; } - void decoder_impl::fine_sync(const gr_complex* in_samples, uint32_t bin_idx) { - int32_t shift_ref = bin_idx * this->d_decim_factor; + void decoder_impl::fine_sync(const gr_complex* in_samples, uint32_t bin_idx, int32_t search_space) { + int32_t shift_ref = (bin_idx+1) * this->d_decim_factor; //shift_ref = std::max(shift_ref + (int32_t)(this->d_decim_factor / 2), 0); - int32_t search_space = this->d_decim_factor; // At most d_decim_factor samples offset float samples_ifreq[d_samples_per_symbol]; float max_correlation = 0.0f; int32_t lag = 0; @@ -351,7 +367,8 @@ namespace gr { this->instantaneous_frequency(in_samples, samples_ifreq, d_samples_per_symbol); for(int32_t i = -search_space+1; i < search_space; i++) { - float c = cross_correlate_ifreq_fast(samples_ifreq, &d_upchirp_ifreq_v[shift_ref+i+d_samples_per_symbol], d_samples_per_symbol-1); + //float c = cross_correlate_fast(in_samples, &d_upchirp_stored[shift_ref+i+d_samples_per_symbol], d_samples_per_symbol); + float c = cross_correlate_ifreq_fast(samples_ifreq, &d_upchirp_ifreq_v[shift_ref+i+d_samples_per_symbol], d_samples_per_symbol); if(c > max_correlation) { max_correlation = c; lag = i; @@ -361,6 +378,10 @@ namespace gr { d_debug << "FINE: " << -lag << std::endl; d_fine_sync = -lag; + + //if(abs(d_fine_sync) >= d_decim_factor / 2) + // d_fine_sync = 0; + //d_fine_sync = 0; } float decoder_impl::detect_preamble_autocorr(const gr_complex *samples, const uint32_t window) { @@ -460,7 +481,7 @@ namespace gr { // Multiply with ideal downchirp for (uint32_t i = 0u; i < this->d_samples_per_symbol; i++) { - this->d_mult_hf[i] = std::conj(samples[i] * this->d_downchirp[i]); + this->d_mult_hf[i] = samples[i] * this->d_downchirp[i]; } samples_to_file("/tmp/mult", &this->d_mult_hf[0], this->d_samples_per_symbol, sizeof(gr_complex)); @@ -498,25 +519,31 @@ namespace gr { uint32_t decoder_impl::max_frequency_gradient_idx(const gr_complex *samples, const bool is_header) { float samples_ifreq[this->d_samples_per_symbol]; + float samples_ifreq_avg[this->d_number_of_bins]; samples_to_file("/tmp/data", &samples[0], this->d_samples_per_symbol, sizeof(gr_complex)); this->instantaneous_frequency(samples, samples_ifreq, this->d_samples_per_symbol); + for(uint32_t i = 0; i < d_number_of_bins; i++) { + volk_32f_accumulator_s32f(&samples_ifreq_avg[i], &samples_ifreq[i*d_decim_factor], d_decim_factor); + samples_ifreq_avg[i] /= d_decim_factor; + } + float max_gradient = 0.2f; float gradient = 0.0f; uint32_t max_index = 0; for (uint32_t i = 1u; i < this->d_number_of_bins; i++) { - int32_t index_1 = (this->d_decim_factor * i) - this->d_decim_factor / 2; - int32_t index_2 = (this->d_decim_factor * (i + 1u)) - this->d_decim_factor / 2; - gradient = samples_ifreq[index_1] - samples_ifreq[index_2]; + gradient = samples_ifreq_avg[i - 1] - samples_ifreq_avg[i]; if (gradient > max_gradient) { max_gradient = gradient; max_index = i; } } - return this->d_number_of_bins - max_index; + max_index += 1; + + return (this->d_number_of_bins - max_index) % this->d_number_of_bins; } bool decoder_impl::demodulate(const gr_complex *samples, const bool is_header) { @@ -526,9 +553,7 @@ namespace gr { uint32_t bin_idx = this->max_frequency_gradient_idx(samples, is_header); //uint32_t bin_idx = this->get_shift_fft(samples); - fine_sync(samples, bin_idx); - if(abs(d_fine_sync) >= d_decim_factor / 2) - d_fine_sync = 0; + fine_sync(samples, bin_idx, 4); // DBGR_INTERMEDIATE_TIME_MEASUREMENT(); @@ -594,6 +619,9 @@ namespace gr { void decoder_impl::decode(uint8_t *out_data, const bool is_header) { static const uint8_t shuffle_pattern[] = {5, 0, 1, 2, 4, 3, 6, 7}; + if (!is_header) + this->values_to_file("/tmp/before_deshuffle", &this->d_demodulated[0], this->d_demodulated.size(), 8); + this->deshuffle(shuffle_pattern, is_header); // For determining whitening sequence @@ -819,7 +847,7 @@ namespace gr { float correlation = detect_preamble_autocorr(input, d_samples_per_symbol); if (correlation >= 0.80f) { - this->samples_to_file("/tmp/detect", &input[0], this->d_samples_per_symbol, sizeof(gr_complex)); + //this->samples_to_file("/tmp/detect", &input[0], this->d_samples_per_symbol, sizeof(gr_complex)); this->d_corr_fails = 0u; this->d_state = gr::lora::DecoderState::SYNC; break; @@ -838,6 +866,11 @@ namespace gr { this->d_debug << "Cu: " << correlation << std::endl; #endif + this->samples_to_file("/tmp/detect", &input[i], this->d_samples_per_symbol, sizeof(gr_complex)); + memcpy(&d_upchirp_stored[0], input+i, sizeof(gr_complex) * this->d_samples_per_symbol); + memcpy(&d_upchirp_stored[d_samples_per_symbol], input+i, sizeof(gr_complex) * this->d_samples_per_symbol); + memcpy(&d_upchirp_stored[d_samples_per_symbol*2], input+i, sizeof(gr_complex) * this->d_samples_per_symbol); + this->consume_each(i); this->d_state = gr::lora::DecoderState::FIND_SFD; break; @@ -851,18 +884,21 @@ namespace gr { #endif if (c > 0.99f) { + d_dbg.store_samples(input, this->d_samples_per_symbol); + memcpy(&d_downchirp_stored[0], input, sizeof(gr_complex) * this->d_samples_per_symbol); #ifndef NDEBUG this->d_debug << "SYNC: " << c << std::endl; #endif // Debug stuff this->samples_to_file("/tmp/sync", input, this->d_samples_per_symbol, sizeof(gr_complex)); + d_dbg.analyze_samples(false, false); //printf("---------------------- SYNC! with %f\n", c); this->d_state = gr::lora::DecoderState::PAUSE; } else { - if(c < -0.95) { - fine_sync(input, 0); + if(c < -0.98) { + fine_sync(input, d_number_of_bins-1, 64); } else { this->d_corr_fails++; } @@ -875,7 +911,7 @@ namespace gr { } } - this->consume_each(this->d_samples_per_symbol+d_fine_sync); + this->consume_each((int32_t)this->d_samples_per_symbol+d_fine_sync); break; } @@ -915,7 +951,7 @@ namespace gr { this->msg_raw_chirp_debug(raw_input, this->d_samples_per_symbol); //samples_debug(input, d_samples_per_symbol); - this->consume_each(this->d_samples_per_symbol+d_fine_sync); + this->consume_each((int32_t)this->d_samples_per_symbol+d_fine_sync); break; } @@ -948,7 +984,7 @@ namespace gr { this->msg_raw_chirp_debug(raw_input, this->d_samples_per_symbol); //samples_debug(input, d_samples_per_symbol); - this->consume_each(this->d_samples_per_symbol+d_fine_sync); + this->consume_each((int32_t)this->d_samples_per_symbol+d_fine_sync); break; } diff --git a/lib/decoder_impl.h b/lib/decoder_impl.h index af085d8..7e2edd9 100644 --- a/lib/decoder_impl.h +++ b/lib/decoder_impl.h @@ -77,6 +77,8 @@ namespace gr { std::vector d_upchirp_ifreq; ///< The instantaneous frequency of the ideal upchirp. std::vector d_upchirp_ifreq_v; ///< The instantaneous frequency of the ideal upchirp. + std::vector d_upchirp_stored; ///< The complex stored upchirp. + std::vector d_downchirp_stored; ///< The complex stored upchirp. std::vector d_fft; ///< Vector containing the FFT resuls. std::vector d_mult_hf; ///< Vector containing the FFT decimation. @@ -119,7 +121,8 @@ namespace gr { double d_dt; ///< Indicates how fast the frequency changes in a symbol (chirp). float cross_correlate_ifreq_fast(const float *samples_ifreq, const float *ideal_chirp, const uint32_t window); - void fine_sync(const gr_complex* in_samples, uint32_t bin_idx); + float cross_correlate_fast(const gr_complex* samples, const gr_complex* ideal_chirp, const uint32_t window); + void fine_sync(const gr_complex* in_samples, uint32_t bin_idx, int32_t search_space); int32_t d_fine_sync; float detect_preamble_autocorr(const gr_complex *samples, uint32_t window); diff --git a/lib/tables.h b/lib/tables.h index 1bdafba..215fe55 100644 --- a/lib/tables.h +++ b/lib/tables.h @@ -35,10 +35,18 @@ namespace gr { * Whitening sequence */ const uint8_t prng_payload[] = { - 0xff, 0xff, 0x2d, 0xff, 0x78, 0xff, 0xe1, 0xff, 0x00, 0xff, 0xd2, 0x2d, 0x55, 0x78, 0x4b, 0xe1, 0x66, 0x00, 0x1e, 0xd2, 0xff, 0x55, 0x2d, 0x4b, 0x78, 0x66, 0xe1, 0x1e, 0xd2, 0xff, 0x87, 0x2d, 0xcc, 0x78, 0xaa, 0xe1, 0xb4, 0xd2, 0x99, 0x87, 0xe1, 0xcc, 0x00, 0xaa, 0x00, 0xb4, 0x00, 0x99, 0x00, 0xe1, 0xd2, 0x00, 0x55, 0x00, 0x99, 0x00, 0xe1, 0x00, 0xd2, 0xd2, 0x87, 0x55, 0x1e, 0x99, 0x2d, 0xe1, 0x78, 0xd2, 0xe1, 0x87, 0xd2, 0x1e, 0x55, 0x2d, 0x99, 0x78, 0x33, 0xe1, 0x55, 0xd2, 0x4b, 0x55, 0x66, 0x99, 0x1e, 0x33, 0x2d, 0x55, 0x78, 0x4b, 0xe1, 0x66, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x78, 0xd2, 0xe1, 0x87, 0x00, 0xcc, 0x00, 0x78, 0x00, 0x33, 0xd2, 0x55, 0x87, 0x99, 0xcc, 0x33, 0x78, 0x55, 0x33, 0x99, 0x55, 0x33, 0x99, 0x87, 0x33, 0xcc, 0x55, 0xaa, 0x99, 0x66, 0x33, 0x1e, 0x87, 0x2d, 0xcc, 0x78, 0xaa, 0x33, 0x66, 0x55, 0x1e, 0x99, 0x2d, 0xe1, 0x78, 0x00, 0x33, 0x00, 0x55, 0xd2, 0x99, 0x55, 0xe1, 0x4b, 0x00, 0xb4, 0x00, 0x4b, 0xd2, 0x66, 0x55, 0xcc, 0x4b, 0xaa, 0xb4, 0x66, 0x4b, 0xcc, 0x66, 0xaa, 0xcc, 0xb4, 0xaa, 0x4b, 0x66, 0x66, 0xcc, 0xcc, 0xaa, 0x78, 0xb4, 0x33, 0x4b, 0x55, 0x66, 0x4b, 0xcc, 0x66, 0x78, 0xcc, 0x33, 0x78, 0x55, 0xe1, 0x4b, 0x00, 0x66, 0xd2, 0xcc, 0x87, 0x78, 0x1e, 0xe1, 0xff, 0x00, 0xff, 0xd2, 0x2d, 0x87, 0xaa, 0x1e, 0x66, 0xff, 0xcc, 0xff, 0xaa, 0x2d, 0x66, 0xaa, 0x1e, 0x66, 0xff, 0xcc, 0x2d, 0xaa, 0xaa, 0x66, 0xb4, 0x1e, 0x4b, 0xff, 0x66, 0x2d, 0x1e, 0xaa, 0x2d, 0xb4, 0xaa, 0x4b, 0xb4, 0x66, 0x99, 0x1e, 0xe1, 0x2d, 0xd2, 0xaa, 0x55, 0xb4, 0x99, 0x99, 0xe1, 0xe1, 0x00, 0xd2, 0xd2, 0x55, 0x87, 0x99, 0xcc, 0xe1, 0xaa, 0x00, 0x66, 0xd2, 0xcc, 0x87, 0x78, 0xcc, 0xe1, 0xaa, 0xd2, 0x66, 0x87, 0xcc, 0x1e, 0x78, 0xff, 0xe1, 0x2d, 0xd2, 0x78, 0x87, 0x33, 0x1e, 0x87, 0xff, 0x1e, 0x2d, 0x2d, 0x78, 0x78, 0x33, 0x33, 0x87, 0x87, 0x1e, 0xcc, 0x2d, 0x78, 0x78, 0xe1, 0x33, 0xd2, 0x87, 0x55, 0xcc, 0x4b, 0x78, 0x66, 0xe1, 0xcc, 0xd2, 0xaa, 0x55, 0xb4, 0x4b, 0x99, 0x66, 0x33, 0xcc, 0x55, 0xaa, 0x99, 0xb4, 0xe1, 0x99, 0xd2, 0x33, 0x55, 0x55, 0x4b, 0x99, 0xb4, 0xe1, 0x99, 0xd2, 0x33, 0x55, 0x55, 0x4b, 0x4b, 0xb4, 0xb4, 0x99, 0x4b, 0x33, 0xb4, 0x55, 0x99, 0x4b, 0x33, 0xb4, 0x87, 0x4b, 0x1e, 0xb4, 0x2d, 0x99, 0xaa, 0x33, 0x66, 0xc7, 0x1e, 0x1e, 0x2d, 0x2d, 0xaa, 0xaa, 0x66, 0x66, 0xcc, 0x1e, 0x78, 0x2d, 0x33, 0xaa, 0x87, 0x66, 0x1e, 0xcc, 0xff, 0x78, 0x2d, 0x33, 0xaa, 0x87, 0x66, 0x1e, 0x1e, 0xff, 0xff, 0x2d, 0xff, 0xaa, 0xff, 0x66, 0x2d, 0x1e, 0xaa, 0xff, 0xb4, 0xff, 0x99, 0xff, 0x33, 0x2d, 0x87, 0xaa, 0xcc, 0xb4, 0x78, 0x99, 0x33, 0x33, 0x87, 0x87, 0xcc, 0xcc, 0xaa, 0x78, 0xb4, 0x33, 0x4b, 0x87, 0xb4, 0xcc, 0x99, 0xaa, 0xe1, 0xb4, 0xd2, 0x4b, 0x87, 0xb4, 0xcc, 0x99, 0x78, 0xe1, 0xe1, 0xd2, 0x00, 0x87, 0x00, 0xcc, 0xd2, 0x78, 0x87, 0xe1, 0x1e, 0x00, 0x2d, 0x00, 0xaa, 0xd2, 0xb4, 0x87, 0x4b, 0x1e, 0xb4, 0x2d, 0x4b, 0xaa, 0xb4, 0xb4, 0x4b, 0x4b, 0x66, 0xb4, 0x1e, 0x4b, 0xff, 0xb4, 0xff, 0x4b, 0x2d, 0x66, 0x78, 0x1e, 0x33, 0xff, 0x55, 0xff, 0x4b, 0x2d, 0xb4, 0x78, 0x99, 0x33, 0xe1, 0x55, 0x00, 0x4b, 0xd2, 0xb4, 0x55, 0x99, 0x99, 0xe1, 0x33, 0x00, 0x87, 0xd2, 0x1e, 0x55, 0xff, 0x99, 0xff, 0x33, 0xff, 0x87, 0xff, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x87, 0xe1, 0xaa, 0xcc, + 0xff, 0xff, 0x2d, 0xff, 0x78, 0xff, 0xe1, 0xff, 0x00, 0xff, 0xd2, 0x2d, 0x55, 0x78, 0x4b, 0xe1, 0x66, 0x00, 0x1e, 0xd2, 0xff, 0x55, 0x2d, 0x4b, 0x78, 0x66, 0xe1, 0x1e, 0xd2, 0xff, 0x87, 0x2d, 0xcc, 0x78, 0xaa, 0xe1, 0xb4, 0xd2, 0x99, 0x87, 0xe1, 0xcc, 0x00, 0xaa, 0x00, 0xb4, 0x00, 0x99, 0x00, 0xe1, 0xd2, 0x00, 0x55, 0x00, 0x99, 0x00, 0xe1, 0x00, 0xd2, 0xd2, 0x87, 0x55, 0x1e, 0x99, 0x2d, 0xe1, 0x78, 0xd2, 0xe1, 0x87, 0xd2, 0x1e, 0x55, 0x2d, 0x99, 0x78, 0x33, 0xe1, 0x55, 0xd2, 0x4b, 0x55, 0x66, 0x99, 0x1e, 0x33, 0x2d, 0x55, 0x78, 0x4b, 0xe1, 0x66, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x78, 0xd2, 0xe1, 0x87, 0x00, 0xcc, 0x00, 0x78, 0x00, 0x33, 0xd2, 0x55, 0x87, 0x99, 0xcc, 0x33, 0x78, 0x55, 0x33, 0x99, 0x55, 0x33, 0x99, 0x87, 0x33, 0xcc, 0x55, 0xaa, 0x99, 0x66, 0x33, 0x1e, 0x87, 0x2d, 0xcc, 0x78, 0xaa, 0x33, 0x66, 0x55, 0x1e, 0x99, 0x2d, 0xe1, 0x78, 0x00, 0x33, 0x00, 0x55, 0xd2, 0x99, 0x55, 0xe1, 0x4b, 0x00, 0xb4, 0x00, 0x4b, 0xd2, 0x66, 0x55, 0xcc, 0x4b, 0xaa, 0xb4, 0x66, 0x4b, 0xcc, 0x66, 0xaa, 0xcc, 0xb4, 0xaa, 0x4b, 0x66, 0x66, 0xcc, 0xcc, 0xaa, 0x78, 0xb4, 0x33, 0x4b, 0x55, 0x66, 0x4b, 0xcc, 0x66, 0x78, 0xcc, 0x33, 0x78, 0x55, 0xe1, 0x4b, 0x00, 0x66, 0xd2, 0xcc, 0x87, 0x78, 0x1e, 0xe1, 0xff, 0x00, 0xff, 0xd2, 0x2d, 0x87, 0xaa, 0x1e, 0x66, 0xff, 0xcc, 0xff, 0xaa, 0x2d, 0x66, 0xaa, 0x1e, 0x66, 0xff, 0xcc, 0x2d, 0xaa, 0xaa, 0x66, 0xb4, 0x1e, 0x4b, 0xff, 0x66, 0x2d, 0x1e, 0xaa, 0x2d, 0xb4, 0xaa, 0x4b, 0xb4, 0x66, 0x99, 0x1e, 0xe1, 0x2d, 0xd2, 0xaa, 0x55, 0xb4, 0x99, 0x99, 0xe1, 0xe1, 0x00, 0xd2, 0xd2, 0x55, 0x87, 0x99, 0xcc, 0xe1, 0xaa, 0x00, 0x66, 0xd2, 0xcc, 0x87, 0x78, 0xcc, 0xe1, 0xaa, 0xd2, 0x66, 0x87, 0xcc, 0x1e, 0x78, 0xff, 0xe1, 0x2d, 0xd2, 0x78, 0x87, 0x33, 0x1e, 0x87, 0xff, 0x1e, 0x2d, 0x2d, 0x78, 0x78, 0x33, 0x33, 0x87, 0x87, 0x1e, 0xcc, 0x2d, 0x78, 0x78, 0xe1, 0x33, 0xd2, 0x87, 0x55, 0xcc, 0x4b, 0x78, 0x66, 0xe1, 0xcc, 0xd2, 0xaa, 0x55, 0xb4, 0x4b, 0x99, 0x66, 0x33, 0xcc, 0x55, 0xaa, 0x99, 0xb4, 0xe1, 0x99, 0xd2, 0x33, 0x55, 0x55, 0x4b, 0x99, 0xb4, 0xe1, 0x99, 0xd2, 0x33, 0x55, 0x55, 0x4b, 0x4b, 0xb4, 0xb4, 0x99, 0x4b, 0x33, 0xb4, 0x55, 0x99, 0x4b, 0x33, 0xb4, 0x87, 0x4b, 0x1e, 0xb4, 0x2d, 0x99, 0xaa, 0x33, 0x66, 0x87, 0x1e, 0x1e, 0x2d, 0x2d, 0xaa, 0xaa, 0x66, 0x66, 0xcc, 0x1e, 0x78, 0x2d, 0x33, 0xaa, 0x87, 0x66, 0x1e, 0xcc, 0xff, 0x78, 0x2d, 0x33, 0xaa, 0x87, 0x66, 0x1e, 0x1e, 0xff, 0xff, 0x2d, 0xff, 0xaa, 0xff, 0x66, 0x2d, 0x1e, 0xaa, 0xff, 0xb4, 0xff, 0x99, 0xff, 0x33, 0x2d, 0x87, 0xaa, 0xcc, 0xb4, 0x78, 0x99, 0x33, 0x33, 0x87, 0x87, 0xcc, 0xcc, 0xaa, 0x78, 0xb4, 0x33, 0x4b, 0x87, 0xb4, 0xcc, 0x99, 0xaa, 0xe1, 0xb4, 0xd2, 0x4b, 0x87, 0xb4, 0xcc, 0x99, 0x78, 0xe1, 0xe1, 0xd2, 0x00, 0x87, 0x00, 0xcc, 0xd2, 0x78, 0x87, 0xe1, 0x1e, 0x00, 0x2d, 0x00, 0xaa, 0xd2, 0xb4, 0x87, 0x4b, 0x1e, 0xb4, 0x2d, 0x4b, 0xaa, 0xb4, 0xb4, 0x4b, 0x4b, 0x66, 0xb4, 0x1e, 0x4b, 0xff, 0xb4, 0xff, 0x4b, 0x2d, 0x66, 0x78, 0x1e, 0x33, 0xff, 0x55, 0xff, 0x4b, 0x2d, 0xb4, 0x78, 0x99, 0x33, 0xe1, 0x55, 0x00, 0x4b, 0xd2, 0xb4, 0x55, 0x99, 0x99, 0xe1, 0x33, 0x00, 0x87, 0xd2, 0x1e, 0x55, 0xff, 0x99, 0xff, 0x33, 0xff, 0x87, 0xff, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x87, 0xe1, 0xaa, 0xcc, /*0xff, 0xff, 0x2e, 0xff, 0x5c, 0xff, 0xe8, 0xff, 0x00, 0xff, 0xd1, 0x2e, 0x72, 0x5c, 0x65, 0xe8, 0x4b, 0x00, 0x17, 0xd1, 0xff, 0x72, 0x2e, 0x65, 0x5c, 0x4b, 0xe8, 0x17, 0xd1, 0xff, 0xa3, 0x2e, 0xc6, 0x5c, 0x8d, 0xe8, 0x9a, 0xd1, 0xb4, 0xa3, 0xe8, 0xc6, 0x00, 0x8d, 0x00, 0x9a, 0x00, 0xb4, 0x00, 0xe8, 0xd1, 0x00, 0x72, 0x00, 0xb4, 0x00, 0xe8, 0x00, 0xd1, 0xd1, 0xa3, 0x72, 0x17, 0xb4, 0x2e, 0xe8, 0x5c, 0xd1, 0xe8, 0xa3, 0xd1, 0x17, 0x72, 0x2e, 0xb4, 0x5c, 0x39, 0xe8, 0x72, 0xd1, 0x65, 0x72, 0x4b, 0xb4, 0x17, 0x39, 0x2e, 0x72, 0x5c, 0x65, 0xe8, 0x4b, 0x00, 0x17, 0x00, 0x2e, 0x00, 0x5c, 0xd1, 0xe8, 0xa3, 0x00, 0xc6, 0x00, 0x5c, 0x00, 0x39, 0xd1, 0x72, 0xa3, 0xb4, 0xc6, 0x39, 0x5c, 0x72, 0x39, 0xb4, 0x72, 0x39, 0xb4, 0xa3, 0x39, 0xc6, 0x72, 0x8d, 0xb4, 0x4b, 0x39, 0x17, 0xa3, 0x2e, 0xc6, 0x5c, 0x8d, 0x39, 0x4b, 0x72, 0x17, 0xb4, 0x2e, 0xe8, 0x5c, 0x00, 0x39, 0x00, 0x72, 0xd1, 0xb4, 0x72, 0xe8, 0x65, 0x00, 0x9a, 0x00, 0x65, 0xd1, 0x4b, 0x72, 0xc6, 0x65, 0x8d, 0x9a, 0x4b, 0x65, 0xc6, 0x4b, 0x8d, 0xc6, 0x9a, 0x8d, 0x65, 0x4b, 0x4b, 0xc6, 0xc6, 0x8d, 0x5c, 0x9a, 0x39, 0x65, 0x72, 0x4b, 0x65, 0xc6, 0x4b, 0x5c, 0xc6, 0x39, 0x5c, 0x72, 0xe8, 0x65, 0x00, 0x4b, 0xd1, 0xc6, 0xa3, 0x5c, 0x17, 0xe8, 0xff, 0x00, 0xff, 0xd1, 0x2e, 0xa3, 0x8d, 0x17, 0x4b, 0xff, 0xc6, 0xff, 0x8d, 0x2e, 0x4b, 0x8d, 0x17, 0x4b, 0xff, 0xc6, 0x2e, 0x8d, 0x8d, 0x4b, 0x9a, 0x17, 0x65, 0xff, 0x4b, 0x2e, 0x17, 0x8d, 0x2e, 0x9a, 0x8d, 0x65, 0x9a, 0x4b, 0xb4, 0x17, 0xe8, 0x2e, 0xd1, 0x8d, 0x72, 0x9a, 0xb4, 0xb4, 0xe8, 0xe8, 0x00, 0xd1, 0xd1, 0x72, 0xa3, 0xb4*/ }; + + const uint8_t prng_payload_sf11[] = { + 0xff, 0xff, 0x2d, 0xff, 0x78, 0xf9, 0xe5, 0xdf, 0x00, 0xee, 0x80, 0x7f, 0xd2, 0x2d, 0x55, 0x78, 0x4b, 0xe1, 0x42, 0x00, 0x36, 0x80, 0x5e, 0xd2, 0xff, 0x55, 0x2d, 0x49, 0x74, 0x4a, 0xe9, 0x26, 0xa1, 0x1e, 0x52, 0xff, 0x87, 0x2d, 0xca, 0x70, 0x8c, 0xe9, 0xaa, 0xa0, 0x34, 0xd2, 0x99, 0x87, 0xe1, 0xca, 0x00, 0x8c, 0x20, 0xaa, 0x00, 0x34, 0x80, 0x99, 0x00, 0xe1, 0xd2, 0x04, 0x5b, 0x00, 0x94, 0x00, 0x19, 0x00, 0xe1, 0x00, 0xd0, 0xd0, 0x83, 0x53, 0x26, 0x84, 0x1f, 0x59, 0xad, 0xe1, 0x78, 0xd0, 0xe1, 0x83, 0xd0, 0x26, 0x42, 0x1f, 0x55, 0xad, 0x99, 0x78, 0x31, 0xe3, 0x53, 0xd8, 0x65, 0x42, 0x0a, 0x15, 0xe6, 0x99, 0x1e, 0x31, 0x29, 0x53, 0x54, 0x65, 0xe8, 0x0b, 0x61, 0xe6, 0x00, 0x1e, 0x00, 0x29, 0x04, 0x5c, 0xe0, 0xe8, 0x93, 0x21, 0x07, 0x00, 0xcc, 0x00, 0x7a, 0x04, 0x19, 0xc0, 0x72, 0x92, 0x15, 0x07, 0x99, 0xcc, 0x31, 0x78, 0x57, 0x19, 0x85, 0x62, 0x18, 0x55, 0xb3, 0x99, 0x87, 0x31, 0xc8, 0x57, 0x84, 0x85, 0x7a, 0x19, 0x66, 0x33, 0x1e, 0x87, 0x2d, 0xc8, 0x74, 0x84, 0x29, 0x7a, 0x32, 0x26, 0xd5, 0x1e, 0x99, 0x2d, 0xe1, 0x70, 0x08, 0x09, 0x10, 0x33, 0x00, 0xd5, 0xd2, 0x99, 0x55, 0xe1, 0x45, 0x00, 0xaa, 0x10, 0x34, 0x00, 0xcb, 0xd2, 0x66, 0x55, 0xca, 0x41, 0x8c, 0x8a, 0x6a, 0x35, 0x66, 0x4b, 0xcc, 0x66, 0xa8, 0xca, 0xb2, 0x84, 0x65, 0x7a, 0x0b, 0x26, 0x66, 0xcc, 0xcc, 0xa8, 0x7a, 0xb2, 0x19, 0x65, 0x62, 0x0a, 0x15, 0xe6, 0x4b, 0xcc, 0x64, 0x7a, 0xc6, 0x11, 0x6c, 0x62, 0xb8, 0x55, 0x61, 0x4b, 0x00, 0x64, 0xd2, 0xc6, 0x83, 0x4c, 0x06, 0xb9, 0x1e, 0xe1, 0xff, 0x00, 0xfd, 0xd2, 0x27, 0x83, 0xac, 0x06, 0x2a, 0x5e, 0x66, 0xff, 0xcc, 0xfd, 0xaa, 0x27, 0x4a, 0xac, 0x36, 0x2b, 0x5e, 0xe6, 0xff, 0xcc, 0x2d, 0xaa, 0xa0, 0x42, 0xaa, 0x36, 0x35, 0x1e, 0x4b, 0xff, 0x66, 0x2d, 0x1a, 0xa0, 0x07, 0xaa, 0xbc, 0x35, 0x2a, 0x4b, 0xb4, 0x66, 0x99, 0x1a, 0xe1, 0x0f, 0xc0, 0xac, 0x13, 0x6a, 0x55, 0xb4, 0x99, 0x99, 0xe3, 0xe1, 0x00, 0xc0, 0xd0, 0x12, 0x52, 0xd5, 0x87, 0x99, 0xcc, 0xe1, 0xa0, 0x00, 0x4a, 0xc0, 0xa6, 0x12, 0x4c, 0x87, 0x78, 0xcc, 0xe3, 0xa4, 0xd8, 0x4a, 0x92, 0xa6, 0x07, 0x4c, 0x1e, 0x78, 0xfd, 0xe1, 0x27, 0xd0, 0x6c, 0x92, 0x38, 0x07, 0xb3, 0x1e, 0x87, 0xfd, 0x1a, 0x27, 0x07, 0x6c, 0x6c, 0x38, 0x78, 0x33, 0x33, 0x87, 0x85, 0x18, 0xc2, 0x0f, 0x6c, 0x7c, 0xb8, 0x78, 0x61, 0x33, 0xd2, 0x85, 0x51, 0xc6, 0x45, 0x6c, 0x5a, 0xb8, 0x26, 0xe1, 0xcc, 0xd2, 0xa8, 0x51, 0xb6, 0x45, 0x85, 0x5a, 0x19, 0x66, 0x33, 0xcc, 0x55, 0xa8, 0x9b, 0xb6, 0xc9, 0x85, 0xf0, 0x18, 0x12, 0x33, 0x55, 0x55, 0x49, 0x9b, 0xb6, 0xc9, 0xa5, 0xf0, 0x19, 0x52, 0xb3, 0x55, 0x55, 0x49, 0x49, 0xb2, 0x92, 0x85, 0x64, 0x18, 0x0b, 0x33, 0xb4, 0x55, 0x99, 0x4b, 0x35, 0x9a, 0x83, 0x74, 0x06, 0x0b, 0x1e, 0xb4, 0x2d, 0x99, 0xa8, 0x31, 0x42, 0xa3, 0x26, 0x07, 0x5e, 0x9e, 0x2d, 0x2d, 0xa8, 0xa8, 0x66, 0x42, 0xe6, 0x36, 0x0c, 0x1e, 0xf8, 0x2d, 0x33, 0xa8, 0x81, 0x62, 0x16, 0xc6, 0xce, 0x0c, 0x3f, 0x78, 0x2d, 0x33, 0xa8, 0x81, 0x62, 0x1e, 0x06, 0xde, 0x9f, 0x3f, 0xff, 0x2d, 0xff, 0xa8, 0xfb, 0x66, 0x0f, 0x06, 0xbc, 0x9e, 0x2a, 0x7f, 0xb4, 0xff, 0x99, 0xf9, 0x35, 0x07, 0x83, 0xbc, 0x87, 0x6a, 0x4c, 0xb4, 0x78, 0x99, 0x33, 0x31, 0x8b, 0x83, 0xc6, 0x87, 0x4c, 0x4c, 0xaa, 0x78, 0xb4, 0x31, 0x41, 0x83, 0xaa, 0xc6, 0xb5, 0x4c, + }; + + const uint8_t prng_payload_sf12[] = { + 0xff, 0xff, 0x2d, 0xff, 0x78, 0xfd, 0xe3, 0xf7, 0x00, 0xcf, 0xc0, 0x3f, 0x12, 0xad, 0x55, 0x78, 0x4b, 0xe1, 0x62, 0x04, 0x1e, 0xe0, 0xde, 0x13, 0x7f, 0xd5, 0x2d, 0x4b, 0x78, 0x64, 0xe1, 0x12, 0xd0, 0xcf, 0x82, 0x3e, 0x07, 0x2d, 0xcc, 0x78, 0xaa, 0xe1, 0xb2, 0xd4, 0x9d, 0x83, 0xd8, 0x86, 0x21, 0x4c, 0x00, 0xaa, 0x00, 0xb4, 0x02, 0x91, 0x00, 0xc9, 0xd0, 0x20, 0x52, 0x80, 0x55, 0x00, 0x99, 0x00, 0xe1, 0x00, 0xd8, 0xc0, 0x92, 0x13, 0x07, 0xd5, 0x1e, 0x99, 0x2d, 0xe1, 0x78, 0xd0, 0xc1, 0x83, 0xe0, 0x06, 0x12, 0x1e, 0x55, 0x2d, 0x99, 0x78, 0x33, 0xe1, 0x53, 0xc0, 0x54, 0x12, 0x4b, 0xd5, 0x66, 0x99, 0x1e, 0x31, 0x29, 0x53, 0x54, 0x65, 0xe8, 0x0b, 0x61, 0xe6, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x74, 0xd0, 0xc9, 0x92, 0x21, 0x47, 0x00, 0xcc, 0x00, 0x78, 0x00, 0x31, 0xd0, 0x5b, 0xa3, 0x94, 0x86, 0x59, 0x4c, 0x33, 0x78, 0x55, 0x31, 0x9b, 0x53, 0x11, 0x85, 0xb2, 0x18, 0x47, 0xb3, 0xcc, 0x55, 0xaa, 0x99, 0x60, 0x35, 0x16, 0x83, 0x1e, 0x87, 0x6d, 0x4c, 0x78, 0xaa, 0x33, 0x64, 0x53, 0x12, 0x95, 0x2f, 0xd8, 0x2d, 0x21, 0x78, 0x00, 0x33, 0x00, 0x55, 0xd2, 0x95, 0x5b, 0xc9, 0x54, 0x20, 0x0b, 0x00, 0xb4, 0x00, 0x4b, 0xd0, 0x60, 0x53, 0xce, 0x45, 0x9c, 0x8b, 0x2a, 0xb4, 0x66, 0x4b, 0xcc, 0x64, 0xa8, 0xc6, 0x82, 0x8c, 0x64, 0x2b, 0x4b, 0x66, 0x66, 0xcc, 0xcc, 0xa8, 0x78, 0xb6, 0x19, 0x45, 0x62, 0x0a, 0x55, 0xe6, 0x4b, 0xcc, 0x66, 0x78, 0xc8, 0x35, 0x54, 0x63, 0xf8, 0x14, 0x21, 0xcb, 0x00, 0x66, 0xd2, 0xcc, 0x83, 0x70, 0x16, 0xe9, 0xde, 0x21, 0x3f, 0x00, 0xff, 0xd2, 0x2d, 0x85, 0xa8, 0x12, 0x4a, 0xef, 0xf6, 0xbe, 0x4c, 0x7f, 0xaa, 0x2d, 0x66, 0xa8, 0x1a, 0x66, 0xdf, 0xc6, 0x3e, 0x8c, 0x2d, 0x2a, 0xaa, 0x66, 0xb4, 0x1c, 0x4b, 0xf7, 0x42, 0x2f, 0x26, 0xac, 0x5e, 0x2a, 0x2d, 0xb4, 0xaa, 0x49, 0xb2, 0x66, 0x9d, 0x26, 0xd8, 0x1f, 0x61, 0xad, 0xd2, 0xaa, 0x55, 0xb4, 0x9b, 0x95, 0xc1, 0xe9, 0x20, 0xa0, 0x40, 0x52, 0xd2, 0x55, 0x87, 0x99, 0xc8, 0xe1, 0x8c, 0x00, 0x7a, 0x81, 0x26, 0xd2, 0xcc, 0x87, 0x78, 0xcc, 0xe1, 0xa0, 0xd0, 0x6a, 0x82, 0xa7, 0x47, 0xcc, 0x1e, 0x78, 0xff, 0xe1, 0x2b, 0xd0, 0x5c, 0xa3, 0x28, 0x06, 0x33, 0x9e, 0x87, 0xff, 0x1e, 0x2d, 0x2b, 0x70, 0x54, 0x09, 0x38, 0xb2, 0x73, 0x87, 0x87, 0x1e, 0xcc, 0x2d, 0x78, 0x70, 0xc9, 0x29, 0xf0, 0xb2, 0x52, 0x07, 0x55, 0xcc, 0x4b, 0x78, 0x60, 0xe1, 0xce, 0xe0, 0x9c, 0x12, 0x6a, 0x55, 0xb4, 0x4b, 0x99, 0x64, 0x31, 0xc2, 0x53, 0xac, 0x84, 0xab, 0x59, 0xb4, 0xe1, 0x99, 0xd2, 0x31, 0x51, 0x57, 0x4d, 0x85, 0x8a, 0x98, 0x74, 0xe1, 0x99, 0xd2, 0x33, 0x55, 0x51, 0x45, 0x45, 0x8a, 0x9a, 0xb5, 0x74, 0x19, 0x4b, 0x33, 0xb4, 0x55, 0x9b, 0x41, 0x19, 0x8a, 0xa2, 0x35, 0x47, 0x4b, 0x1e, 0xb4, 0x2d, 0x99, 0xaa, 0x31, 0x4a, 0x83, 0x26, 0x07, 0x5e, 0x1e, 0x2d, 0x2d, 0xaa, 0xa8, 0x62, 0x62, 0xc6, 0x26, 0x5c, 0x1f, 0x38, 0x2d, 0x33, 0xaa, 0x87, 0x64, 0x1a, 0xc6, 0xd7, 0x6c, 0x2e, 0x38, 0x6d, 0x33, 0xaa, 0x87, 0x66, 0x1c, 0x18, 0xf7, 0xdf, 0x0f, 0xee, 0xac, 0x7f, 0xaa, 0xff, 0x66, 0x2d, 0x1c, 0xaa, 0xf7, 0x9a, 0xef, 0xb4, 0xbf, 0x59, 0xff, 0x33, 0x2d, 0x87, 0xa8, 0xca, 0xb6, 0x5c, 0xa5, 0x38, 0x19, 0x73, 0xb3, 0x87, 0x87, 0xcc, 0xcc, 0xa8, 0x74, 0x92, 0x29, 0x74, 0xb2, 0x0b, 0x87, 0xb4, 0xcc, 0x99, 0xa8, 0xe1, 0xb2, 0xd8, 0x65, 0x92, 0x8a, 0x47, 0x34, + }; } }