diff --git a/NEWS b/NEWS index aee9a7730..70fe9e26f 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ Version 5.x -- future * Change FT1000MP Mark V model names to align with FT1000MP Version 4.6 + * Added Barrett 4100 + * Added DL2MAN (tr)uSDX -- needs refinement * Added Thetis entry -- derived from FlexRadio/Apache PowerSDR * Added VOICE/CW memory capability to many rigs -- thanks to David Balharrie M0DGB/G8FKH * Add -# --skip_init option to rigctl to skip rig initialization -- useful for executing commands quickly diff --git a/include/hamlib/amplifier.h b/include/hamlib/amplifier.h index ce7903980..9149ae814 100644 --- a/include/hamlib/amplifier.h +++ b/include/hamlib/amplifier.h @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ #ifndef _AMPLIFIER_H #define _AMPLIFIER_H 1 @@ -445,6 +446,8 @@ rig_ext_lookup HAMLIB_PARAMS((RIG *rig, extern HAMLIB_EXPORT(setting_t) amp_parse_level(const char *s); extern HAMLIB_EXPORT(const char *) amp_strlevel(setting_t); +extern HAMLIB_EXPORT(void *) amp_data_pointer(AMP *amp, rig_ptrx_t idx); + //! @endcond diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 32dede0ee..8bcb4df7c 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ - +/* SPDX-License-Identifier: LGPL-2.1-or-later */ #ifndef _RIG_H #define _RIG_H 1 @@ -33,7 +33,7 @@ // Our shared secret password #define HAMLIB_SECRET_LENGTH 32 -#define HAMLIB_TRACE rig_debug(RIG_DEBUG_TRACE,"%.*s%s(%d) trace\n",rig->state.depth-1, spaces(), __FILE__, __LINE__) +#define HAMLIB_TRACE rig_debug(RIG_DEBUG_TRACE,"%s%s(%d) trace\n",spaces(rig->state.depth-1), __FILE__, __LINE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #include @@ -2462,6 +2462,54 @@ typedef hamlib_port_t_deprecated port_t_deprecated; typedef hamlib_port_t port_t; #endif +/* Macros to access data structures/pointers + * Make it easier to change location in preparation + * for moving them out of rig->state. + * See https://github.com/Hamlib/Hamlib/issues/1445 + * https://github.com/Hamlib/Hamlib/issues/1452 + * https://github.com/Hamlib/Hamlib/issues/1420 + * https://github.com/Hamlib/Hamlib/issues/536 + * https://github.com/Hamlib/Hamlib/issues/487 + */ +// Note: Experimental, and subject to change!! +#if defined(IN_HAMLIB) +/* These are for internal use only */ +#define RIGPORT(r) (&r->state.rigport) +#define PTTPORT(r) (&r->state.pttport) +#define DCDPORT(r) (&r->state.dcdport) +#define CACHE(r) (&r->state.cache) +#define AMPPORT(a) (&a->state.ampport) +#define ROTPORT(r) (&r->state.rotport) +#define ROTPORT2(r) (&r->state.rotport2) +/* Then when the rigport address is stored as a pointer somewhere else(say, + * in the rig structure itself), the definition could be changed to + * #define RIGPORT(r) r->somewhereelse + * and every reference is updated. + */ +#else +/* Define external unique names */ +#define HAMLIB_RIGPORT(r) ((hamlib_port_t *)rig_data_pointer(r, RIG_PTRX_RIGPORT)) +#define HAMLIB_PTTPORT(r) ((hamlib_port_t *)rig_data_pointer(r, RIG_PTRX_PTTPORT)) +#define HAMLIB_DCDPORT(r) ((hamlib_port_t *)rig_data_pointer(r, RIG_PTRX_DCDPORT)) +#define HAMLIB_CACHE(r) ((struct rig_cache *)rig_data_pointer(r, RIG_PTRX_CACHE)) +#define HAMLIB_AMPPORT(a) ((hamlib_port_t *)amp_data_pointer(a, RIG_PTRX_AMPPORT)) +#define HAMLIB_ROTPORT(r) ((hamlib_port_t *)rot_data_pointer(r, RIG_PTRX_ROTPORT)) +#define HAMLIB_ROTPORT2(r) ((hamlib_port_t *)rot_data_pointer(r, RIG_PTRX_ROTPORT2)) +#endif + +typedef enum { + RIG_PTRX_NONE=0, + RIG_PTRX_RIGPORT, + RIG_PTRX_PTTPORT, + RIG_PTRX_DCDPORT, + RIG_PTRX_CACHE, + RIG_PTRX_AMPPORT, + RIG_PTRX_ROTPORT, + RIG_PTRX_ROTPORT2, +// New entries go directly above this line==================== + RIG_PTRX_MAXIMUM +} rig_ptrx_t; + #define HAMLIB_ELAPSED_GET 0 #define HAMLIB_ELAPSED_SET 1 #define HAMLIB_ELAPSED_INVALIDATE 2 @@ -3667,7 +3715,7 @@ extern HAMLIB_EXPORT_VAR(char) debugmsgsave3[DEBUGMSGSAVE_SIZE]; // last-2 debu // Measuring elapsed time -- local variable inside function when macro is used #define ELAPSED1 struct timespec __begin; elapsed_ms(&__begin, HAMLIB_ELAPSED_SET); -#define ELAPSED2 rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s: elapsed=%.0lfms\n", rig->state.depth-1, spaces(), rig->state.depth, __func__, elapsed_ms(&__begin, HAMLIB_ELAPSED_GET)); +#define ELAPSED2 rig_debug(RIG_DEBUG_VERBOSE, "%s%d:%s: elapsed=%.0lfms\n", spaces(rig->state.depth-1), rig->state.depth, __func__, elapsed_ms(&__begin, HAMLIB_ELAPSED_GET)); // use this instead of snprintf for automatic detection of buffer limit #define SNPRINTF(s,n,...) { snprintf(s,n,##__VA_ARGS__);if (strlen(s) > n-1) fprintf(stderr,"****** %s(%d): buffer overflow ******\n", __func__, __LINE__); } @@ -3798,6 +3846,7 @@ enum GPIO { GPIO1, GPIO2, GPIO3, GPIO4 }; extern HAMLIB_EXPORT(int) rig_cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit); extern HAMLIB_EXPORT(int) rig_cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit); +extern HAMLIB_EXPORT(void *) rig_data_pointer(RIG *rig, rig_ptrx_t idx); //! @endcond diff --git a/include/hamlib/riglist.h b/include/hamlib/riglist.h index 541ab43e0..b09437810 100644 --- a/include/hamlib/riglist.h +++ b/include/hamlib/riglist.h @@ -202,6 +202,7 @@ #define RIG_MODEL_QRPLABS RIG_MAKE_MODEL(RIG_KENWOOD,52) #define RIG_MODEL_FX4 RIG_MAKE_MODEL(RIG_KENWOOD,53) #define RIG_MODEL_THETIS RIG_MAKE_MODEL(RIG_KENWOOD, 54) +#define RIG_MODEL_TRUSDX RIG_MAKE_MODEL(RIG_KENWOOD, 55) /* * Icom @@ -624,6 +625,7 @@ #define RIG_MODEL_BARRETT_2050 RIG_MAKE_MODEL(RIG_BARRETT, 1) #define RIG_MODEL_BARRETT_950 RIG_MAKE_MODEL(RIG_BARRETT, 2) #define RIG_MODEL_BARRETT_4050 RIG_MAKE_MODEL(RIG_BARRETT, 3) +#define RIG_MODEL_BARRETT_4100 RIG_MAKE_MODEL(RIG_BARRETT, 4) /* * Elad diff --git a/include/hamlib/rotator.h b/include/hamlib/rotator.h index 7eb04012d..3b2947eef 100644 --- a/include/hamlib/rotator.h +++ b/include/hamlib/rotator.h @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ #ifndef _ROTATOR_H #define _ROTATOR_H 1 @@ -797,6 +798,8 @@ extern HAMLIB_EXPORT(const char *) rot_strlevel(setting_t); extern HAMLIB_EXPORT(const char *) rot_strparm(setting_t); extern HAMLIB_EXPORT(const char *) rot_strstatus(rot_status_t); +extern HAMLIB_EXPORT(void *) rot_data_pointer(ROT *rot, rig_ptrx_t idx); + //! @endcond /** diff --git a/rigs/barrett/4100.c b/rigs/barrett/4100.c new file mode 100644 index 000000000..814ae7b15 --- /dev/null +++ b/rigs/barrett/4100.c @@ -0,0 +1,301 @@ +/* + * Hamlib Barrett 4100 backend - main file + * Derived from 4050 backend + * Copyright (c) 2017-2024 by Michael Black W9MDB + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include +#include "misc.h" + +#include "barrett.h" + +#define MAXCMDLEN 32 + +//#define BARRETT4100 VFOS (RIG_VFO_A|RIG_VFO_MEM) // VFO_MEM eventually? +#define BARRETT4100 VFOS (RIG_VFO_A) + +#define BARRETT4100_MODES (RIG_MODE_CW | RIG_MODE_SSB) + +// Levels eventually +//#define BARRETT4100_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH) + +// Functions eventually +//#define BARRETT4100_FUNCTIONS (RIG_FUNC_TUNER) + +extern int barret950_get_freq(RIG *rig, vfo_t vfo, freq_t freq); + +/* + * barrett4100_get_info + */ +static const char *barrett4100_get_info(RIG *rig) +{ + char *response = NULL; + int retval; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + retval = barrett_transaction(rig, "M:MIB GM", 0, &response); + + if (retval == RIG_OK) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, + strerror(retval), response); + } + else + { + rig_debug(RIG_DEBUG_VERBOSE, "MIB GM: %s\n", response); + } + + retval = barrett_transaction(rig, "M:FF GM", 0, &response); + + if (retval == RIG_OK) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, + strerror(retval), response); + } + else + { + rig_debug(RIG_DEBUG_VERBOSE, "FF GM: %s\n", response); + } + + retval = barrett_transaction(rig, "M:FF BWA", 0, &response); + + if (retval == RIG_OK) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, + strerror(retval), response); + } + else + { + rig_debug(RIG_DEBUG_VERBOSE, "FF BWA: %s\n", response); + } + + retval = barrett_transaction(rig, "M:FF GRFA", 0, &response); + + if (retval == RIG_OK) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, + strerror(retval), response); + } + else + { + rig_debug(RIG_DEBUG_VERBOSE, "M:FF GRFA: %s\n", response); + } + + return response; +} + +static int barrett4100_open(RIG *rig) +{ + int retval; + char *response; + ENTERFUNC; + retval = barrett_transaction2(rig, "M:REMOTE SENTER2", 0, &response); + + if (retval != RIG_OK || response[0] != 's') + { + rig_debug(RIG_DEBUG_ERR, "%s: REMOTE SENTER2 error: got %s\n", __func__, + response); + } + + barrett4100_get_info(rig); + RETURNFUNC(RIG_OK); +} + +static int barrett4100_close(RIG *rig) +{ + char *response; + int retval = barrett_transaction2(rig, "M:REMOTE SENTER0", 0, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + + return rig_close(rig); +} + +int barrett4100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + char *response; + int retval = barrett_transaction2(rig, "M:FF SRF%.0f GRF", freq, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + else + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + freq_t freq2 = 0; + int n = sscanf(response, "s gRF%lf", &freq2); + + if (n == 1) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); + } + else + { + rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gRF\n", __func__); + } + } + retval = barrett_transaction2(rig, "M:FF STF%.0f GTF", freq, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + else + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + freq_t freq2 = 0; + int n = sscanf(response, "s gTF%lf", &freq2); + + if (n == 1) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); + } + else + { + rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gTF\n", __func__); + } + } + + return retval; +} + +int barrett4100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +{ + char *response; + int retval = barrett_transaction2(rig, "M:FF GRF", 0, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + else + { + sscanf(response, "gRFA1,%*d,%lf,%*d", freq); + } + + return retval; +} + +int barrett4100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) +{ + char *response; + int retval = barrett_transaction2(rig, "M:FF SRPTT%d GRPTT", ptt, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, + response); + return retval; +} +int barrett4100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) +{ + char *response; + int retval = barrett_transaction2(rig, "M:FF GRPTT", 0, &response); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); + } + + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, + response); + return retval; +} + +struct rig_caps barrett4100_caps = +{ + RIG_MODEL(RIG_MODEL_BARRETT_4100), + .model_name = "4100", + .mfg_name = "Barrett", + .version = BACKEND_VER ".0", + .copyright = "LGPL", + .status = RIG_STATUS_ALPHA, + .rig_type = RIG_TYPE_TRANSCEIVER, + .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_NONE, + .port_type = RIG_PORT_NETWORK, + .serial_rate_min = 9600, + .serial_rate_max = 115200, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_XONXOFF, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 500, + .retry = 3, + +// .has_get_func = BARRETT4100_FUNCTIONS, +// .has_set_func = BARRETT4100_FUNCTIONS, +// .has_get_level = BARRETT4100_LEVELS, + .has_set_level = RIG_LEVEL_AGC, + .has_get_parm = RIG_PARM_NONE, + .has_set_parm = RIG_PARM_NONE, + .transceive = RIG_TRN_RIG, + .rx_range_list1 = {{ + .startf = kHz(10), .endf = MHz(30), .modes = BARRETT4100_MODES, + .low_power = -1, .high_power = -1, BARRETT4100_MODES, RIG_ANT_1 + }, + RIG_FRNG_END, + }, + .rx_range_list2 = {RIG_FRNG_END,}, + .tx_range_list1 = {RIG_FRNG_END,}, + .tx_range_list2 = {RIG_FRNG_END,}, + .tuning_steps = { {BARRETT4100_MODES, 1}, {BARRETT4100_MODES, RIG_TS_ANY}, RIG_TS_END, }, + .filters = { + {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, + {RIG_MODE_CW, Hz(500)}, + {RIG_MODE_AM, kHz(8)}, + {RIG_MODE_AM, kHz(2.4)}, + RIG_FLT_END, + }, + .priv = NULL, + + .rig_init = barrett_init, + .rig_cleanup = barrett_cleanup, + .rig_open = barrett4100_open, + .rig_close = barrett4100_close, + + .set_freq = barrett4100_set_freq, + .get_freq = barrett4100_get_freq, +// .set_mode = barrett_set_mode, +// .get_mode = barrett_get_mode, + +// .set_level = barrett_set_level, +// .get_level = barrett_get_level, + + .get_info = barrett4100_get_info, + .set_ptt = barrett4100_set_ptt, + .get_ptt = barrett4100_get_ptt, +// .set_split_freq = barrett_set_split_freq, +// .set_split_vfo = barrett_set_split_vfo, +// .get_split_vfo = barrett_get_split_vfo, + .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS +}; diff --git a/rigs/barrett/Makefile.am b/rigs/barrett/Makefile.am index 5df262606..e319adc7f 100644 --- a/rigs/barrett/Makefile.am +++ b/rigs/barrett/Makefile.am @@ -1,4 +1,4 @@ -BARRETTSRC = barrett.c barrett.h 950.c 4050.c +BARRETTSRC = barrett.c barrett.h 950.c 4050.c 4100.c noinst_LTLIBRARIES = libhamlib-barrett.la libhamlib_barrett_la_SOURCES = $(BARRETTSRC) diff --git a/rigs/barrett/barrett.c b/rigs/barrett/barrett.c index d994e8d91..7c5d1d998 100644 --- a/rigs/barrett/barrett.c +++ b/rigs/barrett/barrett.c @@ -47,12 +47,32 @@ DECLARE_INITRIG_BACKEND(barrett) rig_register(&barrett_caps); rig_register(&barrett950_caps); rig_register(&barrett4050_caps); + rig_register(&barrett4100_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } +// this version is for 4100 +int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result) +{ + char cmd_buf[MAXCMDLEN]; + struct rig_state *rs = &rig->state; + struct barrett_priv_data *priv = rig->state.priv; + int retval; + + SNPRINTF(cmd_buf, sizeof(cmd_buf), "%c%s%s", 0x0a, cmd, EOM); + retval = read_block(&rs->rigport, (unsigned char *) priv->ret_data, expected); + + if (retval < 0) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); + return retval; + } + return retval; +} + int barrett_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; @@ -65,7 +85,13 @@ int barrett_transaction(RIG *rig, char *cmd, int expected, char **result) rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); - SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%s", cmd, EOM); + if (rig->caps->rig_model == RIG_MODEL_BARRETT_4100) + { + } + else + { + SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%s", cmd, EOM); + } rig_flush(&rs->rigport); retval = write_block(&rs->rigport, (unsigned char *) cmd_buf, strlen(cmd_buf)); diff --git a/rigs/barrett/barrett.h b/rigs/barrett/barrett.h index 633560593..f778acc5a 100644 --- a/rigs/barrett/barrett.h +++ b/rigs/barrett/barrett.h @@ -39,6 +39,7 @@ extern struct rig_caps barrett_caps; extern struct rig_caps barrett950_caps; extern struct rig_caps barrett4050_caps; +extern struct rig_caps barrett4100_caps; struct barrett_priv_data { char cmd_str[BARRETT_DATA_LEN]; /* command string buffer */ @@ -48,6 +49,7 @@ struct barrett_priv_data { }; extern int barrett_transaction(RIG *rig, char *cmd, int expected, char **result); +extern int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result); extern int barrett_init(RIG *rig); extern int barrett_cleanup(RIG *rig); diff --git a/rigs/icom/ic7700.c b/rigs/icom/ic7700.c index b23f2f0f4..f9be28d1d 100644 --- a/rigs/icom/ic7700.c +++ b/rigs/icom/ic7700.c @@ -264,6 +264,14 @@ int ic7700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, return retval; } +static int ic7700_rig_open(RIG *rig) +{ + rig_debug(RIG_DEBUG_VERBOSE, "%s: enter\n", __func__); + struct icom_priv_data *priv = (struct icom_priv_data *) rig->state.priv; + priv->x26cmdfails = priv->x25cmdfails = 1; + return icom_rig_open(rig); +} + struct rig_caps ic7700_caps = { RIG_MODEL(RIG_MODEL_IC7700), @@ -401,7 +409,7 @@ struct rig_caps ic7700_caps = .priv = (void *)& ic7700_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, - .rig_open = icom_rig_open, + .rig_open = ic7700_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, diff --git a/rigs/kenwood/elecraft.c b/rigs/kenwood/elecraft.c index b0d88af6c..e349882cb 100644 --- a/rigs/kenwood/elecraft.c +++ b/rigs/kenwood/elecraft.c @@ -99,7 +99,7 @@ int elecraft_open(RIG *rig) struct kenwood_priv_data *priv = rig->state.priv; char *model = "Unknown"; struct rig_state *rs = &rig->state; - + struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, rig version=%s\n", __func__, rig->caps->version); @@ -135,7 +135,7 @@ int elecraft_open(RIG *rig) strcpy(data, "EMPTY"); // Not going to get carried away with retries and such - err = write_block(&rs->rigport, (unsigned char *) cmd, strlen(cmd)); + err = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (err != RIG_OK) { @@ -143,7 +143,7 @@ int elecraft_open(RIG *rig) return err; } - err = read_string(&rs->rigport, (unsigned char *) buf, sizeof(buf), + err = read_string(rp, (unsigned char *) buf, sizeof(buf), ";", 1, 0, 1); if (err < 0) diff --git a/rigs/kenwood/ic10.c b/rigs/kenwood/ic10.c index ed6dfcddc..38d8fad08 100644 --- a/rigs/kenwood/ic10.c +++ b/rigs/kenwood/ic10.c @@ -74,7 +74,7 @@ int ic10_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, { int retval; int retry_cmd = 0; - struct rig_state *rs; + struct hamlib_port *rp = RIGPORT(rig); if (cmd == NULL) { @@ -86,12 +86,10 @@ int ic10_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, "%s: called cmd='%s', len=%d, data=%p, data_len=%p\n", __func__, cmd, cmd_len, data, data_len); - rs = &rig->state; - transaction: - rig_flush(&rs->rigport); + rig_flush(rp); - retval = write_block(&rs->rigport, (unsigned char *) cmd, cmd_len); + retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { @@ -103,18 +101,18 @@ transaction: char buffer[50]; const struct kenwood_priv_data *priv = rig->state.priv; - if (RIG_OK != (retval = write_block(&rs->rigport, + if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { return retval; } // this should be the ID response - retval = read_string(&rs->rigport, (unsigned char *) buffer, sizeof(buffer), + retval = read_string(rp, (unsigned char *) buffer, sizeof(buffer), ";", 1, 0, 1); // might be ?; too - if (buffer[0] == '?' && retry_cmd++ < rs->rigport.retry) + if (buffer[0] == '?' && retry_cmd++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: retrying cmd #%d\n", __func__, retry_cmd); goto transaction; @@ -130,7 +128,7 @@ transaction: return RIG_OK; } - retval = read_string(&rs->rigport, (unsigned char *) data, 50, ";", 1, 0, 1); + retval = read_string(rp, (unsigned char *) data, 50, ";", 1, 0, 1); if (retval == -RIG_ETIMEOUT) { @@ -158,7 +156,7 @@ static int get_ic10_if(RIG *rig, char *data) rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); - for (i = 0; retval != RIG_OK && i < rig->state.rigport.retry; i++) + for (i = 0; retval != RIG_OK && i < RIGPORT(rig)->retry; i++) { data_len = 37; retval = ic10_transaction(rig, "IF;", 3, data, &data_len); diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index d7f26d9d3..501277d96 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -245,6 +245,7 @@ int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, struct kenwood_priv_data *priv = rig->state.priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct rig_state *rs; + struct hamlib_port *rp; /* Pointer to rigport structure */ if (datasize > 0 && datasize < (cmdstr ? strlen(cmdstr) : 0)) { @@ -265,11 +266,12 @@ int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, } rs = &rig->state; + rp = RIGPORT(rig); rs->transaction_active = 1; /* Emulators don't need any post_write_delay */ - if (priv->is_emulation) { rs->rigport.post_write_delay = 0; } + if (priv->is_emulation) { rp->post_write_delay = 0; } // if this is an IF cmdstr and not the first time through check cache if (cmdstr && strcmp(cmdstr, "IF") == 0 && priv->cache_start.tv_sec != 0) @@ -328,9 +330,9 @@ transaction_write: } /* flush anything in the read buffer before command is sent */ - rig_flush(&rs->rigport); + rig_flush(rp); - retval = write_block(&rs->rigport, (unsigned char *) cmd, len); + retval = write_block(rp, (unsigned char *) cmd, len); free(cmd); @@ -382,7 +384,7 @@ transaction_write: /* no reply expected so we need to write a command that always gives a reply so we can read any error replies from the actual command being sent without blocking */ - if (RIG_OK != (retval = write_block(&rs->rigport, + if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { goto transaction_quit; @@ -396,7 +398,7 @@ transaction_read: // eventually we should be able to get rid of this but requires testing all Kenwood rigs len = min(datasize ? datasize + 1 : strlen(priv->verify_cmd) + 48, KENWOOD_MAX_BUF_LEN); - retval = read_string(&rs->rigport, (unsigned char *) buffer, len, + retval = read_string(rp, (unsigned char *) buffer, len, cmdtrm_str, strlen(cmdtrm_str), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string len=%d '%s'\n", __func__, (int)strlen(buffer), buffer); @@ -404,12 +406,12 @@ transaction_read: if (retval < 0) { rig_debug(RIG_DEBUG_WARN, - "%s: read_string retval < 0, retval = %d, retry_read=%d, rs->rigport.retry=%d\n", + "%s: read_string retval < 0, retval = %d, retry_read=%d, rp->retry=%d\n", __func__, - retval, retry_read, rs->rigport.retry); + retval, retry_read, rp->retry); // only retry if we expect a response from the command - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { goto transaction_write; // we use to not re-do the write @@ -439,7 +441,7 @@ transaction_read: rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, buffer); - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { goto transaction_write; } @@ -471,7 +473,7 @@ transaction_read: rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); } - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { goto transaction_write; } @@ -488,7 +490,7 @@ transaction_read: cmdstr); } - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { goto transaction_write; } @@ -531,10 +533,10 @@ transaction_read: } } - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: Retrying shortly %d of %d\n", __func__, - retry_read, rs->rigport.retry); + retry_read, rp->retry); hl_usleep(rig->caps->timeout * 1000); goto transaction_write; } @@ -564,10 +566,10 @@ transaction_read: rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %c%c for command %c%c\n", __func__, buffer[0], buffer[1], cmdstr[0], cmdstr[1]); - rig_debug(RIG_DEBUG_ERR, "%s: retry_read=%d, rs->rigport.retry=%d\n", __func__, - retry_read, rs->rigport.retry); + rig_debug(RIG_DEBUG_ERR, "%s: retry_read=%d, rp->retry=%d\n", __func__, + retry_read, rp->retry); - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { if (strlen(buffer) == 0) { @@ -640,7 +642,7 @@ transaction_read: __func__, buffer[0], buffer[1] , priv->verify_cmd[0], priv->verify_cmd[1]); - if (retry_read++ < rs->rigport.retry) + if (retry_read++ < rp->retry) { goto transaction_write; } @@ -740,7 +742,7 @@ int kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, hl_usleep(50 * 1000); // let's do a short wait } } - while (err != RIG_OK && ++retry < rig->state.rigport.retry); + while (err != RIG_OK && ++retry < RIGPORT(rig)->retry); RETURNFUNC2(err); } @@ -869,12 +871,12 @@ int kenwood_open(RIG *rig) int err, i; char *idptr; char id[KENWOOD_MAX_BUF_LEN]; - int retry_save = rig->state.rigport.retry; + int retry_save = RIGPORT(rig)->retry; ENTERFUNC; id[0] = 0; - rig->state.rigport.retry = 0; + RIGPORT(rig)->retry = 0; priv->question_mark_response_means_rejected = 0; @@ -946,7 +948,7 @@ int kenwood_open(RIG *rig) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version, defaulting to 1.0\n", __func__); - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; priv->fw_rev_uint = 100; } else @@ -964,7 +966,7 @@ int kenwood_open(RIG *rig) else { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; RETURNFUNC(-RIG_EPROTO); } } @@ -983,7 +985,7 @@ int kenwood_open(RIG *rig) if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response from rig\n", __func__); - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } @@ -1000,7 +1002,7 @@ int kenwood_open(RIG *rig) if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", __func__); - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } } @@ -1087,7 +1089,7 @@ int kenwood_open(RIG *rig) rig_strvfo(priv->tx_vfo)); } - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } @@ -1108,7 +1110,7 @@ int kenwood_open(RIG *rig) // we're making this non fatal // mismatched IDs can still be tested - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } @@ -1574,9 +1576,9 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) tsplit = RIG_SPLIT_OFF; // default in case rig does not set split status retval = rig_get_split_vfo(rig, vfo, &tsplit, &tx_vfo); - priv->split = rig->state.cache.split = split; - rig->state.cache.split_vfo = txvfo; - elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET); + priv->split = CACHE(rig)->split = split; + CACHE(rig)->split_vfo = txvfo; + elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); // and it should be OK to do a SPLIT_OFF at any time so we won's skip that if (retval == RIG_OK && split == RIG_SPLIT_ON && tsplit == RIG_SPLIT_ON) @@ -1596,7 +1598,7 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) || rig->caps->rig_model == RIG_MODEL_KX2 || rig->caps->rig_model == RIG_MODEL_KX3) { - rig_set_freq(rig, RIG_VFO_B, rig->state.cache.freqMainA); + rig_set_freq(rig, RIG_VFO_B, CACHE(rig)->freqMainA); } if (retval != RIG_OK) @@ -1605,8 +1607,8 @@ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) } /* Remember whether split is on, for kenwood_set_vfo */ - priv->split = rig->state.cache.split = split; - elapsed_ms(&rig->state.cache.time_split, HAMLIB_ELAPSED_SET); + priv->split = CACHE(rig)->split = split; + elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); RETURNFUNC2(RIG_OK); } @@ -2866,15 +2868,15 @@ static int kenwood_get_micgain_minmax(RIG *rig, int *micgain_now, // we batch these commands together for speed char *cmd = "MG;MG000;MG;MG255;MG;MG000;"; int n; - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; - retval = write_block(&rs->rigport, (unsigned char *) cmd, strlen(cmd)); + retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } - retval = read_string(&rs->rigport, (unsigned char *) levelbuf, sizeof(levelbuf), + retval = read_string(rp, (unsigned char *) levelbuf, sizeof(levelbuf), NULL, 0, 1, 1); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); @@ -2928,6 +2930,7 @@ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, char *cmd; int n; struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; @@ -2940,16 +2943,16 @@ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, // TS890S can't take power levels outside 5-100 and 5-25 // So all we'll do is read power_now case RIG_MODEL_TS890S: - rig->state.power_min = *power_min = 5; - rig->state.power_max = *power_max = 100; + rs->power_min = *power_min = 5; + rs->power_max = *power_max = 100; - if (rig->state.current_mode == RIG_MODE_AM) { *power_max = 50; } + if (rs->current_mode == RIG_MODE_AM) { *power_max = 50; } - if (rig->state.current_freq >= 70) + if (rs->current_freq >= 70) { - rig->state.power_max = 50; + rs->power_max = 50; - if (rig->state.current_mode == RIG_MODE_AM) { *power_max = 13; } + if (rs->current_mode == RIG_MODE_AM) { *power_max = 13; } } @@ -2961,18 +2964,18 @@ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, } // Don't do this if PTT is on...don't want to max out power!! - if (rig->state.cache.ptt == RIG_PTT_ON) + if (CACHE(rig)->ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_TRACE, "%s: ptt on so not checking min/max power levels\n", __func__); // return the last values we got - *power_now = rig->state.power_now; - *power_min = rig->state.power_min; - *power_max = rig->state.power_max; + *power_now = rs->power_now; + *power_min = rs->power_min; + *power_max = rs->power_max; RETURNFUNC(RIG_OK); } - retval = write_block(&rs->rigport, (unsigned char *) cmd, strlen(cmd)); + retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } @@ -2985,7 +2988,7 @@ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, expected_length = 18; } - retval = read_string(&rs->rigport, (unsigned char *) levelbuf, + retval = read_string(rp, (unsigned char *) levelbuf, expected_length + 1, NULL, 0, 0, 1); @@ -3033,9 +3036,9 @@ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, rig_debug(RIG_DEBUG_TRACE, "%s: returning now=%d, min=%d, max=%d\n", __func__, *power_now, *power_min, *power_max); - rig->state.power_now = *power_now; - rig->state.power_min = *power_min; - rig->state.power_max = *power_max; + rs->power_now = *power_now; + rs->power_min = *power_min; + rs->power_max = *power_max; RETURNFUNC(RIG_OK); } @@ -3780,8 +3783,8 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) // This could be done by rig but easy enough to make it automagic if (priv->ag_format < 0) { - int retry_save = rig->state.rigport.retry; - rig->state.rigport.retry = 0; // speed up this check so no retries + int retry_save = RIGPORT(rig)->retry; + RIGPORT(rig)->retry = 0; // speed up this check so no retries rig_debug(RIG_DEBUG_TRACE, "%s: AF format check determination...\n", __func__); // Determine AG format // =-1 == Undetermine @@ -3819,7 +3822,7 @@ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) } } - rig->state.rigport.retry = retry_save; + RIGPORT(rig)->retry = retry_save; } rig_debug(RIG_DEBUG_TRACE, "%s: ag_format=%d\n", __func__, priv->ag_format); @@ -5090,7 +5093,7 @@ int kenwood_get_trn(RIG *rig, int *trn) int kenwood_set_powerstat(RIG *rig, powerstat_t status) { int retval; - struct rig_state *state = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = rig->state.priv; if ((priv->is_k3 || priv->is_k3s) && status == RIG_POWER_ON) @@ -5101,7 +5104,7 @@ int kenwood_set_powerstat(RIG *rig, powerstat_t status) } int i = 0; - int retry_save = rig->state.rigport.retry; + int retry_save = rp->retry; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, status); @@ -5109,11 +5112,11 @@ int kenwood_set_powerstat(RIG *rig, powerstat_t status) { // When powering on a Kenwood rig needs dummy bytes to wake it up, // then wait at least 200ms and within 2 seconds issue the power-on command again - write_block(&state->rigport, (unsigned char *) "PS1;", 4); + write_block(rp, (unsigned char *) "PS1;", 4); hl_usleep(500000); } - rig->state.rigport.retry = 0; + rp->retry = 0; retval = kenwood_transaction(rig, (status == RIG_POWER_ON) ? "PS1;" : "PS0;", @@ -5129,7 +5132,7 @@ int kenwood_set_powerstat(RIG *rig, powerstat_t status) if (retval == RIG_OK) { - rig->state.rigport.retry = retry_save; + rp->retry = retry_save; RETURNFUNC2(retval); } @@ -5137,7 +5140,7 @@ int kenwood_set_powerstat(RIG *rig, powerstat_t status) } } - rig->state.rigport.retry = retry_save; + rp->retry = retry_save; if (i == 9) { @@ -5157,7 +5160,7 @@ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[6]; int result; - struct rig_state *state = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = rig->state.priv; ENTERFUNC; @@ -5183,19 +5186,19 @@ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) short timeout_retry_save; int timeout_save; - retry_save = state->rigport.retry; - timeout_retry_save = state->rigport.timeout_retry; - timeout_save = state->rigport.timeout; + retry_save = rp->retry; + timeout_retry_save = rp->timeout_retry; + timeout_save = rp->timeout; - state->rigport.retry = 0; - state->rigport.timeout_retry = 0; - state->rigport.timeout = 500; + rp->retry = 0; + rp->timeout_retry = 0; + rp->timeout = 500; result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); - state->rigport.retry = retry_save; - state->rigport.timeout_retry = timeout_retry_save; - state->rigport.timeout = timeout_save; + rp->retry = retry_save; + rp->timeout_retry = timeout_retry_save; + rp->timeout = timeout_save; // Rig may respond here already if (result == RIG_OK) @@ -5222,7 +5225,7 @@ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) // after waiting for at least 200ms and within 2 seconds after dummy data hl_usleep(500000); // Discard any unsolicited data - rig_flush(&rig->state.rigport); + rig_flush(rp); result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); @@ -6189,6 +6192,7 @@ DECLARE_INITRIG_BACKEND(kenwood) rig_register(&qrplabs_caps); rig_register(&fx4_caps); rig_register(&thetis_caps); + rig_register(&trudx_caps); return (RIG_OK); } diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index 5ab2e64f0..6c2fdbcb5 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -325,6 +325,7 @@ extern struct rig_caps sdruno_caps; extern struct rig_caps qrplabs_caps; extern struct rig_caps fx4_caps; extern struct rig_caps thetis_caps; +extern struct rig_caps trudx_caps; /* use when not interested in the answer, but want to check its len */ static int inline kenwood_simple_transaction(RIG *rig, const char *cmd, diff --git a/rigs/kenwood/thd72.c b/rigs/kenwood/thd72.c index 34fe6a71e..28c49692e 100644 --- a/rigs/kenwood/thd72.c +++ b/rigs/kenwood/thd72.c @@ -1456,7 +1456,7 @@ static int thd72_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, static int thd72_get_block(RIG *rig, int block_num, char *block) { - hamlib_port_t *rp = &rig->state.rigport; + hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; @@ -1518,7 +1518,7 @@ static int thd72_get_block(RIG *rig, int block_num, char *block) int thd72_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; - hamlib_port_t *rp = &rig->state.rigport; + hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = rig->state.chan_list; int chan_next = chan_list[0].start; diff --git a/rigs/kenwood/thd74.c b/rigs/kenwood/thd74.c index 01b5e89b3..3a37cb9aa 100644 --- a/rigs/kenwood/thd74.c +++ b/rigs/kenwood/thd74.c @@ -1448,7 +1448,7 @@ int thd74_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) static int thd74_get_block(RIG *rig, int block_num, char *block) { - hamlib_port_t *rp = &rig->state.rigport; + hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; @@ -1510,7 +1510,7 @@ static int thd74_get_block(RIG *rig, int block_num, char *block) int thd74_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; - hamlib_port_t *rp = &rig->state.rigport; + hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = rig->state.chan_list; int chan_next = chan_list[0].start; diff --git a/rigs/kenwood/tmd710.c b/rigs/kenwood/tmd710.c index 64d99cbbf..ab9bf7de7 100644 --- a/rigs/kenwood/tmd710.c +++ b/rigs/kenwood/tmd710.c @@ -252,7 +252,7 @@ const struct confparams tmd710_ext_levels[] = struct rig_caps tmd710_caps = { - .rig_model = RIG_MODEL_TMD710, + RIG_MODEL(RIG_MODEL_TMD710), .model_name = "TM-D710(G)", .mfg_name = "Kenwood", .version = BACKEND_VER ".6", diff --git a/rigs/kenwood/ts2000.c b/rigs/kenwood/ts2000.c index 29f5a8766..1e7212884 100644 --- a/rigs/kenwood/ts2000.c +++ b/rigs/kenwood/ts2000.c @@ -519,7 +519,7 @@ static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) { int retval; char cmdbuf[8]; - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 8; int read_meter; @@ -529,7 +529,7 @@ static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) SNPRINTF(cmdbuf, sizeof(cmdbuf), "RM;"); - retval = write_block(&rs->rigport, (unsigned char *) cmdbuf, strlen(cmdbuf)); + retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); @@ -540,7 +540,7 @@ static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) // TS-2000 returns values for a single meter at the same time, for example: RM10000; - retval = read_string(&rs->rigport, (unsigned char *) ackbuf, expected_len + 1, + retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); diff --git a/rigs/kenwood/ts450s.c b/rigs/kenwood/ts450s.c index 6a5a43b4d..e5e393512 100644 --- a/rigs/kenwood/ts450s.c +++ b/rigs/kenwood/ts450s.c @@ -85,9 +85,9 @@ int ts450_open(RIG *rig) return err; } - maxtries = rig->state.rigport.retry; + maxtries = RIGPORT(rig)->retry; /* no retry for this command that may be missing */ - rig->state.rigport.retry = 0; + RIGPORT(rig)->retry = 0; err = kenwood_simple_transaction(rig, "TO", 3); @@ -98,7 +98,7 @@ int ts450_open(RIG *rig) rig->state.has_get_func &= ~RIG_FUNC_TONE; } - rig->state.rigport.retry = maxtries; + RIGPORT(rig)->retry = maxtries; return RIG_OK; } @@ -106,7 +106,6 @@ int ts450_open(RIG *rig) /* * ts450s rig capabilities. * Notice that some rigs share the same functions. - * Also this struct is READONLY! * RIT: Variable Range ±9.99 kHz * * TODO: protocol to be checked with manual (identical to TS690) diff --git a/rigs/kenwood/ts480.c b/rigs/kenwood/ts480.c index 96a904805..54ea51dda 100644 --- a/rigs/kenwood/ts480.c +++ b/rigs/kenwood/ts480.c @@ -429,13 +429,13 @@ static int ts480_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; - retval = write_block(&rs->rigport, (unsigned char *) cmd, strlen(cmd)); + retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); @@ -446,7 +446,7 @@ static int ts480_read_meters(RIG *rig, int *swr, int *comp, int *alc) // TS-480 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; - retval = read_string(&rs->rigport, (unsigned char *) ackbuf, expected_len + 1, + retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); @@ -1438,6 +1438,204 @@ struct rig_caps ts480_caps = .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; +/* + * truSDC rig capabilities + * Notice that some rigs share the same functions. + */ +struct rig_caps trudx_caps = +{ + RIG_MODEL(RIG_MODEL_TRUSDX), + .model_name = "(tr)uSDX", + .mfg_name = "DL2MAN", + .version = BACKEND_VER ".1", + .copyright = "LGPL", + .status = RIG_STATUS_BETA, + .rig_type = RIG_TYPE_TRANSCEIVER, + .ptt_type = RIG_PTT_RIG_MICDATA, + .dcd_type = RIG_DCD_RIG, + .port_type = RIG_PORT_SERIAL, + .serial_rate_min = 38400, + .serial_rate_max = 115200, + .serial_data_bits = 8, + .serial_stop_bits = 1, + .serial_parity = RIG_PARITY_NONE, + .serial_handshake = RIG_HANDSHAKE_NONE, + .write_delay = 0, + .post_write_delay = 0, + .timeout = 500, + .retry = 3, + .preamp = {12, RIG_DBLST_END,}, + .attenuator = {12, RIG_DBLST_END,}, + .max_rit = kHz(9.99), + .max_xit = kHz(9.99), + .max_ifshift = Hz(0), + .targetable_vfo = RIG_TARGETABLE_FREQ, + .transceive = RIG_TRN_RIG, + .agc_level_count = 3, + .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, + + .rx_range_list1 = { + {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, + RIG_FRNG_END, + }, /*!< Receive frequency range list for ITU region 1 */ + .tx_range_list1 = { + {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ + {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ + {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + RIG_FRNG_END, + }, /*!< Transmit frequency range list for ITU region 1 */ + .rx_range_list2 = { + {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, + RIG_FRNG_END, + }, /*!< Receive frequency range list for ITU region 2 */ + .tx_range_list2 = { + {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ + {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ + {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, + {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, + RIG_FRNG_END, + }, /*!< Transmit frequency range list for ITU region 2 */ + .tuning_steps = { + {TS480_ALL_MODES, kHz(1)}, + {TS480_ALL_MODES, Hz(2500)}, + {TS480_ALL_MODES, kHz(5)}, + {TS480_ALL_MODES, Hz(6250)}, + {TS480_ALL_MODES, kHz(10)}, + {TS480_ALL_MODES, Hz(12500)}, + {TS480_ALL_MODES, kHz(15)}, + {TS480_ALL_MODES, kHz(20)}, + {TS480_ALL_MODES, kHz(25)}, + {TS480_ALL_MODES, kHz(30)}, + {TS480_ALL_MODES, kHz(100)}, + {TS480_ALL_MODES, kHz(500)}, + {TS480_ALL_MODES, MHz(1)}, + {TS480_ALL_MODES, 0}, /* any tuning step */ + RIG_TS_END, + }, + /* mode/filter list, remember: order matters! */ + .filters = { + {RIG_MODE_SSB, kHz(2.4)}, + {RIG_MODE_SSB, Hz(270)}, + {RIG_MODE_SSB, Hz(500)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, + {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, + {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, + {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, + {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, + {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, + {RIG_MODE_AM, kHz(6)}, + {RIG_MODE_AM, kHz(2.4)}, + {RIG_MODE_FM, kHz(12)}, + RIG_FLT_END, + }, + .vfo_ops = TS480_VFO_OPS, + .level_gran = + { +#include "level_gran_kenwood.h" + [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, + [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, + [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, + [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, + [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, + [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, + }, + .str_cal = TS480_STR_CAL, + .swr_cal = TS480_SWR_CAL, + + .ext_tokens = ts480_ext_tokens, + .extfuncs = ts480_ext_funcs, + .extlevels = ts480_ext_levels, + + .priv = (void *)& ts480_priv_caps, + .rig_init = ts480_init, + .rig_open = kenwood_open, + .rig_cleanup = kenwood_cleanup, + .set_freq = kenwood_set_freq, + .get_freq = kenwood_get_freq, + .set_rit = ts480_set_rit, + .get_rit = ts480_get_rit, + .set_xit = ts480_set_rit, + .get_xit = ts480_get_rit, + .set_mode = kenwood_set_mode, + .get_mode = kenwood_get_mode, + .set_vfo = kenwood_set_vfo, + .get_vfo = kenwood_get_vfo_if, + .set_split_vfo = kenwood_set_split_vfo, + .get_split_vfo = kenwood_get_split_vfo_if, + .get_ptt = kenwood_get_ptt, + .set_ptt = kenwood_set_ptt, + .get_dcd = kenwood_get_dcd, + .set_powerstat = kenwood_set_powerstat, + .get_powerstat = kenwood_get_powerstat, + .get_info = kenwood_ts480_get_info, + .reset = kenwood_reset, + .set_ant = kenwood_set_ant, + .get_ant = kenwood_get_ant, + .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ + .has_set_level = TS480_LEVEL_SET, + .has_get_level = TS480_LEVEL_GET, + .set_level = kenwood_ts480_set_level, + .get_level = kenwood_ts480_get_level, + .set_ext_level = ts480_set_ext_level, + .get_ext_level = ts480_get_ext_level, + .has_get_func = TS480_FUNC_ALL, + .has_set_func = TS480_FUNC_ALL, + .set_func = ts480_set_func, + .get_func = ts480_get_func, + .set_ext_func = ts480_set_ext_func, + .get_ext_func = ts480_get_ext_func, + .send_morse = kenwood_send_morse, + .wait_morse = rig_wait_morse, + .send_voice_mem = kenwood_send_voice_mem, + .stop_voice_mem = kenwood_stop_voice_mem, + .vfo_op = kenwood_vfo_op, + .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS +}; + /* * QRPLabs TS-480 emulation rig capabilities * Notice that some rigs share the same functions. @@ -2073,7 +2271,6 @@ int malachite_set_freq(RIG *rig, vfo_t vfo, freq_t freq) /* * Malachite SDR rig capabilities. * Notice that some rigs share the same functions. - * Also this struct is READONLY! */ struct rig_caps malachite_caps = { diff --git a/rigs/kenwood/ts570.c b/rigs/kenwood/ts570.c index 33f942c41..ba4f6f49f 100644 --- a/rigs/kenwood/ts570.c +++ b/rigs/kenwood/ts570.c @@ -891,7 +891,6 @@ int ts570_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) /* * ts570 rig capabilities. * Notice that some rigs share the same functions. - * Also this struct is READONLY! * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ @@ -1078,7 +1077,6 @@ struct rig_caps ts570s_caps = /* * ts570d rig capabilities, which is basically the ts570s without 6m. * Notice that some rigs share the same functions. - * Also this struct is READONLY! * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ diff --git a/rigs/kenwood/ts590.c b/rigs/kenwood/ts590.c index e758baa1e..df9dbb9f0 100644 --- a/rigs/kenwood/ts590.c +++ b/rigs/kenwood/ts590.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "hamlib/rig.h" #include "kenwood.h" @@ -217,6 +218,8 @@ static int ts590_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) char kmode = rmode2kenwood(mode, caps->mode_table); char cmd[32], c; int retval = -RIG_EINTERNAL; + int hwidth = 0; + // int lwidth; // not implemented yet until new API is created if (kmode < 0) { @@ -247,6 +250,70 @@ static int ts590_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) return kenwood_set_mode(rig, vfo, mode, width); } + if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) + { + const int cw_table[] = { 50, 80, 100, 150, 200, 250, 300, 400, 500, 600, 1000, 1500, 2000, 2500 }; + int twidth = 2500; // maximum + + for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) + { + if (cw_table[i] >= width) { twidth = cw_table[i]; break; } + } + + SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); + retval = kenwood_transaction(rig, cmd, NULL, 0); + return retval; + } + else if (mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) + { + const int cw_table[] = { 250, 500, 1000, 1500 }; + int twidth = 1500; // maximum + + for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) + { + if (cw_table[i] >= width) { twidth = cw_table[i]; break; } + } + + SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); + retval = kenwood_transaction(rig, cmd, NULL, 0); + return retval; + } + else if (mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) + { + const int pkt_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; + + // not setting SL since no API for it yet + // we will just set SH based on requested bandwidth not taking SL into account + //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; + for (int i = 0; i < sizeof(pkt_htable) / sizeof(int); ++i) + { + if (pkt_htable[i] >= width) { hwidth = i; break; } + } + } + else if (mode == RIG_MODE_AM || mode == RIG_MODE_PKTAM) + { + const int am_htable[] = { 2500, 3000, 4000, 5000 }; + + //const int am_ltable[] = { 0, 100, 200, 300 }; + for (int i = 0; i < sizeof(am_htable) / sizeof(int); ++i) + { + if (am_htable[i] >= width) { hwidth = i; break; } + } + } + else if (mode == RIG_MODE_SSB || mode == RIG_MODE_LSB || mode == RIG_MODE_USB) + { + const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; + + //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; + for (int i = 0; i < sizeof(ssb_htable) / sizeof(int); ++i) + { + if (ssb_htable[i] >= width) { hwidth = i; break; } + } + } + + SNPRINTF(cmd, sizeof(cmd), "SH%02d;", hwidth); + retval = kenwood_transaction(rig, cmd, NULL, 0); + return retval; } @@ -283,6 +350,23 @@ static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) *mode = kenwood2rmode(*mode, caps->mode_table); // now let's get our widths + // CW is different then other modes + if (*mode == RIG_MODE_CW || *mode == RIG_MODE_CWR || *mode == RIG_MODE_RTTY + || *mode == RIG_MODE_RTTYR) + { + SNPRINTF(cmd, sizeof(cmd), "FW"); + retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 6); + + if (retval == RIG_OK) + { + int twidth; + sscanf(ackbuf, "FW%d", &twidth); + *width = twidth; + } + + return retval; + } + SNPRINTF(cmd, sizeof(cmd), "SH"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); @@ -294,12 +378,12 @@ static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) } int hwidth; - sscanf(cmd, "SH%d", &hwidth); + sscanf(ackbuf, "SH%d", &hwidth); int lwidth; int shift = 0; SNPRINTF(cmd, sizeof(cmd), "SL"); - sscanf(cmd, "SH%d", &lwidth); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); + sscanf(ackbuf, "SL%d", &lwidth); if (retval != RIG_OK) { @@ -308,9 +392,7 @@ static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) return retval; } - if (*mode == RIG_MODE_PKTUSB || *mode == RIG_MODE_PKTLSB - || *mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM || *mode == RIG_MODE_USB - || *mode == RIG_MODE_LSB) + if (*mode == RIG_MODE_PKTUSB || *mode == RIG_MODE_PKTLSB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; @@ -325,14 +407,14 @@ static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) *width = am_htable[hwidth] - am_ltable[lwidth]; } -#if 0 // is this different? Manual is confusing - else if (*mode == RIG_MODE_SSB || *mode == RIG_MODE_LSB) + else if (*mode == RIG_MODE_SSB || *mode == RIG_MODE_LSB + || *mode == RIG_MODE_USB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; - //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; + const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; + *width = ssb_htable[hwidth] - ssb_ltable[lwidth]; } -#endif rig_debug(RIG_DEBUG_VERBOSE, "%s: width=%ld, shift=%d, lwidth=%d, hwidth=%d\n", __func__, *width, shift, lwidth, hwidth); @@ -467,7 +549,7 @@ static int ts590_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) switch (level) { case RIG_LEVEL_USB_AF: - kenwood_val = val.f * 9; + kenwood_val = roundl((val.f + .045) * 9); cmd = 65; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } @@ -476,7 +558,7 @@ static int ts590_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) break; case RIG_LEVEL_USB_AF_INPUT: - kenwood_val = val.f * 9; + kenwood_val = roundl((val.f + .045) * 9); cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } @@ -596,13 +678,13 @@ static int ts590_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; - retval = write_block(&rs->rigport, (unsigned char *) cmd, strlen(cmd)); + retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); @@ -613,7 +695,7 @@ static int ts590_read_meters(RIG *rig, int *swr, int *comp, int *alc) // TS-590 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; - retval = read_string(&rs->rigport, (unsigned char *) ackbuf, expected_len + 1, + retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); @@ -663,16 +745,34 @@ static int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); - val->f = levelint / 9.0; + + if (levelint == 9) + { + val->f = 1.0; + } + else + { + val->f = roundl(levelint * 10 / 10.0 + .04) / 10.0; + } + return retval; case RIG_LEVEL_USB_AF_INPUT: - cmd = 65; // TS-590S + cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); - val->f = levelint / 9.0; + + if (levelint == 9) + { + val->f = 1.0; + } + else + { + val->f = roundl(levelint * 10 / 10.0) / 10.0; + } + return retval; case RIG_LEVEL_AF: @@ -1593,7 +1693,7 @@ struct rig_caps ts590_caps = RIG_MODEL(RIG_MODEL_TS590S), .model_name = "TS-590S", .mfg_name = "Kenwood", - .version = BACKEND_VER ".11", + .version = BACKEND_VER ".13", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -1710,8 +1810,10 @@ struct rig_caps ts590_caps = .level_gran = { #include "level_gran_kenwood.h" - [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, - [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, + [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, + [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, + [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, + [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, @@ -1791,7 +1893,7 @@ struct rig_caps fx4_caps = RIG_MODEL(RIG_MODEL_FX4), .model_name = "FX4/C/CR/L", .mfg_name = "BG2FX", - .version = BACKEND_VER ".9", + .version = BACKEND_VER ".10", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -1905,7 +2007,7 @@ struct rig_caps fx4_caps = { #include "level_gran_kenwood.h" [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, - [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, + [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, @@ -1985,7 +2087,7 @@ struct rig_caps ts590sg_caps = RIG_MODEL(RIG_MODEL_TS590SG), .model_name = "TS-590SG", .mfg_name = "Kenwood", - .version = BACKEND_VER ".8", + .version = BACKEND_VER ".9", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -2015,7 +2117,7 @@ struct rig_caps ts590sg_caps = .chan_list = { /* TBC */ { 0, 89, RIG_MTYPE_MEM, TS590_CHANNEL_CAPS }, { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS }, - { 1, 3, RIG_MTYPE_MORSE }, + { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, @@ -2102,8 +2204,10 @@ struct rig_caps ts590sg_caps = }, .level_gran = { #include "level_gran_kenwood.h" - [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, - [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, + [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, + [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, + [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, + [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, diff --git a/rigs/kenwood/ts850.c b/rigs/kenwood/ts850.c index f829934ee..f649c51e2 100644 --- a/rigs/kenwood/ts850.c +++ b/rigs/kenwood/ts850.c @@ -94,7 +94,6 @@ static const struct confparams ts850_ext_parms[] = /* * ts850 rig capabilities. * Notice that some rigs share the same functions. -* Also this struct is READONLY! */ struct rig_caps ts850_caps = { diff --git a/rigs/kenwood/ts870s.c b/rigs/kenwood/ts870s.c index 2a7685cb2..cb130b0ef 100644 --- a/rigs/kenwood/ts870s.c +++ b/rigs/kenwood/ts870s.c @@ -528,7 +528,6 @@ static int ts870s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) /* * ts870s rig capabilities. * Notice that some rigs share the same functions. - * Also this struct is READONLY! * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ diff --git a/rigs/kenwood/ts930.c b/rigs/kenwood/ts930.c index 72f3c9088..31a1e577e 100644 --- a/rigs/kenwood/ts930.c +++ b/rigs/kenwood/ts930.c @@ -44,7 +44,6 @@ static struct kenwood_priv_caps ts930_priv_caps = /* * ts930 rig capabilities. * Notice that some rigs share the same functions. - * Also this struct is READONLY! * * part of infos comes from .http = //www.kenwood.net/ */ diff --git a/rigs/kenwood/xg3.c b/rigs/kenwood/xg3.c index 4a149e2c7..e8c8526fc 100644 --- a/rigs/kenwood/xg3.c +++ b/rigs/kenwood/xg3.c @@ -198,7 +198,7 @@ int xg3_init(RIG *rig) } rig->state.priv = (void *)priv; - rig->state.rigport.type.rig = RIG_PORT_SERIAL; + RIGPORT(rig)->type.rig = RIG_PORT_SERIAL; // Tried set_trn to turn transceiver on/off but turning it on isn't enabled in hamlib for some reason // So we use PTT instead // rig->state.transceive = RIG_TRN_RIG; // this allows xg3_set_trn to be called @@ -280,7 +280,7 @@ int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) char cmdbuf[32], replybuf[32]; int retval; size_t replysize = sizeof(replybuf); - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -288,7 +288,7 @@ int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "L;"); - retval = write_block(&rs->rigport, (unsigned char *) cmdbuf, strlen(cmdbuf)); + retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { @@ -297,7 +297,7 @@ int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return retval; } - retval = read_string(&rs->rigport, (unsigned char *) replybuf, replysize, + retval = read_string(rp, (unsigned char *) replybuf, replysize, ";", 1, 0, 1); if (retval < 0) @@ -424,7 +424,7 @@ int xg3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) */ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { - struct rig_state *rs; + struct hamlib_port *rp; char freqbuf[50]; int freqsize = sizeof(freqbuf); char cmdbuf[16]; @@ -441,7 +441,7 @@ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? rig->state.current_vfo : vfo; - rs = &rig->state; + rp = RIGPORT(rig); switch (tvfo) { @@ -467,7 +467,7 @@ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) SNPRINTF(cmdbuf, sizeof(cmdbuf), "F;"); } - retval = write_block(&rs->rigport, (unsigned char *) cmdbuf, strlen(cmdbuf)); + retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { @@ -475,7 +475,7 @@ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) return retval; } - retval = read_string(&rs->rigport, (unsigned char *) freqbuf, freqsize, + retval = read_string(rp, (unsigned char *) freqbuf, freqsize, ";", 1, 0, 1); if (retval < 0) @@ -574,7 +574,7 @@ int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch) char cmdbuf[32]; char reply[32]; int retval; - struct rig_state *rs = &rig->state; + struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -586,7 +586,7 @@ int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch) return retval; } - retval = read_string(&rs->rigport, (unsigned char *) reply, sizeof(reply), + retval = read_string(rp, (unsigned char *) reply, sizeof(reply), ";", 1, 0, 1); if (retval < 0) diff --git a/rigs/yaesu/ftdx10.c b/rigs/yaesu/ftdx10.c index 0f4f3249c..259d1c5a0 100644 --- a/rigs/yaesu/ftdx10.c +++ b/rigs/yaesu/ftdx10.c @@ -147,7 +147,7 @@ struct rig_caps ftdx10_caps = .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, - .serial_handshake = RIG_HANDSHAKE_NONE, + .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX10_WRITE_DELAY, .post_write_delay = FTDX10_POST_WRITE_DELAY, .timeout = 2000, diff --git a/rigs/yaesu/newcat.c b/rigs/yaesu/newcat.c index ba6056825..f9360c8d1 100644 --- a/rigs/yaesu/newcat.c +++ b/rigs/yaesu/newcat.c @@ -7262,7 +7262,7 @@ int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg) { if (strlen(msg2) > 50) { - msg2[50] = 0; // truncate if too long + msg2[51] = 0; // truncate if too long rig_debug(RIG_DEBUG_ERR, "%s: msg length of %d truncated to 50\n", __func__, (int)strlen(msg)); } @@ -11430,6 +11430,10 @@ int newcat_set_cmd_validate(RIG *rig) { strcpy(valcmd, "PC;"); } + else if (strncmp(priv->cmd_str, "AC", 2) == 0) + { + strcpy(valcmd, ""); + } else { rig_debug(RIG_DEBUG_TRACE, "%s: %s not implemented\n", __func__, priv->cmd_str); diff --git a/rigs/yaesu/newcat.h b/rigs/yaesu/newcat.h index 3d16c7865..d3a722eae 100644 --- a/rigs/yaesu/newcat.h +++ b/rigs/yaesu/newcat.h @@ -50,7 +50,7 @@ typedef char ncboolean; /* shared function version */ -#define NEWCAT_VER "20231230" +#define NEWCAT_VER "20240113" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 diff --git a/simulators/Makefile.am b/simulators/Makefile.am index 9b0412412..4f39570b3 100644 --- a/simulators/Makefile.am +++ b/simulators/Makefile.am @@ -8,7 +8,7 @@ DISTCLEANFILES = bin_PROGRAMS = -check_PROGRAMS = simelecraft simicgeneric simkenwood simyaesu simic9100 simic9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simic7300 simic7000 simic7100 simic7200 simatd578 simic905 simts450 simic7600 simic7610 simic705 simts950 simts990 simic7851 simftdx101 simxiegug90 simqrplabs simft818 simic275 simtrusdx simft1000 +check_PROGRAMS = simelecraft simicgeneric simkenwood simyaesu simic9100 simic9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simic7300 simic7000 simic7100 simic7200 simatd578 simic905 simts450 simic7600 simic7610 simic705 simts950 simts990 simic7851 simftdx101 simxiegug90 simqrplabs simft818 simic275 simtrusdx simft1000 simtmd710 simelecraft_SOURCES = simelecraft.c simkenwood_SOURCES = simkenwood.c diff --git a/simulators/simtmd710.c b/simulators/simtmd710.c new file mode 100644 index 000000000..1759aaf66 --- /dev/null +++ b/simulators/simtmd710.c @@ -0,0 +1,149 @@ +// can run this using rigctl/rigctld and socat pty devices +// gcc -o simyaesu simyaesu.c +#define _XOPEN_SOURCE 700 +// since we are POSIX here we need this +#if 0 +struct ip_mreq +{ + int dummy; +}; +#endif + +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 256 + +int mysleep = 20; + +float freqA = 14074000; +float freqB = 14074500; +int filternum = 7; +int datamode = 0; +int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; + +// ID 0310 == 310, Must drop leading zero +typedef enum nc_rigid_e +{ + NC_RIGID_NONE = 0, + NC_RIGID_FT450 = 241, + NC_RIGID_FT450D = 244, + NC_RIGID_FT950 = 310, + NC_RIGID_FT891 = 135, + NC_RIGID_FT991 = 135, + NC_RIGID_FT2000 = 251, + NC_RIGID_FT2000D = 252, + NC_RIGID_FTDX1200 = 583, + NC_RIGID_FTDX9000D = 101, + NC_RIGID_FTDX9000Contest = 102, + NC_RIGID_FTDX9000MP = 103, + NC_RIGID_FTDX5000 = 362, + NC_RIGID_FTDX3000 = 460, + NC_RIGID_FTDX101D = 681, + NC_RIGID_FTDX101MP = 682 +} nc_rigid_t; + +int +getmyline(int fd, char *buf) +{ + char c; + int i = 0; + memset(buf, 0, BUFSIZE); + + while (read(fd, &c, 1) > 0) + { + buf[i++] = c; + + if (c == 0x0d) { return strlen(buf); } + } + + if (strlen(buf) == 0) { hl_usleep(10 * 1000); } + + return strlen(buf); +} + +#if defined(WIN32) || defined(_WIN32) +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd; + fd = open(comport, O_RDWR); + + if (fd < 0) + { + perror(comport); + } + + return fd; +} + +#else +int openPort(char *comport) // doesn't matter for using pts devices +{ + int fd = posix_openpt(O_RDWR); + char *name = ptsname(fd); + + if (name == NULL) + { + perror("pstname"); + return -1; + } + + printf("name=%s\n", name); + + if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) + { + perror("posix_openpt"); + return -1; + } + + return fd; +} +#endif + + + +int main(int argc, char *argv[]) +{ + char buf[256]; + char *pbuf; + int fd = openPort(argv[1]); + int freqa = 14074000, freqb = 140735000; + int modeA = 0; // , modeB = 0; + + while (1) + { + buf[0] = 0; + + if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } + + if (strncmp(buf, "BC", 2) == 0) + { + SNPRINTF(buf, sizeof(buf), "BC %d %d%c", vfo, vfo_tx, 0x0d); + printf("R:%s\n", buf); + write(fd, buf, strlen(buf)); + continue; + } + else if (strncmp(buf, "FO", 2) == 0) + { + if (buf[3]=='0') { + SNPRINTF(buf, sizeof(buf), "FO 0 %d%c", freqA, 0x0d); + } + else { + SNPRINTF(buf, sizeof(buf), "FO 1 %d%c", freqB, 0x0d); + } + printf("R:%s\n", buf); + write(fd, buf, strlen(buf)); + continue; + } + else if (strlen(buf) > 0) + { + fprintf(stderr, "Unknown command: %s\n", buf); + } + } + + return 0; +} diff --git a/simulators/simxiegug90.c b/simulators/simxiegug90.c index 390854b03..7f995a501 100644 --- a/simulators/simxiegug90.c +++ b/simulators/simxiegug90.c @@ -69,7 +69,7 @@ frameGet(int fd, unsigned char *buf) } } - printf("Error %s\n", strerror(errno)); + //printf("Error %s\n", strerror(errno)); return 0; } diff --git a/src/Makefile.am b/src/Makefile.am index 0e57b113b..69b68b18f 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,7 @@ libhamlib_la_LIBADD = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/li libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/libsecurity.la $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) -EXTRA_DIST = Android.mk hamlibdatetime.h.in +EXTRA_DIST = Android.mk hamlibdatetime.h.in band_changed.c # If we have a .git directory then we will generate the hamlibdate.h diff --git a/src/amplifier.c b/src/amplifier.c index 318998594..bf5987865 100644 --- a/src/amplifier.c +++ b/src/amplifier.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup amplifier @@ -185,6 +186,7 @@ AMP *HAMLIB_API amp_init(amp_model_t amp_model) AMP *amp; const struct amp_caps *caps; struct amp_state *rs; + hamlib_port_t *ap; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -224,37 +226,41 @@ AMP *HAMLIB_API amp_init(amp_model_t amp_model) */ rs = &->state; - rs->comm_state = 0; - rs->ampport.type.rig = caps->port_type; /* default from caps */ + //TODO allocate and link new ampport + // For now, use the embedded one + ap = AMPPORT(amp); - rs->ampport.write_delay = caps->write_delay; - rs->ampport.post_write_delay = caps->post_write_delay; - rs->ampport.timeout = caps->timeout; - rs->ampport.retry = caps->retry; + rs->comm_state = 0; + ap->type.rig = caps->port_type; /* default from caps */ + + ap->write_delay = caps->write_delay; + ap->post_write_delay = caps->post_write_delay; + ap->timeout = caps->timeout; + ap->retry = caps->retry; rs->has_get_level = caps->has_get_level; switch (caps->port_type) { case RIG_PORT_SERIAL: // Don't think we need a default port here - //strncpy(rs->ampport.pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); - rs->ampport.parm.serial.rate = caps->serial_rate_max; /* fastest ! */ - rs->ampport.parm.serial.data_bits = caps->serial_data_bits; - rs->ampport.parm.serial.stop_bits = caps->serial_stop_bits; - rs->ampport.parm.serial.parity = caps->serial_parity; - rs->ampport.parm.serial.handshake = caps->serial_handshake; + //strncpy(ap->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); + ap->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ + ap->parm.serial.data_bits = caps->serial_data_bits; + ap->parm.serial.stop_bits = caps->serial_stop_bits; + ap->parm.serial.parity = caps->serial_parity; + ap->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: - strncpy(rs->ampport.pathname, "127.0.0.1:4531", HAMLIB_FILPATHLEN - 1); + strncpy(ap->pathname, "127.0.0.1:4531", HAMLIB_FILPATHLEN - 1); break; default: - strncpy(rs->ampport.pathname, "", HAMLIB_FILPATHLEN - 1); + strncpy(ap->pathname, "", HAMLIB_FILPATHLEN - 1); } - rs->ampport.fd = -1; + ap->fd = -1; /* * let the backend a chance to setup his private data @@ -279,7 +285,7 @@ AMP *HAMLIB_API amp_init(amp_model_t amp_model) // Now we have to copy our new rig state hamlib_port structure to the deprecated one // Clients built on older 4.X versions will use the old structure // Clients built on newer 4.5 versions will use the new structure - memcpy(&->state.ampport_deprecated, &->state.ampport, + memcpy(&->state.ampport_deprecated, ap, sizeof(amp->state.ampport_deprecated)); return amp; @@ -306,6 +312,7 @@ int HAMLIB_API amp_open(AMP *amp) { const struct amp_caps *caps; struct amp_state *rs; + hamlib_port_t *ap = AMPPORT(amp); int status; int net1, net2, net3, net4, port; @@ -324,21 +331,21 @@ int HAMLIB_API amp_open(AMP *amp) return -RIG_EINVAL; } - rs->ampport.fd = -1; + ap->fd = -1; // determine if we have a network address - if (sscanf(rs->ampport.pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, + if (sscanf(ap->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, - rs->ampport.pathname); - rs->ampport.type.rig = RIG_PORT_NETWORK; + ap->pathname); + ap->type.rig = RIG_PORT_NETWORK; } - switch (rs->ampport.type.rig) + switch (ap->type.rig) { case RIG_PORT_SERIAL: - status = serial_open(&rs->ampport); + status = serial_open(ap); if (status != 0) { @@ -348,7 +355,7 @@ int HAMLIB_API amp_open(AMP *amp) break; case RIG_PORT_PARALLEL: - status = par_open(&rs->ampport); + status = par_open(ap); if (status < 0) { @@ -358,18 +365,18 @@ int HAMLIB_API amp_open(AMP *amp) break; case RIG_PORT_DEVICE: - status = open(rs->ampport.pathname, O_RDWR, 0); + status = open(ap->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } - rs->ampport.fd = status; + ap->fd = status; break; case RIG_PORT_USB: - status = usb_port_open(&rs->ampport); + status = usb_port_open(ap); if (status < 0) { @@ -385,7 +392,7 @@ int HAMLIB_API amp_open(AMP *amp) case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: /* FIXME: default port */ - status = network_open(&rs->ampport, 4531); + status = network_open(ap, 4531); if (status < 0) { @@ -412,31 +419,31 @@ int HAMLIB_API amp_open(AMP *amp) if (status != RIG_OK) { - memcpy(&->state.ampport_deprecated, &->state.ampport, + memcpy(&->state.ampport_deprecated, ap, sizeof(amp->state.ampport_deprecated)); return status; } } - if (rs->ampport.parm.serial.dtr_state == RIG_SIGNAL_ON) + if (ap->parm.serial.dtr_state == RIG_SIGNAL_ON) { - ser_set_dtr(&rs->ampport, 1); + ser_set_dtr(ap, 1); } else { - ser_set_dtr(&rs->ampport, 0); + ser_set_dtr(ap, 0); } - if (rs->ampport.parm.serial.rts_state == RIG_SIGNAL_ON) + if (ap->parm.serial.rts_state == RIG_SIGNAL_ON) { - ser_set_rts(&rs->ampport, 1); + ser_set_rts(ap, 1); } else { - ser_set_rts(&rs->ampport, 0); + ser_set_rts(ap, 0); } - memcpy(&->state.ampport_deprecated, &->state.ampport, + memcpy(&->state.ampport_deprecated, ap, sizeof(amp->state.ampport_deprecated)); return RIG_OK; @@ -464,6 +471,7 @@ int HAMLIB_API amp_close(AMP *amp) { const struct amp_caps *caps; struct amp_state *rs; + hamlib_port_t *ap = AMPPORT(amp); amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -499,32 +507,32 @@ int HAMLIB_API amp_close(AMP *amp) } - if (rs->ampport.fd != -1) + if (ap->fd != -1) { - switch (rs->ampport.type.rig) + switch (ap->type.rig) { case RIG_PORT_SERIAL: - ser_close(&rs->ampport); + ser_close(ap); break; case RIG_PORT_PARALLEL: - par_close(&rs->ampport); + par_close(ap); break; case RIG_PORT_USB: - usb_port_close(&rs->ampport); + usb_port_close(ap); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: - network_close(&rs->ampport); + network_close(ap); break; default: - close(rs->ampport.fd); + close(ap->fd); } - rs->ampport.fd = -1; + ap->fd = -1; } remove_opened_amp(amp); @@ -949,5 +957,21 @@ int HAMLIB_API amp_get_powerstat(AMP *amp, powerstat_t *status) return amp->caps->get_powerstat(amp, status); } - +/** + * \brief Get the address of amplifier data structure(s) + * + * \sa rig_data_pointer + * + */ +void * HAMLIB_API amp_data_pointer(AMP *amp, rig_ptrx_t idx) +{ + switch(idx) + { + case RIG_PTRX_AMPPORT: + return AMPPORT(amp); + default: + amp_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); + return NULL; + } +} /*! @} */ diff --git a/src/band_changed.c b/src/band_changed.c new file mode 100644 index 000000000..075f46ce2 --- /dev/null +++ b/src/band_changed.c @@ -0,0 +1,99 @@ +// This is currently included in rig.c +// Can customize during build +// Eventually should improved this for external actions when +// rigctld gets integrated as a service within Hamlib +int rig_band_changed(RIG *rig, hamlib_bandselect_t band) +{ + // See band_changed.c + // Examples: + // rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TUNER, 1); + // rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TUNER, 0); + // value_t v; + // rig_set_ant(rig, RIG_VFO_CURR, 1, v); + switch (band) + { + case RIG_BANDSELECT_2200M: + break; + + case RIG_BANDSELECT_600M: + break; + + case RIG_BANDSELECT_160M: + break; + + case RIG_BANDSELECT_80M: + break; + + case RIG_BANDSELECT_60M: + break; + + case RIG_BANDSELECT_40M: + break; + + case RIG_BANDSELECT_30M: + break; + + case RIG_BANDSELECT_20M: + break; + + case RIG_BANDSELECT_17M: + break; + + case RIG_BANDSELECT_15M: + break; + + case RIG_BANDSELECT_12M: + + break; + + case RIG_BANDSELECT_10M: + break; + + case RIG_BANDSELECT_6M: + break; + + case RIG_BANDSELECT_WFM: + break; + + case RIG_BANDSELECT_MW: + break; + + case RIG_BANDSELECT_AIR: + break; + + case RIG_BANDSELECT_2M: + break; + + case RIG_BANDSELECT_1_25M: + break; + + case RIG_BANDSELECT_70CM: + break; + + case RIG_BANDSELECT_33CM: + break; + + case RIG_BANDSELECT_23CM: + break; + + case RIG_BANDSELECT_13CM: + break; + + case RIG_BANDSELECT_9CM: + break; + + case RIG_BANDSELECT_5CM: + break; + + case RIG_BANDSELECT_3CM: + break; + + case RIG_BANDSELECT_GEN: + break; + + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unknown band=%d\n", __func__, band); + } + + return RIG_OK; +} diff --git a/src/conf.c b/src/conf.c index 6ed087f6d..5099a0fad 100644 --- a/src/conf.c +++ b/src/conf.c @@ -239,6 +239,9 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) { struct rig_caps *caps; struct rig_state *rs; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); + hamlib_port_t *dcdp = DCDPORT(rig); long val_i; caps = rig->caps; @@ -247,7 +250,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) switch (token) { case TOK_PATHNAME: - strncpy(rs->rigport.pathname, val, HAMLIB_FILPATHLEN - 1); + strncpy(rp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->rigport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; @@ -257,7 +260,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.write_delay = val_i; + rp->write_delay = val_i; rs->rigport_deprecated.write_delay = val_i; break; @@ -267,7 +270,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.post_write_delay = val_i; + rp->post_write_delay = val_i; rs->rigport_deprecated.post_write_delay = val_i; break; @@ -286,7 +289,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.timeout = val_i; + rp->timeout = val_i; rs->rigport_deprecated.timeout = val_i; break; @@ -296,12 +299,12 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.retry = val_i; + rp->retry = val_i; rs->rigport_deprecated.retry = val_i; break; case TOK_SERIAL_SPEED: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } @@ -311,12 +314,12 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.parm.serial.rate = val_i; + rp->parm.serial.rate = val_i; rs->rigport_deprecated.parm.serial.rate = val_i; break; case TOK_DATA_BITS: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } @@ -326,12 +329,12 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.parm.serial.data_bits = val_i; + rp->parm.serial.data_bits = val_i; rs->rigport_deprecated.parm.serial.data_bits = val_i; break; case TOK_STOP_BITS: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } @@ -341,39 +344,39 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->rigport.parm.serial.stop_bits = val_i; + rp->parm.serial.stop_bits = val_i; rs->rigport_deprecated.parm.serial.stop_bits = val_i; break; case TOK_PARITY: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { - rs->rigport.parm.serial.parity = RIG_PARITY_NONE; + rp->parm.serial.parity = RIG_PARITY_NONE; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Odd")) { - rs->rigport.parm.serial.parity = RIG_PARITY_ODD; + rp->parm.serial.parity = RIG_PARITY_ODD; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Even")) { - rs->rigport.parm.serial.parity = RIG_PARITY_EVEN; + rp->parm.serial.parity = RIG_PARITY_EVEN; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Mark")) { - rs->rigport.parm.serial.parity = RIG_PARITY_MARK; + rp->parm.serial.parity = RIG_PARITY_MARK; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Space")) { - rs->rigport.parm.serial.parity = RIG_PARITY_SPACE; + rp->parm.serial.parity = RIG_PARITY_SPACE; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else @@ -384,7 +387,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) break; case TOK_HANDSHAKE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { rig_debug(RIG_DEBUG_ERR, "%s: setting handshake is invalid for non-serial port rig type\n", @@ -394,17 +397,17 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) if (!strcmp(val, "None")) { - rs->rigport.parm.serial.handshake = RIG_HANDSHAKE_NONE; + rp->parm.serial.handshake = RIG_HANDSHAKE_NONE; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else if (!strcmp(val, "XONXOFF")) { - rs->rigport.parm.serial.handshake = RIG_HANDSHAKE_XONXOFF; + rp->parm.serial.handshake = RIG_HANDSHAKE_XONXOFF; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else if (!strcmp(val, "Hardware")) { - rs->rigport.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; + rp->parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else @@ -415,24 +418,24 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) break; case TOK_RTS_STATE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { - rs->rigport.parm.serial.rts_state = RIG_SIGNAL_UNSET; + rp->parm.serial.rts_state = RIG_SIGNAL_UNSET; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { - rs->rigport.parm.serial.rts_state = RIG_SIGNAL_ON; + rp->parm.serial.rts_state = RIG_SIGNAL_ON; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { - rs->rigport.parm.serial.rts_state = RIG_SIGNAL_OFF; + rp->parm.serial.rts_state = RIG_SIGNAL_OFF; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_OFF; } else @@ -443,24 +446,24 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) break; case TOK_DTR_STATE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { - rs->rigport.parm.serial.dtr_state = RIG_SIGNAL_UNSET; + rp->parm.serial.dtr_state = RIG_SIGNAL_UNSET; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { - rs->rigport.parm.serial.dtr_state = RIG_SIGNAL_ON; + rp->parm.serial.dtr_state = RIG_SIGNAL_ON; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { - rs->rigport.parm.serial.dtr_state = RIG_SIGNAL_OFF; + rp->parm.serial.dtr_state = RIG_SIGNAL_OFF; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_OFF; } else @@ -522,46 +525,46 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) case TOK_PTT_TYPE: if (!strcmp(val, "RIG")) { - rs->pttport.type.ptt = RIG_PTT_RIG; + pttp->type.ptt = RIG_PTT_RIG; caps->ptt_type = RIG_PTT_RIG; } else if (!strcmp(val, "RIGMICDATA")) { - rs->pttport.type.ptt = RIG_PTT_RIG_MICDATA; + pttp->type.ptt = RIG_PTT_RIG_MICDATA; caps->ptt_type = RIG_PTT_RIG_MICDATA; } else if (!strcmp(val, "DTR")) { - rs->pttport.type.ptt = RIG_PTT_SERIAL_DTR; + pttp->type.ptt = RIG_PTT_SERIAL_DTR; caps->ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(val, "RTS")) { - rs->pttport.type.ptt = RIG_PTT_SERIAL_RTS; + pttp->type.ptt = RIG_PTT_SERIAL_RTS; caps->ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(val, "Parallel")) { - rs->pttport.type.ptt = RIG_PTT_PARALLEL; + pttp->type.ptt = RIG_PTT_PARALLEL; caps->ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(val, "CM108")) { - rs->pttport.type.ptt = RIG_PTT_CM108; + pttp->type.ptt = RIG_PTT_CM108; caps->ptt_type = RIG_PTT_CM108; } else if (!strcmp(val, "GPIO")) { - rs->pttport.type.ptt = RIG_PTT_GPIO; + pttp->type.ptt = RIG_PTT_GPIO; } else if (!strcmp(val, "GPION")) { - rs->pttport.type.ptt = RIG_PTT_GPION; + pttp->type.ptt = RIG_PTT_GPION; caps->ptt_type = RIG_PTT_GPION; } else if (!strcmp(val, "None")) { - rs->pttport.type.ptt = RIG_PTT_NONE; + pttp->type.ptt = RIG_PTT_NONE; caps->ptt_type = RIG_PTT_NONE; } else @@ -570,13 +573,13 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) } // JTDX and WSJTX currently use state.pttport to check for PTT_NONE - rig->state.pttport.type.ptt = rs->pttport.type.ptt; - rs->pttport_deprecated.type.ptt = rs->pttport.type.ptt; +// rig->state.pttport.type.ptt = pttp->type.ptt; + rs->pttport_deprecated.type.ptt = pttp->type.ptt; break; case TOK_PTT_PATHNAME: - strncpy(rs->pttport.pathname, val, HAMLIB_FILPATHLEN - 1); + strncpy(pttp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->pttport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; @@ -586,55 +589,55 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL;//value format error } - rs->pttport.parm.cm108.ptt_bitnum = val_i; - rs->rigport.parm.cm108.ptt_bitnum = val_i; + pttp->parm.cm108.ptt_bitnum = val_i; + rp->parm.cm108.ptt_bitnum = val_i; rs->pttport_deprecated.parm.cm108.ptt_bitnum = val_i; break; case TOK_DCD_TYPE: if (!strcmp(val, "RIG")) { - rs->dcdport.type.dcd = RIG_DCD_RIG; + dcdp->type.dcd = RIG_DCD_RIG; rs->dcdport_deprecated.type.dcd = RIG_DCD_RIG; } else if (!strcmp(val, "DSR")) { - rs->dcdport.type.dcd = RIG_DCD_SERIAL_DSR; + dcdp->type.dcd = RIG_DCD_SERIAL_DSR; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_DSR; } else if (!strcmp(val, "CTS")) { - rs->dcdport.type.dcd = RIG_DCD_SERIAL_CTS; + dcdp->type.dcd = RIG_DCD_SERIAL_CTS; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_CTS; } else if (!strcmp(val, "CD")) { - rs->dcdport.type.dcd = RIG_DCD_SERIAL_CAR; + dcdp->type.dcd = RIG_DCD_SERIAL_CAR; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_CAR; } else if (!strcmp(val, "Parallel")) { - rs->dcdport.type.dcd = RIG_DCD_PARALLEL; + dcdp->type.dcd = RIG_DCD_PARALLEL; rs->dcdport_deprecated.type.dcd = RIG_DCD_PARALLEL; } else if (!strcmp(val, "CM108")) { - rs->dcdport.type.dcd = RIG_DCD_CM108; + dcdp->type.dcd = RIG_DCD_CM108; rs->dcdport_deprecated.type.dcd = RIG_DCD_CM108; } else if (!strcmp(val, "GPIO")) { - rs->dcdport.type.dcd = RIG_DCD_GPIO; + dcdp->type.dcd = RIG_DCD_GPIO; rs->dcdport_deprecated.type.dcd = RIG_DCD_GPIO; } else if (!strcmp(val, "GPION")) { - rs->dcdport.type.dcd = RIG_DCD_GPION; + dcdp->type.dcd = RIG_DCD_GPION; rs->dcdport_deprecated.type.dcd = RIG_DCD_GPION; } else if (!strcmp(val, "None")) { - rs->dcdport.type.dcd = RIG_DCD_NONE; + dcdp->type.dcd = RIG_DCD_NONE; rs->dcdport_deprecated.type.dcd = RIG_DCD_NONE; } else @@ -645,7 +648,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) break; case TOK_DCD_PATHNAME: - strncpy(rs->dcdport.pathname, val, HAMLIB_FILPATHLEN - 1); + strncpy(dcdp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; @@ -728,7 +731,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL; //value format error } - rs->rigport.flushx = val_i ? 1 : 0; + rp->flushx = val_i ? 1 : 0; break; case TOK_TWIDDLE_TIMEOUT: @@ -768,7 +771,7 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val) return -RIG_EINVAL; } - rs->rigport.timeout_retry = val_i; + rp->timeout_retry = val_i; break; case TOK_OFFSET_VFOA: @@ -833,21 +836,24 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) { struct rig_state *rs; const char *s = ""; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); + hamlib_port_t *dcdp = DCDPORT(rig); rs = &rig->state; switch (token) { case TOK_PATHNAME: - SNPRINTF(val, val_len, "%s", rs->rigport.pathname); + SNPRINTF(val, val_len, "%s", rp->pathname); break; case TOK_WRITE_DELAY: - SNPRINTF(val, val_len, "%d", rs->rigport.write_delay); + SNPRINTF(val, val_len, "%d", rp->write_delay); break; case TOK_POST_WRITE_DELAY: - SNPRINTF(val, val_len, "%d", rs->rigport.post_write_delay); + SNPRINTF(val, val_len, "%d", rp->post_write_delay); break; case TOK_POST_PTT_DELAY: @@ -855,11 +861,11 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_TIMEOUT: - SNPRINTF(val, val_len, "%d", rs->rigport.timeout); + SNPRINTF(val, val_len, "%d", rp->timeout); break; case TOK_RETRY: - SNPRINTF(val, val_len, "%d", rs->rigport.retry); + SNPRINTF(val, val_len, "%d", rp->retry); break; #if 0 // needs to be replace? @@ -871,39 +877,39 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) #endif case TOK_SERIAL_SPEED: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - SNPRINTF(val, val_len, "%d", rs->rigport.parm.serial.rate); + SNPRINTF(val, val_len, "%d", rp->parm.serial.rate); break; case TOK_DATA_BITS: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - SNPRINTF(val, val_len, "%d", rs->rigport.parm.serial.data_bits); + SNPRINTF(val, val_len, "%d", rp->parm.serial.data_bits); break; case TOK_STOP_BITS: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - SNPRINTF(val, val_len, "%d", rs->rigport.parm.serial.stop_bits); + SNPRINTF(val, val_len, "%d", rp->parm.serial.stop_bits); break; case TOK_PARITY: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - switch (rs->rigport.parm.serial.parity) + switch (rp->parm.serial.parity) { case RIG_PARITY_NONE: s = "None"; @@ -933,7 +939,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_HANDSHAKE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { rig_debug(RIG_DEBUG_ERR, "%s: getting handshake is invalid for non-serial port rig type\n", @@ -941,7 +947,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) return -RIG_EINVAL; } - switch (rs->rigport.parm.serial.handshake) + switch (rp->parm.serial.handshake) { case RIG_HANDSHAKE_NONE: s = "None"; @@ -963,12 +969,12 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_RTS_STATE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - switch (rs->rigport.parm.serial.rts_state) + switch (rp->parm.serial.rts_state) { case RIG_SIGNAL_UNSET: s = "Unset"; @@ -990,12 +996,12 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_DTR_STATE: - if (rs->rigport.type.rig != RIG_PORT_SERIAL) + if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } - switch (rs->rigport.parm.serial.dtr_state) + switch (rp->parm.serial.dtr_state) { case RIG_SIGNAL_UNSET: s = "Unset"; @@ -1029,7 +1035,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_PTT_TYPE: - switch (rs->pttport.type.ptt) + switch (pttp->type.ptt) { case RIG_PTT_RIG: s = "RIG"; @@ -1075,15 +1081,15 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_PTT_PATHNAME: - strcpy(val, rs->pttport.pathname); + strcpy(val, pttp->pathname); break; case TOK_PTT_BITNUM: - SNPRINTF(val, val_len, "%d", rs->pttport.parm.cm108.ptt_bitnum); + SNPRINTF(val, val_len, "%d", pttp->parm.cm108.ptt_bitnum); break; case TOK_DCD_TYPE: - switch (rs->dcdport.type.dcd) + switch (dcdp->type.dcd) { case RIG_DCD_RIG: s = "RIG"; @@ -1129,7 +1135,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_DCD_PATHNAME: - strcpy(val, rs->dcdport.pathname); + strcpy(val, dcdp->pathname); break; case TOK_LO_FREQ: @@ -1157,7 +1163,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_FLUSHX: - SNPRINTF(val, val_len, "%d", rs->rigport.flushx); + SNPRINTF(val, val_len, "%d", rp->flushx); break; case TOK_DISABLE_YAESU_BANDSELECT: @@ -1177,7 +1183,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) break; case TOK_TIMEOUT_RETRY: - SNPRINTF(val, val_len, "%d", rs->rigport.timeout_retry); + SNPRINTF(val, val_len, "%d", rp->timeout_retry); break; case TOK_MULTICAST_DATA_ADDR: @@ -1200,7 +1206,7 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len) return -RIG_EINVAL; } - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); return RIG_OK; } @@ -1371,7 +1377,6 @@ token_t HAMLIB_API rig_token_lookup(RIG *rig, const char *name) */ int HAMLIB_API rig_set_conf(RIG *rig, token_t token, const char *val) { - struct rig_state *rs = &rig->state; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) @@ -1380,7 +1385,7 @@ int HAMLIB_API rig_set_conf(RIG *rig, token_t token, const char *val) } // Some parameters can be ignored - if (token == TOK_HANDSHAKE && (rs->rigport.type.rig != RIG_PORT_SERIAL)) + if (token == TOK_HANDSHAKE && (RIGPORT(rig)->type.rig != RIG_PORT_SERIAL)) { rig_debug(RIG_DEBUG_WARN, "%s: handshake is not valid for non-serial port rig\n", __func__); diff --git a/src/misc.c b/src/misc.c index d204886bf..c9000156c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -837,7 +837,7 @@ setting_t HAMLIB_API rig_parse_band(const char *s) rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); - for (i = 0 ; rig_bandselect_str[i].str[0] != '\0'; i++) + for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (!strcmp(s, rig_bandselect_str[i].str)) { @@ -2004,9 +2004,10 @@ vfo_t HAMLIB_API vfo_fixup2a(RIG *rig, vfo_t vfo, split_t split, // We need to add some exceptions to this like the ID-5100 vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo, split_t split) { + vfo_t currvfo = rig->state.current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s:(from %s:%d) vfo=%s, vfo_curr=%s, split=%d\n", __func__, funcname, linenum, - rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo), split); + rig_strvfo(vfo), rig_strvfo(currvfo), split); if (rig->caps->rig_model == RIG_MODEL_ID5100 || rig->caps->rig_model == RIG_MODEL_IC9700) @@ -2023,6 +2024,28 @@ vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo, split_t split) return vfo; // no change to requested vfo } + else if (RIG_IS_IC9700) + { + if (vfo == RIG_VFO_A && (currvfo == RIG_VFO_MAIN || currvfo == RIG_VFO_MAIN_A)) + { + vfo = RIG_VFO_MAIN_A; + } + else if (vfo == RIG_VFO_B && (currvfo == RIG_VFO_MAIN + || currvfo == RIG_VFO_MAIN_A)) + { + vfo = RIG_VFO_MAIN_B; + } + else if (vfo == RIG_VFO_A && (currvfo == RIG_VFO_SUB + || currvfo == RIG_VFO_SUB_A || currvfo == RIG_VFO_SUB_B)) + { + vfo = RIG_VFO_SUB_A; + } + else if (vfo == RIG_VFO_B && (currvfo == RIG_VFO_SUB + || currvfo == RIG_VFO_SUB_A || currvfo == RIG_VFO_SUB_B)) + { + vfo = RIG_VFO_SUB_B; + } + } if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } @@ -2827,9 +2850,25 @@ char *rig_date_strget(char *buf, int buflen, int localtime) return date_strget(buf, buflen, localtime); } -const char *spaces() +const char *spaces(int len) { - static char *s = " "; + static char s[256]; + memset(s, '*', sizeof(s)); + + if (len > 255) + { + len = 0; + } + + if (len > 0) + { + s[len + 1] = 0; + } + else + { + s[1] = 0; + } + return s; } @@ -2841,7 +2880,7 @@ const char *rig_get_band_str(RIG *rig, hamlib_band_t band, int which) if (which == 0) { - for (i = 0; rig_bandselect_str[i].str[0] != '\0'; i++) + for (i = 0; rig_bandselect_str[i].str != NULL; i++) { if (rig_bandselect_str[i].bandselect == band) { @@ -2871,7 +2910,7 @@ const char *rig_get_band_str(RIG *rig, hamlib_band_t band, int which) { if (n == band) { - for (i = 0; rig_bandselect_str[i].str[0] != '\0'; i++) + for (i = 0; rig_bandselect_str[i].str != NULL; i++) { if (strcmp(rig_bandselect_str[i].str, token) == 0) { @@ -2927,7 +2966,7 @@ hamlib_band_t rig_get_band(RIG *rig, freq_t freq, int band) return RIG_BAND_UNUSED; } - for (i = 0 ; rig_bandselect_str[i].str[0] != '\0'; i++) + for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (freq >= rig_bandselect_str[i].start && freq <= rig_bandselect_str[i].stop) { @@ -2944,12 +2983,26 @@ int rig_get_band_rig(RIG *rig, freq_t freq, const char *band) char bandlist[512]; int i; + if (freq == 0 && band == NULL) + { + rig_debug(RIG_DEBUG_ERR, "%s: bad combo of freq==0 && band==NULL\n", __func__); + return RIG_BAND_GEN; + } + if (freq == 0) { rig_sprintf_parm_gran(bandlist, sizeof(bandlist) - 1, RIG_PARM_BANDSELECT, rig->caps->parm_gran); + bandlist[0] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: bandlist=%s\n", __func__, bandlist); + // e.g. BANDSELECT(BAND160M,BAND80M,BANDUNUSED,BAND40M) + if (strlen(bandlist) == 0) + { + rig_debug(RIG_DEBUG_ERR, "%s: rig does not have bandlist\n", __func__); + return RIG_BAND_GEN; + } + char *p = strchr(bandlist, '(') + 1; char *token; @@ -2973,7 +3026,7 @@ int rig_get_band_rig(RIG *rig, freq_t freq, const char *band) return 0; } - for (i = 0 ; rig_bandselect_str[i].str[0] != '\0'; i++) + for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (freq >= rig_bandselect_str[i].start && freq <= rig_bandselect_str[i].stop) { diff --git a/src/misc.h b/src/misc.h index 98c130d45..5c42ad343 100644 --- a/src/misc.h +++ b/src/misc.h @@ -40,7 +40,7 @@ __BEGIN_DECLS // a function to return just a string of spaces for indenting rig debug lines -HAMLIB_EXPORT (const char *) spaces(); +HAMLIB_EXPORT (const char *) spaces(int len); /* * Do a hex dump of the unsigned char array. */ @@ -158,7 +158,7 @@ extern HAMLIB_EXPORT(char *)date_strget(char *buf, int buflen, int localtime); void errmsg(int err, char *s, const char *func, const char *file, int line); #define ERRMSG(err, s) errmsg(err, s, __func__, __FILENAME__, __LINE__) #define ENTERFUNC { ++rig->state.depth; \ - rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s entered\n", rig->state.depth-1, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__); \ + rig_debug(RIG_DEBUG_VERBOSE, "%s%d:%s(%d):%s entered\n", spaces(rig->state.depth), rig->state.depth, __FILENAME__, __LINE__, __func__); \ } #define ENTERFUNC2 { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):%s entered\n", __FILENAME__, __LINE__, __func__); \ } @@ -166,7 +166,7 @@ void errmsg(int err, char *s, const char *func, const char *file, int line); // could be a function call #define RETURNFUNC(rc) {do { \ int rctmp = rc; \ - rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s(%d):%s returning(%ld) %s\n", rig->state.depth, spaces(), rig->state.depth, __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ + rig_debug(RIG_DEBUG_VERBOSE, "%s%d:%s(%d):%s returning(%ld) %s\n", spaces(rig->state.depth), rig->state.depth, __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ --rig->state.depth; \ return (rctmp); \ } while(0);} diff --git a/src/multicast.c b/src/multicast.c index f610cf067..189d15b7f 100644 --- a/src/multicast.c +++ b/src/multicast.c @@ -297,7 +297,7 @@ static int multicast_send_json(RIG *rig) // sprintf(msg,"%s:f=%.1f", date_strget(msg, (int)sizeof(msg), 0), f); msg[0] = 0; snprintf(buf, sizeof(buf), "%s:%s", rig->caps->model_name, - rig->state.rigport.pathname); + RIGPORT(rig)->pathname); strcat(msg, "{\n"); json_add_string(msg, "ID", buf, 1); json_add_time(msg, 1); @@ -339,7 +339,7 @@ void *multicast_thread_rx(void *vrig) while (rig->state.multicast->runflag) { #if 0 - ret = read_string(&rig->state.rigport, (unsigned char *) buf, sizeof(buf), "\n", + ret = read_string(RIGPORT(rig), (unsigned char *) buf, sizeof(buf), "\n", 1, 0, 1); #endif @@ -652,8 +652,8 @@ int main(int argc, const char *argv[]) return 1; } - strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1); - rig->state.rigport.parm.serial.rate = 38400; + strncpy(RIGPORT(rig)->pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1); + RIGPORT(rig)->parm.serial.rate = 38400; rig_open(rig); multicast_init(rig, "224.0.0.1", 4532); pthread_join(rig->state.multicast->threadid, NULL); diff --git a/src/network.c b/src/network.c index 104bd6ec8..686c8d181 100644 --- a/src/network.c +++ b/src/network.c @@ -1053,8 +1053,15 @@ void *multicast_publisher(void *arg) if (send_result < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: error sending UDP packet: %s\n", __func__, - strerror(errno)); + static int flag = 0; + + if (errno != 0 || flag == 0) + { + rig_debug(RIG_DEBUG_ERR, + "%s: error sending UDP packet: %s\n", __func__, + strerror(errno)); + flag = 1; + } } } diff --git a/src/rig.c b/src/rig.c index d128e3ab4..751180729 100644 --- a/src/rig.c +++ b/src/rig.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup rig @@ -517,6 +518,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) RIG *rig; const struct rig_caps *caps; struct rig_state *rs; + hamlib_port_t *rp, *pttp, *dcdp; int i; rig_check_rig_caps(); @@ -581,11 +583,17 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) pthread_mutex_init(&rs->mutex_set_transaction, NULL); #endif + //TODO Allocate and link ports + // For now, use the embedded ones + rp = RIGPORT(rig); + pttp = PTTPORT(rig); + dcdp = DCDPORT(rig); + rs->rig_model = caps->rig_model; rs->priv = NULL; rs->async_data_enabled = 0; - rs->rigport.fd = -1; - rs->pttport.fd = -1; + rp->fd = -1; + pttp->fd = -1; rs->comm_state = 0; rig->state.depth = 1; #if 0 // extra debug if needed @@ -593,9 +601,9 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) __LINE__, &rs->comm_state, rs->comm_state); #endif - rs->rigport.type.rig = caps->port_type; /* default from caps */ + rp->type.rig = caps->port_type; /* default from caps */ #if defined(HAVE_PTHREAD) - rs->rigport.asyncio = 0; + rp->asyncio = 0; #endif rig->state.comm_status = RIG_COMM_STATUS_CONNECTING; @@ -604,73 +612,73 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) switch (caps->port_type) { case RIG_PORT_SERIAL: - strncpy(rs->rigport.pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); - rs->rigport.parm.serial.rate = caps->serial_rate_max; /* fastest ! */ - rs->rigport.parm.serial.data_bits = caps->serial_data_bits; - rs->rigport.parm.serial.stop_bits = caps->serial_stop_bits; - rs->rigport.parm.serial.parity = caps->serial_parity; - rs->rigport.parm.serial.handshake = caps->serial_handshake; + strncpy(rp->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); + rp->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ + rp->parm.serial.data_bits = caps->serial_data_bits; + rp->parm.serial.stop_bits = caps->serial_stop_bits; + rp->parm.serial.parity = caps->serial_parity; + rp->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_PARALLEL: - strncpy(rs->rigport.pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); + strncpy(rp->pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); break; /* Adding support for CM108 GPIO. This is compatible with CM108 series * USB audio chips from CMedia and SSS1623 series USB audio chips from 3S */ case RIG_PORT_CM108: - strncpy(rs->rigport.pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); + strncpy(rp->pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); - if (rs->rigport.parm.cm108.ptt_bitnum == 0) + if (rp->parm.cm108.ptt_bitnum == 0) { - rs->rigport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; - rs->pttport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; + rp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; + pttp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; } break; case RIG_PORT_GPIO: - strncpy(rs->rigport.pathname, DEFAULT_GPIO_PORT, HAMLIB_FILPATHLEN); + strncpy(rp->pathname, DEFAULT_GPIO_PORT, HAMLIB_FILPATHLEN); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: - strncpy(rs->rigport.pathname, "127.0.0.1:4532", HAMLIB_FILPATHLEN - 1); + strncpy(rp->pathname, "127.0.0.1:4532", HAMLIB_FILPATHLEN - 1); break; default: - strncpy(rs->rigport.pathname, "", HAMLIB_FILPATHLEN - 1); + strncpy(rp->pathname, "", HAMLIB_FILPATHLEN - 1); } - rs->rigport.write_delay = caps->write_delay; - rs->rigport.post_write_delay = caps->post_write_delay; + rp->write_delay = caps->write_delay; + rp->post_write_delay = caps->post_write_delay; // since we do two timeouts now we can cut the timeout in half for serial if (caps->port_type == RIG_PORT_SERIAL && caps->timeout_retry >= 0) { - rs->rigport.timeout = caps->timeout / 2; + rp->timeout = caps->timeout / 2; } - rs->rigport.retry = caps->retry; + rp->retry = caps->retry; if (caps->timeout_retry < 0) { // Rigs may disable read timeout retries - rs->rigport.timeout_retry = 0; + rp->timeout_retry = 0; } else if (caps->timeout_retry == 0) { // Default to 1 retry for read timeouts - rs->rigport.timeout_retry = 1; + rp->timeout_retry = 1; } else { - rs->rigport.timeout_retry = caps->timeout_retry; + rp->timeout_retry = caps->timeout_retry; } - rs->pttport.type.ptt = caps->ptt_type; - rs->dcdport.type.dcd = caps->dcd_type; + pttp->type.ptt = caps->ptt_type; + dcdp->type.dcd = caps->dcd_type; rs->vfo_comp = 0.0; /* override it with preferences */ rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */ @@ -837,7 +845,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) rs->max_ifshift = caps->max_ifshift; rs->announces = caps->announces; - rs->rigport.fd = rs->pttport.fd = rs->dcdport.fd = -1; + rp->fd = pttp->fd = dcdp->fd = -1; // some rigs (like SDR) behave differnt when checking for power on // So we assume power is on until one of the backends KNOWS it is off rs->powerstat = RIG_POWER_ON; // default to power on until proven otherwise @@ -889,6 +897,9 @@ int HAMLIB_API rig_open(RIG *rig) { struct rig_caps *caps; struct rig_state *rs; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); + hamlib_port_t *dcdp = DCDPORT(rig); int status = RIG_OK; value_t parm_value; //unsigned int net1, net2, net3, net4, net5, net6, net7, net8, port; @@ -904,10 +915,10 @@ int HAMLIB_API rig_open(RIG *rig) caps = rig->caps; rs = &rig->state; - rs->rigport.rig = rig; + rp->rig = rig; rs->rigport_deprecated.rig = rig; - if (strcmp(rs->rigport.pathname, "USB") == 0) + if (strcmp(rp->pathname, "USB") == 0) { rig_debug(RIG_DEBUG_ERR, "%s: 'USB' is not a valid COM port name\n", __func__); errno = 2; @@ -917,27 +928,27 @@ int HAMLIB_API rig_open(RIG *rig) // rigctl/rigctld may have deprecated values -- backwards compatibility if (rs->rigport_deprecated.pathname[0] != 0) { - strcpy(rs->rigport.pathname, rs->rigport_deprecated.pathname); + strcpy(rp->pathname, rs->rigport_deprecated.pathname); } if (rs->pttport_deprecated.type.ptt != RIG_PTT_NONE) { - rs->pttport.type.ptt = rs->pttport_deprecated.type.ptt; + pttp->type.ptt = rs->pttport_deprecated.type.ptt; } if (rs->dcdport_deprecated.type.dcd != RIG_DCD_NONE) { - rs->dcdport.type.dcd = rs->dcdport_deprecated.type.dcd; + dcdp->type.dcd = rs->dcdport_deprecated.type.dcd; } if (rs->pttport_deprecated.pathname[0] != 0) { - strcpy(rs->pttport.pathname, rs->pttport_deprecated.pathname); + strcpy(pttp->pathname, rs->pttport_deprecated.pathname); } if (rs->dcdport_deprecated.pathname[0] != 0) { - strcpy(rs->dcdport.pathname, rs->dcdport_deprecated.pathname); + strcpy(dcdp->pathname, rs->dcdport_deprecated.pathname); } rig_settings_load_all(NULL); // load default .hamlib_settings @@ -987,12 +998,12 @@ int HAMLIB_API rig_open(RIG *rig) "%s: async_data_enable=%d, async_data_supported=%d\n", __func__, rs->async_data_enabled, caps->async_data_supported); rs->async_data_enabled = rs->async_data_enabled && caps->async_data_supported; - rs->rigport.asyncio = rs->async_data_enabled; + rp->asyncio = rs->async_data_enabled; - if (strlen(rs->rigport.pathname) > 0) + if (strlen(rp->pathname) > 0) { char hoststr[256], portstr[6]; - status = parse_hoststr(rs->rigport.pathname, sizeof(rs->rigport.pathname), + status = parse_hoststr(rp->pathname, sizeof(rp->pathname), hoststr, portstr); if (status == RIG_OK) { is_network = 1; } @@ -1001,16 +1012,16 @@ int HAMLIB_API rig_open(RIG *rig) #if 0 // determine if we have a network address // - is_network |= sscanf(rs->rigport.pathname, "%u.%u.%u.%u:%u", &net1, &net2, + is_network |= sscanf(rp->pathname, "%u.%u.%u.%u:%u", &net1, &net2, &net3, &net4, &port) == 5; - is_network |= sscanf(rs->rigport.pathname, ":%u", &port) == 1; - is_network |= sscanf(rs->rigport.pathname, "%u::%u:%u:%u:%u:%u", &net1, &net2, + is_network |= sscanf(rp->pathname, ":%u", &port) == 1; + is_network |= sscanf(rp->pathname, "%u::%u:%u:%u:%u:%u", &net1, &net2, &net3, &net4, &net5, &port) == 6; - is_network |= sscanf(rs->rigport.pathname, "%u:%u:%u:%u:%u:%u:%u:%u:%u", &net1, + is_network |= sscanf(rp->pathname, "%u:%u:%u:%u:%u:%u:%u:%u:%u", &net1, &net2, &net3, &net4, &net5, &net6, &net7, &net8, &port) == 9; // if we haven't met one of the condition above then we must have a hostname - if (!is_network && (token = strtok_r(rs->rigport.pathname, ":", &strtokp))) + if (!is_network && (token = strtok_r(rp->pathname, ":", &strtokp))) { rig_debug(RIG_DEBUG_TRACE, "%s: token1=%s\n", __func__, token); token = strtok_r(strtokp, ":", &strtokp); @@ -1028,19 +1039,21 @@ int HAMLIB_API rig_open(RIG *rig) if (is_network) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, - rs->rigport.pathname); - rs->rigport.type.rig = RIG_PORT_NETWORK; + rp->pathname); + rp->type.rig = RIG_PORT_NETWORK; if (RIG_BACKEND_NUM(rig->caps->rig_model) == RIG_ICOM) { // Xiegu X6100 does TCP and does not support UDP spectrum that I know of +#if 0 if (rig->caps->rig_model != RIG_MODEL_X6100) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): Icom rig UDP network enabled\n", __FILE__, __LINE__); - rs->rigport.type.rig = RIG_PORT_UDP_NETWORK; + rp->type.rig = RIG_PORT_UDP_NETWORK; } +#endif } } @@ -1049,55 +1062,55 @@ int HAMLIB_API rig_open(RIG *rig) rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %p rs->comm_state==1?=%d\n", __func__, __LINE__, &rs->comm_state, rs->comm_state); - port_close(&rs->rigport, rs->rigport.type.rig); + port_close(rp, rp->type.rig); rs->comm_state = 0; RETURNFUNC2(-RIG_EINVAL); } rs->comm_status = RIG_COMM_STATUS_CONNECTING; - rs->rigport.fd = -1; + rp->fd = -1; - if (rs->rigport.type.rig == RIG_PORT_SERIAL) + if (rp->type.rig == RIG_PORT_SERIAL) { - if (rs->rigport.parm.serial.rts_state != RIG_SIGNAL_UNSET - && rs->rigport.parm.serial.handshake == RIG_HANDSHAKE_HARDWARE) + if (rp->parm.serial.rts_state != RIG_SIGNAL_UNSET + && rp->parm.serial.handshake == RIG_HANDSHAKE_HARDWARE) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set RTS with hardware handshake \"%s\"\n", __func__, - rs->rigport.pathname); + rp->pathname); RETURNFUNC2(-RIG_ECONF); } - if ('\0' == rs->pttport.pathname[0] - || !strcmp(rs->pttport.pathname, rs->rigport.pathname)) + if ('\0' == pttp->pathname[0] + || !strcmp(pttp->pathname, rp->pathname)) { /* check for control line conflicts */ - if (rs->rigport.parm.serial.rts_state != RIG_SIGNAL_UNSET - && rs->pttport.type.ptt == RIG_PTT_SERIAL_RTS) + if (rp->parm.serial.rts_state != RIG_SIGNAL_UNSET + && pttp->type.ptt == RIG_PTT_SERIAL_RTS) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set RTS with PTT by RTS \"%s\"\n", __func__, - rs->rigport.pathname); + rp->pathname); RETURNFUNC2(-RIG_ECONF); } - if (rs->rigport.parm.serial.dtr_state != RIG_SIGNAL_UNSET - && rs->pttport.type.ptt == RIG_PTT_SERIAL_DTR) + if (rp->parm.serial.dtr_state != RIG_SIGNAL_UNSET + && pttp->type.ptt == RIG_PTT_SERIAL_DTR) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set DTR with PTT by DTR \"%s\"\n", __func__, - rs->rigport.pathname); + rp->pathname); RETURNFUNC2(-RIG_ECONF); } } } - rs->rigport.timeout = caps->timeout; - status = port_open(&rs->rigport); + rp->timeout = caps->timeout; + status = port_open(rp); if (status < 0) { @@ -1108,7 +1121,7 @@ int HAMLIB_API rig_open(RIG *rig) RETURNFUNC2(status); } - switch (rs->pttport.type.ptt) + switch (pttp->type.ptt) { case RIG_PTT_NONE: case RIG_PTT_RIG: @@ -1117,124 +1130,123 @@ int HAMLIB_API rig_open(RIG *rig) case RIG_PTT_SERIAL_RTS: case RIG_PTT_SERIAL_DTR: - if (rs->pttport.pathname[0] == '\0' - && rs->rigport.type.rig == RIG_PORT_SERIAL) + if (pttp->pathname[0] == '\0' + && rp->type.rig == RIG_PORT_SERIAL) { - strcpy(rs->pttport.pathname, rs->rigport.pathname); + strcpy(pttp->pathname, rp->pathname); } - if (!strcmp(rs->pttport.pathname, rs->rigport.pathname)) + if (!strcmp(pttp->pathname, rp->pathname)) { - rs->pttport.fd = rs->rigport.fd; + pttp->fd = rp->fd; /* Needed on Linux because the serial port driver sets RTS/DTR on open - only need to address the PTT line as we offer config parameters to control the other (dtr_state & rts_state) */ - if (rs->pttport.type.ptt == RIG_PTT_SERIAL_DTR) + if (pttp->type.ptt == RIG_PTT_SERIAL_DTR) { - status = ser_set_dtr(&rs->pttport, 0); + status = ser_set_dtr(pttp, 0); } - if (rs->pttport.type.ptt == RIG_PTT_SERIAL_RTS) + if (pttp->type.ptt == RIG_PTT_SERIAL_RTS) { - status = ser_set_rts(&rs->pttport, 0); + status = ser_set_rts(pttp, 0); } } else { - rs->pttport.fd = ser_open(&rs->pttport); + pttp->fd = ser_open(pttp); - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); status = -RIG_EIO; } if (RIG_OK == status - && (rs->pttport.type.ptt == RIG_PTT_SERIAL_DTR - || rs->pttport.type.ptt == RIG_PTT_SERIAL_RTS)) + && (pttp->type.ptt == RIG_PTT_SERIAL_DTR + || pttp->type.ptt == RIG_PTT_SERIAL_RTS)) { /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both low since we offer no control of the non-PTT line and low is better than high */ - status = ser_set_dtr(&rs->pttport, 0); + status = ser_set_dtr(pttp, 0); if (RIG_OK == status) { - status = ser_set_rts(&rs->pttport, 0); + status = ser_set_rts(pttp, 0); } } - ser_close(&rs->pttport); + ser_close(pttp); } break; case RIG_PTT_PARALLEL: - rs->pttport.fd = par_open(&rs->pttport); + pttp->fd = par_open(pttp); - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); status = -RIG_EIO; } else { - par_ptt_set(&rs->pttport, RIG_PTT_OFF); + par_ptt_set(pttp, RIG_PTT_OFF); } break; case RIG_PTT_CM108: - rs->pttport.fd = cm108_open(&rs->pttport); + pttp->fd = cm108_open(pttp); - strncpy(rs->rigport.pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); + strncpy(rp->pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); - if (rs->rigport.parm.cm108.ptt_bitnum == 0) + if (rp->parm.cm108.ptt_bitnum == 0) { - rs->rigport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; - rs->pttport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; + rp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; + pttp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; } - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); status = -RIG_EIO; } else { - cm108_ptt_set(&rs->pttport, RIG_PTT_OFF); + cm108_ptt_set(pttp, RIG_PTT_OFF); } break; case RIG_PTT_GPIO: case RIG_PTT_GPION: - rs->pttport.fd = gpio_open(&rs->pttport, 1, - RIG_PTT_GPION == rs->pttport.type.ptt ? 0 : 1); + pttp->fd = gpio_open(pttp, 1, RIG_PTT_GPION == pttp->type.ptt ? 0 : 1); - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"GPIO%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); status = -RIG_EIO; } else { - gpio_ptt_set(&rs->pttport, RIG_PTT_OFF); + gpio_ptt_set(pttp, RIG_PTT_OFF); } break; @@ -1243,11 +1255,11 @@ int HAMLIB_API rig_open(RIG *rig) rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, - rs->pttport.type.ptt); + pttp->type.ptt); status = -RIG_ECONF; } - switch (rs->dcdport.type.dcd) + switch (dcdp->type.dcd) { case RIG_DCD_NONE: case RIG_DCD_RIG: @@ -1256,41 +1268,41 @@ int HAMLIB_API rig_open(RIG *rig) case RIG_DCD_SERIAL_DSR: case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_CAR: - if (rs->dcdport.pathname[0] == '\0' - && rs->rigport.type.rig == RIG_PORT_SERIAL) + if (dcdp->pathname[0] == '\0' + && rp->type.rig == RIG_PORT_SERIAL) { - strcpy(rs->dcdport.pathname, rs->rigport.pathname); + strcpy(dcdp->pathname, rp->pathname); } - if (strcmp(rs->dcdport.pathname, rs->rigport.pathname) == 0) + if (strcmp(dcdp->pathname, rp->pathname) == 0) { - rs->dcdport.fd = rs->rigport.fd; + dcdp->fd = rp->fd; } else { - rs->dcdport.fd = ser_open(&rs->dcdport); + dcdp->fd = ser_open(dcdp); } - if (rs->dcdport.fd < 0) + if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"%s\"\n", __func__, - rs->dcdport.pathname); + dcdp->pathname); status = -RIG_EIO; } break; case RIG_DCD_PARALLEL: - rs->dcdport.fd = par_open(&rs->dcdport); + dcdp->fd = par_open(dcdp); - if (rs->dcdport.fd < 0) + if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"%s\"\n", __func__, - rs->dcdport.pathname); + dcdp->pathname); status = -RIG_EIO; } @@ -1298,15 +1310,15 @@ int HAMLIB_API rig_open(RIG *rig) case RIG_DCD_GPIO: case RIG_DCD_GPION: - rs->dcdport.fd = gpio_open(&rs->dcdport, 0, - RIG_DCD_GPION == rs->dcdport.type.dcd ? 0 : 1); + dcdp->fd = gpio_open(dcdp, 0, + RIG_DCD_GPION == dcdp->type.dcd ? 0 : 1); - if (rs->dcdport.fd < 0) + if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"GPIO%s\"\n", __func__, - rs->dcdport.pathname); + dcdp->pathname); status = -RIG_EIO; } @@ -1316,29 +1328,31 @@ int HAMLIB_API rig_open(RIG *rig) rig_debug(RIG_DEBUG_ERR, "%s: unsupported DCD type %d\n", __func__, - rs->dcdport.type.dcd); + dcdp->type.dcd); status = -RIG_ECONF; } if (status < 0) { - port_close(&rs->rigport, rs->rigport.type.rig); + port_close(rp, rp->type.rig); rig->state.comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); } #if defined(HAVE_PTHREAD) + if (!skip_init) { - status = async_data_handler_start(rig); + status = async_data_handler_start(rig); - if (status < 0) - { - port_close(&rs->rigport, rs->rigport.type.rig); - rig->state.comm_status = RIG_COMM_STATUS_ERROR; - RETURNFUNC2(status); - } + if (status < 0) + { + port_close(rp, rp->type.rig); + rig->state.comm_status = RIG_COMM_STATUS_ERROR; + RETURNFUNC2(status); + } } + #endif rs->comm_state = 1; @@ -1353,8 +1367,8 @@ int HAMLIB_API rig_open(RIG *rig) * Maybe the backend has something to initialize * In case of failure, just close down and report error code. */ - short retry_save = rs->rigport.retry; - rs->rigport.retry = 0; + int retry_save = rp->retry; + rp->retry = 0; if (caps->rig_open != NULL) { @@ -1392,14 +1406,16 @@ int HAMLIB_API rig_open(RIG *rig) { remove_opened_rig(rig); #if defined(HAVE_PTHREAD) + if (!skip_init) - { - async_data_handler_stop(rig); - morse_data_handler_stop(rig); + { + async_data_handler_stop(rig); + morse_data_handler_stop(rig); } + #endif - port_close(&rs->rigport, rs->rigport.type.rig); - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); + port_close(rp, rp->type.rig); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); rs->comm_state = 0; rig->state.comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); @@ -1438,7 +1454,8 @@ int HAMLIB_API rig_open(RIG *rig) rig_strvfo(rs->current_vfo)); } } - if (skip_init) return RIG_OK; + + if (skip_init) { return RIG_OK; } #if defined(HAVE_PTHREAD) status = morse_data_handler_start(rig); @@ -1447,7 +1464,7 @@ int HAMLIB_API rig_open(RIG *rig) { rig_debug(RIG_DEBUG_ERR, "%s: cw_data_handler_start failed: %s\n", __func__, rigerror(status)); - port_close(&rs->rigport, rs->rigport.type.rig); + port_close(rp, rp->type.rig); RETURNFUNC2(status); } @@ -1468,13 +1485,21 @@ int HAMLIB_API rig_open(RIG *rig) if (rig->caps->get_freq) { - retval = rig_get_freq(rig, RIG_VFO_A, &freq); + vfo_t myvfo = RIG_VFO_A; + + if (rig->caps->rig_model == RIG_MODEL_IC9700) { myvfo = RIG_VFO_MAIN_A; } + + retval = rig_get_freq(rig, myvfo, &freq); if (retval == RIG_OK && rig->caps->rig_model != RIG_MODEL_F6K) { split_t split = RIG_SPLIT_OFF; vfo_t tx_vfo = RIG_VFO_NONE; - rig_get_freq(rig, RIG_VFO_B, &freq); + myvfo = RIG_VFO_B; + + if (rig->caps->rig_model == RIG_MODEL_IC9700) { myvfo = RIG_VFO_MAIN_B; } + + rig_get_freq(rig, myvfo, &freq); rig_get_split_vfo(rig, RIG_VFO_RX, &split, &tx_vfo); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Current split=%d, tx_vfo=%s\n", __func__, __LINE__, split, rig_strvfo(tx_vfo)); @@ -1483,24 +1508,32 @@ int HAMLIB_API rig_open(RIG *rig) if (rig->caps->get_mode) { - rig_get_mode(rig, RIG_VFO_A, &mode, &width); + myvfo = RIG_VFO_A; + + if (rig->caps->rig_model == RIG_MODEL_IC9700) { myvfo = RIG_VFO_MAIN_A; } + + rig_get_mode(rig, myvfo, &mode, &width); if (split) { + myvfo = RIG_VFO_B; + + if (rig->caps->rig_model == RIG_MODEL_IC9700) { myvfo = RIG_VFO_MAIN_A; } + rig_debug(RIG_DEBUG_VERBOSE, "xxxsplit=%d\n", split); HAMLIB_TRACE; - rig_get_mode(rig, RIG_VFO_B, &mode, &width); + rig_get_mode(rig, myvfo, &mode, &width); } } } } - rs->rigport.retry = retry_save; + rp->retry = retry_save; - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); - memcpy(&rs->pttport_deprecated, &rs->pttport, sizeof(hamlib_port_t_deprecated)); - memcpy(&rs->dcdport_deprecated, &rs->dcdport, sizeof(hamlib_port_t_deprecated)); - rig_flush_force(&rs->rigport, 1); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); + memcpy(&rs->pttport_deprecated, pttp, sizeof(hamlib_port_t_deprecated)); + memcpy(&rs->dcdport_deprecated, dcdp, sizeof(hamlib_port_t_deprecated)); + rig_flush_force(rp, 1); #if defined(HAVE_PTHREAD) enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE @@ -1562,6 +1595,9 @@ int HAMLIB_API rig_open(RIG *rig) int HAMLIB_API rig_close(RIG *rig) { const struct rig_caps *caps; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); + hamlib_port_t *dcdp = DCDPORT(rig); struct rig_state *rs; if (!rig || !rig->caps) @@ -1586,14 +1622,16 @@ int HAMLIB_API rig_close(RIG *rig) rig->state.comm_status = RIG_COMM_STATUS_DISCONNECTED; #if defined(HAVE_PTHREAD) + if (!skip_init) { - morse_data_handler_stop(rig); - async_data_handler_stop(rig); - rig_poll_routine_stop(rig); - network_multicast_receiver_stop(rig); - network_multicast_publisher_stop(rig); + morse_data_handler_stop(rig); + async_data_handler_stop(rig); + rig_poll_routine_stop(rig); + network_multicast_receiver_stop(rig); + network_multicast_publisher_stop(rig); } + #endif /* @@ -1610,7 +1648,7 @@ int HAMLIB_API rig_close(RIG *rig) * FIXME: what happens if PTT and rig ports are the same? * (eg. ptt_type = RIG_PTT_SERIAL) */ - switch (rs->pttport.type.ptt) + switch (pttp->type.ptt) { case RIG_PTT_NONE: case RIG_PTT_RIG: @@ -1620,14 +1658,14 @@ int HAMLIB_API rig_close(RIG *rig) case RIG_PTT_SERIAL_RTS: // If port is already closed, do nothing - if (rs->pttport.fd > -1) + if (pttp->fd > -1) { - ser_set_rts(&rs->pttport, 0); + ser_set_rts(pttp, 0); - if (rs->pttport.fd != rs->rigport.fd) + if (pttp->fd != rp->fd) { - port_close(&rs->pttport, RIG_PORT_SERIAL); - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); + port_close(pttp, RIG_PORT_SERIAL); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } } @@ -1636,43 +1674,43 @@ int HAMLIB_API rig_close(RIG *rig) case RIG_PTT_SERIAL_DTR: // If port is already closed, do nothing - if (rs->pttport.fd > -1) + if (pttp->fd > -1) { - ser_set_dtr(&rs->pttport, 0); + ser_set_dtr(pttp, 0); - if (rs->pttport.fd != rs->rigport.fd) + if (pttp->fd != rp->fd) { - port_close(&rs->pttport, RIG_PORT_SERIAL); - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); + port_close(pttp, RIG_PORT_SERIAL); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } } break; case RIG_PTT_PARALLEL: - par_ptt_set(&rs->pttport, RIG_PTT_OFF); - par_close(&rs->pttport); + par_ptt_set(pttp, RIG_PTT_OFF); + par_close(pttp); break; case RIG_PTT_CM108: - cm108_ptt_set(&rs->pttport, RIG_PTT_OFF); - cm108_close(&rs->pttport); + cm108_ptt_set(pttp, RIG_PTT_OFF); + cm108_close(pttp); break; case RIG_PTT_GPIO: case RIG_PTT_GPION: - gpio_ptt_set(&rs->pttport, RIG_PTT_OFF); - gpio_close(&rs->pttport); + gpio_ptt_set(pttp, RIG_PTT_OFF); + gpio_close(pttp); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, - rs->pttport.type.ptt); + pttp->type.ptt); } - switch (rs->dcdport.type.dcd) + switch (dcdp->type.dcd) { case RIG_DCD_NONE: case RIG_DCD_RIG: @@ -1681,33 +1719,33 @@ int HAMLIB_API rig_close(RIG *rig) case RIG_DCD_SERIAL_DSR: case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_CAR: - if (rs->dcdport.fd != rs->rigport.fd) + if (dcdp->fd != rp->fd) { - port_close(&rs->dcdport, RIG_PORT_SERIAL); - memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); + port_close(dcdp, RIG_PORT_SERIAL); + memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } break; case RIG_DCD_PARALLEL: - par_close(&rs->dcdport); + par_close(dcdp); break; case RIG_DCD_GPIO: case RIG_DCD_GPION: - gpio_close(&rs->dcdport); + gpio_close(dcdp); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported DCD type %d\n", __func__, - rs->dcdport.type.dcd); + dcdp->type.dcd); } - rs->dcdport.fd = rs->pttport.fd = -1; + dcdp->fd = pttp->fd = -1; - port_close(&rs->rigport, rs->rigport.type.rig); + port_close(rp, rp->type.rig); // zero split so it will allow it to be set again on open for rigctld rig->state.cache.split = 0; @@ -1756,6 +1794,8 @@ int HAMLIB_API rig_cleanup(RIG *rig) rig->caps->rig_cleanup(rig); } + //TODO Release and null any allocated port structures + free(rig); return (RIG_OK); @@ -1891,6 +1931,8 @@ static int twiddling(RIG *rig) RETURNFUNC2(0); } +#include "band_changed.c" + /** * \brief set the frequency of the target VFO * \param rig The rig handle @@ -1917,6 +1959,8 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) int retcode; freq_t freq_new = freq; vfo_t vfo_save; + static int last_band = -1; + int curr_band; if (CHECK_RIG_ARG(rig)) { @@ -1924,9 +1968,21 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) return -RIG_EINVAL; } + curr_band = rig_get_band(rig, freq, -1); + + if (rig->state.tx_vfo == vfo && curr_band != last_band) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: band changing to %s\n", __func__, + rig_get_band_str(rig, curr_band, 0)); + rig_band_changed(rig, curr_band); + last_band = curr_band; + } + ELAPSED1; ENTERFUNC; LOCK(1); + + #if BUILTINFUNC rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, freq=%.0f, called from %s\n", __func__, @@ -1941,7 +1997,8 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_A)) { - if (rig->state.cache.freqMainA != freq && (((int)freq % 10) != 0)) + if (rig->state.cache.freqMainA != freq && (((int)freq % 10) != 0) + && (((int)freq % 100) != 55)) { rig->state.doppler = 1; rig_debug(RIG_DEBUG_VERBOSE, @@ -1954,7 +2011,8 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && rig->state.current_vfo == RIG_VFO_B)) { - if (rig->state.cache.freqMainB != freq && ((int)freq % 10) != 0) + if (rig->state.cache.freqMainB != freq && ((int)freq % 10) != 0 + && (((int)freq % 100) != 55)) { rig->state.doppler = 1; rig_debug(RIG_DEBUG_VERBOSE, @@ -2237,6 +2295,8 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) vfo_t curr_vfo; rmode_t mode; pbwidth_t width; + int curr_band; + static int last_band = -1; if (CHECK_RIG_ARG(rig)) { @@ -2498,6 +2558,21 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) rig_cache_show(rig, __func__, __LINE__); } + // we only want to look for band change on main vfo for now + if (*freq != 0 && (rig->state.current_vfo == RIG_VFO_A + || rig->state.current_vfo == RIG_VFO_MAIN)) + { + curr_band = rig_get_band(rig, *freq, -1); + + if (rig->state.tx_vfo == vfo && curr_band != last_band) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: band changing to %s\n", __func__, + rig_get_band_str(rig, curr_band, 0)); + rig_band_changed(rig, curr_band); + last_band = curr_band; + } + } + ELAPSED2; LOCK(0); RETURNFUNC(retcode); @@ -2910,8 +2985,7 @@ pbwidth_t HAMLIB_API rig_passband_normal(RIG *rig, rmode_t mode) { if (rs->filters[i].modes & mode) { - rig_debug(RIG_DEBUG_VERBOSE, "%.*s%d:%s: return filter#%d, width=%d\n", - rig->state.depth, spaces(), rig->state.depth, __func__, i, + rig_debug(RIG_DEBUG_VERBOSE, "%s: return filter#%d, width=%d\n", __func__, i, (int)rs->filters[i].width); RETURNFUNC(rs->filters[i].width); } @@ -3075,7 +3149,7 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo) if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { - rig_debug(RIG_DEBUG_VERBOSE, "%s ********************** called vfo=%s\n", + rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); } @@ -3277,6 +3351,8 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const struct rig_caps *caps; struct rig_state *rs = &rig->state; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); int retcode = RIG_OK; if (CHECK_RIG_ARG(rig)) @@ -3292,7 +3368,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) LOCK(1); - switch (rig->state.pttport.type.ptt) + switch (pttp->type.ptt) { case RIG_PTT_RIG: if (ptt == RIG_PTT_ON_MIC || ptt == RIG_PTT_ON_DATA) @@ -3440,19 +3516,19 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0 + if (strcmp(pttp->pathname, rp->pathname) + && pttp->fd < 0 && RIG_PTT_OFF != ptt) { - rs->pttport.fd = ser_open(&rs->pttport); + pttp->fd = ser_open(pttp); - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); ELAPSED2; RETURNFUNC(-RIG_EIO); } @@ -3460,7 +3536,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both since we offer no control of the non-PTT line and low is better than high */ - retcode = ser_set_rts(&rs->pttport, 0); + retcode = ser_set_rts(pttp, 0); if (RIG_OK != retcode) { @@ -3469,16 +3545,16 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) } } - retcode = ser_set_dtr(&rig->state.pttport, ptt != RIG_PTT_OFF); + retcode = ser_set_dtr(pttp, ptt != RIG_PTT_OFF); rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%s, pttport=%s, ptt_share=%d\n", - __func__, rs->pttport.pathname, rs->rigport.pathname, rs->ptt_share); + __func__, rp->pathname, pttp->pathname, rs->ptt_share); - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) + if (strcmp(pttp->pathname, rp->pathname) && ptt == RIG_PTT_OFF && rs->ptt_share != 0) { /* free the port */ - ser_close(&rs->pttport); + ser_close(pttp); } break; @@ -3489,20 +3565,20 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0 + if (strcmp(pttp->pathname, rp->pathname) + && pttp->fd < 0 && RIG_PTT_OFF != ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: PTT RTS debug#1\n", __func__); - rs->pttport.fd = ser_open(&rs->pttport); + pttp->fd = ser_open(pttp); - if (rs->pttport.fd < 0) + if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, - rs->pttport.pathname); + pttp->pathname); ELAPSED2; RETURNFUNC(-RIG_EIO); } @@ -3510,7 +3586,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both since we offer no control of the non-PTT line and low is better than high */ - retcode = ser_set_dtr(&rs->pttport, 0); + retcode = ser_set_dtr(pttp, 0); if (RIG_OK != retcode) { @@ -3520,31 +3596,31 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) } } - retcode = ser_set_rts(&rig->state.pttport, ptt != RIG_PTT_OFF); + retcode = ser_set_rts(pttp, ptt != RIG_PTT_OFF); rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%s, pttport=%s, ptt_share=%d\n", - __func__, rs->pttport.pathname, rs->rigport.pathname, rs->ptt_share); + __func__, rp->pathname, pttp->pathname, rs->ptt_share); - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) + if (strcmp(pttp->pathname, rp->pathname) && ptt == RIG_PTT_OFF && rs->ptt_share != 0) { /* free the port */ - ser_close(&rs->pttport); + ser_close(pttp); } break; case RIG_PTT_PARALLEL: - retcode = par_ptt_set(&rig->state.pttport, ptt); + retcode = par_ptt_set(pttp, ptt); break; case RIG_PTT_CM108: - retcode = cm108_ptt_set(&rig->state.pttport, ptt); + retcode = cm108_ptt_set(pttp, ptt); break; case RIG_PTT_GPIO: case RIG_PTT_GPION: - retcode = gpio_ptt_set(&rig->state.pttport, ptt); + retcode = gpio_ptt_set(pttp, ptt); break; case RIG_PTT_NONE: @@ -3553,7 +3629,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) default: rig_debug(RIG_DEBUG_WARN, "%s: unknown PTT type=%d\n", __func__, - rig->state.pttport.type.ptt); + pttp->type.ptt); ELAPSED2; RETURNFUNC(-RIG_EINVAL); } @@ -3573,7 +3649,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: return code=%d\n", __func__, retcode); } - memcpy(&rig->state.pttport_deprecated, &rig->state.pttport, + memcpy(&rig->state.pttport_deprecated, pttp, sizeof(rig->state.pttport_deprecated)); if (rig->state.post_ptt_delay > 0) { hl_usleep(rig->state.post_ptt_delay * 1000); } @@ -3602,6 +3678,8 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct rig_caps *caps; struct rig_state *rs = &rig->state; + hamlib_port_t *rp = RIGPORT(rig); + hamlib_port_t *pttp = PTTPORT(rig); int retcode = RIG_OK; int status; vfo_t curr_vfo; @@ -3643,7 +3721,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) LOCK(1); - switch (rig->state.pttport.type.ptt) + switch (pttp->type.ptt) { case RIG_PTT_RIG: case RIG_PTT_RIG_MICDATA: @@ -3747,15 +3825,15 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) #endif - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0) + if (strcmp(pttp->pathname, rp->pathname) + && pttp->fd < 0) { /* port is closed so assume PTT off */ *ptt = RIG_PTT_OFF; } else { - retcode = ser_get_rts(&rig->state.pttport, &status); + retcode = ser_get_rts(pttp, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } @@ -3785,15 +3863,15 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) #endif - if (strcmp(rs->pttport.pathname, rs->rigport.pathname) - && rs->pttport.fd < 0) + if (strcmp(pttp->pathname, rp->pathname) + && pttp->fd < 0) { /* port is closed so assume PTT off */ *ptt = RIG_PTT_OFF; } else { - retcode = ser_get_dtr(&rig->state.pttport, &status); + retcode = ser_get_dtr(pttp, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } @@ -3820,7 +3898,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) RETURNFUNC(retcode); } - retcode = par_ptt_get(&rig->state.pttport, ptt); + retcode = par_ptt_get(pttp, ptt); if (retcode == RIG_OK) { @@ -3849,7 +3927,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) RETURNFUNC(retcode); } - retcode = cm108_ptt_get(&rig->state.pttport, ptt); + retcode = cm108_ptt_get(pttp, ptt); if (retcode == RIG_OK) { @@ -3880,7 +3958,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) } elapsed_ms(&rig->state.cache.time_ptt, HAMLIB_ELAPSED_SET); - retcode = gpio_ptt_get(&rig->state.pttport, ptt); + retcode = gpio_ptt_get(pttp, ptt); ELAPSED2; LOCK(0); RETURNFUNC(retcode); @@ -3919,6 +3997,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) int HAMLIB_API rig_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { const struct rig_caps *caps; + hamlib_port_t *dcdp = DCDPORT(rig); int retcode, rc2, status; vfo_t curr_vfo; @@ -3939,7 +4018,7 @@ int HAMLIB_API rig_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) caps = rig->caps; - switch (rig->state.dcdport.type.dcd) + switch (dcdp->type.dcd) { case RIG_DCD_RIG: if (caps->get_dcd == NULL) @@ -3990,24 +4069,24 @@ int HAMLIB_API rig_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) break; case RIG_DCD_SERIAL_CTS: - retcode = ser_get_cts(&rig->state.dcdport, &status); - memcpy(&rig->state.dcdport_deprecated, &rig->state.dcdport, + retcode = ser_get_cts(dcdp, &status); + memcpy(&rig->state.dcdport_deprecated, dcdp, sizeof(rig->state.dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_SERIAL_DSR: - retcode = ser_get_dsr(&rig->state.dcdport, &status); - memcpy(&rig->state.dcdport_deprecated, &rig->state.dcdport, + retcode = ser_get_dsr(dcdp, &status); + memcpy(&rig->state.dcdport_deprecated, dcdp, sizeof(rig->state.dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_SERIAL_CAR: - retcode = ser_get_car(&rig->state.dcdport, &status); - memcpy(&rig->state.dcdport_deprecated, &rig->state.dcdport, + retcode = ser_get_car(dcdp, &status); + memcpy(&rig->state.dcdport_deprecated, dcdp, sizeof(rig->state.dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; @@ -4015,16 +4094,16 @@ int HAMLIB_API rig_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) case RIG_DCD_PARALLEL: - retcode = par_dcd_get(&rig->state.dcdport, dcd); - memcpy(&rig->state.dcdport_deprecated, &rig->state.dcdport, + retcode = par_dcd_get(dcdp, dcd); + memcpy(&rig->state.dcdport_deprecated, dcdp, sizeof(rig->state.dcdport_deprecated)); ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_GPIO: case RIG_DCD_GPION: - retcode = gpio_dcd_get(&rig->state.dcdport, dcd); - memcpy(&rig->state.dcdport_deprecated, &rig->state.dcdport, + retcode = gpio_dcd_get(dcdp, dcd); + memcpy(&rig->state.dcdport_deprecated, dcdp, sizeof(rig->state.dcdport_deprecated)); ELAPSED2; RETURNFUNC(retcode); @@ -6505,7 +6584,7 @@ int HAMLIB_API rig_set_powerstat(RIG *rig, powerstat_t status) } // if anything is queued up flush it - rig_flush_force(&rig->state.rigport, 1); + rig_flush_force(RIGPORT(rig), 1); ELAPSED2; RETURNFUNC(retcode); } @@ -8247,7 +8326,7 @@ void *async_data_handler(void *arg) if (rs->transaction_active) { unsigned char data = (unsigned char) result; - write_block_sync_error(&rs->rigport, &data, 1); + write_block_sync_error(RIGPORT(rig), &data, 1); } // TODO: error handling -> store errors in rig state -> to be exposed in async snapshot packets @@ -8281,7 +8360,7 @@ void *async_data_handler(void *arg) } else { - result = write_block_sync(&rs->rigport, frame, frame_length); + result = write_block_sync(RIGPORT(rig), frame, frame_length); if (result < 0) { @@ -8465,12 +8544,12 @@ extern int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, int send_len, unsigned char *reply, int reply_len, unsigned char *term) { - struct rig_state *rs = &rig->state; int nbytes; int retval; + hamlib_port_t *rp = RIGPORT(rig); int simulate = rig->caps->rig_model == RIG_MODEL_DUMMY || rig->caps->rig_model == RIG_MODEL_NONE || - rs->rigport.rig == RIG_PORT_NONE; + rp->rig == RIG_PORT_NONE; ENTERFUNC; ELAPSED1; @@ -8487,7 +8566,7 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, } else { - retval = write_block(&rs->rigport, send, send_len); + retval = write_block(rp, send, send_len); if (retval < 0) { @@ -8512,25 +8591,25 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, if (term == NULL) { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading binary frame\n", __func__); - retval = read_string(&rs->rigport, buf, reply_len, NULL, 0, 0, 1); + retval = read_string(rp, buf, reply_len, NULL, 0, 0, 1); } else if (*term == 0xfd) // then we want an Icom frame { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading icom frame\n", __func__); - retval = read_icom_frame(&rs->rigport, buf, sizeof(buf)); + retval = read_icom_frame(rp, buf, sizeof(buf)); } else // we'll assume the provided terminator works { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading frame terminated by 0x%x\n", __func__, *term); - retval = read_string(&rs->rigport, buf, sizeof(buf), (const char *)term, + retval = read_string(rp, buf, sizeof(buf), (const char *)term, 1, 0, 1); } if (retval < RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: read_string, result=%d\n", __func__, retval); - rig_flush_force(&rs->rigport, 1); + rig_flush_force(rp, 1); set_transaction_inactive(rig); RETURNFUNC(retval); } @@ -8541,7 +8620,7 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, { rig_debug(RIG_DEBUG_ERR, "%s: reply_len(%d) less than reply from rig(%d)\n", __func__, reply_len, nbytes); - rig_flush_force(&rs->rigport, 1); + rig_flush_force(rp, 1); set_transaction_inactive(rig); return -RIG_EINVAL; } @@ -8551,12 +8630,12 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, } else { - rig_flush_force(&rs->rigport, 1); + rig_flush_force(rp, 1); set_transaction_inactive(rig); RETURNFUNC(retval); } - rig_flush_force(&rs->rigport, 1); + rig_flush_force(rp, 1); set_transaction_inactive(rig); ELAPSED2; @@ -8621,3 +8700,36 @@ int morse_data_handler_set_keyspd(RIG *rig, int keyspd) return RIG_OK; } #endif + +/* + * \brief Get the address of a Hamlib data structure + * \param rig Pointer to main data anchor + * \param idx enum for which pointer requested + * + * Get the address of a structure without relying on changeable + * internal data organization. + * + * \retval The address of the enumed structure + * + * Note: This is meant for use by the HAMLIB_???PORT macros mostly. Only + * compatiblity with them is supported. + * + * \sa amp_data_pointer, rot_data_pointer + */ +HAMLIB_EXPORT(void *) rig_data_pointer(RIG *rig, rig_ptrx_t idx) +{ + switch(idx) + { + case RIG_PTRX_RIGPORT: + return RIGPORT(rig); + case RIG_PTRX_PTTPORT: + return PTTPORT(rig); + case RIG_PTRX_DCDPORT: + return DCDPORT(rig); + case RIG_PTRX_CACHE: + return CACHE(rig); + default: + rig_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); + return NULL; + } +} diff --git a/src/rotator.c b/src/rotator.c index 918fc5cb8..b1db5c478 100644 --- a/src/rotator.c +++ b/src/rotator.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup rotator @@ -219,6 +220,7 @@ ROT *HAMLIB_API rot_init(rot_model_t rot_model) ROT *rot; const struct rot_caps *caps; struct rot_state *rs; + hamlib_port_t *rotp, *rotp2; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -258,41 +260,46 @@ ROT *HAMLIB_API rot_init(rot_model_t rot_model) */ rs = &rot->state; + //TODO Allocate new rotport[2] + // For now, use the embedded ones + rotp = ROTPORT(rot); + rotp2 = ROTPORT2(rot); + rs->comm_state = 0; - rs->rotport.type.rig = caps->port_type; /* default from caps */ + rotp->type.rig = caps->port_type; /* default from caps */ - rs->rotport.write_delay = caps->write_delay; - rs->rotport.post_write_delay = caps->post_write_delay; - rs->rotport.timeout = caps->timeout; - rs->rotport.retry = caps->retry; + rotp->write_delay = caps->write_delay; + rotp->post_write_delay = caps->post_write_delay; + rotp->timeout = caps->timeout; + rotp->retry = caps->retry; switch (caps->port_type) { case RIG_PORT_SERIAL: - strncpy(rs->rotport.pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); - rs->rotport.parm.serial.rate = rs->rotport2.parm.serial.rate = + strncpy(rotp->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); + rotp->parm.serial.rate = rotp2->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ - rs->rotport.parm.serial.data_bits = rs->rotport2.parm.serial.data_bits = + rotp->parm.serial.data_bits = rotp2->parm.serial.data_bits = caps->serial_data_bits; - rs->rotport.parm.serial.stop_bits = rs->rotport2.parm.serial.stop_bits = + rotp->parm.serial.stop_bits = rotp2->parm.serial.stop_bits = caps->serial_stop_bits; - rs->rotport.parm.serial.parity = rs->rotport2.parm.serial.parity = + rotp->parm.serial.parity = rotp2->parm.serial.parity = caps->serial_parity; - rs->rotport.parm.serial.handshake = rs->rotport2.parm.serial.handshake = + rotp->parm.serial.handshake = rotp2->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_PARALLEL: - strncpy(rs->rotport.pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); + strncpy(rotp->pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: - strncpy(rs->rotport.pathname, "127.0.0.1:4533", HAMLIB_FILPATHLEN - 1); + strncpy(rotp->pathname, "127.0.0.1:4533", HAMLIB_FILPATHLEN - 1); break; default: - strncpy(rs->rotport.pathname, "", HAMLIB_FILPATHLEN - 1); + strncpy(rotp->pathname, "", HAMLIB_FILPATHLEN - 1); } rs->min_el = caps->min_el; @@ -301,7 +308,7 @@ ROT *HAMLIB_API rot_init(rot_model_t rot_model) rs->max_az = caps->max_az; rs->current_speed = 50; // Set default speed to 50% - rs->rotport.fd = -1; + rotp->fd = -1; rs->has_get_func = caps->has_get_func; rs->has_set_func = caps->has_set_func; @@ -338,7 +345,7 @@ ROT *HAMLIB_API rot_init(rot_model_t rot_model) // Now we have to copy our new rig state hamlib_port structure to the deprecated one // Clients built on older 4.X versions will use the old structure // Clients built on newer 4.5 versions will use the new structure - memcpy(&rot->state.rotport_deprecated, &rot->state.rotport, + memcpy(&rot->state.rotport_deprecated, rotp, sizeof(rot->state.rotport_deprecated)); return rot; @@ -366,6 +373,8 @@ int HAMLIB_API rot_open(ROT *rot) { const struct rot_caps *caps; struct rot_state *rs; + hamlib_port_t *rotp = ROTPORT(rot); + hamlib_port_t *rotp2 = ROTPORT2(rot); int status; int net1, net2, net3, net4, port; @@ -384,30 +393,30 @@ int HAMLIB_API rot_open(ROT *rot) return -RIG_EINVAL; } - rs->rotport.fd = -1; - rs->rotport2.fd = -1; + rotp->fd = -1; + rotp2->fd = -1; // determine if we have a network address - if (sscanf(rs->rotport.pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, + if (sscanf(rotp->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, - rs->rotport.pathname); - rs->rotport.type.rig = RIG_PORT_NETWORK; + rotp->pathname); + rotp->type.rig = RIG_PORT_NETWORK; } - if (sscanf(rs->rotport2.pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, + if (sscanf(rotp2->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, - rs->rotport2.pathname); - rs->rotport2.type.rig = RIG_PORT_NETWORK; + rotp2->pathname); + rotp2->type.rig = RIG_PORT_NETWORK; } - switch (rs->rotport.type.rig) + switch (rotp->type.rig) { case RIG_PORT_SERIAL: - status = serial_open(&rs->rotport); + status = serial_open(rotp); if (status != 0) { @@ -416,9 +425,9 @@ int HAMLIB_API rot_open(ROT *rot) // RT21 has 2nd serial port elevation // so if a 2nd pathname is provided we'll open it - if (rot->caps->rot_model == ROT_MODEL_RT21 && rs->rotport2.pathname[0] != 0) + if (rot->caps->rot_model == ROT_MODEL_RT21 && rotp2->pathname[0] != 0) { - status = serial_open(&rs->rotport2); + status = serial_open(rotp2); if (status != 0) { @@ -429,7 +438,7 @@ int HAMLIB_API rot_open(ROT *rot) break; case RIG_PORT_PARALLEL: - status = par_open(&rs->rotport); + status = par_open(rotp); if (status < 0) { @@ -439,27 +448,27 @@ int HAMLIB_API rot_open(ROT *rot) break; case RIG_PORT_DEVICE: - status = open(rs->rotport.pathname, O_RDWR, 0); + status = open(rotp->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } - rs->rotport.fd = status; + rotp->fd = status; // RT21 has 2nd serial port elevation // so if a 2nd pathname is provided we'll open it - if (rot->caps->rot_model == ROT_MODEL_RT21 && rs->rotport2.pathname[0] != 0) + if (rot->caps->rot_model == ROT_MODEL_RT21 && rotp2->pathname[0] != 0) { - status = open(rs->rotport2.pathname, O_RDWR, 0); + status = open(rotp2->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } - rs->rotport2.fd = status; + rotp2->fd = status; } break; @@ -467,7 +476,7 @@ int HAMLIB_API rot_open(ROT *rot) #if defined(HAVE_LIB_USB_H) || defined(HAMB_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: - status = usb_port_open(&rs->rotport); + status = usb_port_open(rotp); if (status < 0) { @@ -484,7 +493,7 @@ int HAMLIB_API rot_open(ROT *rot) case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: /* FIXME: default port */ - status = network_open(&rs->rotport, 4533); + status = network_open(rotp, 4533); if (status < 0) { @@ -511,31 +520,31 @@ int HAMLIB_API rot_open(ROT *rot) if (status != RIG_OK) { - memcpy(&rot->state.rotport_deprecated, &rot->state.rotport, + memcpy(&rot->state.rotport_deprecated, rotp, sizeof(rot->state.rotport_deprecated)); return status; } } - if (rs->rotport.parm.serial.dtr_state == RIG_SIGNAL_ON) + if (rotp->parm.serial.dtr_state == RIG_SIGNAL_ON) { - ser_set_dtr(&rs->rotport, 1); + ser_set_dtr(rotp, 1); } else { - ser_set_dtr(&rs->rotport, 0); + ser_set_dtr(rotp, 0); } - if (rs->rotport.parm.serial.rts_state == RIG_SIGNAL_ON) + if (rotp->parm.serial.rts_state == RIG_SIGNAL_ON) { - ser_set_rts(&rs->rotport, 1); + ser_set_rts(rotp, 1); } else { - ser_set_rts(&rs->rotport, 0); + ser_set_rts(rotp, 0); } - memcpy(&rot->state.rotport_deprecated, &rot->state.rotport, + memcpy(&rot->state.rotport_deprecated, rotp, sizeof(rot->state.rotport_deprecated)); return RIG_OK; @@ -561,6 +570,7 @@ int HAMLIB_API rot_close(ROT *rot) { const struct rot_caps *caps; struct rot_state *rs; + hamlib_port_t *rotp = ROTPORT(rot); rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); @@ -587,42 +597,42 @@ int HAMLIB_API rot_close(ROT *rot) } - if (rs->rotport.fd != -1) + if (rotp->fd != -1) { - switch (rs->rotport.type.rig) + switch (rotp->type.rig) { case RIG_PORT_SERIAL: - ser_close(&rs->rotport); + ser_close(rotp); break; case RIG_PORT_PARALLEL: - par_close(&rs->rotport); + par_close(rotp); break; #if defined(HAVE_LIB_USB_H) || defined(HAMB_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: - usb_port_close(&rs->rotport); + usb_port_close(rotp); break; #endif case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: - network_close(&rs->rotport); + network_close(rotp); break; default: - close(rs->rotport.fd); + close(rotp->fd); } - rs->rotport.fd = -1; + rotp->fd = -1; } remove_opened_rot(rot); rs->comm_state = 0; - memcpy(&rot->state.rotport_deprecated, &rot->state.rotport, + memcpy(&rot->state.rotport_deprecated, rotp, sizeof(rot->state.rotport_deprecated)); return RIG_OK; @@ -670,6 +680,8 @@ int HAMLIB_API rot_cleanup(ROT *rot) rot->caps->rot_cleanup(rot); } + //TODO Release any allocated port structures + free(rot); return RIG_OK; @@ -1031,4 +1043,23 @@ int HAMLIB_API rot_get_status(ROT *rot, rot_status_t *status) return rot->caps->get_status(rot, status); } +/** + * \brief Get the address of rotator data structure(s) + * + * \sa rig_data_pointer + * + */ +void * HAMLIB_API rot_data_pointer(ROT *rot, rig_ptrx_t idx) +{ + switch(idx) + { + case RIG_PTRX_ROTPORT: + return ROTPORT(rot); + case RIG_PTRX_ROTPORT2: + return ROTPORT2(rot); + default: + rot_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); + return NULL; + } +} /*! @} */ diff --git a/src/serial.c b/src/serial.c index 447397220..302e67b0c 100644 --- a/src/serial.c +++ b/src/serial.c @@ -522,6 +522,7 @@ int HAMLIB_API serial_setup(hamlib_port_t *rp) * Set stop bits to requested values. * */ + rig_debug(RIG_DEBUG_TRACE, "%s: stopbits=%d\n", __func__, rp->parm.serial.stop_bits); switch (rp->parm.serial.stop_bits) { case 1: @@ -1050,7 +1051,7 @@ int HAMLIB_API ser_set_rts(hamlib_port_t *p, int state) /** * \brief Get RTS bit - * \param p supposed to be &rig->state.rigport + * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_rts(hamlib_port_t *p, int *state) @@ -1133,7 +1134,7 @@ int HAMLIB_API ser_set_dtr(hamlib_port_t *p, int state) /** * \brief Get DTR bit - * \param p supposed to be &rig->state.rigport + * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_dtr(hamlib_port_t *p, int *state) @@ -1185,7 +1186,7 @@ int HAMLIB_API ser_set_brk(const hamlib_port_t *p, int state) /** * \brief Get Carrier (CI?) bit - * \param p supposed to be &rig->state.rigport + * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_car(hamlib_port_t *p, int *state) @@ -1208,7 +1209,7 @@ int HAMLIB_API ser_get_car(hamlib_port_t *p, int *state) /** * \brief Get Clear to Send (CTS) bit - * \param p supposed to be &rig->state.rigport + * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_cts(hamlib_port_t *p, int *state) @@ -1231,7 +1232,7 @@ int HAMLIB_API ser_get_cts(hamlib_port_t *p, int *state) /** * \brief Get Data Set Ready (DSR) bit - * \param p supposed to be &rig->state.rigport + * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_dsr(hamlib_port_t *p, int *state) diff --git a/src/snapshot_data.c b/src/snapshot_data.c index 52f9a1333..7ddd53de2 100644 --- a/src/snapshot_data.c +++ b/src/snapshot_data.c @@ -22,7 +22,7 @@ static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig) cJSON *id_node = cJSON_CreateObject(); cJSON_AddStringToObject(id_node, "model", rig->caps->model_name); - cJSON_AddStringToObject(id_node, "endpoint", rig->state.rigport.pathname); + cJSON_AddStringToObject(id_node, "endpoint", RIGPORT(rig)->pathname); cJSON_AddStringToObject(id_node, "process", snapshot_data_pid); cJSON_AddStringToObject(id_node, "deviceId", rig->state.device_id); cJSON_AddItemToObject(rig_node, "id", id_node); diff --git a/tests/example.c b/tests/example.c index c784c3698..a9274d3c0 100644 --- a/tests/example.c +++ b/tests/example.c @@ -43,9 +43,9 @@ int main() /* Instantiate a rig */ my_rig = rig_init(MODEL); // your rig model. - strncpy(my_rig->state.rigport.pathname, PATH, HAMLIB_FILPATHLEN - 1); + rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), PATH); - my_rig->state.rigport.parm.serial.rate = BAUD; // your baud rate + HAMLIB_RIGPORT(my_rig)->parm.serial.rate = BAUD; // your baud rate /* Open my rig */ retcode = rig_open(my_rig); @@ -131,7 +131,7 @@ int main() if (range) { char vfolist[256]; - rig_sprintf_vfo(vfolist, sizeof(vfo_list), my_rig->state.vfo_list); + rig_sprintf_vfo(vfolist, sizeof(vfolist), my_rig->state.vfo_list); printf("Range start=%"PRIfreq", end=%"PRIfreq", low_power=%d, high_power=%d, vfos=%s\n", range->startf, range->endf, range->low_power, range->high_power, vfolist); } diff --git a/tests/rigctl.c b/tests/rigctl.c index f898c75cd..062baa746 100644 --- a/tests/rigctl.c +++ b/tests/rigctl.c @@ -939,6 +939,7 @@ void usage(void) " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" " -!, --cookie use cookie control\n\n" + " -#, --skipinit skips rig initialization\n" ); usage_rig(stdout);