diff options
Diffstat (limited to 'utils')
-rw-r--r-- | utils/convenience/convenience.c | 4 | ||||
-rw-r--r-- | utils/rtl_adsb.c | 21 | ||||
-rw-r--r-- | utils/rtl_biast.c | 101 | ||||
-rw-r--r-- | utils/rtl_eeprom.c | 7 | ||||
-rw-r--r-- | utils/rtl_fm.c | 41 | ||||
-rw-r--r-- | utils/rtl_power.c | 21 | ||||
-rw-r--r-- | utils/rtl_tcp.c | 119 | ||||
-rw-r--r-- | utils/rtl_test.c | 62 |
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"); } |