diff --git a/include/output_rtltcp.h b/include/output_rtltcp.h index 59ac76e2..58adc879 100644 --- a/include/output_rtltcp.h +++ b/include/output_rtltcp.h @@ -26,6 +26,6 @@ struct r_cfg; @return The initialized rtltcp output instance. You must release this object with raw_output_free once you're done with it. */ -struct raw_output *raw_output_rtltcp_create(char const *host, char const *port, struct r_cfg *cfg); +struct raw_output *raw_output_rtltcp_create(char const *host, char const *port, char const *opts, struct r_cfg *cfg); #endif /* INCLUDE_OUTPUT_RTLTCP_H_ */ diff --git a/src/output_rtltcp.c b/src/output_rtltcp.c index ea445514..67598ad2 100644 --- a/src/output_rtltcp.c +++ b/src/output_rtltcp.c @@ -98,6 +98,7 @@ typedef struct rtltcp_server { socklen_t addr_len; SOCKET sock; int client_count; ///< number of connected clients + int control; ///< are clients allowed to change SDR parameters uint8_t const *data_buf; ///< data buffer with most recent data, NULL otherwise uint32_t data_len; ///< data buffer length in bytes, 0 otherwise @@ -157,7 +158,7 @@ E.g. initialization from Gqrx: - RTLTCP_SET_FREQ with 433968000 */ -static int parse_command(r_cfg_t *cfg, uint8_t const *buf, int len) +static int parse_command(r_cfg_t *cfg, int control, uint8_t const *buf, int len) { UNUSED(cfg); @@ -171,21 +172,28 @@ static int parse_command(r_cfg_t *cfg, uint8_t const *buf, int len) switch (cmd) { case RTLTCP_SET_FREQ: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_FREQ with %u", arg); - // set_center_freq(cfg, arg); + if (control) + set_center_freq(cfg, arg); break; case RTLTCP_SET_SAMPLE_RATE: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_SAMPLE_RATE with %u", arg); - // set_sample_rate(cfg, arg); + if (control) + set_sample_rate(cfg, arg); break; case RTLTCP_SET_GAIN_MODE: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_GAIN_MODE with %u", arg); + // if (control) + // if (arg == 0 /* =auto */) sdr_set_auto_gain(dev, 0); break; case RTLTCP_SET_GAIN: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_GAIN with %u", arg); + // if (control) + // sdr_set_tuner_gain(dev, char const *gain_str, 0) break; case RTLTCP_SET_FREQ_CORRECTION: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_FREQ_CORRECTION with %u", arg); - // set_freq_correction(cfg, (int)arg); + if (control) + set_freq_correction(cfg, (int)arg); break; case RTLTCP_SET_IF_TUNER_GAIN: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_IF_TUNER_GAIN with %u", arg); @@ -195,6 +203,7 @@ static int parse_command(r_cfg_t *cfg, uint8_t const *buf, int len) break; case RTLTCP_SET_AGC_MODE: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_AGC_MODE with %u", arg); + // ... break; case RTLTCP_SET_DIRECT_SAMPLING: print_logf(LOG_DEBUG, "rtl_tcp", "received command SET_DIRECT_SAMPLING with %u", arg); @@ -253,6 +262,7 @@ static THREAD_RETURN THREAD_CALL accept_thread(void *arg) unsigned addr_len = sizeof(addr); int sock = accept(srv->sock, (struct sockaddr *)&addr, &addr_len); + // TODO: ignore ECONNABORTED (Software caused connection abort) if (sock < 0) { perror("ERROR on accept"); continue; @@ -308,7 +318,7 @@ static THREAD_RETURN THREAD_CALL accept_thread(void *arg) } int pos = 0; while (pos + 5 <= len) { - pos += parse_command(srv->cfg, &buf[pos], (int)len - pos); + pos += parse_command(srv->cfg, srv->control, & buf[pos], (int)len - pos); } } if (abort) { @@ -487,7 +497,7 @@ static void raw_output_rtltcp_free(raw_output_t *output) free(rtltcp); } -struct raw_output *raw_output_rtltcp_create(const char *host, const char *port, r_cfg_t *cfg) +struct raw_output *raw_output_rtltcp_create(const char *host, const char *port, char const *opts, r_cfg_t *cfg) { raw_output_rtltcp_t *rtltcp = calloc(1, sizeof(raw_output_rtltcp_t)); if (!rtltcp) { @@ -504,6 +514,14 @@ struct raw_output *raw_output_rtltcp_create(const char *host, const char *port, } #endif + // If clients allowed to change SDR parameters + if (opts && !strcasecmp(opts, "control")) + rtltcp->server.control = 1; + else if (opts && *opts) { + print_logf(LOG_FATAL, __func__, "Invalid \"%s\" option.", opts); + exit(1); + } + rtltcp->output.output_frame = raw_output_rtltcp_frame; rtltcp->output.output_free = raw_output_rtltcp_free; diff --git a/src/r_api.c b/src/r_api.c index d35b4fe6..d0cd659d 100644 --- a/src/r_api.c +++ b/src/r_api.c @@ -1143,7 +1143,7 @@ void add_rtltcp_output(r_cfg_t *cfg, char *param) } print_logf(LOG_CRITICAL, "rtl_tcp server", "Starting rtl_tcp server at %s port %s", host, port); - list_push(&cfg->raw_handler, raw_output_rtltcp_create(host, port, cfg)); + list_push(&cfg->raw_handler, raw_output_rtltcp_create(host, port, extra, cfg)); } void add_sr_dumper(r_cfg_t *cfg, char const *spec, int overwrite)