From a5e0e0ecb1bdff3c9919549b80c561adba443df1 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 4 Jan 2015 15:47:48 -0600 Subject: [PATCH 01/74] add rtlsdr_rpc support --- include/rtlsdr_rpc.h | 123 ++++++ include/rtlsdr_rpc_msg.h | 94 +++++ src/CMakeLists.txt | 11 +- src/Makefile.am | 7 +- src/librtlsdr.c | 172 ++++++++ src/rtl_rpcd.c | 861 ++++++++++++++++++++++++++++++++++++++ src/rtlsdr_rpc.c | 881 +++++++++++++++++++++++++++++++++++++++ src/rtlsdr_rpc_msg.c | 298 +++++++++++++ 8 files changed, 2444 insertions(+), 3 deletions(-) create mode 100644 include/rtlsdr_rpc.h create mode 100644 include/rtlsdr_rpc_msg.h create mode 100644 src/rtl_rpcd.c create mode 100644 src/rtlsdr_rpc.c create mode 100644 src/rtlsdr_rpc_msg.c diff --git a/include/rtlsdr_rpc.h b/include/rtlsdr_rpc.h new file mode 100644 index 0000000..eb782c6 --- /dev/null +++ b/include/rtlsdr_rpc.h @@ -0,0 +1,123 @@ +#ifndef RTLSDR_RPC_H_INCLUDED +#define RTLSDR_RPC_H_INCLUDED + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*rtlsdr_rpc_read_async_cb_t) +(unsigned char*, uint32_t, void*); + +uint32_t rtlsdr_rpc_get_device_count(void); + +const char* rtlsdr_rpc_get_device_name +(uint32_t nidex); + +int rtlsdr_rpc_get_device_usb_strings +(uint32_t index, char* manufact, char* product, char* serial); + +int rtlsdr_rpc_get_index_by_serial +(const char* serial); + +int rtlsdr_rpc_open +(void** dev, uint32_t index); + +int rtlsdr_rpc_close +(void* dev); + +int rtlsdr_rpc_set_xtal_freq +(void* dev, uint32_t rtl_freq, uint32_t tuner_freq); + +int rtlsdr_rpc_get_xtal_freq +(void* dev, uint32_t* rtl_freq, uint32_t* tuner_freq); + +int rtlsdr_rpc_get_usb_strings +(void* dev, char* manufact, char* product, char* serial); + +int rtlsdr_rpc_write_eeprom +(void* dev, uint8_t* data, uint8_t offset, uint16_t len); + +int rtlsdr_rpc_read_eeprom +(void* dev, uint8_t* data, uint8_t offset, uint16_t len); + +int rtlsdr_rpc_set_center_freq +(void* dev, uint32_t freq); + +uint32_t rtlsdr_rpc_get_center_freq +(void* dev); + +int rtlsdr_rpc_set_freq_correction +(void* dev, int ppm); + +int rtlsdr_rpc_get_freq_correction +(void *dev); + +int rtlsdr_rpc_get_tuner_type +(void* dev); + +int rtlsdr_rpc_get_tuner_gains +(void* dev, int* gainsp); + +int rtlsdr_rpc_set_tuner_gain +(void *dev, int gain); + +int rtlsdr_rpc_get_tuner_gain +(void* dev); + +int rtlsdr_rpc_set_tuner_if_gain +(void* dev, int stage, int gain); + +int rtlsdr_rpc_set_tuner_gain_mode +(void* dev, int manual); + +int rtlsdr_rpc_set_sample_rate +(void* dev, uint32_t rate); + +uint32_t rtlsdr_rpc_get_sample_rate +(void* dev); + +int rtlsdr_rpc_set_testmode +(void* dev, int on); + +int rtlsdr_rpc_set_agc_mode +(void* dev, int on); + +int rtlsdr_rpc_set_direct_sampling +(void* dev, int on); + +int rtlsdr_rpc_get_direct_sampling +(void* dev); + +int rtlsdr_rpc_set_offset_tuning +(void* dev, int on); + +int rtlsdr_rpc_get_offset_tuning +(void* dev); + +int rtlsdr_rpc_reset_buffer +(void* dev); + +int rtlsdr_rpc_read_sync +(void* dev, void* buf, int len, int* n_read); + +int rtlsdr_rpc_wait_async +(void* dev, rtlsdr_rpc_read_async_cb_t cb, void* ctx); + +int rtlsdr_rpc_read_async +(void* dev, rtlsdr_rpc_read_async_cb_t cb, void* ctx, uint32_t buf_num, uint32_t buf_len); + +int rtlsdr_rpc_cancel_async +(void* dev); + +unsigned int rtlsdr_rpc_is_enabled(void); + +#ifdef __cplusplus +} +#endif + + +#endif /* RTLSDR_RPC_H_INCLUDED */ diff --git a/include/rtlsdr_rpc_msg.h b/include/rtlsdr_rpc_msg.h new file mode 100644 index 0000000..d028c21 --- /dev/null +++ b/include/rtlsdr_rpc_msg.h @@ -0,0 +1,94 @@ +#ifndef RTLSDR_RPC_MSG_H_INCLUDED +#define RTLSDR_RPC_MSG_H_INCLUDED + + +#include +#include + +typedef enum +{ + RTLSDR_RPC_OP_GET_DEVICE_COUNT = 0, + RTLSDR_RPC_OP_GET_DEVICE_NAME, + RTLSDR_RPC_OP_GET_DEVICE_USB_STRINGS, + RTLSDR_RPC_OP_GET_INDEX_BY_SERIAL, + RTLSDR_RPC_OP_OPEN, + RTLSDR_RPC_OP_CLOSE, + RTLSDR_RPC_OP_SET_XTAL_FREQ, + RTLSDR_RPC_OP_GET_XTAL_FREQ, + RTLSDR_RPC_OP_GET_USB_STRINGS, + RTLSDR_RPC_OP_WRITE_EEPROM, + RTLSDR_RPC_OP_READ_EEPROM, + RTLSDR_RPC_OP_SET_CENTER_FREQ, + RTLSDR_RPC_OP_GET_CENTER_FREQ, + RTLSDR_RPC_OP_SET_FREQ_CORRECTION, + RTLSDR_RPC_OP_GET_FREQ_CORRECTION, + RTLSDR_RPC_OP_GET_TUNER_TYPE, + RTLSDR_RPC_OP_GET_TUNER_GAINS, + RTLSDR_RPC_OP_SET_TUNER_GAIN, + RTLSDR_RPC_OP_GET_TUNER_GAIN, + RTLSDR_RPC_OP_SET_TUNER_IF_GAIN, + RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE, + RTLSDR_RPC_OP_SET_SAMPLE_RATE, + RTLSDR_RPC_OP_GET_SAMPLE_RATE, + RTLSDR_RPC_OP_SET_TESTMODE, + RTLSDR_RPC_OP_SET_AGC_MODE, + RTLSDR_RPC_OP_SET_DIRECT_SAMPLING, + RTLSDR_RPC_OP_GET_DIRECT_SAMPLING, + RTLSDR_RPC_OP_SET_OFFSET_TUNING, + RTLSDR_RPC_OP_GET_OFFSET_TUNING, + RTLSDR_RPC_OP_RESET_BUFFER, + RTLSDR_RPC_OP_READ_SYNC, + RTLSDR_RPC_OP_WAIT_ASYNC, + RTLSDR_RPC_OP_READ_ASYNC, + RTLSDR_RPC_OP_CANCEL_ASYNC, + + /* non api operations */ + RTLSDR_RPC_OP_EVENT_STATE, + + RTLSDR_RPC_OP_INVALID +} rtlsdr_rpc_op_t; + +typedef struct +{ + /* raw network format */ + uint32_t size; + uint8_t op; + uint16_t mid; + uint32_t err; + uint8_t data[1]; +} __attribute__((packed)) rtlsdr_rpc_fmt_t; + +typedef struct +{ + size_t off; + size_t size; + uint8_t* fmt; +} rtlsdr_rpc_msg_t; + +int rtlsdr_rpc_msg_init(rtlsdr_rpc_msg_t*, size_t); +int rtlsdr_rpc_msg_fini(rtlsdr_rpc_msg_t*); +void rtlsdr_rpc_msg_reset(rtlsdr_rpc_msg_t*); +int rtlsdr_rpc_msg_realloc(rtlsdr_rpc_msg_t*, size_t); + +void rtlsdr_rpc_msg_set_size(rtlsdr_rpc_msg_t*, size_t); +size_t rtlsdr_rpc_msg_get_size(const rtlsdr_rpc_msg_t*); +void rtlsdr_rpc_msg_set_op(rtlsdr_rpc_msg_t*, rtlsdr_rpc_op_t); +rtlsdr_rpc_op_t rtlsdr_rpc_msg_get_op(const rtlsdr_rpc_msg_t*); +void rtlsdr_rpc_msg_set_mid(rtlsdr_rpc_msg_t*, uint16_t); +uint16_t rtlsdr_rpc_msg_get_mid(const rtlsdr_rpc_msg_t*); +void rtlsdr_rpc_msg_set_err(rtlsdr_rpc_msg_t*, int); +int rtlsdr_rpc_msg_get_err(const rtlsdr_rpc_msg_t*); + +int rtlsdr_rpc_msg_push_int32(rtlsdr_rpc_msg_t*, int32_t); +int rtlsdr_rpc_msg_push_uint32(rtlsdr_rpc_msg_t*, uint32_t); +void rtlsdr_rpc_msg_push_uint32_safe(rtlsdr_rpc_msg_t*, uint32_t); +int rtlsdr_rpc_msg_push_str(rtlsdr_rpc_msg_t*, const char*); +int rtlsdr_rpc_msg_push_buf(rtlsdr_rpc_msg_t*, const uint8_t*, size_t); +void rtlsdr_rpc_msg_skip_safe(rtlsdr_rpc_msg_t*, size_t); +int rtlsdr_rpc_msg_pop_int32(rtlsdr_rpc_msg_t*, int32_t*); +int rtlsdr_rpc_msg_pop_uint32(rtlsdr_rpc_msg_t*, uint32_t*); +int rtlsdr_rpc_msg_pop_str(rtlsdr_rpc_msg_t*, const char**); +int rtlsdr_rpc_msg_pop_buf(rtlsdr_rpc_msg_t*, const uint8_t**, size_t*); + + +#endif /* RTLSDR_RPC_MSG_H_INCLUDED */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07d64ab..defa14d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,8 @@ RTLSDR_APPEND_SRCS( tuner_fc0013.c tuner_fc2580.c tuner_r82xx.c + rtlsdr_rpc.c + rtlsdr_rpc_msg.c ) ######################################################################## @@ -91,7 +93,8 @@ add_executable(rtl_fm rtl_fm.c) add_executable(rtl_eeprom rtl_eeprom.c) add_executable(rtl_adsb rtl_adsb.c) add_executable(rtl_power rtl_power.c) -set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power) +add_executable(rtl_rpcd rtl_rpcd.c rtlsdr_rpc_msg.c) +set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power rtl_rpcd) target_link_libraries(rtl_sdr rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} @@ -121,6 +124,10 @@ target_link_libraries(rtl_power rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) +target_link_libraries(rtl_rpcd rtlsdr_shared convenience_static + ${LIBUSB_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} +) if(UNIX) target_link_libraries(rtl_fm m) target_link_libraries(rtl_adsb m) @@ -140,6 +147,7 @@ target_link_libraries(rtl_fm libgetopt_static) target_link_libraries(rtl_eeprom libgetopt_static) target_link_libraries(rtl_adsb libgetopt_static) target_link_libraries(rtl_power libgetopt_static) +target_link_libraries(rtl_rpcd ws2_32 libgetopt_static) set_property(TARGET rtl_sdr APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_tcp APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_test APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) @@ -147,6 +155,7 @@ set_property(TARGET rtl_fm APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_eeprom APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_adsb APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_power APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) +set_property(TARGET rtl_rpcd APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) endif() ######################################################################## # Install built library files & utilities diff --git a/src/Makefile.am b/src/Makefile.am index 200990a..11855a9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,10 +9,10 @@ AM_CFLAGS = ${CFLAGS} -fPIC ${SYMBOL_VISIBILITY} lib_LTLIBRARIES = librtlsdr.la -librtlsdr_la_SOURCES = librtlsdr.c tuner_e4k.c tuner_fc0012.c tuner_fc0013.c tuner_fc2580.c tuner_r82xx.c +librtlsdr_la_SOURCES = librtlsdr.c tuner_e4k.c tuner_fc0012.c tuner_fc0013.c tuner_fc2580.c tuner_r82xx.c rtlsdr_rpc.c rtlsdr_rpc_msg.c librtlsdr_la_LDFLAGS = -version-info $(LIBVERSION) -bin_PROGRAMS = rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power +bin_PROGRAMS = rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power rtl_rpcd rtl_sdr_SOURCES = rtl_sdr.c convenience/convenience.c rtl_sdr_LDADD = librtlsdr.la @@ -34,3 +34,6 @@ rtl_adsb_LDADD = librtlsdr.la $(LIBM) rtl_power_SOURCES = rtl_power.c convenience/convenience.c rtl_power_LDADD = librtlsdr.la $(LIBM) + +rtl_rpcd_SOURCES = rtl_rpcd.c rtlsdr_rpc_msg.c convenience/convenience.c +rtl_rpcd_LDADD = librtlsdr.la diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 9a3ebcd..eb1c4eb 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -28,6 +28,7 @@ #endif #include +#include "rtlsdr_rpc.h" /* * All libusb callback functions should be marked with the LIBUSB_CALL macro @@ -714,6 +715,11 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_xtal_freq(dev, rtl_freq, tuner_freq); + } + if (!dev) return -1; @@ -750,6 +756,11 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_freq) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_xtal_freq(dev, rtl_freq, tuner_freq); + } + if (!dev) return -1; @@ -772,6 +783,11 @@ int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, const int buf_max = 256; int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_usb_strings(dev, manufact, product, serial); + } + if (!dev || !dev->devh) return -1; @@ -811,6 +827,11 @@ int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16 int i; uint8_t cmd[2]; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_write_eeprom(dev, data, offset, len); + } + if (!dev) return -1; @@ -848,6 +869,11 @@ int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_ int r = 0; int i; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_read_eeprom(dev, data, offset, len); + } + if (!dev) return -1; @@ -872,6 +898,11 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) { int r = -1; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_center_freq(dev, freq); + } + if (!dev || !dev->tuner) return -1; @@ -893,6 +924,11 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_center_freq(dev); + } + if (!dev) return 0; @@ -903,6 +939,11 @@ int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_freq_correction(dev, ppm); + } + if (!dev) return -1; @@ -926,6 +967,11 @@ int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_freq_correction(dev); + } + if (!dev) return 0; @@ -934,6 +980,11 @@ int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev) enum rtlsdr_tuner rtlsdr_get_tuner_type(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return (enum rtlsdr_tuner)rtlsdr_rpc_get_tuner_type(dev); + } + if (!dev) return RTLSDR_TUNER_UNKNOWN; @@ -959,6 +1010,11 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) const int *ptr = NULL; int len = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_tuner_gains(dev, gains); + } + if (!dev) return -1; @@ -998,6 +1054,11 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_tuner_gain(dev, gain); + } + if (!dev || !dev->tuner) return -1; @@ -1017,6 +1078,11 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_tuner_gain(dev); + } + if (!dev) return 0; @@ -1027,6 +1093,11 @@ int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_tuner_if_gain(dev, stage, gain); + } + if (!dev || !dev->tuner) return -1; @@ -1043,6 +1114,11 @@ int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int mode) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_tuner_gain_mode(dev, mode); + } + if (!dev || !dev->tuner) return -1; @@ -1062,6 +1138,11 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) uint32_t rsamp_ratio, real_rsamp_ratio; double real_rate; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_sample_rate(dev, samp_rate); + } + if (!dev) return -1; @@ -1109,6 +1190,11 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_sample_rate(dev); + } + if (!dev) return 0; @@ -1117,6 +1203,11 @@ uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev) int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_testmode(dev, on); + } + if (!dev) return -1; @@ -1125,6 +1216,11 @@ int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on) int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_agc_mode(dev, on); + } + if (!dev) return -1; @@ -1135,6 +1231,11 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_direct_sampling(dev, on); + } + if (!dev) return -1; @@ -1196,6 +1297,11 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_direct_sampling(dev); + } + if (!dev) return -1; @@ -1206,6 +1312,11 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) { int r = 0; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_set_offset_tuning(dev, on); + } + if (!dev) return -1; @@ -1234,6 +1345,11 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) int rtlsdr_get_offset_tuning(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_offset_tuning(dev); + } + if (!dev) return -1; @@ -1264,6 +1380,11 @@ uint32_t rtlsdr_get_device_count(void) struct libusb_device_descriptor dd; ssize_t cnt; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_device_count(); + } + libusb_init(&ctx); cnt = libusb_get_device_list(ctx, &list); @@ -1292,6 +1413,11 @@ const char *rtlsdr_get_device_name(uint32_t index) uint32_t device_count = 0; ssize_t cnt; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_device_name(index); + } + libusb_init(&ctx); cnt = libusb_get_device_list(ctx, &list); @@ -1332,6 +1458,12 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, uint32_t device_count = 0; ssize_t cnt; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_device_usb_strings + (index, manufact, product, serial); + } + libusb_init(&ctx); cnt = libusb_get_device_list(ctx, &list); @@ -1370,6 +1502,11 @@ int rtlsdr_get_index_by_serial(const char *serial) int i, cnt, r; char str[256]; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_get_index_by_serial(serial); + } + if (!serial) return -1; @@ -1399,6 +1536,11 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) uint8_t reg; ssize_t cnt; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_open((void**)out_dev, index); + } + dev = malloc(sizeof(rtlsdr_dev_t)); if (NULL == dev) return -ENOMEM; @@ -1585,6 +1727,11 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) int rtlsdr_close(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_close(dev); + } + if (!dev) return -1; @@ -1623,6 +1770,11 @@ int rtlsdr_close(rtlsdr_dev_t *dev) int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_reset_buffer(dev); + } + if (!dev) return -1; @@ -1634,6 +1786,11 @@ int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_read_sync(dev, buf, len, n_read); + } + if (!dev) return -1; @@ -1670,6 +1827,11 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_wait_async(dev, cb, ctx); + } + return rtlsdr_read_async(dev, cb, ctx, 0, 0); } @@ -1739,6 +1901,11 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, struct timeval zerotv = { 0, 0 }; enum rtlsdr_async_status next_status = RTLSDR_INACTIVE; + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_read_async(dev, cb, ctx, buf_num, buf_len); + } + if (!dev) return -1; @@ -1836,6 +2003,11 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, int rtlsdr_cancel_async(rtlsdr_dev_t *dev) { + if (rtlsdr_rpc_is_enabled()) + { + return rtlsdr_rpc_cancel_async(dev); + } + if (!dev) return -1; diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c new file mode 100644 index 0000000..45b6e67 --- /dev/null +++ b/src/rtl_rpcd.c @@ -0,0 +1,861 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rtlsdr_rpc_msg.h" + + +#if 1 +#include +#define PRINTF(__s, ...) fprintf(stderr, __s, ##__VA_ARGS__) +#define TRACE() PRINTF("[t] %s,%u\n", __FILE__, __LINE__) +#define ERROR() PRINTF("[e] %s,%u\n", __FILE__, __LINE__) +#else +#define TRACE() +#define ERROR() +#define PRINTF(...) +#endif + + +typedef struct +{ + int listen_sock; + int cli_sock; + + rtlsdr_dev_t* dev; + uint32_t did; + + rtlsdr_rpc_msg_t query_msg; + rtlsdr_rpc_msg_t reply_msg; + rtlsdr_rpc_msg_t event_msg; + +} rpcd_t; + +static int resolve_ip_addr +( + struct sockaddr_storage saddr_both[2], size_t size_both[2], + const char* addr, const char* port +) +{ + struct addrinfo ai; + struct addrinfo* aip = NULL; + int err = -1; + size_t i; + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = AF_UNSPEC; + ai.ai_socktype = SOCK_STREAM; + ai.ai_flags = AI_PASSIVE; + + if (getaddrinfo(addr, port, &ai, &aip)) goto on_error; + + size_both[0] = 0; + size_both[1] = 0; + i = 0; + for (; (i != 2) && (aip != NULL); aip = aip->ai_next) + { + if ((aip->ai_family != AF_INET) && (aip->ai_family != AF_INET6)) continue ; + if (aip->ai_addrlen == 0) continue ; + memcpy(&saddr_both[i], aip->ai_addr, aip->ai_addrlen); + size_both[i] = aip->ai_addrlen; + ++i; + } + + if (i == 0) goto on_error; + + err = 0; + on_error: + if (aip != NULL) freeaddrinfo(aip); + return err; +} + +static int open_nonblock_socket +( + struct sockaddr_storage saddr_both[2], size_t size_both[2], + int type, int proto, + struct sockaddr_storage** saddr_used, size_t* size_used +) +{ + size_t i; + int fd = -1; + + for (i = 0; (i != 2) && (size_both[i]); ++i) + { + const struct sockaddr* const sa = (const struct sockaddr*)&saddr_both[i]; + fd = socket(sa->sa_family, type, proto); + if (fd != -1) break ; + } + + if ((i == 2) || (size_both[i] == 0)) return -1; + + *saddr_used = &saddr_both[i]; + *size_used = size_both[i]; + + if (fcntl(fd, F_SETFL, O_NONBLOCK)) + { + close(fd); + return -1; + } + + return fd; +} + +static int init_rpcd(rpcd_t* rpcd, const char* addr, const char* port) +{ + struct sockaddr_storage saddrs[2]; + struct sockaddr_storage* saddr; + size_t sizes[2]; + size_t size; + int err; + int enable = 1; + + /* TODO: handle errors */ + rtlsdr_rpc_msg_init(&rpcd->query_msg, 0); + rtlsdr_rpc_msg_init(&rpcd->reply_msg, 0); + rtlsdr_rpc_msg_init(&rpcd->event_msg, 0); + + if (resolve_ip_addr(saddrs, sizes, addr, port)) + { + ERROR(); + goto on_error_0; + } + + rpcd->listen_sock = open_nonblock_socket + (saddrs, sizes, SOCK_STREAM, IPPROTO_TCP, &saddr, &size); + if (rpcd->listen_sock == -1) + { + ERROR(); + goto on_error_0; + } + + err = setsockopt + (rpcd->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); + if (err) + { + ERROR(); + goto on_error_1; + } + + err = bind + (rpcd->listen_sock, (const struct sockaddr*)saddr, (socklen_t)size); + if (err) + { + ERROR(); + goto on_error_1; + } + + if (listen(rpcd->listen_sock, 5)) + { + ERROR(); + goto on_error_1; + } + + rpcd->cli_sock = -1; + rpcd->dev = NULL; + + return 0; + + on_error_1: + close(rpcd->listen_sock); + on_error_0: + return -1; +} + +static int fini_rpcd(rpcd_t* rpcd) +{ + if (rpcd->cli_sock != -1) + { + shutdown(rpcd->cli_sock, SHUT_RDWR); + close(rpcd->cli_sock); + } + + shutdown(rpcd->listen_sock, SHUT_RDWR); + close(rpcd->listen_sock); + + rtlsdr_rpc_msg_fini(&rpcd->query_msg); + rtlsdr_rpc_msg_fini(&rpcd->reply_msg); + rtlsdr_rpc_msg_fini(&rpcd->event_msg); + + return 0; +} + +static int recv_all(int fd, uint8_t* buf, size_t size) +{ + ssize_t n; + fd_set rset; + + while (1) + { + errno = 0; + n = recv(fd, buf, size, 0); + if (n <= 0) + { + if ((errno != EWOULDBLOCK) || (errno != EAGAIN)) + return -1; + } + else + { + size -= (size_t)n; + buf += (size_t)n; + if (size == 0) break ; + } + + FD_ZERO(&rset); + FD_SET(fd, &rset); + if (select(fd + 1, &rset, NULL, NULL, NULL) <= 0) + { + return -1; + } + } + + return 0; +} + +static int send_all_check_recv +(int fd, const uint8_t* buf, size_t size, unsigned int* is_recv) +{ + ssize_t n; + fd_set wset; + fd_set rset; + fd_set* rsetp; + + rsetp = NULL; + if (is_recv != NULL) *is_recv = 0; + + while (1) + { + FD_ZERO(&wset); + FD_SET(fd, &wset); + + rsetp = NULL; + if ((is_recv != NULL) && (*is_recv == 0)) + { + FD_ZERO(&rset); + FD_SET(fd, &rset); + rsetp = &rset; + } + + if (select(fd + 1, rsetp, &wset, NULL, NULL) <= 0) + { + return -1; + } + + if ((rsetp != NULL) && FD_ISSET(fd, rsetp)) + { + *is_recv = 1; + } + + if (FD_ISSET(fd, &wset)) + { + errno = 0; + n = send(fd, buf, size, 0); + if (n <= 0) + { + if ((errno != EWOULDBLOCK) || (errno != EAGAIN)) + return -1; + } + else + { + size -= (size_t)n; + buf += (size_t)n; + if (size == 0) break ; + } + } + } + + return 0; +} + +static int send_all(int fd, const uint8_t* buf, size_t size) +{ + return send_all_check_recv(fd, buf, size, NULL); +} + +static int recv_msg(int fd, rtlsdr_rpc_msg_t* m) +{ + uint32_t size; + + if (recv_all(fd, (uint8_t*)&size, sizeof(uint32_t))) + { + ERROR(); + return -1; + } + + rtlsdr_rpc_msg_set_size(m, size); + size = rtlsdr_rpc_msg_get_size(m); + + if (rtlsdr_rpc_msg_realloc(m, size)) + { + ERROR(); + return -1; + } + + if (recv_all(fd, m->fmt + sizeof(uint32_t), size - sizeof(uint32_t))) + { + ERROR(); + return -1; + } + + return 0; +} + +static int send_msg(int fd, rtlsdr_rpc_msg_t* m) +{ + return send_all(fd, m->fmt, m->off); +} + +static int recv_query(rpcd_t* rpcd, rtlsdr_rpc_msg_t** q) +{ + *q = NULL; + rtlsdr_rpc_msg_reset(&rpcd->query_msg); + if (recv_msg(rpcd->cli_sock, &rpcd->query_msg)) return -1; + *q = &rpcd->query_msg; + return 0; +} + +static int send_reply(rpcd_t* rpcd, rtlsdr_rpc_msg_t* r) +{ + return send_msg(rpcd->cli_sock, r); +} + +static void read_async_cb +(unsigned char* buf, uint32_t len, void* ctx) +{ + rpcd_t* const rpcd = ctx; + const size_t off = offsetof(rtlsdr_rpc_fmt_t, data); + rtlsdr_rpc_fmt_t fmt; + rtlsdr_rpc_msg_t msg; + unsigned int is_recv; + + if (rpcd->reply_msg.off) + { + send_reply(rpcd, &rpcd->reply_msg); + rpcd->reply_msg.off = 0; + } + + msg.off = off; + msg.size = off + len; + msg.fmt = (uint8_t*)&fmt; + rtlsdr_rpc_msg_set_size(&msg, msg.size); + rtlsdr_rpc_msg_set_op(&msg, RTLSDR_RPC_OP_READ_ASYNC); + + send_all(rpcd->cli_sock, (const uint8_t*)&fmt, off); + send_all_check_recv(rpcd->cli_sock, buf, len, &is_recv); + + if (is_recv) rtlsdr_cancel_async(rpcd->dev); +} + +static int handle_query +(rpcd_t* rpcd, rtlsdr_rpc_msg_t* q, rtlsdr_rpc_msg_t** rr) +{ + rtlsdr_rpc_msg_t* const r = &rpcd->reply_msg; + rtlsdr_rpc_op_t op; + int err = -1; + + *rr = NULL; + + rtlsdr_rpc_msg_reset(r); + + op = rtlsdr_rpc_msg_get_op(q); + switch (op) + { + case RTLSDR_RPC_OP_GET_DEVICE_COUNT: + { + uint32_t n; + + PRINTF("get_device_count()\n"); + + n = rtlsdr_get_device_count(); + if (rtlsdr_rpc_msg_push_uint32(r, n)) goto on_error; + err = 0; + break ; + } + + case RTLSDR_RPC_OP_GET_DEVICE_NAME: + { + const char* s; + uint32_t i; + + PRINTF("get_device_name()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &i)) goto on_error; + + s = rtlsdr_get_device_name(i); + if (s == NULL) s = ""; + + if (rtlsdr_rpc_msg_push_str(r, s)) goto on_error; + + err = 0; + + break ; + } + + case RTLSDR_RPC_OP_GET_DEVICE_USB_STRINGS: + { + char manuf[256]; + char product[256]; + char serial[256]; + uint32_t i; + + PRINTF("get_device_usb_strings()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &i)) goto on_error; + + err = rtlsdr_get_device_usb_strings(i, manuf, product, serial); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_push_str(r, manuf)) + { + err = -1; + goto on_error; + } + + if (rtlsdr_rpc_msg_push_str(r, product)) + { + err = -1; + goto on_error; + } + + if (rtlsdr_rpc_msg_push_str(r, serial)) + { + err = -1; + goto on_error; + } + + break ; + } + + case RTLSDR_RPC_OP_GET_INDEX_BY_SERIAL: + { + const char* serial; + + PRINTF("get_index_by_serial()\n"); + + if (rtlsdr_rpc_msg_pop_str(q, &serial)) goto on_error; + err = rtlsdr_get_index_by_serial(serial); + if (err < 0) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_OPEN: + { + PRINTF("open()\n"); + + if (rpcd->dev != NULL) goto on_error; + + if (rtlsdr_rpc_msg_pop_uint32(q, &rpcd->did)) goto on_error; + err = rtlsdr_open(&rpcd->dev, rpcd->did); + if (err) + { + rpcd->dev = NULL; + goto on_error; + } + + break ; + } + + case RTLSDR_RPC_OP_CLOSE: + { + uint32_t did; + + PRINTF("close()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + err = rtlsdr_close(rpcd->dev); + rpcd->dev = NULL; + + break ; + } + + case RTLSDR_RPC_OP_SET_XTAL_FREQ: + { + uint32_t did; + uint32_t rtl_freq; + uint32_t tuner_freq; + + PRINTF("set_xtal_freq()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &rtl_freq)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &tuner_freq)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_xtal_freq(rpcd->dev, rtl_freq, tuner_freq); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_GET_XTAL_FREQ: + { + uint32_t did; + uint32_t rtl_freq; + uint32_t tuner_freq; + + PRINTF("get_xtal_freq()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_xtal_freq(rpcd->dev, &rtl_freq, &tuner_freq); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_push_uint32(r, rtl_freq)) + { + err = -1; + goto on_error; + } + + if (rtlsdr_rpc_msg_push_uint32(r, tuner_freq)) + { + err = -1; + goto on_error; + } + + break ; + } + + case RTLSDR_RPC_OP_SET_CENTER_FREQ: + { + uint32_t did; + uint32_t freq; + + PRINTF("set_center_freq()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &freq)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_center_freq(rpcd->dev, freq); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_GET_CENTER_FREQ: + { + uint32_t did; + uint32_t freq; + + PRINTF("get_center_freq()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + freq = rtlsdr_get_center_freq(rpcd->dev); + if (freq == 0) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(r, freq)) goto on_error; + err = 0; + + break ; + } + + case RTLSDR_RPC_OP_SET_FREQ_CORRECTION: + { + uint32_t did; + uint32_t ppm; + + PRINTF("set_freq_correction()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &ppm)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_freq_correction(rpcd->dev, (int)ppm); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_GET_FREQ_CORRECTION: + { + uint32_t did; + + PRINTF("get_freq_correction()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_freq_correction(rpcd->dev); + + break ; + } + + case RTLSDR_RPC_OP_GET_TUNER_TYPE: + { + uint32_t did; + + PRINTF("get_tuner_type()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_tuner_type(rpcd->dev); + + break ; + } + + case RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE: + { + uint32_t did; + uint32_t manual; + + PRINTF("set_tuner_gain_mode()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &manual)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_tuner_gain_mode(rpcd->dev, (int)manual); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_SET_SAMPLE_RATE: + { + uint32_t did; + uint32_t rate; + + PRINTF("set_sample_rate()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &rate)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_sample_rate(rpcd->dev, rate); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_GET_SAMPLE_RATE: + { + uint32_t did; + uint32_t rate; + + PRINTF("get_sample_rate()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + rate = rtlsdr_get_sample_rate(rpcd->dev); + if (rate == 0) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(r, rate)) goto on_error; + err = 0; + + break ; + } + + case RTLSDR_RPC_OP_RESET_BUFFER: + { + uint32_t did; + + PRINTF("reset_buffer()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_reset_buffer(rpcd->dev); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_READ_ASYNC: + { + uint32_t did; + uint32_t buf_num; + uint32_t buf_len; + + PRINTF("read_async()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &buf_num)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &buf_len)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + /* prepare the reply here */ + rtlsdr_rpc_msg_set_size(r, r->off); + rtlsdr_rpc_msg_set_op(r, op); + rtlsdr_rpc_msg_set_mid(r, rtlsdr_rpc_msg_get_mid(q)); + rtlsdr_rpc_msg_set_err(r, 0); + + rtlsdr_read_async + (rpcd->dev, read_async_cb, rpcd, buf_num, buf_len); + + /* do not resend reply */ + return 0; + break ; + } + + case RTLSDR_RPC_OP_CANCEL_ASYNC: + { + uint32_t did; + + PRINTF("cancel_async()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + /* already cancelled if here */ + err = 0; + + break ; + } + + case RTLSDR_RPC_OP_READ_SYNC: + { + uint32_t did; + uint32_t len; + int n_read; + uint8_t* buf; + size_t new_size; + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &len)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + new_size = r->off + sizeof(uint32_t) + len; + if (rtlsdr_rpc_msg_realloc(r, new_size)) goto on_error; + buf = r->fmt + r->off + sizeof(uint32_t); + + err = rtlsdr_read_sync(rpcd->dev, buf, (int)len, &n_read); + if (err) goto on_error; + + rtlsdr_rpc_msg_push_uint32_safe(r, (uint32_t)n_read); + rtlsdr_rpc_msg_skip_safe(r, (size_t)n_read); + + break ; + } + + default: + { + PRINTF("invalid op: %u\n", op); + break ; + } + } + + on_error: + rtlsdr_rpc_msg_set_size(r, r->off); + rtlsdr_rpc_msg_set_op(r, op); + rtlsdr_rpc_msg_set_mid(r, rtlsdr_rpc_msg_get_mid(q)); + rtlsdr_rpc_msg_set_err(r, err); + *rr = r; + return 0; +} + +static int do_rpcd(rpcd_t* rpcd) +{ + fd_set rset; + int max_fd; + + while (1) + { + FD_ZERO(&rset); + + if (rpcd->cli_sock != -1) + { + FD_SET(rpcd->cli_sock, &rset); + max_fd = rpcd->cli_sock; + } + else + { + FD_SET(rpcd->listen_sock, &rset); + max_fd = rpcd->listen_sock; + } + + if (select(max_fd + 1, &rset, NULL, NULL, NULL) <= 0) + { + ERROR(); + return -1; + } + + if (FD_ISSET(rpcd->listen_sock, &rset)) + { + PRINTF("new client\n"); + + rpcd->cli_sock = accept(rpcd->listen_sock, NULL, NULL); + if (rpcd->cli_sock == -1) + { + if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) + continue ; + ERROR(); + break ; + } + + if (fcntl(rpcd->cli_sock, F_SETFL, O_NONBLOCK)) + { + ERROR(); + break ; + } + } + else if (FD_ISSET(rpcd->cli_sock, &rset)) + { + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; + + if (recv_query(rpcd, &q)) + { + PRINTF("cli closed\n"); + shutdown(rpcd->cli_sock, SHUT_RDWR); + close(rpcd->cli_sock); + rpcd->cli_sock = -1; + } + else if (q != NULL) + { + handle_query(rpcd, q, &r); + if (r != NULL) send_reply(rpcd, r); + } + } + } + + return 0; +} + +int main(int ac, char** av) +{ + rpcd_t rpcd; + const char* addr; + const char* port; + + addr = getenv("RTLSDR_RPC_SERV_ADDR"); + if (addr == NULL) addr = "127.0.0.1"; + + port = getenv("RTLSDR_RPC_SERV_PORT"); + if (port == NULL) port = "40000"; + + if (init_rpcd(&rpcd, addr, port)) return -1; + do_rpcd(&rpcd); + fini_rpcd(&rpcd); + + return 0; +} diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c new file mode 100644 index 0000000..cd4a5b4 --- /dev/null +++ b/src/rtlsdr_rpc.c @@ -0,0 +1,881 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rtlsdr_rpc_msg.h" + + +#if 1 +#include +#define PRINTF(__s, ...) fprintf(stderr, __s, ##__VA_ARGS__) +#define TRACE() PRINTF("[t] %s,%u\n", __FILE__, __LINE__) +#define ERROR() PRINTF("[e] %s,%u\n", __FILE__, __LINE__) +#define UNIMPL() PRINTF("[u] %s,%u\n", __FILE__, __LINE__) +#else +#define PRINTF(...) +#define TRACE() +#define ERROR() +#define UNIMPL() +#endif + + +typedef struct +{ + unsigned int is_init; + uint16_t mid; + int sock; + rtlsdr_rpc_msg_t query; + rtlsdr_rpc_msg_t reply; + volatile unsigned int is_async_cancel; +} rtlsdr_rpc_cli_t; + +static rtlsdr_rpc_cli_t rtlsdr_rpc_cli = { 0, }; + +typedef void (*rtlsdr_rpc_read_async_cb_t) +(unsigned char*, uint32_t, void*); + +typedef struct rtlsdr_rpc_dev +{ + uint32_t index; + rtlsdr_rpc_cli_t* cli; +} rtlsdr_rpc_dev_t; + +static int resolve_ip_addr +( + struct sockaddr_storage saddr_both[2], size_t size_both[2], + const char* addr, const char* port +) +{ + struct addrinfo ai; + struct addrinfo* aip = NULL; + int err = -1; + size_t i; + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = AF_UNSPEC; + ai.ai_socktype = SOCK_STREAM; + ai.ai_flags = AI_PASSIVE; + + if (getaddrinfo(addr, port, &ai, &aip)) goto on_error; + + size_both[0] = 0; + size_both[1] = 0; + i = 0; + for (; (i != 2) && (aip != NULL); aip = aip->ai_next) + { + if ((aip->ai_family != AF_INET) && (aip->ai_family != AF_INET6)) continue ; + if (aip->ai_addrlen == 0) continue ; + memcpy(&saddr_both[i], aip->ai_addr, aip->ai_addrlen); + size_both[i] = aip->ai_addrlen; + ++i; + } + + if (i == 0) goto on_error; + + err = 0; + on_error: + if (aip != NULL) freeaddrinfo(aip); + return err; +} + +static int open_socket +( + struct sockaddr_storage saddr_both[2], size_t size_both[2], + int type, int proto, + struct sockaddr_storage** saddr_used, size_t* size_used +) +{ + size_t i; + int fd; + + for (i = 0; (i != 2) && (size_both[i]); ++i) + { + const struct sockaddr* const sa = (const struct sockaddr*)&saddr_both[i]; + fd = socket(sa->sa_family, type, proto); + if (fd != -1) break ; + } + + if ((i == 2) || (size_both[i] == 0)) return -1; + + *saddr_used = &saddr_both[i]; + *size_used = size_both[i]; + + return fd; +} + +static int init_cli(rtlsdr_rpc_cli_t* cli) +{ + struct sockaddr_storage saddrs[2]; + struct sockaddr_storage* saddr; + size_t sizes[2]; + size_t size; + const char* addr; + const char* port; + + if (cli->is_init) return 0; + + addr = getenv("RTLSDR_RPC_SERV_ADDR"); + if (addr == NULL) addr = "127.0.0.1"; + + port = getenv("RTLSDR_RPC_SERV_PORT"); + if (port == NULL) port = "40000"; + + if (resolve_ip_addr(saddrs, sizes, addr, port)) + { + ERROR(); + goto on_error_0; + } + + cli->sock = open_socket + (saddrs, sizes, SOCK_STREAM, IPPROTO_TCP, &saddr, &size); + if (cli->sock == -1) + { + ERROR(); + goto on_error_0; + } + + if (connect(cli->sock, (const struct sockaddr*)saddr, (socklen_t)size)) + { + ERROR(); + goto on_error_1; + } + + if (fcntl(cli->sock, F_SETFL, O_NONBLOCK)) + { + ERROR(); + goto on_error_1; + } + + cli->mid = 0; + if (rtlsdr_rpc_msg_init(&cli->query, 0)) goto on_error_1; + if (rtlsdr_rpc_msg_init(&cli->reply, 0)) goto on_error_2; + cli->is_init = 1; + + return 0; + + on_error_2: + rtlsdr_rpc_msg_fini(&cli->query); + on_error_1: + shutdown(cli->sock, SHUT_RDWR); + close(cli->sock); + on_error_0: + return -1; +} + +__attribute__((unused)) +static int fini_cli(rtlsdr_rpc_cli_t* cli) +{ + rtlsdr_rpc_msg_fini(&cli->query); + rtlsdr_rpc_msg_fini(&cli->reply); + shutdown(cli->sock, SHUT_RDWR); + close(cli->sock); + return 0; +} + +static uint16_t get_mid(rtlsdr_rpc_cli_t* cli) +{ + return cli->mid++; +} + +static int recv_all(int fd, uint8_t* buf, size_t size) +{ + ssize_t n; + fd_set rset; + + while (1) + { + errno = 0; + n = recv(fd, buf, size, 0); + if (n <= 0) + { + if ((errno != EWOULDBLOCK) || (errno != EAGAIN)) + return -1; + } + else + { + size -= (size_t)n; + buf += (size_t)n; + if (size == 0) break ; + } + + FD_ZERO(&rset); + FD_SET(fd, &rset); + if (select(fd + 1, &rset, NULL, NULL, NULL) <= 0) + { + return -1; + } + } + + return 0; +} + +static int send_all(int fd, const uint8_t* buf, size_t size) +{ + ssize_t n; + fd_set wset; + + while (1) + { + errno = 0; + n = send(fd, buf, size, 0); + if (n <= 0) + { + if ((errno != EWOULDBLOCK) || (errno != EAGAIN)) + return -1; + } + else + { + size -= (size_t)n; + buf += (size_t)n; + if (size == 0) break ; + } + + FD_ZERO(&wset); + FD_SET(fd, &wset); + if (select(fd + 1, NULL, &wset, NULL, NULL) <= 0) + { + return -1; + } + } + + return 0; +} + +static int recv_msg(int fd, rtlsdr_rpc_msg_t* m) +{ + uint32_t size; + + if (recv_all(fd, (uint8_t*)&size, sizeof(uint32_t))) return -1; + rtlsdr_rpc_msg_set_size(m, size); + size = rtlsdr_rpc_msg_get_size(m); + if (rtlsdr_rpc_msg_realloc(m, size)) return -1; + size -= sizeof(uint32_t); + if (recv_all(fd, m->fmt + sizeof(uint32_t), size)) return -1; + return 0; +} + +static int send_msg(int fd, rtlsdr_rpc_msg_t* m) +{ + return send_all(fd, m->fmt, m->off); +} + +static int send_recv_msg +(rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t* q, rtlsdr_rpc_msg_t* r) +{ + rtlsdr_rpc_msg_set_size(q, (uint32_t)q->off); + rtlsdr_rpc_msg_set_mid(q, get_mid(cli)); + + if (send_msg(cli->sock, q)) return -1; + + if (recv_msg(cli->sock, r)) return -1; + rtlsdr_rpc_msg_reset(r); + + return 0; +} + +uint32_t rtlsdr_rpc_get_device_count(void) +{ + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + uint32_t n = 0; + + if (init_cli(cli)) goto on_error; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_COUNT); + + if (send_recv_msg(cli, q, r)) goto on_error; + + if (rtlsdr_rpc_msg_pop_uint32(r, &n)) goto on_error; + + on_error: + return n; +} + +const char* rtlsdr_rpc_get_device_name +( + uint32_t index +) +{ + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + const char* s = NULL; + + if (init_cli(cli)) goto on_error; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_NAME); + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + /* TODO: memory leak here */ + s = strdup(s); + + on_error: + return s; +} + +int rtlsdr_rpc_get_device_usb_strings +(uint32_t index, char* manufact, char* product, char* serial) +{ + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + const char* s; + int err = -1; + + if (init_cli(cli)) goto on_error; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_USB_STRINGS); + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(manufact, s); + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(product, s); + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(serial, s); + + on_error: + return err; +} + +int rtlsdr_rpc_get_index_by_serial(const char* serial) +{ + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + if (init_cli(cli)) goto on_error; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_INDEX_BY_SERIAL); + if (rtlsdr_rpc_msg_push_str(q, serial)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; +} + +int rtlsdr_rpc_open(void** devp, uint32_t index) +{ + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_dev_t* dev; + int err = -1; + + *devp = NULL; + + if (init_cli(cli)) goto on_error_0; + + dev = malloc(sizeof(rtlsdr_rpc_dev_t)); + if (dev == NULL) goto on_error_0; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_OPEN); + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error_1; + + if (send_recv_msg(cli, q, r)) goto on_error_1; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_1; + + dev->index = index; + dev->cli = cli; + *devp = dev; + + on_error_1: + if (err) free(dev); + on_error_0: + return err; +} + +int rtlsdr_rpc_close(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_CLOSE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + free(dev); + return err; +} + +int rtlsdr_rpc_set_xtal_freq +(void* devp, uint32_t rtl_freq, uint32_t tuner_freq) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_XTAL_FREQ); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, rtl_freq)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, tuner_freq)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; +} + +int rtlsdr_rpc_get_xtal_freq +(void* devp, uint32_t* rtl_freq, uint32_t* tuner_freq) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_XTAL_FREQ); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + if (rtlsdr_rpc_msg_pop_uint32(r, rtl_freq)) + { + err = -1; + goto on_error_0; + } + + if (rtlsdr_rpc_msg_pop_uint32(r, tuner_freq)) + { + err = -1; + goto on_error_0; + } + + on_error_0: + return err; +} + +int rtlsdr_rpc_get_usb_strings +(void* dev, char* manufact, char* product, char* serial) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_write_eeprom +(void* dev, uint8_t* data, uint8_t offset, uint16_t len) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_read_eeprom +(void* dev, uint8_t* data, uint8_t offset, uint16_t len) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_center_freq(void* devp, uint32_t freq) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_CENTER_FREQ); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, freq)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; +} + +uint32_t rtlsdr_rpc_get_center_freq(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + uint32_t freq = 0; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_CENTER_FREQ); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + if (rtlsdr_rpc_msg_get_err(r)) goto on_error_0; + if (rtlsdr_rpc_msg_pop_uint32(r, &freq)) goto on_error_0; + + on_error_0: + return freq; +} + +int rtlsdr_rpc_set_freq_correction(void* devp, int ppm) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_FREQ_CORRECTION); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)ppm)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + on_error: + return err; +} + +int rtlsdr_rpc_get_freq_correction(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_FREQ_CORRECTION); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; +} + +int rtlsdr_rpc_get_tuner_type(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_TYPE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; +} + +int rtlsdr_rpc_get_tuner_gains(void* dev, int* gainsp) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_tuner_gain(void* dev, int gain) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_get_tuner_gain(void* dev) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_tuner_if_gain(void* dev, int stage, int gain) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_tuner_gain_mode(void* devp, int manual) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, manual)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + on_error: + return err; +} + +int rtlsdr_rpc_set_sample_rate(void* devp, uint32_t rate) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_SAMPLE_RATE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, rate)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; +} + +uint32_t rtlsdr_rpc_get_sample_rate(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + uint32_t rate = 0; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_SAMPLE_RATE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + if (rtlsdr_rpc_msg_get_err(r)) goto on_error_0; + if (rtlsdr_rpc_msg_pop_uint32(r, &rate)) goto on_error_0; + + on_error_0: + return rate; +} + +int rtlsdr_rpc_set_testmode(void* dev, int on) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_agc_mode(void* dev, int on) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_direct_sampling(void* dev, int on) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_get_direct_sampling(void* dev) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_set_offset_tuning(void* dev, int on) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_get_offset_tuning(void* dev) +{ + UNIMPL(); + return -1; +} + +int rtlsdr_rpc_reset_buffer(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_RESET_BUFFER); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; +} + +int rtlsdr_rpc_read_sync +(void* devp, void* buf, int len, int* n_read) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + const uint8_t* tmp; + size_t size; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_READ_SYNC); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)len)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) + { + err = -1; + goto on_error; + } + + if (size > (size_t)len) size = len; + + memcpy(buf, tmp, size); + + *n_read = (int)size; + + on_error: + return err; +} + +static volatile unsigned int is_cancel; +int rtlsdr_rpc_read_async +( + void* devp, + rtlsdr_rpc_read_async_cb_t cb, void* ctx, + uint32_t buf_num, uint32_t buf_len +) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + size_t size; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_READ_ASYNC); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, buf_num)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, buf_len)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + cli->is_async_cancel = 0; + while (cli->is_async_cancel == 0) + { + static const size_t off = offsetof(rtlsdr_rpc_fmt_t, data); + + if (recv_msg(cli->sock, r)) + { + err = -1; + goto on_error_0; + } + + size = rtlsdr_rpc_msg_get_size(r); + cb(r->fmt + off, size - off, ctx); + } + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_CANCEL_ASYNC); + rtlsdr_rpc_msg_push_uint32(q, dev->index); + send_recv_msg(cli, q, r); + + on_error_0: + return err; +} + +int rtlsdr_rpc_wait_async +( + void* dev, + rtlsdr_rpc_read_async_cb_t cb, void* ctx +) +{ + return rtlsdr_rpc_read_async(dev, cb, ctx, 0, 0); +} + +int rtlsdr_rpc_cancel_async(void* devp) +{ + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + cli->is_async_cancel = 1; + return 0; +} + +unsigned int rtlsdr_rpc_is_enabled(void) +{ + static unsigned int is_enabled = (unsigned int)-1; + if (is_enabled == (unsigned int)-1) + is_enabled = (getenv("RTLSDR_RPC_IS_ENABLED") != NULL); + return is_enabled; +} diff --git a/src/rtlsdr_rpc_msg.c b/src/rtlsdr_rpc_msg.c new file mode 100644 index 0000000..970cb7b --- /dev/null +++ b/src/rtlsdr_rpc_msg.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include "rtlsdr_rpc_msg.h" + +#if 1 +#include +#define PRINTF(__s, ...) fprintf(stderr, __s, ##__VA_ARGS__) +#define TRACE() PRINTF("[t] %s,%u\n", __FILE__, __LINE__) +#define ERROR() PRINTF("[e] %s,%u\n", __FILE__, __LINE__) +#else +#define TRACE() +#define ERROR() +#define PRINTF(...) +#endif + + +int rtlsdr_rpc_msg_init(rtlsdr_rpc_msg_t* msg, size_t data_size) +{ + size_t fmt_size; + + if (data_size == 0) data_size = 64; + + fmt_size = offsetof(rtlsdr_rpc_fmt_t, data) + data_size; + msg->fmt = malloc(fmt_size); + if (msg->fmt == NULL) return -1; + + msg->off = offsetof(rtlsdr_rpc_fmt_t, data); + msg->size = fmt_size; + + return 0; +} + +int rtlsdr_rpc_msg_fini(rtlsdr_rpc_msg_t* msg) +{ + free(msg->fmt); + return 0; +} + +void rtlsdr_rpc_msg_reset(rtlsdr_rpc_msg_t* msg) +{ + msg->off = offsetof(rtlsdr_rpc_fmt_t, data); +} + +int rtlsdr_rpc_msg_realloc(rtlsdr_rpc_msg_t* msg, size_t size) +{ + uint8_t* new_fmt; + + if (msg->size >= size) return 0; + + new_fmt = malloc(size); + if (new_fmt == NULL) return -1; + + memcpy(new_fmt, msg->fmt, msg->off); + free(msg->fmt); + msg->fmt = new_fmt; + msg->size = size; + + return 0; +} + +static int check_size(const rtlsdr_rpc_msg_t* msg, size_t size) +{ + if ((msg->off + size) > msg->size) return -1; + return 0; +} + +static int check_size_or_realloc(rtlsdr_rpc_msg_t* msg, size_t size) +{ + uint8_t* new_fmt; + size_t new_size; + + if (check_size(msg, size) == 0) return 0; + + new_size = (msg->off + size + 256) & ~(256 - 1); + new_fmt = malloc(new_size); + if (new_fmt == NULL) return -1; + + memcpy(new_fmt, msg->fmt, msg->off); + free(msg->fmt); + + msg->fmt = new_fmt; + msg->size = new_size; + + return 0; +} + +static int pop_uint32(rtlsdr_rpc_msg_t* msg, uint32_t* x) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + if (check_size(msg, sizeof(uint32_t))) return -1; + *x = *(const uint32_t*)(msg->fmt + msg->off); + msg->off += sizeof(uint32_t); + return 0; +} + +static void push_mem_safe(rtlsdr_rpc_msg_t* msg, const uint8_t* x, size_t n) +{ + memcpy(msg->fmt + msg->off, x, n); + msg->off += n; +} + +static void push_uint32_safe(rtlsdr_rpc_msg_t* msg, uint32_t x) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + push_mem_safe(msg, (const uint8_t*)&x, sizeof(uint32_t)); +} + +int rtlsdr_rpc_msg_push_int32(rtlsdr_rpc_msg_t* msg, int x) +{ + if (check_size_or_realloc(msg, sizeof(x))) return -1; + push_uint32_safe(msg, (uint32_t)x); + return 0; +} + +int rtlsdr_rpc_msg_push_uint32(rtlsdr_rpc_msg_t* msg, uint32_t x) +{ + if (check_size_or_realloc(msg, sizeof(x))) return -1; + push_uint32_safe(msg, x); + return 0; +} + +void rtlsdr_rpc_msg_push_uint32_safe(rtlsdr_rpc_msg_t* msg, uint32_t x) +{ + push_uint32_safe(msg, x); +} + +int rtlsdr_rpc_msg_push_str(rtlsdr_rpc_msg_t* msg, const char* s) +{ + if (check_size_or_realloc(msg, strlen(s) + 1)) return -1; + push_mem_safe(msg, (const uint8_t*)s, strlen(s) + 1); + return 0; +} + +int rtlsdr_rpc_msg_push_buf(rtlsdr_rpc_msg_t* msg, const uint8_t* buf, size_t size) +{ + size_t total_size = sizeof(uint32_t) + size; + if (check_size_or_realloc(msg, total_size)) return -1; + push_uint32_safe(msg, (uint32_t)size); + push_mem_safe(msg, buf, size); + return 0; +} + +void rtlsdr_rpc_msg_skip_safe(rtlsdr_rpc_msg_t* msg, size_t size) +{ + msg->off += size; +} + +int rtlsdr_rpc_msg_pop_int(rtlsdr_rpc_msg_t* msg, int* x) +{ + return pop_uint32(msg, (uint32_t*)x); +} + +int rtlsdr_rpc_msg_pop_uint32(rtlsdr_rpc_msg_t* msg, uint32_t* x) +{ + return pop_uint32(msg, x); +} + +int rtlsdr_rpc_msg_pop_str(rtlsdr_rpc_msg_t* msg, const char** s) +{ + size_t i; + + *s = (const char*)(msg->fmt + msg->off); + + for (i = msg->off; i != msg->size; ++i) + { + if (msg->fmt[i] == 0) + { + msg->off = i + 1; + return 0; + } + } + + return -1; +} + +int rtlsdr_rpc_msg_pop_buf +(rtlsdr_rpc_msg_t* msg, const uint8_t** buf, size_t* size) +{ + uint32_t x; + + if (pop_uint32(msg, &x)) return -1; + if ((msg->off + x) > msg->size) return -1; + + *buf = (const uint8_t*)(msg->fmt + msg->off); + msg->off += x; + + *size = (size_t)x; + + return 0; +} + +static void put_uint8(void* p, uint8_t x) +{ + memcpy(p, (const void*)&x, sizeof(x)); +} + +static void put_uint16(void* p, uint16_t x) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + memcpy(p, (const void*)&x, sizeof(x)); +} + +static void put_uint32(void* p, uint32_t x) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + memcpy(p, (const void*)&x, sizeof(x)); +} + +static uint8_t get_uint8(const void* p) +{ + uint8_t x; + memcpy((void*)&x, p, sizeof(x)); + return x; +} + +static uint16_t get_uint16(const void* p) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + uint16_t x; + memcpy((void*)&x, p, sizeof(x)); + return x; +} + +static uint32_t get_uint32(const void* p) +{ +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "unsupported endianness" +#endif + + uint32_t x; + memcpy((void*)&x, p, sizeof(x)); + return x; +} + +void rtlsdr_rpc_msg_set_size(rtlsdr_rpc_msg_t* msg, size_t size) +{ + rtlsdr_rpc_fmt_t* const fmt = (rtlsdr_rpc_fmt_t*)msg->fmt; + put_uint32(&fmt->size, (uint32_t)size); +} + +size_t rtlsdr_rpc_msg_get_size(const rtlsdr_rpc_msg_t* msg) +{ + const rtlsdr_rpc_fmt_t* const fmt = (const rtlsdr_rpc_fmt_t*)msg->fmt; + return (size_t)get_uint32(&fmt->size); +} + +void rtlsdr_rpc_msg_set_op(rtlsdr_rpc_msg_t* msg, rtlsdr_rpc_op_t op) +{ + rtlsdr_rpc_fmt_t* const fmt = (rtlsdr_rpc_fmt_t*)msg->fmt; + put_uint8(&fmt->op, (uint8_t)op); +} + +rtlsdr_rpc_op_t rtlsdr_rpc_msg_get_op(const rtlsdr_rpc_msg_t* msg) +{ + const rtlsdr_rpc_fmt_t* const fmt = (const rtlsdr_rpc_fmt_t*)msg->fmt; + return (rtlsdr_rpc_op_t)get_uint8(&fmt->op); +} + +void rtlsdr_rpc_msg_set_mid(rtlsdr_rpc_msg_t* msg, uint16_t mid) +{ + rtlsdr_rpc_fmt_t* const fmt = (rtlsdr_rpc_fmt_t*)msg->fmt; + put_uint16(&fmt->mid, mid); +} + +uint16_t rtlsdr_rpc_msg_get_mid(const rtlsdr_rpc_msg_t* msg) +{ + const rtlsdr_rpc_fmt_t* const fmt = (const rtlsdr_rpc_fmt_t*)msg->fmt; + return get_uint16(&fmt->mid); +} + +void rtlsdr_rpc_msg_set_err(rtlsdr_rpc_msg_t* msg, int err) +{ + rtlsdr_rpc_fmt_t* const fmt = (rtlsdr_rpc_fmt_t*)msg->fmt; + put_uint32(&fmt->err, (uint32_t)err); +} + +int rtlsdr_rpc_msg_get_err(const rtlsdr_rpc_msg_t* msg) +{ + const rtlsdr_rpc_fmt_t* const fmt = (const rtlsdr_rpc_fmt_t*)msg->fmt; + return (int)get_uint32(&fmt->err); +} From 5cffcda9d7e3ee35c82a60383b23282dc07f7fff Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 4 Jan 2015 19:42:10 -0600 Subject: [PATCH 02/74] implement rtlsdr_rpc_get_usb_strings --- src/rtl_rpcd.c | 37 +++++++++++++++++++++++++++++++++++++ src/rtlsdr_rpc.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 45b6e67..555da65 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -531,6 +531,43 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_GET_USB_STRINGS: + { + uint32_t did; + char manuf[256]; + char product[256]; + char serial[256]; + + PRINTF("get_usb_strings()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_usb_strings(rpcd->dev, manuf, product, serial); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_push_str(r, manuf)) + { + err = -1; + goto on_error; + } + + if (rtlsdr_rpc_msg_push_str(r, product)) + { + err = -1; + goto on_error; + } + + if (rtlsdr_rpc_msg_push_str(r, serial)) + { + err = -1; + goto on_error; + } + + break ; + } + case RTLSDR_RPC_OP_SET_CENTER_FREQ: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index cd4a5b4..2edd140 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -497,10 +497,35 @@ int rtlsdr_rpc_get_xtal_freq } int rtlsdr_rpc_get_usb_strings -(void* dev, char* manufact, char* product, char* serial) +(void* devp, char* manufact, char* product, char* serial) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + const char* s; + int err = -1; + + if (init_cli(cli)) goto on_error; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_USB_STRINGS); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(manufact, s); + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(product, s); + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + strcpy(serial, s); + + on_error: + return err; } int rtlsdr_rpc_write_eeprom From 2f0ecfea98ce29aaa17a8ebc376758e1d9121c9f Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 4 Jan 2015 23:05:26 -0600 Subject: [PATCH 03/74] ok if device already opened --- src/rtl_rpcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 555da65..2d77005 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -454,7 +454,12 @@ static int handle_query { PRINTF("open()\n"); - if (rpcd->dev != NULL) goto on_error; + if (rpcd->dev != NULL) + { + /* already opened */ + err = 0; + goto on_error; + } if (rtlsdr_rpc_msg_pop_uint32(q, &rpcd->did)) goto on_error; err = rtlsdr_open(&rpcd->dev, rpcd->did); From 245819dbf71f2630dacee5dc4ac0f34ccdffc6d7 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 4 Jan 2015 23:40:26 -0600 Subject: [PATCH 04/74] fflush stderr. uint8_t fmt. --- src/rtl_rpcd.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 2d77005..f8eda2e 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -19,7 +19,11 @@ #if 1 #include -#define PRINTF(__s, ...) fprintf(stderr, __s, ##__VA_ARGS__) +#define PRINTF(__s, ...) \ +do { \ + fprintf(stderr, __s, ##__VA_ARGS__); \ + fflush(stderr); \ +} while (0) #define TRACE() PRINTF("[t] %s,%u\n", __FILE__, __LINE__) #define ERROR() PRINTF("[e] %s,%u\n", __FILE__, __LINE__) #else @@ -333,25 +337,26 @@ static int send_reply(rpcd_t* rpcd, rtlsdr_rpc_msg_t* r) static void read_async_cb (unsigned char* buf, uint32_t len, void* ctx) { - rpcd_t* const rpcd = ctx; const size_t off = offsetof(rtlsdr_rpc_fmt_t, data); - rtlsdr_rpc_fmt_t fmt; + + rpcd_t* const rpcd = ctx; + uint8_t fmt[offsetof(rtlsdr_rpc_fmt_t, data)]; rtlsdr_rpc_msg_t msg; unsigned int is_recv; if (rpcd->reply_msg.off) { send_reply(rpcd, &rpcd->reply_msg); - rpcd->reply_msg.off = 0; + rpcd->reply_msg.off = off; } msg.off = off; msg.size = off + len; - msg.fmt = (uint8_t*)&fmt; + msg.fmt = fmt; rtlsdr_rpc_msg_set_size(&msg, msg.size); rtlsdr_rpc_msg_set_op(&msg, RTLSDR_RPC_OP_READ_ASYNC); - send_all(rpcd->cli_sock, (const uint8_t*)&fmt, off); + send_all(rpcd->cli_sock, fmt, off); send_all_check_recv(rpcd->cli_sock, buf, len, &is_recv); if (is_recv) rtlsdr_cancel_async(rpcd->dev); From c39f7f071189a4dce9cf76f0ff62d913a0d42ff6 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 11:40:47 -0600 Subject: [PATCH 05/74] rtlsdr_rpc_set_testmode --- src/rtl_rpcd.c | 18 ++++++++++++++++++ src/rtlsdr_rpc.c | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index f8eda2e..dc5a4cc 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -718,6 +718,24 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_SET_TESTMODE: + { + uint32_t did; + uint32_t on; + + PRINTF("set_testmode()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_testmode(rpcd->dev, (int)on); + if (err) goto on_error; + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 2edd140..5274a66 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -736,10 +736,26 @@ uint32_t rtlsdr_rpc_get_sample_rate(void* devp) return rate; } -int rtlsdr_rpc_set_testmode(void* dev, int on) +int rtlsdr_rpc_set_testmode(void* devp, int on) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TESTMODE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; } int rtlsdr_rpc_set_agc_mode(void* dev, int on) From a08dd08f3c19a6d3331644b20e8e392a5f3882b2 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 12:51:51 -0600 Subject: [PATCH 06/74] missing tuner routines --- src/rtl_rpcd.c | 81 ++++++++++++++++++++++++++++++++++++++++ src/rtlsdr_rpc.c | 97 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 166 insertions(+), 12 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index dc5a4cc..2de34d9 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -663,6 +663,87 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_GET_TUNER_GAINS: + { + uint32_t did; + size_t new_size; + uint8_t* buf; + size_t gain_size; + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_tuner_gains(rpcd->dev, NULL); + if (err <= 0) goto on_error; + gain_size = err * sizeof(int); + + new_size = r->off + sizeof(uint32_t) + gain_size; + if (rtlsdr_rpc_msg_realloc(r, new_size)) goto on_error; + buf = r->fmt + r->off + sizeof(uint32_t); + + err = rtlsdr_get_tuner_gains(rpcd->dev, (int*)buf); + if (err <= 0) goto on_error; + + rtlsdr_rpc_msg_push_uint32_safe(r, gain_size); + rtlsdr_rpc_msg_skip_safe(r, gain_size); + + break ; + } + + case RTLSDR_RPC_OP_SET_TUNER_GAIN: + { + uint32_t did; + uint32_t gain; + + PRINTF("set_tuner_gain()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &gain)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_tuner_gain(rpcd->dev, (int)gain); + if (err) goto on_error; + + break ; + } + + case RTLSDR_RPC_OP_GET_TUNER_GAIN: + { + uint32_t did; + + PRINTF("get_tuner_gain()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_tuner_gain(rpcd->dev); + + break ; + } + + case RTLSDR_RPC_OP_SET_TUNER_IF_GAIN: + { + uint32_t did; + uint32_t stage; + uint32_t gain; + + PRINTF("set_tuner_if_gain()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &stage)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &gain)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_tuner_if_gain(rpcd->dev, (int)stage, (int)gain); + if (err) goto on_error; + + break ; + } + case RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 5274a66..1392a7f 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -647,28 +647,101 @@ int rtlsdr_rpc_get_tuner_type(void* devp) return err; } -int rtlsdr_rpc_get_tuner_gains(void* dev, int* gainsp) +int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + const uint8_t* tmp; + size_t size; + int err = 0; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_GAINS); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err <= 0) goto on_error; + + if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) + { + err = 0; + goto on_error; + } + + /* TODO: endianess */ + memcpy(gainsp, tmp, size); + + on_error: + return err; } -int rtlsdr_rpc_set_tuner_gain(void* dev, int gain) +int rtlsdr_rpc_set_tuner_gain(void* devp, int gain) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_GAIN); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + on_error: + return err; } -int rtlsdr_rpc_get_tuner_gain(void* dev) +int rtlsdr_rpc_get_tuner_gain(void* devp) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_GAIN); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; } -int rtlsdr_rpc_set_tuner_if_gain(void* dev, int stage, int gain) +int rtlsdr_rpc_set_tuner_if_gain(void* devp, int stage, int gain) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_IF_GAIN); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)stage)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error; + + on_error: + return err; } int rtlsdr_rpc_set_tuner_gain_mode(void* devp, int manual) From f5f543e7bcca1a1aabd7ca2d048be020c90426d0 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 13:31:16 -0600 Subject: [PATCH 07/74] rtlsdr_rpc_set_agc_mode --- src/rtl_rpcd.c | 18 ++++++++++++++++++ src/rtlsdr_rpc.c | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 2de34d9..40c38f5 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -817,6 +817,24 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_SET_AGC_MODE: + { + uint32_t did; + uint32_t on; + + PRINTF("set_agc_mode()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_agc_mode(rpcd->dev, (int)on); + if (err) goto on_error; + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 1392a7f..cbb7abe 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -831,10 +831,26 @@ int rtlsdr_rpc_set_testmode(void* devp, int on) return err; } -int rtlsdr_rpc_set_agc_mode(void* dev, int on) +int rtlsdr_rpc_set_agc_mode(void* devp, int on) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_AGC_MODE); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; } int rtlsdr_rpc_set_direct_sampling(void* dev, int on) From f14c3b5e351282937550b091b245b11678d29eb4 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 13:32:17 -0600 Subject: [PATCH 08/74] rtlsdr_rpc_set_direct_sampling --- src/rtl_rpcd.c | 18 ++++++++++++++++++ src/rtlsdr_rpc.c | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 40c38f5..7b29001 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -835,6 +835,24 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_SET_DIRECT_SAMPLING: + { + uint32_t did; + uint32_t on; + + PRINTF("set_direct_sampling()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_direct_sampling(rpcd->dev, (int)on); + if (err) goto on_error; + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index cbb7abe..af6c94b 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -853,10 +853,26 @@ int rtlsdr_rpc_set_agc_mode(void* devp, int on) return err; } -int rtlsdr_rpc_set_direct_sampling(void* dev, int on) +int rtlsdr_rpc_set_direct_sampling(void* devp, int on) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_DIRECT_SAMPLING); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; } int rtlsdr_rpc_get_direct_sampling(void* dev) From d40cd428ba2c500b612535728a7ba5092bf964a9 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 13:34:02 -0600 Subject: [PATCH 09/74] rtlsdr_rpc_get_direct_sampling --- src/rtl_rpcd.c | 15 +++++++++++++++ src/rtlsdr_rpc.c | 20 +++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 7b29001..f9a5274 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -853,6 +853,21 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_GET_DIRECT_SAMPLING: + { + uint32_t did; + + PRINTF("get_direct_sampling()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_direct_sampling(rpcd->dev); + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index af6c94b..cdb66f0 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -875,10 +875,24 @@ int rtlsdr_rpc_set_direct_sampling(void* devp, int on) return err; } -int rtlsdr_rpc_get_direct_sampling(void* dev) +int rtlsdr_rpc_get_direct_sampling(void* devp) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DIRECT_SAMPLING); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; } int rtlsdr_rpc_set_offset_tuning(void* dev, int on) From dab5cb6b1341b53712d4dc4e2138361e7db45c3e Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 13:35:14 -0600 Subject: [PATCH 10/74] rtlsdr_rpc_set_offset_tuning --- src/rtl_rpcd.c | 18 ++++++++++++++++++ src/rtlsdr_rpc.c | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index f9a5274..30685b2 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -868,6 +868,24 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_SET_OFFSET_TUNING: + { + uint32_t did; + uint32_t on; + + PRINTF("set_offset_tuning()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_set_offset_tuning(rpcd->dev, (int)on); + if (err) goto on_error; + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index cdb66f0..34eba72 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -895,10 +895,26 @@ int rtlsdr_rpc_get_direct_sampling(void* devp) return err; } -int rtlsdr_rpc_set_offset_tuning(void* dev, int on) +int rtlsdr_rpc_set_offset_tuning(void* devp, int on) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_OFFSET_TUNING); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + + if (send_recv_msg(cli, q, r)) goto on_error_0; + + err = rtlsdr_rpc_msg_get_err(r); + if (err) goto on_error_0; + + on_error_0: + return err; } int rtlsdr_rpc_get_offset_tuning(void* dev) From 431631c05a2a37215a8181d9b1cfcf76fc86947d Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 13:36:11 -0600 Subject: [PATCH 11/74] rtlsdr_rpc_get_offset_tuning --- src/rtl_rpcd.c | 15 +++++++++++++++ src/rtlsdr_rpc.c | 20 +++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 30685b2..bebdf54 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -886,6 +886,21 @@ static int handle_query break ; } + case RTLSDR_RPC_OP_GET_OFFSET_TUNING: + { + uint32_t did; + + PRINTF("get_offset_tuning()\n"); + + if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + + if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; + + err = rtlsdr_get_offset_tuning(rpcd->dev); + + break ; + } + case RTLSDR_RPC_OP_RESET_BUFFER: { uint32_t did; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 34eba72..44a6223 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -917,10 +917,24 @@ int rtlsdr_rpc_set_offset_tuning(void* devp, int on) return err; } -int rtlsdr_rpc_get_offset_tuning(void* dev) +int rtlsdr_rpc_get_offset_tuning(void* devp) { - UNIMPL(); - return -1; + rtlsdr_rpc_dev_t* const dev = devp; + rtlsdr_rpc_cli_t* const cli = dev->cli; + rtlsdr_rpc_msg_t* const q = &cli->query; + rtlsdr_rpc_msg_t* const r = &cli->reply; + int err = -1; + + rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_OFFSET_TUNING); + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + + if (send_recv_msg(cli, q, r)) goto on_error; + + err = rtlsdr_rpc_msg_get_err(r); + + on_error: + return err; } int rtlsdr_rpc_reset_buffer(void* devp) From ad0cc0afc5ef8794c364a4bb2531fc9a086f72c8 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 15:15:14 -0600 Subject: [PATCH 12/74] remove some PRINTF --- src/rtl_rpcd.c | 58 -------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index bebdf54..180a181 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -380,8 +380,6 @@ static int handle_query { uint32_t n; - PRINTF("get_device_count()\n"); - n = rtlsdr_get_device_count(); if (rtlsdr_rpc_msg_push_uint32(r, n)) goto on_error; err = 0; @@ -393,8 +391,6 @@ static int handle_query const char* s; uint32_t i; - PRINTF("get_device_name()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &i)) goto on_error; s = rtlsdr_get_device_name(i); @@ -414,8 +410,6 @@ static int handle_query char serial[256]; uint32_t i; - PRINTF("get_device_usb_strings()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &i)) goto on_error; err = rtlsdr_get_device_usb_strings(i, manuf, product, serial); @@ -446,8 +440,6 @@ static int handle_query { const char* serial; - PRINTF("get_index_by_serial()\n"); - if (rtlsdr_rpc_msg_pop_str(q, &serial)) goto on_error; err = rtlsdr_get_index_by_serial(serial); if (err < 0) goto on_error; @@ -457,8 +449,6 @@ static int handle_query case RTLSDR_RPC_OP_OPEN: { - PRINTF("open()\n"); - if (rpcd->dev != NULL) { /* already opened */ @@ -481,8 +471,6 @@ static int handle_query { uint32_t did; - PRINTF("close()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; err = rtlsdr_close(rpcd->dev); @@ -497,8 +485,6 @@ static int handle_query uint32_t rtl_freq; uint32_t tuner_freq; - PRINTF("set_xtal_freq()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &rtl_freq)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &tuner_freq)) goto on_error; @@ -517,8 +503,6 @@ static int handle_query uint32_t rtl_freq; uint32_t tuner_freq; - PRINTF("get_xtal_freq()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -548,8 +532,6 @@ static int handle_query char product[256]; char serial[256]; - PRINTF("get_usb_strings()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -583,8 +565,6 @@ static int handle_query uint32_t did; uint32_t freq; - PRINTF("set_center_freq()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &freq)) goto on_error; @@ -601,8 +581,6 @@ static int handle_query uint32_t did; uint32_t freq; - PRINTF("get_center_freq()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -620,8 +598,6 @@ static int handle_query uint32_t did; uint32_t ppm; - PRINTF("set_freq_correction()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &ppm)) goto on_error; @@ -637,8 +613,6 @@ static int handle_query { uint32_t did; - PRINTF("get_freq_correction()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -652,8 +626,6 @@ static int handle_query { uint32_t did; - PRINTF("get_tuner_type()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -696,8 +668,6 @@ static int handle_query uint32_t did; uint32_t gain; - PRINTF("set_tuner_gain()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &gain)) goto on_error; @@ -713,8 +683,6 @@ static int handle_query { uint32_t did; - PRINTF("get_tuner_gain()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -730,8 +698,6 @@ static int handle_query uint32_t stage; uint32_t gain; - PRINTF("set_tuner_if_gain()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &stage)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &gain)) goto on_error; @@ -749,8 +715,6 @@ static int handle_query uint32_t did; uint32_t manual; - PRINTF("set_tuner_gain_mode()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &manual)) goto on_error; @@ -767,8 +731,6 @@ static int handle_query uint32_t did; uint32_t rate; - PRINTF("set_sample_rate()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &rate)) goto on_error; @@ -785,8 +747,6 @@ static int handle_query uint32_t did; uint32_t rate; - PRINTF("get_sample_rate()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -804,8 +764,6 @@ static int handle_query uint32_t did; uint32_t on; - PRINTF("set_testmode()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; @@ -822,8 +780,6 @@ static int handle_query uint32_t did; uint32_t on; - PRINTF("set_agc_mode()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; @@ -840,8 +796,6 @@ static int handle_query uint32_t did; uint32_t on; - PRINTF("set_direct_sampling()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; @@ -857,8 +811,6 @@ static int handle_query { uint32_t did; - PRINTF("get_direct_sampling()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -873,8 +825,6 @@ static int handle_query uint32_t did; uint32_t on; - PRINTF("set_offset_tuning()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &on)) goto on_error; @@ -890,8 +840,6 @@ static int handle_query { uint32_t did; - PRINTF("get_offset_tuning()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -905,8 +853,6 @@ static int handle_query { uint32_t did; - PRINTF("reset_buffer()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; @@ -923,8 +869,6 @@ static int handle_query uint32_t buf_num; uint32_t buf_len; - PRINTF("read_async()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &buf_num)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &buf_len)) goto on_error; @@ -949,8 +893,6 @@ static int handle_query { uint32_t did; - PRINTF("cancel_async()\n"); - if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; From 5cfd82c788dd5a06ca0bba04950d9bb3cf4584d7 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 16:26:00 -0600 Subject: [PATCH 13/74] fixme: usleep --- src/rtl_rpcd.c | 1 + src/rtlsdr_rpc.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 180a181..ba3ca48 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -355,6 +355,7 @@ static void read_async_cb msg.fmt = fmt; rtlsdr_rpc_msg_set_size(&msg, msg.size); rtlsdr_rpc_msg_set_op(&msg, RTLSDR_RPC_OP_READ_ASYNC); + rtlsdr_rpc_msg_set_err(&msg, 0); send_all(rpcd->cli_sock, fmt, off); send_all_check_recv(rpcd->cli_sock, buf, len, &is_recv); diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 44a6223..229e96d 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -1010,6 +1010,11 @@ int rtlsdr_rpc_read_async size_t size; int err = -1; + /* fixme: required, otherwise rtl_fm controller thread */ + /* uses socket concurrently. this is not a good solution */ + /* but is working for now. */ + usleep(100000); + rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_READ_ASYNC); if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; From 2cb35d08a483073a8036b02cb2a70c7d7dff9f60 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Jan 2015 16:28:37 -0600 Subject: [PATCH 14/74] default server address to wildcard --- src/rtl_rpcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index ba3ca48..24e5e10 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -1021,7 +1021,7 @@ int main(int ac, char** av) const char* port; addr = getenv("RTLSDR_RPC_SERV_ADDR"); - if (addr == NULL) addr = "127.0.0.1"; + if (addr == NULL) addr = "0.0.0.0"; port = getenv("RTLSDR_RPC_SERV_PORT"); if (port == NULL) port = "40000"; From 055403bed40c21f47f2f6870f04b8861596832a0 Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 12 Jan 2015 20:14:41 -0600 Subject: [PATCH 15/74] add README.rtlsdr_rpc --- README.rtlsdr_rpc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 README.rtlsdr_rpc diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc new file mode 100644 index 0000000..687bdd4 --- /dev/null +++ b/README.rtlsdr_rpc @@ -0,0 +1,25 @@ +This implementation of librtlsdr makes remote dongles +appear to the local software as if they were on the +same computer. It works by forwarding librtlsdr calls +to the remote computer over TCP. + +It allows one to use existing tools without modifying +them. Also, it allows a developer to use the same API +no matter weither the dongle is local or distant. + +To use it, one must compile and install the library +with CMAKE the usual way. Then, a server (called rtl_rpcd) +must be run on the remote location. + +In my case, the dongle is in a beagle bone black is +at address 192.168.0.43: +beagleboneblack #> ./rtl_rpcd + +Then, the existing tool (for instance rtlizer) can be +run on the local computer using: +RTLSDR_RPC_IS_ENABLED=1 RTLSDR_RPC_SERV_ADDR=192.168.0.43 \ +rtlizer + +This implementation still has some limitations, but +works well in most cases. Please report any bug to +texane@gmail.com From 3796c234c61b4007228d57d9205e6ba9faa87ba5 Mon Sep 17 00:00:00 2001 From: texane Date: Fri, 16 Jan 2015 23:58:57 -0600 Subject: [PATCH 16/74] fix get_tuner_gains --- src/rtl_rpcd.c | 31 ++++++++++++++++++++----------- src/rtlsdr_rpc.c | 23 +++++++++++++++++------ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 24e5e10..78e6c07 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -639,27 +639,36 @@ static int handle_query case RTLSDR_RPC_OP_GET_TUNER_GAINS: { uint32_t did; + uint32_t is_null; + uint32_t gain_size; size_t new_size; uint8_t* buf; - size_t gain_size; if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &is_null)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(q, &gain_size)) goto on_error; if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; - err = rtlsdr_get_tuner_gains(rpcd->dev, NULL); - if (err <= 0) goto on_error; - gain_size = err * sizeof(int); + if (is_null) + { + err = rtlsdr_get_tuner_gains(rpcd->dev, NULL); + if (err <= 0) goto on_error; + } + else + { + new_size = r->off + sizeof(uint32_t) + gain_size; + if (rtlsdr_rpc_msg_realloc(r, new_size)) goto on_error; + buf = r->fmt + r->off + sizeof(uint32_t); - new_size = r->off + sizeof(uint32_t) + gain_size; - if (rtlsdr_rpc_msg_realloc(r, new_size)) goto on_error; - buf = r->fmt + r->off + sizeof(uint32_t); + err = rtlsdr_get_tuner_gains(rpcd->dev, (int*)buf); + if (err <= 0) goto on_error; - err = rtlsdr_get_tuner_gains(rpcd->dev, (int*)buf); - if (err <= 0) goto on_error; + rtlsdr_rpc_msg_push_uint32_safe(r, gain_size); + rtlsdr_rpc_msg_skip_safe(r, gain_size); + } - rtlsdr_rpc_msg_push_uint32_safe(r, gain_size); - rtlsdr_rpc_msg_skip_safe(r, gain_size); + err *= sizeof(int); break ; } diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 229e96d..c456967 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -48,6 +48,7 @@ typedef void (*rtlsdr_rpc_read_async_cb_t) typedef struct rtlsdr_rpc_dev { uint32_t index; + size_t gain_size; rtlsdr_rpc_cli_t* cli; } rtlsdr_rpc_dev_t; @@ -407,6 +408,7 @@ int rtlsdr_rpc_open(void** devp, uint32_t index) if (err) goto on_error_1; dev->index = index; + dev->gain_size = 0; dev->cli = cli; *devp = dev; @@ -653,6 +655,8 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) rtlsdr_rpc_cli_t* const cli = dev->cli; rtlsdr_rpc_msg_t* const q = &cli->query; rtlsdr_rpc_msg_t* const r = &cli->reply; + const uint32_t is_null = (gainsp == NULL); + const uint32_t gain_size = (uint32_t)dev->gain_size; const uint8_t* tmp; size_t size; int err = 0; @@ -660,20 +664,27 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_GAINS); if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, is_null)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, gain_size)) goto on_error; if (send_recv_msg(cli, q, r)) goto on_error; err = rtlsdr_rpc_msg_get_err(r); if (err <= 0) goto on_error; - if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) + dev->gain_size = (size_t)err; + + if (is_null != 0) { - err = 0; - goto on_error; - } + if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) + { + err = 0; + goto on_error; + } - /* TODO: endianess */ - memcpy(gainsp, tmp, size); + /* TODO: endianess */ + memcpy(gainsp, tmp, size); + } on_error: return err; From 91e085b16d6126d84dbe9df0c376bf1dc758443e Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 17 Jan 2015 00:50:26 -0600 Subject: [PATCH 17/74] fix get_tuner_gains --- src/rtl_rpcd.c | 2 -- src/rtlsdr_rpc.c | 11 ++++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 78e6c07..ef32f01 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -668,8 +668,6 @@ static int handle_query rtlsdr_rpc_msg_skip_safe(r, gain_size); } - err *= sizeof(int); - break ; } diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index c456967..0f4632d 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -48,7 +48,7 @@ typedef void (*rtlsdr_rpc_read_async_cb_t) typedef struct rtlsdr_rpc_dev { uint32_t index; - size_t gain_size; + size_t gain_count; rtlsdr_rpc_cli_t* cli; } rtlsdr_rpc_dev_t; @@ -408,7 +408,7 @@ int rtlsdr_rpc_open(void** devp, uint32_t index) if (err) goto on_error_1; dev->index = index; - dev->gain_size = 0; + dev->gain_count = 0; dev->cli = cli; *devp = dev; @@ -656,7 +656,7 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) rtlsdr_rpc_msg_t* const q = &cli->query; rtlsdr_rpc_msg_t* const r = &cli->reply; const uint32_t is_null = (gainsp == NULL); - const uint32_t gain_size = (uint32_t)dev->gain_size; + const uint32_t gain_size = (uint32_t)dev->gain_count * sizeof(int); const uint8_t* tmp; size_t size; int err = 0; @@ -670,11 +670,12 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) if (send_recv_msg(cli, q, r)) goto on_error; err = rtlsdr_rpc_msg_get_err(r); + if (err <= 0) goto on_error; - dev->gain_size = (size_t)err; + dev->gain_count = (size_t)err; - if (is_null != 0) + if (is_null == 0) { if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) { From 0d72bb419f01c8081097886493524214ab6aac46 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 17 Jan 2015 11:58:21 -0600 Subject: [PATCH 18/74] fix reply offset --- src/rtl_rpcd.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index ef32f01..29c2c54 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -344,7 +344,7 @@ static void read_async_cb rtlsdr_rpc_msg_t msg; unsigned int is_recv; - if (rpcd->reply_msg.off) + if (rpcd->reply_msg.off != off) { send_reply(rpcd, &rpcd->reply_msg); rpcd->reply_msg.off = off; @@ -363,6 +363,52 @@ static void read_async_cb if (is_recv) rtlsdr_cancel_async(rpcd->dev); } +__attribute__((unused)) +static const char* op_to_string(rtlsdr_rpc_op_t op) +{ + const char* const s[] = + { + "RTLSDR_RPC_OP_GET_DEVICE_COUNT", + "RTLSDR_RPC_OP_GET_DEVICE_NAME", + "RTLSDR_RPC_OP_GET_DEVICE_USB_STRINGS", + "RTLSDR_RPC_OP_GET_INDEX_BY_SERIAL", + "RTLSDR_RPC_OP_OPEN", + "RTLSDR_RPC_OP_CLOSE", + "RTLSDR_RPC_OP_SET_XTAL_FREQ", + "RTLSDR_RPC_OP_GET_XTAL_FREQ", + "RTLSDR_RPC_OP_GET_USB_STRINGS", + "RTLSDR_RPC_OP_WRITE_EEPROM", + "RTLSDR_RPC_OP_READ_EEPROM", + "RTLSDR_RPC_OP_SET_CENTER_FREQ", + "RTLSDR_RPC_OP_GET_CENTER_FREQ", + "RTLSDR_RPC_OP_SET_FREQ_CORRECTION", + "RTLSDR_RPC_OP_GET_FREQ_CORRECTION", + "RTLSDR_RPC_OP_GET_TUNER_TYPE", + "RTLSDR_RPC_OP_GET_TUNER_GAINS", + "RTLSDR_RPC_OP_SET_TUNER_GAIN", + "RTLSDR_RPC_OP_GET_TUNER_GAIN", + "RTLSDR_RPC_OP_SET_TUNER_IF_GAIN", + "RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE", + "RTLSDR_RPC_OP_SET_SAMPLE_RATE", + "RTLSDR_RPC_OP_GET_SAMPLE_RATE", + "RTLSDR_RPC_OP_SET_TESTMODE", + "RTLSDR_RPC_OP_SET_AGC_MODE", + "RTLSDR_RPC_OP_SET_DIRECT_SAMPLING", + "RTLSDR_RPC_OP_GET_DIRECT_SAMPLING", + "RTLSDR_RPC_OP_SET_OFFSET_TUNING", + "RTLSDR_RPC_OP_GET_OFFSET_TUNING", + "RTLSDR_RPC_OP_RESET_BUFFER", + "RTLSDR_RPC_OP_READ_SYNC", + "RTLSDR_RPC_OP_WAIT_ASYNC", + "RTLSDR_RPC_OP_READ_ASYNC", + "RTLSDR_RPC_OP_CANCEL_ASYNC", + "RTLSDR_RPC_OP_EVENT_STATE", + "RTLSDR_RPC_OP_INVALID" + }; + if (op >= RTLSDR_RPC_OP_INVALID) op = RTLSDR_RPC_OP_INVALID; + return s[op]; +} + static int handle_query (rpcd_t* rpcd, rtlsdr_rpc_msg_t* q, rtlsdr_rpc_msg_t** rr) { From 4008c0b89a80f7deb10de962edf8725c4b361909 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 17 Jan 2015 12:10:15 -0600 Subject: [PATCH 19/74] default gain_count --- src/rtlsdr_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 0f4632d..e5db376 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -408,7 +408,7 @@ int rtlsdr_rpc_open(void** devp, uint32_t index) if (err) goto on_error_1; dev->index = index; - dev->gain_count = 0; + dev->gain_count = 32; dev->cli = cli; *devp = dev; From b321103b1b0b6b7c3a7e1fe7c0a411617de4d2fd Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 17 Jan 2015 15:43:39 -0600 Subject: [PATCH 20/74] send_flush_msgs --- src/rtlsdr_rpc.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index e5db376..6761ec0 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -285,6 +285,31 @@ static int send_recv_msg return 0; } +static int send_flush_msgs +(rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t* q) +{ + struct timeval tm; + ssize_t n; + fd_set rset; + uint8_t buf[256]; + + rtlsdr_rpc_msg_set_size(q, (uint32_t)q->off); + rtlsdr_rpc_msg_set_mid(q, get_mid(cli)); + if (send_msg(cli->sock, q)) return -1; + + while (1) + { + FD_ZERO(&rset); + FD_SET(cli->sock, &rset); + tm.tv_sec = 0; + tm.tv_usec = 200000; + if (select(cli->sock + 1, &rset, NULL, NULL, &tm) < 0) break ; + if (recv(cli->sock, buf, sizeof(buf), 0) <= 0) break ; + } + + return 0; +} + uint32_t rtlsdr_rpc_get_device_count(void) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; @@ -1007,6 +1032,7 @@ int rtlsdr_rpc_read_sync return err; } + static volatile unsigned int is_cancel; int rtlsdr_rpc_read_async ( @@ -1049,6 +1075,9 @@ int rtlsdr_rpc_read_async goto on_error_0; } + if (rtlsdr_rpc_msg_get_op(r) != RTLSDR_RPC_OP_READ_ASYNC) + continue ; + size = rtlsdr_rpc_msg_get_size(r); cb(r->fmt + off, size - off, ctx); } @@ -1056,7 +1085,7 @@ int rtlsdr_rpc_read_async rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_CANCEL_ASYNC); rtlsdr_rpc_msg_push_uint32(q, dev->index); - send_recv_msg(cli, q, r); + send_flush_msgs(cli, q); on_error_0: return err; From 4fb1eadff143cf14c709c1162801f188c6b2bcc1 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 17 Jan 2015 23:31:45 -0600 Subject: [PATCH 21/74] note abount using latest libusb --- README.rtlsdr_rpc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc index 687bdd4..23f6ff6 100644 --- a/README.rtlsdr_rpc +++ b/README.rtlsdr_rpc @@ -23,3 +23,8 @@ rtlizer This implementation still has some limitations, but works well in most cases. Please report any bug to texane@gmail.com + +Also, note that the latest version of libusb should be +used as librtlsdr crashed when used with older version +(esp. the rtlsdr_read_async routine): +https://github.com/libusb/libusb.git From 078a487843dbff8c192ccbe4bdc7553c9fd79f3b Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 18 Jan 2015 18:00:33 +0100 Subject: [PATCH 22/74] handle conccurrent requests --- include/rtlsdr_rpc_msg.h | 6 +- src/rtl_rpcd.c | 41 ++- src/rtlsdr_rpc.c | 757 +++++++++++++++++++++++++-------------- src/rtlsdr_rpc_msg.c | 8 +- 4 files changed, 532 insertions(+), 280 deletions(-) diff --git a/include/rtlsdr_rpc_msg.h b/include/rtlsdr_rpc_msg.h index d028c21..2ad9bd6 100644 --- a/include/rtlsdr_rpc_msg.h +++ b/include/rtlsdr_rpc_msg.h @@ -53,7 +53,7 @@ typedef struct /* raw network format */ uint32_t size; uint8_t op; - uint16_t mid; + uint8_t id; uint32_t err; uint8_t data[1]; } __attribute__((packed)) rtlsdr_rpc_fmt_t; @@ -74,8 +74,8 @@ void rtlsdr_rpc_msg_set_size(rtlsdr_rpc_msg_t*, size_t); size_t rtlsdr_rpc_msg_get_size(const rtlsdr_rpc_msg_t*); void rtlsdr_rpc_msg_set_op(rtlsdr_rpc_msg_t*, rtlsdr_rpc_op_t); rtlsdr_rpc_op_t rtlsdr_rpc_msg_get_op(const rtlsdr_rpc_msg_t*); -void rtlsdr_rpc_msg_set_mid(rtlsdr_rpc_msg_t*, uint16_t); -uint16_t rtlsdr_rpc_msg_get_mid(const rtlsdr_rpc_msg_t*); +void rtlsdr_rpc_msg_set_id(rtlsdr_rpc_msg_t*, uint8_t); +uint8_t rtlsdr_rpc_msg_get_id(const rtlsdr_rpc_msg_t*); void rtlsdr_rpc_msg_set_err(rtlsdr_rpc_msg_t*, int); int rtlsdr_rpc_msg_get_err(const rtlsdr_rpc_msg_t*); diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 29c2c54..1096e5f 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -45,6 +45,9 @@ typedef struct rtlsdr_rpc_msg_t reply_msg; rtlsdr_rpc_msg_t event_msg; + unsigned int async_replied; + uint8_t async_id; + } rpcd_t; static int resolve_ip_addr @@ -344,10 +347,10 @@ static void read_async_cb rtlsdr_rpc_msg_t msg; unsigned int is_recv; - if (rpcd->reply_msg.off != off) + if (rpcd->async_replied == 0) { send_reply(rpcd, &rpcd->reply_msg); - rpcd->reply_msg.off = off; + rpcd->async_replied = 1; } msg.off = off; @@ -355,6 +358,7 @@ static void read_async_cb msg.fmt = fmt; rtlsdr_rpc_msg_set_size(&msg, msg.size); rtlsdr_rpc_msg_set_op(&msg, RTLSDR_RPC_OP_READ_ASYNC); + rtlsdr_rpc_msg_set_id(&msg, rpcd->async_id); rtlsdr_rpc_msg_set_err(&msg, 0); send_all(rpcd->cli_sock, fmt, off); @@ -922,6 +926,10 @@ static int handle_query uint32_t did; uint32_t buf_num; uint32_t buf_len; + rtlsdr_rpc_op_t new_op; + rtlsdr_rpc_msg_t* new_q; + rtlsdr_rpc_msg_t* new_r; + uint8_t id; if (rtlsdr_rpc_msg_pop_uint32(q, &did)) goto on_error; if (rtlsdr_rpc_msg_pop_uint32(q, &buf_num)) goto on_error; @@ -930,16 +938,35 @@ static int handle_query if ((rpcd->dev == NULL) || (rpcd->did != did)) goto on_error; /* prepare the reply here */ + id = rtlsdr_rpc_msg_get_id(q); rtlsdr_rpc_msg_set_size(r, r->off); rtlsdr_rpc_msg_set_op(r, op); - rtlsdr_rpc_msg_set_mid(r, rtlsdr_rpc_msg_get_mid(q)); + rtlsdr_rpc_msg_set_id(r, id); rtlsdr_rpc_msg_set_err(r, 0); + + rpcd->async_id = id; + rpcd->async_replied = 0; + while (1) + { + rtlsdr_read_async + (rpcd->dev, read_async_cb, rpcd, buf_num, buf_len); + + if (rpcd->async_replied == 0) goto on_error; + + if (recv_query(rpcd, &new_q)) goto on_error; - rtlsdr_read_async - (rpcd->dev, read_async_cb, rpcd, buf_num, buf_len); + new_op = rtlsdr_rpc_msg_get_op(new_q); + + /* do not reply is cancel_async */ + if (new_op == RTLSDR_RPC_OP_CANCEL_ASYNC) return 0; + handle_query(rpcd, new_q, &new_r); + + if (new_r != NULL) send_reply(rpcd, new_r); + } /* do not resend reply */ - return 0; + if (rpcd->async_replied) return 0; + goto on_error; break ; } @@ -993,7 +1020,7 @@ static int handle_query on_error: rtlsdr_rpc_msg_set_size(r, r->off); rtlsdr_rpc_msg_set_op(r, op); - rtlsdr_rpc_msg_set_mid(r, rtlsdr_rpc_msg_get_mid(q)); + rtlsdr_rpc_msg_set_id(r, rtlsdr_rpc_msg_get_id(q)); rtlsdr_rpc_msg_set_err(r, err); *rr = r; return 0; diff --git a/src/rtlsdr_rpc.c b/src/rtlsdr_rpc.c index 6761ec0..b51fb48 100644 --- a/src/rtlsdr_rpc.c +++ b/src/rtlsdr_rpc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -32,12 +33,22 @@ typedef struct { - unsigned int is_init; - uint16_t mid; + volatile unsigned int is_locked; + volatile unsigned int is_init; int sock; - rtlsdr_rpc_msg_t query; - rtlsdr_rpc_msg_t reply; + +#define QR_COUNT 32 + pthread_mutex_t qr_lock; + volatile uint32_t qr_mask; + volatile uint32_t qr_box; + rtlsdr_rpc_msg_t query[QR_COUNT]; + rtlsdr_rpc_msg_t reply[QR_COUNT]; + + pthread_mutex_t send_lock; + pthread_mutex_t recv_lock; + volatile unsigned int is_async_cancel; + } rtlsdr_rpc_cli_t; static rtlsdr_rpc_cli_t rtlsdr_rpc_cli = { 0, }; @@ -123,8 +134,15 @@ static int init_cli(rtlsdr_rpc_cli_t* cli) size_t size; const char* addr; const char* port; + size_t i; + size_t j; + int err = -1; + + /* no better way in this case ... */ + while (cli->is_locked) usleep(10000); + cli->is_locked = 1; - if (cli->is_init) return 0; + if (cli->is_init) goto on_success; addr = getenv("RTLSDR_RPC_SERV_ADDR"); if (addr == NULL) addr = "127.0.0.1"; @@ -158,35 +176,106 @@ static int init_cli(rtlsdr_rpc_cli_t* cli) goto on_error_1; } - cli->mid = 0; - if (rtlsdr_rpc_msg_init(&cli->query, 0)) goto on_error_1; - if (rtlsdr_rpc_msg_init(&cli->reply, 0)) goto on_error_2; + for (i = 0; i != QR_COUNT; ++i) + { + rtlsdr_rpc_msg_t* const q = &cli->query[i]; + rtlsdr_rpc_msg_t* const r = &cli->reply[i]; + + if (rtlsdr_rpc_msg_init(q, 0)) + goto on_error_2; + + if (rtlsdr_rpc_msg_init(r, 0)) + { + rtlsdr_rpc_msg_fini(q); + goto on_error_2; + } + } + pthread_mutex_init(&cli->qr_lock, NULL); + cli->qr_mask = 0; + cli->qr_box = 0; + + pthread_mutex_init(&cli->send_lock, NULL); + pthread_mutex_init(&cli->recv_lock, NULL); + cli->is_init = 1; - return 0; + on_success: + err = 0; + goto on_error_0; on_error_2: - rtlsdr_rpc_msg_fini(&cli->query); + for (j = 0; j != i; ++j) + { + rtlsdr_rpc_msg_fini(&cli->query[j]); + rtlsdr_rpc_msg_fini(&cli->reply[j]); + } + on_error_1: shutdown(cli->sock, SHUT_RDWR); close(cli->sock); + on_error_0: - return -1; + cli->is_locked = 0; + return err; } __attribute__((unused)) static int fini_cli(rtlsdr_rpc_cli_t* cli) { - rtlsdr_rpc_msg_fini(&cli->query); - rtlsdr_rpc_msg_fini(&cli->reply); + size_t i; + + for (i = 0; i != QR_COUNT; ++i) + { + rtlsdr_rpc_msg_fini(&cli->query[i]); + rtlsdr_rpc_msg_fini(&cli->reply[i]); + } + pthread_mutex_destroy(&cli->qr_lock); + + pthread_mutex_destroy(&cli->send_lock); + pthread_mutex_destroy(&cli->recv_lock); + shutdown(cli->sock, SHUT_RDWR); close(cli->sock); + return 0; } -static uint16_t get_mid(rtlsdr_rpc_cli_t* cli) +static int alloc_qr +(rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t** q, rtlsdr_rpc_msg_t** r) { - return cli->mid++; + size_t i; + + pthread_mutex_lock(&cli->qr_lock); + for (i = 0; i != QR_COUNT; ++i) + { + const uint32_t m = 1 << i; + if ((cli->qr_mask & m) == 0) + { + cli->qr_mask |= m; + break ; + } + } + pthread_mutex_unlock(&cli->qr_lock); + + if (i == QR_COUNT) return -1; + + *q = &cli->query[i]; + *r = &cli->reply[i]; + + /* set the query id */ + rtlsdr_rpc_msg_reset(*q); + rtlsdr_rpc_msg_set_id(*q, (uint8_t)i); + + return 0; +} + +static void free_qr +(rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t* q, rtlsdr_rpc_msg_t* r) +{ + const uint32_t m = 1 << (uint32_t)rtlsdr_rpc_msg_get_id(q); + pthread_mutex_lock(&cli->qr_lock); + cli->qr_mask &= ~m; + pthread_mutex_unlock(&cli->qr_lock); } static int recv_all(int fd, uint8_t* buf, size_t size) @@ -253,33 +342,81 @@ static int send_all(int fd, const uint8_t* buf, size_t size) return 0; } -static int recv_msg(int fd, rtlsdr_rpc_msg_t* m) +static int recv_msg +(rtlsdr_rpc_cli_t* cli, uint8_t id, rtlsdr_rpc_msg_t* m) { + static const size_t fmt_size = offsetof(rtlsdr_rpc_fmt_t, data); + const uint32_t mask = 1 << (uint32_t)id; + const int fd = cli->sock; uint32_t size; + uint8_t to_id; + int err = -1; + rtlsdr_rpc_msg_t* to_m; - if (recv_all(fd, (uint8_t*)&size, sizeof(uint32_t))) return -1; - rtlsdr_rpc_msg_set_size(m, size); - size = rtlsdr_rpc_msg_get_size(m); - if (rtlsdr_rpc_msg_realloc(m, size)) return -1; - size -= sizeof(uint32_t); - if (recv_all(fd, m->fmt + sizeof(uint32_t), size)) return -1; - return 0; + pthread_mutex_lock(&cli->recv_lock); + + if (cli->qr_box & mask) + { + cli->qr_box &= ~mask; + goto on_success; + } + + while (1) + { + /* receive next message */ + if (recv_all(fd, m->fmt, fmt_size)) goto on_error; + + /* get destination message by id */ + to_id = rtlsdr_rpc_msg_get_id(m); + + if (to_id >= QR_COUNT) goto on_error; + to_m = &cli->reply[to_id]; + if (to_id != id) memcpy(to_m->fmt, m->fmt, fmt_size); + + size = rtlsdr_rpc_msg_get_size(to_m); + if (size < fmt_size) goto on_error; + + if (rtlsdr_rpc_msg_realloc(to_m, size)) goto on_error; + + size -= fmt_size; + if (size) + { + if (recv_all(fd, to_m->fmt + fmt_size, size)) goto on_error; + } + + if (to_id == id) goto on_success; + + /* message not for this query, forward */ + cli->qr_box |= 1 << (uint32_t)to_id; + } + + on_success: + err = 0; + on_error: + pthread_mutex_unlock(&cli->recv_lock); + return err; } -static int send_msg(int fd, rtlsdr_rpc_msg_t* m) +static int send_msg(rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t* m) { - return send_all(fd, m->fmt, m->off); + int err; + + rtlsdr_rpc_msg_set_size(m, (uint32_t)m->off); + + pthread_mutex_lock(&cli->send_lock); + err = send_all(cli->sock, m->fmt, m->off); + pthread_mutex_unlock(&cli->send_lock); + + return err; } static int send_recv_msg (rtlsdr_rpc_cli_t* cli, rtlsdr_rpc_msg_t* q, rtlsdr_rpc_msg_t* r) { - rtlsdr_rpc_msg_set_size(q, (uint32_t)q->off); - rtlsdr_rpc_msg_set_mid(q, get_mid(cli)); - - if (send_msg(cli->sock, q)) return -1; + const uint8_t id = rtlsdr_rpc_msg_get_id(q); - if (recv_msg(cli->sock, r)) return -1; + if (send_msg(cli, q)) return -1; + if (recv_msg(cli, id, r)) return -1; rtlsdr_rpc_msg_reset(r); return 0; @@ -293,9 +430,9 @@ static int send_flush_msgs fd_set rset; uint8_t buf[256]; - rtlsdr_rpc_msg_set_size(q, (uint32_t)q->off); - rtlsdr_rpc_msg_set_mid(q, get_mid(cli)); - if (send_msg(cli->sock, q)) return -1; + if (send_msg(cli, q)) return -1; + + pthread_mutex_lock(&cli->recv_lock); while (1) { @@ -307,26 +444,31 @@ static int send_flush_msgs if (recv(cli->sock, buf, sizeof(buf), 0) <= 0) break ; } + pthread_mutex_unlock(&cli->recv_lock); + return 0; } uint32_t rtlsdr_rpc_get_device_count(void) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; uint32_t n = 0; - if (init_cli(cli)) goto on_error; + if (init_cli(cli)) goto on_error_0; + + if (alloc_qr(cli, &q, &r)) goto on_error_0; - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_COUNT); - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; - if (rtlsdr_rpc_msg_pop_uint32(r, &n)) goto on_error; + if (rtlsdr_rpc_msg_pop_uint32(r, &n)) goto on_error_1; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return n; } @@ -336,23 +478,26 @@ const char* rtlsdr_rpc_get_device_name ) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; const char* s = NULL; - if (init_cli(cli)) goto on_error; + if (init_cli(cli)) goto on_error_0; + + if (alloc_qr(cli, &q, &r)) goto on_error_0; - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_NAME); - if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; /* TODO: memory leak here */ s = strdup(s); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return s; } @@ -360,59 +505,65 @@ int rtlsdr_rpc_get_device_usb_strings (uint32_t index, char* manufact, char* product, char* serial) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; const char* s; int err = -1; - if (init_cli(cli)) goto on_error; + if (init_cli(cli)) goto on_error_0; + + if (alloc_qr(cli, &q, &r)) goto on_error_0; - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DEVICE_USB_STRINGS); - if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(manufact, s); - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(product, s); - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(serial, s); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } int rtlsdr_rpc_get_index_by_serial(const char* serial) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - if (init_cli(cli)) goto on_error; + if (init_cli(cli)) goto on_error_0; + + if (alloc_qr(cli, &q, &r)) goto on_error_0; - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_INDEX_BY_SERIAL); - if (rtlsdr_rpc_msg_push_str(q, serial)) goto on_error; + if (rtlsdr_rpc_msg_push_str(q, serial)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } int rtlsdr_rpc_open(void** devp, uint32_t index) { rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; rtlsdr_rpc_dev_t* dev; int err = -1; @@ -423,20 +574,23 @@ int rtlsdr_rpc_open(void** devp, uint32_t index) dev = malloc(sizeof(rtlsdr_rpc_dev_t)); if (dev == NULL) goto on_error_0; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_1; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_OPEN); - if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, index)) goto on_error_2; - if (send_recv_msg(cli, q, r)) goto on_error_1; + if (send_recv_msg(cli, q, r)) goto on_error_2; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_1; + if (err) goto on_error_2; dev->index = index; dev->gain_count = 32; dev->cli = cli; *devp = dev; + on_error_2: + free_qr(cli, q, r); on_error_1: if (err) free(dev); on_error_0: @@ -447,19 +601,22 @@ int rtlsdr_rpc_close(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_CLOSE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: free(dev); return err; @@ -470,21 +627,24 @@ int rtlsdr_rpc_set_xtal_freq { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_XTAL_FREQ); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, rtl_freq)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, tuner_freq)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, rtl_freq)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, tuner_freq)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -494,31 +654,34 @@ int rtlsdr_rpc_get_xtal_freq { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_XTAL_FREQ); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; if (rtlsdr_rpc_msg_pop_uint32(r, rtl_freq)) { err = -1; - goto on_error_0; + goto on_error_1; } if (rtlsdr_rpc_msg_pop_uint32(r, tuner_freq)) { err = -1; - goto on_error_0; + goto on_error_1; } + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -528,30 +691,33 @@ int rtlsdr_rpc_get_usb_strings { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = &rtlsdr_rpc_cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; const char* s; int err = -1; - if (init_cli(cli)) goto on_error; + if (init_cli(cli)) goto on_error_0; + + if (alloc_qr(cli, &q, &r)) goto on_error_0; - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_USB_STRINGS); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(manufact, s); - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(product, s); - if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error; + if (rtlsdr_rpc_msg_pop_str(r, &s)) goto on_error_1; strcpy(serial, s); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -573,20 +739,23 @@ int rtlsdr_rpc_set_center_freq(void* devp, uint32_t freq) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_CENTER_FREQ); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, freq)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, freq)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -595,19 +764,22 @@ uint32_t rtlsdr_rpc_get_center_freq(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; uint32_t freq = 0; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_CENTER_FREQ); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; - if (rtlsdr_rpc_msg_get_err(r)) goto on_error_0; - if (rtlsdr_rpc_msg_pop_uint32(r, &freq)) goto on_error_0; + if (rtlsdr_rpc_msg_get_err(r)) goto on_error_1; + if (rtlsdr_rpc_msg_pop_uint32(r, &freq)) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return freq; } @@ -616,21 +788,24 @@ int rtlsdr_rpc_set_freq_correction(void* devp, int ppm) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_FREQ_CORRECTION); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)ppm)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)ppm)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -638,19 +813,22 @@ int rtlsdr_rpc_get_freq_correction(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_FREQ_CORRECTION); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -658,19 +836,22 @@ int rtlsdr_rpc_get_tuner_type(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_TYPE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -678,25 +859,26 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; const uint32_t is_null = (gainsp == NULL); const uint32_t gain_size = (uint32_t)dev->gain_count * sizeof(int); const uint8_t* tmp; size_t size; int err = 0; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_GAINS); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, is_null)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, gain_size)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, is_null)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, gain_size)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err <= 0) goto on_error; + if (err <= 0) goto on_error_1; dev->gain_count = (size_t)err; @@ -705,14 +887,16 @@ int rtlsdr_rpc_get_tuner_gains(void* devp, int* gainsp) if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) { err = 0; - goto on_error; + goto on_error_1; } /* TODO: endianess */ memcpy(gainsp, tmp, size); } - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -720,21 +904,24 @@ int rtlsdr_rpc_set_tuner_gain(void* devp, int gain) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_GAIN); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -742,19 +929,22 @@ int rtlsdr_rpc_get_tuner_gain(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_TUNER_GAIN); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -762,22 +952,25 @@ int rtlsdr_rpc_set_tuner_if_gain(void* devp, int stage, int gain) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_IF_GAIN); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)stage)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)stage)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)gain)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -785,21 +978,24 @@ int rtlsdr_rpc_set_tuner_gain_mode(void* devp, int manual) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TUNER_GAIN_MODE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, manual)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, manual)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -807,20 +1003,23 @@ int rtlsdr_rpc_set_sample_rate(void* devp, uint32_t rate) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_SAMPLE_RATE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, rate)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, rate)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -829,19 +1028,22 @@ uint32_t rtlsdr_rpc_get_sample_rate(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; uint32_t rate = 0; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_SAMPLE_RATE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; - if (rtlsdr_rpc_msg_get_err(r)) goto on_error_0; - if (rtlsdr_rpc_msg_pop_uint32(r, &rate)) goto on_error_0; + if (rtlsdr_rpc_msg_get_err(r)) goto on_error_1; + if (rtlsdr_rpc_msg_pop_uint32(r, &rate)) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return rate; } @@ -850,20 +1052,23 @@ int rtlsdr_rpc_set_testmode(void* devp, int on) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_TESTMODE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -872,20 +1077,23 @@ int rtlsdr_rpc_set_agc_mode(void* devp, int on) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_AGC_MODE); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -894,20 +1102,23 @@ int rtlsdr_rpc_set_direct_sampling(void* devp, int on) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_DIRECT_SAMPLING); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -916,19 +1127,22 @@ int rtlsdr_rpc_get_direct_sampling(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_DIRECT_SAMPLING); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -936,20 +1150,23 @@ int rtlsdr_rpc_set_offset_tuning(void* devp, int on) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_SET_OFFSET_TUNING); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)on)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -958,19 +1175,22 @@ int rtlsdr_rpc_get_offset_tuning(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_GET_OFFSET_TUNING); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -978,19 +1198,22 @@ int rtlsdr_rpc_reset_buffer(void* devp) { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_RESET_BUFFER); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } @@ -1000,26 +1223,27 @@ int rtlsdr_rpc_read_sync { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; const uint8_t* tmp; size_t size; int err = -1; - rtlsdr_rpc_msg_reset(q); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_READ_SYNC); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error; - if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)len)) goto on_error; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, (uint32_t)len)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error; + if (err) goto on_error_1; if (rtlsdr_rpc_msg_pop_buf(r, &tmp, &size)) { err = -1; - goto on_error; + goto on_error_1; } if (size > (size_t)len) size = len; @@ -1028,7 +1252,9 @@ int rtlsdr_rpc_read_sync *n_read = (int)size; - on_error: + on_error_1: + free_qr(cli, q, r); + on_error_0: return err; } @@ -1043,50 +1269,49 @@ int rtlsdr_rpc_read_async { rtlsdr_rpc_dev_t* const dev = devp; rtlsdr_rpc_cli_t* const cli = dev->cli; - rtlsdr_rpc_msg_t* const q = &cli->query; - rtlsdr_rpc_msg_t* const r = &cli->reply; + rtlsdr_rpc_msg_t* q; + rtlsdr_rpc_msg_t* r; + uint8_t id; size_t size; int err = -1; - /* fixme: required, otherwise rtl_fm controller thread */ - /* uses socket concurrently. this is not a good solution */ - /* but is working for now. */ - usleep(100000); + if (alloc_qr(cli, &q, &r)) goto on_error_0; + + id = rtlsdr_rpc_msg_get_id(q); - rtlsdr_rpc_msg_reset(q); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_READ_ASYNC); - if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, buf_num)) goto on_error_0; - if (rtlsdr_rpc_msg_push_uint32(q, buf_len)) goto on_error_0; + if (rtlsdr_rpc_msg_push_uint32(q, dev->index)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, buf_num)) goto on_error_1; + if (rtlsdr_rpc_msg_push_uint32(q, buf_len)) goto on_error_1; - if (send_recv_msg(cli, q, r)) goto on_error_0; + if (send_recv_msg(cli, q, r)) goto on_error_1; err = rtlsdr_rpc_msg_get_err(r); - if (err) goto on_error_0; + if (err) goto on_error_1; cli->is_async_cancel = 0; while (cli->is_async_cancel == 0) { static const size_t off = offsetof(rtlsdr_rpc_fmt_t, data); - if (recv_msg(cli->sock, r)) + if (recv_msg(cli, id, r)) { err = -1; - goto on_error_0; + goto on_error_1; } - if (rtlsdr_rpc_msg_get_op(r) != RTLSDR_RPC_OP_READ_ASYNC) - continue ; - size = rtlsdr_rpc_msg_get_size(r); cb(r->fmt + off, size - off, ctx); } rtlsdr_rpc_msg_reset(q); + rtlsdr_rpc_msg_set_id(q, id); rtlsdr_rpc_msg_set_op(q, RTLSDR_RPC_OP_CANCEL_ASYNC); rtlsdr_rpc_msg_push_uint32(q, dev->index); send_flush_msgs(cli, q); + on_error_1: + free_qr(cli, q, r); on_error_0: return err; } diff --git a/src/rtlsdr_rpc_msg.c b/src/rtlsdr_rpc_msg.c index 970cb7b..ea9e787 100644 --- a/src/rtlsdr_rpc_msg.c +++ b/src/rtlsdr_rpc_msg.c @@ -273,16 +273,16 @@ rtlsdr_rpc_op_t rtlsdr_rpc_msg_get_op(const rtlsdr_rpc_msg_t* msg) return (rtlsdr_rpc_op_t)get_uint8(&fmt->op); } -void rtlsdr_rpc_msg_set_mid(rtlsdr_rpc_msg_t* msg, uint16_t mid) +void rtlsdr_rpc_msg_set_id(rtlsdr_rpc_msg_t* msg, uint8_t id) { rtlsdr_rpc_fmt_t* const fmt = (rtlsdr_rpc_fmt_t*)msg->fmt; - put_uint16(&fmt->mid, mid); + put_uint16(&fmt->id, id); } -uint16_t rtlsdr_rpc_msg_get_mid(const rtlsdr_rpc_msg_t* msg) +uint8_t rtlsdr_rpc_msg_get_id(const rtlsdr_rpc_msg_t* msg) { const rtlsdr_rpc_fmt_t* const fmt = (const rtlsdr_rpc_fmt_t*)msg->fmt; - return get_uint16(&fmt->mid); + return get_uint8(&fmt->id); } void rtlsdr_rpc_msg_set_err(rtlsdr_rpc_msg_t* msg, int err) From 8f0434474e2d5802d7124aab2254c1dc485a6791 Mon Sep 17 00:00:00 2001 From: lementec Date: Mon, 19 Jan 2015 11:02:16 +0100 Subject: [PATCH 23/74] add list of known working software --- README.rtlsdr_rpc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc index 23f6ff6..15d162f 100644 --- a/README.rtlsdr_rpc +++ b/README.rtlsdr_rpc @@ -28,3 +28,10 @@ Also, note that the latest version of libusb should be used as librtlsdr crashed when used with older version (esp. the rtlsdr_read_async routine): https://github.com/libusb/libusb.git + +list of known working software: +rtl_fm +rtl_power +rtlsdr-waterfall +rtlizer +gnuradio-companion From b80d5c945341dc7a8de8fdb3e7098bdef385fbfc Mon Sep 17 00:00:00 2001 From: texane Date: Tue, 20 Jan 2015 07:29:38 +0100 Subject: [PATCH 24/74] update list of known working software, cubicsdr --- README.rtlsdr_rpc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc index 15d162f..c091078 100644 --- a/README.rtlsdr_rpc +++ b/README.rtlsdr_rpc @@ -35,3 +35,4 @@ rtl_power rtlsdr-waterfall rtlizer gnuradio-companion +cubicsdr \ No newline at end of file From 3be49cb927b557c0188f2e321a11a7c54cd76963 Mon Sep 17 00:00:00 2001 From: lementec Date: Wed, 21 Jan 2015 16:51:07 +0100 Subject: [PATCH 25/74] update list of known working software, gqrx --- README.rtlsdr_rpc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc index c091078..8e11068 100644 --- a/README.rtlsdr_rpc +++ b/README.rtlsdr_rpc @@ -35,4 +35,5 @@ rtl_power rtlsdr-waterfall rtlizer gnuradio-companion -cubicsdr \ No newline at end of file +cubicsdr +gqrx \ No newline at end of file From 5c376fc79c919c0e16a832328c92f5213f0cdd54 Mon Sep 17 00:00:00 2001 From: Hoernchen Date: Tue, 9 Jun 2015 01:37:46 +0200 Subject: [PATCH 26/74] tools: allow built-in functions for newer versions of MSVC --- src/rtl_adsb.c | 2 ++ src/rtl_fm.c | 4 ++-- src/rtl_power.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/rtl_adsb.c b/src/rtl_adsb.c index 7b10306..e611e78 100644 --- a/src/rtl_adsb.c +++ b/src/rtl_adsb.c @@ -45,8 +45,10 @@ #ifdef _WIN32 #define sleep Sleep +#if defined(_MSC_VER) && (_MSC_VER < 1800) #define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) #endif +#endif #define ADSB_RATE 2000000 #define ADSB_FREQ 1090000000 diff --git a/src/rtl_fm.c b/src/rtl_fm.c index 0f7ac38..e89e42d 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -62,7 +62,7 @@ #include #include "getopt/getopt.h" #define usleep(x) Sleep(x/1000) -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1800) #define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) #endif #define _USE_MATH_DEFINES @@ -271,7 +271,7 @@ int cic_9_tables[][10] = { {9, -199, -362, 5303, -25505, 77489, -25505, 5303, -362, -199}, }; -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1800) double log2(double n) { return log(n) / log(2.0); diff --git a/src/rtl_power.c b/src/rtl_power.c index 7eb1d06..aa7a138 100644 --- a/src/rtl_power.c +++ b/src/rtl_power.c @@ -53,7 +53,7 @@ #include #include "getopt/getopt.h" #define usleep(x) Sleep(x/1000) -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1800) #define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) #endif #define _USE_MATH_DEFINES @@ -220,7 +220,7 @@ int cic_9_tables[][10] = { {9, -199, -362, 5303, -25505, 77489, -25505, 5303, -362, -199}, }; -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1800) double log2(double n) { return log(n) / log(2.0); From e3c03f738f5aef4dc51e2b741fbdb542b9cc1bb1 Mon Sep 17 00:00:00 2001 From: Hoernchen Date: Tue, 9 Jun 2015 01:48:55 +0200 Subject: [PATCH 27/74] lib: check for libusb init failure --- src/librtlsdr.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 0650606..cdf1ca9 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -1298,14 +1298,16 @@ static rtlsdr_dongle_t *find_known_device(uint16_t vid, uint16_t pid) uint32_t rtlsdr_get_device_count(void) { - int i; + int i,r; libusb_context *ctx; libusb_device **list; uint32_t device_count = 0; struct libusb_device_descriptor dd; ssize_t cnt; - libusb_init(&ctx); + r = libusb_init(&ctx); + if(r < 0) + return 0; cnt = libusb_get_device_list(ctx, &list); @@ -1325,7 +1327,7 @@ uint32_t rtlsdr_get_device_count(void) const char *rtlsdr_get_device_name(uint32_t index) { - int i; + int i,r; libusb_context *ctx; libusb_device **list; struct libusb_device_descriptor dd; @@ -1333,7 +1335,9 @@ const char *rtlsdr_get_device_name(uint32_t index) uint32_t device_count = 0; ssize_t cnt; - libusb_init(&ctx); + r = libusb_init(&ctx); + if(r < 0) + return ""; cnt = libusb_get_device_list(ctx, &list); @@ -1373,7 +1377,9 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, uint32_t device_count = 0; ssize_t cnt; - libusb_init(&ctx); + r = libusb_init(&ctx); + if(r < 0) + return r; cnt = libusb_get_device_list(ctx, &list); @@ -1447,7 +1453,11 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) memset(dev, 0, sizeof(rtlsdr_dev_t)); memcpy(dev->fir, fir_default, sizeof(fir_default)); - libusb_init(&dev->ctx); + r = libusb_init(&dev->ctx); + if(r < 0){ + free(dev); + return -1; + } dev->dev_lost = 1; From 4a0e25ba41fc81f29ddd84aa5dbf2bbc1358dbbb Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sun, 14 Jun 2015 02:17:40 +0200 Subject: [PATCH 28/74] added option -L to print current level values added option -c to configure de-emphasis time constant for wbfm added option -v to print verbose (debug) output added alias modulation names nbfm, nfm, wfm --- src/rtl_fm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index 0f7ac38..8cf95f0 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -4,6 +4,7 @@ * Copyright (C) 2012 by Hoernchen * Copyright (C) 2012 by Kyle Keen * Copyright (C) 2013 by Elias Oenal + * Copyright (C) 2015 by Hayati Ayguen * * 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 @@ -92,6 +93,13 @@ static int *atan_lut = NULL; static int atan_lut_size = 131072; /* 512 KB */ static int atan_lut_coef = 8; +static int verbosity = 0; +static int printLevels = 0; +static int printLevelNo = 1; +static int levelMax = 0; +static int levelMaxMax = 0; +static double levelSum = 0.0; + struct dongle_state { int exit_flag; @@ -187,16 +195,21 @@ void usage(void) "\t-f frequency_to_tune_to [Hz]\n" "\t use multiple -f for scanning (requires squelch)\n" "\t ranges supported, -f 118M:137M:25k\n" + "\t[-v verbosity (default: 0)]\n" "\t[-M modulation (default: fm)]\n" - "\t fm, wbfm, raw, am, usb, lsb\n" + "\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n" "\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n" "\t raw mode outputs 2x16 bit IQ pairs\n" "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" "\t[-g tuner_gain (default: automatic)]\n" "\t[-l squelch_level (default: 0/off)]\n" + "\t[-L N prints levels every N calculations]\n" + "\t output are comma separated values (csv):\n" + "\t mean since last output, max since last output, overall max, squelch\n" + "\t[-c de-emphasis_time_constant in us for wbfm. 'us' or 'eu' for 75/50 us (default: us)]\n" //"\t for fm squelch is inverted\n" - //"\t[-o oversampling (default: 1, 4 recommended)]\n" + "\t[-o oversampling (default: 1, 4 recommended)]\n" "\t[-p ppm_error (default: 0)]\n" "\t[-E enable_option (default: none)]\n" "\t use multiple -E to enable multiple options\n" @@ -759,6 +772,24 @@ void full_demod(struct demod_state *d) } else { d->squelch_hits = 0;} } + + if (printLevels) { + if (!sr) + sr = rms(d->lowpassed, d->lp_len, 1); + --printLevelNo; + if (printLevels) { + levelSum += sr; + if (levelMax < sr) levelMax = sr; + if (levelMaxMax < sr) levelMaxMax = sr; + if (!printLevelNo) { + printLevelNo = printLevels; + fprintf(stderr, "%f, %d, %d, %d\n", (levelSum / printLevels), levelMax, levelMaxMax, d->squelch_level ); + levelMax = 0; + levelSum = 0; + } + } + } + d->mode_demod(d); /* lowpassed -> result */ if (d->mode_demod == &raw_demod) { return; @@ -864,9 +895,16 @@ static void optimal_settings(int freq, int rate) } capture_freq = freq; capture_rate = dm->downsample * dm->rate_in; + if (verbosity) + fprintf(stderr, "capture_rate = dm->downsample * dm->rate_in = %d * %d = %d\n", dm->downsample, dm->rate_in, capture_rate ); if (!d->offset_tuning) { - capture_freq = freq + capture_rate/4;} + capture_freq = freq + capture_rate/4; + if (verbosity) + fprintf(stderr, "optimal_settings(freq = %d): capture_freq = freq + capture_rate/4 = %d\n", freq, capture_freq ); + } capture_freq += cs->edge * dm->rate_in / 2; + if (verbosity) + fprintf(stderr, "optimal_settings(freq = %d): capture_freq += cs->edge * dm->rate_in / 2 = %d * %d / 2 = %d\n", freq, cs->edge, dm->rate_in, capture_freq ); dm->output_scale = (1<<15) / (128 * dm->downsample); if (dm->output_scale < 1) { dm->output_scale = 1;} @@ -874,6 +912,8 @@ static void optimal_settings(int freq, int rate) dm->output_scale = 1;} d->freq = (uint32_t)capture_freq; d->rate = (uint32_t)capture_rate; + if (verbosity) + fprintf(stderr, "optimal_settings(freq = %d) delivers freq %.0f, rate %.0f\n", freq, (double)d->freq, (double)d->rate ); } static void *controller_thread_fn(void *arg) @@ -884,6 +924,8 @@ static void *controller_thread_fn(void *arg) struct controller_state *s = arg; if (s->wb_mode) { + if (verbosity) + fprintf(stderr, "wbfm: adding 16000 Hz to every intput frequency\n"); for (i=0; i < s->freq_len; i++) { s->freqs[i] += 16000;} } @@ -896,6 +938,10 @@ static void *controller_thread_fn(void *arg) verbose_offset_tuning(dongle.dev);} /* Set the frequency */ + if (verbosity) { + fprintf(stderr, "verbose_set_frequency(%.0f Hz)\n", (double)dongle.freq); + fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n"); + } verbose_set_frequency(dongle.dev, dongle.freq); fprintf(stderr, "Oversampling input by: %ix.\n", demod.downsample); fprintf(stderr, "Oversampling output by: %ix.\n", demod.post_downsample); @@ -903,6 +949,8 @@ static void *controller_thread_fn(void *arg) 1000 * 0.5 * (float)ACTUAL_BUF_LENGTH / (float)dongle.rate); /* Set the sample rate */ + if (verbosity) + fprintf(stderr, "verbose_set_sample_rate(%.0f Hz)\n", (double)dongle.rate); verbose_set_sample_rate(dongle.dev, dongle.rate); fprintf(stderr, "Output at %u Hz.\n", demod.rate_in/demod.post_downsample); @@ -1042,12 +1090,13 @@ int main(int argc, char **argv) int r, opt; int dev_given = 0; int custom_ppm = 0; + int timeConstant = 75; /* default: U.S. 75 uS */ 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:L:o:t:r:p:E:F:A:M:c:v:h")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -1070,6 +1119,9 @@ int main(int argc, char **argv) case 'l': demod.squelch_level = (int)atof(optarg); break; + case 'L': + printLevels = (int)atof(optarg); + break; case 's': demod.rate_in = (uint32_t)atofs(optarg); demod.rate_out = (uint32_t)atofs(optarg); @@ -1121,9 +1173,9 @@ int main(int argc, char **argv) demod.custom_atan = 2;} break; case 'M': - if (strcmp("fm", optarg) == 0) { + if (strcmp("nbfm", optarg) == 0 || strcmp("nfm", optarg) == 0 || strcmp("fm", optarg) == 0) { demod.mode_demod = &fm_demod;} - if (strcmp("raw", optarg) == 0) { + if (strcmp("raw", optarg) == 0 || strcmp("iq", optarg) == 0) { demod.mode_demod = &raw_demod;} if (strcmp("am", optarg) == 0) { demod.mode_demod = &am_demod;} @@ -1131,7 +1183,7 @@ int main(int argc, char **argv) demod.mode_demod = &usb_demod;} if (strcmp("lsb", optarg) == 0) { demod.mode_demod = &lsb_demod;} - if (strcmp("wbfm", optarg) == 0) { + if (strcmp("wbfm", optarg) == 0 || strcmp("wfm", optarg) == 0) { controller.wb_mode = 1; demod.mode_demod = &fm_demod; demod.rate_in = 170000; @@ -1142,6 +1194,17 @@ int main(int argc, char **argv) demod.deemph = 1; demod.squelch_level = 0;} break; + case 'c': + if (strcmp("us", optarg) == 0) + timeConstant = 75; + else if (strcmp("eu", optarg) == 0) + timeConstant = 50; + else + timeConstant = (int)atof(optarg); + break; + case 'v': + verbosity = (int)atof(optarg); + break; case 'h': default: usage(); @@ -1194,7 +1257,10 @@ int main(int argc, char **argv) #endif if (demod.deemph) { - demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * 75e-6))))); + double tc = (double)timeConstant * 1e-6; + demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * tc))))); + if (verbosity) + fprintf(stderr, "using wbfm deemphasis filter with time constant %d us\n", timeConstant ); } /* Set the tuner gain */ From f5c7ad917134cdf7961ad801685d120521ab1d3d Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sat, 18 Jul 2015 15:40:33 +0200 Subject: [PATCH 29/74] added dc filter on raw data (after decimation) with option "-E rdc" added option "-q" for setting averaging speed added option "-E adc" in addition to "-E dc" --- src/rtl_fm.c | 62 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index 8cf95f0..f607e4e 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -146,7 +146,8 @@ struct demod_state int deemph, deemph_a; int now_lpr; int prev_lpr_index; - int dc_block, dc_avg; + int dc_block_audio, dc_avg, adc_block_const; + int dc_block_raw, dc_avgI, dc_avgQ, rdc_block_const; void (*mode_demod)(struct demod_state*); pthread_rwlock_t rw; pthread_cond_t ready; @@ -214,10 +215,13 @@ void usage(void) "\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 rdc: enable dc blocking filter on raw I/Q data\n" + "\t adc: enable dc blocking filter on demodulated audio\n" + "\t dc: same as adc\n" "\t deemp: enable de-emphasis filter\n" "\t direct: enable direct sampling\n" "\t offset: enable offset tuning\n" + "\t[-q dc_avg_factor for option rdc (default: 9)]\n" "\tfilename ('-' means stdout)\n" "\t omitting the filename also uses stdout\n\n" "Experimental options:\n" @@ -623,7 +627,7 @@ void deemph_filter(struct demod_state *fm) } } -void dc_block_filter(struct demod_state *fm) +void dc_block_audio_filter(struct demod_state *fm) { int i, avg; int64_t sum = 0; @@ -631,13 +635,37 @@ void dc_block_filter(struct demod_state *fm) sum += fm->result[i]; } avg = sum / fm->result_len; - avg = (avg + fm->dc_avg * 9) / 10; + avg = (avg + fm->dc_avg * fm->adc_block_const) / ( fm->adc_block_const + 1 ); for (i=0; i < fm->result_len; i++) { fm->result[i] -= avg; } fm->dc_avg = avg; } +void dc_block_raw_filter(struct demod_state *fm) +{ + /* derived from dc_block_audio_filter, + running over the raw I/Q components + */ + int16_t *lp = fm->lowpassed; + int i, avgI, avgQ; + int64_t sumI = 0; + int64_t sumQ = 0; + for (i = 0; i < fm->lp_len; i += 2) { + sumI += lp[i]; + sumQ += lp[i+1]; + } + avgI = sumI / ( fm->lp_len / 2 ); + avgQ = sumQ / ( fm->lp_len / 2 ); + avgI = (avgI + fm->dc_avgI * fm->rdc_block_const) / ( fm->rdc_block_const + 1 ); + avgQ = (avgQ + fm->dc_avgQ * fm->rdc_block_const) / ( fm->rdc_block_const + 1 ); + for (i = 0; i < fm->lp_len; i += 2) { + lp[i] -= avgI; + lp[i+1] -= avgQ; + } + fm->dc_avgI = avgI; + fm->dc_avgQ = avgQ; +} int mad(int16_t *samples, int len, int step) /* mean average deviation */ { @@ -789,7 +817,9 @@ void full_demod(struct demod_state *d) } } } - + if (d->dc_block_raw) { + dc_block_raw_filter(d); + } d->mode_demod(d); /* lowpassed -> result */ if (d->mode_demod == &raw_demod) { return; @@ -800,8 +830,8 @@ void full_demod(struct demod_state *d) d->result_len = low_pass_simple(d->result, d->result_len, d->post_downsample);} if (d->deemph) { deemph_filter(d);} - if (d->dc_block) { - dc_block_filter(d);} + if (d->dc_block_audio) { + dc_block_audio_filter(d);} if (d->rate_out2 > 0) { low_pass_real(d); //arbitrary_resample(d->result, d->result, d->result_len, d->result_len * d->rate_out2 / d->rate_out); @@ -1017,8 +1047,13 @@ void demod_init(struct demod_state *s) s->prev_lpr_index = 0; s->deemph_a = 0; s->now_lpr = 0; - s->dc_block = 0; + s->dc_block_audio = 0; s->dc_avg = 0; + s->adc_block_const = 9; + s->dc_block_raw = 0; + s->dc_avgI = 0; + s->dc_avgQ = 0; + s->rdc_block_const = 9; pthread_rwlock_init(&s->rw, NULL); pthread_cond_init(&s->ready, NULL); pthread_mutex_init(&s->ready_m, NULL); @@ -1096,7 +1131,7 @@ int main(int argc, char **argv) output_init(&output); controller_init(&controller); - while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:F:A:M:c:v:h")) != -1) { + while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:v:h")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -1150,8 +1185,10 @@ int main(int argc, char **argv) case 'E': if (strcmp("edge", optarg) == 0) { controller.edge = 1;} - if (strcmp("dc", optarg) == 0) { - demod.dc_block = 1;} + if (strcmp("dc", optarg) == 0 || strcmp("adc", optarg) == 0) { + demod.dc_block_audio = 1;} + if (strcmp("rdc", optarg) == 0) { + demod.dc_block_raw = 1;} if (strcmp("deemp", optarg) == 0) { demod.deemph = 1;} if (strcmp("direct", optarg) == 0) { @@ -1159,6 +1196,9 @@ int main(int argc, char **argv) if (strcmp("offset", optarg) == 0) { dongle.offset_tuning = 1;} break; + case 'q': + demod.rdc_block_const = atoi(optarg); + break; case 'F': demod.downsample_passes = 1; /* truthy placeholder */ demod.comp_fir_size = atoi(optarg); From 5e063d82042922d7620e48e4e1a805d383412cc9 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sun, 19 Jul 2015 12:43:04 +0200 Subject: [PATCH 30/74] "rdc" filter in rtl_fm now at capture rate, before mixing or filtering: DC is now totally removed, when not using option "-F 9" due to bad anti-alias rejection the RTL dongle's DC folded into the decimated band therefore swapped conversion to 16 bit and up-mixing by fs/4 (rotate_90) --- src/rtl_fm.c | 65 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index f607e4e..2b98f5f 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -109,7 +109,7 @@ struct dongle_state uint32_t freq; uint32_t rate; int gain; - uint16_t buf16[MAXIMUM_BUF_LENGTH]; + int16_t buf16[MAXIMUM_BUF_LENGTH]; uint32_t buf_len; int ppm_error; int offset_tuning; @@ -215,7 +215,7 @@ void usage(void) "\t[-E enable_option (default: none)]\n" "\t use multiple -E to enable multiple options\n" "\t edge: enable lower edge tuning\n" - "\t rdc: enable dc blocking filter on raw I/Q data\n" + "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" "\t adc: enable dc blocking filter on demodulated audio\n" "\t dc: same as adc\n" "\t deemp: enable de-emphasis filter\n" @@ -295,6 +295,27 @@ double log2(double n) } #endif +void rotate16_90(int16_t *buf, uint32_t len) +/* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j + or [0, 1, -3, 2, -4, -5, 7, -6] */ +{ + uint32_t i; + int16_t tmp; + for (i=0; idc_avg = avg; } -void dc_block_raw_filter(struct demod_state *fm) +void dc_block_raw_filter(struct demod_state *fm, int16_t *buf, int len) { /* derived from dc_block_audio_filter, running over the raw I/Q components */ - int16_t *lp = fm->lowpassed; int i, avgI, avgQ; int64_t sumI = 0; int64_t sumQ = 0; - for (i = 0; i < fm->lp_len; i += 2) { - sumI += lp[i]; - sumQ += lp[i+1]; + for (i = 0; i < len; i += 2) { + sumI += buf[i]; + sumQ += buf[i+1]; } - avgI = sumI / ( fm->lp_len / 2 ); - avgQ = sumQ / ( fm->lp_len / 2 ); + avgI = sumI / ( len / 2 ); + avgQ = sumQ / ( len / 2 ); avgI = (avgI + fm->dc_avgI * fm->rdc_block_const) / ( fm->rdc_block_const + 1 ); avgQ = (avgQ + fm->dc_avgQ * fm->rdc_block_const) / ( fm->rdc_block_const + 1 ); - for (i = 0; i < fm->lp_len; i += 2) { - lp[i] -= avgI; - lp[i+1] -= avgQ; + for (i = 0; i < len; i += 2) { + buf[i] -= avgI; + buf[i+1] -= avgQ; } fm->dc_avgI = avgI; fm->dc_avgQ = avgQ; @@ -817,9 +837,6 @@ void full_demod(struct demod_state *d) } } } - if (d->dc_block_raw) { - dc_block_raw_filter(d); - } d->mode_demod(d); /* lowpassed -> result */ if (d->mode_demod == &raw_demod) { return; @@ -853,10 +870,19 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) buf[i] = 127;} s->mute = 0; } - if (!s->offset_tuning) { - rotate_90(buf, len);} + /* 1st: convert to 16 bit - to allow easier calculation of DC */ for (i=0; i<(int)len; i++) { - s->buf16[i] = (int16_t)buf[i] - 127;} + s->buf16[i] = ( (int16_t)buf[i] - 127 ); + } + /* 2nd: do DC filtering BEFORE up-mixing */ + if (d->dc_block_raw) { + dc_block_raw_filter(d, s->buf16, (int)len); + } + /* 3rd: up-mixing */ + if (!s->offset_tuning) { + rotate16_90(s->buf16, (int)len); + /* rotate_90(buf, len); */ + } pthread_rwlock_wrlock(&d->rw); memcpy(d->lowpassed, s->buf16, 2*len); d->lp_len = len; @@ -923,6 +949,9 @@ static void optimal_settings(int freq, int rate) dm->downsample_passes = (int)log2(dm->downsample) + 1; dm->downsample = 1 << dm->downsample_passes; } + if (verbosity) { + fprintf(stderr, "downsample_passes = %d (= # of fifth_order() iterations), downsample = %d\n", dm->downsample_passes, dm->downsample ); + } capture_freq = freq; capture_rate = dm->downsample * dm->rate_in; if (verbosity) From 8a68ce1a51b83707e115dd0cfbb8ef85e6d59f2e Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 17 Aug 2015 23:09:54 +0200 Subject: [PATCH 31/74] add uninstall note to README.rtlsdr_rpc --- README.rtlsdr_rpc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.rtlsdr_rpc b/README.rtlsdr_rpc index 8e11068..646b13d 100644 --- a/README.rtlsdr_rpc +++ b/README.rtlsdr_rpc @@ -8,8 +8,12 @@ them. Also, it allows a developer to use the same API no matter weither the dongle is local or distant. To use it, one must compile and install the library -with CMAKE the usual way. Then, a server (called rtl_rpcd) -must be run on the remote location. +with CMAKE the usual way. Note that you may need to +uninstall the existing librtlsdr, as people reported +runtime errors due to conflicting installs. + +Then, a server (called rtl_rpcd) must be run on the +remote location. In my case, the dongle is in a beagle bone black is at address 192.168.0.43: From 25d0e8e6737b93b3564ad04d0fd2cd5e91cefa8b Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 31 Jan 2016 15:57:42 -0200 Subject: [PATCH 32/74] Ported SDR# R820T Manual Gain Settings Plugin * Ported Manual Gain Settings for R820T from http://sourceforge.net/projects/sdrr820tmanualgainsettings/ --- .gitignore | 1 + include/rtl-sdr.h | 11 +++++ include/tuner_r82xx.h | 4 +- src/librtlsdr.c | 33 +++++++++++-- src/tuner_r82xx.c | 109 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 153 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 5ef0532..a12eb65 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ CMakeCache.txt */CMakeFiles CMakeFiles *.cmake +build diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index fe64bea..38ae207 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -232,6 +232,17 @@ RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw); */ RTLSDR_API int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev); +/*! + * Set LNA / Mixer / VGA Device Gain for R820T device is configured to. + * + * \param dev the device handle given by rtlsdr_open() + * \param lna_gain in tenths of a dB, -30 means -3.0 dB. + * \param mixer_gain in tenths of a dB, -30 means -3.0 dB. + * \param vga_gain in tenths of a dB, -30 means -3.0 dB. + * \return 0 on success + */ +RTLSDR_API int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, int vga_gain); + /*! * Set the intermediate frequency gain for the device. * diff --git a/include/tuner_r82xx.h b/include/tuner_r82xx.h index f6c206a..49d73d6 100644 --- a/include/tuner_r82xx.h +++ b/include/tuner_r82xx.h @@ -114,7 +114,9 @@ enum r82xx_delivery_system { int r82xx_standby(struct r82xx_priv *priv); int r82xx_init(struct r82xx_priv *priv); int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq); -int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain); +//int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain); +int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, int extended_mode, int lna_gain, int mixer_gain, int vga_gain); + int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate); #endif diff --git a/src/librtlsdr.c b/src/librtlsdr.c index cdf1ca9..ef6c7ba 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -255,12 +255,18 @@ int r820t_set_bw(void *dev, int bw) { } int r820t_set_gain(void *dev, int gain) { - rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - return r82xx_set_gain(&devt->r82xx_p, 1, gain); + rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; + return r82xx_set_gain(&devt->r82xx_p, 1, gain, 0, 0, 0, 0); +} + +int r820t_set_gain_ext(void *dev, int lna_gain, int mixer_gain, int vga_gain) { + rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; + return r82xx_set_gain(&devt->r82xx_p, 0, 0, 1, lna_gain, mixer_gain, vga_gain); } + int r820t_set_gain_mode(void *dev, int manual) { rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - return r82xx_set_gain(&devt->r82xx_p, manual, 0); + return r82xx_set_gain(&devt->r82xx_p, manual, 0, 0, 0, 0, 0); } /* definition order must match enum rtlsdr_tuner */ @@ -1048,6 +1054,27 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) return r; } +int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, int vga_gain) +{ + int r = 0; + + if (!dev || !dev->tuner) + return -1; + + if (dev->tuner->set_gain) { + rtlsdr_set_i2c_repeater(dev, 1); + r = r820t_set_gain_ext((void *)dev, lna_gain, mixer_gain, vga_gain); + rtlsdr_set_i2c_repeater(dev, 0); + } + + if (!r) + dev->gain = lna_gain + mixer_gain + vga_gain; + else + dev->gain = 0; + + return r; +} + int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev) { if (!dev) diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c index f620238..eb62352 100644 --- a/src/tuner_r82xx.c +++ b/src/tuner_r82xx.c @@ -1004,7 +1004,7 @@ static const int r82xx_mixer_gain_steps[] = { 0, 5, 10, 10, 19, 9, 10, 25, 17, 10, 8, 16, 13, 6, 3, -8 }; -int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain) +int r82xx_set_gain_old(struct r82xx_priv *priv, int set_manual_gain, int gain) { int rc; @@ -1073,6 +1073,113 @@ int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain) return 0; } +int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, + int extended_mode, int lna_gain, int mixer_gain, int vga_gain) +{ + int rc; + + int i, total_gain = 0; + uint8_t mix_index = 0, lna_index = 0; + uint8_t data[4]; + + if (extended_mode) { + /* + // LNA auto off + rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); + if (rc < 0) + return rc; + + // Mixer auto off + rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); + if (rc < 0) + return rc; + + rc = r82xx_read(priv, 0x00, data, sizeof(data)); + if (rc < 0) + return rc; + */ + + /* Set LNA */ + rc = r82xx_write_reg_mask(priv, 0x05, lna_gain, 0x0f); + if (rc < 0) + return rc; + + /* Set Mixer */ + rc = r82xx_write_reg_mask(priv, 0x07, mixer_gain, 0x0f); + if (rc < 0) + return rc; + + /* Set VGA */ + rc = r82xx_write_reg_mask(priv, 0x0c, vga_gain, 0x9f); + if (rc < 0) + return rc; + + return 0; + } + + if (set_manual_gain) { + + /* LNA auto off */ + rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); + if (rc < 0) + return rc; + + /* Mixer auto off */ + rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); + if (rc < 0) + return rc; + + rc = r82xx_read(priv, 0x00, data, sizeof(data)); + if (rc < 0) + return rc; + + /* set fixed VGA gain for now (16.3 dB) */ + rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f); + if (rc < 0) + return rc; + + for (i = 0; i < 15; i++) { + if (total_gain >= gain) + break; + + total_gain += r82xx_lna_gain_steps[++lna_index]; + + if (total_gain >= gain) + break; + + total_gain += r82xx_mixer_gain_steps[++mix_index]; + } + + /* set LNA gain */ + rc = r82xx_write_reg_mask(priv, 0x05, lna_index, 0x0f); + if (rc < 0) + return rc; + + /* set Mixer gain */ + rc = r82xx_write_reg_mask(priv, 0x07, mix_index, 0x0f); + if (rc < 0) + return rc; + } else { + /* LNA */ + rc = r82xx_write_reg_mask(priv, 0x05, 0, 0x10); + if (rc < 0) + return rc; + + /* Mixer */ + rc = r82xx_write_reg_mask(priv, 0x07, 0x10, 0x10); + if (rc < 0) + return rc; + + /* set fixed VGA gain for now (26.5 dB) */ + rc = r82xx_write_reg_mask(priv, 0x0c, 0x0b, 0x9f); + if (rc < 0) + return rc; + } + + return 0; +} + + /* Bandwidth contribution by low-pass filter. */ static const int r82xx_if_low_pass_bw_table[] = { 1700000, 1600000, 1550000, 1450000, 1200000, 900000, 700000, 550000, 450000, 350000 From a9780dc5a5014366f918f645e0fb38f0dbe09402 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 28 Feb 2016 16:35:27 -0300 Subject: [PATCH 33/74] Added debian scripts to generate debian packages TODO: Move to CMAKE --- debian/debianize | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 debian/debianize diff --git a/debian/debianize b/debian/debianize new file mode 100755 index 0000000..c42d0bf --- /dev/null +++ b/debian/debianize @@ -0,0 +1,52 @@ +#!/bin/bash + +PKG_NAME="librtlsdr0" + +REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../" +DIR="/tmp/package/${PKG_NAME}" +USRDIR="${DIR}/usr/" +LIBDIR="${USRDIR}/lib/x86_64-linux-gnu" +BINDIR="${USRDIR}/bin/" +DEBIAN="${DIR}/DEBIAN" +INCDIR="${USRDIR}/include" + +rm -rf ${DIR} + +mkdir -p ${DIR} +mkdir -p ${DEBIAN} +mkdir -p ${LIBDIR} +mkdir -p ${BINDIR} +mkdir -p ${INCDIR} + +G_REV=`git rev-parse --short=8 HEAD` +DATE=`date +"%Y%m%d%H%M%S"` +VERSION="0.5.3-git+${DATE}.${G_REV}~$1" + +cat <<- EOF > ${DEBIAN}/control +Package: ${PKG_NAME} +Source: rtl-sdr +Version: ${VERSION} +Architecture: amd64 +Maintainer: Lucas Teske +Pre-Depends: multiarch-support +Depends: libc6 (>= 2.14), libusb-1.0-0 (>= 2:1.0.9) +Section: libs +Priority: extra +Multi-Arch: same +Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr +Description: Software defined radio receiver for Realtek RTL2832U (library) + rtl-sdr is a software defined radio (SDR) receiver software for certain + low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip. + . + This package contains the shared library. +EOF + +DEB_PKG="${PKG_NAME}_${VERSION}_amd64.deb" + +cp -rf ${REPO_DIR}/build/src/rtl_* ${BINDIR} +cp -rf ${REPO_DIR}/build/src/lib* ${LIBDIR} +cp -rf ${REPO_DIR}/include/*.h ${INCDIR} + +dpkg-deb -b ${DIR} ./${DEB_PKG} + +echo ${DEB_PKG} From d53592606dc9bb83e4ad10c5ae6f492bb21e8017 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 28 Feb 2016 16:56:33 -0300 Subject: [PATCH 34/74] Fixes to Debianize Script --- .gitignore | 2 + debian/.gitignore | 1 + debian/debianize | 114 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 debian/.gitignore diff --git a/.gitignore b/.gitignore index a12eb65..d22084c 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ CMakeCache.txt CMakeFiles *.cmake build + +debianize/*.deb diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000..c00df13 --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1 @@ +*.deb diff --git a/debian/debianize b/debian/debianize index c42d0bf..a931dad 100755 --- a/debian/debianize +++ b/debian/debianize @@ -1,29 +1,22 @@ #!/bin/bash -PKG_NAME="librtlsdr0" - REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../" -DIR="/tmp/package/${PKG_NAME}" -USRDIR="${DIR}/usr/" -LIBDIR="${USRDIR}/lib/x86_64-linux-gnu" -BINDIR="${USRDIR}/bin/" -DEBIAN="${DIR}/DEBIAN" -INCDIR="${USRDIR}/include" - -rm -rf ${DIR} - -mkdir -p ${DIR} -mkdir -p ${DEBIAN} -mkdir -p ${LIBDIR} -mkdir -p ${BINDIR} -mkdir -p ${INCDIR} G_REV=`git rev-parse --short=8 HEAD` DATE=`date +"%Y%m%d%H%M%S"` VERSION="0.5.3-git+${DATE}.${G_REV}~$1" -cat <<- EOF > ${DEBIAN}/control -Package: ${PKG_NAME} +# +# librtlsdr0 +# + +rm -fr /tmp/librtlsdr0/ +mkdir -p /tmp/librtlsdr0/ +mkdir -p /tmp/librtlsdr0/usr/lib/x86_64-linux-gnu/ +mkdir -p /tmp/librtlsdr0/DEBIAN + +cat <<- EOF > /tmp/librtlsdr0/DEBIAN/control +Package: librtlsdr0 Source: rtl-sdr Version: ${VERSION} Architecture: amd64 @@ -41,12 +34,87 @@ Description: Software defined radio receiver for Realtek RTL2832U (library) This package contains the shared library. EOF -DEB_PKG="${PKG_NAME}_${VERSION}_amd64.deb" +DEB_PKG="librtlsdr0_${VERSION}_amd64.deb" + +cp -rf ${REPO_DIR}/build/src/lib*so* /tmp/librtlsdr0/usr/lib/x86_64-linux-gnu/ +dpkg-deb -b /tmp/librtlsdr0/ ./${DEB_PKG} + +echo ${DEB_PKG} + +# +# rtl-sdr +# + +rm -fr /tmp/rtl-sdr/ +mkdir -p /tmp/rtl-sdr/ +mkdir -p /tmp/rtl-sdr/usr/bin/ +mkdir -p /tmp/rtl-sdr/DEBIAN + +cat <<- EOF > /tmp/rtl-sdr/DEBIAN/control +Package: rtl-sdr +Version: ${VERSION} +Architecture: amd64 +Maintainer: Lucas Teske +Depends: librtlsdr0 (= ${VERSION}), libc6 (>= 2.15) +Section: libs +Priority: extra +Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr +Description: Software defined radio receiver for Realtek RTL2832U (tools) + rtl-sdr is a software defined radio (SDR) receiver software for certain + low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip. + . + This package contains a set of command line utilities: + * rtl_adsb: a simple ADS-B decoder for RTL2832 based DVB-T receivers + * rtl_eeprom: an EEPROM programming tool for RTL2832 based DVB-T receivers + * rtl_fm: a narrow band FM demodulator for RTL2832 based DVB-T receivers + * rtl_sdr: an I/Q recorder for RTL2832 based DVB-T receivers + * rtl_tcp: an I/Q spectrum server for RTL2832 based DVB-T receivers + * rtl_test: a benchmark tool for RTL2832 based DVB-T receivers + -cp -rf ${REPO_DIR}/build/src/rtl_* ${BINDIR} -cp -rf ${REPO_DIR}/build/src/lib* ${LIBDIR} -cp -rf ${REPO_DIR}/include/*.h ${INCDIR} +EOF + +DEB_PKG="rtl-sdr_${VERSION}_amd64.deb" -dpkg-deb -b ${DIR} ./${DEB_PKG} +cp -rf ${REPO_DIR}/build/src/rtl_* /tmp/rtl-sdr/usr/bin/ +dpkg-deb -b /tmp/rtl-sdr/ ./${DEB_PKG} echo ${DEB_PKG} + + +# +# librtlsdr-dev +# + +rm -fr /tmp/librtlsdr-dev/ +mkdir -p /tmp/librtlsdr-dev/ +mkdir -p /tmp/librtlsdr-dev/usr/include +mkdir -p /tmp/librtlsdr-dev/usr/lib/x86_64-linux-gnu/pkgconfig +mkdir -p /tmp/librtlsdr-dev/DEBIAN + +cat <<- EOF > /tmp/librtlsdr-dev/DEBIAN/control +Package: librtlsdr-dev +Source: rtl-sdr +Version: ${VERSION} +Architecture: amd64 +Maintainer: Lucas Teske +Pre-Depends: multiarch-support +Depends: librtlsdr0 (= ${VERSION}) +Section: libdevel +Priority: extra +Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr +Description: Software defined radio receiver for Realtek RTL2832U (development files) + rtl-sdr is a software defined radio (SDR) receiver software for certain + low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip. + . + This package contains development files. + +EOF + +DEB_PKG="librtlsdr-dev_${VERSION}_amd64.deb" + +cp -rf ${REPO_DIR}/build/include/*.h /tmp/librtlsdr-dev/usr/include +cat ../librtlsdr.pc | sed 's/\/usr\/local/\/usr/g' | sed 's/v0.5.3.*/${VERSION}/' > /tmp/librtlsdr-dev/usr/lib/x86_64-linux-gnu/pkgconfig/librtlsdr.pc +dpkg-deb -b /tmp/librtlsdr-dev/ ./${DEB_PKG} + +echo ${DEB_PKG} \ No newline at end of file From 3ef9ce972d66cd6cab087f8af9ea488cb923759e Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sat, 5 Mar 2016 23:19:52 -0300 Subject: [PATCH 35/74] Changed the VERSION to use git describe --- debian/debianize | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/debian/debianize b/debian/debianize index a931dad..32d8233 100755 --- a/debian/debianize +++ b/debian/debianize @@ -4,8 +4,8 @@ REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../" G_REV=`git rev-parse --short=8 HEAD` DATE=`date +"%Y%m%d%H%M%S"` -VERSION="0.5.3-git+${DATE}.${G_REV}~$1" - +#VERSION="0.5.3-git+${DATE}.${G_REV}~$1" +VERSION=`git describe | cut -dv -f2` # # librtlsdr0 # @@ -113,8 +113,7 @@ EOF DEB_PKG="librtlsdr-dev_${VERSION}_amd64.deb" -cp -rf ${REPO_DIR}/build/include/*.h /tmp/librtlsdr-dev/usr/include -cat ../librtlsdr.pc | sed 's/\/usr\/local/\/usr/g' | sed 's/v0.5.3.*/${VERSION}/' > /tmp/librtlsdr-dev/usr/lib/x86_64-linux-gnu/pkgconfig/librtlsdr.pc +cp -rf ${REPO_DIR}/include/*.h /tmp/librtlsdr-dev/usr/include dpkg-deb -b /tmp/librtlsdr-dev/ ./${DEB_PKG} echo ${DEB_PKG} \ No newline at end of file From 38312eac038b275827bd76999967b4241204b97e Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Sun, 6 Mar 2016 12:08:27 -0600 Subject: [PATCH 36/74] minor formatting --- include/tuner_e4k.h | 156 +++++++++++++++---------------- include/tuner_fc2580.h | 6 +- include/tuner_r82xx.h | 34 ++++--- src/convenience/convenience.h | 4 + src/librtlsdr.c | 48 +++++----- src/rtl_adsb.c | 2 +- src/rtl_fm.c | 4 +- src/rtl_power.c | 4 +- src/rtl_test.c | 2 +- src/tuner_e4k.c | 10 +- src/tuner_fc0013.c | 16 ++-- src/tuner_fc2580.c | 59 +++++------- src/tuner_r82xx.c | 170 +++++++++++++++++----------------- 13 files changed, 253 insertions(+), 262 deletions(-) diff --git a/include/tuner_e4k.h b/include/tuner_e4k.h index 79591ce..36f6aa1 100644 --- a/include/tuner_e4k.h +++ b/include/tuner_e4k.h @@ -29,94 +29,94 @@ #define E4K_CHECK_VAL 0x40 enum e4k_reg { - E4K_REG_MASTER1 = 0x00, - E4K_REG_MASTER2 = 0x01, - E4K_REG_MASTER3 = 0x02, - E4K_REG_MASTER4 = 0x03, - E4K_REG_MASTER5 = 0x04, - E4K_REG_CLK_INP = 0x05, - E4K_REG_REF_CLK = 0x06, - E4K_REG_SYNTH1 = 0x07, - E4K_REG_SYNTH2 = 0x08, - E4K_REG_SYNTH3 = 0x09, - E4K_REG_SYNTH4 = 0x0a, - E4K_REG_SYNTH5 = 0x0b, - E4K_REG_SYNTH6 = 0x0c, - E4K_REG_SYNTH7 = 0x0d, - E4K_REG_SYNTH8 = 0x0e, - E4K_REG_SYNTH9 = 0x0f, - E4K_REG_FILT1 = 0x10, - E4K_REG_FILT2 = 0x11, - E4K_REG_FILT3 = 0x12, + E4K_REG_MASTER1 = 0x00, + E4K_REG_MASTER2 = 0x01, + E4K_REG_MASTER3 = 0x02, + E4K_REG_MASTER4 = 0x03, + E4K_REG_MASTER5 = 0x04, + E4K_REG_CLK_INP = 0x05, + E4K_REG_REF_CLK = 0x06, + E4K_REG_SYNTH1 = 0x07, + E4K_REG_SYNTH2 = 0x08, + E4K_REG_SYNTH3 = 0x09, + E4K_REG_SYNTH4 = 0x0a, + E4K_REG_SYNTH5 = 0x0b, + E4K_REG_SYNTH6 = 0x0c, + E4K_REG_SYNTH7 = 0x0d, + E4K_REG_SYNTH8 = 0x0e, + E4K_REG_SYNTH9 = 0x0f, + E4K_REG_FILT1 = 0x10, + E4K_REG_FILT2 = 0x11, + E4K_REG_FILT3 = 0x12, // gap - E4K_REG_GAIN1 = 0x14, - E4K_REG_GAIN2 = 0x15, - E4K_REG_GAIN3 = 0x16, - E4K_REG_GAIN4 = 0x17, + E4K_REG_GAIN1 = 0x14, + E4K_REG_GAIN2 = 0x15, + E4K_REG_GAIN3 = 0x16, + E4K_REG_GAIN4 = 0x17, // gap - E4K_REG_AGC1 = 0x1a, - E4K_REG_AGC2 = 0x1b, - E4K_REG_AGC3 = 0x1c, - E4K_REG_AGC4 = 0x1d, - E4K_REG_AGC5 = 0x1e, - E4K_REG_AGC6 = 0x1f, - E4K_REG_AGC7 = 0x20, - E4K_REG_AGC8 = 0x21, + E4K_REG_AGC1 = 0x1a, + E4K_REG_AGC2 = 0x1b, + E4K_REG_AGC3 = 0x1c, + E4K_REG_AGC4 = 0x1d, + E4K_REG_AGC5 = 0x1e, + E4K_REG_AGC6 = 0x1f, + E4K_REG_AGC7 = 0x20, + E4K_REG_AGC8 = 0x21, // gap - E4K_REG_AGC11 = 0x24, - E4K_REG_AGC12 = 0x25, + E4K_REG_AGC11 = 0x24, + E4K_REG_AGC12 = 0x25, // gap - E4K_REG_DC1 = 0x29, - E4K_REG_DC2 = 0x2a, - E4K_REG_DC3 = 0x2b, - E4K_REG_DC4 = 0x2c, - E4K_REG_DC5 = 0x2d, - E4K_REG_DC6 = 0x2e, - E4K_REG_DC7 = 0x2f, - E4K_REG_DC8 = 0x30, + E4K_REG_DC1 = 0x29, + E4K_REG_DC2 = 0x2a, + E4K_REG_DC3 = 0x2b, + E4K_REG_DC4 = 0x2c, + E4K_REG_DC5 = 0x2d, + E4K_REG_DC6 = 0x2e, + E4K_REG_DC7 = 0x2f, + E4K_REG_DC8 = 0x30, // gap - E4K_REG_QLUT0 = 0x50, - E4K_REG_QLUT1 = 0x51, - E4K_REG_QLUT2 = 0x52, - E4K_REG_QLUT3 = 0x53, + E4K_REG_QLUT0 = 0x50, + E4K_REG_QLUT1 = 0x51, + E4K_REG_QLUT2 = 0x52, + E4K_REG_QLUT3 = 0x53, // gap - E4K_REG_ILUT0 = 0x60, - E4K_REG_ILUT1 = 0x61, - E4K_REG_ILUT2 = 0x62, - E4K_REG_ILUT3 = 0x63, + E4K_REG_ILUT0 = 0x60, + E4K_REG_ILUT1 = 0x61, + E4K_REG_ILUT2 = 0x62, + E4K_REG_ILUT3 = 0x63, // gap - E4K_REG_DCTIME1 = 0x70, - E4K_REG_DCTIME2 = 0x71, - E4K_REG_DCTIME3 = 0x72, - E4K_REG_DCTIME4 = 0x73, - E4K_REG_PWM1 = 0x74, - E4K_REG_PWM2 = 0x75, - E4K_REG_PWM3 = 0x76, - E4K_REG_PWM4 = 0x77, - E4K_REG_BIAS = 0x78, - E4K_REG_CLKOUT_PWDN = 0x7a, + E4K_REG_DCTIME1 = 0x70, + E4K_REG_DCTIME2 = 0x71, + E4K_REG_DCTIME3 = 0x72, + E4K_REG_DCTIME4 = 0x73, + E4K_REG_PWM1 = 0x74, + E4K_REG_PWM2 = 0x75, + E4K_REG_PWM3 = 0x76, + E4K_REG_PWM4 = 0x77, + E4K_REG_BIAS = 0x78, + E4K_REG_CLKOUT_PWDN = 0x7a, E4K_REG_CHFILT_CALIB = 0x7b, E4K_REG_I2C_REG_ADDR = 0x7d, // FIXME }; -#define E4K_MASTER1_RESET (1 << 0) +#define E4K_MASTER1_RESET (1 << 0) #define E4K_MASTER1_NORM_STBY (1 << 1) -#define E4K_MASTER1_POR_DET (1 << 2) +#define E4K_MASTER1_POR_DET (1 << 2) -#define E4K_SYNTH1_PLL_LOCK (1 << 0) +#define E4K_SYNTH1_PLL_LOCK (1 << 0) #define E4K_SYNTH1_BAND_SHIF 1 #define E4K_SYNTH7_3PHASE_EN (1 << 3) #define E4K_SYNTH8_VCOCAL_UPD (1 << 2) -#define E4K_FILT3_DISABLE (1 << 5) +#define E4K_FILT3_DISABLE (1 << 5) -#define E4K_AGC1_LIN_MODE (1 << 4) -#define E4K_AGC1_LNA_UPDATE (1 << 5) -#define E4K_AGC1_LNA_G_LOW (1 << 6) -#define E4K_AGC1_LNA_G_HIGH (1 << 7) +#define E4K_AGC1_LIN_MODE (1 << 4) +#define E4K_AGC1_LNA_UPDATE (1 << 5) +#define E4K_AGC1_LNA_G_LOW (1 << 6) +#define E4K_AGC1_LNA_G_HIGH (1 << 7) #define E4K_AGC6_LNA_CAL_REQ (1 << 4) @@ -127,27 +127,27 @@ enum e4k_reg { #define E4K_AGC11_LNA_GAIN_ENH (1 << 0) -#define E4K_DC1_CAL_REQ (1 << 0) +#define E4K_DC1_CAL_REQ (1 << 0) -#define E4K_DC5_I_LUT_EN (1 << 0) -#define E4K_DC5_Q_LUT_EN (1 << 1) +#define E4K_DC5_I_LUT_EN (1 << 0) +#define E4K_DC5_Q_LUT_EN (1 << 1) #define E4K_DC5_RANGE_DET_EN (1 << 2) -#define E4K_DC5_RANGE_EN (1 << 3) -#define E4K_DC5_TIMEVAR_EN (1 << 4) +#define E4K_DC5_RANGE_EN (1 << 3) +#define E4K_DC5_TIMEVAR_EN (1 << 4) -#define E4K_CLKOUT_DISABLE 0x96 +#define E4K_CLKOUT_DISABLE 0x96 -#define E4K_CHFCALIB_CMD (1 << 0) +#define E4K_CHFCALIB_CMD (1 << 0) -#define E4K_AGC1_MOD_MASK 0xF +#define E4K_AGC1_MOD_MASK 0xF enum e4k_agc_mode { - E4K_AGC_MOD_SERIAL = 0x0, + E4K_AGC_MOD_SERIAL = 0x0, E4K_AGC_MOD_IF_PWM_LNA_SERIAL = 0x1, E4K_AGC_MOD_IF_PWM_LNA_AUTONL = 0x2, E4K_AGC_MOD_IF_PWM_LNA_SUPERV = 0x3, E4K_AGC_MOD_IF_SERIAL_LNA_PWM = 0x4, - E4K_AGC_MOD_IF_PWM_LNA_PWM = 0x5, + E4K_AGC_MOD_IF_PWM_LNA_PWM = 0x5, E4K_AGC_MOD_IF_DIG_LNA_SERIAL = 0x6, E4K_AGC_MOD_IF_DIG_LNA_AUTON = 0x7, E4K_AGC_MOD_IF_DIG_LNA_SUPERV = 0x8, @@ -159,7 +159,7 @@ enum e4k_band { E4K_BAND_VHF2 = 0, E4K_BAND_VHF3 = 1, E4K_BAND_UHF = 2, - E4K_BAND_L = 3, + E4K_BAND_L = 3, }; enum e4k_mixer_filter_bw { diff --git a/include/tuner_fc2580.h b/include/tuner_fc2580.h index 9ebd935..6eb08b7 100644 --- a/include/tuner_fc2580.h +++ b/include/tuner_fc2580.h @@ -1,9 +1,9 @@ #ifndef __TUNER_FC2580_H #define __TUNER_FC2580_H -#define BORDER_FREQ 2600000 //2.6GHz : The border frequency which determines whether Low VCO or High VCO is used -#define USE_EXT_CLK 0 //0 : Use internal XTAL Oscillator / 1 : Use External Clock input -#define OFS_RSSI 57 +#define BORDER_FREQ 2600000 /* 2.6GHz : The border frequency which determines whether Low VCO or High VCO is used */ +#define USE_EXT_CLK 0 /* 0 : Use internal XTAL Oscillator / 1 : Use External Clock input */ +#define OFS_RSSI 57 #define FC2580_I2C_ADDR 0xac #define FC2580_CHECK_ADDR 0x01 diff --git a/include/tuner_r82xx.h b/include/tuner_r82xx.h index 49d73d6..ad3638d 100644 --- a/include/tuner_r82xx.h +++ b/include/tuner_r82xx.h @@ -35,11 +35,11 @@ #define R82XX_IF_FREQ 3570000 #define REG_SHADOW_START 5 -#define NUM_REGS 30 -#define NUM_IMR 5 -#define IMR_TRIAL 9 +#define NUM_REGS 30 +#define NUM_IMR 5 +#define IMR_TRIAL 9 -#define VER_NUM 49 +#define VER_NUM 49 enum r82xx_chip { CHIP_R820T, @@ -75,23 +75,21 @@ struct r82xx_config { struct r82xx_priv { struct r82xx_config *cfg; - uint8_t regs[NUM_REGS]; - uint8_t buf[NUM_REGS + 1]; + uint8_t regs[NUM_REGS]; + uint8_t buf[NUM_REGS + 1]; enum r82xx_xtal_cap_value xtal_cap_sel; - uint16_t pll; /* kHz */ - uint32_t int_freq; - uint8_t fil_cal_code; - uint8_t input; - int has_lock; - int init_done; + uint16_t pll; /* kHz */ + uint32_t int_freq; + uint8_t fil_cal_code; + uint8_t input; + int has_lock; + int init_done; /* Store current mode */ - uint32_t delsys; - enum r82xx_tuner_type type; - - uint32_t bw; /* in MHz */ - - void *rtl_dev; + uint32_t delsys; + enum r82xx_tuner_type type; + uint32_t bw; /* in MHz */ + void *rtl_dev; }; struct r82xx_freq_range { diff --git a/src/convenience/convenience.h b/src/convenience/convenience.h index 1faa2af..6d39b65 100644 --- a/src/convenience/convenience.h +++ b/src/convenience/convenience.h @@ -14,6 +14,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#ifndef __CONVENIENCE_H +#define __CONVENIENCE_H + /* a collection of user friendly tools */ @@ -140,3 +143,4 @@ int verbose_reset_buffer(rtlsdr_dev_t *dev); int verbose_device_search(char *s); +#endif /*__CONVENIENCE_H*/ diff --git a/src/librtlsdr.c b/src/librtlsdr.c index ef6c7ba..2187d24 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -366,19 +366,19 @@ static rtlsdr_dongle_t known_devices[] = { #define MIN_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ - 1000) #define MAX_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ + 1000) -#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN) -#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT) +#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN) +#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT) #define CTRL_TIMEOUT 300 #define BULK_TIMEOUT 0 #define EEPROM_ADDR 0xa0 enum usb_reg { - USB_SYSCTL = 0x2000, - USB_CTRL = 0x2010, - USB_STAT = 0x2014, - USB_EPA_CFG = 0x2144, - USB_EPA_CTL = 0x2148, + USB_SYSCTL = 0x2000, + USB_CTRL = 0x2010, + USB_STAT = 0x2014, + USB_EPA_CFG = 0x2144, + USB_EPA_CTL = 0x2148, USB_EPA_MAXPKT = 0x2158, USB_EPA_MAXPKT_2 = 0x215a, USB_EPA_FIFO_CFG = 0x2160, @@ -386,10 +386,10 @@ enum usb_reg { enum sys_reg { DEMOD_CTL = 0x3000, - GPO = 0x3001, - GPI = 0x3002, + GPO = 0x3001, + GPI = 0x3002, GPOE = 0x3003, - GPD = 0x3004, + GPD = 0x3004, SYSINTE = 0x3005, SYSINTS = 0x3006, GP_CFG0 = 0x3007, @@ -406,7 +406,7 @@ enum blocks { SYSB = 2, TUNB = 3, ROMB = 4, - IRB = 5, + IRB = 5, IICB = 6, }; @@ -1056,23 +1056,23 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, int vga_gain) { - int r = 0; + int r = 0; - if (!dev || !dev->tuner) - return -1; + if (!dev || !dev->tuner) + return -1; - if (dev->tuner->set_gain) { - rtlsdr_set_i2c_repeater(dev, 1); - r = r820t_set_gain_ext((void *)dev, lna_gain, mixer_gain, vga_gain); - rtlsdr_set_i2c_repeater(dev, 0); - } + if (dev->tuner->set_gain) { + rtlsdr_set_i2c_repeater(dev, 1); + r = r820t_set_gain_ext((void *)dev, lna_gain, mixer_gain, vga_gain); + rtlsdr_set_i2c_repeater(dev, 0); + } - if (!r) - dev->gain = lna_gain + mixer_gain + vga_gain; - else - dev->gain = 0; + if (!r) + dev->gain = lna_gain + mixer_gain + vga_gain; + else + dev->gain = 0; - return r; + return r; } int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev) diff --git a/src/rtl_adsb.c b/src/rtl_adsb.c index e611e78..2738a9e 100644 --- a/src/rtl_adsb.c +++ b/src/rtl_adsb.c @@ -76,7 +76,7 @@ int quality = 10; int allowed_errors = 5; FILE *file; int adsb_frame[14]; -#define preamble_len 16 +#define preamble_len 16 #define long_frame 112 #define short_frame 56 diff --git a/src/rtl_fm.c b/src/rtl_fm.c index f00f86a..e96c22f 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -80,8 +80,8 @@ #define DEFAULT_BUF_LENGTH (1 * 16384) #define MAXIMUM_OVERSAMPLE 16 #define MAXIMUM_BUF_LENGTH (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH) -#define AUTO_GAIN -100 -#define BUFFER_DUMP 4096 +#define AUTO_GAIN -100 +#define BUFFER_DUMP 4096 #define FREQUENCIES_LIMIT 1000 diff --git a/src/rtl_power.c b/src/rtl_power.c index aa7a138..c395f99 100644 --- a/src/rtl_power.c +++ b/src/rtl_power.c @@ -69,8 +69,8 @@ #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define DEFAULT_BUF_LENGTH (1 * 16384) -#define AUTO_GAIN -100 -#define BUFFER_DUMP (1<<12) +#define AUTO_GAIN -100 +#define BUFFER_DUMP (1<<12) #define MAXIMUM_RATE 2800000 #define MINIMUM_RATE 1000000 diff --git a/src/rtl_test.c b/src/rtl_test.c index 9a6cfda..b3b74ba 100644 --- a/src/rtl_test.c +++ b/src/rtl_test.c @@ -48,7 +48,7 @@ #define MINIMAL_BUF_LENGTH 512 #define MAXIMAL_BUF_LENGTH (256 * 16384) -#define MHZ(x) ((x)*1000*1000) +#define MHZ(x) ((x)*1000*1000) #define PPM_DURATION 10 #define PPM_DUMP_TIME 5 diff --git a/src/tuner_e4k.c b/src/tuner_e4k.c index 400e745..c7c13bc 100644 --- a/src/tuner_e4k.c +++ b/src/tuner_e4k.c @@ -342,7 +342,7 @@ int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter) #define E4K_FVCO_MIN_KHZ 2600000 /* 2.6 GHz */ #define E4K_FVCO_MAX_KHZ 3900000 /* 3.9 GHz */ -#define E4K_PLL_Y 65536 +#define E4K_PLL_Y 65536 #ifdef OUT_OF_SPEC #define E4K_FLO_MIN_MHZ 50 @@ -646,10 +646,10 @@ static const struct reg_field if_stage_gain_regs[] = { static const int32_t lnagain[] = { -50, 0, -25, 1, - 0, 4, - 25, 5, - 50, 6, - 75, 7, + 0, 4, + 25, 5, + 50, 6, + 75, 7, 100, 8, 125, 9, 150, 10, diff --git a/src/tuner_fc0013.c b/src/tuner_fc0013.c index 78b696e..8c4b365 100644 --- a/src/tuner_fc0013.c +++ b/src/tuner_fc0013.c @@ -455,14 +455,14 @@ int fc0013_lna_gains[] ={ -60, 0x07, -58, 0x01, -54, 0x06, - 58, 0x0f, - 61, 0x0e, - 63, 0x0d, - 65, 0x0c, - 67, 0x0b, - 68, 0x0a, - 70, 0x09, - 71, 0x08, + 58, 0x0f, + 61, 0x0e, + 63, 0x0d, + 65, 0x0c, + 67, 0x0b, + 68, 0x0a, + 70, 0x09, + 71, 0x08, 179, 0x17, 181, 0x16, 182, 0x15, diff --git a/src/tuner_fc2580.c b/src/tuner_fc2580.c index d2eeba5..ca233fb 100644 --- a/src/tuner_fc2580.c +++ b/src/tuner_fc2580.c @@ -44,10 +44,7 @@ fc2580_fci_result_type fc2580_i2c_read(void *pTuner, unsigned char reg, unsigned return FC2580_FCI_SUCCESS; } -int -fc2580_Initialize( - void *pTuner - ) +int fc2580_Initialize(void *pTuner) { int AgcMode; unsigned int CrystalFreqKhz; @@ -70,11 +67,7 @@ fc2580_Initialize( return FUNCTION_ERROR; } -int -fc2580_SetRfFreqHz( - void *pTuner, - unsigned long RfFreqHz - ) +int fc2580_SetRfFreqHz(void *pTuner, unsigned long RfFreqHz) { unsigned int RfFreqKhz; unsigned int CrystalFreqKhz; @@ -99,11 +92,7 @@ fc2580_SetRfFreqHz( @brief Set FC2580 tuner bandwidth mode. */ -int -fc2580_SetBandwidthMode( - void *pTuner, - int BandwidthMode - ) +int fc2580_SetBandwidthMode(void *pTuner, int BandwidthMode) { unsigned int CrystalFreqKhz; @@ -143,7 +132,7 @@ void fc2580_wait_msec(void *pTuner, int a) 2 : Voltage Control Mode ==============================================================================*/ -fc2580_fci_result_type fc2580_set_init( void *pTuner, int ifagc_mode, unsigned int freq_xtal ) +fc2580_fci_result_type fc2580_set_init(void *pTuner, int ifagc_mode, unsigned int freq_xtal) { fc2580_fci_result_type result = FC2580_FCI_SUCCESS; @@ -192,14 +181,14 @@ fc2580_fci_result_type fc2580_set_init( void *pTuner, int ifagc_mode, unsigned i ex) 2.6GHz = 2600000 ==============================================================================*/ -fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigned int freq_xtal ) +fc2580_fci_result_type fc2580_set_freq(void *pTuner, unsigned int f_lo, unsigned int freq_xtal) { unsigned int f_diff, f_diff_shifted, n_val, k_val; unsigned int f_vco, r_val, f_comp; unsigned char pre_shift_bits = 4;// number of preshift to prevent overflow in shifting f_diff to f_diff_shifted unsigned char data_0x18; unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E; - + fc2580_band_type band = ( f_lo > 1000000 )? FC2580_L_BAND : ( f_lo > 400000 )? FC2580_UHF_BAND : FC2580_VHF_BAND; fc2580_fci_result_type result = FC2580_FCI_SUCCESS; @@ -208,19 +197,19 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne r_val = ( f_vco >= 2*76*freq_xtal )? 1 : ( f_vco >= 76*freq_xtal )? 2 : 4; f_comp = freq_xtal/r_val; n_val = ( f_vco / 2 ) / f_comp; - + f_diff = f_vco - 2* f_comp * n_val; f_diff_shifted = f_diff << ( 20 - pre_shift_bits ); k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits ); - + if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) ) k_val = k_val + 1; - + if( f_vco >= BORDER_FREQ ) //Select VCO Band data_0x02 = data_0x02 | 0x08; //0x02[3] = 1; else data_0x02 = data_0x02 & 0xF7; //0x02[3] = 0; - + // if( band != curr_band ) { switch(band) { @@ -237,7 +226,7 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne if( f_lo < 538000 ) result &= fc2580_i2c_write(pTuner, 0x5F, 0x13); - else + else result &= fc2580_i2c_write(pTuner, 0x5F, 0x15); if( f_lo < 538000 ) @@ -345,7 +334,7 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne //A command about UHF LNA Load Cap if( band == FC2580_UHF_BAND ) result &= fc2580_i2c_write(pTuner, 0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F ); //LNA_OUT_CAP - + return result; } @@ -366,10 +355,10 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne 6 : 6MHz (Bandwidth 6MHz) 7 : 6.8MHz (Bandwidth 7MHz) 8 : 7.8MHz (Bandwidth 8MHz) - + ==============================================================================*/ -fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, unsigned int freq_xtal ) +fc2580_fci_result_type fc2580_set_filter(void *pTuner, unsigned char filter_bw, unsigned int freq_xtal) { unsigned char cal_mon = 0, i; fc2580_fci_result_type result = FC2580_FCI_SUCCESS; @@ -403,7 +392,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); } - + for(i=0; i<5; i++) { fc2580_wait_msec(pTuner, 5);//wait 5ms @@ -426,7 +415,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, fc2580 RSSI function This function is a generic function which returns fc2580's - + current RSSI value. @@ -438,7 +427,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, ==============================================================================*/ //int fc2580_get_rssi(void) { -// +// // unsigned char s_lna, s_rfvga, s_cfs, s_ifvga; // int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi; // @@ -446,9 +435,9 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, // fc2580_i2c_read(0x72, &s_rfvga ); // fc2580_i2c_read(0x73, &s_cfs ); // fc2580_i2c_read(0x74, &s_ifvga ); -// // -// ofs_lna = +// +// ofs_lna = // (curr_band==FC2580_UHF_BAND)? // (s_lna==0)? 0 : // (s_lna==1)? -6 : @@ -470,18 +459,18 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, // ofs_ifvga = s_ifvga/4; // // return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI; -// +// //} /*============================================================================== fc2580 Xtal frequency Setting - This function is a generic function which sets - + This function is a generic function which sets + the frequency of xtal. - + - + frequency frequency value of internal(external) Xtal(clock) in kHz unit. diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c index eb62352..3a25c34 100644 --- a/src/tuner_r82xx.c +++ b/src/tuner_r82xx.c @@ -39,7 +39,7 @@ /* Those initial values start from REG_SHADOW_START */ static const uint8_t r82xx_init_array[NUM_REGS] = { - 0x83, 0x32, 0x75, /* 05 to 07 */ + 0x83, 0x32, 0x75, /* 05 to 07 */ 0xc0, 0x40, 0xd6, 0x6c, /* 08 to 0b */ 0xf5, 0x63, 0x75, 0x68, /* 0c to 0f */ 0x6c, 0x83, 0x80, 0x00, /* 10 to 13 */ @@ -51,173 +51,173 @@ static const uint8_t r82xx_init_array[NUM_REGS] = { /* Tuner frequency ranges */ static const struct r82xx_freq_range freq_ranges[] = { { - /* .freq = */ 0, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 0, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0xdf, /* R27[7:0] band2,band0 */ + /* .tf_c = */ 0xdf, /* R27[7:0] band2,band0 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 50, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 50, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0xbe, /* R27[7:0] band4,band1 */ + /* .tf_c = */ 0xbe, /* R27[7:0] band4,band1 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 55, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 55, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x8b, /* R27[7:0] band7,band4 */ + /* .tf_c = */ 0x8b, /* R27[7:0] band7,band4 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 60, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 60, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x7b, /* R27[7:0] band8,band4 */ + /* .tf_c = */ 0x7b, /* R27[7:0] band8,band4 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 65, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 65, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x69, /* R27[7:0] band9,band6 */ + /* .tf_c = */ 0x69, /* R27[7:0] band9,band6 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 70, /* Start freq, in MHz */ - /* .open_d = */ 0x08, /* low */ + /* .freq = */ 70, /* Start freq, in MHz */ + /* .open_d = */ 0x08, /* low */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x58, /* R27[7:0] band10,band7 */ + /* .tf_c = */ 0x58, /* R27[7:0] band10,band7 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 75, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 75, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */ + /* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 80, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 80, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */ + /* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */ /* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 90, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 90, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */ + /* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */ /* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 100, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 100, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */ + /* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */ /* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 110, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 110, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */ + /* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */ /* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 120, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 120, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */ + /* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */ /* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 140, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 140, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x14, /* R27[7:0] band14,band11 */ + /* .tf_c = */ 0x14, /* R27[7:0] band14,band11 */ /* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */ /* .xtal_cap10p = */ 0x01, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 180, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 180, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */ + /* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 220, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 220, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */ + /* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 250, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 250, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x11, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x11, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 280, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 280, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */ - /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 310, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 310, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */ - /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 450, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 450, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */ - /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 588, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 588, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */ - /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, }, { - /* .freq = */ 650, /* Start freq, in MHz */ - /* .open_d = */ 0x00, /* high */ + /* .freq = */ 650, /* Start freq, in MHz */ + /* .open_d = */ 0x00, /* high */ /* .rf_mux_ploy = */ 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */ - /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ + /* .tf_c = */ 0x00, /* R27[7:0] highest,highest */ /* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */ /* .xtal_cap10p = */ 0x00, - /* .xtal_cap0p = */ 0x00, + /* .xtal_cap0p = */ 0x00, } }; From cee5d10200d84b40fe3bdb029c76270911b98a06 Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Sun, 6 Mar 2016 14:22:00 -0600 Subject: [PATCH 37/74] remove circle ci file --- circle.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 circle.yml diff --git a/circle.yml b/circle.yml deleted file mode 100644 index b55d711..0000000 --- a/circle.yml +++ /dev/null @@ -1,8 +0,0 @@ -dependencies: - pre: - - sudo apt-get update; sudo apt-get install libusb-1.0-0-dev; - override: - - cd ~/; git clone https://github.com/librtlsdr/librtlsdr.git; cd librtlsdr; mkdir build; cd build; cmake ../; make; sudo make install; sudo ldconfig; -test: - override: - - echo "----- done -----"; From ba43a14e9238ccd59adc85c894e5aea7e0d694b4 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 6 Mar 2016 01:09:59 -0300 Subject: [PATCH 38/74] Updates on rtl_tcp * Added Bandwidth Parameter (-w) to rtl_tcp to set the device bandwidth through cmd args * Added Bandwidth Network Parameter (0x0E) to rtl_tcp to set the device bandwidth through network * Added RTL_TCP_COMMANDS enum to better organize the network commands * Added binary files to gitignore --- .gitignore | 9 +++++++++ include/rtl-sdr.h | 1 + include/rtl_tcp.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/rtl_tcp.c | 46 ++++++++++++++++++++++++++++-------------- 4 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 include/rtl_tcp.h diff --git a/.gitignore b/.gitignore index d22084c..84e02eb 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,13 @@ CMakeFiles *.cmake build +**/*.o +**/*.so* +**/*.a +src/rtl_adsb +src/rtl_eeprom +src/rtl_fm +src/rtl_power +src/rtl_test + debianize/*.deb diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 38ae207..0f90caf 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -26,6 +26,7 @@ extern "C" { #include #include +#include typedef struct rtlsdr_dev rtlsdr_dev_t; diff --git a/include/rtl_tcp.h b/include/rtl_tcp.h new file mode 100644 index 0000000..fb8d613 --- /dev/null +++ b/include/rtl_tcp.h @@ -0,0 +1,51 @@ +/* + * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver + * Copyright (C) 2012-2013 by Steve Markgraf + * Copyright (C) 2012 by Dimitri Stolnikov + * + * 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 . + */ + +#ifndef __RTL_TCP_H +#define __RTL_TCP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * This enum defines the possible commands in rtl_tcp + */ +enum RTL_TCP_COMMANDS { + SET_FREQUENCY = 0x01, + SET_SAMPLE_RATE = 0x02, + SET_GAIN_MODE = 0x03, + SET_GAIN = 0x04, + SET_FREQUENCY_CORRECTION = 0x05, + SET_IF_STAGE = 0x06, + SET_TEST_MODE = 0x07, + SET_AGC_MODE = 0x08, + SET_DIRECT_SAMPLING = 0x09, + SET_OFFSET_TUNING = 0x0A, + SET_RTL_CRYSTAL = 0x0B, + SET_TUNER_CRYSTAL = 0x0C, + SET_TUNER_GAIN_BY_INDEX = 0x0D, + SET_TUNER_BANDWIDTH = 0x0E +}; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index 317e0f3..9f17bd8 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -94,6 +94,7 @@ void usage(void) "\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[-w rtlsdr device bandwidth (for R820T device)\n" "\t[-d device index (default: 0)]\n" "\t[-P ppm_error (default: 0)]\n"); exit(1); @@ -302,59 +303,63 @@ static void *command_worker(void *arg) } } switch(cmd.cmd) { - case 0x01: + case SET_FREQUENCY: printf("set freq %d\n", ntohl(cmd.param)); rtlsdr_set_center_freq(dev,ntohl(cmd.param)); break; - case 0x02: + case SET_SAMPLE_RATE: printf("set sample rate %d\n", ntohl(cmd.param)); rtlsdr_set_sample_rate(dev, ntohl(cmd.param)); break; - case 0x03: + case SET_GAIN_MODE: printf("set gain mode %d\n", ntohl(cmd.param)); rtlsdr_set_tuner_gain_mode(dev, ntohl(cmd.param)); break; - case 0x04: + case SET_GAIN: printf("set gain %d\n", ntohl(cmd.param)); rtlsdr_set_tuner_gain(dev, ntohl(cmd.param)); break; - case 0x05: + case SET_FREQUENCY_CORRECTION: printf("set freq correction %d\n", ntohl(cmd.param)); rtlsdr_set_freq_correction(dev, ntohl(cmd.param)); break; - case 0x06: + case SET_IF_STAGE: tmp = ntohl(cmd.param); printf("set if stage %d gain %d\n", tmp >> 16, (short)(tmp & 0xffff)); rtlsdr_set_tuner_if_gain(dev, tmp >> 16, (short)(tmp & 0xffff)); break; - case 0x07: + case SET_TEST_MODE: printf("set test mode %d\n", ntohl(cmd.param)); rtlsdr_set_testmode(dev, ntohl(cmd.param)); break; - case 0x08: + case SET_AGC_MODE: printf("set agc mode %d\n", ntohl(cmd.param)); rtlsdr_set_agc_mode(dev, ntohl(cmd.param)); break; - case 0x09: + case SET_DIRECT_SAMPLING: printf("set direct sampling %d\n", ntohl(cmd.param)); rtlsdr_set_direct_sampling(dev, ntohl(cmd.param)); break; - case 0x0a: + case SET_OFFSET_TUNING: printf("set offset tuning %d\n", ntohl(cmd.param)); rtlsdr_set_offset_tuning(dev, ntohl(cmd.param)); break; - case 0x0b: + case SET_RTL_CRYSTAL: printf("set rtl xtal %d\n", ntohl(cmd.param)); rtlsdr_set_xtal_freq(dev, ntohl(cmd.param), 0); break; - case 0x0c: + case SET_TUNER_CRYSTAL: printf("set tuner xtal %d\n", ntohl(cmd.param)); rtlsdr_set_xtal_freq(dev, 0, ntohl(cmd.param)); break; - case 0x0d: + case SET_TUNER_GAIN_BY_INDEX: printf("set tuner gain by index %d\n", ntohl(cmd.param)); set_gain_by_index(dev, ntohl(cmd.param)); break; + case SET_TUNER_BANDWIDTH: + printf("set tuner bandwidth to %i\n", ntohl(cmd.param)); + rtlsdr_set_tuner_bandwidth(dev, ntohl(cmd.param)); + break; default: break; } @@ -367,7 +372,7 @@ 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; + uint32_t frequency = 100000000, samp_rate = 2048000, bandwidth = 0; struct sockaddr_in local, remote; uint32_t buf_num = 0; int dev_index = 0; @@ -391,7 +396,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:w:")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); @@ -420,6 +425,9 @@ int main(int argc, char **argv) break; case 'P': ppm_error = atoi(optarg); + break; + case 'w': + bandwidth = (uint32_t)atofs(optarg); break; default: usage(); @@ -491,6 +499,14 @@ int main(int argc, char **argv) fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0); } + r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); + if (r < 0) + fprintf(stderr, "WARNING: Failed to set tuner bandwidth.\n"); + else if (bandwidth != 0) + fprintf(stderr, "Tuner bandwidth set to %i.\n", bandwidth); + else + fprintf(stderr, "Tuner bandwidth set to automatic.\n"); + /* Reset endpoint before we start reading from it (mandatory) */ r = rtlsdr_reset_buffer(dev); if (r < 0) From 9a2c4748f26e18062ff57cf3192fbf83c24cde33 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 6 Mar 2016 01:20:39 -0300 Subject: [PATCH 39/74] Device Bandwidth to Convenience and rtl_fm * Added Device Bandwidth to Convenience * Added Device Bandwidth to rtl_fm (-w option) --- src/convenience/convenience.c | 14 ++++++++++++++ src/convenience/convenience.h | 11 +++++++++++ src/rtl_fm.c | 11 +++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/convenience/convenience.c b/src/convenience/convenience.c index 517dc4e..b4d7b4f 100644 --- a/src/convenience/convenience.c +++ b/src/convenience/convenience.c @@ -160,6 +160,20 @@ int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) return r; } +int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth) +{ + int r; + r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); + if (r < 0) { + fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); + } else if (bandwidth > 0) { + fprintf(stderr, "Bandwidth set to %u Hz.\n", bandwidth); + } else { + fprintf(stderr, "Bandwidth set to automatic.\n"); + } + return r; +} + int verbose_direct_sampling(rtlsdr_dev_t *dev, int on) { int r; diff --git a/src/convenience/convenience.h b/src/convenience/convenience.h index 6d39b65..d3b46dc 100644 --- a/src/convenience/convenience.h +++ b/src/convenience/convenience.h @@ -77,6 +77,17 @@ int verbose_set_frequency(rtlsdr_dev_t *dev, uint32_t frequency); int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate); +/*! + * Set device bandwidth and report status on stderr + * + * \param dev the device handle given by rtlsdr_open() + * \param frequency in Hz + * \return 0 on success + */ + +int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth); + + /*! * Enable or disable the direct sampling mode and report status on stderr * diff --git a/src/rtl_fm.c b/src/rtl_fm.c index e96c22f..e7153a7 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -108,6 +108,7 @@ struct dongle_state int dev_index; uint32_t freq; uint32_t rate; + uint32_t bandwidth; int gain; int16_t buf16[MAXIMUM_BUF_LENGTH]; uint32_t buf_len; @@ -203,7 +204,8 @@ 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[-g tuner_gain (default: automatic)]\n" + "\t[-g tuner_gain (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" "\t output are comma separated values (csv):\n" @@ -1160,7 +1162,7 @@ int main(int argc, char **argv) output_init(&output); controller_init(&controller); - while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:v:h")) != -1) { + while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:v:h:w:")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -1274,6 +1276,9 @@ int main(int argc, char **argv) case 'v': verbosity = (int)atof(optarg); break; + case 'w': + dongle.bandwidth = (uint32_t)atofs(optarg); + break; case 'h': default: usage(); @@ -1342,6 +1347,8 @@ int main(int argc, char **argv) verbose_ppm_set(dongle.dev, dongle.ppm_error); + verbose_set_bandwidth(dongle.dev, dongle.bandwidth); + if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */ output.file = stdout; #ifdef _WIN32 From aebbb9a16f981d789bddef1c8460c4b84f8f5f66 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sun, 6 Mar 2016 01:24:26 -0300 Subject: [PATCH 40/74] Added "Hz" in bandwidth set message. --- src/rtl_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index 9f17bd8..bf0e3ea 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -357,7 +357,7 @@ static void *command_worker(void *arg) set_gain_by_index(dev, ntohl(cmd.param)); break; case SET_TUNER_BANDWIDTH: - printf("set tuner bandwidth to %i\n", ntohl(cmd.param)); + printf("set tuner bandwidth to %i Hz\n", ntohl(cmd.param)); rtlsdr_set_tuner_bandwidth(dev, ntohl(cmd.param)); break; default: From 32b051bba3c0452e8f96e43fdc218213e6987ce8 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sat, 12 Mar 2016 19:00:39 -0300 Subject: [PATCH 41/74] Added default bandwidth to list --- src/rtl_fm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index e7153a7..6005e1a 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -1056,6 +1056,7 @@ void dongle_init(struct dongle_state *s) s->direct_sampling = 0; s->offset_tuning = 0; s->demod_target = &demod; + s->bandwidth = 0; } void demod_init(struct demod_state *s) From af20337c93ec04576011039ae1442ff83bfd0a87 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sat, 12 Mar 2016 04:05:48 +0100 Subject: [PATCH 42/74] added rtlsdr_set_and_get_tuner_bandwidth() to RTLSDR_API this allows to return the configured/applied bandwidth to the caller this also allows pre-determining all possible bandwidth values (with apply_bw=0) see rtl_fm with verbose flag, when using -w option API does only work for R820T tuner. other tuner always return 0 (=unknown) bandwidth Signed-off-by: Lucas Teske --- include/rtl-sdr.h | 7 ++++- include/tuner_r82xx.h | 2 +- src/convenience/convenience.c | 8 ++++-- src/librtlsdr.c | 52 +++++++++++++++++++++++++++-------- src/rtl_fm.c | 16 ++++++++++- src/tuner_r82xx.c | 35 ++++++++++++++++------- 6 files changed, 92 insertions(+), 28 deletions(-) mode change 100644 => 100755 include/rtl-sdr.h mode change 100644 => 100755 include/tuner_r82xx.h mode change 100644 => 100755 src/convenience/convenience.c mode change 100644 => 100755 src/librtlsdr.c mode change 100644 => 100755 src/rtl_fm.c mode change 100644 => 100755 src/tuner_r82xx.c diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h old mode 100644 new mode 100755 index 0f90caf..384caa9 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -221,9 +221,14 @@ RTLSDR_API int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain); * * \param dev the device handle given by rtlsdr_open() * \param bw bandwidth in Hz. Zero means automatic BW selection. + * \param applied_bw is applied bandwidth in Hz, or 0 if unknown + * \param apply_bw: 1 to really apply configure the tuner chip; 0 for just returning applied_bw * \return 0 on success */ -RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw); +RTLSDR_API int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t *applied_bw, int apply_bw ); + +RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw ); + /*! * Get actual gain the device is configured to. diff --git a/include/tuner_r82xx.h b/include/tuner_r82xx.h old mode 100644 new mode 100755 index ad3638d..a940731 --- a/include/tuner_r82xx.h +++ b/include/tuner_r82xx.h @@ -115,6 +115,6 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq); //int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain); int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, int extended_mode, int lna_gain, int mixer_gain, int vga_gain); -int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate); +int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate, uint32_t * applied_bw, int apply); #endif diff --git a/src/convenience/convenience.c b/src/convenience/convenience.c old mode 100644 new mode 100755 index b4d7b4f..fb6ac3b --- a/src/convenience/convenience.c +++ b/src/convenience/convenience.c @@ -163,13 +163,15 @@ int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth) { int r; - r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); + uint32_t applied_bw = 0; + /* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */ + r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */); if (r < 0) { fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); } else if (bandwidth > 0) { - fprintf(stderr, "Bandwidth set to %u Hz.\n", bandwidth); + fprintf(stderr, "Bandwidth set to %u Hz resulted in %u Hz.\n", bandwidth, applied_bw); } else { - fprintf(stderr, "Bandwidth set to automatic.\n"); + fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw); } return r; } diff --git a/src/librtlsdr.c b/src/librtlsdr.c old mode 100644 new mode 100755 index 2187d24..f9cdedb --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -60,7 +60,7 @@ typedef struct rtlsdr_tuner_iface { int (*init)(void *); int (*exit)(void *); int (*set_freq)(void *, uint32_t freq /* Hz */); - int (*set_bw)(void *, int bw /* Hz */); + int (*set_bw)(void *, int bw /* Hz */, uint32_t *applied_bw /* configured bw in Hz */, int apply /* 1 == configure it!, 0 == deliver applied_bw */); int (*set_gain)(void *, int gain /* tenth dB */); int (*set_if_gain)(void *, int stage, int gain /* tenth dB */); int (*set_gain_mode)(void *, int manual); @@ -146,9 +146,11 @@ int e4000_set_freq(void *dev, uint32_t freq) { return e4k_tune_freq(&devt->e4k_s, freq); } -int e4000_set_bw(void *dev, int bw) { +int e4000_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { int r = 0; rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; + if(!apply) + return 0; r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_MIX, bw); r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_RC, bw); @@ -190,7 +192,7 @@ int fc0012_set_freq(void *dev, uint32_t freq) { rtlsdr_set_gpio_bit(dev, 6, (freq > 300000000) ? 1 : 0); return fc0012_set_params(dev, freq, 6000000); } -int fc0012_set_bw(void *dev, int bw) { return 0; } +int fc0012_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { return 0; } int _fc0012_set_gain(void *dev, int gain) { return fc0012_set_gain(dev, gain); } int fc0012_set_gain_mode(void *dev, int manual) { return 0; } @@ -199,7 +201,7 @@ int fc0013_exit(void *dev) { return 0; } int fc0013_set_freq(void *dev, uint32_t freq) { return fc0013_set_params(dev, freq, 6000000); } -int fc0013_set_bw(void *dev, int bw) { return 0; } +int fc0013_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { return 0; } int _fc0013_set_gain(void *dev, int gain) { return fc0013_set_lna_gain(dev, gain); } int fc2580_init(void *dev) { return fc2580_Initialize(dev); } @@ -207,7 +209,11 @@ int fc2580_exit(void *dev) { return 0; } int _fc2580_set_freq(void *dev, uint32_t freq) { return fc2580_SetRfFreqHz(dev, freq); } -int fc2580_set_bw(void *dev, int bw) { return fc2580_SetBandwidthMode(dev, 1); } +int fc2580_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { + if(!apply) + return 0; + return fc2580_SetBandwidthMode(dev, 1); +} int fc2580_set_gain(void *dev, int gain) { return 0; } int fc2580_set_gain_mode(void *dev, int manual) { return 0; } @@ -241,12 +247,14 @@ int r820t_set_freq(void *dev, uint32_t freq) { return r82xx_set_freq(&devt->r82xx_p, freq); } -int r820t_set_bw(void *dev, int bw) { +int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { int r; rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate); - if(r < 0) + r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate, applied_bw, apply); + if(!apply) + return 0; + if(r < 0) return r; r = rtlsdr_set_if_freq(devt, r); if (r) @@ -1015,16 +1023,26 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) } } -int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw) +int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t *applied_bw, int apply_bw ) { int r = 0; + *applied_bw = 0; /* unknown */ + if (!dev || !dev->tuner) return -1; + if(!apply_bw) + { + if (dev->tuner->set_bw) { + r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); + } + return r; + } + if (dev->tuner->set_bw) { rtlsdr_set_i2c_repeater(dev, 1); - r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate); + r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); rtlsdr_set_i2c_repeater(dev, 0); if (r) return r; @@ -1033,6 +1051,14 @@ int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw) return r; } +int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw ) +{ + uint32_t applied_bw = 0; + return rtlsdr_set_and_get_tuner_bandwidth(dev, bw, &applied_bw, 1 /* =apply_bw */ ); +} + + + int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) { int r = 0; @@ -1144,8 +1170,9 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) dev->rate = (uint32_t)real_rate; if (dev->tuner && dev->tuner->set_bw) { + uint32_t applied_bw = 0; rtlsdr_set_i2c_repeater(dev, 1); - dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate); + dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate, &applied_bw, 1); rtlsdr_set_i2c_repeater(dev, 0); } @@ -1282,6 +1309,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) r |= rtlsdr_set_if_freq(dev, dev->offs_freq); if (dev->tuner && dev->tuner->set_bw) { + uint32_t applied_bw = 0; rtlsdr_set_i2c_repeater(dev, 1); if (on) { bw = 2 * dev->offs_freq; @@ -1290,7 +1318,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) } else { bw = dev->rate; } - dev->tuner->set_bw(dev, bw); + dev->tuner->set_bw(dev, bw, &applied_bw, 1); rtlsdr_set_i2c_repeater(dev, 0); } diff --git a/src/rtl_fm.c b/src/rtl_fm.c old mode 100644 new mode 100755 index 6005e1a..1091555 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -1348,7 +1348,21 @@ int main(int argc, char **argv) verbose_ppm_set(dongle.dev, dongle.ppm_error); - verbose_set_bandwidth(dongle.dev, dongle.bandwidth); + verbose_set_bandwidth(dongle.dev, dongle.bandwidth); + + if (verbosity && dongle.bandwidth) + { + int r; + uint32_t in_bw, out_bw, last_bw = 0; + for ( in_bw = 1; in_bw < 3200; ++in_bw ) + { + r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); + if ( r == 0 && ( out_bw != last_bw || in_bw == 1 ) ) + fprintf(stderr, "device sets bandwidth %u Hz for bw para >= %u kHz\n", out_bw, in_bw ); + last_bw = out_bw; + } + fprintf(stderr,"\n"); + } if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */ output.file = stdout; diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c old mode 100644 new mode 100755 index 3a25c34..f6c1694 --- a/src/tuner_r82xx.c +++ b/src/tuner_r82xx.c @@ -1187,7 +1187,7 @@ static const int r82xx_if_low_pass_bw_table[] = { #define FILT_HP_BW1 350000 #define FILT_HP_BW2 380000 -int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate) +int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate, uint32_t * applied_bw, int apply) { int rc; unsigned int i; @@ -1197,27 +1197,35 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate) if (bw > 7000000) { // BW: 8 MHz + *applied_bw = 8000000; reg_0a = 0x10; reg_0b = 0x0b; - priv->int_freq = 4570000; + if (apply) + priv->int_freq = 4570000; } else if (bw > 6000000) { // BW: 7 MHz - reg_0a = 0x10; + *applied_bw = 7000000; + reg_0a = 0x10; reg_0b = 0x2a; - priv->int_freq = 4570000; + if (apply) + priv->int_freq = 4570000; } else if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1 + FILT_HP_BW2) { // BW: 6 MHz - reg_0a = 0x10; + *applied_bw = 6000000; + reg_0a = 0x10; reg_0b = 0x6b; - priv->int_freq = 3570000; + if (apply) + priv->int_freq = 3570000; } else { reg_0a = 0x00; reg_0b = 0x80; - priv->int_freq = 2300000; + if (apply) + priv->int_freq = 2300000; if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1) { bw -= FILT_HP_BW2; - priv->int_freq += FILT_HP_BW2; + if (apply) + priv->int_freq += FILT_HP_BW2; real_bw += FILT_HP_BW2; } else { reg_0b |= 0x20; @@ -1225,7 +1233,8 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate) if (bw > r82xx_if_low_pass_bw_table[0]) { bw -= FILT_HP_BW1; - priv->int_freq += FILT_HP_BW1; + if (apply) + priv->int_freq += FILT_HP_BW1; real_bw += FILT_HP_BW1; } else { reg_0b |= 0x40; @@ -1240,9 +1249,15 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate) reg_0b |= 15 - i; real_bw += r82xx_if_low_pass_bw_table[i]; - priv->int_freq -= real_bw / 2; + *applied_bw = real_bw; + + if (apply) + priv->int_freq -= real_bw / 2; } + if (!apply) + return 0; + rc = r82xx_write_reg_mask(priv, 0x0a, reg_0a, 0x10); if (rc < 0) return rc; From 6f1660dd8b5dbc86fd54ec59a6d3bccbe0256b3e Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sat, 12 Mar 2016 19:11:59 -0300 Subject: [PATCH 43/74] Fixes for identation --- src/librtlsdr.c | 141 +++++++++++++++---------------- src/rtl_fm.c | 204 ++++++++++++++++++++++----------------------- src/tuner_r82xx.c | 206 +++++++++++++++++++++++----------------------- 3 files changed, 277 insertions(+), 274 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index f9cdedb..8c27006 100755 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -10,11 +10,11 @@ * * 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 + * 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 . + * along with this program. If not, see . */ #include @@ -60,7 +60,7 @@ typedef struct rtlsdr_tuner_iface { int (*init)(void *); int (*exit)(void *); int (*set_freq)(void *, uint32_t freq /* Hz */); - int (*set_bw)(void *, int bw /* Hz */, uint32_t *applied_bw /* configured bw in Hz */, int apply /* 1 == configure it!, 0 == deliver applied_bw */); + int (*set_bw)(void *, int bw /* Hz */, uint32_t *applied_bw /* configured bw in Hz */, int apply /* 1 == configure it!, 0 == deliver applied_bw */); int (*set_gain)(void *, int gain /* tenth dB */); int (*set_if_gain)(void *, int stage, int gain /* tenth dB */); int (*set_gain_mode)(void *, int manual); @@ -149,8 +149,8 @@ int e4000_set_freq(void *dev, uint32_t freq) { int e4000_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { int r = 0; rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - if(!apply) - return 0; + if(!apply) + return 0; r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_MIX, bw); r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_RC, bw); @@ -210,9 +210,9 @@ int _fc2580_set_freq(void *dev, uint32_t freq) { return fc2580_SetRfFreqHz(dev, freq); } int fc2580_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { - if(!apply) - return 0; - return fc2580_SetBandwidthMode(dev, 1); + if(!apply) + return 0; + return fc2580_SetBandwidthMode(dev, 1); } int fc2580_set_gain(void *dev, int gain) { return 0; } int fc2580_set_gain_mode(void *dev, int manual) { return 0; } @@ -251,11 +251,12 @@ int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { int r; rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate, applied_bw, apply); - if(!apply) - return 0; - if(r < 0) - return r; + r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate, applied_bw, apply); + if(!apply) + return 0; + if(r < 0) + return r; + r = rtlsdr_set_if_freq(devt, r); if (r) return r; @@ -263,18 +264,18 @@ int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { } int r820t_set_gain(void *dev, int gain) { - rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - return r82xx_set_gain(&devt->r82xx_p, 1, gain, 0, 0, 0, 0); + rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; + return r82xx_set_gain(&devt->r82xx_p, 1, gain, 0, 0, 0, 0); } int r820t_set_gain_ext(void *dev, int lna_gain, int mixer_gain, int vga_gain) { - rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - return r82xx_set_gain(&devt->r82xx_p, 0, 0, 1, lna_gain, mixer_gain, vga_gain); + rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; + return r82xx_set_gain(&devt->r82xx_p, 0, 0, 1, lna_gain, mixer_gain, vga_gain); } int r820t_set_gain_mode(void *dev, int manual) { rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev; - return r82xx_set_gain(&devt->r82xx_p, manual, 0, 0, 0, 0, 0); + return r82xx_set_gain(&devt->r82xx_p, manual, 0, 0, 0, 0, 0); } /* definition order must match enum rtlsdr_tuner */ @@ -647,7 +648,7 @@ void rtlsdr_init_baseband(rtlsdr_dev_t *dev) rtlsdr_demod_write_reg(dev, 1, 0x15, 0x00, 1); rtlsdr_demod_write_reg(dev, 1, 0x16, 0x0000, 2); - /* clear both DDC shift and IF frequency registers */ + /* clear both DDC shift and IF frequency registers */ for (i = 0; i < 6; i++) rtlsdr_demod_write_reg(dev, 1, 0x16 + i, 0x00, 1); @@ -766,7 +767,7 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr /* read corrected clock value into e4k and r82xx structure */ if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc) || - rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal)) + rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal)) return -3; /* update xtal-dependent settings */ @@ -794,7 +795,7 @@ int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_ } int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, - char *serial) + char *serial) { struct libusb_device_descriptor dd; libusb_device *device = NULL; @@ -813,22 +814,22 @@ int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, if (manufact) { memset(manufact, 0, buf_max); libusb_get_string_descriptor_ascii(dev->devh, dd.iManufacturer, - (unsigned char *)manufact, - buf_max); + (unsigned char *)manufact, + buf_max); } if (product) { memset(product, 0, buf_max); libusb_get_string_descriptor_ascii(dev->devh, dd.iProduct, - (unsigned char *)product, - buf_max); + (unsigned char *)product, + buf_max); } if (serial) { memset(serial, 0, buf_max); libusb_get_string_descriptor_ascii(dev->devh, dd.iSerialNumber, - (unsigned char *)serial, - buf_max); + (unsigned char *)serial, + buf_max); } return 0; @@ -944,7 +945,7 @@ int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) /* read corrected clock value into e4k and r82xx structure */ if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc) || - rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal)) + rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal)) return -3; if (dev->freq) /* retune to apply new correction value */ @@ -973,16 +974,16 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) { /* all gain values are expressed in tenths of a dB */ const int e4k_gains[] = { -10, 15, 40, 65, 90, 115, 140, 165, 190, 215, - 240, 290, 340, 420 }; + 240, 290, 340, 420 }; const int fc0012_gains[] = { -99, -40, 71, 179, 192 }; const int fc0013_gains[] = { -99, -73, -65, -63, -60, -58, -54, 58, 61, - 63, 65, 67, 68, 70, 71, 179, 181, 182, - 184, 186, 188, 191, 197 }; + 63, 65, 67, 68, 70, 71, 179, 181, 182, + 184, 186, 188, 191, 197 }; const int fc2580_gains[] = { 0 /* no gain values */ }; const int r82xx_gains[] = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, - 166, 197, 207, 229, 254, 280, 297, 328, - 338, 364, 372, 386, 402, 421, 434, 439, - 445, 480, 496 }; + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496 }; const int unknown_gains[] = { 0 /* no gain values */ }; const int *ptr = NULL; @@ -1027,22 +1028,22 @@ int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t { int r = 0; - *applied_bw = 0; /* unknown */ + *applied_bw = 0; /* unknown */ if (!dev || !dev->tuner) return -1; - if(!apply_bw) - { - if (dev->tuner->set_bw) { - r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); - } - return r; - } + if(!apply_bw) + { + if (dev->tuner->set_bw) { + r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); + } + return r; + } if (dev->tuner->set_bw) { rtlsdr_set_i2c_repeater(dev, 1); - r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); + r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw); rtlsdr_set_i2c_repeater(dev, 0); if (r) return r; @@ -1053,8 +1054,8 @@ int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw ) { - uint32_t applied_bw = 0; - return rtlsdr_set_and_get_tuner_bandwidth(dev, bw, &applied_bw, 1 /* =apply_bw */ ); + uint32_t applied_bw = 0; + return rtlsdr_set_and_get_tuner_bandwidth(dev, bw, &applied_bw, 1 /* =apply_bw */ ); } @@ -1153,7 +1154,7 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) /* check if the rate is supported by the resampler */ if ((samp_rate <= 225000) || (samp_rate > 3200000) || - ((samp_rate > 300000) && (samp_rate <= 900000))) { + ((samp_rate > 300000) && (samp_rate <= 900000))) { fprintf(stderr, "Invalid sample rate: %u Hz\n", samp_rate); return -EINVAL; } @@ -1170,9 +1171,9 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) dev->rate = (uint32_t)real_rate; if (dev->tuner && dev->tuner->set_bw) { - uint32_t applied_bw = 0; + uint32_t applied_bw = 0; rtlsdr_set_i2c_repeater(dev, 1); - dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate, &applied_bw, 1); + dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate, &applied_bw, 1); rtlsdr_set_i2c_repeater(dev, 0); } @@ -1254,7 +1255,7 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) } if ((dev->tuner_type == RTLSDR_TUNER_R820T) || - (dev->tuner_type == RTLSDR_TUNER_R828D)) { + (dev->tuner_type == RTLSDR_TUNER_R828D)) { r |= rtlsdr_set_if_freq(dev, R82XX_IF_FREQ); /* enable spectrum inversion */ @@ -1298,7 +1299,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) return -1; if ((dev->tuner_type == RTLSDR_TUNER_R820T) || - (dev->tuner_type == RTLSDR_TUNER_R828D)) + (dev->tuner_type == RTLSDR_TUNER_R828D)) return -2; if (dev->direct_sampling) @@ -1309,7 +1310,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) r |= rtlsdr_set_if_freq(dev, dev->offs_freq); if (dev->tuner && dev->tuner->set_bw) { - uint32_t applied_bw = 0; + uint32_t applied_bw = 0; rtlsdr_set_i2c_repeater(dev, 1); if (on) { bw = 2 * dev->offs_freq; @@ -1318,7 +1319,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) } else { bw = dev->rate; } - dev->tuner->set_bw(dev, bw, &applied_bw, 1); + dev->tuner->set_bw(dev, bw, &applied_bw, 1); rtlsdr_set_i2c_repeater(dev, 0); } @@ -1420,7 +1421,7 @@ const char *rtlsdr_get_device_name(uint32_t index) } int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, - char *product, char *serial) + char *product, char *serial) { int r = -2; int i; @@ -1450,9 +1451,9 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, r = libusb_open(list[i], &devt.devh); if (!r) { r = rtlsdr_get_usb_strings(&devt, - manufact, - product, - serial); + manufact, + product, + serial); libusb_close(devt.devh); } break; @@ -1762,7 +1763,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) dev->xfer_errors++; if (dev->xfer_errors >= dev->xfer_buf_num || - LIBUSB_TRANSFER_NO_DEVICE == xfer->status) { + LIBUSB_TRANSFER_NO_DEVICE == xfer->status) { #endif dev->dev_lost = 1; rtlsdr_cancel_async(dev); @@ -1788,7 +1789,7 @@ static int _rtlsdr_alloc_async_buffers(rtlsdr_dev_t *dev) if (!dev->xfer) { dev->xfer = malloc(dev->xfer_buf_num * - sizeof(struct libusb_transfer *)); + sizeof(struct libusb_transfer *)); for(i = 0; i < dev->xfer_buf_num; ++i) dev->xfer[i] = libusb_alloc_transfer(0); @@ -1796,7 +1797,7 @@ static int _rtlsdr_alloc_async_buffers(rtlsdr_dev_t *dev) if (!dev->xfer_buf) { dev->xfer_buf = malloc(dev->xfer_buf_num * - sizeof(unsigned char *)); + sizeof(unsigned char *)); for(i = 0; i < dev->xfer_buf_num; ++i) dev->xfer_buf[i] = malloc(dev->xfer_buf_len); @@ -1837,7 +1838,7 @@ static int _rtlsdr_free_async_buffers(rtlsdr_dev_t *dev) } int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, - uint32_t buf_num, uint32_t buf_len) + uint32_t buf_num, uint32_t buf_len) { unsigned int i; int r = 0; @@ -1871,13 +1872,13 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, for(i = 0; i < dev->xfer_buf_num; ++i) { libusb_fill_bulk_transfer(dev->xfer[i], - dev->devh, - 0x81, - dev->xfer_buf[i], - dev->xfer_buf_len, - _libusb_callback, - (void *)dev, - BULK_TIMEOUT); + dev->devh, + 0x81, + dev->xfer_buf[i], + dev->xfer_buf_len, + _libusb_callback, + (void *)dev, + BULK_TIMEOUT); r = libusb_submit_transfer(dev->xfer[i]); if (r < 0) { @@ -1889,7 +1890,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, while (RTLSDR_INACTIVE != dev->async_status) { r = libusb_handle_events_timeout_completed(dev->ctx, &tv, - &dev->async_cancel); + &dev->async_cancel); if (r < 0) { /*fprintf(stderr, "handle_events returned: %d\n", r);*/ if (r == LIBUSB_ERROR_INTERRUPTED) /* stray signal */ @@ -1914,7 +1915,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, * to allow transfer status to * propagate */ libusb_handle_events_timeout_completed(dev->ctx, - &zerotv, NULL); + &zerotv, NULL); if (r < 0) continue; @@ -1927,7 +1928,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, * be handled before exiting after we * just cancelled all transfers */ libusb_handle_events_timeout_completed(dev->ctx, - &zerotv, NULL); + &zerotv, NULL); break; } } diff --git a/src/rtl_fm.c b/src/rtl_fm.c index 1091555..baf8bb9 100755 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -30,23 +30,23 @@ * (no many-to-many locks) * * todo: - * sanity checks - * scale squelch to other input parameters - * test all the demodulations - * pad output on hop - * frequency ranges could be stored better - * scaled AM demod amplification - * auto-hop after time limit - * peak detector to tune onto stronger signals - * fifo for active hop frequency - * clips - * noise squelch - * merge stereo patch - * merge soft agc patch - * merge udp patch - * testmode to detect overruns - * watchdog to reset bad dongle - * fix oversampling + * sanity checks + * scale squelch to other input parameters + * test all the demodulations + * pad output on hop + * frequency ranges could be stored better + * scaled AM demod amplification + * auto-hop after time limit + * peak detector to tune onto stronger signals + * fifo for active hop frequency + * clips + * noise squelch + * merge stereo patch + * merge soft agc patch + * merge udp patch + * testmode to detect overruns + * watchdog to reset bad dongle + * fix oversampling */ #include @@ -102,54 +102,54 @@ static double levelSum = 0.0; struct dongle_state { - int exit_flag; + int exit_flag; pthread_t thread; rtlsdr_dev_t *dev; - int dev_index; + int dev_index; uint32_t freq; uint32_t rate; uint32_t bandwidth; - int gain; + int gain; int16_t buf16[MAXIMUM_BUF_LENGTH]; uint32_t buf_len; - int ppm_error; - int offset_tuning; - int direct_sampling; - int mute; + int ppm_error; + int offset_tuning; + int direct_sampling; + int mute; struct demod_state *demod_target; }; struct demod_state { - int exit_flag; + int exit_flag; pthread_t thread; int16_t lowpassed[MAXIMUM_BUF_LENGTH]; - int lp_len; + int lp_len; int16_t lp_i_hist[10][6]; int16_t lp_q_hist[10][6]; int16_t result[MAXIMUM_BUF_LENGTH]; int16_t droop_i_hist[9]; int16_t droop_q_hist[9]; - int result_len; - int rate_in; - int rate_out; - int rate_out2; - int now_r, now_j; - int pre_r, pre_j; - int prev_index; - int downsample; /* min 1, max 256 */ - int post_downsample; - int output_scale; - int squelch_level, conseq_squelch, squelch_hits, terminate_on_squelch; - int downsample_passes; - int comp_fir_size; - int custom_atan; - int deemph, deemph_a; - int now_lpr; - int prev_lpr_index; - int dc_block_audio, dc_avg, adc_block_const; - int dc_block_raw, dc_avgI, dc_avgQ, rdc_block_const; - void (*mode_demod)(struct demod_state*); + int result_len; + int rate_in; + int rate_out; + int rate_out2; + int now_r, now_j; + int pre_r, pre_j; + int prev_index; + int downsample; /* min 1, max 256 */ + int post_downsample; + int output_scale; + int squelch_level, conseq_squelch, squelch_hits, terminate_on_squelch; + int downsample_passes; + int comp_fir_size; + int custom_atan; + int deemph, deemph_a; + int now_lpr; + int prev_lpr_index; + int dc_block_audio, dc_avg, adc_block_const; + int dc_block_raw, dc_avgI, dc_avgQ, rdc_block_const; + void (*mode_demod)(struct demod_state*); pthread_rwlock_t rw; pthread_cond_t ready; pthread_mutex_t ready_m; @@ -158,13 +158,13 @@ struct demod_state struct output_state { - int exit_flag; + int exit_flag; pthread_t thread; - FILE *file; - char *filename; + FILE *file; + char *filename; int16_t result[MAXIMUM_BUF_LENGTH]; - int result_len; - int rate; + int result_len; + int rate; pthread_rwlock_t rw; pthread_cond_t ready; pthread_mutex_t ready_m; @@ -172,13 +172,13 @@ struct output_state struct controller_state { - int exit_flag; + int exit_flag; pthread_t thread; uint32_t freqs[FREQUENCIES_LIMIT]; - int freq_len; - int freq_now; - int edge; - int wb_mode; + int freq_len; + int freq_now; + int edge; + int wb_mode; pthread_cond_t hop; pthread_mutex_t hop_m; }; @@ -195,44 +195,44 @@ void usage(void) "rtl_fm, a simple narrow band FM demodulator for RTL2832 based DVB-T receivers\n\n" "Use:\trtl_fm -f freq [-options] [filename]\n" "\t-f frequency_to_tune_to [Hz]\n" - "\t use multiple -f for scanning (requires squelch)\n" - "\t ranges supported, -f 118M:137M:25k\n" + "\t use multiple -f for scanning (requires squelch)\n" + "\t ranges supported, -f 118M:137M:25k\n" "\t[-v verbosity (default: 0)]\n" "\t[-M modulation (default: fm)]\n" - "\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n" - "\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n" - "\t raw mode outputs 2x16 bit IQ pairs\n" + "\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n" + "\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n" + "\t raw mode outputs 2x16 bit IQ pairs\n" "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" - "\t[-g tuner_gain (default: automatic)]\n" - "\t[-w tuner_bandwidth (default: automatic)]\n" + "\t[-g tuner_gain (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" - "\t output are comma separated values (csv):\n" - "\t mean since last output, max since last output, overall max, squelch\n" + "\t output are comma separated values (csv):\n" + "\t mean since last output, max since last output, overall max, squelch\n" "\t[-c de-emphasis_time_constant in us for wbfm. 'us' or 'eu' for 75/50 us (default: us)]\n" - //"\t for fm squelch is inverted\n" + //"\t for fm squelch is inverted\n" "\t[-o oversampling (default: 1, 4 recommended)]\n" "\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 rdc: enable dc blocking filter on raw I/Q data at capture rate\n" - "\t adc: enable dc blocking filter on demodulated audio\n" - "\t dc: same as adc\n" - "\t deemp: enable de-emphasis filter\n" - "\t direct: enable direct sampling\n" - "\t offset: enable offset tuning\n" + "\t use multiple -E to enable multiple options\n" + "\t edge: enable lower edge tuning\n" + "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" + "\t adc: enable dc blocking filter on demodulated audio\n" + "\t dc: same as adc\n" + "\t deemp: enable de-emphasis filter\n" + "\t direct: enable direct sampling\n" + "\t offset: enable offset tuning\n" "\t[-q dc_avg_factor for option rdc (default: 9)]\n" "\tfilename ('-' means stdout)\n" - "\t omitting the filename also uses stdout\n\n" + "\t omitting the filename also uses stdout\n\n" "Experimental options:\n" "\t[-r resample_rate (default: none / same as -s)]\n" "\t[-t squelch_delay (default: 10)]\n" - "\t +values will mute/scan, -values will exit\n" + "\t +values will mute/scan, -values will exit\n" "\t[-F fir_size (default: off)]\n" - "\t enables low-leakage downsample filter\n" - "\t size can be 0 or 9. 0 has bad roll off\n" + "\t enables low-leakage downsample filter\n" + "\t size can be 0 or 9. 0 has bad roll off\n" "\t[-A std/fast/lut choose atan math (default: std)]\n" //"\t[-C clip_path (default: off)\n" //"\t (create time stamped raw clips, requires squelch)\n" @@ -242,7 +242,7 @@ void usage(void) "\n" "Produces signed 16 bit ints, use Sox or aplay to hear them.\n" "\trtl_fm ... | play -t raw -r 24k -es -b 16 -c 1 -V1 -\n" - "\t | aplay -r 24k -f S16_LE -t raw -c 1\n" + "\t | aplay -r 24k -f S16_LE -t raw -c 1\n" "\t -M wbfm | play -r 32k ... \n" "\t -s 22050 | multimon -t raw /dev/stdin\n\n"); exit(1); @@ -441,7 +441,7 @@ void generic_fir(int16_t *data, int length, int *fir, int16_t *hist) sum += (hist[1] + hist[7]) * fir[2]; sum += (hist[2] + hist[6]) * fir[3]; sum += (hist[3] + hist[5]) * fir[4]; - sum += hist[4] * fir[5]; + sum += hist[4] * fir[5]; data[d] = sum >> 15 ; hist[0] = hist[1]; hist[1] = hist[2]; @@ -1056,7 +1056,7 @@ void dongle_init(struct dongle_state *s) s->direct_sampling = 0; s->offset_tuning = 0; s->demod_target = &demod; - s->bandwidth = 0; + s->bandwidth = 0; } void demod_init(struct demod_state *s) @@ -1070,10 +1070,10 @@ void demod_init(struct demod_state *s) s->downsample_passes = 0; s->comp_fir_size = 0; s->prev_index = 0; - s->post_downsample = 1; // once this works, default = 4 + s->post_downsample = 1; // once this works, default = 4 s->custom_atan = 0; s->deemph = 0; - s->rate_out2 = -1; // flag for disabled + s->rate_out2 = -1; // flag for disabled s->mode_demod = &fm_demod; s->pre_j = s->pre_r = s->now_r = s->now_j = 0; s->prev_lpr_index = 0; @@ -1277,9 +1277,9 @@ int main(int argc, char **argv) case 'v': verbosity = (int)atof(optarg); break; - case 'w': - dongle.bandwidth = (uint32_t)atofs(optarg); - break; + case 'w': + dongle.bandwidth = (uint32_t)atofs(optarg); + break; case 'h': default: usage(); @@ -1348,21 +1348,23 @@ int main(int argc, char **argv) verbose_ppm_set(dongle.dev, dongle.ppm_error); - verbose_set_bandwidth(dongle.dev, dongle.bandwidth); - - if (verbosity && dongle.bandwidth) - { - int r; - uint32_t in_bw, out_bw, last_bw = 0; - for ( in_bw = 1; in_bw < 3200; ++in_bw ) - { - r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); - if ( r == 0 && ( out_bw != last_bw || in_bw == 1 ) ) - fprintf(stderr, "device sets bandwidth %u Hz for bw para >= %u kHz\n", out_bw, in_bw ); - last_bw = out_bw; - } - fprintf(stderr,"\n"); - } + verbose_set_bandwidth(dongle.dev, dongle.bandwidth); + + verbose_set_bandwidth(dongle.dev, dongle.bandwidth); + + if (verbosity && dongle.bandwidth) + { + int r; + uint32_t in_bw, out_bw, last_bw = 0; + for ( in_bw = 1; in_bw < 3200; ++in_bw ) + { + r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); + if ( r == 0 && ( out_bw != last_bw || in_bw == 1 ) ) + fprintf(stderr, "device sets bandwidth %u Hz for bw para >= %u kHz\n", out_bw, in_bw ); + last_bw = out_bw; + } + fprintf(stderr,"\n"); + } if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */ output.file = stdout; diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c index f6c1694..ad54b55 100755 --- a/src/tuner_r82xx.c +++ b/src/tuner_r82xx.c @@ -250,7 +250,7 @@ static void shadow_store(struct r82xx_priv *priv, uint8_t reg, const uint8_t *va } static int r82xx_write(struct r82xx_priv *priv, uint8_t reg, const uint8_t *val, - unsigned int len) + unsigned int len) { int rc, size, pos = 0; @@ -561,8 +561,8 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq) } static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq, - enum r82xx_tuner_type type, - uint32_t delsys) + enum r82xx_tuner_type type, + uint32_t delsys) { int rc; uint8_t mixer_top, lna_top, cp_cur, div_buf_cur, lna_vth_l, mixer_vth_l; @@ -1083,97 +1083,97 @@ int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, uint8_t data[4]; if (extended_mode) { - /* - // LNA auto off - rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); - if (rc < 0) - return rc; - - // Mixer auto off - rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); - if (rc < 0) - return rc; - - rc = r82xx_read(priv, 0x00, data, sizeof(data)); - if (rc < 0) - return rc; - */ - - /* Set LNA */ - rc = r82xx_write_reg_mask(priv, 0x05, lna_gain, 0x0f); - if (rc < 0) - return rc; - - /* Set Mixer */ - rc = r82xx_write_reg_mask(priv, 0x07, mixer_gain, 0x0f); - if (rc < 0) - return rc; - - /* Set VGA */ - rc = r82xx_write_reg_mask(priv, 0x0c, vga_gain, 0x9f); - if (rc < 0) - return rc; - - return 0; + /* + // LNA auto off + rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); + if (rc < 0) + return rc; + + // Mixer auto off + rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); + if (rc < 0) + return rc; + + rc = r82xx_read(priv, 0x00, data, sizeof(data)); + if (rc < 0) + return rc; + */ + + /* Set LNA */ + rc = r82xx_write_reg_mask(priv, 0x05, lna_gain, 0x0f); + if (rc < 0) + return rc; + + /* Set Mixer */ + rc = r82xx_write_reg_mask(priv, 0x07, mixer_gain, 0x0f); + if (rc < 0) + return rc; + + /* Set VGA */ + rc = r82xx_write_reg_mask(priv, 0x0c, vga_gain, 0x9f); + if (rc < 0) + return rc; + + return 0; } if (set_manual_gain) { - /* LNA auto off */ - rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); - if (rc < 0) - return rc; + /* LNA auto off */ + rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10); + if (rc < 0) + return rc; - /* Mixer auto off */ - rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); - if (rc < 0) - return rc; + /* Mixer auto off */ + rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10); + if (rc < 0) + return rc; - rc = r82xx_read(priv, 0x00, data, sizeof(data)); - if (rc < 0) - return rc; + rc = r82xx_read(priv, 0x00, data, sizeof(data)); + if (rc < 0) + return rc; - /* set fixed VGA gain for now (16.3 dB) */ - rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f); - if (rc < 0) - return rc; + /* set fixed VGA gain for now (16.3 dB) */ + rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f); + if (rc < 0) + return rc; - for (i = 0; i < 15; i++) { - if (total_gain >= gain) - break; + for (i = 0; i < 15; i++) { + if (total_gain >= gain) + break; - total_gain += r82xx_lna_gain_steps[++lna_index]; + total_gain += r82xx_lna_gain_steps[++lna_index]; - if (total_gain >= gain) - break; + if (total_gain >= gain) + break; - total_gain += r82xx_mixer_gain_steps[++mix_index]; - } + total_gain += r82xx_mixer_gain_steps[++mix_index]; + } - /* set LNA gain */ - rc = r82xx_write_reg_mask(priv, 0x05, lna_index, 0x0f); - if (rc < 0) - return rc; + /* set LNA gain */ + rc = r82xx_write_reg_mask(priv, 0x05, lna_index, 0x0f); + if (rc < 0) + return rc; - /* set Mixer gain */ - rc = r82xx_write_reg_mask(priv, 0x07, mix_index, 0x0f); - if (rc < 0) - return rc; + /* set Mixer gain */ + rc = r82xx_write_reg_mask(priv, 0x07, mix_index, 0x0f); + if (rc < 0) + return rc; } else { - /* LNA */ - rc = r82xx_write_reg_mask(priv, 0x05, 0, 0x10); - if (rc < 0) - return rc; - - /* Mixer */ - rc = r82xx_write_reg_mask(priv, 0x07, 0x10, 0x10); - if (rc < 0) - return rc; - - /* set fixed VGA gain for now (26.5 dB) */ - rc = r82xx_write_reg_mask(priv, 0x0c, 0x0b, 0x9f); - if (rc < 0) - return rc; + /* LNA */ + rc = r82xx_write_reg_mask(priv, 0x05, 0, 0x10); + if (rc < 0) + return rc; + + /* Mixer */ + rc = r82xx_write_reg_mask(priv, 0x07, 0x10, 0x10); + if (rc < 0) + return rc; + + /* set fixed VGA gain for now (26.5 dB) */ + rc = r82xx_write_reg_mask(priv, 0x0c, 0x0b, 0x9f); + if (rc < 0) + return rc; } return 0; @@ -1197,35 +1197,35 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate, uint32_t if (bw > 7000000) { // BW: 8 MHz - *applied_bw = 8000000; + *applied_bw = 8000000; reg_0a = 0x10; reg_0b = 0x0b; - if (apply) - priv->int_freq = 4570000; + if (apply) + priv->int_freq = 4570000; } else if (bw > 6000000) { // BW: 7 MHz - *applied_bw = 7000000; - reg_0a = 0x10; + *applied_bw = 7000000; + reg_0a = 0x10; reg_0b = 0x2a; - if (apply) - priv->int_freq = 4570000; + if (apply) + priv->int_freq = 4570000; } else if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1 + FILT_HP_BW2) { // BW: 6 MHz - *applied_bw = 6000000; - reg_0a = 0x10; + *applied_bw = 6000000; + reg_0a = 0x10; reg_0b = 0x6b; - if (apply) - priv->int_freq = 3570000; + if (apply) + priv->int_freq = 3570000; } else { reg_0a = 0x00; reg_0b = 0x80; - if (apply) - priv->int_freq = 2300000; + if (apply) + priv->int_freq = 2300000; if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1) { bw -= FILT_HP_BW2; - if (apply) - priv->int_freq += FILT_HP_BW2; + if (apply) + priv->int_freq += FILT_HP_BW2; real_bw += FILT_HP_BW2; } else { reg_0b |= 0x20; @@ -1233,8 +1233,8 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate, uint32_t if (bw > r82xx_if_low_pass_bw_table[0]) { bw -= FILT_HP_BW1; - if (apply) - priv->int_freq += FILT_HP_BW1; + if (apply) + priv->int_freq += FILT_HP_BW1; real_bw += FILT_HP_BW1; } else { reg_0b |= 0x40; @@ -1249,14 +1249,14 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate, uint32_t reg_0b |= 15 - i; real_bw += r82xx_if_low_pass_bw_table[i]; - *applied_bw = real_bw; + *applied_bw = real_bw; - if (apply) - priv->int_freq -= real_bw / 2; + if (apply) + priv->int_freq -= real_bw / 2; } - if (!apply) - return 0; + if (!apply) + return 0; rc = r82xx_write_reg_mask(priv, 0x0a, reg_0a, 0x10); if (rc < 0) @@ -1292,7 +1292,7 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq) air_cable1_in = (freq > MHZ(345)) ? 0x00 : 0x60; if ((priv->cfg->rafael_chip == CHIP_R828D) && - (air_cable1_in != priv->input)) { + (air_cable1_in != priv->input)) { priv->input = air_cable1_in; rc = r82xx_write_reg_mask(priv, 0x05, air_cable1_in, 0x60); } From 240abf60761c63d6e1b5955e3ce9328f5d3d61de Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Fri, 25 Mar 2016 15:31:13 +0000 Subject: [PATCH 44/74] use offset tuning when using bandwidth option bandwidth filter are around center frequency without offset tuning rtl_fm automatically uses the frequency -fs/4 for demodulation but this lies outside the bandwidth filter! switch on offset option to use the center frequency for demodulation fixed/precised output texts output available bandwidths in kHz for better readability --- include/rtl-sdr.h | 7 +++++++ src/convenience/convenience.c | 34 ++++++++++++++++++++------------- src/rtl_fm.c | 36 ++++++++++++++++++----------------- src/rtl_tcp.c | 2 +- 4 files changed, 48 insertions(+), 31 deletions(-) mode change 100644 => 100755 src/rtl_tcp.c diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 384caa9..633524c 100755 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -143,6 +143,13 @@ RTLSDR_API int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, RTLSDR_API int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len); +/*! + * Set the frequency the device is tuned to. + * + * \param dev the device handle given by rtlsdr_open() + * \param frequency in Hz + * \return 0 on error, frequency in Hz otherwise + */ RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq); /*! diff --git a/src/convenience/convenience.c b/src/convenience/convenience.c index fb6ac3b..e234333 100755 --- a/src/convenience/convenience.c +++ b/src/convenience/convenience.c @@ -162,18 +162,21 @@ int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth) { - int r; - uint32_t applied_bw = 0; - /* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */ - r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */); - if (r < 0) { - fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); - } else if (bandwidth > 0) { - fprintf(stderr, "Bandwidth set to %u Hz resulted in %u Hz.\n", bandwidth, applied_bw); - } else { - fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw); - } - return r; + int r; + uint32_t applied_bw = 0; + /* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */ + r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */); + if (r < 0) { + fprintf(stderr, "WARNING: Failed to set bandwidth.\n"); + } else if (bandwidth > 0) { + if (applied_bw) + fprintf(stderr, "Bandwidth parameter %u Hz resulted in %u Hz.\n", bandwidth, applied_bw); + else + fprintf(stderr, "Set bandwidth parameter %u Hz.\n", bandwidth); + } else { + fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw); + } + return r; } int verbose_direct_sampling(rtlsdr_dev_t *dev, int on) @@ -198,7 +201,12 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev) int r; r = rtlsdr_set_offset_tuning(dev, 1); if (r != 0) { - fprintf(stderr, "WARNING: Failed to set offset tuning.\n"); + if ( r == -2 ) + fprintf(stderr, "WARNING: Failed to set offset tuning: tuner doesn't support offset tuning!\n"); + else if ( r == -3 ) + fprintf(stderr, "WARNING: Failed to set offset tuning: direct sampling not combinable with offset tuning!\n"); + else + fprintf(stderr, "WARNING: Failed to set offset tuning.\n"); } else { fprintf(stderr, "Offset tuning mode enabled.\n"); } diff --git a/src/rtl_fm.c b/src/rtl_fm.c index baf8bb9..c9f2f50 100755 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -205,7 +205,7 @@ void usage(void) "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" "\t[-g tuner_gain (default: automatic)]\n" - "\t[-w tuner_bandwidth (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" "\t output are comma separated values (csv):\n" @@ -221,8 +221,8 @@ void usage(void) "\t adc: enable dc blocking filter on demodulated audio\n" "\t dc: same as adc\n" "\t deemp: enable de-emphasis filter\n" - "\t direct: enable direct sampling\n" - "\t offset: enable offset tuning\n" + "\t direct: enable direct sampling (bypasses tuner, uses rtl2832 xtal)\n" + "\t offset: enable offset tuning (only e4000 tuner)\n" "\t[-q dc_avg_factor for option rdc (default: 9)]\n" "\tfilename ('-' means stdout)\n" "\t omitting the filename also uses stdout\n\n" @@ -986,7 +986,7 @@ static void *controller_thread_fn(void *arg) if (s->wb_mode) { if (verbosity) - fprintf(stderr, "wbfm: adding 16000 Hz to every intput frequency\n"); + fprintf(stderr, "wbfm: adding 16000 Hz to every input frequency\n"); for (i=0; i < s->freq_len; i++) { s->freqs[i] += 16000;} } @@ -1001,7 +1001,8 @@ static void *controller_thread_fn(void *arg) /* Set the frequency */ if (verbosity) { fprintf(stderr, "verbose_set_frequency(%.0f Hz)\n", (double)dongle.freq); - fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n"); + if (!dongle.offset_tuning) + fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n"); } verbose_set_frequency(dongle.dev, dongle.freq); fprintf(stderr, "Oversampling input by: %ix.\n", demod.downsample); @@ -1279,6 +1280,8 @@ int main(int argc, char **argv) break; case 'w': dongle.bandwidth = (uint32_t)atofs(optarg); + if (dongle.bandwidth) + dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ break; case 'h': default: @@ -1350,20 +1353,19 @@ int main(int argc, char **argv) verbose_set_bandwidth(dongle.dev, dongle.bandwidth); - verbose_set_bandwidth(dongle.dev, dongle.bandwidth); - if (verbosity && dongle.bandwidth) { - int r; - uint32_t in_bw, out_bw, last_bw = 0; - for ( in_bw = 1; in_bw < 3200; ++in_bw ) - { - r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); - if ( r == 0 && ( out_bw != last_bw || in_bw == 1 ) ) - fprintf(stderr, "device sets bandwidth %u Hz for bw para >= %u kHz\n", out_bw, in_bw ); - last_bw = out_bw; - } - fprintf(stderr,"\n"); + int r; + uint32_t in_bw, out_bw, last_bw = 0; + fprintf(stderr, "Supported bandwidth values in kHz:\n"); + for ( in_bw = 1; in_bw < 3200; ++in_bw ) + { + r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */); + if ( r == 0 && out_bw != 0 && ( out_bw != last_bw || in_bw == 1 ) ) + fprintf(stderr, "%s%.1f", (in_bw==1 ? "" : ", "), out_bw/1000.0 ); + last_bw = out_bw; + } + fprintf(stderr,"\n"); } if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */ diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c old mode 100644 new mode 100755 index bf0e3ea..3f90923 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -94,7 +94,7 @@ void usage(void) "\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[-w rtlsdr device bandwidth (for R820T device)\n" + "\t[-w rtlsdr device bandwidth [Hz] (for R820T device)\n" "\t[-d device index (default: 0)]\n" "\t[-P ppm_error (default: 0)]\n"); exit(1); From 57238073b82edb999063abe24c07bf04f8808726 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Fri, 25 Mar 2016 16:37:03 +0000 Subject: [PATCH 45/74] merged option to activate digital agc of rtl2832 with '-E rtlagc' also reformatted -E options --- src/rtl_fm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/rtl_fm.c b/src/rtl_fm.c index c9f2f50..0d59056 100755 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -217,9 +217,11 @@ void usage(void) "\t[-E enable_option (default: none)]\n" "\t use multiple -E to enable multiple options\n" "\t edge: enable lower edge tuning\n" - "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" - "\t adc: enable dc blocking filter on demodulated audio\n" - "\t dc: same as adc\n" + "\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n" + "\t adc: enable dc blocking filter on demodulated audio\n" + "\t dc: same as adc\n" + "\t rtlagc: enable rtl2832's digital agc (default: off)\n" + "\t agc: same as rtlagc\n" "\t deemp: enable de-emphasis filter\n" "\t direct: enable direct sampling (bypasses tuner, uses rtl2832 xtal)\n" "\t offset: enable offset tuning (only e4000 tuner)\n" @@ -1159,6 +1161,7 @@ int main(int argc, char **argv) int dev_given = 0; int custom_ppm = 0; int timeConstant = 75; /* default: U.S. 75 uS */ + int rtlagc = 0; dongle_init(&dongle); demod_init(&demod); output_init(&output); @@ -1228,6 +1231,8 @@ int main(int argc, char **argv) dongle.direct_sampling = 1;} if (strcmp("offset", optarg) == 0) { dongle.offset_tuning = 1;} + if (strcmp("rtlagc", optarg) == 0 || strcmp("agc", optarg) == 0) { + rtlagc = 1;} break; case 'q': demod.rdc_block_const = atoi(optarg); @@ -1349,6 +1354,8 @@ int main(int argc, char **argv) verbose_gain_set(dongle.dev, dongle.gain); } + rtlsdr_set_agc_mode(dongle.dev, rtlagc); + verbose_ppm_set(dongle.dev, dongle.ppm_error); verbose_set_bandwidth(dongle.dev, dongle.bandwidth); From aabe859851c8cd5471adcf68cea527a08acb369a Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sun, 3 Apr 2016 16:08:23 +0000 Subject: [PATCH 46/74] rtl_fm: made -v flag without argument rtl_tcp: added verbose option -v rtl_tcp: reduced mutex timeout from 5 to 1 sec. makes rtl_tcp re-available faster fixed formatting/indentation with tabs --- src/librtlsdr.c | 0 src/rtl_fm.c | 26 ++++++++++++---------- src/rtl_tcp.c | 55 ++++++++++++++++++++++++++++++----------------- src/tuner_r82xx.c | 0 4 files changed, 50 insertions(+), 31 deletions(-) mode change 100755 => 100644 src/librtlsdr.c mode change 100755 => 100644 src/rtl_fm.c mode change 100755 => 100644 src/rtl_tcp.c mode change 100755 => 100644 src/tuner_r82xx.c diff --git a/src/librtlsdr.c b/src/librtlsdr.c old mode 100755 new mode 100644 diff --git a/src/rtl_fm.c b/src/rtl_fm.c old mode 100755 new mode 100644 index 0d59056..80688fa --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -108,7 +108,7 @@ struct dongle_state int dev_index; uint32_t freq; uint32_t rate; - uint32_t bandwidth; + uint32_t bandwidth; int gain; int16_t buf16[MAXIMUM_BUF_LENGTH]; uint32_t buf_len; @@ -197,15 +197,15 @@ void usage(void) "\t-f frequency_to_tune_to [Hz]\n" "\t use multiple -f for scanning (requires squelch)\n" "\t ranges supported, -f 118M:137M:25k\n" - "\t[-v verbosity (default: 0)]\n" + "\t[-v increase verbosity (default: 0)]\n" "\t[-M modulation (default: fm)]\n" "\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n" "\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n" "\t raw mode outputs 2x16 bit IQ pairs\n" "\t[-s sample_rate (default: 24k)]\n" "\t[-d device_index (default: 0)]\n" - "\t[-g tuner_gain (default: automatic)]\n" - "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" + "\t[-g tuner_gain (default: automatic)]\n" + "\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n" "\t[-l squelch_level (default: 0/off)]\n" "\t[-L N prints levels every N calculations]\n" "\t output are comma separated values (csv):\n" @@ -1167,7 +1167,7 @@ int main(int argc, char **argv) output_init(&output); controller_init(&controller); - while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:v:h:w:")) != -1) { + while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:h:w:v")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -1281,20 +1281,24 @@ int main(int argc, char **argv) timeConstant = (int)atof(optarg); break; case 'v': - verbosity = (int)atof(optarg); + ++verbosity; + break; + case 'w': + dongle.bandwidth = (uint32_t)atofs(optarg); + if (dongle.bandwidth) + dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ break; - case 'w': - dongle.bandwidth = (uint32_t)atofs(optarg); - if (dongle.bandwidth) - dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */ - break; case 'h': + case '?': default: usage(); break; } } + if (verbosity) + fprintf(stderr, "verbosity set to %d\n", verbosity); + /* quadruple sample_rate to limit to Δθ to ±π/2 */ demod.rate_in *= demod.post_downsample; diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c old mode 100755 new mode 100644 index 3f90923..3906f9c --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -78,6 +78,8 @@ typedef struct { /* structure size must be multiple of 2 bytes */ static rtlsdr_dev_t *dev = NULL; +static int verbosity = 0; +static uint32_t bandwidth = 0; static int global_numq = 0; static struct llist *ll_buffers = 0; static int llbuf_num = 500; @@ -94,9 +96,10 @@ void usage(void) "\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[-w rtlsdr device bandwidth [Hz] (for R820T device)\n" + "\t[-w rtlsdr device bandwidth [Hz] (for R820T device)]\n" "\t[-d device index (default: 0)]\n" - "\t[-P ppm_error (default: 0)]\n"); + "\t[-P ppm_error (default: 0)]\n" + "\t[-v increase verbosity (default: 0)]\n"); exit(1); } @@ -203,7 +206,7 @@ static void *tcp_worker(void *arg) pthread_mutex_lock(&ll_mutex); gettimeofday(&tp, NULL); - ts.tv_sec = tp.tv_sec+5; + ts.tv_sec = tp.tv_sec+1; ts.tv_nsec = tp.tv_usec * 1000; r = pthread_cond_timedwait(&cond, &ll_mutex, &ts); if(r == ETIMEDOUT) { @@ -257,6 +260,8 @@ static int set_gain_by_index(rtlsdr_dev_t *_dev, unsigned int index) count = rtlsdr_get_tuner_gains(_dev, gains); res = rtlsdr_set_tuner_gain(_dev, gains[index]); + if (verbosity) + fprintf(stderr, "set tuner gain to %.1f dB\n", gains[index] / 10.0); free(gains); } @@ -310,6 +315,7 @@ static void *command_worker(void *arg) case SET_SAMPLE_RATE: printf("set sample rate %d\n", ntohl(cmd.param)); rtlsdr_set_sample_rate(dev, ntohl(cmd.param)); + /*verbose_set_bandwidth(dev, bandwidth);*/ break; case SET_GAIN_MODE: printf("set gain mode %d\n", ntohl(cmd.param)); @@ -356,10 +362,11 @@ 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 SET_TUNER_BANDWIDTH: - printf("set tuner bandwidth to %i Hz\n", ntohl(cmd.param)); - rtlsdr_set_tuner_bandwidth(dev, ntohl(cmd.param)); - break; + case SET_TUNER_BANDWIDTH: + bandwidth = ntohl(cmd.param); + printf("set tuner bandwidth to %i Hz\n", bandwidth); + verbose_set_bandwidth(dev, bandwidth); + break; default: break; } @@ -372,7 +379,7 @@ 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, bandwidth = 0; + uint32_t frequency = 100000000, samp_rate = 2048000; struct sockaddr_in local, remote; uint32_t buf_num = 0; int dev_index = 0; @@ -389,6 +396,7 @@ int main(int argc, char **argv) fd_set readfds; u_long blockmode = 1; dongle_info_t dongle_info; + int gains[100]; #ifdef _WIN32 WSADATA wsd; i = WSAStartup(MAKEWORD(2,2), &wsd); @@ -396,7 +404,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:w:")) != -1) { + while ((opt = getopt(argc, argv, "a:p:f:g:s:b:n:d:P:w:v")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); @@ -425,9 +433,12 @@ int main(int argc, char **argv) break; case 'P': ppm_error = atoi(optarg); - break; - case 'w': - bandwidth = (uint32_t)atofs(optarg); + break; + case 'w': + bandwidth = (uint32_t)atofs(optarg); + break; + case 'v': + ++verbosity; break; default: usage(); @@ -438,6 +449,9 @@ int main(int argc, char **argv) if (argc < optind) usage(); + if (verbosity) + fprintf(stderr, "verbosity set to %d\n", verbosity); + if (!dev_given) { dev_index = verbose_device_search("0"); } @@ -499,13 +513,7 @@ int main(int argc, char **argv) fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0); } - r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); - if (r < 0) - fprintf(stderr, "WARNING: Failed to set tuner bandwidth.\n"); - else if (bandwidth != 0) - fprintf(stderr, "Tuner bandwidth set to %i.\n", bandwidth); - else - fprintf(stderr, "Tuner bandwidth set to automatic.\n"); + verbose_set_bandwidth(dev, bandwidth); /* Reset endpoint before we start reading from it (mandatory) */ r = rtlsdr_reset_buffer(dev); @@ -571,9 +579,16 @@ int main(int argc, char **argv) if (r >= 0) dongle_info.tuner_type = htonl(r); - r = rtlsdr_get_tuner_gains(dev, NULL); + r = rtlsdr_get_tuner_gains(dev, gains); if (r >= 0) dongle_info.tuner_gain_count = htonl(r); + if (verbosity) + { + fprintf(stderr, "Supported gain values (%d): ", r); + for (i = 0; i < r; i++) + fprintf(stderr, "%.1f ", gains[i] / 10.0); + fprintf(stderr, "\n"); + } r = send(s, (const char *)&dongle_info, sizeof(dongle_info), 0); if (sizeof(dongle_info) != r) diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c old mode 100755 new mode 100644 From 35639adcef76218974a1623f3b300701dad1ce38 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sat, 4 Jun 2016 23:41:14 +0000 Subject: [PATCH 47/74] minor correction in usage --- src/rtl_tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index 3906f9c..ed880b8 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -92,11 +92,11 @@ void usage(void) "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[-g gain in dB (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[-w rtlsdr device bandwidth [Hz] (for R820T device)]\n" + "\t[-w rtlsdr tuner bandwidth [Hz] (for R820T and E4000 tuners)]\n" "\t[-d device index (default: 0)]\n" "\t[-P ppm_error (default: 0)]\n" "\t[-v increase verbosity (default: 0)]\n"); From 20bc4dc0fb398cadc3ddc6d48c4137e7ca4e2e57 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Sat, 4 Jun 2016 23:42:39 +0000 Subject: [PATCH 48/74] added CMakeLists.txt for Win32 and a README --- win32-qtcreator/CMakeLists.txt | 75 ++++++++++++++++++++++++++++++++++ win32-qtcreator/README.txt | 31 ++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 win32-qtcreator/CMakeLists.txt create mode 100644 win32-qtcreator/README.txt diff --git a/win32-qtcreator/CMakeLists.txt b/win32-qtcreator/CMakeLists.txt new file mode 100644 index 0000000..539eab4 --- /dev/null +++ b/win32-qtcreator/CMakeLists.txt @@ -0,0 +1,75 @@ +project(rtlsdr) +cmake_minimum_required(VERSION 2.8) + +# created and tested with +# Qt 5.5.1 for Windows 32-bit (MinGW 4.9.2) from +# https://www.qt.io/download-open-source/#section-2 +# +# and QtCreator 4.0.0 +# +# and LibUSB 1.0.20 from +# https://sourceforge.net/projects/libusb/files/ +# libusb-1.0.20.7z +# + +# edit this path +SET( LIBUSBBASE C:/src/_foreign/libusb-1.0.20 ) + + +add_definitions( -DWIN32 -D_WIN32 -DNDEBUG ) + +include_directories( + ../include + ${LIBUSBBASE}/include/libusb-1.0 +) + +SET( LIBUSB ${LIBUSBBASE}/MinGW32/static/libusb-1.0.a ) + +SET( SOCKLIBS ws2_32 wsock32 ) + +SET( RTLLIBFILES + ../include/rtl_tcp.h + ../include/reg_field.h + ../include/rtlsdr_i2c.h + + ../src/convenience/convenience.c + ../src/convenience/convenience.h + + ../src/getopt/getopt.c + ../src/getopt/getopt.h + + ../include/rtl-sdr_export.h + ../include/rtl-sdr.h + ../src/librtlsdr.c + + ../include/tuner_e4k.h + ../src/tuner_e4k.c + + ../include/tuner_fc0012.h + ../src/tuner_fc0012.c + + ../include/tuner_fc0013.h + ../src/tuner_fc0013.c + + ../include/tuner_fc2580.h + ../src/tuner_fc2580.c + + ../include/tuner_r82xx.h + ../src/tuner_r82xx.c +) + +add_executable( rtl_test ../src/rtl_test.c ${RTLLIBFILES} ) +target_link_libraries( rtl_test ${LIBUSB} ) + +add_executable( rtl_fm ../src/rtl_fm.c ${RTLLIBFILES} ) +target_link_libraries( rtl_fm ${LIBUSB} ) + +add_executable( rtl_tcp ../src/rtl_tcp.c ${RTLLIBFILES} ) +target_link_libraries( rtl_tcp ${LIBUSB} ${SOCKLIBS} ) + +add_executable( rtl_adsb ../src/rtl_adsb.c ${RTLLIBFILES} ) +target_link_libraries( rtl_adsb ${LIBUSB} ) + +add_executable( rtl_power ../src/rtl_power.c ${RTLLIBFILES} ) +target_link_libraries( rtl_power ${LIBUSB} ) + diff --git a/win32-qtcreator/README.txt b/win32-qtcreator/README.txt new file mode 100644 index 0000000..e92aabb --- /dev/null +++ b/win32-qtcreator/README.txt @@ -0,0 +1,31 @@ + +there is an outdated "How to compile new releases of librtlsdr (and tools) on Windows" at +https://www.reddit.com/r/RTLSDR/comments/uce3e/how_to_compile_new_releases_of_librtlsdr_and/ +unfortunately the link to the CMakeLists.txt is broken! + +so, i needed to find another solution .. + + +1) aquire and install Qt 5.5.x for Windows 32-bit (MinGW 4.9.2) from +https://www.qt.io/download-open-source/#section-2 + +2) aquire and install QtCreator 4.0.x +from same site as 1) +probably this step is not necessary and you can use the qtcreator IDE from 1) + +3) aquire LibUSB 1.0.20 from +https://sourceforge.net/projects/libusb/files/ +last tested: libusb-1.0.20.7z + +and place the file at C:/src/_foreign/libusb-1.0.20 + +or replace LIBUSBBASE path in CMakeLists.txt + +4) start qtcreator and open the (modified) CMakeLists.txt +configure compiler/environment and compile + + +the resulting executables have no other dependencies than libwinpthread-1.dll +from the MINGW system at C:\Qt\Qt5.5.1\Tools\mingw492_32\bin\ + or C:\Qt\Qt5.5.1\5.5\mingw492_32\bin + From e6bdc91e9995e7dda1925c39623b5b86e14fe8a8 Mon Sep 17 00:00:00 2001 From: Hayati Ayguen Date: Mon, 13 Jun 2016 21:04:53 +0000 Subject: [PATCH 49/74] added option '-l' for rtl_tcp to set block length in units of 512 samples new default is 64*512 samples = 16 kSamples, old default was 512*512 samples = 131 kSamples what is not very smooth in a live spectrum! debug output of queues with 'll+'/'ll-' only with verbose flag Signed-off-by: Hayati Ayguen --- src/rtl_tcp.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index ed880b8..f1111f6 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -95,6 +95,7 @@ void usage(void) "\t[-g gain in dB (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[-l length of single buffer in units of 512 samples (default: 64 was 256)]\n" "\t[-n max number of linked list buffers to keep (default: 500)]\n" "\t[-w rtlsdr tuner bandwidth [Hz] (for R820T and E4000 tuners)]\n" "\t[-d device index (default: 0)]\n" @@ -178,10 +179,13 @@ void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) cur->next = rpt; - if (num_queued > global_numq) - printf("ll+, now %d\n", num_queued); - else if (num_queued < global_numq) - printf("ll-, now %d\n", num_queued); + if ( verbosity ) + { + if (num_queued > global_numq) + printf("ll+, now %d\n", num_queued); + else if (num_queued < global_numq) + printf("ll-, now %d\n", num_queued); + } global_numq = num_queued; } @@ -382,6 +386,16 @@ int main(int argc, char **argv) uint32_t frequency = 100000000, samp_rate = 2048000; struct sockaddr_in local, remote; uint32_t buf_num = 0; + /* buf_len: + * -> 256 -> 262 ms @ 250 kS or 20.48 ms @ 3.2 MS (internal default) + * -> 128 -> 131 ms @ 250 kS or 10.24 ms @ 3.2 MS + * -> 64 -> 65 ms @ 250 kS or 5.12 ms @ 3.2 MS (new default) + * + * usual soundcard as reference: + * 512 samples @ 48 kHz ~= 10.6 ms + * 512 samples @ 8 kHz = 64 ms + */ + uint32_t buf_len = 64; int dev_index = 0; int dev_given = 0; int gain = 0; @@ -404,7 +418,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:w:v")) != -1) { + while ((opt = getopt(argc, argv, "a:p:f:g:s:b:l:n:d:P:w:v")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); @@ -428,6 +442,9 @@ int main(int argc, char **argv) case 'b': buf_num = atoi(optarg); break; + case 'l': + buf_len = 512 * atoi(optarg); + break; case 'n': llbuf_num = atoi(optarg); break; @@ -600,7 +617,7 @@ int main(int argc, char **argv) r = pthread_create(&command_thread, &attr, command_worker, NULL); pthread_attr_destroy(&attr); - r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, buf_num, 0); + r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, buf_num, buf_len); pthread_join(tcp_worker_thread, &status); pthread_join(command_thread, &status); From 069362655fc5b4cdfdbb14fc59e25ff782c1fcbd Mon Sep 17 00:00:00 2001 From: rxseger Date: Fri, 1 Jul 2016 23:04:49 -0700 Subject: [PATCH 50/74] Add IrDA and IR registers from Linux dvb_usb_rtl28xxu driver Based on https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h#L245-L288 --- src/librtlsdr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 0650606..1338fce 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -392,6 +392,51 @@ enum sys_reg { SYSINTS_1 = 0x300a, DEMOD_CTL_1 = 0x300b, IR_SUSPEND = 0x300c, + + /* IrDA registers */ + SYS_IRRC_PSR = 0x3020, /* IR protocol selection */ + SYS_IRRC_PER = 0x3024, /* IR protocol extension */ + SYS_IRRC_SF = 0x3028, /* IR sampling frequency */ + SYS_IRRC_DPIR = 0x302C, /* IR data package interval */ + SYS_IRRC_CR = 0x3030, /* IR control */ + SYS_IRRC_RP = 0x3034, /* IR read port */ + SYS_IRRC_SR = 0x3038, /* IR status */ + /* I2C master registers */ + SYS_I2CCR = 0x3040, /* I2C clock */ + SYS_I2CMCR = 0x3044, /* I2C master control */ + SYS_I2CMSTR = 0x3048, /* I2C master SCL timing */ + SYS_I2CMSR = 0x304C, /* I2C master status */ + SYS_I2CMFR = 0x3050, /* I2C master FIFO */ + + /* + * IR registers + */ + IR_RX_BUF = 0xFC00, + IR_RX_IE = 0xFD00, + IR_RX_IF = 0xFD01, + IR_RX_CTRL = 0xFD02, + IR_RX_CFG = 0xFD03, + IR_MAX_DURATION0 = 0xFD04, + IR_MAX_DURATION1 = 0xFD05, + IR_IDLE_LEN0 = 0xFD06, + IR_IDLE_LEN1 = 0xFD07, + IR_GLITCH_LEN = 0xFD08, + IR_RX_BUF_CTRL = 0xFD09, + IR_RX_BUF_DATA = 0xFD0A, + IR_RX_BC = 0xFD0B, + IR_RX_CLK = 0xFD0C, + IR_RX_C_COUNT_L = 0xFD0D, + IR_RX_C_COUNT_H = 0xFD0E, + IR_SUSPEND_CTRL = 0xFD10, + IR_ERR_TOL_CTRL = 0xFD11, + IR_UNIT_LEN = 0xFD12, + IR_ERR_TOL_LEN = 0xFD13, + IR_MAX_H_TOL_LEN = 0xFD14, + IR_MAX_L_TOL_LEN = 0xFD15, + IR_MASK_CTRL = 0xFD16, + IR_MASK_DATA = 0xFD17, + IR_RES_MASK_ADDR = 0xFD18, + IR_RES_MASK_T_LEN = 0xFD19, }; enum blocks { From aa206d0d5bcfb7b9c69f29dd26cd68d1b138b0df Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 14:54:03 -0700 Subject: [PATCH 51/74] Add rtl_ir tool stub --- src/CMakeLists.txt | 10 +++++++++- src/Makefile.am | 5 ++++- src/rtl_ir.c | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/rtl_ir.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07d64ab..17b4a76 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,10 +88,11 @@ add_executable(rtl_sdr rtl_sdr.c) add_executable(rtl_tcp rtl_tcp.c) add_executable(rtl_test rtl_test.c) add_executable(rtl_fm rtl_fm.c) +add_executable(rtl_ir rtl_ir.c) add_executable(rtl_eeprom rtl_eeprom.c) add_executable(rtl_adsb rtl_adsb.c) add_executable(rtl_power rtl_power.c) -set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power) +set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power) target_link_libraries(rtl_sdr rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} @@ -109,6 +110,10 @@ target_link_libraries(rtl_fm rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) +target_link_libraries(rtl_ir rtlsdr_shared convenience_static + ${LIBUSB_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} +) target_link_libraries(rtl_eeprom rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} @@ -123,6 +128,7 @@ target_link_libraries(rtl_power rtlsdr_shared convenience_static ) if(UNIX) target_link_libraries(rtl_fm m) +target_link_libraries(rtl_ir m) target_link_libraries(rtl_adsb m) target_link_libraries(rtl_power m) if(APPLE) @@ -137,6 +143,7 @@ target_link_libraries(rtl_sdr libgetopt_static) target_link_libraries(rtl_tcp ws2_32 libgetopt_static) target_link_libraries(rtl_test libgetopt_static) target_link_libraries(rtl_fm libgetopt_static) +target_link_libraries(rtl_ir libgetopt_static) target_link_libraries(rtl_eeprom libgetopt_static) target_link_libraries(rtl_adsb libgetopt_static) target_link_libraries(rtl_power libgetopt_static) @@ -144,6 +151,7 @@ set_property(TARGET rtl_sdr APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" set_property(TARGET rtl_tcp APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_test APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_fm APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) +set_property(TARGET rtl_ir APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_eeprom APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_adsb APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_power APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) diff --git a/src/Makefile.am b/src/Makefile.am index 200990a..591ba56 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ lib_LTLIBRARIES = librtlsdr.la librtlsdr_la_SOURCES = librtlsdr.c tuner_e4k.c tuner_fc0012.c tuner_fc0013.c tuner_fc2580.c tuner_r82xx.c librtlsdr_la_LDFLAGS = -version-info $(LIBVERSION) -bin_PROGRAMS = rtl_sdr rtl_tcp rtl_test rtl_fm rtl_eeprom rtl_adsb rtl_power +bin_PROGRAMS = rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power rtl_sdr_SOURCES = rtl_sdr.c convenience/convenience.c rtl_sdr_LDADD = librtlsdr.la @@ -26,6 +26,9 @@ rtl_test_LDADD = librtlsdr.la $(LIBM) rtl_fm_SOURCES = rtl_fm.c convenience/convenience.c rtl_fm_LDADD = librtlsdr.la $(LIBM) +rtl_ir_SOURCES = rtl_ir.c convenience/convenience.c +rtl_ir_LDADD = librtlsdr.la $(LIBM) + rtl_eeprom_SOURCES = rtl_eeprom.c convenience/convenience.c rtl_eeprom_LDADD = librtlsdr.la $(LIBM) diff --git a/src/rtl_ir.c b/src/rtl_ir.c new file mode 100644 index 0000000..a32611b --- /dev/null +++ b/src/rtl_ir.c @@ -0,0 +1,7 @@ + +#include + +int main(int argc, char **argv) { + printf("Hello, world!\n"); + return 0; +} From 024f3c57a247950673ae939e9063a1a50626ae4b Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 17:30:59 -0700 Subject: [PATCH 52/74] rtl_ir: initialize dongle --- src/rtl_ir.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/src/rtl_ir.c b/src/rtl_ir.c index a32611b..b43b877 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -1,7 +1,170 @@ +/* + * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver + * Copyright (C) 2012 by Steve Markgraf + * Copyright (C) 2012 by Hoernchen + * Copyright (C) 2012 by Kyle Keen + * Copyright (C) 2013 by Elias Oenal + * Copyright (C) 2016 by Robert X. Seger + * + * 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 . + */ + +#include +#include +#include #include +#include + +#ifndef _WIN32 +#include +#else +#include +#include +#include +#include "getopt/getopt.h" +#define usleep(x) Sleep(x/1000) +#ifdef _MSC_VER +#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5)) +#endif +#define _USE_MATH_DEFINES +#endif + +#include +#include +#include + +#include "rtl-sdr.h" +#include "convenience/convenience.h" + +static volatile int do_exit = 0; + +struct dongle_state +{ + int exit_flag; + pthread_t thread; + rtlsdr_dev_t *dev; + int dev_index; +}; + +void dongle_init(struct dongle_state *s) +{ + s->dev_index = 0; +} + +struct dongle_state dongle; + +void usage(void) +{ + fprintf(stderr, + "rtl_ir\n\n" + "Use:\trtl_ir [-options]\n" + "\t[-d device_index (default: 0)]\n"); + exit(1); +} + +#ifdef _WIN32 +BOOL WINAPI +sighandler(int signum) +{ + if (CTRL_C_EVENT == signum) { + fprintf(stderr, "Signal caught, exiting!\n"); + do_exit = 1; + rtlsdr_cancel_async(dongle.dev); + return TRUE; + } + return FALSE; +} +#else +static void sighandler(int signum) +{ + fprintf(stderr, "Signal caught, exiting!\n"); + do_exit = 1; + rtlsdr_cancel_async(dongle.dev); +} +#endif + +static void *dongle_thread_fn(void *arg) +{ + struct dongle_state *s = arg; + printf("TODO\n"); + //rtlsdr_read_async(s->dev, rtlsdr_callback, s, 0, s->buf_len); + return 0; +} + int main(int argc, char **argv) { - printf("Hello, world!\n"); +#ifndef _WIN32 + struct sigaction sigact; +#endif + int r, opt; + int dev_given = 0; + dongle_init(&dongle); + + while ((opt = getopt(argc, argv, "d:h")) != -1) { + switch (opt) { + case 'd': + dongle.dev_index = verbose_device_search(optarg); + dev_given = 1; + break; + case 'h': + default: + usage(); + break; + } + } + + if (dongle.dev_index < 0) { + exit(1); + } + + r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index); + if (r < 0) { + fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dongle.dev_index); + exit(1); + } +#ifndef _WIN32 + sigact.sa_handler = sighandler; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + sigaction(SIGINT, &sigact, NULL); + sigaction(SIGTERM, &sigact, NULL); + sigaction(SIGQUIT, &sigact, NULL); + sigaction(SIGPIPE, &sigact, NULL); +#else + SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); +#endif + + verbose_reset_buffer(dongle.dev); + + usleep(100000); + pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(&dongle)); + + while (!do_exit) { + usleep(100000); + } + + if (do_exit) { + fprintf(stderr, "\nUser cancel, exiting...\n");} + else { + fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} + + rtlsdr_cancel_async(dongle.dev); + pthread_join(dongle.thread, NULL); + + rtlsdr_close(dongle.dev); + return r >= 0 ? r : -r; + return 0; } From 4b4942fb05f69368b4f0863e5b3b38087ff0b28b Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 18:17:25 -0700 Subject: [PATCH 53/74] rtl_ir: merge some init code from Linux dvb-usb-v2 driver https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c --- src/rtl_ir.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 340 insertions(+), 1 deletion(-) diff --git a/src/rtl_ir.c b/src/rtl_ir.c index b43b877..5ab468c 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -1,5 +1,8 @@ /* * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver + * Copyright (C) 2009 Antti Palosaari + * Copyright (C) 2011 Antti Palosaari + * Copyright (C) 2012 Thomas Mair * Copyright (C) 2012 by Steve Markgraf * Copyright (C) 2012 by Hoernchen * Copyright (C) 2012 by Kyle Keen @@ -48,19 +51,263 @@ #include "rtl-sdr.h" #include "convenience/convenience.h" +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +// Registers from Linux drivers/media/usb/dvb-usb-v2/rtl28xxu.h TODO: merge into librtlsdr? +struct rtl28xxu_req { + uint16_t value; + uint16_t index; + uint16_t size; + uint8_t *data; +}; + +struct rtl28xxu_reg_val { + uint16_t reg; + uint8_t val; +}; + +struct rtl28xxu_reg_val_mask { + uint16_t reg; + uint8_t val; + uint8_t mask; +}; + +/* + * memory map + * + * 0x0000 DEMOD : demodulator + * 0x2000 USB : SIE, USB endpoint, debug, DMA + * 0x3000 SYS : system + * 0xfc00 RC : remote controller (not RTL2831U) + */ + +/* + * USB registers + */ +/* SIE Control Registers */ +#define USB_SYSCTL 0x2000 /* USB system control */ +#define USB_SYSCTL_0 0x2000 /* USB system control */ +#define USB_SYSCTL_1 0x2001 /* USB system control */ +#define USB_SYSCTL_2 0x2002 /* USB system control */ +#define USB_SYSCTL_3 0x2003 /* USB system control */ +#define USB_IRQSTAT 0x2008 /* SIE interrupt status */ +#define USB_IRQEN 0x200C /* SIE interrupt enable */ +#define USB_CTRL 0x2010 /* USB control */ +#define USB_STAT 0x2014 /* USB status */ +#define USB_DEVADDR 0x2018 /* USB device address */ +#define USB_TEST 0x201C /* USB test mode */ +#define USB_FRAME_NUMBER 0x2020 /* frame number */ +#define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */ +#define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */ +#define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */ +/* Endpoint Registers */ +#define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */ +#define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */ +#define USB_EP0_CFG 0x2104 /* EP 0 configure */ +#define USB_EP0_CTL 0x2108 /* EP 0 control */ +#define USB_EP0_STAT 0x210C /* EP 0 status */ +#define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */ +#define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */ +#define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */ +#define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */ +#define USB_EPA_CFG 0x2144 /* EP A configure */ +#define USB_EPA_CFG_0 0x2144 /* EP A configure */ +#define USB_EPA_CFG_1 0x2145 /* EP A configure */ +#define USB_EPA_CFG_2 0x2146 /* EP A configure */ +#define USB_EPA_CFG_3 0x2147 /* EP A configure */ +#define USB_EPA_CTL 0x2148 /* EP A control */ +#define USB_EPA_CTL_0 0x2148 /* EP A control */ +#define USB_EPA_CTL_1 0x2149 /* EP A control */ +#define USB_EPA_CTL_2 0x214A /* EP A control */ +#define USB_EPA_CTL_3 0x214B /* EP A control */ +#define USB_EPA_STAT 0x214C /* EP A status */ +#define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */ +#define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */ +#define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */ +#define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */ +#define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */ +#define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */ +#define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */ +#define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */ +#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */ +#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */ +#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */ +#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */ +/* Debug Registers */ +#define USB_PHYTSTDIS 0x2F04 /* PHY test disable */ +#define USB_TOUT_VAL 0x2F08 /* USB time-out time */ +#define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */ +#define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */ +#define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */ +#define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */ +#define USB_UTMI_TST 0x2F80 /* UTMI test */ +#define USB_UTMI_STATUS 0x2F84 /* UTMI status */ +#define USB_TSTCTL 0x2F88 /* test control */ +#define USB_TSTCTL2 0x2F8C /* test control 2 */ +#define USB_PID_FORCE 0x2F90 /* force PID */ +#define USB_PKTERR_CNT 0x2F94 /* packet error counter */ +#define USB_RXERR_CNT 0x2F98 /* RX error counter */ +#define USB_MEM_BIST 0x2F9C /* MEM BIST test */ +#define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */ +#define USB_CNTTEST 0x2FA4 /* counter test */ +#define USB_PHYTST 0x2FC0 /* USB PHY test */ +#define USB_DBGIDX 0x2FF0 /* select individual block debug signal */ +#define USB_DBGMUX 0x2FF4 /* debug signal module mux */ + +/* + * SYS registers + */ +/* demod control registers */ +#define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */ +#define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */ +/* GPIO registers */ +#define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */ +#define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */ +#define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */ +#define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */ +#define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */ +#define SYS_SYSINTE 0x3005 /* system interrupt enable */ +#define SYS_SYSINTS 0x3006 /* system interrupt status */ +#define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */ +#define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */ +#define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */ +#define SYS_DEMOD_CTL1 0x300B + +/* IrDA registers */ +#define SYS_IRRC_PSR 0x3020 /* IR protocol selection */ +#define SYS_IRRC_PER 0x3024 /* IR protocol extension */ +#define SYS_IRRC_SF 0x3028 /* IR sampling frequency */ +#define SYS_IRRC_DPIR 0x302C /* IR data package interval */ +#define SYS_IRRC_CR 0x3030 /* IR control */ +#define SYS_IRRC_RP 0x3034 /* IR read port */ +#define SYS_IRRC_SR 0x3038 /* IR status */ +/* I2C master registers */ +#define SYS_I2CCR 0x3040 /* I2C clock */ +#define SYS_I2CMCR 0x3044 /* I2C master control */ +#define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */ +#define SYS_I2CMSR 0x304C /* I2C master status */ +#define SYS_I2CMFR 0x3050 /* I2C master FIFO */ + +/* + * IR registers + */ +#define IR_RX_BUF 0xFC00 +#define IR_RX_IE 0xFD00 +#define IR_RX_IF 0xFD01 +#define IR_RX_CTRL 0xFD02 +#define IR_RX_CFG 0xFD03 +#define IR_MAX_DURATION0 0xFD04 +#define IR_MAX_DURATION1 0xFD05 +#define IR_IDLE_LEN0 0xFD06 +#define IR_IDLE_LEN1 0xFD07 +#define IR_GLITCH_LEN 0xFD08 +#define IR_RX_BUF_CTRL 0xFD09 +#define IR_RX_BUF_DATA 0xFD0A +#define IR_RX_BC 0xFD0B +#define IR_RX_CLK 0xFD0C +#define IR_RX_C_COUNT_L 0xFD0D +#define IR_RX_C_COUNT_H 0xFD0E +#define IR_SUSPEND_CTRL 0xFD10 +#define IR_ERR_TOL_CTRL 0xFD11 +#define IR_UNIT_LEN 0xFD12 +#define IR_ERR_TOL_LEN 0xFD13 +#define IR_MAX_H_TOL_LEN 0xFD14 +#define IR_MAX_L_TOL_LEN 0xFD15 +#define IR_MASK_CTRL 0xFD16 +#define IR_MASK_DATA 0xFD17 +#define IR_RES_MASK_ADDR 0xFD18 +#define IR_RES_MASK_T_LEN 0xFD19 + static volatile int do_exit = 0; struct dongle_state { int exit_flag; + int rc_active; pthread_t thread; rtlsdr_dev_t *dev; int dev_index; }; +// Register I/O +static int rtl28xxu_wr_regs(struct dongle_state *d, uint16_t reg, uint8_t *val, int len) +{ + /* TODO + struct rtl28xxu_req req; + + if (reg < 0x3000) + req.index = CMD_USB_WR; + else if (reg < 0x4000) + req.index = CMD_SYS_WR; + else + req.index = CMD_IR_WR; + + req.value = reg; + req.size = len; + req.data = val; + + return rtl28xxu_ctrl_msg(d, &req); + */ +} + +static int rtl28xxu_rd_regs(struct dongle_state *d, uint16_t reg, uint8_t *val, int len) +{ + /* TODO + struct rtl28xxu_req req; + + if (reg < 0x3000) + req.index = CMD_USB_RD; + else if (reg < 0x4000) + req.index = CMD_SYS_RD; + else + req.index = CMD_IR_RD; + + req.value = reg; + req.size = len; + req.data = val; + + return rtl28xxu_ctrl_msg(d, &req); + */ +} + +static int rtl28xxu_wr_reg(struct dongle_state *d, uint16_t reg, uint8_t val) +{ + return rtl28xxu_wr_regs(d, reg, &val, 1); +} + +static int rtl28xxu_rd_reg(struct dongle_state *d, uint16_t reg, uint8_t *val) +{ + return rtl28xxu_rd_regs(d, reg, val, 1); +} + +static int rtl28xxu_wr_reg_mask(struct dongle_state *d, uint16_t reg, uint8_t val, + uint8_t mask) +{ + int ret; + uint8_t tmp; + + /* no need for read if whole reg is written */ + if (mask != 0xff) { + ret = rtl28xxu_rd_reg(d, reg, &tmp); + if (ret) + return ret; + + val &= mask; + tmp &= ~mask; + val |= tmp; + } + + return rtl28xxu_wr_reg(d, reg, val); +} + +struct rtlsdr_dev2 { + libusb_context *ctx; + struct libusb_device_handle *devh; +}; + void dongle_init(struct dongle_state *s) { - s->dev_index = 0; + bzero(s, sizeof(struct dongle_state)); } struct dongle_state dongle; @@ -103,6 +350,98 @@ static void *dongle_thread_fn(void *arg) return 0; } +static int rtl2832u_rc_query(struct dongle_state *d) +{ + int ret, i, len; + rtlsdr_dev_t *dev = d->dev; + uint8_t buf[128]; + static const struct rtl28xxu_reg_val_mask refresh_tab[] = { + {IR_RX_IF, 0x03, 0xff}, + {IR_RX_BUF_CTRL, 0x80, 0xff}, + {IR_RX_CTRL, 0x80, 0xff}, + }; + + /* init remote controller */ + if (!d->rc_active) { + static const struct rtl28xxu_reg_val_mask init_tab[] = { + {SYS_DEMOD_CTL1, 0x00, 0x04}, + {SYS_DEMOD_CTL1, 0x00, 0x08}, + {USB_CTRL, 0x20, 0x20}, + {SYS_GPIO_DIR, 0x00, 0x08}, + {SYS_GPIO_OUT_EN, 0x08, 0x08}, + {SYS_GPIO_OUT_VAL, 0x08, 0x08}, + {IR_MAX_DURATION0, 0xd0, 0xff}, + {IR_MAX_DURATION1, 0x07, 0xff}, + {IR_IDLE_LEN0, 0xc0, 0xff}, + {IR_IDLE_LEN1, 0x00, 0xff}, + {IR_GLITCH_LEN, 0x03, 0xff}, + {IR_RX_CLK, 0x09, 0xff}, + {IR_RX_CFG, 0x1c, 0xff}, + {IR_MAX_H_TOL_LEN, 0x1e, 0xff}, + {IR_MAX_L_TOL_LEN, 0x1e, 0xff}, + {IR_RX_CTRL, 0x80, 0xff}, + }; + + for (i = 0; i < ARRAY_SIZE(init_tab); i++) { + ret = rtl28xxu_wr_reg_mask(d, init_tab[i].reg, + init_tab[i].val, init_tab[i].mask); + if (ret) + goto err; + } + + d->rc_active = 1; + } + + ret = rtl28xxu_rd_reg(d, IR_RX_IF, &buf[0]); + if (ret) + goto err; + + if (buf[0] != 0x83) + goto exit; + + ret = rtl28xxu_rd_reg(d, IR_RX_BC, &buf[0]); + if (ret) + goto err; + + len = buf[0]; + + /* read raw code from hw */ + ret = rtl28xxu_rd_regs(d, IR_RX_BUF, buf, len); + if (ret) + goto err; + + /* let hw receive new code */ + for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) { + ret = rtl28xxu_wr_reg_mask(d, refresh_tab[i].reg, + refresh_tab[i].val, refresh_tab[i].mask); + if (ret) + goto err; + } + + /* pass data to Kernel IR decoder */ + //TODO init_ir_raw_event(&ev); + + printf("IR: \n"); + for (i = 0; i < len; i++) { + //ev.pulse = buf[i] >> 7; + //ev.duration = 50800 * (buf[i] & 0x7f); + + printf("pulse %d, duration %d\n", buf[i] >> 7, 50800 * (buf[i] & 0x7f)); + //TODO + //ir_raw_event_store_with_filter(d->rc_dev, &ev); + } + + /* 'flush' ir_raw_event_store_with_filter() */ + /*TODO + ir_raw_event_set_idle(d->rc_dev, true); + ir_raw_event_handle(d->rc_dev); + */ +exit: + return ret; +err: + //dev_dbg(&d->intf->dev, "failed=%d\n", ret); + return ret; +} int main(int argc, char **argv) { #ifndef _WIN32 From 4ca84aedaf03b1eb56bb135542e860d8b30abc63 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 18:39:25 -0700 Subject: [PATCH 54/74] Add infrared block USB control message indexes Most of the indexes are x<<8 for write, (x<<8)|0x10 for read, but not IR. From https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h#L63-L66 #define CMD_SYS_RD 0x0200 #define CMD_IR_RD 0x0201 #define CMD_IR_WR 0x0211 #define CMD_SYS_WR 0x0210 --- src/librtlsdr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 1338fce..7cb9abd 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -454,6 +454,8 @@ int rtlsdr_read_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t * int r; uint16_t index = (block << 8); + if (block == IRB) index = (SYSB << 8) | 0x01; + r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, array, len, CTRL_TIMEOUT); #if 0 if (r < 0) @@ -467,6 +469,8 @@ int rtlsdr_write_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t int r; uint16_t index = (block << 8) | 0x10; + if (block == IRB) index = (SYSB << 8) | 0x11; + r = libusb_control_transfer(dev->devh, CTRL_OUT, 0, addr, index, array, len, CTRL_TIMEOUT); #if 0 if (r < 0) From 70a34fdf0c44854ffa8b565c4ea99a83cce91dcd Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 20:07:17 -0700 Subject: [PATCH 55/74] Begin integrating IR from dvb_usb_rtl28xxu into librtlsdr --- src/librtlsdr.c | 169 ++++++++++++++++++++++++ src/rtl_ir.c | 335 ------------------------------------------------ 2 files changed, 169 insertions(+), 335 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 7cb9abd..a1c899c 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -124,6 +124,7 @@ struct rtlsdr_dev { int dev_lost; int driver_active; unsigned int xfer_errors; + int rc_active; }; void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val); @@ -1975,3 +1976,171 @@ int rtlsdr_i2c_read_fn(void *dev, uint8_t addr, uint8_t *buf, int len) return -1; } + + +/* Infrared (IR) sensor support + * based on Linux dvb_usb_rtl28xxu drivers/media/usb/dvb-usb-v2/rtl28xxu.h + * Copyright (C) 2009 Antti Palosaari + * Copyright (C) 2011 Antti Palosaari + * Copyright (C) 2012 Thomas Mair + */ + +struct rtl28xxu_req { + uint16_t value; + uint16_t index; + uint16_t size; + uint8_t *data; +}; + +struct rtl28xxu_reg_val { + uint16_t reg; + uint8_t val; +}; + +struct rtl28xxu_reg_val_mask { + int block; + uint16_t reg; + uint8_t val; + uint8_t mask; +}; + + +static int rtl28xxu_rd_regs(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *val, int len) +{ + /* TODO + struct rtl28xxu_req req; + + if (reg < 0x3000) + req.index = CMD_USB_RD; + else if (reg < 0x4000) + req.index = CMD_SYS_RD; + else + req.index = CMD_IR_RD; + + req.value = reg; + req.size = len; + req.data = val; + + return rtl28xxu_ctrl_msg(d, &req); + */ + + // TODO + //uint16_t ret = rtlsdr_read_reg(d, block, reg, len); +} + +static int rtl28xxu_rd_reg(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *val) +{ + return rtl28xxu_rd_regs(d, block, reg, val, 1); +} + +// TODO: rename rtlsdr_write_reg_mask? +static int rtl28xxu_wr_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val, + uint8_t mask) +{ + int ret; + uint8_t tmp; + + /* no need for read if whole reg is written */ + if (mask != 0xff) { + tmp = rtlsdr_read_reg(d, block, reg, 1); + + val &= mask; + tmp &= ~mask; + val |= tmp; + } + + return rtlsdr_write_reg(d, block, reg, (uint16_t)val, 1); +} + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static int rtl2832u_rc_query(rtlsdr_dev_t *d) +{ + int ret, i, len; + uint8_t buf[128]; + static const struct rtl28xxu_reg_val_mask refresh_tab[] = { + {IRB, IR_RX_IF, 0x03, 0xff}, + {IRB, IR_RX_BUF_CTRL, 0x80, 0xff}, + {IRB, IR_RX_CTRL, 0x80, 0xff}, + }; + + /* init remote controller */ + if (!d->rc_active) { + static const struct rtl28xxu_reg_val_mask init_tab[] = { + {USBB, DEMOD_CTL, 0x00, 0x04}, + {USBB, DEMOD_CTL, 0x00, 0x08}, + {USBB, USB_CTRL, 0x20, 0x20}, + {USBB, GPD, 0x00, 0x08}, + {USBB, GPOE, 0x08, 0x08}, + {USBB, GPO, 0x08, 0x08}, + {IRB, IR_MAX_DURATION0, 0xd0, 0xff}, + {IRB, IR_MAX_DURATION1, 0x07, 0xff}, + {IRB, IR_IDLE_LEN0, 0xc0, 0xff}, + {IRB, IR_IDLE_LEN1, 0x00, 0xff}, + {IRB, IR_GLITCH_LEN, 0x03, 0xff}, + {IRB, IR_RX_CLK, 0x09, 0xff}, + {IRB, IR_RX_CFG, 0x1c, 0xff}, + {IRB, IR_MAX_H_TOL_LEN, 0x1e, 0xff}, + {IRB, IR_MAX_L_TOL_LEN, 0x1e, 0xff}, + {IRB, IR_RX_CTRL, 0x80, 0xff}, + }; + + for (i = 0; i < ARRAY_SIZE(init_tab); i++) { + ret = rtl28xxu_wr_reg_mask(d, init_tab[i].block, init_tab[i].reg, + init_tab[i].val, init_tab[i].mask); + if (ret) + goto err; + } + + d->rc_active = 1; + } + + buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); + + if (buf[0] != 0x83) + goto exit; + + buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_BC, 1); + + len = buf[0]; + printf("len=%d\n", len); + + /* read raw code from hw */ + //TODO: read regs? can rtlsdr_read_reg handle len>2? + ret = rtl28xxu_rd_regs(d, IRB, IR_RX_BUF, buf, len); + if (ret) + goto err; + + /* let hw receive new code */ + for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) { + ret = rtl28xxu_wr_reg_mask(d, refresh_tab[i].block, refresh_tab[i].reg, + refresh_tab[i].val, refresh_tab[i].mask); + if (ret) + goto err; + } + + /* pass data to Kernel IR decoder */ + //TODO init_ir_raw_event(&ev); + + printf("IR: \n"); + for (i = 0; i < len; i++) { + //ev.pulse = buf[i] >> 7; + //ev.duration = 50800 * (buf[i] & 0x7f); + + printf("pulse %d, duration %d\n", buf[i] >> 7, 50800 * (buf[i] & 0x7f)); + //TODO + //ir_raw_event_store_with_filter(d->rc_dev, &ev); + } + + /* 'flush' ir_raw_event_store_with_filter() */ + /*TODO + ir_raw_event_set_idle(d->rc_dev, true); + ir_raw_event_handle(d->rc_dev); + */ +exit: + return ret; +err: + //dev_dbg(&d->intf->dev, "failed=%d\n", ret); + return ret; +} + diff --git a/src/rtl_ir.c b/src/rtl_ir.c index 5ab468c..546bd6a 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -51,173 +51,6 @@ #include "rtl-sdr.h" #include "convenience/convenience.h" -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -// Registers from Linux drivers/media/usb/dvb-usb-v2/rtl28xxu.h TODO: merge into librtlsdr? -struct rtl28xxu_req { - uint16_t value; - uint16_t index; - uint16_t size; - uint8_t *data; -}; - -struct rtl28xxu_reg_val { - uint16_t reg; - uint8_t val; -}; - -struct rtl28xxu_reg_val_mask { - uint16_t reg; - uint8_t val; - uint8_t mask; -}; - -/* - * memory map - * - * 0x0000 DEMOD : demodulator - * 0x2000 USB : SIE, USB endpoint, debug, DMA - * 0x3000 SYS : system - * 0xfc00 RC : remote controller (not RTL2831U) - */ - -/* - * USB registers - */ -/* SIE Control Registers */ -#define USB_SYSCTL 0x2000 /* USB system control */ -#define USB_SYSCTL_0 0x2000 /* USB system control */ -#define USB_SYSCTL_1 0x2001 /* USB system control */ -#define USB_SYSCTL_2 0x2002 /* USB system control */ -#define USB_SYSCTL_3 0x2003 /* USB system control */ -#define USB_IRQSTAT 0x2008 /* SIE interrupt status */ -#define USB_IRQEN 0x200C /* SIE interrupt enable */ -#define USB_CTRL 0x2010 /* USB control */ -#define USB_STAT 0x2014 /* USB status */ -#define USB_DEVADDR 0x2018 /* USB device address */ -#define USB_TEST 0x201C /* USB test mode */ -#define USB_FRAME_NUMBER 0x2020 /* frame number */ -#define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */ -#define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */ -#define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */ -/* Endpoint Registers */ -#define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */ -#define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */ -#define USB_EP0_CFG 0x2104 /* EP 0 configure */ -#define USB_EP0_CTL 0x2108 /* EP 0 control */ -#define USB_EP0_STAT 0x210C /* EP 0 status */ -#define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */ -#define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */ -#define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */ -#define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */ -#define USB_EPA_CFG 0x2144 /* EP A configure */ -#define USB_EPA_CFG_0 0x2144 /* EP A configure */ -#define USB_EPA_CFG_1 0x2145 /* EP A configure */ -#define USB_EPA_CFG_2 0x2146 /* EP A configure */ -#define USB_EPA_CFG_3 0x2147 /* EP A configure */ -#define USB_EPA_CTL 0x2148 /* EP A control */ -#define USB_EPA_CTL_0 0x2148 /* EP A control */ -#define USB_EPA_CTL_1 0x2149 /* EP A control */ -#define USB_EPA_CTL_2 0x214A /* EP A control */ -#define USB_EPA_CTL_3 0x214B /* EP A control */ -#define USB_EPA_STAT 0x214C /* EP A status */ -#define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */ -#define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */ -#define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */ -#define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */ -#define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */ -#define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */ -#define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */ -#define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */ -#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */ -#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */ -#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */ -#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */ -/* Debug Registers */ -#define USB_PHYTSTDIS 0x2F04 /* PHY test disable */ -#define USB_TOUT_VAL 0x2F08 /* USB time-out time */ -#define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */ -#define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */ -#define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */ -#define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */ -#define USB_UTMI_TST 0x2F80 /* UTMI test */ -#define USB_UTMI_STATUS 0x2F84 /* UTMI status */ -#define USB_TSTCTL 0x2F88 /* test control */ -#define USB_TSTCTL2 0x2F8C /* test control 2 */ -#define USB_PID_FORCE 0x2F90 /* force PID */ -#define USB_PKTERR_CNT 0x2F94 /* packet error counter */ -#define USB_RXERR_CNT 0x2F98 /* RX error counter */ -#define USB_MEM_BIST 0x2F9C /* MEM BIST test */ -#define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */ -#define USB_CNTTEST 0x2FA4 /* counter test */ -#define USB_PHYTST 0x2FC0 /* USB PHY test */ -#define USB_DBGIDX 0x2FF0 /* select individual block debug signal */ -#define USB_DBGMUX 0x2FF4 /* debug signal module mux */ - -/* - * SYS registers - */ -/* demod control registers */ -#define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */ -#define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */ -/* GPIO registers */ -#define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */ -#define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */ -#define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */ -#define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */ -#define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */ -#define SYS_SYSINTE 0x3005 /* system interrupt enable */ -#define SYS_SYSINTS 0x3006 /* system interrupt status */ -#define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */ -#define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */ -#define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */ -#define SYS_DEMOD_CTL1 0x300B - -/* IrDA registers */ -#define SYS_IRRC_PSR 0x3020 /* IR protocol selection */ -#define SYS_IRRC_PER 0x3024 /* IR protocol extension */ -#define SYS_IRRC_SF 0x3028 /* IR sampling frequency */ -#define SYS_IRRC_DPIR 0x302C /* IR data package interval */ -#define SYS_IRRC_CR 0x3030 /* IR control */ -#define SYS_IRRC_RP 0x3034 /* IR read port */ -#define SYS_IRRC_SR 0x3038 /* IR status */ -/* I2C master registers */ -#define SYS_I2CCR 0x3040 /* I2C clock */ -#define SYS_I2CMCR 0x3044 /* I2C master control */ -#define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */ -#define SYS_I2CMSR 0x304C /* I2C master status */ -#define SYS_I2CMFR 0x3050 /* I2C master FIFO */ - -/* - * IR registers - */ -#define IR_RX_BUF 0xFC00 -#define IR_RX_IE 0xFD00 -#define IR_RX_IF 0xFD01 -#define IR_RX_CTRL 0xFD02 -#define IR_RX_CFG 0xFD03 -#define IR_MAX_DURATION0 0xFD04 -#define IR_MAX_DURATION1 0xFD05 -#define IR_IDLE_LEN0 0xFD06 -#define IR_IDLE_LEN1 0xFD07 -#define IR_GLITCH_LEN 0xFD08 -#define IR_RX_BUF_CTRL 0xFD09 -#define IR_RX_BUF_DATA 0xFD0A -#define IR_RX_BC 0xFD0B -#define IR_RX_CLK 0xFD0C -#define IR_RX_C_COUNT_L 0xFD0D -#define IR_RX_C_COUNT_H 0xFD0E -#define IR_SUSPEND_CTRL 0xFD10 -#define IR_ERR_TOL_CTRL 0xFD11 -#define IR_UNIT_LEN 0xFD12 -#define IR_ERR_TOL_LEN 0xFD13 -#define IR_MAX_H_TOL_LEN 0xFD14 -#define IR_MAX_L_TOL_LEN 0xFD15 -#define IR_MASK_CTRL 0xFD16 -#define IR_MASK_DATA 0xFD17 -#define IR_RES_MASK_ADDR 0xFD18 -#define IR_RES_MASK_T_LEN 0xFD19 - static volatile int do_exit = 0; struct dongle_state @@ -229,82 +62,6 @@ struct dongle_state int dev_index; }; -// Register I/O -static int rtl28xxu_wr_regs(struct dongle_state *d, uint16_t reg, uint8_t *val, int len) -{ - /* TODO - struct rtl28xxu_req req; - - if (reg < 0x3000) - req.index = CMD_USB_WR; - else if (reg < 0x4000) - req.index = CMD_SYS_WR; - else - req.index = CMD_IR_WR; - - req.value = reg; - req.size = len; - req.data = val; - - return rtl28xxu_ctrl_msg(d, &req); - */ -} - -static int rtl28xxu_rd_regs(struct dongle_state *d, uint16_t reg, uint8_t *val, int len) -{ - /* TODO - struct rtl28xxu_req req; - - if (reg < 0x3000) - req.index = CMD_USB_RD; - else if (reg < 0x4000) - req.index = CMD_SYS_RD; - else - req.index = CMD_IR_RD; - - req.value = reg; - req.size = len; - req.data = val; - - return rtl28xxu_ctrl_msg(d, &req); - */ -} - -static int rtl28xxu_wr_reg(struct dongle_state *d, uint16_t reg, uint8_t val) -{ - return rtl28xxu_wr_regs(d, reg, &val, 1); -} - -static int rtl28xxu_rd_reg(struct dongle_state *d, uint16_t reg, uint8_t *val) -{ - return rtl28xxu_rd_regs(d, reg, val, 1); -} - -static int rtl28xxu_wr_reg_mask(struct dongle_state *d, uint16_t reg, uint8_t val, - uint8_t mask) -{ - int ret; - uint8_t tmp; - - /* no need for read if whole reg is written */ - if (mask != 0xff) { - ret = rtl28xxu_rd_reg(d, reg, &tmp); - if (ret) - return ret; - - val &= mask; - tmp &= ~mask; - val |= tmp; - } - - return rtl28xxu_wr_reg(d, reg, val); -} - -struct rtlsdr_dev2 { - libusb_context *ctx; - struct libusb_device_handle *devh; -}; - void dongle_init(struct dongle_state *s) { bzero(s, sizeof(struct dongle_state)); @@ -350,98 +107,6 @@ static void *dongle_thread_fn(void *arg) return 0; } -static int rtl2832u_rc_query(struct dongle_state *d) -{ - int ret, i, len; - rtlsdr_dev_t *dev = d->dev; - uint8_t buf[128]; - static const struct rtl28xxu_reg_val_mask refresh_tab[] = { - {IR_RX_IF, 0x03, 0xff}, - {IR_RX_BUF_CTRL, 0x80, 0xff}, - {IR_RX_CTRL, 0x80, 0xff}, - }; - - /* init remote controller */ - if (!d->rc_active) { - static const struct rtl28xxu_reg_val_mask init_tab[] = { - {SYS_DEMOD_CTL1, 0x00, 0x04}, - {SYS_DEMOD_CTL1, 0x00, 0x08}, - {USB_CTRL, 0x20, 0x20}, - {SYS_GPIO_DIR, 0x00, 0x08}, - {SYS_GPIO_OUT_EN, 0x08, 0x08}, - {SYS_GPIO_OUT_VAL, 0x08, 0x08}, - {IR_MAX_DURATION0, 0xd0, 0xff}, - {IR_MAX_DURATION1, 0x07, 0xff}, - {IR_IDLE_LEN0, 0xc0, 0xff}, - {IR_IDLE_LEN1, 0x00, 0xff}, - {IR_GLITCH_LEN, 0x03, 0xff}, - {IR_RX_CLK, 0x09, 0xff}, - {IR_RX_CFG, 0x1c, 0xff}, - {IR_MAX_H_TOL_LEN, 0x1e, 0xff}, - {IR_MAX_L_TOL_LEN, 0x1e, 0xff}, - {IR_RX_CTRL, 0x80, 0xff}, - }; - - for (i = 0; i < ARRAY_SIZE(init_tab); i++) { - ret = rtl28xxu_wr_reg_mask(d, init_tab[i].reg, - init_tab[i].val, init_tab[i].mask); - if (ret) - goto err; - } - - d->rc_active = 1; - } - - ret = rtl28xxu_rd_reg(d, IR_RX_IF, &buf[0]); - if (ret) - goto err; - - if (buf[0] != 0x83) - goto exit; - - ret = rtl28xxu_rd_reg(d, IR_RX_BC, &buf[0]); - if (ret) - goto err; - - len = buf[0]; - - /* read raw code from hw */ - ret = rtl28xxu_rd_regs(d, IR_RX_BUF, buf, len); - if (ret) - goto err; - - /* let hw receive new code */ - for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) { - ret = rtl28xxu_wr_reg_mask(d, refresh_tab[i].reg, - refresh_tab[i].val, refresh_tab[i].mask); - if (ret) - goto err; - } - - /* pass data to Kernel IR decoder */ - //TODO init_ir_raw_event(&ev); - - printf("IR: \n"); - for (i = 0; i < len; i++) { - //ev.pulse = buf[i] >> 7; - //ev.duration = 50800 * (buf[i] & 0x7f); - - printf("pulse %d, duration %d\n", buf[i] >> 7, 50800 * (buf[i] & 0x7f)); - //TODO - //ir_raw_event_store_with_filter(d->rc_dev, &ev); - } - - /* 'flush' ir_raw_event_store_with_filter() */ - /*TODO - ir_raw_event_set_idle(d->rc_dev, true); - ir_raw_event_handle(d->rc_dev); - */ -exit: - return ret; -err: - //dev_dbg(&d->intf->dev, "failed=%d\n", ret); - return ret; -} int main(int argc, char **argv) { #ifndef _WIN32 From 45abfbeb5b4ff7c291e5e9f66f20e5985f1e3627 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 20:15:17 -0700 Subject: [PATCH 56/74] Fix rtl28xxu_wr_reg_mask return code, now <0 is error --- include/rtl-sdr.h | 4 ++++ src/librtlsdr.c | 13 +++++++++---- src/rtl_ir.c | 3 +++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index fe64bea..07d0ef5 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -380,6 +380,10 @@ RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev, */ RTLSDR_API int rtlsdr_cancel_async(rtlsdr_dev_t *dev); +/*! + */ +RTLSDR_API int rtlsdr_ir_query(rtlsdr_dev_t *dev); + #ifdef __cplusplus } #endif diff --git a/src/librtlsdr.c b/src/librtlsdr.c index a1c899c..df51696 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2054,7 +2054,7 @@ static int rtl28xxu_wr_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -static int rtl2832u_rc_query(rtlsdr_dev_t *d) +int rtlsdr_ir_query(rtlsdr_dev_t *d) { int ret, i, len; uint8_t buf[128]; @@ -2066,6 +2066,7 @@ static int rtl2832u_rc_query(rtlsdr_dev_t *d) /* init remote controller */ if (!d->rc_active) { + printf("initializing remote controller\n"); static const struct rtl28xxu_reg_val_mask init_tab[] = { {USBB, DEMOD_CTL, 0x00, 0x04}, {USBB, DEMOD_CTL, 0x00, 0x08}, @@ -2088,11 +2089,15 @@ static int rtl2832u_rc_query(rtlsdr_dev_t *d) for (i = 0; i < ARRAY_SIZE(init_tab); i++) { ret = rtl28xxu_wr_reg_mask(d, init_tab[i].block, init_tab[i].reg, init_tab[i].val, init_tab[i].mask); - if (ret) + if (ret < 0) { + printf("write %d reg %d %.4x %.2x %.2x failed\n", i, init_tab[i].block, + init_tab[i].reg, init_tab[i].val, init_tab[i].mask); goto err; + } } d->rc_active = 1; + printf("rc active\n"); } buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); @@ -2115,7 +2120,7 @@ static int rtl2832u_rc_query(rtlsdr_dev_t *d) for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) { ret = rtl28xxu_wr_reg_mask(d, refresh_tab[i].block, refresh_tab[i].reg, refresh_tab[i].val, refresh_tab[i].mask); - if (ret) + if (ret < 0) goto err; } @@ -2140,7 +2145,7 @@ static int rtl2832u_rc_query(rtlsdr_dev_t *d) exit: return ret; err: - //dev_dbg(&d->intf->dev, "failed=%d\n", ret); + printf("failed=%d\n", ret); return ret; } diff --git a/src/rtl_ir.c b/src/rtl_ir.c index 546bd6a..bcdcb73 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -153,6 +153,9 @@ int main(int argc, char **argv) { verbose_reset_buffer(dongle.dev); usleep(100000); + + printf("rtlsdr_ir_query=%d\n", rtlsdr_ir_query(dongle.dev)); + pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(&dongle)); while (!do_exit) { From 5824c16511ed7a0ee1c261a4a471bf237986bfe4 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 20:16:19 -0700 Subject: [PATCH 57/74] Rename rtl28xxu_wr_reg_mask -> rtlsdr_write_reg_mask --- src/librtlsdr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index df51696..d60fd4c 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2033,8 +2033,7 @@ static int rtl28xxu_rd_reg(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *va return rtl28xxu_rd_regs(d, block, reg, val, 1); } -// TODO: rename rtlsdr_write_reg_mask? -static int rtl28xxu_wr_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val, +static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val, uint8_t mask) { int ret; @@ -2087,7 +2086,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) }; for (i = 0; i < ARRAY_SIZE(init_tab); i++) { - ret = rtl28xxu_wr_reg_mask(d, init_tab[i].block, init_tab[i].reg, + ret = rtlsdr_write_reg_mask(d, init_tab[i].block, init_tab[i].reg, init_tab[i].val, init_tab[i].mask); if (ret < 0) { printf("write %d reg %d %.4x %.2x %.2x failed\n", i, init_tab[i].block, @@ -2118,7 +2117,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) /* let hw receive new code */ for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) { - ret = rtl28xxu_wr_reg_mask(d, refresh_tab[i].block, refresh_tab[i].reg, + ret = rtlsdr_write_reg_mask(d, refresh_tab[i].block, refresh_tab[i].reg, refresh_tab[i].val, refresh_tab[i].mask); if (ret < 0) goto err; From d7a7a0845d32da86cccc932da587fd290d82237e Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 20:25:02 -0700 Subject: [PATCH 58/74] Fix IR block claculation for read/write registers non-array --- src/librtlsdr.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index d60fd4c..069a3f8 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -454,7 +454,6 @@ int rtlsdr_read_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t * { int r; uint16_t index = (block << 8); - if (block == IRB) index = (SYSB << 8) | 0x01; r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, array, len, CTRL_TIMEOUT); @@ -469,7 +468,6 @@ int rtlsdr_write_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t { int r; uint16_t index = (block << 8) | 0x10; - if (block == IRB) index = (SYSB << 8) | 0x11; r = libusb_control_transfer(dev->devh, CTRL_OUT, 0, addr, index, array, len, CTRL_TIMEOUT); @@ -526,6 +524,7 @@ uint16_t rtlsdr_read_reg(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_ int r; unsigned char data[2]; uint16_t index = (block << 8); + if (block == IRB) index = (SYSB << 8) | 0x01; uint16_t reg; r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, data, len, CTRL_TIMEOUT); @@ -544,6 +543,7 @@ int rtlsdr_write_reg(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint16_t v unsigned char data[2]; uint16_t index = (block << 8) | 0x10; + if (block == IRB) index = (SYSB << 8) | 0x11; if (len == 1) data[0] = val & 0xff; @@ -2028,11 +2028,6 @@ static int rtl28xxu_rd_regs(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *v //uint16_t ret = rtlsdr_read_reg(d, block, reg, len); } -static int rtl28xxu_rd_reg(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *val) -{ - return rtl28xxu_rd_regs(d, block, reg, val, 1); -} - static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val, uint8_t mask) { From 05649bfaf9fb785f77a52f806bab3cd116d4d1ee Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 21:15:58 -0700 Subject: [PATCH 59/74] Add rtlsdr_read_regs to read IR data into buffer --- src/librtlsdr.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 069a3f8..9d6da79 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2004,6 +2004,19 @@ struct rtl28xxu_reg_val_mask { uint8_t mask; }; +static int rtlsdr_read_regs(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t *data, uint8_t len) +{ + int r; + uint16_t index = (block << 8); + if (block == IRB) index = (SYSB << 8) | 0x01; + + r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, data, len, CTRL_TIMEOUT); + + if (r < 0) + fprintf(stderr, "%s failed with %d\n", __FUNCTION__, r); + + return r; +} static int rtl28xxu_rd_regs(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *val, int len) { @@ -2084,7 +2097,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) ret = rtlsdr_write_reg_mask(d, init_tab[i].block, init_tab[i].reg, init_tab[i].val, init_tab[i].mask); if (ret < 0) { - printf("write %d reg %d %.4x %.2x %.2x failed\n", i, init_tab[i].block, + fprintf(stderr, "write %d reg %d %.4x %.2x %.2x failed\n", i, init_tab[i].block, init_tab[i].reg, init_tab[i].val, init_tab[i].mask); goto err; } @@ -2096,18 +2109,25 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); - if (buf[0] != 0x83) + if (buf[0] != 0x83) { + fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); + // if 0, no IR TODO: gracefully return goto exit; + } buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_BC, 1); len = buf[0]; - printf("len=%d\n", len); + fprintf(stderr, "read IR_RX_BC len=%d\n", len); + + if (len > sizeof(buf)) { + fprintf(stderr, "read IR_RX_BC too large for buffer %lu\n", sizeof(buf)); + goto exit; + } /* read raw code from hw */ - //TODO: read regs? can rtlsdr_read_reg handle len>2? - ret = rtl28xxu_rd_regs(d, IRB, IR_RX_BUF, buf, len); - if (ret) + ret = rtlsdr_read_regs(d, IRB, IR_RX_BUF, buf, len); + if (ret < 0) goto err; /* let hw receive new code */ @@ -2126,7 +2146,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) //ev.pulse = buf[i] >> 7; //ev.duration = 50800 * (buf[i] & 0x7f); - printf("pulse %d, duration %d\n", buf[i] >> 7, 50800 * (buf[i] & 0x7f)); + printf("pulse %d, duration %d\n", buf[i] >> 7, buf[i] & 0x7f); //TODO //ir_raw_event_store_with_filter(d->rc_dev, &ev); } From ed6c2deb9a901f6572641725c2315c4c852900b3 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 22:13:08 -0700 Subject: [PATCH 60/74] rtl_ir: query IR in a loop --- include/rtl-sdr.h | 4 ++++ src/librtlsdr.c | 33 ++++++++++++++++++--------------- src/rtl_ir.c | 39 ++++++++++++++++++++------------------- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 07d0ef5..e85fd68 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -381,6 +381,10 @@ RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev, RTLSDR_API int rtlsdr_cancel_async(rtlsdr_dev_t *dev); /*! + * Read from the remote control (RC) infrared (IR) sensor + * + * \param dev the device handle given by rtlsdr_open() + * \return 0 if no signal */ RTLSDR_API int rtlsdr_ir_query(rtlsdr_dev_t *dev); diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 9d6da79..a4b06cc 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2063,7 +2063,7 @@ static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8 int rtlsdr_ir_query(rtlsdr_dev_t *d) { - int ret, i, len; + int ret = -1, i, len; uint8_t buf[128]; static const struct rtl28xxu_reg_val_mask refresh_tab[] = { {IRB, IR_RX_IF, 0x03, 0xff}, @@ -2110,15 +2110,22 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); if (buf[0] != 0x83) { + + if (buf[0] == 0) { + // no IR signal, graceful exit + ret = 0; + goto exit; + } + fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); - // if 0, no IR TODO: gracefully return + // TODO: what is 0x81? goto exit; } buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_BC, 1); len = buf[0]; - fprintf(stderr, "read IR_RX_BC len=%d\n", len); + //fprintf(stderr, "read IR_RX_BC len=%d\n", len); if (len > sizeof(buf)) { fprintf(stderr, "read IR_RX_BC too large for buffer %lu\n", sizeof(buf)); @@ -2138,24 +2145,20 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) goto err; } - /* pass data to Kernel IR decoder */ - //TODO init_ir_raw_event(&ev); - - printf("IR: \n"); + //printf("IR: \n"); for (i = 0; i < len; i++) { //ev.pulse = buf[i] >> 7; //ev.duration = 50800 * (buf[i] & 0x7f); - printf("pulse %d, duration %d\n", buf[i] >> 7, buf[i] & 0x7f); - //TODO - //ir_raw_event_store_with_filter(d->rc_dev, &ev); + // TODO: return this data from this function + int pulse = buf[i] >> 7; + int duration = buf[i] & 0x7f; + //printf("pulse %d, duration %d\n", pulse, duration); + + for (int j = 0; j < duration; ++j) printf("%d", pulse); } + printf("\n"); - /* 'flush' ir_raw_event_store_with_filter() */ - /*TODO - ir_raw_event_set_idle(d->rc_dev, true); - ir_raw_event_handle(d->rc_dev); - */ exit: return ret; err: diff --git a/src/rtl_ir.c b/src/rtl_ir.c index bcdcb73..caf3c54 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -45,7 +45,6 @@ #endif #include -#include #include #include "rtl-sdr.h" @@ -57,7 +56,6 @@ struct dongle_state { int exit_flag; int rc_active; - pthread_t thread; rtlsdr_dev_t *dev; int dev_index; }; @@ -74,7 +72,10 @@ void usage(void) fprintf(stderr, "rtl_ir\n\n" "Use:\trtl_ir [-options]\n" - "\t[-d device_index (default: 0)]\n"); + "\t[-d device_index (default: 0)]\n" + "\t[-w wait_usec]\tDelay to wait before each iteration (10000)\n" + "\t[-c max_count]\tMaximum number of loop iterations (0)\n" + ); exit(1); } @@ -99,14 +100,6 @@ static void sighandler(int signum) } #endif -static void *dongle_thread_fn(void *arg) -{ - struct dongle_state *s = arg; - printf("TODO\n"); - //rtlsdr_read_async(s->dev, rtlsdr_callback, s, 0, s->buf_len); - return 0; -} - int main(int argc, char **argv) { #ifndef _WIN32 @@ -114,14 +107,22 @@ int main(int argc, char **argv) { #endif int r, opt; int dev_given = 0; + unsigned int wait_usec = 100000; + int max_count = 0, iteration_count = 0; dongle_init(&dongle); - while ((opt = getopt(argc, argv, "d:h")) != -1) { + while ((opt = getopt(argc, argv, "d:c:w:h")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); dev_given = 1; break; + case 'w': + wait_usec = atoi(optarg); + break; + case 'c': + max_count = atoi(optarg); + break; case 'h': default: usage(); @@ -152,14 +153,15 @@ int main(int argc, char **argv) { verbose_reset_buffer(dongle.dev); - usleep(100000); - - printf("rtlsdr_ir_query=%d\n", rtlsdr_ir_query(dongle.dev)); + while (!do_exit) { + usleep(wait_usec); - pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(&dongle)); + r = rtlsdr_ir_query(dongle.dev); + if (r < 0) { + fprintf(stderr, "rtlsdr_ir_query failed: %d\n", r); + } - while (!do_exit) { - usleep(100000); + if (max_count != 0 && ++iteration_count >= max_count) do_exit = 1; } if (do_exit) { @@ -168,7 +170,6 @@ int main(int argc, char **argv) { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dongle.dev); - pthread_join(dongle.thread, NULL); rtlsdr_close(dongle.dev); return r >= 0 ? r : -r; From 61d845e69413823912f359505b65e694f957814d Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 23:44:19 -0700 Subject: [PATCH 61/74] rtlsdr_ir_query() returns packed buffer, rtl_ir prints --- include/rtl-sdr.h | 6 +++-- src/librtlsdr.c | 53 ++++++++------------------------------------ src/rtl_ir.c | 56 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 55 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index e85fd68..0798681 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -384,9 +384,11 @@ RTLSDR_API int rtlsdr_cancel_async(rtlsdr_dev_t *dev); * Read from the remote control (RC) infrared (IR) sensor * * \param dev the device handle given by rtlsdr_open() - * \return 0 if no signal + * \param buf buffer to write IR signal (MSB=pulse/space, 7LSB=duration*20usec), recommended 128-bytes + * \param buf_len size of buf + * \return 0 if no signal, >0 number of bytes written into buf, <0 for error */ -RTLSDR_API int rtlsdr_ir_query(rtlsdr_dev_t *dev); +RTLSDR_API int rtlsdr_ir_query(rtlsdr_dev_t *dev, uint8_t *buf, size_t buf_len); #ifdef __cplusplus } diff --git a/src/librtlsdr.c b/src/librtlsdr.c index a4b06cc..c0e8b86 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2018,29 +2018,6 @@ static int rtlsdr_read_regs(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uin return r; } -static int rtl28xxu_rd_regs(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t *val, int len) -{ - /* TODO - struct rtl28xxu_req req; - - if (reg < 0x3000) - req.index = CMD_USB_RD; - else if (reg < 0x4000) - req.index = CMD_SYS_RD; - else - req.index = CMD_IR_RD; - - req.value = reg; - req.size = len; - req.data = val; - - return rtl28xxu_ctrl_msg(d, &req); - */ - - // TODO - //uint16_t ret = rtlsdr_read_reg(d, block, reg, len); -} - static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val, uint8_t mask) { @@ -2061,10 +2038,9 @@ static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -int rtlsdr_ir_query(rtlsdr_dev_t *d) +int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) { int ret = -1, i, len; - uint8_t buf[128]; static const struct rtl28xxu_reg_val_mask refresh_tab[] = { {IRB, IR_RX_IF, 0x03, 0xff}, {IRB, IR_RX_BUF_CTRL, 0x80, 0xff}, @@ -2073,7 +2049,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) /* init remote controller */ if (!d->rc_active) { - printf("initializing remote controller\n"); + //fprintf(stderr, "initializing remote controller\n"); static const struct rtl28xxu_reg_val_mask init_tab[] = { {USBB, DEMOD_CTL, 0x00, 0x04}, {USBB, DEMOD_CTL, 0x00, 0x08}, @@ -2104,8 +2080,9 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) } d->rc_active = 1; - printf("rc active\n"); + //fprintf(stderr, "rc active\n"); } + // TODO: option to ir disable buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); @@ -2118,7 +2095,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) } fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); - // TODO: what is 0x81? + // TODO: what is 0x81? and 0x82? sometimes occurs at edges goto exit; } @@ -2127,8 +2104,8 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) len = buf[0]; //fprintf(stderr, "read IR_RX_BC len=%d\n", len); - if (len > sizeof(buf)) { - fprintf(stderr, "read IR_RX_BC too large for buffer %lu\n", sizeof(buf)); + if (len > buf_len) { + fprintf(stderr, "read IR_RX_BC too large for buffer, %d > %lu\n", len, buf_len); goto exit; } @@ -2145,19 +2122,8 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) goto err; } - //printf("IR: \n"); - for (i = 0; i < len; i++) { - //ev.pulse = buf[i] >> 7; - //ev.duration = 50800 * (buf[i] & 0x7f); - - // TODO: return this data from this function - int pulse = buf[i] >> 7; - int duration = buf[i] & 0x7f; - //printf("pulse %d, duration %d\n", pulse, duration); - - for (int j = 0; j < duration; ++j) printf("%d", pulse); - } - printf("\n"); + // On success return length + ret = len; exit: return ret; @@ -2165,4 +2131,3 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d) printf("failed=%d\n", ret); return ret; } - diff --git a/src/rtl_ir.c b/src/rtl_ir.c index caf3c54..fd851e4 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -55,7 +55,6 @@ static volatile int do_exit = 0; struct dongle_state { int exit_flag; - int rc_active; rtlsdr_dev_t *dev; int dev_index; }; @@ -75,6 +74,10 @@ void usage(void) "\t[-d device_index (default: 0)]\n" "\t[-w wait_usec]\tDelay to wait before each iteration (10000)\n" "\t[-c max_count]\tMaximum number of loop iterations (0)\n" + "\t[-b]\tDisplay output in binary (default), pulse=1, space=0; each 20 usec\n" + "\t[-t]\tDisplay output in text format\n" + "\t[-x]\tDisplay output in raw packed bytes, MSB=pulse/space, 7LSB=duration*20 usec\n" + "\t[-h\t]Help\n" ); exit(1); } @@ -109,9 +112,10 @@ int main(int argc, char **argv) { int dev_given = 0; unsigned int wait_usec = 100000; int max_count = 0, iteration_count = 0; + int output_binary = 0, output_text = 0, output_packed = 0; dongle_init(&dongle); - while ((opt = getopt(argc, argv, "d:c:w:h")) != -1) { + while ((opt = getopt(argc, argv, "d:c:w:btxh")) != -1) { switch (opt) { case 'd': dongle.dev_index = verbose_device_search(optarg); @@ -123,6 +127,15 @@ int main(int argc, char **argv) { case 'c': max_count = atoi(optarg); break; + case 'b': + output_binary = 1; + break; + case 't': + output_text = 1; + break; + case 'x': + output_packed = 1; + break; case 'h': default: usage(); @@ -153,15 +166,40 @@ int main(int argc, char **argv) { verbose_reset_buffer(dongle.dev); + if (!output_binary && !output_text && !output_packed) + output_binary = 1; + + uint8_t buf[128] = { 0 }; + while (!do_exit) { - usleep(wait_usec); + usleep(wait_usec); - r = rtlsdr_ir_query(dongle.dev); - if (r < 0) { - fprintf(stderr, "rtlsdr_ir_query failed: %d\n", r); - } + r = rtlsdr_ir_query(dongle.dev, buf, sizeof(buf)); + if (r < 0) { + fprintf(stderr, "rtlsdr_ir_query failed: %d\n", r); + } + + for (int i = 0; i < r; i++) { + int pulse = buf[i] >> 7; + int duration = buf[i] & 0x7f; + + if (output_text) { + printf("pulse %d, duration %d usec\n", pulse, duration * 20); + } + + if (output_binary) { + for (int j = 0; j < duration; ++j) { + printf("%d", pulse); + } + } + + if (output_packed) { + putchar(buf[i]); + } + } + if (r != 0) printf("\n"); - if (max_count != 0 && ++iteration_count >= max_count) do_exit = 1; + if (max_count != 0 && ++iteration_count >= max_count) do_exit = 1; } if (do_exit) { @@ -174,5 +212,5 @@ int main(int argc, char **argv) { rtlsdr_close(dongle.dev); return r >= 0 ? r : -r; - return 0; + return 0; } From e49367159dd5e520cc1748f787fd27894cf6d017 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 23:48:13 -0700 Subject: [PATCH 62/74] rtl_ir: flush output after writing (so can use with |xxd -b) --- src/rtl_ir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rtl_ir.c b/src/rtl_ir.c index fd851e4..ba8a0fa 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -198,6 +198,7 @@ int main(int argc, char **argv) { } } if (r != 0) printf("\n"); + fflush(stdout); if (max_count != 0 && ++iteration_count >= max_count) do_exit = 1; } From b446cd1eb9c9508514022a42d40ddded5b87c11c Mon Sep 17 00:00:00 2001 From: rxseger Date: Sat, 2 Jul 2016 23:56:57 -0700 Subject: [PATCH 63/74] Read data when IR_RX_IF returns 0x82, 0x81 not only 0x83 --- src/librtlsdr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index c0e8b86..05c8e4c 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2086,7 +2086,12 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); - if (buf[0] != 0x83) { + if (buf[0] != 0x83 // usual + // also observed - with lengths 1, 5, 0.. unknown, sometimes occurs at edges + // pass through anyway in case this data is useful + && buf[0] != 0x82 + && buf[0] != 0x81 + ) { if (buf[0] == 0) { // no IR signal, graceful exit @@ -2095,7 +2100,6 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) } fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); - // TODO: what is 0x81? and 0x82? sometimes occurs at edges goto exit; } From 0cd8007279969bdcc458c996981ce53ffef08a06 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 02:16:43 -0700 Subject: [PATCH 64/74] rtl_tcp: add -I to enable infrared listener port (rtl_ir) --- src/rtl_tcp.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index 317e0f3..9f043cb 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -89,6 +89,8 @@ 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[-I infrared sensor listen port (default: 0=none)]\n" + "\t[-w infrared sensor query wait interval usec (default: 10000)]\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" @@ -362,11 +364,86 @@ static void *command_worker(void *arg) } } +struct ir_thread_data +{ + rtlsdr_dev_t *dev; + SOCKET port; + int wait; + char *addr; +}; + +void *ir_thread_fn(void *arg) +{ + int r = 1; + struct linger ling = {1,0}; + SOCKET listensocket; + SOCKET irsocket; + struct sockaddr_in local, remote; + socklen_t rlen; + uint8_t buf[128]; + int ret = 0; + + struct ir_thread_data *data = (struct ir_thread_data *)arg; + + rtlsdr_dev_t *dev = data->dev; + int port = data->port; + int wait = data->wait; + char *addr = data->addr; + + + memset(&local,0,sizeof(local)); + local.sin_family = AF_INET; + local.sin_port = htons(port); + local.sin_addr.s_addr = inet_addr(addr); + + 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)); + + + while(1) { + printf("listening on IR port %d...\n", port); + listen(listensocket,1); + + irsocket = accept(listensocket,(struct sockaddr *)&remote, &rlen); + setsockopt(irsocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); + + printf("IR client accepted!\n"); + + while(1) { + ret = rtlsdr_ir_query(dev, buf, sizeof(buf)); + if (ret < 0) { + printf("rtlsdr_ir_query error %d\n", ret); + break; + } + + int len = ret; + + ret = send(irsocket, buf, len, 0); + if (ret != len){ + printf("incomplete write to ir client: %d != %d\n", ret,len); + break; + } + + usleep(wait); + } + + closesocket(irsocket); + } + + return 0; +} + int main(int argc, char **argv) { int r, opt, i; char* addr = "127.0.0.1"; int port = 1234; + int port_ir = 0; + int wait_ir = 10000; + pthread_t thread_ir; uint32_t frequency = 100000000, samp_rate = 2048000; struct sockaddr_in local, remote; uint32_t buf_num = 0; @@ -391,7 +468,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:I:w:f:g:s:b:n:d:P:")) != -1) { switch (opt) { case 'd': dev_index = verbose_device_search(optarg); @@ -412,6 +489,12 @@ int main(int argc, char **argv) case 'p': port = atoi(optarg); break; + case 'I': + port_ir = atoi(optarg); + break; + case 'w': + wait_ir = atoi(optarg); + break; case 'b': buf_num = atoi(optarg); break; @@ -502,6 +585,13 @@ int main(int argc, char **argv) pthread_cond_init(&cond, NULL); pthread_cond_init(&exit_cond, NULL); + if (port_ir) { + struct ir_thread_data data = {.dev = dev, .port = port_ir, .wait = wait_ir, .addr = addr}; + + pthread_create(&thread_ir, NULL, &ir_thread_fn, (void *)(&data)); + } + + memset(&local,0,sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons(port); @@ -594,6 +684,7 @@ int main(int argc, char **argv) out: rtlsdr_close(dev); closesocket(listensocket); + //if (port_ir) pthread_join(thread_ir, &status); closesocket(s); #ifdef _WIN32 WSACleanup(); From c45833a765e95812a6cfced069dc1a4c227472ae Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 17:59:24 +0000 Subject: [PATCH 65/74] Fix compile warnings with GCC 4.9.2 --- src/librtlsdr.c | 7 ++++--- src/rtl_ir.c | 9 +++++---- src/rtl_tcp.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 05c8e4c..f55e0ed 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -523,9 +523,9 @@ uint16_t rtlsdr_read_reg(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_ { int r; unsigned char data[2]; + uint16_t reg; uint16_t index = (block << 8); if (block == IRB) index = (SYSB << 8) | 0x01; - uint16_t reg; r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, data, len, CTRL_TIMEOUT); @@ -2040,7 +2040,8 @@ static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8 int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) { - int ret = -1, i, len; + int ret = -1; + size_t i, len; static const struct rtl28xxu_reg_val_mask refresh_tab[] = { {IRB, IR_RX_IF, 0x03, 0xff}, {IRB, IR_RX_BUF_CTRL, 0x80, 0xff}, @@ -2109,7 +2110,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) //fprintf(stderr, "read IR_RX_BC len=%d\n", len); if (len > buf_len) { - fprintf(stderr, "read IR_RX_BC too large for buffer, %d > %lu\n", len, buf_len); + //fprintf(stderr, "read IR_RX_BC too large for buffer, %lu > %lu\n", buf_len, buf_len); goto exit; } diff --git a/src/rtl_ir.c b/src/rtl_ir.c index ba8a0fa..a291cd4 100644 --- a/src/rtl_ir.c +++ b/src/rtl_ir.c @@ -109,10 +109,13 @@ int main(int argc, char **argv) { struct sigaction sigact; #endif int r, opt; + int i, j; int dev_given = 0; unsigned int wait_usec = 100000; int max_count = 0, iteration_count = 0; int output_binary = 0, output_text = 0, output_packed = 0; + uint8_t buf[128] = { 0 }; + dongle_init(&dongle); while ((opt = getopt(argc, argv, "d:c:w:btxh")) != -1) { @@ -169,8 +172,6 @@ int main(int argc, char **argv) { if (!output_binary && !output_text && !output_packed) output_binary = 1; - uint8_t buf[128] = { 0 }; - while (!do_exit) { usleep(wait_usec); @@ -179,7 +180,7 @@ int main(int argc, char **argv) { fprintf(stderr, "rtlsdr_ir_query failed: %d\n", r); } - for (int i = 0; i < r; i++) { + for (i = 0; i < r; i++) { int pulse = buf[i] >> 7; int duration = buf[i] & 0x7f; @@ -188,7 +189,7 @@ int main(int argc, char **argv) { } if (output_binary) { - for (int j = 0; j < duration; ++j) { + for (j = 0; j < duration; ++j) { printf("%d", pulse); } } diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index 9f043cb..6bf227a 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -381,7 +381,7 @@ void *ir_thread_fn(void *arg) struct sockaddr_in local, remote; socklen_t rlen; uint8_t buf[128]; - int ret = 0; + int ret = 0, len; struct ir_thread_data *data = (struct ir_thread_data *)arg; @@ -419,7 +419,7 @@ void *ir_thread_fn(void *arg) break; } - int len = ret; + len = ret; ret = send(irsocket, buf, len, 0); if (ret != len){ From 3ae20729ebc0f8fd92d99b2b57ab657554929a13 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 18:24:57 +0000 Subject: [PATCH 66/74] Do not read when IR_RX_IF returns 0x82/1, fixes -7 libusb timeout on RPi --- src/librtlsdr.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index f55e0ed..fe73f70 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2087,19 +2087,20 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); - if (buf[0] != 0x83 // usual - // also observed - with lengths 1, 5, 0.. unknown, sometimes occurs at edges - // pass through anyway in case this data is useful - && buf[0] != 0x82 - && buf[0] != 0x81 - ) { - + if (buf[0] != 0x83) { if (buf[0] == 0) { // no IR signal, graceful exit ret = 0; goto exit; } + // also observed: 0x82, 0x81 - with lengths 1, 5, 0.. unknown, sometimes occurs at edges + // "IR not ready"? causes a -7 timeout if we read + if (buf[0] == 0x82 || buf[0] == 0x81) { + ret = 0; + goto exit; + } + fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); goto exit; } From c4e955c825ae7f661f0b79551e50a847b9371f5c Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 18:28:16 +0000 Subject: [PATCH 67/74] Only read if IR_RX_BC returns 0x83, to match Linux DVB driver --- src/librtlsdr.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index fe73f70..313f12a 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -2088,20 +2088,16 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) buf[0] = rtlsdr_read_reg(d, IRB, IR_RX_IF, 1); if (buf[0] != 0x83) { - if (buf[0] == 0) { - // no IR signal, graceful exit - ret = 0; - goto exit; - } - - // also observed: 0x82, 0x81 - with lengths 1, 5, 0.. unknown, sometimes occurs at edges - // "IR not ready"? causes a -7 timeout if we read - if (buf[0] == 0x82 || buf[0] == 0x81) { - ret = 0; - goto exit; + if (buf[0] == 0 || // no IR signal + // also observed: 0x82, 0x81 - with lengths 1, 5, 0.. unknown, sometimes occurs at edges + // "IR not ready"? causes a -7 timeout if we read + buf[0] == 0x82 || buf[0] == 0x81) { + // graceful exit + } else { + fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); } - fprintf(stderr, "read IR_RX_IF unexpected: %.2x\n", buf[0]); + ret = 0; goto exit; } From 110c4a56ecfe813c4f85ec9907ea669a28f27af7 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 21:15:02 +0000 Subject: [PATCH 68/74] rtl_rpcd: accept command-line arguments --- src/rtl_rpcd.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 1096e5f..4696fe4 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -1094,16 +1094,46 @@ static int do_rpcd(rpcd_t* rpcd) return 0; } +void usage(void) +{ + fprintf(stderr, + "rtl_rpcd, a Remote Procedure Call server for RTL-SDR dongles\n\n" + "Use:\trtl_rpcd [-options]\n" + "\t[-a address]\tAddress to listen on (default: 0.0.0.0 for all), or RTLSDR_RPC_SERV_ADDR\n" + "\t[-p port]\tPort number to listen on (default: 40000), or RTLSDR_RPC_SERV_PORT\n" + "\t[-h]\t\tHelp\n" + "\n" + "On the remote client, set RTLSDR_RPC_IS_ENABLED and matching address/port\n" + ); + exit(1); +} + int main(int ac, char** av) { rpcd_t rpcd; - const char* addr; - const char* port; + const char* addr = NULL; + const char* port = NULL; + + int opt; + + while ((opt = getopt(ac, av, "a:p:h")) != -1) { + switch (opt) { + case 'a': + addr = optarg; + break; + case 'p': + port = optarg; + break; + case 'h': + default: + usage(); + } + } - addr = getenv("RTLSDR_RPC_SERV_ADDR"); + if (addr == NULL) addr = getenv("RTLSDR_RPC_SERV_ADDR"); if (addr == NULL) addr = "0.0.0.0"; - port = getenv("RTLSDR_RPC_SERV_PORT"); + if (port == NULL) port = getenv("RTLSDR_RPC_SERV_PORT"); if (port == NULL) port = "40000"; if (init_rpcd(&rpcd, addr, port)) return -1; From 04992ac4bddd6857f63289f920b0541b7c13e999 Mon Sep 17 00:00:00 2001 From: rxseger Date: Sun, 3 Jul 2016 21:42:23 +0000 Subject: [PATCH 69/74] rtl_rpcd: add IR listening option --- src/rtl_rpcd.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index 4696fe4..e770cee 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include "rtlsdr_rpc_msg.h" @@ -48,6 +50,9 @@ typedef struct unsigned int async_replied; uint8_t async_id; + int port_ir; + const char *addr_ir; + int wait_ir; } rpcd_t; static int resolve_ip_addr @@ -1101,6 +1106,8 @@ void usage(void) "Use:\trtl_rpcd [-options]\n" "\t[-a address]\tAddress to listen on (default: 0.0.0.0 for all), or RTLSDR_RPC_SERV_ADDR\n" "\t[-p port]\tPort number to listen on (default: 40000), or RTLSDR_RPC_SERV_PORT\n" + "\t[-I port_ir]\tinfrared sensor listen port (default: 0=none)\n" + "\t[-w wait_ir]\tinfrared sensor query wait interval usec (default: 10000)\n" "\t[-h]\t\tHelp\n" "\n" "On the remote client, set RTLSDR_RPC_IS_ENABLED and matching address/port\n" @@ -1108,6 +1115,79 @@ void usage(void) exit(1); } +void *ir_thread_fn(void *arg) +{ + int r = 1; + struct linger ling = {1,0}; + int listensocket; + int irsocket; + struct sockaddr_in local, remote; + socklen_t rlen; + uint8_t buf[128]; + int ret = 0, len; + + rpcd_t *rpcd = (rpcd_t *)arg; + + rtlsdr_dev_t *dev = rpcd->dev; + const char *addr = rpcd->addr_ir; + int port = rpcd->port_ir; + int wait = rpcd->wait_ir; + + + memset(&local,0,sizeof(local)); + local.sin_family = AF_INET; + local.sin_port = htons(port); + local.sin_addr.s_addr = inet_addr(addr); + + 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)); + + + while(1) { + printf("listening on IR port %d...\n", port); + listen(listensocket,1); + + irsocket = accept(listensocket,(struct sockaddr *)&remote, &rlen); + setsockopt(irsocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); + + printf("IR client accepted!\n"); + + while(1) { + dev = rpcd->dev; + if (!dev) { + printf("no device available yet\n"); + // Keep waiting until RPC connects and opens device + usleep(1000000); + continue; + } + + ret = rtlsdr_ir_query(dev, buf, sizeof(buf)); + if (ret < 0) { + printf("rtlsdr_ir_query error %d\n", ret); + break; + } + + len = ret; + + ret = send(irsocket, buf, len, 0); + if (ret != len){ + printf("incomplete write to ir client: %d != %d\n", ret,len); + break; + } + + usleep(wait); + } + + close(irsocket); + } + + return 0; +} + + int main(int ac, char** av) { rpcd_t rpcd; @@ -1115,8 +1195,10 @@ int main(int ac, char** av) const char* port = NULL; int opt; + int port_ir = 0, wait_ir = 10000; + pthread_t thread_ir; - while ((opt = getopt(ac, av, "a:p:h")) != -1) { + while ((opt = getopt(ac, av, "a:p:I:w:h")) != -1) { switch (opt) { case 'a': addr = optarg; @@ -1124,6 +1206,12 @@ int main(int ac, char** av) case 'p': port = optarg; break; + case 'I': + port_ir = atoi(optarg); + break; + case 'w': + wait_ir = atoi(optarg); + break; case 'h': default: usage(); @@ -1137,6 +1225,13 @@ int main(int ac, char** av) if (port == NULL) port = "40000"; if (init_rpcd(&rpcd, addr, port)) return -1; + if (port_ir) { + rpcd.port_ir = port_ir; + rpcd.addr_ir = addr; + rpcd.wait_ir = wait_ir; + pthread_create(&thread_ir, NULL, &ir_thread_fn, (void *)(&rpcd)); + } + do_rpcd(&rpcd); fini_rpcd(&rpcd); From 2316a13bd3d85fcdf64bdc38cf4dc5be279f0297 Mon Sep 17 00:00:00 2001 From: rxseger Date: Mon, 4 Jul 2016 01:36:48 +0000 Subject: [PATCH 70/74] rtl_rpcd: on IR thread, use select() to check if can send instead of blocking forever --- src/rtl_rpcd.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/rtl_rpcd.c b/src/rtl_rpcd.c index e770cee..3c41d13 100644 --- a/src/rtl_rpcd.c +++ b/src/rtl_rpcd.c @@ -1125,6 +1125,8 @@ void *ir_thread_fn(void *arg) socklen_t rlen; uint8_t buf[128]; int ret = 0, len; + struct timeval tv; + fd_set writefds, errorfds; rpcd_t *rpcd = (rpcd_t *)arg; @@ -1170,15 +1172,35 @@ void *ir_thread_fn(void *arg) break; } - len = ret; + len = ret; + FD_ZERO(&writefds); + FD_SET(irsocket, &writefds); + + FD_ZERO(&errorfds); + FD_SET(irsocket, &errorfds); + + tv.tv_sec = 1; + tv.tv_usec = 0; + select(irsocket+1, NULL, &writefds, &errorfds, &tv); + + if (FD_ISSET(irsocket, &errorfds)) { + printf("error condition from irsocket, breaking\n"); + break; + } + + if (FD_ISSET(irsocket, &writefds)) { ret = send(irsocket, buf, len, 0); if (ret != len){ printf("incomplete write to ir client: %d != %d\n", ret,len); break; } + } else { + printf("irsocket not ready to write, breaking\n"); + break; + } - usleep(wait); + usleep(wait); } close(irsocket); From 3cda64cbc3cb9cfa0004a0efbdd6ab5cc4ee78d4 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Fri, 22 Jul 2016 02:02:09 -0300 Subject: [PATCH 71/74] Bug Fix for some Broken MinGW PThreads sources --- CMakeLists.txt | 8 ++++++++ src/rtl_adsb.c | 5 ++++- src/rtl_fm.c | 4 ++++ src/rtl_power.c | 3 +++ src/rtl_tcp.c | 3 +++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0597600..bf216a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,14 @@ if(CMAKE_COMPILER_IS_GNUCC AND NOT WIN32) add_definitions(-fvisibility=hidden) endif() +######################################################################### +# Bug Fix +######################################################################### +OPTION(NEED_PTHREADS_WORKARROUND "PThreads Workarround for timespec") +IF (DEFINED NEED_PTHREADS_WORKARROUND) + ADD_DEFINITIONS(-DNEED_PTHREADS_WORKARROUND) +ENDIF() + ######################################################################## # Find build dependencies ######################################################################## diff --git a/src/rtl_adsb.c b/src/rtl_adsb.c index 2738a9e..fd9e422 100644 --- a/src/rtl_adsb.c +++ b/src/rtl_adsb.c @@ -36,7 +36,10 @@ #include #include "getopt/getopt.h" #endif - + +#ifdef NEED_PTHREADS_WORKARROUND +#define HAVE_STRUCT_TIMESPEC +#endif #include #include diff --git a/src/rtl_fm.c b/src/rtl_fm.c index 80688fa..8e308a7 100644 --- a/src/rtl_fm.c +++ b/src/rtl_fm.c @@ -69,6 +69,10 @@ #define _USE_MATH_DEFINES #endif +#ifdef NEED_PTHREADS_WORKARROUND +#define HAVE_STRUCT_TIMESPEC +#endif + #include #include #include diff --git a/src/rtl_power.c b/src/rtl_power.c index c395f99..96d2b09 100644 --- a/src/rtl_power.c +++ b/src/rtl_power.c @@ -60,6 +60,9 @@ #endif #include +#ifdef NEED_PTHREADS_WORKARROUND +#define HAVE_STRUCT_TIMESPEC +#endif #include #include diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c index f1111f6..0d05e30 100644 --- a/src/rtl_tcp.c +++ b/src/rtl_tcp.c @@ -37,6 +37,9 @@ #include "getopt/getopt.h" #endif +#ifdef NEED_PTHREADS_WORKARROUND +#define HAVE_STRUCT_TIMESPEC +#endif #include #include "rtl-sdr.h" From 3e80bdf9c53efb923f5d38fd66cb426d08654cee Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Fri, 22 Jul 2016 14:48:07 -0300 Subject: [PATCH 72/74] Change version to 0.6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf216a6..4bc4721 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ endif() # Set the version information here set(VERSION_INFO_MAJOR_VERSION 0) # increment major on api compatibility changes -set(VERSION_INFO_MINOR_VERSION 5) # increment minor on feature-level changes +set(VERSION_INFO_MINOR_VERSION 6) # increment minor on feature-level changes set(VERSION_INFO_PATCH_VERSION git) # increment patch for bug fixes and docs include(Version) # setup version info From f0c0e8a9ed873881e78f2cb5fd1ff2b5a5c71397 Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Wed, 17 Aug 2016 10:44:02 -0300 Subject: [PATCH 73/74] Disabling RPC in Windows builds. It uses POSIX calls and we should port it in the future. --- include/rtl-sdr.h | 5 +++ src/CMakeLists.txt | 26 +++++++++++++--- src/librtlsdr.c | 77 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 98 insertions(+), 10 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 4d59c14..09ad2df 100755 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -24,6 +24,11 @@ extern "C" { #endif +#ifndef WIN32 +#define _ENABLE_RPC +#endif + + #include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2b5810..e3718fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ MACRO(RTLSDR_APPEND_SRCS) LIST(APPEND rtlsdr_srcs ${ARGV}) ENDMACRO(RTLSDR_APPEND_SRCS) +if(!WIN32) RTLSDR_APPEND_SRCS( librtlsdr.c tuner_e4k.c @@ -31,6 +32,16 @@ RTLSDR_APPEND_SRCS( rtlsdr_rpc.c rtlsdr_rpc_msg.c ) +else() +RTLSDR_APPEND_SRCS( + librtlsdr.c + tuner_e4k.c + tuner_fc0012.c + tuner_fc0013.c + tuner_fc2580.c + tuner_r82xx.c +) +endif() ######################################################################## # Set up Windows DLL resource files @@ -94,8 +105,12 @@ add_executable(rtl_ir rtl_ir.c) add_executable(rtl_eeprom rtl_eeprom.c) add_executable(rtl_adsb rtl_adsb.c) add_executable(rtl_power rtl_power.c) -add_executable(rtl_rpcd rtl_rpcd.c rtlsdr_rpc_msg.c) -set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power rtl_rpcd) +if (!WIN32) + add_executable(rtl_rpcd rtl_rpcd.c rtlsdr_rpc_msg.c) + set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power rtl_rpcd) +else() + set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power) +endif() target_link_libraries(rtl_sdr rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} @@ -129,10 +144,13 @@ target_link_libraries(rtl_power rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) +if(!WIN32) target_link_libraries(rtl_rpcd rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) +endif() + if(UNIX) target_link_libraries(rtl_fm m) target_link_libraries(rtl_ir m) @@ -154,7 +172,7 @@ target_link_libraries(rtl_ir libgetopt_static) target_link_libraries(rtl_eeprom libgetopt_static) target_link_libraries(rtl_adsb libgetopt_static) target_link_libraries(rtl_power libgetopt_static) -target_link_libraries(rtl_rpcd ws2_32 libgetopt_static) +#target_link_libraries(rtl_rpcd ws2_32 libgetopt_static) set_property(TARGET rtl_sdr APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_tcp APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_test APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) @@ -163,7 +181,7 @@ set_property(TARGET rtl_ir APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_eeprom APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_adsb APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) set_property(TARGET rtl_power APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) -set_property(TARGET rtl_rpcd APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) +#set_property(TARGET rtl_rpcd APPEND PROPERTY COMPILE_DEFINITIONS "rtlsdr_STATIC" ) endif() ######################################################################## # Install built library files & utilities diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 6ac1690..258cf03 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -28,8 +28,9 @@ #endif #include +#ifndef WIN32 #include "rtlsdr_rpc.h" - +#endif /* * All libusb callback functions should be marked with the LIBUSB_CALL macro * to ensure that they are compiled with the same calling convention as libusb. @@ -795,10 +796,12 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr { int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_xtal_freq(dev, rtl_freq, tuner_freq); } + #endif if (!dev) return -1; @@ -836,10 +839,12 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_freq) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_xtal_freq(dev, rtl_freq, tuner_freq); } + #endif if (!dev) return -1; @@ -863,10 +868,12 @@ int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, const int buf_max = 256; int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_usb_strings(dev, manufact, product, serial); } + #endif if (!dev || !dev->devh) return -1; @@ -907,10 +914,12 @@ int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16 int i; uint8_t cmd[2]; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_write_eeprom(dev, data, offset, len); } + #endif if (!dev) return -1; @@ -948,11 +957,12 @@ int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_ { int r = 0; int i; - + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_read_eeprom(dev, data, offset, len); } + #endif if (!dev) return -1; @@ -977,12 +987,12 @@ int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) { int r = -1; - + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_center_freq(dev, freq); } - + #endif if (!dev || !dev->tuner) return -1; @@ -1004,10 +1014,12 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_center_freq(dev); } + #endif if (!dev) return 0; @@ -1018,11 +1030,12 @@ uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev) int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) { int r = 0; - + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_freq_correction(dev, ppm); } + #endif if (!dev) return -1; @@ -1047,10 +1060,12 @@ int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_freq_correction(dev); } + #endif if (!dev) return 0; @@ -1060,10 +1075,12 @@ int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev) enum rtlsdr_tuner rtlsdr_get_tuner_type(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return (enum rtlsdr_tuner)rtlsdr_rpc_get_tuner_type(dev); } + #endif if (!dev) return RTLSDR_TUNER_UNKNOWN; @@ -1090,10 +1107,12 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) const int *ptr = NULL; int len = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_tuner_gains(dev, gains); } + #endif if (!dev) return -1; @@ -1170,10 +1189,12 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) { int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_tuner_gain(dev, gain); } + #endif if (!dev || !dev->tuner) return -1; @@ -1215,10 +1236,12 @@ int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, i int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_tuner_gain(dev); } + #endif if (!dev) return 0; @@ -1230,10 +1253,12 @@ int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain) { int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_tuner_if_gain(dev, stage, gain); } + #endif if (!dev || !dev->tuner) return -1; @@ -1251,10 +1276,12 @@ int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int mode) { int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_tuner_gain_mode(dev, mode); } + #endif if (!dev || !dev->tuner) return -1; @@ -1275,10 +1302,12 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) uint32_t rsamp_ratio, real_rsamp_ratio; double real_rate; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_sample_rate(dev, samp_rate); } + #endif if (!dev) return -1; @@ -1328,10 +1357,12 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_sample_rate(dev); } + #endif if (!dev) return 0; @@ -1341,10 +1372,12 @@ uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev) int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_testmode(dev, on); } + #endif if (!dev) return -1; @@ -1354,10 +1387,12 @@ int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on) int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_agc_mode(dev, on); } + #endif if (!dev) return -1; @@ -1369,10 +1404,12 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) { int r = 0; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_direct_sampling(dev, on); } + #endif if (!dev) return -1; @@ -1435,10 +1472,12 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_direct_sampling(dev); } + #endif if (!dev) return -1; @@ -1451,10 +1490,12 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) int r = 0; int bw; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_set_offset_tuning(dev, on); } + #endif if (!dev) return -1; @@ -1492,10 +1533,12 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) int rtlsdr_get_offset_tuning(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_offset_tuning(dev); } + #endif if (!dev) return -1; @@ -1527,10 +1570,12 @@ uint32_t rtlsdr_get_device_count(void) struct libusb_device_descriptor dd; ssize_t cnt; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_device_count(); } + #endif r = libusb_init(&ctx); if(r < 0) @@ -1562,10 +1607,12 @@ const char *rtlsdr_get_device_name(uint32_t index) uint32_t device_count = 0; ssize_t cnt; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_device_name(index); } + #endif r = libusb_init(&ctx); if(r < 0) @@ -1609,11 +1656,13 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, uint32_t device_count = 0; ssize_t cnt; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_device_usb_strings (index, manufact, product, serial); } + #endif r = libusb_init(&ctx); if(r < 0) @@ -1655,10 +1704,12 @@ int rtlsdr_get_index_by_serial(const char *serial) int i, cnt, r; char str[256]; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_get_index_by_serial(serial); } + #endif if (!serial) return -1; @@ -1689,10 +1740,12 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) uint8_t reg; ssize_t cnt; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_open((void**)out_dev, index); } + #endif dev = malloc(sizeof(rtlsdr_dev_t)); if (NULL == dev) @@ -1884,10 +1937,12 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) int rtlsdr_close(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_close(dev); } + #endif if (!dev) return -1; @@ -1927,10 +1982,12 @@ int rtlsdr_close(rtlsdr_dev_t *dev) int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_reset_buffer(dev); } + #endif if (!dev) return -1; @@ -1943,10 +2000,12 @@ int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_read_sync(dev, buf, len, n_read); } + #endif if (!dev) return -1; @@ -1984,10 +2043,12 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_wait_async(dev, cb, ctx); } + #endif return rtlsdr_read_async(dev, cb, ctx, 0, 0); } @@ -2058,10 +2119,12 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, struct timeval zerotv = { 0, 0 }; enum rtlsdr_async_status next_status = RTLSDR_INACTIVE; + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_read_async(dev, cb, ctx, buf_num, buf_len); } + #endif if (!dev) return -1; @@ -2160,10 +2223,12 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, int rtlsdr_cancel_async(rtlsdr_dev_t *dev) { + #ifdef _ENABLE_RPC if (rtlsdr_rpc_is_enabled()) { return rtlsdr_rpc_cancel_async(dev); } + #endif if (!dev) return -1; @@ -2370,4 +2435,4 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len) err: printf("failed=%d\n", ret); return ret; -} +} \ No newline at end of file From 7228e75429419d43f4b63b4bbd656d8d3a7c956d Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Wed, 17 Aug 2016 10:47:56 -0300 Subject: [PATCH 74/74] Sorry, wrong notation at CMAKE --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3718fe..1d89acb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ MACRO(RTLSDR_APPEND_SRCS) LIST(APPEND rtlsdr_srcs ${ARGV}) ENDMACRO(RTLSDR_APPEND_SRCS) -if(!WIN32) +if(NOT WIN32) RTLSDR_APPEND_SRCS( librtlsdr.c tuner_e4k.c @@ -105,7 +105,7 @@ add_executable(rtl_ir rtl_ir.c) add_executable(rtl_eeprom rtl_eeprom.c) add_executable(rtl_adsb rtl_adsb.c) add_executable(rtl_power rtl_power.c) -if (!WIN32) +if (NOT WIN32) add_executable(rtl_rpcd rtl_rpcd.c rtlsdr_rpc_msg.c) set(INSTALL_TARGETS rtlsdr_shared rtlsdr_static rtl_sdr rtl_tcp rtl_test rtl_fm rtl_ir rtl_eeprom rtl_adsb rtl_power rtl_rpcd) else() @@ -144,7 +144,7 @@ target_link_libraries(rtl_power rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) -if(!WIN32) +if(NOT WIN32) target_link_libraries(rtl_rpcd rtlsdr_shared convenience_static ${LIBUSB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}