summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/convenience/convenience.c4
-rw-r--r--utils/rtl_adsb.c21
-rw-r--r--utils/rtl_biast.c101
-rw-r--r--utils/rtl_eeprom.c7
-rw-r--r--utils/rtl_fm.c41
-rw-r--r--utils/rtl_power.c21
-rw-r--r--utils/rtl_tcp.c119
-rw-r--r--utils/rtl_test.c62
8 files changed, 313 insertions, 63 deletions
diff --git a/utils/convenience/convenience.c b/utils/convenience/convenience.c
index 517dc4e..00cc2cc 100644
--- a/utils/convenience/convenience.c
+++ b/utils/convenience/convenience.c
@@ -49,9 +49,11 @@ double atofs(char *s)
case 'g':
case 'G':
suff *= 1e3;
+ /* fall-through */
case 'm':
case 'M':
suff *= 1e3;
+ /* fall-through */
case 'k':
case 'K':
suff *= 1e3;
@@ -76,9 +78,11 @@ double atoft(char *s)
case 'h':
case 'H':
suff *= 60;
+ /* fall-through */
case 'm':
case 'M':
suff *= 60;
+ /* fall-through */
case 's':
case 'S':
suff *= atof(s);
diff --git a/utils/rtl_adsb.c b/utils/rtl_adsb.c
index 7de9204..7aea8dd 100644
--- a/utils/rtl_adsb.c
+++ b/utils/rtl_adsb.c
@@ -96,6 +96,7 @@ void usage(void)
"\t[-e allowed_errors (default: 5)]\n"
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-p ppm_error (default: 0)]\n"
+ "\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\tfilename (a '-' dumps samples to stdout)\n"
"\t (omitting the filename also uses stdout)\n\n"
"Streaming with netcat:\n"
@@ -182,7 +183,7 @@ int magnitute(uint8_t *buf, int len)
return len/2;
}
-uint16_t single_manchester(uint16_t a, uint16_t b, uint16_t c, uint16_t d)
+static inline uint16_t single_manchester(uint16_t a, uint16_t b, uint16_t c, uint16_t d)
/* takes 4 consecutive real samples, return 0 or 1, BADSAMPLE on error */
{
int bit, bit_p;
@@ -223,17 +224,17 @@ uint16_t single_manchester(uint16_t a, uint16_t b, uint16_t c, uint16_t d)
return BADSAMPLE;
}
-inline uint16_t min16(uint16_t a, uint16_t b)
+static inline uint16_t min16(uint16_t a, uint16_t b)
{
return a<b ? a : b;
}
-inline uint16_t max16(uint16_t a, uint16_t b)
+static inline uint16_t max16(uint16_t a, uint16_t b)
{
return a>b ? a : b;
}
-int preamble(uint16_t *buf, int i)
+static inline int preamble(uint16_t *buf, int i)
/* returns 0/1 for preamble at index i */
{
int i2;
@@ -371,11 +372,12 @@ int main(int argc, char **argv)
int dev_index = 0;
int dev_given = 0;
int ppm_error = 0;
+ int enable_biastee = 0;
pthread_cond_init(&ready, NULL);
pthread_mutex_init(&ready_m, NULL);
squares_precompute();
- while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1)
+ while ((opt = getopt(argc, argv, "d:g:p:e:Q:VST")) != -1)
{
switch (opt) {
case 'd':
@@ -400,6 +402,9 @@ int main(int argc, char **argv)
case 'Q':
quality = (int)(atof(optarg) * 10);
break;
+ case 'T':
+ enable_biastee = 1;
+ break;
default:
usage();
return 0;
@@ -470,6 +475,10 @@ int main(int argc, char **argv)
/* Set the sample rate */
verbose_set_sample_rate(dev, ADSB_RATE);
+ rtlsdr_set_bias_tee(dev, enable_biastee);
+ if (enable_biastee)
+ fprintf(stderr, "activated bias-T on GPIO PIN 0\n");
+
/* Reset endpoint before we start reading from it (mandatory) */
verbose_reset_buffer(dev);
@@ -483,6 +492,8 @@ int main(int argc, char **argv)
else {
fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
rtlsdr_cancel_async(dev);
+ pthread_cancel(demod_thread);
+ pthread_join(demod_thread, NULL);
pthread_cond_destroy(&ready);
pthread_mutex_destroy(&ready_m);
diff --git a/utils/rtl_biast.c b/utils/rtl_biast.c
new file mode 100644
index 0000000..185e838
--- /dev/null
+++ b/utils/rtl_biast.c
@@ -0,0 +1,101 @@
+/*
+ * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
+ * rtl_biast, tool to set bias tee gpio output
+ * Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de>
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <windows.h>
+#include "getopt/getopt.h"
+#endif
+
+#include "rtl-sdr.h"
+#include "convenience/convenience.h"
+
+static rtlsdr_dev_t *dev = NULL;
+
+void usage(void)
+{
+ fprintf(stderr,
+ "rtl_biast, a tool for turning the RTL-SDR.com \n"
+ "bias tee or any GPIO ON and OFF. Example to turn on the \n"
+ "bias tee: rtl_biast -d 0 -b 1\n"
+ "Any GPIO: rtl_biast -d 0 -g 1 -b 1\n\n"
+ "Usage:\n"
+ "\t[-d device_index (default: 0)]\n"
+ "\t[-b bias_on (default: 0)]\n"
+ "\t[-g GPIO select (default: 0)]\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int i, r, opt;
+ int dev_index = 0;
+ int dev_given = 0;
+ uint32_t bias_on = 0;
+ uint32_t gpio_pin = 0;
+ int device_count;
+
+ while ((opt = getopt(argc, argv, "d:b:g:h?")) != -1) {
+ switch (opt) {
+ case 'd':
+ dev_index = verbose_device_search(optarg);
+ dev_given = 1;
+ break;
+ case 'b':
+ bias_on = atoi(optarg);
+ break;
+ case 'g':
+ gpio_pin = atoi(optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (!dev_given) {
+ dev_index = verbose_device_search("0");
+ }
+
+ if (dev_index < 0) {
+ exit(1);
+ }
+
+ r = rtlsdr_open(&dev, dev_index);
+ rtlsdr_set_bias_tee_gpio(dev, gpio_pin, bias_on);
+
+exit:
+ /*
+ * Note - rtlsdr_close() in this tree does not clear the bias tee
+ * GPIO line, so it leaves the bias tee enabled if a client program
+ * doesn't explictly disable it.
+ *
+ * If that behaviour changes then another rtlsdr_close() will be
+ * needed that takes some extension flags, and one of them should
+ * be to either explicitly close the biast or leave it alone.
+ */
+ rtlsdr_close(dev);
+
+ return r >= 0 ? r : -r;
+}
diff --git a/utils/rtl_eeprom.c b/utils/rtl_eeprom.c
index 5259820..24be900 100644
--- a/utils/rtl_eeprom.c
+++ b/utils/rtl_eeprom.c
@@ -303,6 +303,7 @@ int main(int argc, char **argv)
case 'w':
flash_file = 1;
change = 1;
+ /* fall-through */
case 'r':
filename = optarg;
break;
@@ -369,14 +370,14 @@ int main(int argc, char **argv)
}
if (manuf_str)
- strncpy((char*)&conf.manufacturer, manuf_str, MAX_STR_SIZE);
+ strncpy((char*)&conf.manufacturer, manuf_str, MAX_STR_SIZE - 1);
if (product_str)
- strncpy((char*)&conf.product, product_str, MAX_STR_SIZE);
+ strncpy((char*)&conf.product, product_str, MAX_STR_SIZE - 1);
if (serial_str) {
conf.have_serial = 1;
- strncpy((char*)&conf.serial, serial_str, MAX_STR_SIZE);
+ strncpy((char*)&conf.serial, serial_str, MAX_STR_SIZE - 1);
}
if (ir_endpoint != 0)
diff --git a/utils/rtl_fm.c b/utils/rtl_fm.c
index e89e42d..7c84332 100644
--- a/utils/rtl_fm.c
+++ b/utils/rtl_fm.c
@@ -193,6 +193,7 @@ void usage(void)
"\t raw mode outputs 2x16 bit IQ pairs\n"
"\t[-s sample_rate (default: 24k)]\n"
"\t[-d device_index (default: 0)]\n"
+ "\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-l squelch_level (default: 0/off)]\n"
//"\t for fm squelch is inverted\n"
@@ -200,11 +201,12 @@ void usage(void)
"\t[-p ppm_error (default: 0)]\n"
"\t[-E enable_option (default: none)]\n"
"\t use multiple -E to enable multiple options\n"
- "\t edge: enable lower edge tuning\n"
- "\t dc: enable dc blocking filter\n"
- "\t deemp: enable de-emphasis filter\n"
- "\t direct: enable direct sampling\n"
- "\t offset: enable offset tuning\n"
+ "\t edge: enable lower edge tuning\n"
+ "\t dc: enable dc blocking filter\n"
+ "\t deemp: enable de-emphasis filter\n"
+ "\t direct: enable direct sampling 1 (usually I)\n"
+ "\t direct2: enable direct sampling 2 (usually Q)\n"
+ "\t offset: enable offset tuning\n"
"\tfilename ('-' means stdout)\n"
"\t omitting the filename also uses stdout\n\n"
"Experimental options:\n"
@@ -502,7 +504,7 @@ int polar_disc_lut(int ar, int aj, int br, int bj)
if (x_abs >= atan_lut_size) {
/* we can use linear range, but it is not necessary */
- return (cj > 0) ? 1<<13 : -1<<13;
+ return (cj > 0) ? 1<<13 : -(1<<13);
}
if (x > 0) {
@@ -891,7 +893,7 @@ static void *controller_thread_fn(void *arg)
/* set up primary channel */
optimal_settings(s->freqs[0], demod.rate_in);
if (dongle.direct_sampling) {
- verbose_direct_sampling(dongle.dev, 1);}
+ verbose_direct_sampling(dongle.dev, dongle.direct_sampling);}
if (dongle.offset_tuning) {
verbose_offset_tuning(dongle.dev);}
@@ -925,8 +927,21 @@ void frequency_range(struct controller_state *s, char *arg)
int i;
start = arg;
stop = strchr(start, ':') + 1;
+ if (stop == (char *)1) { // no stop or step given
+ s->freqs[s->freq_len] = (uint32_t) atofs(start);
+ s->freq_len++;
+ return;
+ }
stop[-1] = '\0';
step = strchr(stop, ':') + 1;
+ if (step == (char *)1) { // no step given
+ s->freqs[s->freq_len] = (uint32_t) atofs(start);
+ s->freq_len++;
+ s->freqs[s->freq_len] = (uint32_t) atofs(stop);
+ s->freq_len++;
+ stop[-1] = ':';
+ return;
+ }
step[-1] = '\0';
for(i=(int)atofs(start); i<=(int)atofs(stop); i+=(int)atofs(step))
{
@@ -1042,12 +1057,13 @@ int main(int argc, char **argv)
int r, opt;
int dev_given = 0;
int custom_ppm = 0;
+ int enable_biastee = 0;
dongle_init(&dongle);
demod_init(&demod);
output_init(&output);
controller_init(&controller);
- while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:E:F:A:M:h")) != -1) {
+ while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:E:F:A:M:hT")) != -1) {
switch (opt) {
case 'd':
dongle.dev_index = verbose_device_search(optarg);
@@ -1104,6 +1120,8 @@ int main(int argc, char **argv)
demod.deemph = 1;}
if (strcmp("direct", optarg) == 0) {
dongle.direct_sampling = 1;}
+ if (strcmp("direct2", optarg) == 0) {
+ dongle.direct_sampling = 2;}
if (strcmp("offset", optarg) == 0) {
dongle.offset_tuning = 1;}
break;
@@ -1142,6 +1160,9 @@ int main(int argc, char **argv)
demod.deemph = 1;
demod.squelch_level = 0;}
break;
+ case 'T':
+ enable_biastee = 1;
+ break;
case 'h':
default:
usage();
@@ -1205,6 +1226,10 @@ int main(int argc, char **argv)
verbose_gain_set(dongle.dev, dongle.gain);
}
+ rtlsdr_set_bias_tee(dongle.dev, enable_biastee);
+ if (enable_biastee)
+ fprintf(stderr, "activated bias-T on GPIO PIN 0\n");
+
verbose_ppm_set(dongle.dev, dongle.ppm_error);
if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */
diff --git a/utils/rtl_power.c b/utils/rtl_power.c
index 23b516c..6204de2 100644
--- a/utils/rtl_power.c
+++ b/utils/rtl_power.c
@@ -133,6 +133,7 @@ void usage(void)
"\t[-d device_index (default: 0)]\n"
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-p ppm_error (default: 0)]\n"
+ "\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n"
"\tfilename (a '-' dumps samples to stdout)\n"
"\t (omitting the filename also uses stdout)\n"
"\n"
@@ -249,7 +250,7 @@ void sine_table(int size)
}
}
-int16_t FIX_MPY(int16_t a, int16_t b)
+static inline int16_t FIX_MPY(int16_t a, int16_t b)
/* fixed point multiply and scale */
{
int c = ((int)a * (int)b) >> 14;
@@ -436,8 +437,16 @@ void frequency_range(char *arg, double crop)
/* hacky string parsing */
start = arg;
stop = strchr(start, ':') + 1;
+ if (stop == (char *)1) {
+ fprintf(stderr, "Bad frequency range specification: %s\n", arg);
+ exit(1);
+ }
stop[-1] = '\0';
step = strchr(stop, ':') + 1;
+ if (step == (char *)1) {
+ fprintf(stderr, "Bad frequency range specification: %s\n", arg);
+ exit(1);
+ }
step[-1] = '\0';
lower = (int)atofs(start);
upper = (int)atofs(stop);
@@ -771,6 +780,7 @@ int main(int argc, char **argv)
int single = 0;
int direct_sampling = 0;
int offset_tuning = 0;
+ int enable_biastee = 0;
double crop = 0.0;
char *freq_optarg;
time_t next_tick;
@@ -781,7 +791,7 @@ int main(int argc, char **argv)
double (*window_fn)(int, int) = rectangle;
freq_optarg = "";
- while ((opt = getopt(argc, argv, "f:i:s:t:d:g:p:e:w:c:F:1PDOh")) != -1) {
+ while ((opt = getopt(argc, argv, "f:i:s:t:d:g:p:e:w:c:F:1PDOhT")) != -1) {
switch (opt) {
case 'f': // lower:upper:bin_size
freq_optarg = strdup(optarg);
@@ -849,6 +859,9 @@ int main(int argc, char **argv)
boxcar = 0;
comp_fir_size = atoi(optarg);
break;
+ case 'T':
+ enable_biastee = 1;
+ break;
case 'h':
default:
usage();
@@ -925,6 +938,10 @@ int main(int argc, char **argv)
verbose_ppm_set(dev, ppm_error);
+ rtlsdr_set_bias_tee(dev, enable_biastee);
+ if (enable_biastee)
+ fprintf(stderr, "activated bias-T on GPIO PIN 0\n");
+
if (strcmp(filename, "-") == 0) { /* Write log to stdout */
file = stdout;
#ifdef _WIN32
diff --git a/utils/rtl_tcp.c b/utils/rtl_tcp.c
index 317e0f3..84f5591 100644
--- a/utils/rtl_tcp.c
+++ b/utils/rtl_tcp.c
@@ -30,10 +30,12 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <fcntl.h>
#else
#include <winsock2.h>
+#include <ws2tcpip.h>
#include "getopt/getopt.h"
#endif
@@ -54,6 +56,10 @@ typedef int socklen_t;
#define SOCKET_ERROR -1
#endif
+#define DEFAULT_PORT_STR "1234"
+#define DEFAULT_SAMPLE_RATE_HZ 2048000
+#define DEFAULT_MAX_NUM_BUFFERS 500
+
static SOCKET s;
static pthread_t tcp_worker_thread;
@@ -78,24 +84,27 @@ typedef struct { /* structure size must be multiple of 2 bytes */
static rtlsdr_dev_t *dev = NULL;
+static int enable_biastee = 0;
static int global_numq = 0;
static struct llist *ll_buffers = 0;
-static int llbuf_num = 500;
+static int llbuf_num = DEFAULT_MAX_NUM_BUFFERS;
static volatile int do_exit = 0;
+
void usage(void)
{
- printf("rtl_tcp, an I/Q spectrum server for RTL2832 based DVB-T receivers\n\n"
- "Usage:\t[-a listen address]\n"
- "\t[-p listen port (default: 1234)]\n"
- "\t[-f frequency to tune to [Hz]]\n"
- "\t[-g gain (default: 0 for auto)]\n"
- "\t[-s samplerate in Hz (default: 2048000 Hz)]\n"
- "\t[-b number of buffers (default: 15, set by library)]\n"
- "\t[-n max number of linked list buffers to keep (default: 500)]\n"
- "\t[-d device index (default: 0)]\n"
- "\t[-P ppm_error (default: 0)]\n");
+ printf("rtl_tcp, an I/Q spectrum server for RTL2832 based DVB-T receivers\n\n");
+ printf("Usage:\t[-a listen address]\n");
+ printf("\t[-p listen port (default: %s)]\n", DEFAULT_PORT_STR);
+ printf("\t[-f frequency to tune to [Hz]]\n");
+ printf("\t[-g gain (default: 0 for auto)]\n");
+ printf("\t[-s samplerate in Hz (default: %d Hz)]\n", DEFAULT_SAMPLE_RATE_HZ);
+ printf("\t[-b number of buffers (default: 15, set by library)]\n");
+ printf("\t[-n max number of linked list buffers to keep (default: %d)]\n", DEFAULT_MAX_NUM_BUFFERS);
+ printf("\t[-d device index (default: 0)]\n");
+ printf("\t[-P ppm_error (default: 0)]\n");
+ printf("\t[-T enable bias-T on GPIO PIN 0 (works for rtl-sdr.com v3 dongles)]\n");
exit(1);
}
@@ -355,6 +364,10 @@ static void *command_worker(void *arg)
printf("set tuner gain by index %d\n", ntohl(cmd.param));
set_gain_by_index(dev, ntohl(cmd.param));
break;
+ case 0x0e:
+ printf("set bias tee %d\n", ntohl(cmd.param));
+ rtlsdr_set_bias_tee(dev, (int)ntohl(cmd.param));
+ break;
default:
break;
}
@@ -365,10 +378,18 @@ static void *command_worker(void *arg)
int main(int argc, char **argv)
{
int r, opt, i;
- char* addr = "127.0.0.1";
- int port = 1234;
- uint32_t frequency = 100000000, samp_rate = 2048000;
- struct sockaddr_in local, remote;
+ char *addr = "127.0.0.1";
+ const char *port = DEFAULT_PORT_STR;
+ uint32_t frequency = 100000000, samp_rate = DEFAULT_SAMPLE_RATE_HZ;
+ struct sockaddr_storage local, remote;
+ struct addrinfo *ai;
+ struct addrinfo *aiHead;
+ struct addrinfo hints;
+ char hostinfo[NI_MAXHOST];
+ char portinfo[NI_MAXSERV];
+ char remhostinfo[NI_MAXHOST];
+ char remportinfo[NI_MAXSERV];
+ int aiErr;
uint32_t buf_num = 0;
int dev_index = 0;
int dev_given = 0;
@@ -379,7 +400,7 @@ int main(int argc, char **argv)
void *status;
struct timeval tv = {1,0};
struct linger ling = {1,0};
- SOCKET listensocket;
+ SOCKET listensocket = 0;
socklen_t rlen;
fd_set readfds;
u_long blockmode = 1;
@@ -391,7 +412,7 @@ int main(int argc, char **argv)
struct sigaction sigact, sigign;
#endif
- while ((opt = getopt(argc, argv, "a:p:f:g:s:b:n:d:P:")) != -1) {
+ while ((opt = getopt(argc, argv, "a:p:f:g:s:b:n:d:P:T")) != -1) {
switch (opt) {
case 'd':
dev_index = verbose_device_search(optarg);
@@ -407,10 +428,10 @@ int main(int argc, char **argv)
samp_rate = (uint32_t)atofs(optarg);
break;
case 'a':
- addr = optarg;
+ addr = strdup(optarg);
break;
case 'p':
- port = atoi(optarg);
+ port = strdup(optarg);
break;
case 'b':
buf_num = atoi(optarg);
@@ -421,6 +442,9 @@ int main(int argc, char **argv)
case 'P':
ppm_error = atoi(optarg);
break;
+ case 'T':
+ enable_biastee = 1;
+ break;
default:
usage();
break;
@@ -491,6 +515,10 @@ int main(int argc, char **argv)
fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0);
}
+ rtlsdr_set_bias_tee(dev, enable_biastee);
+ if (enable_biastee)
+ fprintf(stderr, "activated bias-T on GPIO PIN 0\n");
+
/* Reset endpoint before we start reading from it (mandatory) */
r = rtlsdr_reset_buffer(dev);
if (r < 0)
@@ -502,16 +530,42 @@ int main(int argc, char **argv)
pthread_cond_init(&cond, NULL);
pthread_cond_init(&exit_cond, NULL);
- memset(&local,0,sizeof(local));
- local.sin_family = AF_INET;
- local.sin_port = htons(port);
- local.sin_addr.s_addr = inet_addr(addr);
+ hints.ai_flags = AI_PASSIVE; /* Server mode. */
+ hints.ai_family = PF_UNSPEC; /* IPv4 or IPv6. */
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if ((aiErr = getaddrinfo(addr,
+ port,
+ &hints,
+ &aiHead )) != 0)
+ {
+ fprintf(stderr, "local address %s ERROR - %s.\n",
+ addr, gai_strerror(aiErr));
+ return(-1);
+ }
+ memcpy(&local, aiHead->ai_addr, aiHead->ai_addrlen);
+
+ for (ai = aiHead; ai != NULL; ai = ai->ai_next) {
+ aiErr = getnameinfo((struct sockaddr *)ai->ai_addr, ai->ai_addrlen,
+ hostinfo, NI_MAXHOST,
+ portinfo, NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST);
+ if (aiErr)
+ fprintf( stderr, "getnameinfo ERROR - %s.\n",hostinfo);
+
+ listensocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (listensocket < 0)
+ continue;
+
+ r = 1;
+ setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
+ setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- r = 1;
- setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
- setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- bind(listensocket,(struct sockaddr *)&local,sizeof(local));
+ if (bind(listensocket, (struct sockaddr *)&local, sizeof(local)))
+ fprintf(stderr, "rtl_tcp bind error: %s", strerror(errno));
+ else
+ break;
+ }
#ifdef _WIN32
ioctlsocket(listensocket, FIONBIO, &blockmode);
@@ -522,11 +576,11 @@ int main(int argc, char **argv)
while(1) {
printf("listening...\n");
- printf("Use the device argument 'rtl_tcp=%s:%d' in OsmoSDR "
+ printf("Use the device argument 'rtl_tcp=%s:%s' in OsmoSDR "
"(gr-osmosdr) source\n"
"to receive samples in GRC and control "
"rtl_tcp parameters (frequency, gain, ...).\n",
- addr, port);
+ hostinfo, portinfo);
listen(listensocket,1);
while(1) {
@@ -546,7 +600,10 @@ int main(int argc, char **argv)
setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- printf("client accepted!\n");
+ getnameinfo((struct sockaddr *)&remote, rlen,
+ remhostinfo, NI_MAXHOST,
+ remportinfo, NI_MAXSERV, NI_NUMERICSERV);
+ printf("client accepted! %s %s\n", remhostinfo, remportinfo);
memset(&dongle_info, 0, sizeof(dongle_info));
memcpy(&dongle_info.magic, "RTL0", 4);
diff --git a/utils/rtl_test.c b/utils/rtl_test.c
index 9a6cfda..9b44097 100644
--- a/utils/rtl_test.c
+++ b/utils/rtl_test.c
@@ -53,6 +53,21 @@
#define PPM_DURATION 10
#define PPM_DUMP_TIME 5
+struct time_generic
+/* holds all the platform specific values */
+{
+#ifndef _WIN32
+ time_t tv_sec;
+ long tv_nsec;
+#else
+ long tv_sec;
+ long tv_nsec;
+ int init;
+ LARGE_INTEGER frequency;
+ LARGE_INTEGER ticks;
+#endif
+};
+
static enum {
NO_BENCHMARK,
TUNER_BENCHMARK,
@@ -134,21 +149,42 @@ static void underrun_test(unsigned char *buf, uint32_t len, int mute)
}
#ifndef _WIN32
-static int ppm_gettime(struct timespec *ts)
+static int ppm_gettime(struct time_generic *tg)
{
int rv = ENOSYS;
+ struct timespec ts;
#ifdef __unix__
- rv = clock_gettime(CLOCK_MONOTONIC, ts);
+ rv = clock_gettime(CLOCK_MONOTONIC, &ts);
+ tg->tv_sec = ts.tv_sec;
+ tg->tv_nsec = ts.tv_nsec;
#elif __APPLE__
struct timeval tv;
rv = gettimeofday(&tv, NULL);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
+ tg->tv_sec = tv.tv_sec;
+ tg->tv_nsec = tv.tv_usec * 1000;
#endif
return rv;
}
+#endif
+
+#ifdef _WIN32
+static int ppm_gettime(struct time_generic *tg)
+{
+ int rv;
+ int64_t frac;
+ if (!tg->init) {
+ QueryPerformanceFrequency(&tg->frequency);
+ tg->init = 1;
+ }
+ rv = QueryPerformanceCounter(&tg->ticks);
+ tg->tv_sec = tg->ticks.QuadPart / tg->frequency.QuadPart;
+ frac = (int64_t)(tg->ticks.QuadPart - (tg->tv_sec * tg->frequency.QuadPart));
+ tg->tv_nsec = (long)(frac * 1000000000L / (int64_t)tg->frequency.QuadPart);
+ return !rv;
+}
+#endif
static int ppm_report(uint64_t nsamples, uint64_t interval)
{
@@ -165,8 +201,8 @@ static void ppm_test(uint32_t len)
static uint64_t interval = 0;
static uint64_t nsamples_total = 0;
static uint64_t interval_total = 0;
- struct timespec ppm_now;
- static struct timespec ppm_recent;
+ struct time_generic ppm_now;
+ static struct time_generic ppm_recent;
static enum {
PPM_INIT_NO,
PPM_INIT_DUMP,
@@ -174,6 +210,7 @@ static void ppm_test(uint32_t len)
} ppm_init = PPM_INIT_NO;
ppm_gettime(&ppm_now);
+
if (ppm_init != PPM_INIT_RUN) {
/*
* Kyle Keen wrote:
@@ -189,11 +226,11 @@ static void ppm_test(uint32_t len)
}
if (ppm_init == PPM_INIT_DUMP && ppm_recent.tv_sec < ppm_now.tv_sec)
return;
- ppm_recent.tv_sec = ppm_now.tv_sec;
- ppm_recent.tv_nsec = ppm_now.tv_nsec;
+ ppm_recent = ppm_now;
ppm_init = PPM_INIT_RUN;
return;
}
+
nsamples += (uint64_t)(len / 2UL);
interval = (uint64_t)(ppm_now.tv_sec - ppm_recent.tv_sec);
if (interval < ppm_duration)
@@ -206,19 +243,16 @@ static void ppm_test(uint32_t len)
(int)((1000000000UL * nsamples) / interval),
ppm_report(nsamples, interval),
ppm_report(nsamples_total, interval_total));
- ppm_recent.tv_sec = ppm_now.tv_sec;
- ppm_recent.tv_nsec = ppm_now.tv_nsec;
+ ppm_recent = ppm_now;
nsamples = 0;
}
-#endif
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
underrun_test(buf, len, 0);
-#ifndef _WIN32
+
if (test_mode == PPM_BENCHMARK)
ppm_test(len);
-#endif
}
void e4k_benchmark(void)
@@ -375,7 +409,7 @@ int main(int argc, char **argv)
verbose_reset_buffer(dev);
if ((test_mode == PPM_BENCHMARK) && !sync_mode) {
- fprintf(stderr, "Reporting PPM error measurement every %i seconds...\n", ppm_duration);
+ fprintf(stderr, "Reporting PPM error measurement every %u seconds...\n", ppm_duration);
fprintf(stderr, "Press ^C after a few minutes.\n");
}