diff --git a/apps/lora_receive_file.py b/apps/lora_receive_file.py
index 810eb7b..bc54d1e 100755
--- a/apps/lora_receive_file.py
+++ b/apps/lora_receive_file.py
@@ -3,7 +3,7 @@
##################################################
# GNU Radio Python Flow Graph
# Title: Lora Receive File
-# Generated: Thu Sep 7 15:38:03 2017
+# Generated: Wed Sep 20 10:10:43 2017
##################################################
if __name__ == '__main__':
@@ -66,7 +66,7 @@ class lora_receive_file(grc_wxgui.top_block_gui):
peak_hold=False,
)
self.Add(self.wxgui_fftsink2_1.win)
- self.lora_lora_receiver_0 = lora.lora_receiver(samp_rate, capture_freq, ([target_freq]), 7, 1000000, 0.002)
+ self.lora_lora_receiver_0 = lora.lora_receiver(samp_rate, capture_freq, ([target_freq]), 7, 1000000, False, 4, True)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, 'counting_cr4_sf7.cfile', True)
diff --git a/apps/lora_receive_realtime.py b/apps/lora_receive_realtime.py
index 3fefa8c..f9afba5 100755
--- a/apps/lora_receive_realtime.py
+++ b/apps/lora_receive_realtime.py
@@ -3,7 +3,7 @@
##################################################
# GNU Radio Python Flow Graph
# Title: Lora Receive Realtime
-# Generated: Thu Sep 14 16:24:32 2017
+# Generated: Wed Sep 20 10:11:08 2017
##################################################
if __name__ == '__main__':
@@ -81,7 +81,7 @@ class lora_receive_realtime(grc_wxgui.top_block_gui):
self.osmosdr_source_0.set_bandwidth(0, 0)
self.lora_message_socket_sink_0 = lora.message_socket_sink('127.0.0.1', 40868, False, True)
- self.lora_lora_receiver_0 = lora.lora_receiver(samp_rate, capture_freq, ([target_freq]), sf, internal_sampling_rate, 0.002)
+ self.lora_lora_receiver_0 = lora.lora_receiver(samp_rate, capture_freq, ([target_freq]), sf, internal_sampling_rate, False, 4, True)
##################################################
# Connections
diff --git a/docs/test-results/decode_long_hackrf.md b/docs/test-results/decode_long_hackrf.md
index d2e6b97..cb7b8ca 100644
--- a/docs/test-results/decode_long_hackrf.md
+++ b/docs/test-results/decode_long_hackrf.md
@@ -1,6 +1,6 @@
# Test suite: 'decode_long_hackrf'
-*Results on 2017-09-15 11:28:32.183183*
+*Results on 2017-09-20 07:54:45.563359*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/docs/test-results/decode_long_rtl-sdr.md b/docs/test-results/decode_long_rtl-sdr.md
index afce559..c15f775 100644
--- a/docs/test-results/decode_long_rtl-sdr.md
+++ b/docs/test-results/decode_long_rtl-sdr.md
@@ -1,6 +1,6 @@
# Test suite: 'decode_long_rtl-sdr'
-*Results on 2017-09-15 11:27:16.260766*
+*Results on 2017-09-20 07:53:29.656650*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/docs/test-results/decode_long_usrp.md b/docs/test-results/decode_long_usrp.md
index 164c773..9776b4d 100644
--- a/docs/test-results/decode_long_usrp.md
+++ b/docs/test-results/decode_long_usrp.md
@@ -1,6 +1,6 @@
# Test suite: 'decode_long_usrp'
-*Results on 2017-09-15 11:27:52.849819*
+*Results on 2017-09-20 07:54:06.220649*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/docs/test-results/short_hackrf.md b/docs/test-results/short_hackrf.md
index dc1e35e..00ce432 100644
--- a/docs/test-results/short_hackrf.md
+++ b/docs/test-results/short_hackrf.md
@@ -1,6 +1,6 @@
# Test suite: 'short_hackrf'
-*Results on 2017-09-15 11:37:48.801373*
+*Results on 2017-09-20 08:04:02.415820*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/docs/test-results/short_rtl-sdr.md b/docs/test-results/short_rtl-sdr.md
index cd6be43..72dd9e0 100644
--- a/docs/test-results/short_rtl-sdr.md
+++ b/docs/test-results/short_rtl-sdr.md
@@ -1,6 +1,6 @@
# Test suite: 'short_rtl-sdr'
-*Results on 2017-09-15 11:29:09.534517*
+*Results on 2017-09-20 07:55:22.913194*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/docs/test-results/short_usrp.md b/docs/test-results/short_usrp.md
index 4d4e893..680771c 100644
--- a/docs/test-results/short_usrp.md
+++ b/docs/test-results/short_usrp.md
@@ -1,6 +1,6 @@
# Test suite: 'short_usrp'
-*Results on 2017-09-15 11:33:12.759248*
+*Results on 2017-09-20 07:59:26.311889*
### 868.1 MHz, SF 7, CR 4/8, BW 125 kHz, prlen 8, crc on, implicit off
diff --git a/grc/lora_receiver.xml b/grc/lora_receiver.xml
index 0b98210..77c7ccd 100644
--- a/grc/lora_receiver.xml
+++ b/grc/lora_receiver.xml
@@ -4,12 +4,11 @@
lora_lora_receiver
[LoRa]
import lora
- lora.lora_receiver($in_samp_rate, $center_freq, $channel_list, $sf, $out_samp_rate, $threshold)
+ lora.lora_receiver($in_samp_rate, $center_freq, $channel_list, $sf, $out_samp_rate, $implicit, $cr, $crc)
set_center_freq($freq)
set_sf($sf)
set_out_samp_rate($out_samp_rate)
- set_threshold($threshold)
Sample rate
@@ -39,10 +38,57 @@
- Detection threshold
- threshold
- 0.01
- float
+ Implicit header
+ implicit
+ enum
+
+
+
+
+
+ Coding rate
+ cr
+ enum
+ $implicit.hide_imp
+
+
+
+
+
+
+
+ CRC
+ crc
+ enum
+ $implicit.hide_imp
+
+
diff --git a/include/lora/decoder.h b/include/lora/decoder.h
index ef596c1..94fcb2e 100644
--- a/include/lora/decoder.h
+++ b/include/lora/decoder.h
@@ -702,11 +702,10 @@ namespace gr {
* class. lora::decoder::make is the public interface for
* creating new instances.
*/
- static sptr make(float samp_rate, int sf);
+ static sptr make(float samp_rate, int sf, bool implicit, uint8_t cr, bool crc);
virtual void set_sf(uint8_t sf) = 0;
virtual void set_samp_rate(float samp_rate) = 0;
- virtual void set_abs_threshold(float threshold) = 0;
};
} // namespace lora
diff --git a/include/lora/utilities.h b/include/lora/utilities.h
index d8e631b..bf96a88 100644
--- a/include/lora/utilities.h
+++ b/include/lora/utilities.h
@@ -338,6 +338,16 @@ namespace gr {
out << std::flush;
}
+ inline bool header_checksum(const uint8_t* header) {
+ (void) header;
+ /*Found valid order for bit #0: (1, 4, 8, 9, 10, 11)
+ Found valid order for bit #1: (0, 2, 5, 8, 9, 10)
+ Found valid order for bit #2: (0, 3, 6, 9, 11)
+ Found valid order for bit #3: (1, 2, 3, 7, 8)
+ Found valid order for bit #4: (4, 5, 6, 7)*/
+ return true;
+ }
+
inline uint32_t dissect_packet(const void **header, uint32_t header_size, const uint8_t *buffer, uint32_t offset) {
(*header) = buffer + offset;
return offset + header_size;
diff --git a/lib/decoder_impl.cc b/lib/decoder_impl.cc
index 45798f3..597bb5d 100644
--- a/lib/decoder_impl.cc
+++ b/lib/decoder_impl.cc
@@ -37,15 +37,15 @@
namespace gr {
namespace lora {
- decoder::sptr decoder::make(float samp_rate, int sf) {
+ decoder::sptr decoder::make(float samp_rate, int sf, bool implicit, uint8_t cr, bool crc) {
return gnuradio::get_initial_sptr
- (new decoder_impl(samp_rate, sf));
+ (new decoder_impl(samp_rate, sf, implicit, cr, crc));
}
/**
* The private constructor
*/
- decoder_impl::decoder_impl(float samp_rate, uint8_t sf)
+ decoder_impl::decoder_impl(float samp_rate, uint8_t sf, bool implicit, uint8_t cr, bool crc)
: gr::sync_block("decoder",
gr::io_signature::make(1, -1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, 0)) {
@@ -65,7 +65,9 @@ namespace gr {
#endif
d_bw = 125000u;
- d_phdr.cr = 4;
+ d_implicit = implicit;
+ d_phdr.cr = cr;
+ d_phdr.has_mac_crc = crc;
d_samples_per_second = samp_rate;
d_payload_symbols = 0;
d_cfo_estimation = 0.0f;
@@ -80,7 +82,7 @@ namespace gr {
d_number_of_bins = (uint32_t)(1u << d_sf);
d_number_of_bins_hdr = (uint32_t)(1u << (d_sf-2));
d_decim_factor = d_samples_per_symbol / d_number_of_bins;
- d_energy_threshold = 0.01f;
+ d_energy_threshold = 0.0f;
d_whitening_sequence = gr::lora::prng_payload;
d_fine_sync = 0;
set_output_multiple(2 * d_samples_per_symbol);
@@ -89,6 +91,10 @@ namespace gr {
std::cout << "Bins per symbol: \t" << d_number_of_bins << std::endl;
std::cout << "Samples per symbol: \t" << d_samples_per_symbol << std::endl;
std::cout << "Decimation: \t\t" << d_decim_factor << std::endl;
+ if(d_implicit) {
+ std::cout << "CR: \t\t" << (int)d_phdr.cr << std::endl;
+ std::cout << "CRC: \t\t" << (int)d_phdr.has_mac_crc << std::endl;
+ }
// Locally generated chirps
build_ideal_chirps();
@@ -325,10 +331,20 @@ namespace gr {
volk_32f_accumulator_s32f(&energy_chirp2, magsq_chirp2, window);
autocorr = abs(dot_product / gr_complex(sqrt(energy_chirp1 * energy_chirp2), 0));
+ d_energy_threshold = energy_chirp2 / 2.0f; // When using implicit mode, stop when energy is halved.
return autocorr;
}
+ float decoder_impl::determine_energy(const gr_complex *samples) {
+ float magsq_chirp[d_samples_per_symbol];
+ float energy_chirp = 0;
+ volk_32fc_magnitude_squared_32f(magsq_chirp, samples, d_samples_per_symbol);
+ volk_32f_accumulator_s32f(&energy_chirp, magsq_chirp, d_samples_per_symbol);
+
+ return energy_chirp;
+ }
+
float decoder_impl::detect_downchirp(const gr_complex *samples, const uint32_t window) {
float samples_ifreq[window];
instantaneous_frequency(samples, samples_ifreq, window);
@@ -764,7 +780,12 @@ namespace gr {
}
case gr::lora::DecoderState::PAUSE: {
- d_state = gr::lora::DecoderState::DECODE_HEADER;
+ if(d_implicit){
+ d_state = gr::lora::DecoderState::DECODE_PAYLOAD;
+ d_payload_symbols = 1;
+ } else {
+ d_state = gr::lora::DecoderState::DECODE_HEADER;
+ }
consume_each(d_samples_per_symbol + d_delay_after_sync);
break;
}
@@ -801,26 +822,22 @@ namespace gr {
}
case gr::lora::DecoderState::DECODE_PAYLOAD: {
- //**************************************************************************
- // Failsafe if decoding length reaches end of actual data == noise reached?
- // Could be replaced be rejecting packets with CRC mismatch...
- if (std::abs(input[0]) < d_energy_threshold) {
- //printf("\n*** Decode payload reached end of data! (payload length in HDR is wrong)\n");
+ if (d_implicit && determine_energy(input) < d_energy_threshold) {
d_payload_symbols = 0;
+ //d_demodulated.erase(d_demodulated.begin(), d_demodulated.begin() + 7u); // Test for SF 8 with header
+ d_payload_length = (int32_t)(d_demodulated.size() / 2);
+ } else if (demodulate(input, false)) {
+ if(!d_implicit)
+ d_payload_symbols -= (4u + d_phdr.cr);
}
- //**************************************************************************
- if (demodulate(input, false)) {
- d_payload_symbols -= (4u + d_phdr.cr);
+ if (d_payload_symbols <= 0) {
+ decode(false);
+ gr::lora::print_vector_hex(std::cout, &d_decoded[0], d_payload_length, true);
+ msg_lora_frame();
- if (d_payload_symbols <= 0) {
- decode(false);
- gr::lora::print_vector_hex(std::cout, &d_decoded[0], d_payload_length, true);
- msg_lora_frame();
-
- d_state = gr::lora::DecoderState::DETECT;
- d_decoded.clear();
- }
+ d_state = gr::lora::DecoderState::DETECT;
+ d_decoded.clear();
}
consume_each((int32_t)d_samples_per_symbol+d_fine_sync);
@@ -856,10 +873,5 @@ namespace gr {
std::cerr << "[LoRa Decoder] WARNING : Setting the sample rate during execution is currently not supported." << std::endl
<< "Nothing set, kept SR of " << d_samples_per_second << "." << std::endl;
}
-
- void decoder_impl::set_abs_threshold(const float threshold) {
- d_energy_threshold = gr::lora::clamp(threshold, 0.0f, 20.0f);
- }
-
} /* namespace lora */
} /* namespace gr */
diff --git a/lib/decoder_impl.h b/lib/decoder_impl.h
index c656b44..5d9dd9a 100644
--- a/lib/decoder_impl.h
+++ b/lib/decoder_impl.h
@@ -80,6 +80,7 @@ namespace gr {
std::vector d_mult_hf; ///< Vector containing the FFT decimation.
std::vector d_tmp; ///< Vector containing the FFT decimation.
+ bool d_implicit; ///< Implicit header mode.
uint8_t d_sf; ///< The Spreading Factor.
uint32_t d_bw; ///< The receiver bandwidth (fixed to `125kHz`).
loraphy_header_t d_phdr; ///< LoRa PHY header.
@@ -262,6 +263,14 @@ namespace gr {
*/
void determine_cfo(const gr_complex *samples);
+ /**
+ * \brief Determine the energy of a symbol.
+ *
+ * \param samples
+ * The complex symbol to analyse.
+ */
+ float determine_energy(const gr_complex *samples);
+
/**
* \brief Returns the index of the bin containing the frequency change.
*
@@ -407,7 +416,7 @@ namespace gr {
* \param sf
* The expected spreqding factor.
*/
- decoder_impl(float samp_rate, uint8_t sf);
+ decoder_impl(float samp_rate, uint8_t sf, bool implicit, uint8_t cr, bool crc);
/**
* Default destructor.
@@ -445,16 +454,6 @@ namespace gr {
* The new sample rate.
*/
virtual void set_samp_rate(const float samp_rate);
-
- /**
- * \brief Set the absolute threshold to distinguish signal from noise.
- *
Should be around 0.01f (default) for normal environments,
- *
or as low as 0.001f for the very noise-resistant USRP.
- *
- * \param threshold
- * The new threshold value.
- */
- virtual void set_abs_threshold(const float threshold);
};
} // namespace lora
} // namespace gr
diff --git a/lib/message_socket_sink_impl.cc b/lib/message_socket_sink_impl.cc
index 9d23f35..9ad4c32 100644
--- a/lib/message_socket_sink_impl.cc
+++ b/lib/message_socket_sink_impl.cc
@@ -93,7 +93,7 @@ namespace gr {
offset = gr::lora::dissect_packet((const void **)&loratap_header, sizeof(loratap_header_t), data, offset);
offset = gr::lora::dissect_packet((const void **)&loraphy_header, sizeof(loraphy_header_t), data, offset);
- uint32_t payload_length = loraphy_header->length + (MAC_CRC_SIZE * loraphy_header->has_mac_crc);
+ uint32_t payload_length = size - (sizeof(loratap_header_t) + sizeof(loraphy_header_t));
offset = gr::lora::dissect_packet((const void **)&payload, sizeof(uint8_t)*payload_length, data, offset);
if(offset != size) {
std::cerr << "message_socket_sink_impl::handle: invalid read: " << offset << " != " << size << std::endl;
diff --git a/python/lora_receiver.py b/python/lora_receiver.py
index b744f6e..28f585f 100644
--- a/python/lora_receiver.py
+++ b/python/lora_receiver.py
@@ -26,7 +26,7 @@ class lora_receiver(gr.hier_block2):
"""
docstring for block lora_receiver
"""
- def __init__(self, in_samp_rate, center_freq, channel_list, sf, out_samp_rate, threshold = 0.01):
+ def __init__(self, in_samp_rate, center_freq, channel_list, sf, out_samp_rate, implicit, cr, crc):
gr.hier_block2.__init__(self,
"lora_receiver", # Min, Max, gr.sizeof_
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
@@ -41,8 +41,7 @@ class lora_receiver(gr.hier_block2):
# Define blocks
self.channelizer = lora.channelizer(in_samp_rate, out_samp_rate, center_freq, channel_list)
- self.decoder = lora.decoder(out_samp_rate, sf)
- self.set_threshold(threshold)
+ self.decoder = lora.decoder(out_samp_rate, sf, implicit, cr, crc)
# Messages
self.message_port_register_hier_out('frames')
@@ -66,10 +65,3 @@ class lora_receiver(gr.hier_block2):
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.channelizer.set_center_freq(self.center_freq)
-
- def get_threshold(self):
- return self.threshold
-
- def set_threshold(self, threshold):
- self.threshold = threshold
- self.decoder.set_abs_threshold(self.threshold)
diff --git a/python/qa_testsuite.py b/python/qa_testsuite.py
index 0204b0a..2243097 100755
--- a/python/qa_testsuite.py
+++ b/python/qa_testsuite.py
@@ -246,7 +246,7 @@ class qa_testsuite():
# Build flowgraph
tb = gr.top_block()
file_source = blocks.file_source(gr.sizeof_gr_complex, data_file, False)
- lora_receiver = lora.lora_receiver(sample_rate, capture_freq, [868100000], sf, 1000000, 0.002)
+ lora_receiver = lora.lora_receiver(sample_rate, capture_freq, [868100000], sf, 1000000, False, 4, True)
throttle = blocks.throttle(gr.sizeof_gr_complex, sample_rate, True)
message_socket_sink = lora.message_socket_sink("127.0.0.1", 40868, False, False)
freq_xlating_fir_filter = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, sample_rate, 200000, 100000, firdes.WIN_HAMMING, 6.67)), frequency_offset, sample_rate)