From lucas at teske.net.br Mon Aug 1 01:40:35 2016 From: lucas at teske.net.br (Lucas Teske) Date: Sun, 31 Jul 2016 22:40:35 -0300 Subject: Compiling rtlsdr for windows. In-Reply-To: References: Message-ID: If you're trying to find the librtlsdr, you can get the latest release here: https://github.com/librtlsdr/librtlsdr Since the original repository is somewhat "frozen", we decided to fork it and maintain, so you should be able to get the latest release there. Lucas Em 31/07/2016 20:24, Bill Gaylord escreveu: > I know there is a precompiled binary but it is 2 years out of date. > Anyone have any luck compiling it for 32 bit windows? (I need some > functionality that was just recently added in) From loic.cloatre at amossys.fr Tue Aug 2 14:04:23 2016 From: loic.cloatre at amossys.fr (loic.cloatre) Date: Tue, 2 Aug 2016 16:04:23 +0200 Subject: [Help] first steps with sdrangelove In-Reply-To: References: Message-ID: Hello, Le 20/07/2016 ? 00:06, Martin M?ller a ?crit : >> Hello, > Hi! > >> I have installed all the thing and I get the main API: > What do you mean by ?get the main API?? I try again to install sdrangelove in order to see LORA trafic with a HackRF. > >> How to configure in order to see LoRa trafic? > If you mean LoRaWAN (I never looked at it before) I think you should expect the signal to be around 868 MHz if you?re in Europe and 915 MHz in the US [1]. You have to set this frequency in the rotary digit display on the left either by typing, scrolling the mouse wheel while hovering the mouse pointer over a digit by or selecting a digit and using the up or down arrow keys. (Note: You have to enter the frequency in kHz!) > But this first requires sample acquisition to be running which comes to you error message: Yes, I think my problem is with the sample acquisition because I cannot change the frequency by scrolling my mouse > >> (if I click on aquisition, I get an error message "no sample source configured?) > The error message you get on starting sample acquisition probably means that there was no SDR device found. > What software defined radio device are you using? I am using one HackRF > >> Maybe a quickstart help exists? > I fear there is no more information available than provided on the sparse website :( > > Maybe posting relevant output in the console might help. > > Regards > Martin From nkcyham at yahoo.com Fri Aug 5 05:09:49 2016 From: nkcyham at yahoo.com (Neoklis Kyriazis) Date: Fri, 5 Aug 2016 05:09:49 +0000 (UTC) Subject: Uccess! My first librtlsdr application References: <1565657774.9528793.1470373789409.JavaMail.yahoo.ref@mail.yahoo.com> Message-ID: <1565657774.9528793.1470373789409.JavaMail.yahoo@mail.yahoo.com> Hi First, my thanks to everyone involved with the development and release of librtlsdr. Well done. :-) I always wanted to try my hand building an SDR application and so I installed the latest librtlsdr and started writing code to test the various functions in the librtlsdr library. Having gotten familiar with this, I started work on modifying my old Wx satellite APT image decoder app, xwxapt, to support an rtlsdr receiver beside the linear VHF receiver it was written for. Its always difficult to extensively modify an existing app, but in the end it all worked out well and xwxapt can now receive the old APT format images from Wx sats with the rtl-sdr receiver. In the process, I modified xwxapt to include controls for the rtl-sdr unit, display an FFT-derived spectrum of the 2.4kHz sub-carrier and a spectrum of the baseband O/P of the RTL2832 device. Images are decoded in real time and displayed incrementally in xwxapt's window. xwxapt is available under the GPL at: http://www.5b4az.org/ in Weather Imaging->Image Decoders menu. -- Best Regards Neoklis - Ham Radio Call:5B4AZ http://www.5b4az.org/ From lucas at teske.net.br Fri Aug 5 16:29:29 2016 From: lucas at teske.net.br (Lucas Teske) Date: Fri, 5 Aug 2016 13:29:29 -0300 Subject: Uccess! My first librtlsdr application In-Reply-To: <1565657774.9528793.1470373789409.JavaMail.yahoo@mail.yahoo.com> References: <1565657774.9528793.1470373789409.JavaMail.yahoo.ref@mail.yahoo.com> <1565657774.9528793.1470373789409.JavaMail.yahoo@mail.yahoo.com> Message-ID: Nice Neoklis! It looks good, I will give a try on the weekend :D Btw, you should post the source-code at github, in this way it is easier to submit patches and stuff. Lucas Em 05/08/2016 02:09, Neoklis Kyriazis escreveu: > Hi > > > First, my thanks to everyone involved with the development and > release of librtlsdr. Well done. :-) > > I always wanted to try my hand building an SDR application and > so I installed the latest librtlsdr and started writing code > > to test the various functions in the librtlsdr library. Having > gotten familiar with this, I started work on modifying my old > Wx satellite APT image decoder app, xwxapt, to support an rtlsdr > receiver beside the linear VHF receiver it was written for. > > Its always difficult to extensively modify an existing app, but > in the end it all worked out well and xwxapt can now receive the > old APT format images from Wx sats with the rtl-sdr receiver. In > the process, I modified xwxapt to include controls for the rtl-sdr > unit, display an FFT-derived spectrum of the 2.4kHz sub-carrier > and a spectrum of the baseband O/P of the RTL2832 device. Images > are decoded in real time and displayed incrementally in xwxapt's > window. xwxapt is available under the GPL at: > > > http://www.5b4az.org/ in Weather Imaging->Image Decoders menu. > > -- > Best Regards > Neoklis - Ham Radio Call:5B4AZ > http://www.5b4az.org/ -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3823 bytes Desc: Assinatura criptogr??fica S/MIME URL: From ptrkrysik at gmail.com Mon Aug 8 11:14:30 2016 From: ptrkrysik at gmail.com (Piotr Krysik) Date: Mon, 8 Aug 2016 13:14:30 +0200 Subject: Fwd: Development of rtl-sdr driver In-Reply-To: <1802ccb1-85c7-4a10-7544-9dc878ccb172@gmail.com> References: <1802ccb1-85c7-4a10-7544-9dc878ccb172@gmail.com> Message-ID: Hi everyone, I've send the e-mail to the OpenBSC list before, but as I was informed by Harald this is the right place for such discussions. So I'm resending it here. The osmocom's version of rtl-sdr driver seems to be the main one. Osmocom's repository is used by distributions to build rtl-sdr packages and it is source of the code for compilation with use of GNU Radio's Pybombs. Is there someone in the Osmocom who is maintaining it? There were some important developments regarding this driver and it would be great to add these patches in the Osmocom's repo. For example one that interests me is turning off dithering so multiple dongles sharing the same clock generate the same LO frequency. Currently there is always little frequency offset that makes coherent of the receivers operation much harder. Such changes of course have to be done carefully so nothing gets broken in the process. In case of turning off dithering it results with worse tuning granularity, so for example turning it off could be made optional. -- Best Regards, Piotr Krysik From khc at pm.waw.pl Wed Aug 24 21:43:03 2016 From: khc at pm.waw.pl (Krzysztof Halasa) Date: Wed, 24 Aug 2016 23:43:03 +0200 Subject: RTL-SDR and RTL-TCP drivers Message-ID: Hello, it's my first mail on this list, so please forgive me if I do something wrong. I'm about to post a couple of patches for RTL drivers: 1. RTL-SDR: convert _lut to float[] to reduce size by a factor of 256. The _lut is being indexed by I + Q (16 bits = 65536 entries), however both samples can be processed independently, resulting in 8-bit LUT. Saves a bit of RAM and CPU cache. lib/rtl/rtl_source_c.cc | 19 ++++++------------- lib/rtl/rtl_source_c.h | 4 ++-- 2 files changed, 8 insertions(+), 15 deletions(-) 2. RTL-TCP: Convert to single class model The existing RTL TCP driver is quite different from its brother RTL_SDR. It's much more complicated, uses gr::blocks::deinterleave and gr::blocks::float_to_complex, and generally doesn't work correctly (e.g. https://github.com/csete/gqrx/issues/99 Spectrum is mirrored when filter or demodulator changes (rtl_tcp) #99) I've converted the RTL TCP driver to the model used by RTL_SDR, simplifying it in the process, and fixing the GQRX issue. lib/rtl_tcp/CMakeLists.txt | 1 - lib/rtl_tcp/rtl_tcp_source_c.cc | 352 ++++++++++++++++++++++++++++++++-------- lib/rtl_tcp/rtl_tcp_source_c.h | 32 +++- lib/rtl_tcp/rtl_tcp_source_f.cc | 327 ------------------------------------- lib/rtl_tcp/rtl_tcp_source_f.h | 125 -------------- 5 files changed, 309 insertions(+), 528 deletions(-) I'm also thinking about merging the code common to RTL-SDR and RTL-TCP, but this it's done yet. Comments? -- Krzysztof Halasa From khc at pm.waw.pl Wed Aug 24 21:53:39 2016 From: khc at pm.waw.pl (Krzysztof Halasa) Date: Wed, 24 Aug 2016 23:53:39 +0200 Subject: [PATCH] RTL-SDR: convert _lut to float[] to reduce size by a factor of 256 In-Reply-To: (Krzysztof Halasa's message of "Wed, 24 Aug 2016 23:43:03 +0200") References: Message-ID: The _lut is being indexed by I + Q (16 bits = 65536 entries), however both samples can be processed independently, resulting in 8-bit LUT. Saves a bit of RAM and CPU cache. diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index 93328b8..999ff9e 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -172,15 +172,8 @@ rtl_source_c::rtl_source_c (const std::string &args) _samp_avail = _buf_len / BYTES_PER_SAMPLE; // create a lookup table for gr_complex values - for (unsigned int i = 0; i <= 0xffff; i++) { -#ifdef BOOST_LITTLE_ENDIAN - _lut.push_back( gr_complex( (float(i & 0xff) - 127.4f) * (1.0f/128.0f), - (float(i >> 8) - 127.4f) * (1.0f/128.0f) ) ); -#else // BOOST_BIG_ENDIAN - _lut.push_back( gr_complex( (float(i >> 8) - 127.4f) * (1.0f/128.0f), - (float(i & 0xff) - 127.4f) * (1.0f/128.0f) ) ); -#endif - } + for (unsigned int i = 0; i < 0x100; i++) + _lut.push_back((i - 127.4f) / 128.0f); _dev = NULL; ret = rtlsdr_open( &_dev, dev_index ); @@ -230,11 +223,11 @@ 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 short **) malloc(_buf_num * sizeof(unsigned short *)); + _buf = (unsigned char **)malloc(_buf_num * sizeof(unsigned char *)); if (_buf) { for(unsigned int i = 0; i < _buf_num; ++i) - _buf[i] = (unsigned short *) malloc(_buf_len); + _buf[i] = (unsigned char *)malloc(_buf_len); } } @@ -348,10 +341,10 @@ int rtl_source_c::work( int noutput_items, while (noutput_items && _buf_used) { const int nout = std::min(noutput_items, _samp_avail); - const unsigned short *buf = _buf[_buf_head] + _buf_offset; + const unsigned char *buf = _buf[_buf_head] + _buf_offset * 2; for (int i = 0; i < nout; ++i) - *out++ = _lut[ *(buf + i) ]; + *out++ = gr_complex(_lut[buf[i * 2]], _lut[buf[i * 2 + 1]]); noutput_items -= nout; _samp_avail -= nout; diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h index 76de400..902b386 100644 --- a/lib/rtl/rtl_source_c.h +++ b/lib/rtl/rtl_source_c.h @@ -122,11 +122,11 @@ private: static void _rtlsdr_wait(rtl_source_c *obj); void rtlsdr_wait(); - std::vector _lut; + std::vector _lut; rtlsdr_dev_t *_dev; gr::thread::thread _thread; - unsigned short **_buf; + unsigned char **_buf; unsigned int _buf_num; unsigned int _buf_len; unsigned int _buf_head; From khc at pm.waw.pl Wed Aug 24 21:55:40 2016 From: khc at pm.waw.pl (Krzysztof Halasa) Date: Wed, 24 Aug 2016 23:55:40 +0200 Subject: [PATCH] RTL-TCP: Convert to single class model In-Reply-To: (Krzysztof Halasa's message of "Wed, 24 Aug 2016 23:43:03 +0200") References: Message-ID: The existing RTL TCP driver is quite different from its brother RTL_SDR. It's much more complicated, uses gr::blocks::deinterleave and gr::blocks::float_to_complex, and generally doesn't work correctly (e.g. https://github.com/csete/gqrx/issues/99 Spectrum is mirrored when filter or demodulator changes (rtl_tcp) #99) I've converted the RTL TCP driver to the model used by RTL_SDR, simplifying it in the process, and fixing the GQRX issue. diff --git a/lib/rtl_tcp/CMakeLists.txt b/lib/rtl_tcp/CMakeLists.txt index 18400fd..9f7c201 100644 --- a/lib/rtl_tcp/CMakeLists.txt +++ b/lib/rtl_tcp/CMakeLists.txt @@ -26,7 +26,6 @@ include_directories( ) set(rtl_tcp_srcs - ${CMAKE_CURRENT_SOURCE_DIR}/rtl_tcp_source_f.cc ${CMAKE_CURRENT_SOURCE_DIR}/rtl_tcp_source_c.cc ) diff --git a/lib/rtl_tcp/rtl_tcp_source_c.cc b/lib/rtl_tcp/rtl_tcp_source_c.cc index a365688..64a3f77 100644 --- a/lib/rtl_tcp/rtl_tcp_source_c.cc +++ b/lib/rtl_tcp/rtl_tcp_source_c.cc @@ -1,4 +1,4 @@ -/* -*- c++ -*- */ +/* -*- mode: c++; c-basic-offset: 2 -*- */ /* * Copyright 2012 Dimitri Stolnikov * @@ -26,31 +26,114 @@ #include #include -#include -#include #include "rtl_tcp_source_c.h" - #include "arg_helpers.h" +#if defined(_WIN32) +// if not posix, assume winsock +#pragma comment(lib, "ws2_32.lib") +#define USING_WINSOCK +#include +#include +#define SHUT_RDWR 2 +typedef char* optval_t; +#else +#include +#include +#include +#include +#include +#include +typedef void* optval_t; +#endif + +#ifdef _MSC_VER +#include +typedef ptrdiff_t ssize_t; +#endif //_MSC_VER + +#ifndef _WIN32 +#include +#else +#include +#endif + +#define BYTES_PER_SAMPLE 2 // rtl_tcp device delivers 8 bit unsigned IQ data + +/* copied from rtl sdr code */ +typedef struct { /* structure size must be multiple of 2 bytes */ + char magic[4]; + uint32_t tuner_type; + uint32_t tuner_gain_count; +} dongle_info_t; + +#ifdef _WIN32 +#define __attribute__(x) +#pragma pack(push, 1) +#endif +struct command { + unsigned char cmd; + unsigned int param; +} __attribute__((packed)); +#ifdef _WIN32 +#pragma pack(pop) +#endif + +#define USE_SELECT 1 // non-blocking receive on all platforms +#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin +#define SRC_VERBOSE 0 +#define SNK_VERBOSE 0 + +static int is_error( int perr ) +{ + // Compare error to posix error code; return nonzero if match. +#if defined(USING_WINSOCK) +#define ENOPROTOOPT 109 + // All codes to be checked for must be defined below + int werr = WSAGetLastError(); + switch( werr ) { + case WSAETIMEDOUT: + return( perr == EAGAIN ); + case WSAENOPROTOOPT: + return( perr == ENOPROTOOPT ); + default: + fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", perr, werr ); + throw std::runtime_error("internal error"); + } + return 0; +#else + return( perr == errno ); +#endif +} + +static void report_error( const char *msg1, const char *msg2 ) +{ + // Deal with errors, both posix and winsock +#if defined(USING_WINSOCK) + int werr = WSAGetLastError(); + fprintf(stderr, "%s: winsock error %d\n", msg1, werr ); +#else + perror(msg1); +#endif + if( msg2 != NULL ) + throw std::runtime_error(msg2); + return; +} + using namespace boost::assign; -static std::string get_tuner_name( enum rtlsdr_tuner tuner_type ) +const char * rtl_tcp_source_c::get_tuner_name(void) { - if ( RTLSDR_TUNER_E4000 == tuner_type ) - return "E4000"; - else if ( RTLSDR_TUNER_FC0012 == tuner_type ) - return "FC0012"; - else if ( RTLSDR_TUNER_FC0013 == tuner_type ) - return "FC0013"; - else if ( RTLSDR_TUNER_FC2580 == tuner_type ) - return "FC2580"; - else if ( RTLSDR_TUNER_R820T == tuner_type ) - return "R820T"; - else if ( RTLSDR_TUNER_R828D == tuner_type ) - return "R828D"; - else - return "Unknown"; + switch (d_tuner_type) { + case RTLSDR_TUNER_E4000: return "E4000"; + case RTLSDR_TUNER_FC0012: return "FC0012"; + case RTLSDR_TUNER_FC0013: return "FC0013"; + case RTLSDR_TUNER_FC2580: return "FC2580"; + case RTLSDR_TUNER_R820T: return "R820T"; + case RTLSDR_TUNER_R828D: return "R828D"; + default: return "Unknown"; + } } rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const std::string &args) @@ -59,9 +142,10 @@ rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const std::string &args) } rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : - gr::hier_block2("rtl_tcp_source_c", + gr::sync_block("rtl_tcp_source_c", gr::io_signature::make(0, 0, 0), gr::io_signature::make(1, 1, sizeof (gr_complex))), + d_socket(-1), _no_tuner(false), _auto_gain(false), _if_gain(0) @@ -107,43 +191,162 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : if (payload_size <= 0) payload_size = 16384; - _src = make_rtl_tcp_source_f(sizeof(float), host.c_str(), port, payload_size); +#if defined(USING_WINSOCK) // for Windows (with MinGW) + // initialize winsock DLL + WSADATA wsaData; + int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); + if( iResult != NO_ERROR ) { + report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" ); + } +#endif - if ( _src->get_tuner_type() != RTLSDR_TUNER_UNKNOWN ) - { + // Set up the address stucture for the source address and port numbers + // Get the source IP address from the host name + struct addrinfo *ip_src; // store the source IP address to use + struct addrinfo hints; + memset( (void*)&hints, 0, sizeof(hints) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; + char port_str[12]; + sprintf( port_str, "%d", port ); + + // FIXME leaks if report_error throws below + int ret = getaddrinfo(host.c_str(), port_str, &hints, &ip_src); + if (ret != 0) + report_error("rtl_tcp_source_f/getaddrinfo", + "can't initialize source socket" ); + + // FIXME leaks if report_error throws below + d_temp_buff = new unsigned char[payload_size]; // allow it to hold up to payload_size bytes + d_LUT = new float[0x100]; + for (int i = 0; i < 0x100; ++i) + d_LUT[i] = (((float)(i & 0xff)) - 127.4f) * (1.0f / 128.0f); + + // create socket + d_socket = socket(ip_src->ai_family, ip_src->ai_socktype, + ip_src->ai_protocol); + if (d_socket == -1) + report_error("socket open","can't open socket"); + + // Turn on reuse address + int opt_val = 1; + if (setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) + report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR"); + + // Don't wait when shutting down + linger lngr; + lngr.l_onoff = 1; + lngr.l_linger = 0; + if (setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) + if (!is_error(ENOPROTOOPT)) // no SO_LINGER for SOCK_DGRAM on Windows + report_error("SO_LINGER","can't set socket option SO_LINGER"); + +#if USE_RCV_TIMEO + // Set a timeout on the receive function to not block indefinitely + // This value can (and probably should) be changed + // Ignored on Cygwin +#if defined(USING_WINSOCK) + DWORD timeout = 1000; // milliseconds +#else + timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; +#endif + if (setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) + report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO"); +#endif // USE_RCV_TIMEO + + while (::connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0) + ; // FIXME handle errors? + freeaddrinfo(ip_src); + + int flag = 1; + setsockopt(d_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,sizeof(flag)); + + dongle_info_t dongle_info; + ret = recv(d_socket, (char*)&dongle_info, sizeof(dongle_info), 0); + if (sizeof(dongle_info) != ret) + fprintf(stderr,"failed to read dongle info\n"); + + d_tuner_type = RTLSDR_TUNER_UNKNOWN; + d_tuner_gain_count = 0; + d_tuner_if_gain_count = 0; + + if (memcmp(dongle_info.magic, "RTL0", 4) == 0) { + d_tuner_type = rtlsdr_tuner(ntohl(dongle_info.tuner_type)); + d_tuner_gain_count = ntohl(dongle_info.tuner_gain_count); + if (RTLSDR_TUNER_E4000 == d_tuner_type) + d_tuner_if_gain_count = 53; + } + + if (d_tuner_type != RTLSDR_TUNER_UNKNOWN) { std::cerr << "The RTL TCP server reports a " - << get_tuner_name( _src->get_tuner_type() ) + << get_tuner_name() << " tuner with " - << _src->get_tuner_gain_count() << " RF and " - << _src->get_tuner_if_gain_count() << " IF gains." + << d_tuner_gain_count << " RF and " + << d_tuner_if_gain_count << " IF gains." << std::endl; } set_gain_mode(false); /* enable manual gain mode by default */ - _src->set_direct_sampling(direct_samp); - if (direct_samp) { + // set direct sampling + struct command cmd = { 0x09, htonl(direct_samp) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); + if (direct_samp) _no_tuner = true; - } - _src->set_offset_tuning(offset_tune); - - /* rtl tcp source provides a stream of interleaved IQ floats */ - gr::blocks::deinterleave::sptr deinterleave = \ - gr::blocks::deinterleave::make( sizeof(float) ); + // set offset tuning + cmd = { 0x0a, htonl(offset_tune) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); +} - /* block to convert deinterleaved floats to a complex stream */ - gr::blocks::float_to_complex::sptr f2c = \ - gr::blocks::float_to_complex::make( 1 ); +rtl_tcp_source_c::~rtl_tcp_source_c() +{ + delete [] d_temp_buff; + + if (d_socket != -1) { + shutdown(d_socket, SHUT_RDWR); +#if defined(USING_WINSOCK) + closesocket(d_socket); +#else + ::close(d_socket); +#endif + d_socket = -1; + } - connect(_src, 0, deinterleave, 0); - connect(deinterleave, 0, f2c, 0); /* I */ - connect(deinterleave, 1, f2c, 1); /* Q */ - connect(f2c, 0, self(), 0); +#if defined(USING_WINSOCK) // for Windows (with MinGW) + // free winsock resources + WSACleanup(); +#endif } -rtl_tcp_source_c::~rtl_tcp_source_c() + +int rtl_tcp_source_c::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gr_complex *out = (gr_complex *)output_items[0]; + int bytesleft = noutput_items * BYTES_PER_SAMPLE; + int index = 0; + int receivedbytes = 0; + while (bytesleft > 0) { + receivedbytes = recv(d_socket, (char*)&d_temp_buff[index], bytesleft, 0); + + if (receivedbytes == -1 && !is_error(EAGAIN)) { + fprintf(stderr, "socket error\n"); + return -1; + } + bytesleft -= receivedbytes; + index += receivedbytes; + } + + for (int i = 0; i < noutput_items; i++) + out[i] = gr_complex(d_LUT[d_temp_buff[i * 2]], d_LUT[d_temp_buff[i * 2 + 1]]); + + return noutput_items; } std::string rtl_tcp_source_c::name() @@ -193,7 +396,8 @@ osmosdr::meta_range_t rtl_tcp_source_c::get_sample_rates( void ) double rtl_tcp_source_c::set_sample_rate( double rate ) { - _src->set_sample_rate( int(rate) ); + struct command cmd = { 0x02, htonl(rate) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); _rate = rate; @@ -214,24 +418,26 @@ osmosdr::freq_range_t rtl_tcp_source_c::get_freq_range( size_t chan ) return range; } - enum rtlsdr_tuner tuner = _src->get_tuner_type(); - - if ( tuner == RTLSDR_TUNER_E4000 ) { - /* there is a (temperature dependent) gap between 1100 to 1250 MHz */ - range += osmosdr::range_t( 52e6, 2.2e9 ); - } else if ( tuner == RTLSDR_TUNER_FC0012 ) { + switch (d_tuner_type) { + case RTLSDR_TUNER_FC0012: range += osmosdr::range_t( 22e6, 948e6 ); - } else if ( tuner == RTLSDR_TUNER_FC0013 ) { + break; + case RTLSDR_TUNER_FC0013: range += osmosdr::range_t( 22e6, 1.1e9 ); - } else if ( tuner == RTLSDR_TUNER_FC2580 ) { + break; + case RTLSDR_TUNER_FC2580: range += osmosdr::range_t( 146e6, 308e6 ); range += osmosdr::range_t( 438e6, 924e6 ); - } else if ( tuner == RTLSDR_TUNER_R820T ) { + break; + case RTLSDR_TUNER_R820T: range += osmosdr::range_t( 24e6, 1766e6 ); - } else if ( tuner == RTLSDR_TUNER_R828D ) { + break; + case RTLSDR_TUNER_R828D: range += osmosdr::range_t( 24e6, 1766e6 ); - } else { - range += osmosdr::range_t( 52e6, 2.2e9 ); // assume E4000 tuner + break; + default: // assume E4000 tuner + /* there is a (temperature dependent) gap between 1100 to 1250 MHz */ + range += osmosdr::range_t( 52e6, 2.2e9 ); } return range; @@ -239,7 +445,8 @@ osmosdr::freq_range_t rtl_tcp_source_c::get_freq_range( size_t chan ) double rtl_tcp_source_c::set_center_freq( double freq, size_t chan ) { - _src->set_freq( int(freq) ); + struct command cmd = { 0x01, htonl(freq) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); _freq = freq; @@ -253,7 +460,8 @@ double rtl_tcp_source_c::get_center_freq( size_t chan ) double rtl_tcp_source_c::set_freq_corr( double ppm, size_t chan ) { - _src->set_freq_corr( int(ppm) ); + struct command cmd = { 0x05, htonl(ppm) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); _corr = ppm; @@ -271,9 +479,8 @@ std::vector rtl_tcp_source_c::get_gain_names( size_t chan ) names += "LNA"; - if ( _src->get_tuner_type() == RTLSDR_TUNER_E4000 ) { + if (d_tuner_type == RTLSDR_TUNER_E4000) names += "IF"; - } return names; } @@ -301,8 +508,7 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( size_t chan ) const int *ptr = NULL; int len = 0; - switch (_src->get_tuner_type()) - { + switch (d_tuner_type) { case RTLSDR_TUNER_E4000: ptr = e4k_gains; len = sizeof(e4k_gains); break; @@ -335,11 +541,10 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( size_t chan ) osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( const std::string & name, size_t chan ) { if ( "IF" == name ) { - if ( _src->get_tuner_type() == RTLSDR_TUNER_E4000 ) { + if (d_tuner_type == RTLSDR_TUNER_E4000) return osmosdr::gain_range_t(3, 56, 1); - } else { + else return osmosdr::gain_range_t(); - } } return get_gain_range( chan ); @@ -347,8 +552,13 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( const std::string & name bool rtl_tcp_source_c::set_gain_mode( bool automatic, size_t chan ) { - _src->set_gain_mode(int(!automatic)); - _src->set_agc_mode(automatic); + // gain mode + struct command cmd = { 0x03, htonl(!automatic) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); + + // AGC mode + cmd = { 0x08, htonl(automatic) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); _auto_gain = automatic; @@ -364,7 +574,8 @@ double rtl_tcp_source_c::set_gain( double gain, size_t chan ) { osmosdr::gain_range_t gains = rtl_tcp_source_c::get_gain_range( chan ); - _src->set_gain( int(gains.clip(gain) * 10.0) ); + struct command cmd = { 0x04, htonl(int(gains.clip(gain) * 10.0)) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); _gain = gain; @@ -396,7 +607,7 @@ double rtl_tcp_source_c::get_gain( const std::string & name, size_t chan ) double rtl_tcp_source_c::set_if_gain(double gain, size_t chan) { - if ( _src->get_tuner_type() != RTLSDR_TUNER_E4000 ) { + if (d_tuner_type != RTLSDR_TUNER_E4000) { _if_gain = 0; return _if_gain; } @@ -448,7 +659,10 @@ double rtl_tcp_source_c::set_if_gain(double gain, size_t chan) std::cerr << " = " << sum << std::endl; #endif for (unsigned int stage = 1; stage <= gains.size(); stage++) { - _src->set_if_gain(stage, int(gains[ stage ] * 10.0)); + int gain_i = int(gains[stage] * 10.0); + uint32_t params = stage << 16 | (gain_i & 0xffff); + struct command cmd = { 0x06, htonl(params) }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); } _if_gain = gain; diff --git a/lib/rtl_tcp/rtl_tcp_source_c.h b/lib/rtl_tcp/rtl_tcp_source_c.h index 454d1a2..b07e5dd 100644 --- a/lib/rtl_tcp/rtl_tcp_source_c.h +++ b/lib/rtl_tcp/rtl_tcp_source_c.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- */ +/* -*- mode: c++; c-basic-offset: 2 -*- */ /* * Copyright 2012 Dimitri Stolnikov * @@ -20,12 +20,10 @@ #ifndef RTL_TCP_SOURCE_C_H #define RTL_TCP_SOURCE_C_H -#include +#include #include "source_iface.h" -#include "rtl_tcp_source_f.h" - class rtl_tcp_source_c; typedef boost::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr; @@ -33,17 +31,33 @@ typedef boost::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr; rtl_tcp_source_c_sptr make_rtl_tcp_source_c( const std::string & args = "" ); class rtl_tcp_source_c : - public gr::hier_block2, + public gr::sync_block, public source_iface { private: + /* copied from rtl sdr */ + enum rtlsdr_tuner { + RTLSDR_TUNER_UNKNOWN = 0, + RTLSDR_TUNER_E4000, + RTLSDR_TUNER_FC0012, + RTLSDR_TUNER_FC0013, + RTLSDR_TUNER_FC2580, + RTLSDR_TUNER_R820T, + RTLSDR_TUNER_R828D + }; + friend rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const std::string &args); rtl_tcp_source_c(const std::string &args); + const char * get_tuner_name(void); public: ~rtl_tcp_source_c(); + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + std::string name(); static std::vector< std::string > get_devices( bool fake = false ); @@ -77,11 +91,17 @@ public: std::string get_antenna( size_t chan = 0 ); private: + int d_socket; // handle to socket double _freq, _rate, _gain, _corr; bool _no_tuner; bool _auto_gain; double _if_gain; - rtl_tcp_source_f_sptr _src; + + enum rtlsdr_tuner d_tuner_type; + unsigned int d_tuner_gain_count; + unsigned int d_tuner_if_gain_count; + unsigned char *d_temp_buff; // hold buffer between calls + float *d_LUT; }; #endif // RTL_TCP_SOURCE_C_H diff --git a/lib/rtl_tcp/rtl_tcp_source_f.cc b/lib/rtl_tcp/rtl_tcp_source_f.cc deleted file mode 100644 index a17594c..0000000 --- a/lib/rtl_tcp/rtl_tcp_source_f.cc +++ /dev/null @@ -1,327 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Hoernchen - * Copyright 2012 Dimitri Stolnikov - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -//#define HAVE_WINDOWS_H - - -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#else -#include -#endif - -/* copied from rtl sdr code */ -typedef struct { /* structure size must be multiple of 2 bytes */ - char magic[4]; - uint32_t tuner_type; - uint32_t tuner_gain_count; -} dongle_info_t; - -#define USE_SELECT 1 // non-blocking receive on all platforms -#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin -#define SRC_VERBOSE 0 -#define SNK_VERBOSE 0 - -static int is_error( int perr ) -{ - // Compare error to posix error code; return nonzero if match. -#if defined(USING_WINSOCK) -#define ENOPROTOOPT 109 - // All codes to be checked for must be defined below - int werr = WSAGetLastError(); - switch( werr ) { - case WSAETIMEDOUT: - return( perr == EAGAIN ); - case WSAENOPROTOOPT: - return( perr == ENOPROTOOPT ); - default: - fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", perr, werr ); - throw std::runtime_error("internal error"); - } - return 0; -#else - return( perr == errno ); -#endif -} - -static void report_error( const char *msg1, const char *msg2 ) -{ - // Deal with errors, both posix and winsock -#if defined(USING_WINSOCK) - int werr = WSAGetLastError(); - fprintf(stderr, "%s: winsock error %d\n", msg1, werr ); -#else - perror(msg1); -#endif - if( msg2 != NULL ) - throw std::runtime_error(msg2); - return; -} - -rtl_tcp_source_f::rtl_tcp_source_f(size_t itemsize, - const char *host, - unsigned short port, - int payload_size, - bool eof, - bool wait) - : gr::sync_block ("rtl_tcp_source_f", - gr::io_signature::make(0, 0, 0), - gr::io_signature::make(1, 1, sizeof(float))), - d_itemsize(itemsize), - d_payload_size(payload_size), - d_eof(eof), - d_wait(wait), - d_socket(-1), - d_temp_offset(0) -{ - int ret = 0; -#if defined(USING_WINSOCK) // for Windows (with MinGW) - // initialize winsock DLL - WSADATA wsaData; - int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); - if( iResult != NO_ERROR ) { - report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" ); - } -#endif - - // Set up the address stucture for the source address and port numbers - // Get the source IP address from the host name - struct addrinfo *ip_src; // store the source IP address to use - struct addrinfo hints; - memset( (void*)&hints, 0, sizeof(hints) ); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - char port_str[12]; - sprintf( port_str, "%d", port ); - - // FIXME leaks if report_error throws below - ret = getaddrinfo( host, port_str, &hints, &ip_src ); - if( ret != 0 ) - report_error("rtl_tcp_source_f/getaddrinfo", - "can't initialize source socket" ); - - // FIXME leaks if report_error throws below - d_temp_buff = new unsigned char[d_payload_size]; // allow it to hold up to payload_size bytes - d_LUT= new float[0xff+1]; - for(int i=0; i <=(0xff);++i){ - d_LUT[i] = (((float)(i&0xff))-127.4f)*(1.0f/128.0f); - } - // create socket - d_socket = socket(ip_src->ai_family, ip_src->ai_socktype, - ip_src->ai_protocol); - if(d_socket == -1) { - report_error("socket open","can't open socket"); - } - - // Turn on reuse address - int opt_val = 1; - if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) { - report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR"); - } - - // Don't wait when shutting down - linger lngr; - lngr.l_onoff = 1; - lngr.l_linger = 0; - if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) { - if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows - report_error("SO_LINGER","can't set socket option SO_LINGER"); - } - } - -#if USE_RCV_TIMEO - // Set a timeout on the receive function to not block indefinitely - // This value can (and probably should) be changed - // Ignored on Cygwin -#if defined(USING_WINSOCK) - DWORD timeout = 1000; // milliseconds -#else - timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; -#endif - if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) { - report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO"); - } -#endif // USE_RCV_TIMEO - - while(connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0); - freeaddrinfo(ip_src); - - int flag = 1; - setsockopt(d_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,sizeof(flag)); - - dongle_info_t dongle_info; - ret = recv(d_socket, (char*)&dongle_info, sizeof(dongle_info), 0); - if (sizeof(dongle_info) != ret) - fprintf(stderr,"failed to read dongle info\n"); - - d_tuner_type = RTLSDR_TUNER_UNKNOWN; - d_tuner_gain_count = 0; - d_tuner_if_gain_count = 0; - - if (memcmp(dongle_info.magic, "RTL0", 4) == 0) - { - d_tuner_type = ntohl(dongle_info.tuner_type); - d_tuner_gain_count = ntohl(dongle_info.tuner_gain_count); - if ( RTLSDR_TUNER_E4000 == d_tuner_type ) - d_tuner_if_gain_count = 53; - } -} - -rtl_tcp_source_f_sptr make_rtl_tcp_source_f (size_t itemsize, - const char *ipaddr, - unsigned short port, - int payload_size, - bool eof, - bool wait) -{ - return gnuradio::get_initial_sptr(new rtl_tcp_source_f ( - itemsize, - ipaddr, - port, - payload_size, - eof, - wait)); -} - -rtl_tcp_source_f::~rtl_tcp_source_f () -{ - delete [] d_temp_buff; - - if (d_socket != -1){ - shutdown(d_socket, SHUT_RDWR); -#if defined(USING_WINSOCK) - closesocket(d_socket); -#else - ::close(d_socket); -#endif - d_socket = -1; - } - -#if defined(USING_WINSOCK) // for Windows (with MinGW) - // free winsock resources - WSACleanup(); -#endif -} - -int rtl_tcp_source_f::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - float *out = (float *) output_items[0]; - ssize_t r = 0; - - int bytesleft = noutput_items; - int index = 0; - int receivedbytes = 0; - while(bytesleft > 0) { - receivedbytes = recv(d_socket, (char*)&d_temp_buff[index], bytesleft, 0); - - if(receivedbytes == -1 && !is_error(EAGAIN)){ - fprintf(stderr, "socket error\n"); - return -1; - } - bytesleft -= receivedbytes; - index += receivedbytes; - } - r = noutput_items; - - for(int i=0; i - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef RTL_TCP_SOURCE_F_H -#define RTL_TCP_SOURCE_F_H - -#include -#include - -#if defined(_WIN32) -// if not posix, assume winsock -#pragma comment(lib, "ws2_32.lib") -#define USING_WINSOCK -#include -#include -#define SHUT_RDWR 2 -typedef char* optval_t; -#else -#include -#include -#include -#include -#include -#include -typedef void* optval_t; -#endif - -#ifdef _MSC_VER -#include -typedef ptrdiff_t ssize_t; -#endif //_MSC_VER - -/* copied from rtl sdr */ -enum rtlsdr_tuner { - RTLSDR_TUNER_UNKNOWN = 0, - RTLSDR_TUNER_E4000, - RTLSDR_TUNER_FC0012, - RTLSDR_TUNER_FC0013, - RTLSDR_TUNER_FC2580, - RTLSDR_TUNER_R820T, - RTLSDR_TUNER_R828D -}; - -class rtl_tcp_source_f; -typedef boost::shared_ptr rtl_tcp_source_f_sptr; - -rtl_tcp_source_f_sptr make_rtl_tcp_source_f ( - size_t itemsize, - const char *host, - unsigned short port, - int payload_size, - bool eof = false, - bool wait = false); - -class rtl_tcp_source_f : public gr::sync_block -{ -private: - size_t d_itemsize; - int d_payload_size; // maximum transmission unit (packet length) - bool d_eof; // zero-length packet is EOF - bool d_wait; // wait if data if not immediately available - int d_socket; // handle to socket - unsigned char *d_temp_buff; // hold buffer between calls - size_t d_temp_offset; // point to temp buffer location offset - float *d_LUT; - - unsigned int d_tuner_type; - unsigned int d_tuner_gain_count; - unsigned int d_tuner_if_gain_count; - -private: - rtl_tcp_source_f(size_t itemsize, const char *host, - unsigned short port, int payload_size, bool eof, bool wait); - - // The friend declaration allows make_source_c to - // access the private constructor. - friend rtl_tcp_source_f_sptr make_rtl_tcp_source_f ( - size_t itemsize, - const char *host, - unsigned short port, - int payload_size, - bool eof, - bool wait); - -public: - ~rtl_tcp_source_f(); - - enum rtlsdr_tuner get_tuner_type() { return (enum rtlsdr_tuner) d_tuner_type; } - unsigned int get_tuner_gain_count() { return d_tuner_gain_count; } - unsigned int get_tuner_if_gain_count() { return d_tuner_if_gain_count; } - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - void set_freq(int freq); - void set_sample_rate(int sample_rate); - void set_gain_mode(int manual); - void set_gain(int gain); - void set_freq_corr(int ppm); - void set_if_gain(int stage, int gain); - void set_agc_mode(int on); - void set_direct_sampling(int on); - void set_offset_tuning(int on); -}; - - -#endif /* RTL_TCP_SOURCE_F_H */ From ct2fzi at gmail.com Wed Aug 24 22:36:12 2016 From: ct2fzi at gmail.com (CT2FZI IM58kr) Date: Wed, 24 Aug 2016 23:36:12 +0100 Subject: osmocom-sdr Digest, Vol 21, Issue 2 In-Reply-To: References: Message-ID: unsubscribe Em 24/08/2016 22:55, escreveu: > Send osmocom-sdr mailing list submissions to > osmocom-sdr at lists.osmocom.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://lists.osmocom.org/mailman/listinfo/osmocom-sdr > or, via email, send a message with subject or body 'help' to > osmocom-sdr-request at lists.osmocom.org > > You can reach the person managing the list at > osmocom-sdr-owner at lists.osmocom.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of osmocom-sdr digest..." > > > Today's Topics: > > 1. PATCH: Fixed arbitrary resampling in rtl_fm > (f.meyer-hermann at gsg-elektronik.de) > 2. Uccess! My first librtlsdr application (Neoklis Kyriazis) > 3. Re: Uccess! My first librtlsdr application (Lucas Teske) > 4. Fwd: Development of rtl-sdr driver (Piotr Krysik) > 5. RTL-SDR and RTL-TCP drivers (Krzysztof Halasa) > 6. [PATCH] RTL-SDR: convert _lut to float[] to reduce size by a > factor of 256 (Krzysztof Halasa) > 7. [PATCH] RTL-TCP: Convert to single class model (Krzysztof Halasa) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Mon, 25 Jul 2016 13:13:13 +0200 > From: f.meyer-hermann at gsg-elektronik.de > To: osmocom-sdr at lists.osmocom.org > Subject: PATCH: Fixed arbitrary resampling in rtl_fm > Message-ID: <20160725111313.GA15278 at gsg-elektronik.de> > Content-Type: text/plain; charset=us-ascii > > As already on github, I fixed rtl_fm's arbitrary resampling by fixing the > output buffer length and allowing upsampling by copying the audio data > since > the algorithm cannot work in-place. > I have attached a patch, if you are interested to integrate it into the > official branch. > Regards, > > Ferdinand Meyer-Hermann > > > ------------------------------ > > Message: 2 > Date: Fri, 5 Aug 2016 05:09:49 +0000 (UTC) > From: Neoklis Kyriazis > To: "osmocom-sdr at lists.osmocom.org" > Subject: Uccess! My first librtlsdr application > Message-ID: > <1565657774.9528793.1470373789409.JavaMail.yahoo at mail.yahoo.com> > Content-Type: text/plain; charset=UTF-8 > > Hi > > > First, my thanks to everyone involved with the development and > release of librtlsdr. Well done. :-) > > I always wanted to try my hand building an SDR application and > so I installed the latest librtlsdr and started writing code > > to test the various functions in the librtlsdr library. Having > gotten familiar with this, I started work on modifying my old > Wx satellite APT image decoder app, xwxapt, to support an rtlsdr > receiver beside the linear VHF receiver it was written for. > > Its always difficult to extensively modify an existing app, but > in the end it all worked out well and xwxapt can now receive the > old APT format images from Wx sats with the rtl-sdr receiver. In > the process, I modified xwxapt to include controls for the rtl-sdr > unit, display an FFT-derived spectrum of the 2.4kHz sub-carrier > and a spectrum of the baseband O/P of the RTL2832 device. Images > are decoded in real time and displayed incrementally in xwxapt's > window. xwxapt is available under the GPL at: > > > http://www.5b4az.org/ in Weather Imaging->Image Decoders menu. > > -- > Best Regards > Neoklis - Ham Radio Call:5B4AZ > http://www.5b4az.org/ > > > ------------------------------ > > Message: 3 > Date: Fri, 5 Aug 2016 13:29:29 -0300 > From: Lucas Teske > To: osmocom-sdr at lists.osmocom.org > Subject: Re: Uccess! My first librtlsdr application > Message-ID: > Content-Type: text/plain; charset="utf-8" > > Nice Neoklis! > > > It looks good, I will give a try on the weekend :D > > > Btw, you should post the source-code at github, in this way it is easier > to submit patches and stuff. > > > Lucas > > Em 05/08/2016 02:09, Neoklis Kyriazis escreveu: > > Hi > > > > > > First, my thanks to everyone involved with the development and > > release of librtlsdr. Well done. :-) > > > > I always wanted to try my hand building an SDR application and > > so I installed the latest librtlsdr and started writing code > > > > to test the various functions in the librtlsdr library. Having > > gotten familiar with this, I started work on modifying my old > > Wx satellite APT image decoder app, xwxapt, to support an rtlsdr > > receiver beside the linear VHF receiver it was written for. > > > > Its always difficult to extensively modify an existing app, but > > in the end it all worked out well and xwxapt can now receive the > > old APT format images from Wx sats with the rtl-sdr receiver. In > > the process, I modified xwxapt to include controls for the rtl-sdr > > unit, display an FFT-derived spectrum of the 2.4kHz sub-carrier > > and a spectrum of the baseband O/P of the RTL2832 device. Images > > are decoded in real time and displayed incrementally in xwxapt's > > window. xwxapt is available under the GPL at: > > > > > > http://www.5b4az.org/ in Weather Imaging->Image Decoders menu. > > > > -- > > Best Regards > > Neoklis - Ham Radio Call:5B4AZ > > http://www.5b4az.org/ > > > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: smime.p7s > Type: application/pkcs7-signature > Size: 3823 bytes > Desc: Assinatura criptogr??fica S/MIME > URL: attachments/20160805/d6b47cd6/attachment-0001.bin> > > ------------------------------ > > Message: 4 > Date: Mon, 8 Aug 2016 13:14:30 +0200 > From: Piotr Krysik > To: osmocom-sdr at lists.osmocom.org > Subject: Fwd: Development of rtl-sdr driver > Message-ID: > Content-Type: text/plain; charset=utf-8 > > > Hi everyone, > > I've send the e-mail to the OpenBSC list before, but as I was informed > by Harald this is the right place for such discussions. So I'm resending > it here. > > The osmocom's version of rtl-sdr driver seems to be the main one. > Osmocom's repository is used by distributions to build rtl-sdr packages > and it is source of the code for compilation with use of GNU Radio's > Pybombs. > > Is there someone in the Osmocom who is maintaining it? There were some > important developments regarding this driver and it would be great to > add these patches in the Osmocom's repo. > > For example one that interests me is turning off dithering so multiple > dongles sharing the same clock generate the same LO frequency. Currently > there is always little frequency offset that makes coherent of the > receivers operation much harder. > > Such changes of course have to be done carefully so nothing gets broken > in the process. In case of turning off dithering it results with worse > tuning granularity, so for example turning it off could be made optional. > > -- > Best Regards, > Piotr Krysik > > > ------------------------------ > > Message: 5 > Date: Wed, 24 Aug 2016 23:43:03 +0200 > From: Krzysztof Halasa > To: osmocom-sdr at lists.osmocom.org > Subject: RTL-SDR and RTL-TCP drivers > Message-ID: > Content-Type: text/plain > > Hello, > > it's my first mail on this list, so please forgive me if I do something > wrong. > > I'm about to post a couple of patches for RTL drivers: > > 1. RTL-SDR: convert _lut to float[] to reduce size by a factor of 256. > > The _lut is being indexed by I + Q (16 bits = 65536 entries), however > both samples can be processed independently, resulting in 8-bit LUT. > Saves a bit of RAM and CPU cache. > > lib/rtl/rtl_source_c.cc | 19 ++++++------------- > lib/rtl/rtl_source_c.h | 4 ++-- > 2 files changed, 8 insertions(+), 15 deletions(-) > > > 2. RTL-TCP: Convert to single class model > > The existing RTL TCP driver is quite different from its brother RTL_SDR. > It's much more complicated, uses gr::blocks::deinterleave and > gr::blocks::float_to_complex, and generally doesn't work correctly > (e.g. https://github.com/csete/gqrx/issues/99 > Spectrum is mirrored when filter or demodulator changes (rtl_tcp) #99) > > I've converted the RTL TCP driver to the model used by RTL_SDR, > simplifying it in the process, and fixing the GQRX issue. > > lib/rtl_tcp/CMakeLists.txt | 1 - > lib/rtl_tcp/rtl_tcp_source_c.cc | 352 ++++++++++++++++++++++++++++++ > ++-------- > lib/rtl_tcp/rtl_tcp_source_c.h | 32 +++- > lib/rtl_tcp/rtl_tcp_source_f.cc | 327 ------------------------------ > ------- > lib/rtl_tcp/rtl_tcp_source_f.h | 125 -------------- > 5 files changed, 309 insertions(+), 528 deletions(-) > > > I'm also thinking about merging the code common to RTL-SDR and RTL-TCP, > but this it's done yet. > > Comments? > -- > Krzysztof Halasa > > > ------------------------------ > > Message: 6 > Date: Wed, 24 Aug 2016 23:53:39 +0200 > From: Krzysztof Halasa > To: osmocom-sdr at lists.osmocom.org > Subject: [PATCH] RTL-SDR: convert _lut to float[] to reduce size by a > factor of 256 > Message-ID: > Content-Type: text/plain > > The _lut is being indexed by I + Q (16 bits = 65536 entries), however > both samples can be processed independently, resulting in 8-bit LUT. > Saves a bit of RAM and CPU cache. > > diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc > index 93328b8..999ff9e 100644 > --- a/lib/rtl/rtl_source_c.cc > +++ b/lib/rtl/rtl_source_c.cc > @@ -172,15 +172,8 @@ rtl_source_c::rtl_source_c (const std::string &args) > _samp_avail = _buf_len / BYTES_PER_SAMPLE; > > // create a lookup table for gr_complex values > - for (unsigned int i = 0; i <= 0xffff; i++) { > -#ifdef BOOST_LITTLE_ENDIAN > - _lut.push_back( gr_complex( (float(i & 0xff) - 127.4f) * > (1.0f/128.0f), > - (float(i >> 8) - 127.4f) * (1.0f/128.0f) > ) ); > -#else // BOOST_BIG_ENDIAN > - _lut.push_back( gr_complex( (float(i >> 8) - 127.4f) * (1.0f/128.0f), > - (float(i & 0xff) - 127.4f) * > (1.0f/128.0f) ) ); > -#endif > - } > + for (unsigned int i = 0; i < 0x100; i++) > + _lut.push_back((i - 127.4f) / 128.0f); > > _dev = NULL; > ret = rtlsdr_open( &_dev, dev_index ); > @@ -230,11 +223,11 @@ 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 short **) malloc(_buf_num * sizeof(unsigned short *)); > + _buf = (unsigned char **)malloc(_buf_num * sizeof(unsigned char *)); > > if (_buf) { > for(unsigned int i = 0; i < _buf_num; ++i) > - _buf[i] = (unsigned short *) malloc(_buf_len); > + _buf[i] = (unsigned char *)malloc(_buf_len); > } > } > > @@ -348,10 +341,10 @@ int rtl_source_c::work( int noutput_items, > > while (noutput_items && _buf_used) { > const int nout = std::min(noutput_items, _samp_avail); > - const unsigned short *buf = _buf[_buf_head] + _buf_offset; > + const unsigned char *buf = _buf[_buf_head] + _buf_offset * 2; > > for (int i = 0; i < nout; ++i) > - *out++ = _lut[ *(buf + i) ]; > + *out++ = gr_complex(_lut[buf[i * 2]], _lut[buf[i * 2 + 1]]); > > noutput_items -= nout; > _samp_avail -= nout; > diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h > index 76de400..902b386 100644 > --- a/lib/rtl/rtl_source_c.h > +++ b/lib/rtl/rtl_source_c.h > @@ -122,11 +122,11 @@ private: > static void _rtlsdr_wait(rtl_source_c *obj); > void rtlsdr_wait(); > > - std::vector _lut; > + std::vector _lut; > > rtlsdr_dev_t *_dev; > gr::thread::thread _thread; > - unsigned short **_buf; > + unsigned char **_buf; > unsigned int _buf_num; > unsigned int _buf_len; > unsigned int _buf_head; > > > ------------------------------ > > Message: 7 > Date: Wed, 24 Aug 2016 23:55:40 +0200 > From: Krzysztof Halasa > To: osmocom-sdr at lists.osmocom.org > Subject: [PATCH] RTL-TCP: Convert to single class model > Message-ID: > Content-Type: text/plain > > The existing RTL TCP driver is quite different from its brother RTL_SDR. > It's much more complicated, uses gr::blocks::deinterleave and > gr::blocks::float_to_complex, and generally doesn't work correctly > (e.g. https://github.com/csete/gqrx/issues/99 > Spectrum is mirrored when filter or demodulator changes (rtl_tcp) #99) > > I've converted the RTL TCP driver to the model used by RTL_SDR, > simplifying it in the process, and fixing the GQRX issue. > > diff --git a/lib/rtl_tcp/CMakeLists.txt b/lib/rtl_tcp/CMakeLists.txt > index 18400fd..9f7c201 100644 > --- a/lib/rtl_tcp/CMakeLists.txt > +++ b/lib/rtl_tcp/CMakeLists.txt > @@ -26,7 +26,6 @@ include_directories( > ) > > set(rtl_tcp_srcs > - ${CMAKE_CURRENT_SOURCE_DIR}/rtl_tcp_source_f.cc > ${CMAKE_CURRENT_SOURCE_DIR}/rtl_tcp_source_c.cc > ) > > diff --git a/lib/rtl_tcp/rtl_tcp_source_c.cc b/lib/rtl_tcp/rtl_tcp_source_ > c.cc > index a365688..64a3f77 100644 > --- a/lib/rtl_tcp/rtl_tcp_source_c.cc > +++ b/lib/rtl_tcp/rtl_tcp_source_c.cc > @@ -1,4 +1,4 @@ > -/* -*- c++ -*- */ > +/* -*- mode: c++; c-basic-offset: 2 -*- */ > /* > * Copyright 2012 Dimitri Stolnikov > * > @@ -26,31 +26,114 @@ > #include > > #include > -#include > -#include > > #include "rtl_tcp_source_c.h" > - > #include "arg_helpers.h" > > +#if defined(_WIN32) > +// if not posix, assume winsock > +#pragma comment(lib, "ws2_32.lib") > +#define USING_WINSOCK > +#include > +#include > +#define SHUT_RDWR 2 > +typedef char* optval_t; > +#else > +#include > +#include > +#include > +#include > +#include > +#include > +typedef void* optval_t; > +#endif > + > +#ifdef _MSC_VER > +#include > +typedef ptrdiff_t ssize_t; > +#endif //_MSC_VER > + > +#ifndef _WIN32 > +#include > +#else > +#include > +#endif > + > +#define BYTES_PER_SAMPLE 2 // rtl_tcp device delivers 8 bit unsigned IQ > data > + > +/* copied from rtl sdr code */ > +typedef struct { /* structure size must be multiple of 2 bytes */ > + char magic[4]; > + uint32_t tuner_type; > + uint32_t tuner_gain_count; > +} dongle_info_t; > + > +#ifdef _WIN32 > +#define __attribute__(x) > +#pragma pack(push, 1) > +#endif > +struct command { > + unsigned char cmd; > + unsigned int param; > +} __attribute__((packed)); > +#ifdef _WIN32 > +#pragma pack(pop) > +#endif > + > +#define USE_SELECT 1 // non-blocking receive on all platforms > +#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin > +#define SRC_VERBOSE 0 > +#define SNK_VERBOSE 0 > + > +static int is_error( int perr ) > +{ > + // Compare error to posix error code; return nonzero if match. > +#if defined(USING_WINSOCK) > +#define ENOPROTOOPT 109 > + // All codes to be checked for must be defined below > + int werr = WSAGetLastError(); > + switch( werr ) { > + case WSAETIMEDOUT: > + return( perr == EAGAIN ); > + case WSAENOPROTOOPT: > + return( perr == ENOPROTOOPT ); > + default: > + fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", > perr, werr ); > + throw std::runtime_error("internal error"); > + } > + return 0; > +#else > + return( perr == errno ); > +#endif > +} > + > +static void report_error( const char *msg1, const char *msg2 ) > +{ > + // Deal with errors, both posix and winsock > +#if defined(USING_WINSOCK) > + int werr = WSAGetLastError(); > + fprintf(stderr, "%s: winsock error %d\n", msg1, werr ); > +#else > + perror(msg1); > +#endif > + if( msg2 != NULL ) > + throw std::runtime_error(msg2); > + return; > +} > + > using namespace boost::assign; > > -static std::string get_tuner_name( enum rtlsdr_tuner tuner_type ) > +const char * rtl_tcp_source_c::get_tuner_name(void) > { > - if ( RTLSDR_TUNER_E4000 == tuner_type ) > - return "E4000"; > - else if ( RTLSDR_TUNER_FC0012 == tuner_type ) > - return "FC0012"; > - else if ( RTLSDR_TUNER_FC0013 == tuner_type ) > - return "FC0013"; > - else if ( RTLSDR_TUNER_FC2580 == tuner_type ) > - return "FC2580"; > - else if ( RTLSDR_TUNER_R820T == tuner_type ) > - return "R820T"; > - else if ( RTLSDR_TUNER_R828D == tuner_type ) > - return "R828D"; > - else > - return "Unknown"; > + switch (d_tuner_type) { > + case RTLSDR_TUNER_E4000: return "E4000"; > + case RTLSDR_TUNER_FC0012: return "FC0012"; > + case RTLSDR_TUNER_FC0013: return "FC0013"; > + case RTLSDR_TUNER_FC2580: return "FC2580"; > + case RTLSDR_TUNER_R820T: return "R820T"; > + case RTLSDR_TUNER_R828D: return "R828D"; > + default: return "Unknown"; > + } > } > > rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const std::string &args) > @@ -59,9 +142,10 @@ rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const > std::string &args) > } > > rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : > - gr::hier_block2("rtl_tcp_source_c", > + gr::sync_block("rtl_tcp_source_c", > gr::io_signature::make(0, 0, 0), > gr::io_signature::make(1, 1, sizeof (gr_complex))), > + d_socket(-1), > _no_tuner(false), > _auto_gain(false), > _if_gain(0) > @@ -107,43 +191,162 @@ rtl_tcp_source_c::rtl_tcp_source_c(const > std::string &args) : > if (payload_size <= 0) > payload_size = 16384; > > - _src = make_rtl_tcp_source_f(sizeof(float), host.c_str(), port, > payload_size); > +#if defined(USING_WINSOCK) // for Windows (with MinGW) > + // initialize winsock DLL > + WSADATA wsaData; > + int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); > + if( iResult != NO_ERROR ) { > + report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" ); > + } > +#endif > > - if ( _src->get_tuner_type() != RTLSDR_TUNER_UNKNOWN ) > - { > + // Set up the address stucture for the source address and port numbers > + // Get the source IP address from the host name > + struct addrinfo *ip_src; // store the source IP address to use > + struct addrinfo hints; > + memset( (void*)&hints, 0, sizeof(hints) ); > + hints.ai_family = AF_UNSPEC; > + hints.ai_socktype = SOCK_STREAM; > + hints.ai_protocol = IPPROTO_TCP; > + hints.ai_flags = AI_PASSIVE; > + char port_str[12]; > + sprintf( port_str, "%d", port ); > + > + // FIXME leaks if report_error throws below > + int ret = getaddrinfo(host.c_str(), port_str, &hints, &ip_src); > + if (ret != 0) > + report_error("rtl_tcp_source_f/getaddrinfo", > + "can't initialize source socket" ); > + > + // FIXME leaks if report_error throws below > + d_temp_buff = new unsigned char[payload_size]; // allow it to hold up > to payload_size bytes > + d_LUT = new float[0x100]; > + for (int i = 0; i < 0x100; ++i) > + d_LUT[i] = (((float)(i & 0xff)) - 127.4f) * (1.0f / 128.0f); > + > + // create socket > + d_socket = socket(ip_src->ai_family, ip_src->ai_socktype, > + ip_src->ai_protocol); > + if (d_socket == -1) > + report_error("socket open","can't open socket"); > + > + // Turn on reuse address > + int opt_val = 1; > + if (setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, > sizeof(int)) == -1) > + report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR"); > + > + // Don't wait when shutting down > + linger lngr; > + lngr.l_onoff = 1; > + lngr.l_linger = 0; > + if (setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, > sizeof(linger)) == -1) > + if (!is_error(ENOPROTOOPT)) // no SO_LINGER for SOCK_DGRAM on Windows > + report_error("SO_LINGER","can't set socket option SO_LINGER"); > + > +#if USE_RCV_TIMEO > + // Set a timeout on the receive function to not block indefinitely > + // This value can (and probably should) be changed > + // Ignored on Cygwin > +#if defined(USING_WINSOCK) > + DWORD timeout = 1000; // milliseconds > +#else > + timeval timeout; > + timeout.tv_sec = 1; > + timeout.tv_usec = 0; > +#endif > + if (setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, > sizeof(timeout)) == -1) > + report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO"); > +#endif // USE_RCV_TIMEO > + > + while (::connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0) > + ; // FIXME handle errors? > + freeaddrinfo(ip_src); > + > + int flag = 1; > + setsockopt(d_socket, IPPROTO_TCP, TCP_NODELAY, (char > *)&flag,sizeof(flag)); > + > + dongle_info_t dongle_info; > + ret = recv(d_socket, (char*)&dongle_info, sizeof(dongle_info), 0); > + if (sizeof(dongle_info) != ret) > + fprintf(stderr,"failed to read dongle info\n"); > + > + d_tuner_type = RTLSDR_TUNER_UNKNOWN; > + d_tuner_gain_count = 0; > + d_tuner_if_gain_count = 0; > + > + if (memcmp(dongle_info.magic, "RTL0", 4) == 0) { > + d_tuner_type = rtlsdr_tuner(ntohl(dongle_info.tuner_type)); > + d_tuner_gain_count = ntohl(dongle_info.tuner_gain_count); > + if (RTLSDR_TUNER_E4000 == d_tuner_type) > + d_tuner_if_gain_count = 53; > + } > + > + if (d_tuner_type != RTLSDR_TUNER_UNKNOWN) { > std::cerr << "The RTL TCP server reports a " > - << get_tuner_name( _src->get_tuner_type() ) > + << get_tuner_name() > << " tuner with " > - << _src->get_tuner_gain_count() << " RF and " > - << _src->get_tuner_if_gain_count() << " IF gains." > + << d_tuner_gain_count << " RF and " > + << d_tuner_if_gain_count << " IF gains." > << std::endl; > } > > set_gain_mode(false); /* enable manual gain mode by default */ > > - _src->set_direct_sampling(direct_samp); > - if (direct_samp) { > + // set direct sampling > + struct command cmd = { 0x09, htonl(direct_samp) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > + if (direct_samp) > _no_tuner = true; > - } > > - _src->set_offset_tuning(offset_tune); > - > - /* rtl tcp source provides a stream of interleaved IQ floats */ > - gr::blocks::deinterleave::sptr deinterleave = \ > - gr::blocks::deinterleave::make( sizeof(float) ); > + // set offset tuning > + cmd = { 0x0a, htonl(offset_tune) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > +} > > - /* block to convert deinterleaved floats to a complex stream */ > - gr::blocks::float_to_complex::sptr f2c = \ > - gr::blocks::float_to_complex::make( 1 ); > +rtl_tcp_source_c::~rtl_tcp_source_c() > +{ > + delete [] d_temp_buff; > + > + if (d_socket != -1) { > + shutdown(d_socket, SHUT_RDWR); > +#if defined(USING_WINSOCK) > + closesocket(d_socket); > +#else > + ::close(d_socket); > +#endif > + d_socket = -1; > + } > > - connect(_src, 0, deinterleave, 0); > - connect(deinterleave, 0, f2c, 0); /* I */ > - connect(deinterleave, 1, f2c, 1); /* Q */ > - connect(f2c, 0, self(), 0); > +#if defined(USING_WINSOCK) // for Windows (with MinGW) > + // free winsock resources > + WSACleanup(); > +#endif > } > > -rtl_tcp_source_c::~rtl_tcp_source_c() > + > +int rtl_tcp_source_c::work(int noutput_items, > + gr_vector_const_void_star &input_items, > + gr_vector_void_star &output_items) > { > + gr_complex *out = (gr_complex *)output_items[0]; > + int bytesleft = noutput_items * BYTES_PER_SAMPLE; > + int index = 0; > + int receivedbytes = 0; > + while (bytesleft > 0) { > + receivedbytes = recv(d_socket, (char*)&d_temp_buff[index], bytesleft, > 0); > + > + if (receivedbytes == -1 && !is_error(EAGAIN)) { > + fprintf(stderr, "socket error\n"); > + return -1; > + } > + bytesleft -= receivedbytes; > + index += receivedbytes; > + } > + > + for (int i = 0; i < noutput_items; i++) > + out[i] = gr_complex(d_LUT[d_temp_buff[i * 2]], d_LUT[d_temp_buff[i * > 2 + 1]]); > + > + return noutput_items; > } > > std::string rtl_tcp_source_c::name() > @@ -193,7 +396,8 @@ osmosdr::meta_range_t rtl_tcp_source_c::get_sample_rates( > void ) > > double rtl_tcp_source_c::set_sample_rate( double rate ) > { > - _src->set_sample_rate( int(rate) ); > + struct command cmd = { 0x02, htonl(rate) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > > _rate = rate; > > @@ -214,24 +418,26 @@ osmosdr::freq_range_t rtl_tcp_source_c::get_freq_range( > size_t chan ) > return range; > } > > - enum rtlsdr_tuner tuner = _src->get_tuner_type(); > - > - if ( tuner == RTLSDR_TUNER_E4000 ) { > - /* there is a (temperature dependent) gap between 1100 to 1250 MHz */ > - range += osmosdr::range_t( 52e6, 2.2e9 ); > - } else if ( tuner == RTLSDR_TUNER_FC0012 ) { > + switch (d_tuner_type) { > + case RTLSDR_TUNER_FC0012: > range += osmosdr::range_t( 22e6, 948e6 ); > - } else if ( tuner == RTLSDR_TUNER_FC0013 ) { > + break; > + case RTLSDR_TUNER_FC0013: > range += osmosdr::range_t( 22e6, 1.1e9 ); > - } else if ( tuner == RTLSDR_TUNER_FC2580 ) { > + break; > + case RTLSDR_TUNER_FC2580: > range += osmosdr::range_t( 146e6, 308e6 ); > range += osmosdr::range_t( 438e6, 924e6 ); > - } else if ( tuner == RTLSDR_TUNER_R820T ) { > + break; > + case RTLSDR_TUNER_R820T: > range += osmosdr::range_t( 24e6, 1766e6 ); > - } else if ( tuner == RTLSDR_TUNER_R828D ) { > + break; > + case RTLSDR_TUNER_R828D: > range += osmosdr::range_t( 24e6, 1766e6 ); > - } else { > - range += osmosdr::range_t( 52e6, 2.2e9 ); // assume E4000 tuner > + break; > + default: // assume E4000 tuner > + /* there is a (temperature dependent) gap between 1100 to 1250 MHz */ > + range += osmosdr::range_t( 52e6, 2.2e9 ); > } > > return range; > @@ -239,7 +445,8 @@ osmosdr::freq_range_t rtl_tcp_source_c::get_freq_range( > size_t chan ) > > double rtl_tcp_source_c::set_center_freq( double freq, size_t chan ) > { > - _src->set_freq( int(freq) ); > + struct command cmd = { 0x01, htonl(freq) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > > _freq = freq; > > @@ -253,7 +460,8 @@ double rtl_tcp_source_c::get_center_freq( size_t chan > ) > > double rtl_tcp_source_c::set_freq_corr( double ppm, size_t chan ) > { > - _src->set_freq_corr( int(ppm) ); > + struct command cmd = { 0x05, htonl(ppm) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > > _corr = ppm; > > @@ -271,9 +479,8 @@ std::vector rtl_tcp_source_c::get_gain_names( > size_t chan ) > > names += "LNA"; > > - if ( _src->get_tuner_type() == RTLSDR_TUNER_E4000 ) { > + if (d_tuner_type == RTLSDR_TUNER_E4000) > names += "IF"; > - } > > return names; > } > @@ -301,8 +508,7 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( > size_t chan ) > const int *ptr = NULL; > int len = 0; > > - switch (_src->get_tuner_type()) > - { > + switch (d_tuner_type) { > case RTLSDR_TUNER_E4000: > ptr = e4k_gains; len = sizeof(e4k_gains); > break; > @@ -335,11 +541,10 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( > size_t chan ) > osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( const > std::string & name, size_t chan ) > { > if ( "IF" == name ) { > - if ( _src->get_tuner_type() == RTLSDR_TUNER_E4000 ) { > + if (d_tuner_type == RTLSDR_TUNER_E4000) > return osmosdr::gain_range_t(3, 56, 1); > - } else { > + else > return osmosdr::gain_range_t(); > - } > } > > return get_gain_range( chan ); > @@ -347,8 +552,13 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( > const std::string & name > > bool rtl_tcp_source_c::set_gain_mode( bool automatic, size_t chan ) > { > - _src->set_gain_mode(int(!automatic)); > - _src->set_agc_mode(automatic); > + // gain mode > + struct command cmd = { 0x03, htonl(!automatic) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > + > + // AGC mode > + cmd = { 0x08, htonl(automatic) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > > _auto_gain = automatic; > > @@ -364,7 +574,8 @@ double rtl_tcp_source_c::set_gain( double gain, size_t > chan ) > { > osmosdr::gain_range_t gains = rtl_tcp_source_c::get_gain_range( chan ); > > - _src->set_gain( int(gains.clip(gain) * 10.0) ); > + struct command cmd = { 0x04, htonl(int(gains.clip(gain) * 10.0)) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > > _gain = gain; > > @@ -396,7 +607,7 @@ double rtl_tcp_source_c::get_gain( const std::string & > name, size_t chan ) > > double rtl_tcp_source_c::set_if_gain(double gain, size_t chan) > { > - if ( _src->get_tuner_type() != RTLSDR_TUNER_E4000 ) { > + if (d_tuner_type != RTLSDR_TUNER_E4000) { > _if_gain = 0; > return _if_gain; > } > @@ -448,7 +659,10 @@ double rtl_tcp_source_c::set_if_gain(double gain, > size_t chan) > std::cerr << " = " << sum << std::endl; > #endif > for (unsigned int stage = 1; stage <= gains.size(); stage++) { > - _src->set_if_gain(stage, int(gains[ stage ] * 10.0)); > + int gain_i = int(gains[stage] * 10.0); > + uint32_t params = stage << 16 | (gain_i & 0xffff); > + struct command cmd = { 0x06, htonl(params) }; > + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > } > > _if_gain = gain; > diff --git a/lib/rtl_tcp/rtl_tcp_source_c.h b/lib/rtl_tcp/rtl_tcp_source_ > c.h > index 454d1a2..b07e5dd 100644 > --- a/lib/rtl_tcp/rtl_tcp_source_c.h > +++ b/lib/rtl_tcp/rtl_tcp_source_c.h > @@ -1,4 +1,4 @@ > -/* -*- c++ -*- */ > +/* -*- mode: c++; c-basic-offset: 2 -*- */ > /* > * Copyright 2012 Dimitri Stolnikov > * > @@ -20,12 +20,10 @@ > #ifndef RTL_TCP_SOURCE_C_H > #define RTL_TCP_SOURCE_C_H > > -#include > +#include > > #include "source_iface.h" > > -#include "rtl_tcp_source_f.h" > - > class rtl_tcp_source_c; > > typedef boost::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr; > @@ -33,17 +31,33 @@ typedef boost::shared_ptr< rtl_tcp_source_c > > rtl_tcp_source_c_sptr; > rtl_tcp_source_c_sptr make_rtl_tcp_source_c( const std::string & args = > "" ); > > class rtl_tcp_source_c : > - public gr::hier_block2, > + public gr::sync_block, > public source_iface > { > private: > + /* copied from rtl sdr */ > + enum rtlsdr_tuner { > + RTLSDR_TUNER_UNKNOWN = 0, > + RTLSDR_TUNER_E4000, > + RTLSDR_TUNER_FC0012, > + RTLSDR_TUNER_FC0013, > + RTLSDR_TUNER_FC2580, > + RTLSDR_TUNER_R820T, > + RTLSDR_TUNER_R828D > + }; > + > friend rtl_tcp_source_c_sptr make_rtl_tcp_source_c(const std::string > &args); > > rtl_tcp_source_c(const std::string &args); > + const char * get_tuner_name(void); > > public: > ~rtl_tcp_source_c(); > > + int work(int noutput_items, > + gr_vector_const_void_star &input_items, > + gr_vector_void_star &output_items); > + > std::string name(); > > static std::vector< std::string > get_devices( bool fake = false ); > @@ -77,11 +91,17 @@ public: > std::string get_antenna( size_t chan = 0 ); > > private: > + int d_socket; // handle to socket > double _freq, _rate, _gain, _corr; > bool _no_tuner; > bool _auto_gain; > double _if_gain; > - rtl_tcp_source_f_sptr _src; > + > + enum rtlsdr_tuner d_tuner_type; > + unsigned int d_tuner_gain_count; > + unsigned int d_tuner_if_gain_count; > + unsigned char *d_temp_buff; // hold buffer between calls > + float *d_LUT; > }; > > #endif // RTL_TCP_SOURCE_C_H > diff --git a/lib/rtl_tcp/rtl_tcp_source_f.cc b/lib/rtl_tcp/rtl_tcp_source_ > f.cc > deleted file mode 100644 > index a17594c..0000000 > --- a/lib/rtl_tcp/rtl_tcp_source_f.cc > +++ /dev/null > @@ -1,327 +0,0 @@ > -/* -*- c++ -*- */ > -/* > - * Copyright 2012 Hoernchen > - * Copyright 2012 Dimitri Stolnikov > - * > - * GNU Radio is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 3, or (at your option) > - * any later version. > - * > - * GNU Radio is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with GNU Radio; see the file COPYING. If not, write to > - * the Free Software Foundation, Inc., 51 Franklin Street, > - * Boston, MA 02110-1301, USA. > - */ > -//#define HAVE_WINDOWS_H > - > - > -#include > -#include > -#include > -#include > -#include > -#include > - > -#ifndef _WIN32 > -#include > -#else > -#include > -#endif > - > -/* copied from rtl sdr code */ > -typedef struct { /* structure size must be multiple of 2 bytes */ > - char magic[4]; > - uint32_t tuner_type; > - uint32_t tuner_gain_count; > -} dongle_info_t; > - > -#define USE_SELECT 1 // non-blocking receive on all platforms > -#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin > -#define SRC_VERBOSE 0 > -#define SNK_VERBOSE 0 > - > -static int is_error( int perr ) > -{ > - // Compare error to posix error code; return nonzero if match. > -#if defined(USING_WINSOCK) > -#define ENOPROTOOPT 109 > - // All codes to be checked for must be defined below > - int werr = WSAGetLastError(); > - switch( werr ) { > - case WSAETIMEDOUT: > - return( perr == EAGAIN ); > - case WSAENOPROTOOPT: > - return( perr == ENOPROTOOPT ); > - default: > - fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", > perr, werr ); > - throw std::runtime_error("internal error"); > - } > - return 0; > -#else > - return( perr == errno ); > -#endif > -} > - > -static void report_error( const char *msg1, const char *msg2 ) > -{ > - // Deal with errors, both posix and winsock > -#if defined(USING_WINSOCK) > - int werr = WSAGetLastError(); > - fprintf(stderr, "%s: winsock error %d\n", msg1, werr ); > -#else > - perror(msg1); > -#endif > - if( msg2 != NULL ) > - throw std::runtime_error(msg2); > - return; > -} > - > -rtl_tcp_source_f::rtl_tcp_source_f(size_t itemsize, > - const char *host, > - unsigned short port, > - int payload_size, > - bool eof, > - bool wait) > - : gr::sync_block ("rtl_tcp_source_f", > - gr::io_signature::make(0, 0, 0), > - gr::io_signature::make(1, 1, sizeof(float))), > - d_itemsize(itemsize), > - d_payload_size(payload_size), > - d_eof(eof), > - d_wait(wait), > - d_socket(-1), > - d_temp_offset(0) > -{ > - int ret = 0; > -#if defined(USING_WINSOCK) // for Windows (with MinGW) > - // initialize winsock DLL > - WSADATA wsaData; > - int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); > - if( iResult != NO_ERROR ) { > - report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" ); > - } > -#endif > - > - // Set up the address stucture for the source address and port numbers > - // Get the source IP address from the host name > - struct addrinfo *ip_src; // store the source IP address to use > - struct addrinfo hints; > - memset( (void*)&hints, 0, sizeof(hints) ); > - hints.ai_family = AF_UNSPEC; > - hints.ai_socktype = SOCK_STREAM; > - hints.ai_protocol = IPPROTO_TCP; > - hints.ai_flags = AI_PASSIVE; > - char port_str[12]; > - sprintf( port_str, "%d", port ); > - > - // FIXME leaks if report_error throws below > - ret = getaddrinfo( host, port_str, &hints, &ip_src ); > - if( ret != 0 ) > - report_error("rtl_tcp_source_f/getaddrinfo", > - "can't initialize source socket" ); > - > - // FIXME leaks if report_error throws below > - d_temp_buff = new unsigned char[d_payload_size]; // allow it to hold > up to payload_size bytes > - d_LUT= new float[0xff+1]; > - for(int i=0; i <=(0xff);++i){ > - d_LUT[i] = (((float)(i&0xff))-127.4f)*(1.0f/128.0f); > - } > - // create socket > - d_socket = socket(ip_src->ai_family, ip_src->ai_socktype, > - ip_src->ai_protocol); > - if(d_socket == -1) { > - report_error("socket open","can't open socket"); > - } > - > - // Turn on reuse address > - int opt_val = 1; > - if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, > sizeof(int)) == -1) { > - report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR"); > - } > - > - // Don't wait when shutting down > - linger lngr; > - lngr.l_onoff = 1; > - lngr.l_linger = 0; > - if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, > sizeof(linger)) == -1) { > - if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on > Windows > - report_error("SO_LINGER","can't set socket option SO_LINGER"); > - } > - } > - > -#if USE_RCV_TIMEO > - // Set a timeout on the receive function to not block indefinitely > - // This value can (and probably should) be changed > - // Ignored on Cygwin > -#if defined(USING_WINSOCK) > - DWORD timeout = 1000; // milliseconds > -#else > - timeval timeout; > - timeout.tv_sec = 1; > - timeout.tv_usec = 0; > -#endif > - if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, > sizeof(timeout)) == -1) { > - report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO"); > - } > -#endif // USE_RCV_TIMEO > - > - while(connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0); > - freeaddrinfo(ip_src); > - > - int flag = 1; > - setsockopt(d_socket, IPPROTO_TCP, TCP_NODELAY, (char > *)&flag,sizeof(flag)); > - > - dongle_info_t dongle_info; > - ret = recv(d_socket, (char*)&dongle_info, sizeof(dongle_info), 0); > - if (sizeof(dongle_info) != ret) > - fprintf(stderr,"failed to read dongle info\n"); > - > - d_tuner_type = RTLSDR_TUNER_UNKNOWN; > - d_tuner_gain_count = 0; > - d_tuner_if_gain_count = 0; > - > - if (memcmp(dongle_info.magic, "RTL0", 4) == 0) > - { > - d_tuner_type = ntohl(dongle_info.tuner_type); > - d_tuner_gain_count = ntohl(dongle_info.tuner_gain_count); > - if ( RTLSDR_TUNER_E4000 == d_tuner_type ) > - d_tuner_if_gain_count = 53; > - } > -} > - > -rtl_tcp_source_f_sptr make_rtl_tcp_source_f (size_t itemsize, > - const char *ipaddr, > - unsigned short port, > - int payload_size, > - bool eof, > - bool wait) > -{ > - return gnuradio::get_initial_sptr(new rtl_tcp_source_f ( > - itemsize, > - ipaddr, > - port, > - payload_size, > - eof, > - wait)); > -} > - > -rtl_tcp_source_f::~rtl_tcp_source_f () > -{ > - delete [] d_temp_buff; > - > - if (d_socket != -1){ > - shutdown(d_socket, SHUT_RDWR); > -#if defined(USING_WINSOCK) > - closesocket(d_socket); > -#else > - ::close(d_socket); > -#endif > - d_socket = -1; > - } > - > -#if defined(USING_WINSOCK) // for Windows (with MinGW) > - // free winsock resources > - WSACleanup(); > -#endif > -} > - > -int rtl_tcp_source_f::work (int noutput_items, > - gr_vector_const_void_star &input_items, > - gr_vector_void_star &output_items) > -{ > - float *out = (float *) output_items[0]; > - ssize_t r = 0; > - > - int bytesleft = noutput_items; > - int index = 0; > - int receivedbytes = 0; > - while(bytesleft > 0) { > - receivedbytes = recv(d_socket, (char*)&d_temp_buff[index], bytesleft, > 0); > - > - if(receivedbytes == -1 && !is_error(EAGAIN)){ > - fprintf(stderr, "socket error\n"); > - return -1; > - } > - bytesleft -= receivedbytes; > - index += receivedbytes; > - } > - r = noutput_items; > - > - for(int i=0; i - out[i]=d_LUT[*(d_temp_buff+d_temp_offset+i)]; > - > - return r; > -} > - > -#ifdef _WIN32 > -#define __attribute__(x) > -#pragma pack(push, 1) > -#endif > -struct command{ > - unsigned char cmd; > - unsigned int param; > -}__attribute__((packed)); > -#ifdef _WIN32 > -#pragma pack(pop) > -#endif > - > -void rtl_tcp_source_f::set_freq(int freq) > -{ > - struct command cmd = { 0x01, htonl(freq) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_sample_rate(int sample_rate) > -{ > - struct command cmd = { 0x02, htonl(sample_rate) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_gain_mode(int manual) > -{ > - struct command cmd = { 0x03, htonl(manual) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_gain(int gain) > -{ > - struct command cmd = { 0x04, htonl(gain) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_freq_corr(int ppm) > -{ > - struct command cmd = { 0x05, htonl(ppm) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_if_gain(int stage, int gain) > -{ > - uint32_t params = stage << 16 | (gain & 0xffff); > - struct command cmd = { 0x06, htonl(params) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_agc_mode(int on) > -{ > - struct command cmd = { 0x08, htonl(on) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_direct_sampling(int on) > -{ > - struct command cmd = { 0x09, htonl(on) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > - > -void rtl_tcp_source_f::set_offset_tuning(int on) > -{ > - struct command cmd = { 0x0a, htonl(on) }; > - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); > -} > diff --git a/lib/rtl_tcp/rtl_tcp_source_f.h b/lib/rtl_tcp/rtl_tcp_source_ > f.h > deleted file mode 100644 > index 84ac57a..0000000 > --- a/lib/rtl_tcp/rtl_tcp_source_f.h > +++ /dev/null > @@ -1,125 +0,0 @@ > -/* -*- c++ -*- */ > -/* > - * Copyright 2012 Hoernchen > - * > - * GNU Radio is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 3, or (at your option) > - * any later version. > - * > - * GNU Radio is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with GNU Radio; see the file COPYING. If not, write to > - * the Free Software Foundation, Inc., 51 Franklin Street, > - * Boston, MA 02110-1301, USA. > - */ > - > -#ifndef RTL_TCP_SOURCE_F_H > -#define RTL_TCP_SOURCE_F_H > - > -#include > -#include > - > -#if defined(_WIN32) > -// if not posix, assume winsock > -#pragma comment(lib, "ws2_32.lib") > -#define USING_WINSOCK > -#include > -#include > -#define SHUT_RDWR 2 > -typedef char* optval_t; > -#else > -#include > -#include > -#include > -#include > -#include > -#include > -typedef void* optval_t; > -#endif > - > -#ifdef _MSC_VER > -#include > -typedef ptrdiff_t ssize_t; > -#endif //_MSC_VER > - > -/* copied from rtl sdr */ > -enum rtlsdr_tuner { > - RTLSDR_TUNER_UNKNOWN = 0, > - RTLSDR_TUNER_E4000, > - RTLSDR_TUNER_FC0012, > - RTLSDR_TUNER_FC0013, > - RTLSDR_TUNER_FC2580, > - RTLSDR_TUNER_R820T, > - RTLSDR_TUNER_R828D > -}; > - > -class rtl_tcp_source_f; > -typedef boost::shared_ptr rtl_tcp_source_f_sptr; > - > -rtl_tcp_source_f_sptr make_rtl_tcp_source_f ( > - size_t itemsize, > - const char *host, > - unsigned short port, > - int payload_size, > - bool eof = false, > - bool wait = false); > - > -class rtl_tcp_source_f : public gr::sync_block > -{ > -private: > - size_t d_itemsize; > - int d_payload_size; // maximum transmission unit (packet > length) > - bool d_eof; // zero-length packet is EOF > - bool d_wait; // wait if data if not immediately > available > - int d_socket; // handle to socket > - unsigned char *d_temp_buff; // hold buffer between calls > - size_t d_temp_offset; // point to temp buffer location offset > - float *d_LUT; > - > - unsigned int d_tuner_type; > - unsigned int d_tuner_gain_count; > - unsigned int d_tuner_if_gain_count; > - > -private: > - rtl_tcp_source_f(size_t itemsize, const char *host, > - unsigned short port, int payload_size, bool eof, bool > wait); > - > - // The friend declaration allows make_source_c to > - // access the private constructor. > - friend rtl_tcp_source_f_sptr make_rtl_tcp_source_f ( > - size_t itemsize, > - const char *host, > - unsigned short port, > - int payload_size, > - bool eof, > - bool wait); > - > -public: > - ~rtl_tcp_source_f(); > - > - enum rtlsdr_tuner get_tuner_type() { return (enum rtlsdr_tuner) > d_tuner_type; } > - unsigned int get_tuner_gain_count() { return d_tuner_gain_count; } > - unsigned int get_tuner_if_gain_count() { return d_tuner_if_gain_count; } > - > - int work(int noutput_items, > - gr_vector_const_void_star &input_items, > - gr_vector_void_star &output_items); > - > - void set_freq(int freq); > - void set_sample_rate(int sample_rate); > - void set_gain_mode(int manual); > - void set_gain(int gain); > - void set_freq_corr(int ppm); > - void set_if_gain(int stage, int gain); > - void set_agc_mode(int on); > - void set_direct_sampling(int on); > - void set_offset_tuning(int on); > -}; > - > - > -#endif /* RTL_TCP_SOURCE_F_H */ > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > osmocom-sdr mailing list > osmocom-sdr at lists.osmocom.org > https://lists.osmocom.org/mailman/listinfo/osmocom-sdr > > > ------------------------------ > > End of osmocom-sdr Digest, Vol 21, Issue 2 > ****************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: