[PATCH] gr-osmosdr/rtl: bugfix: respect buffer len in cb

Karl Semich 0xloem at gmail.com
Sun Sep 23 12:38:37 UTC 2018


Callback now stores and makes use of rtlsdr data length, preventing
corruption in the case of short reads.
---
 lib/rtl/rtl_source_c.cc | 13 +++++++------
 lib/rtl/rtl_source_c.h  |  2 +-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc
index a371464..215500e 100644
--- a/lib/rtl/rtl_source_c.cc
+++ b/lib/rtl/rtl_source_c.cc
@@ -173,8 +173,6 @@ rtl_source_c::rtl_source_c (const std::string &args)
               << std::endl;
   }
 
-  _samp_avail = _buf_len / BYTES_PER_SAMPLE;
-
   // create a lookup table for gr_complex values
   for (unsigned int i = 0; i < 0x100; i++)
     _lut.push_back((i - 127.4f) / 128.0f);
@@ -232,6 +230,7 @@ rtl_source_c::rtl_source_c (const std::string &args)
   set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */
 
   _buf = (unsigned char **)malloc(_buf_num * sizeof(unsigned char *));
+  _samp_avails = (int *)malloc(_buf_num * sizeof(uint32_t));
 
   if (_buf) {
     for(unsigned int i = 0; i < _buf_num; ++i)
@@ -261,6 +260,8 @@ rtl_source_c::~rtl_source_c ()
       free(_buf[i]);
     }
 
+    free(_samp_avails);
+    _samp_avails = NULL;
     free(_buf);
     _buf = NULL;
   }
@@ -302,6 +303,7 @@ void rtl_source_c::rtlsdr_callback(unsigned char *buf, uint32_t len)
 
     int buf_tail = (_buf_head + _buf_used) % _buf_num;
     memcpy(_buf[buf_tail], buf, len);
+    _samp_avails[buf_tail] = len / BYTES_PER_SAMPLE;
 
     if (_buf_used == _buf_num) {
       std::cerr << "O" << std::flush;
@@ -348,23 +350,22 @@ int rtl_source_c::work( int noutput_items,
     return WORK_DONE;
 
   while (noutput_items && _buf_used) {
-    const int nout = std::min(noutput_items, _samp_avail);
+    const int nout = std::min(noutput_items, _samp_avails[_buf_head]);
     const unsigned char *buf = _buf[_buf_head] + _buf_offset * 2;
 
     for (int i = 0; i < nout; ++i)
       *out++ = gr_complex(_lut[buf[i * 2]], _lut[buf[i * 2 + 1]]);
 
     noutput_items -= nout;
-    _samp_avail -= nout;
+    _samp_avails[_buf_head] -= nout;
 
-    if (!_samp_avail) {
+    if (!_samp_avails[_buf_head]) {
       {
         boost::mutex::scoped_lock lock( _buf_mutex );
 
         _buf_head = (_buf_head + 1) % _buf_num;
         _buf_used--;
       }
-      _samp_avail = _buf_len / BYTES_PER_SAMPLE;
       _buf_offset = 0;
     } else {
       _buf_offset += nout;
diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h
index 902b386..8e537a5 100644
--- a/lib/rtl/rtl_source_c.h
+++ b/lib/rtl/rtl_source_c.h
@@ -127,6 +127,7 @@ private:
   rtlsdr_dev_t *_dev;
   gr::thread::thread _thread;
   unsigned char **_buf;
+  int *_samp_avails;
   unsigned int _buf_num;
   unsigned int _buf_len;
   unsigned int _buf_head;
@@ -136,7 +137,6 @@ private:
   bool _running;
 
   unsigned int _buf_offset;
-  int _samp_avail;
 
   bool _no_tuner;
   bool _auto_gain;
-- 
2.11.0



More information about the osmocom-sdr mailing list