kopia lustrzana https://github.com/Hamlib/Hamlib
Merge master and fix conflicts
commit
89abbfeb3a
|
@ -2380,6 +2380,7 @@ typedef struct hamlib_port {
|
|||
int fd_sync_error_read; /*!< file descriptor for reading synchronous data error codes */
|
||||
#endif
|
||||
short timeout_retry; /*!< number of retries to make in case of read timeout errors, some serial interfaces may require this, 0 to disable */
|
||||
int post_ptt_delay; /*!< delay after PTT to allow for relays and such */
|
||||
} hamlib_port_t;
|
||||
|
||||
|
||||
|
@ -2550,6 +2551,7 @@ struct rig_cache {
|
|||
struct timespec time_ptt;
|
||||
struct timespec time_split;
|
||||
int satmode; // if rig is in satellite mode
|
||||
double swr; // keep swr
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2576,6 +2578,15 @@ struct multicast_s
|
|||
//#endif
|
||||
};
|
||||
|
||||
typedef unsigned int rig_comm_status_t;
|
||||
|
||||
#define RIG_COMM_STATUS_OK 0x00
|
||||
#define RIG_COMM_STATUS_CONNECTING 0x01
|
||||
#define RIG_COMM_STATUS_DISCONNECTED 0x02
|
||||
#define RIG_COMM_STATUS_TERMINATED 0x03
|
||||
#define RIG_COMM_STATUS_WARNING 0x04
|
||||
#define RIG_COMM_STATUS_ERROR 0x05
|
||||
|
||||
/**
|
||||
* \brief Rig state containing live data and customized fields.
|
||||
*
|
||||
|
@ -2758,7 +2769,15 @@ struct rig_state {
|
|||
volatile int morse_data_handler_thread_run;
|
||||
void *morse_data_handler_priv_data;
|
||||
FIFO_RIG *fifo_morse;
|
||||
int port_multicast; /*!< May be different so this is initially a copy of rigctl'd port selection */
|
||||
int doppler; /*!< True if doppler changing detected */
|
||||
char *multicast_data_addr; /*!< Multicast data UDP address for publishing rig data and state */
|
||||
int multicast_data_port; /*!< Multicast data UDP port for publishing rig data and state */
|
||||
char *multicast_cmd_addr; /*!< Multicast command server UDP address for sending commands to rig */
|
||||
int multicast_cmd_port; /*!< Multicast command server UDP port for sending commands to rig */
|
||||
volatile int multicast_receiver_run;
|
||||
void *multicast_receiver_priv_data;
|
||||
rig_comm_status_t comm_status; /*!< Detailed rig control status */
|
||||
char device_id[HAMLIB_RIGNAMSIZ];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3703,6 +3722,7 @@ extern HAMLIB_EXPORT(const char *) rig_strscan(scan_t scan);
|
|||
extern HAMLIB_EXPORT(const char *) rig_strstatus(enum rig_status_e status);
|
||||
extern HAMLIB_EXPORT(const char *) rig_strmtype(chan_type_t mtype);
|
||||
extern HAMLIB_EXPORT(const char *) rig_strspectrummode(enum rig_spectrum_mode_e mode);
|
||||
extern HAMLIB_EXPORT(const char *) rig_strcommstatus(rig_comm_status_t vfo);
|
||||
|
||||
extern HAMLIB_EXPORT(rmode_t) rig_parse_mode(const char *s);
|
||||
extern HAMLIB_EXPORT(vfo_t) rig_parse_vfo(const char *s);
|
||||
|
|
|
@ -3619,7 +3619,7 @@ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
|
||||
for (i = 0; extcmds && extcmds[i].id.s != 0; i++)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i);
|
||||
//rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i);
|
||||
|
||||
if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level)
|
||||
{
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
#define POWERSDR_FUNC_ALL (RIG_FUNC_VOX|RIG_FUNC_SQL|RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MUTE|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER)
|
||||
|
||||
#define POWERSDR_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF|RIG_LEVEL_STRENGTH)
|
||||
#define POWERSDR_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR)
|
||||
#define POWERSDR_LEVEL_SET (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF)
|
||||
|
||||
|
||||
|
@ -837,6 +837,29 @@ int powersdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
ans = 3;
|
||||
break;
|
||||
|
||||
case RIG_LEVEL_SWR:
|
||||
{
|
||||
// if not PTT we'll return the last SWR value
|
||||
// seems desirable to able to see this always
|
||||
ptt_t ptt;
|
||||
rig_get_ptt(rig, RIG_VFO_TX, &ptt);
|
||||
if (!ptt) { val->f = rig->state.cache.swr; return RIG_OK; }
|
||||
double forward=0, reverse=0;
|
||||
cmd = "ZZRM5"; // get forward power
|
||||
len = 5;
|
||||
ans = 4;
|
||||
retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans);
|
||||
if (retval != RIG_OK) { val->f = 0; return RIG_OK;};
|
||||
sscanf(lvlbuf,"ZZRM5%lg", &forward);
|
||||
if (forward == 0) { val->f = 1.0; return RIG_OK;}
|
||||
cmd = "ZZRM7";
|
||||
retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans);
|
||||
if (retval != RIG_OK) { val->f = 0; return RIG_OK;};
|
||||
sscanf(lvlbuf,"ZZRM7%lg", &reverse);
|
||||
rig->state.cache.swr = val->f = (1.0 + sqrt(reverse/forward)) / (1.0 - sqrt(reverse/forward));
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
default:
|
||||
return kenwood_get_level(rig, vfo, level, val);
|
||||
}
|
||||
|
@ -921,14 +944,20 @@ int powersdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
|
||||
case RIG_LEVEL_RFPOWER_METER:
|
||||
case RIG_LEVEL_RFPOWER_METER_WATTS:
|
||||
n = sscanf(lvlbuf, "ZZRM5%f", &val->f);
|
||||
|
||||
if (n != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n",
|
||||
// if not ptt then no power is going out so return 0W
|
||||
ptt_t ptt;
|
||||
rig_get_ptt(rig, RIG_VFO_TX, &ptt);
|
||||
if (!ptt) { val->f = 0; return RIG_OK; }
|
||||
n = sscanf(lvlbuf, "ZZRM5%f", &val->f);
|
||||
|
||||
if (n != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n",
|
||||
__func__, lvlbuf);
|
||||
val->f = 0;
|
||||
return -RIG_EPROTO;
|
||||
val->f = 0;
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
}
|
||||
|
||||
if (level != RIG_LEVEL_RFPOWER_METER_WATTS)
|
||||
|
@ -1321,7 +1350,7 @@ const struct rig_caps powersdr_caps =
|
|||
RIG_MODEL(RIG_MODEL_POWERSDR),
|
||||
.model_name = "PowerSDR/Thetis",
|
||||
.mfg_name = "FlexRadio/ANAN",
|
||||
.version = "20230819.0",
|
||||
.version = "20231104.0",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_STABLE,
|
||||
.rig_type = RIG_TYPE_TRANSCEIVER,
|
||||
|
|
|
@ -1862,15 +1862,17 @@ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
}
|
||||
|
||||
// Malchite is so slow we don't do the get_freq
|
||||
if (!RIG_IS_MALACHITE)
|
||||
// And when we have detected Doppler operations we just set the freq all the time
|
||||
// This should provide stable timing for set_ptt operation so relay delays are consistent
|
||||
if (!RIG_IS_MALACHITE && rig->state.doppler == 0)
|
||||
{
|
||||
rig_get_freq(rig, tvfo, &tfreq);
|
||||
rig_get_freq(rig, tvfo, &tfreq);
|
||||
|
||||
if (tfreq == freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__);
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
if (tfreq == freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__);
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
}
|
||||
|
||||
switch (tvfo)
|
||||
|
@ -2861,7 +2863,7 @@ static int kenwood_get_micgain_minmax(RIG *rig, int *micgain_now,
|
|||
if (retval != RIG_OK) { RETURNFUNC(retval); }
|
||||
|
||||
retval = read_string(&rs->rigport, (unsigned char *) levelbuf, sizeof(levelbuf),
|
||||
NULL, ";", 1, 1);
|
||||
NULL, 0, 1, 1);
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "token.h"
|
||||
#include "idx_builtin.h"
|
||||
|
||||
#define BACKEND_VER "20231023"
|
||||
#define BACKEND_VER "20231031"
|
||||
|
||||
#define EOM_KEN ';'
|
||||
#define EOM_TH '\r'
|
||||
|
|
|
@ -461,14 +461,14 @@ 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 * 10;
|
||||
kenwood_val = val.f * 9;
|
||||
cmd = 65; // TS-590S
|
||||
if (rig->caps->rig_model == RIG_MODEL_TS590SG) cmd=72;
|
||||
SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val);
|
||||
break;
|
||||
|
||||
case RIG_LEVEL_USB_AF_INPUT:
|
||||
kenwood_val = val.f * 10;
|
||||
kenwood_val = val.f * 9;
|
||||
cmd = 64; // TS-590S
|
||||
if (rig->caps->rig_model == RIG_MODEL_TS590SG) cmd=71;
|
||||
SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val);
|
||||
|
@ -673,14 +673,14 @@ static int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
cmd = 65; // TS-590S
|
||||
if (rig->caps->rig_model == RIG_MODEL_TS590SG) cmd=72;
|
||||
retval = ts590_get_ex_menu(rig, cmd, 1, &levelint);
|
||||
val->f = levelint / 10.0;
|
||||
val->f = levelint / 9.0;
|
||||
return retval;
|
||||
|
||||
case RIG_LEVEL_USB_AF_INPUT:
|
||||
cmd = 65; // TS-590S
|
||||
if (rig->caps->rig_model == RIG_MODEL_TS590SG) cmd=71;
|
||||
retval = ts590_get_ex_menu(rig, cmd, 1, &levelint);
|
||||
val->f = levelint / 10.0;
|
||||
val->f = levelint / 9.0;
|
||||
return retval;
|
||||
|
||||
case RIG_LEVEL_AF:
|
||||
|
|
|
@ -204,6 +204,7 @@ const struct rig_caps ftdx101d_caps =
|
|||
[LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
},
|
||||
.parm_gran = {
|
||||
[PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}}
|
||||
|
|
|
@ -106,6 +106,7 @@ const struct rig_caps ftdx101mp_caps =
|
|||
[LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
[LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } },
|
||||
},
|
||||
.parm_gran = {
|
||||
[PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}}
|
||||
|
|
|
@ -211,6 +211,8 @@ const cal_table_float_t yaesu_default_id_meter_cal =
|
|||
static ncboolean is_ft450;
|
||||
static ncboolean is_ft710;
|
||||
static ncboolean is_ft891;
|
||||
static ncboolean is_ft897;
|
||||
static ncboolean is_ft897d;
|
||||
static ncboolean is_ft950;
|
||||
static ncboolean is_ft991;
|
||||
static ncboolean is_ft2000;
|
||||
|
@ -497,6 +499,8 @@ int newcat_init(RIG *rig)
|
|||
is_ft450 = newcat_is_rig(rig, RIG_MODEL_FT450);
|
||||
is_ft450 |= newcat_is_rig(rig, RIG_MODEL_FT450D);
|
||||
is_ft891 = newcat_is_rig(rig, RIG_MODEL_FT891);
|
||||
is_ft897 = newcat_is_rig(rig, RIG_MODEL_FT897);
|
||||
is_ft897d = newcat_is_rig(rig, RIG_MODEL_FT897D);
|
||||
is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950);
|
||||
is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991);
|
||||
is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000);
|
||||
|
@ -847,7 +851,7 @@ int newcat_60m_exception(RIG *rig, freq_t freq, mode_t mode)
|
|||
}
|
||||
|
||||
// some rigs need to skip freq/mode settings as 60M only operates in memory mode
|
||||
if (is_ft991) { return 1; }
|
||||
if (is_ft991 || is_ft897 || is_ft897d || is_ftdx5000) { return 1; }
|
||||
|
||||
if (!is_ftdx10 && !is_ft710 && !is_ftdx101d && !is_ftdx101mp) { return 0; }
|
||||
|
||||
|
@ -4030,12 +4034,8 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0';
|
||||
}
|
||||
|
||||
//TODO Replace the next line
|
||||
level_info = &rig->caps->level_gran[rig_setting2idx(level)];
|
||||
// with the next 2 lines
|
||||
//err = check_level_param(rig, level, val, &level_info);
|
||||
//if (err != RIG_OK ) { RETURNFUNC(err); }
|
||||
//endTODO
|
||||
err = check_level_param(rig, level, val, &level_info);
|
||||
if (err != RIG_OK ) { RETURNFUNC(err); }
|
||||
|
||||
switch (level)
|
||||
{
|
||||
|
@ -4054,19 +4054,6 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
fpf = (int)((val.f / level_info->step.f) + 0.5f );
|
||||
}
|
||||
|
||||
//TODO Remove when global level checking enabled
|
||||
if (is_ft950 || is_ft891 || is_ft991 || is_ftdx3000 || is_ftdx3000dm
|
||||
|| is_ftdx101d
|
||||
|| is_ftdx101mp || is_ftdx10)
|
||||
{
|
||||
// Minimum is 5 watts on these rigs
|
||||
if (fpf < 5)
|
||||
{
|
||||
fpf = 5;
|
||||
}
|
||||
}
|
||||
//endTODO
|
||||
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%03d%c", fpf, cat_term);
|
||||
break;
|
||||
|
||||
|
@ -4076,9 +4063,6 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
RETURNFUNC(-RIG_ENAVAIL);
|
||||
}
|
||||
|
||||
//TODO Remove when common level checking enabled
|
||||
if (val.f > 1.0) { RETURNFUNC(-RIG_EINVAL); }
|
||||
|
||||
fpf = (int)((val.f / level_info->step.f) + 0.5f);
|
||||
|
||||
if (is_ftdx10) { main_sub_vfo = '0'; }
|
||||
|
@ -4207,22 +4191,8 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
RETURNFUNC(-RIG_ENAVAIL);
|
||||
}
|
||||
|
||||
//TODO Get rid of these checks when limit checking enabled
|
||||
if (val.i < 300)
|
||||
{
|
||||
i = 300;
|
||||
}
|
||||
else if (val.i > 1050)
|
||||
{
|
||||
i = 1050;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = val.i;
|
||||
}
|
||||
|
||||
// Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps
|
||||
kp = (i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i;
|
||||
kp = (val.i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i;
|
||||
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", kp, cat_term);
|
||||
break;
|
||||
|
@ -4264,9 +4234,6 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
newcat_get_mode(rig, vfo, &mode, &width);
|
||||
}
|
||||
|
||||
//TODO Remove when level_gran check enabled
|
||||
if (val.f > 1.0) { RETURNFUNC(-RIG_EINVAL); }
|
||||
|
||||
fpf = (int) (( val.f / level_info->step.f ) + 0.5f );
|
||||
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term);
|
||||
|
@ -4790,9 +4757,6 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
RETURNFUNC(-RIG_ENAVAIL);
|
||||
}
|
||||
|
||||
//TODO Remove when full level checking enabled
|
||||
if (val.f > 1.0) { RETURNFUNC(-RIG_EINVAL); }
|
||||
|
||||
fpf = (int)((val.f / level_info->step.f) + 0.5f);
|
||||
|
||||
if (is_ftdx9000)
|
||||
|
@ -4854,24 +4818,25 @@ int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
|
|||
if (is_ftdx101d || is_ftdx101mp)
|
||||
{
|
||||
rmode_t curmode = rig->state.current_vfo == RIG_VFO_A? rig->state.cache.modeMainA : rig->state.cache.modeMainB;
|
||||
float valf = val.f / level_info->step.f;
|
||||
switch(curmode)
|
||||
{
|
||||
case RIG_MODE_USB:
|
||||
case RIG_MODE_LSB:
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%03.0f%c", val.f*100, cat_term);
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%03.0f%c", valf, cat_term);
|
||||
break;
|
||||
case RIG_MODE_AM:
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%03.0f%c", val.f*100, cat_term);
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%03.0f%c", valf, cat_term);
|
||||
break;
|
||||
case RIG_MODE_FM:
|
||||
case RIG_MODE_FMN:
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%03.0f%c", val.f*100, cat_term);
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%03.0f%c", valf, cat_term);
|
||||
break;
|
||||
case RIG_MODE_PKTFM: // is this the right place for this?
|
||||
case RIG_MODE_PKTFMN: // is this the right place for this?
|
||||
case RIG_MODE_PKTUSB:
|
||||
case RIG_MODE_PKTLSB:
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%03.0f%c", val.f*100, cat_term);
|
||||
SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%03.0f%c", valf, cat_term);
|
||||
break;
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown how to set USB_AF for mode=%s\n", __func__, rig_strrmode(curmode));
|
||||
|
@ -5498,7 +5463,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08lx\n", __func__, level);
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08llx\n", __func__, (long long unsigned int)level);
|
||||
RETURNFUNC(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
|
@ -5950,7 +5915,7 @@ int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
|||
case RIG_LEVEL_USB_AF_INPUT:
|
||||
i = 0;
|
||||
sscanf(retlvl, "%3d", &i);
|
||||
val->f = i / 100.0;
|
||||
val->f = i * level_info->step.f;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
typedef char ncboolean;
|
||||
|
||||
/* shared function version */
|
||||
#define NEWCAT_VER "20231024"
|
||||
#define NEWCAT_VER "20231101"
|
||||
|
||||
/* Hopefully large enough for future use, 128 chars plus '\0' */
|
||||
#define NEWCAT_DATA_LEN 129
|
||||
|
|
|
@ -27,6 +27,7 @@ int filternum = 7;
|
|||
int datamode = 0;
|
||||
int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune;
|
||||
int tomode = 0;
|
||||
int keyspd = 25;
|
||||
|
||||
int
|
||||
getmyline(int fd, char *buf)
|
||||
|
@ -203,17 +204,6 @@ int main(int argc, char *argv[])
|
|||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
|
||||
else if (strncmp(buf, "AI", 2) == 0)
|
||||
{
|
||||
if (strcmp(buf, "AI;"))
|
||||
{
|
||||
printf("%s\n", buf);
|
||||
hl_usleep(mysleep * 1000);
|
||||
pbuf = "AI0;";
|
||||
WRITE(fd, pbuf, strlen(pbuf));
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(buf, "VS;") == 0)
|
||||
{
|
||||
printf("%s\n", buf);
|
||||
|
@ -251,10 +241,9 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
sscanf(buf, "FB%d", &freqb);
|
||||
}
|
||||
else if (strncmp(buf, "AI;", 3) == 0)
|
||||
else if (strncmp(buf, "AI", 2) == 0)
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "AI0;");
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
// nothing to do yet
|
||||
}
|
||||
|
||||
else if (strncmp(buf, "PS;", 3) == 0)
|
||||
|
@ -314,7 +303,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
else if (strcmp(buf, "FT;") == 0)
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx);
|
||||
SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx);
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
else if (strncmp(buf, "FT", 2) == 0)
|
||||
|
@ -358,12 +347,11 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
else if (strlen(buf) > 0)
|
||||
{
|
||||
fprintf(stderr, "Unknown command: %s\n", buf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -30,8 +30,8 @@ int keyspd = 25;
|
|||
int width_high = 0;
|
||||
int width_low = 0;
|
||||
int afgain = 50;
|
||||
int usb_af = 5;
|
||||
int usb_af_input = 2;
|
||||
int usb_af = 9;
|
||||
int usb_af_input = 9;
|
||||
int mic_gain = 50;
|
||||
|
||||
int
|
||||
|
@ -234,24 +234,42 @@ int main(int argc, char *argv[])
|
|||
pbuf = "VS0;";
|
||||
WRITE(fd, pbuf, strlen(pbuf));
|
||||
}
|
||||
else if (strcmp(buf, "EX0640000;") == 0)
|
||||
else if (strcmp(buf, "EX0640000;") == 0) // TS-590S version
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "EX0640000%d;", usb_af_input);
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
else if (strncmp(buf, "EX0640000", 9) == 0)
|
||||
else if (strncmp(buf, "EX0640000", 9) == 0) // TS-590S version
|
||||
{
|
||||
sscanf(buf, "EX0640000%d", &usb_af_input);
|
||||
}
|
||||
else if (strcmp(buf, "EX0650000;") == 0)
|
||||
else if (strcmp(buf, "EX0650000;") == 0) // TS-590S version
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "EX0650000%d;", usb_af);
|
||||
SNPRINTF(buf, sizeof(buf), "EX0650000%d;", usb_af); // TS-590S version
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
else if (strncmp(buf, "EX0650000", 9) == 0)
|
||||
else if (strncmp(buf, "EX0650000", 9) == 0) // TS-590S version
|
||||
{
|
||||
sscanf(buf, "EX0650000%d", &usb_af);
|
||||
}
|
||||
else if (strcmp(buf, "EX0710000;") == 0) // TS-590SG version
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "EX0710000%d;", usb_af_input);
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
else if (strncmp(buf, "EX0710000", 9) == 0) // TS-590SG version
|
||||
{
|
||||
sscanf(buf, "EX0710000%d", &usb_af_input);
|
||||
}
|
||||
else if (strcmp(buf, "EX0720000;") == 0) // TS-590SG version
|
||||
{
|
||||
SNPRINTF(buf, sizeof(buf), "EX0720000%d;", usb_af); // TS-590SG version
|
||||
WRITE(fd, buf, strlen(buf));
|
||||
}
|
||||
else if (strncmp(buf, "EX0720000", 9) == 0) // TS-590S version
|
||||
{
|
||||
sscanf(buf, "EX0720000%d", &usb_af);
|
||||
}
|
||||
else if (strcmp(buf, "EX032;") == 0)
|
||||
{
|
||||
static int ant = 0;
|
||||
|
|
104
src/conf.c
104
src/conf.c
|
@ -61,6 +61,11 @@ static const struct confparams frontend_cfg_params[] =
|
|||
"Delay in ms between each command sent out",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_POST_PTT_DELAY, "post_ptt_delay", "Post ptt delay",
|
||||
"Delay in ms after PTT is asserted",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 2000, 1 } } // 2000ms should be more than enough
|
||||
},
|
||||
{
|
||||
TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } }
|
||||
|
@ -71,7 +76,7 @@ static const struct confparams frontend_cfg_params[] =
|
|||
},
|
||||
{
|
||||
TOK_TIMEOUT_RETRY, "timeout_retry", "Number of retries for read timeouts",
|
||||
"Set the number of retries for data read timeouts that may occur especially with some serial interfaces",
|
||||
"Set the # of retries for read timeouts that may occur with some serial interfaces",
|
||||
"1", RIG_CONF_NUMERIC, { .n = { 0, 100, 1 } }
|
||||
},
|
||||
{
|
||||
|
@ -84,6 +89,11 @@ static const struct confparams frontend_cfg_params[] =
|
|||
"The tx/rx range list name",
|
||||
"Default", RIG_CONF_STRING
|
||||
},
|
||||
{
|
||||
TOK_DEVICE_ID, "device_id", "Device ID",
|
||||
"User-specified device ID for multicast state data and commands",
|
||||
"", RIG_CONF_STRING,
|
||||
},
|
||||
|
||||
{
|
||||
TOK_VFO_COMP, "vfo_comp", "VFO compensation",
|
||||
|
@ -91,9 +101,9 @@ static const struct confparams frontend_cfg_params[] =
|
|||
"0", RIG_CONF_NUMERIC, { .n = { 0.0, 1000.0, .001 } }
|
||||
},
|
||||
{
|
||||
TOK_POLL_INTERVAL, "poll_interval", "Rig state poll interval in milliseconds",
|
||||
"Polling interval in milliseconds for transceive emulation, value of 0 disables polling",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
TOK_POLL_INTERVAL, "poll_interval", "Rig state poll interval in ms",
|
||||
"Polling interval in ms for transceive emulation, defaults to 1000, value of 0 disables polling",
|
||||
"1000", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_PTT_TYPE, "ptt_type", "PTT type",
|
||||
|
@ -102,7 +112,7 @@ static const struct confparams frontend_cfg_params[] =
|
|||
},
|
||||
{
|
||||
TOK_PTT_PATHNAME, "ptt_pathname", "PTT path name",
|
||||
"Path name to the device file of the Push-To-Talk",
|
||||
"Path to the device of the Push-To-Talk",
|
||||
"/dev/rig", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
|
@ -117,7 +127,7 @@ static const struct confparams frontend_cfg_params[] =
|
|||
},
|
||||
{
|
||||
TOK_DCD_PATHNAME, "dcd_pathname", "DCD path name",
|
||||
"Path name to the device file of the Data Carrier Detect (or squelch)",
|
||||
"Path to the device of the Data Carrier Detect (or squelch)",
|
||||
"/dev/rig", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
|
@ -172,12 +182,12 @@ static const struct confparams frontend_cfg_params[] =
|
|||
},
|
||||
{
|
||||
TOK_ASYNC, "async", "Asynchronous data transfer support",
|
||||
"True enables asynchronous data transfer for backends that support it. This allows use of transceive and spectrum data.",
|
||||
"True enables async data for rigs that support it to allow use of transceive and spectrum data",
|
||||
"0", RIG_CONF_CHECKBUTTON, { }
|
||||
},
|
||||
{
|
||||
TOK_TUNER_CONTROL_PATHNAME, "tuner_control_pathname", "Tuner script/program path name",
|
||||
"Path name to a script/program to control a tuner with 1 argument of 0/1 for Tuner Off/On",
|
||||
"Path to a program to control a tuner with 1 argument of 0/1 for Tuner Off/On",
|
||||
"hamlib_tuner_control", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
|
@ -190,6 +200,26 @@ static const struct confparams frontend_cfg_params[] =
|
|||
"Add Hz to VFOB/Sub frequency set",
|
||||
"0", RIG_CONF_NUMERIC, { .n = {0, 1e12, 1}}
|
||||
},
|
||||
{
|
||||
TOK_MULTICAST_DATA_ADDR, "multicast_data_addr", "Multicast data UDP address",
|
||||
"Multicast data UDP address for publishing rig data and state, value of 0.0.0.0 disables multicast data publishing",
|
||||
"224.0.0.1", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
TOK_MULTICAST_DATA_PORT, "multicast_data_port", "Multicast data UDP port",
|
||||
"Multicast data UDP port for publishing rig data and state",
|
||||
"4532", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_MULTICAST_CMD_ADDR, "multicast_cmd_addr", "Multicast command server UDP address",
|
||||
"Multicast command UDP address for sending commands to rig, value of 0.0.0.0 disables multicast command server",
|
||||
"224.0.0.2", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
TOK_MULTICAST_CMD_PORT, "multicast_cmd_port", "Multicast command server UDP port",
|
||||
"Multicast data UDP port for sending commands to rig",
|
||||
"4532", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
},
|
||||
|
||||
{ RIG_CONF_END, NULL, }
|
||||
};
|
||||
|
@ -602,13 +632,21 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
|
|||
strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1);
|
||||
break;
|
||||
|
||||
case TOK_DEVICE_ID:
|
||||
strncpy(rs->device_id, val, HAMLIB_RIGNAMSIZ - 1);
|
||||
break;
|
||||
|
||||
|
||||
case TOK_VFO_COMP:
|
||||
rs->vfo_comp = atof(val);
|
||||
break;
|
||||
|
||||
case TOK_POLL_INTERVAL:
|
||||
rs->poll_interval = atof(val);
|
||||
if (1 != sscanf(val, "%ld", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
rs->poll_interval = val_i;
|
||||
// Make sure cache times out before next poll cycle
|
||||
rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, atol(val));
|
||||
break;
|
||||
|
@ -735,7 +773,31 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
|
|||
rig_debug(RIG_DEBUG_VERBOSE, "%s: offset_vfob=%ld\n", __func__, val_i);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_DATA_ADDR:
|
||||
rs->multicast_data_addr = strdup(val);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_DATA_PORT:
|
||||
if (1 != sscanf(val, "%ld", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->multicast_data_port = val_i;
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_CMD_ADDR:
|
||||
rs->multicast_cmd_addr = strdup(val);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_CMD_PORT:
|
||||
if (1 != sscanf(val, "%ld", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->multicast_cmd_port = val_i;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
|
@ -770,6 +832,10 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
|
|||
SNPRINTF(val, val_len, "%d", rs->rigport.post_write_delay);
|
||||
break;
|
||||
|
||||
case TOK_POST_PTT_DELAY:
|
||||
SNPRINTF(val, val_len, "%d", rs->rigport.post_ptt_delay);
|
||||
break;
|
||||
|
||||
case TOK_TIMEOUT:
|
||||
SNPRINTF(val, val_len, "%d", rs->rigport.timeout);
|
||||
break;
|
||||
|
@ -932,6 +998,10 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
|
|||
strcpy(val, s);
|
||||
break;
|
||||
|
||||
case TOK_DEVICE_ID:
|
||||
SNPRINTF(val, val_len, "%s", rs->device_id);
|
||||
break;
|
||||
|
||||
case TOK_VFO_COMP:
|
||||
SNPRINTF(val, val_len, "%f", rs->vfo_comp);
|
||||
break;
|
||||
|
@ -1092,6 +1162,22 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
|
|||
SNPRINTF(val, val_len, "%d", rs->rigport.timeout_retry);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_DATA_ADDR:
|
||||
SNPRINTF(val, val_len, "%s", rs->multicast_data_addr);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_DATA_PORT:
|
||||
SNPRINTF(val, val_len, "%d", rs->multicast_data_port);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_CMD_ADDR:
|
||||
SNPRINTF(val, val_len, "%s", rs->multicast_cmd_addr);
|
||||
break;
|
||||
|
||||
case TOK_MULTICAST_CMD_PORT:
|
||||
SNPRINTF(val, val_len, "%d", rs->multicast_cmd_port);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
|
141
src/event.c
141
src/event.c
|
@ -64,8 +64,6 @@ typedef struct rig_poll_routine_priv_data_s
|
|||
rig_poll_routine_args args;
|
||||
} rig_poll_routine_priv_data;
|
||||
|
||||
// TODO: Where to start/stop rig poll routine?
|
||||
|
||||
void *rig_poll_routine(void *arg)
|
||||
{
|
||||
rig_poll_routine_args *args = (rig_poll_routine_args *)arg;
|
||||
|
@ -75,12 +73,11 @@ void *rig_poll_routine(void *arg)
|
|||
int update_occurred;
|
||||
|
||||
vfo_t vfo = RIG_VFO_NONE, vfo_prev = RIG_VFO_NONE;
|
||||
freq_t freq_main = 0, freq_sub = 0, freq_main_prev = 0, freq_sub_prev = 0;
|
||||
rmode_t mode_main = RIG_MODE_NONE, mode_sub = RIG_MODE_NONE,
|
||||
mode_main_prev = RIG_MODE_NONE, mode_sub_prev = RIG_MODE_NONE;
|
||||
pbwidth_t width_main = 0, width_sub = 0, width_main_prev = 0,
|
||||
width_sub_prev = 0;
|
||||
split_t split, split_prev = -1;
|
||||
freq_t freq_main_a = 0, freq_main_b = 0, freq_main_c = 0, freq_sub_a = 0, freq_sub_b = 0, freq_sub_c = 0;
|
||||
rmode_t mode_main_a = 0, mode_main_b = 0, mode_main_c = 0, mode_sub_a = 0, mode_sub_b = 0, mode_sub_c = 0;
|
||||
pbwidth_t width_main_a = 0, width_main_b = 0, width_main_c = 0, width_sub_a = 0, width_sub_b = 0, width_sub_c = 0;
|
||||
ptt_t ptt = RIG_PTT_OFF;
|
||||
split_t split = RIG_SPLIT_OFF;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting rig poll routine thread\n",
|
||||
__FILE__, __LINE__);
|
||||
|
@ -88,10 +85,119 @@ void *rig_poll_routine(void *arg)
|
|||
// Rig cache time should be equal to rig poll interval (should be set automatically by rigctld at least)
|
||||
rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, rs->poll_interval);
|
||||
|
||||
// Attempt to detect changes with the interval below (in milliseconds)
|
||||
int change_detection_interval = 50;
|
||||
int interval_count = 0;
|
||||
|
||||
update_occurred = 0;
|
||||
|
||||
network_publish_rig_poll_data(rig);
|
||||
|
||||
while (rs->poll_routine_thread_run)
|
||||
{
|
||||
if (rig->state.cache.freqMainA != freq_main_a)
|
||||
{
|
||||
freq_main_a = rig->state.cache.freqMainA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.freqMainB != freq_main_b)
|
||||
{
|
||||
freq_main_b = rig->state.cache.freqMainB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.freqMainC != freq_main_c)
|
||||
{
|
||||
freq_main_b = rig->state.cache.freqMainC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.freqSubA != freq_sub_a)
|
||||
{
|
||||
freq_sub_a = rig->state.cache.freqSubA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.freqSubB != freq_sub_b)
|
||||
{
|
||||
freq_sub_b = rig->state.cache.freqSubB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.freqSubC != freq_sub_c)
|
||||
{
|
||||
freq_sub_c = rig->state.cache.freqSubC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.ptt != ptt)
|
||||
{
|
||||
ptt = rig->state.cache.ptt;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.split != split)
|
||||
{
|
||||
split = rig->state.cache.split;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeMainA != mode_main_a)
|
||||
{
|
||||
mode_main_a = rig->state.cache.modeMainA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeMainB != mode_main_b)
|
||||
{
|
||||
mode_main_b = rig->state.cache.modeMainB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeMainC != mode_main_c)
|
||||
{
|
||||
mode_main_c = rig->state.cache.modeMainC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeSubA != mode_sub_a)
|
||||
{
|
||||
mode_sub_a = rig->state.cache.modeSubA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeSubB != mode_sub_b)
|
||||
{
|
||||
mode_sub_b = rig->state.cache.modeSubB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.modeSubC != mode_sub_c)
|
||||
{
|
||||
mode_sub_c = rig->state.cache.modeSubC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthMainA != width_main_a)
|
||||
{
|
||||
width_main_a = rig->state.cache.widthMainA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthMainB != width_main_b)
|
||||
{
|
||||
width_main_b = rig->state.cache.widthMainB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthMainC != width_main_c)
|
||||
{
|
||||
width_main_c = rig->state.cache.widthMainC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthSubA != width_sub_a)
|
||||
{
|
||||
width_sub_a = rig->state.cache.widthSubA;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthSubB != width_sub_b)
|
||||
{
|
||||
width_sub_b = rig->state.cache.widthSubB;
|
||||
update_occurred = 1;
|
||||
}
|
||||
else if (rig->state.cache.widthSubC != width_sub_c)
|
||||
{
|
||||
width_sub_c = rig->state.cache.widthSubC;
|
||||
update_occurred = 1;
|
||||
}
|
||||
|
||||
// The original code here actively reads rig state, which can be too intensive and intrusive
|
||||
#if 0
|
||||
if (rig->caps->get_vfo)
|
||||
{
|
||||
result = rig_get_vfo(rig, &vfo);
|
||||
|
@ -225,15 +331,28 @@ void *rig_poll_routine(void *arg)
|
|||
split_prev = split;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (update_occurred)
|
||||
{
|
||||
network_publish_rig_poll_data(rig);
|
||||
update_occurred = 0;
|
||||
interval_count = 0;
|
||||
}
|
||||
|
||||
hl_usleep(rs->poll_interval * 1000);
|
||||
hl_usleep(change_detection_interval * 1000);
|
||||
interval_count++;
|
||||
|
||||
// Publish updates every poll_interval if no changes have been detected
|
||||
if (interval_count >= (rs->poll_interval / change_detection_interval))
|
||||
{
|
||||
interval_count = 0;
|
||||
network_publish_rig_poll_data(rig);
|
||||
}
|
||||
}
|
||||
|
||||
network_publish_rig_poll_data(rig);
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n",
|
||||
__FILE__,
|
||||
__LINE__);
|
||||
|
@ -291,6 +410,8 @@ int rig_poll_routine_start(RIG *rig)
|
|||
RETURNFUNC(-RIG_EINTERNAL);
|
||||
}
|
||||
|
||||
network_publish_rig_poll_data(rig);
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
|
@ -336,6 +457,8 @@ int rig_poll_routine_stop(RIG *rig)
|
|||
poll_routine_priv->thread_id = 0;
|
||||
}
|
||||
|
||||
network_publish_rig_poll_data(rig);
|
||||
|
||||
free(rs->poll_routine_priv_data);
|
||||
rs->poll_routine_priv_data = NULL;
|
||||
|
||||
|
|
36
src/misc.c
36
src/misc.c
|
@ -2707,6 +2707,42 @@ const char *HAMLIB_API rig_get_caps_cptr(rig_model_t rig_model,
|
|||
}
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
rig_comm_status_t status;
|
||||
const char *str;
|
||||
} comm_status_str[] =
|
||||
{
|
||||
{ RIG_COMM_STATUS_OK, "OK" },
|
||||
{ RIG_COMM_STATUS_CONNECTING, "CONNECTING" },
|
||||
{ RIG_COMM_STATUS_DISCONNECTED, "DISCONNECTED" },
|
||||
{ RIG_COMM_STATUS_TERMINATED, "TERMINATIED" },
|
||||
{ RIG_COMM_STATUS_WARNING, "WARNING" },
|
||||
{ RIG_COMM_STATUS_ERROR, "ERROR" },
|
||||
{ 0xffffffff, "" },
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Convert enum RIG_COMM_STATUS... to alpha string
|
||||
* \param vfo RIG_COMM_STATUS_...
|
||||
* \return alpha string
|
||||
*/
|
||||
const char *HAMLIB_API rig_strcommstatus(rig_comm_status_t status)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; comm_status_str[i].str[0] != '\0'; i++)
|
||||
{
|
||||
if (status == comm_status_str[i].status)
|
||||
{
|
||||
return comm_status_str[i].str;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void errmsg(int err, char *s, const char *func, const char *file, int line)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s(%s:%d): %s: %s\b", __func__, file, line, s,
|
||||
|
|
361
src/network.c
361
src/network.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Hamlib Interface - network communication low-level support
|
||||
* Copyright (c) 2021 by Mikael Nousiainen
|
||||
* Copyright (c) 2021-2023 by Mikael Nousiainen
|
||||
* Copyright (c) 2000-2012 by Stephane Fillod
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
|
@ -126,6 +126,20 @@ typedef struct multicast_publisher_priv_data_s
|
|||
multicast_publisher_args args;
|
||||
} multicast_publisher_priv_data;
|
||||
|
||||
typedef struct multicast_receiver_args_s
|
||||
{
|
||||
RIG *rig;
|
||||
int socket_fd;
|
||||
const char *multicast_addr;
|
||||
int multicast_port;
|
||||
} multicast_receiver_args;
|
||||
|
||||
typedef struct multicast_receiver_priv_data_s
|
||||
{
|
||||
pthread_t thread_id;
|
||||
multicast_receiver_args args;
|
||||
} multicast_receiver_priv_data;
|
||||
|
||||
static void handle_error(enum rig_debug_level_e lvl, const char *msg)
|
||||
{
|
||||
int e;
|
||||
|
@ -714,7 +728,7 @@ static int multicast_publisher_write_packet_header(RIG *rig,
|
|||
if (rs->multicast_publisher_priv_data == NULL)
|
||||
{
|
||||
// Silently ignore if multicast publisher is not enabled
|
||||
RETURNFUNC2(RIG_OK);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
mcast_publisher_priv = (multicast_publisher_priv_data *)
|
||||
|
@ -727,10 +741,10 @@ static int multicast_publisher_write_packet_header(RIG *rig,
|
|||
|
||||
if (result != RIG_OK)
|
||||
{
|
||||
RETURNFUNC2(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
RETURNFUNC2(RIG_OK);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
// cppcheck-suppress unusedFunction
|
||||
|
@ -773,7 +787,6 @@ int network_publish_rig_transceive_data(RIG *rig)
|
|||
return multicast_publisher_write_packet_header(rig, &packet);
|
||||
}
|
||||
|
||||
// cppcheck-suppress unusedFunction
|
||||
int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line)
|
||||
{
|
||||
int result;
|
||||
|
@ -908,6 +921,8 @@ void *multicast_publisher(void *arg)
|
|||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast publisher\n", __FILE__,
|
||||
__LINE__);
|
||||
|
||||
snapshot_init();
|
||||
|
||||
memset(&dest_addr, 0, sizeof(dest_addr));
|
||||
dest_addr.sin_family = AF_INET;
|
||||
dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr);
|
||||
|
@ -930,7 +945,7 @@ void *multicast_publisher(void *arg)
|
|||
|
||||
// TODO: how to detect closing of pipe, indicate with error code
|
||||
// TODO: error handling, flush pipe in case of error?
|
||||
hl_usleep(500 * 1000);
|
||||
hl_usleep(100 * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -969,6 +984,146 @@ void *multicast_publisher(void *arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void *multicast_receiver(void *arg)
|
||||
{
|
||||
char data[4096];
|
||||
|
||||
struct multicast_receiver_args_s *args = (struct multicast_receiver_args_s *)
|
||||
arg;
|
||||
RIG *rig = args->rig;
|
||||
struct rig_state *rs = &rig->state;
|
||||
|
||||
struct sockaddr_in dest_addr;
|
||||
int socket_fd = args->socket_fd;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast receiver\n", __FILE__,
|
||||
__LINE__);
|
||||
|
||||
int optval = 1;
|
||||
#ifdef __MINGW32__
|
||||
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (PCHAR)&optval, sizeof(optval)) < 0)
|
||||
#else
|
||||
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
|
||||
#endif
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP address reuse: %s\n", __func__,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Windows does not have SO_REUSEPORT. However, SO_REUSEADDR works in a similar way.
|
||||
#if defined(SO_REUSEPORT)
|
||||
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP port reuse: %s\n", __func__,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&dest_addr, 0, sizeof(dest_addr));
|
||||
dest_addr.sin_family = AF_INET;
|
||||
#ifdef __MINGW32__
|
||||
// Windows cannot bind to multicast group addresses for some unknown reason
|
||||
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
#else
|
||||
dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr);
|
||||
#endif
|
||||
dest_addr.sin_port = htons(args->multicast_port);
|
||||
|
||||
if (bind(socket_fd, (struct sockaddr *) &dest_addr, sizeof(dest_addr)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error binding UDP socket to %s:%d: %s\n", __func__,
|
||||
args->multicast_addr, args->multicast_port, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ip_mreq mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(args->multicast_addr);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
if (setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (PCHAR)&mreq, sizeof(mreq)) < 0)
|
||||
#else
|
||||
if (setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
#endif
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error joining multicast group %s:%d: %s\n", __func__,
|
||||
args->multicast_addr, args->multicast_port, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rs->multicast_receiver_run = 1;
|
||||
|
||||
while (rs->multicast_receiver_run == 1)
|
||||
{
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
fd_set rfds, efds;
|
||||
struct timeval timeout;
|
||||
int select_result;
|
||||
ssize_t result;
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(socket_fd, &rfds);
|
||||
efds = rfds;
|
||||
|
||||
select_result = select(socket_fd + 1, &rfds, NULL, &efds, &timeout);
|
||||
if (select_result == 0)
|
||||
{
|
||||
// Select timed out
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_result < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s(): select() failed when reading UDP multicast socket data: %s\n",
|
||||
__func__,
|
||||
strerror(errno));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(socket_fd, &efds))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s(): fd error when reading UDP multicast socket data\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
result = recvfrom(socket_fd, data, sizeof(data), 0, (struct sockaddr *) &client_addr, &client_len);
|
||||
|
||||
if (result <= 0)
|
||||
{
|
||||
if (result < 0)
|
||||
{
|
||||
if (errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error receiving from UDP socket %s:%d: %s\n", __func__,
|
||||
args->multicast_addr, args->multicast_port, strerror(errno));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: handle commands from multicast clients
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: received %ld bytes of data: %.*s\n", __func__, (long) result, (int) result, data);
|
||||
|
||||
// TODO: if a new snapshot needs to be sent, call network_publish_rig_poll_data() and the publisher routine will send out a snapshot
|
||||
// TODO: new logic in publisher needs to be written for other types of responses
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping multicast receiver\n", __FILE__,
|
||||
__LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
|
@ -990,11 +1145,11 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
|||
|
||||
ENTERFUNC;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):multicast address=%s, port=%d\n", __FILE__,
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): multicast publisher address=%s, port=%d\n", __FILE__,
|
||||
__LINE__,
|
||||
multicast_addr, multicast_port);
|
||||
|
||||
if (strcmp(multicast_addr, "0.0.0.0") == 0)
|
||||
if (multicast_addr == NULL || strcmp(multicast_addr, "0.0.0.0") == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s(%d): not starting multicast publisher\n",
|
||||
__FILE__, __LINE__);
|
||||
|
@ -1025,6 +1180,24 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
|||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
|
||||
// Enable non-blocking mode
|
||||
u_long mode = 1;
|
||||
#ifdef __MINGW32__
|
||||
if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#else
|
||||
if (ioctl(socket_fd, FIONBIO, &mode) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (items & RIG_MULTICAST_TRANSCEIVE)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__,
|
||||
|
@ -1036,11 +1209,6 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
|||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_SPECTRUM enabled\n", __FILE__,
|
||||
__LINE__);
|
||||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s(%d) unknown MULTICAST item requested=0x%x\n",
|
||||
__FILE__, __LINE__, items);
|
||||
}
|
||||
|
||||
rs->snapshot_packet_sequence_number = 0;
|
||||
rs->multicast_publisher_run = 1;
|
||||
|
@ -1142,5 +1310,172 @@ int network_multicast_publisher_stop(RIG *rig)
|
|||
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Start multicast receiver
|
||||
*
|
||||
* Start multicast receiver.
|
||||
*
|
||||
* \param multicast_addr UDP address
|
||||
* \param multicast_port UDP socket port
|
||||
* \return RIG_OK or < 0 if error
|
||||
*/
|
||||
int network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port)
|
||||
{
|
||||
struct rig_state *rs = &rig->state;
|
||||
multicast_receiver_priv_data *mcast_receiver_priv;
|
||||
int socket_fd;
|
||||
int status;
|
||||
|
||||
ENTERFUNC;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): multicast receiver address=%s, port=%d\n", __FILE__,
|
||||
__LINE__,
|
||||
multicast_addr, multicast_port);
|
||||
|
||||
if (multicast_addr == NULL || strcmp(multicast_addr, "0.0.0.0") == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s(%d): not starting multicast receiver\n",
|
||||
__FILE__, __LINE__);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
if (rs->multicast_receiver_priv_data != NULL)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s(%d): multicast receiver already running\n",
|
||||
__FILE__,
|
||||
__LINE__);
|
||||
RETURNFUNC(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
status = network_init();
|
||||
|
||||
if (status != RIG_OK)
|
||||
{
|
||||
RETURNFUNC(status);
|
||||
}
|
||||
|
||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error opening new UDP socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
|
||||
// Enable non-blocking mode
|
||||
u_long mode = 1;
|
||||
#ifdef __MINGW32__
|
||||
if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#else
|
||||
if (ioctl(socket_fd, FIONBIO, &mode) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
rs->multicast_receiver_run = 1;
|
||||
rs->multicast_receiver_priv_data = calloc(1,
|
||||
sizeof(multicast_receiver_priv_data));
|
||||
|
||||
if (rs->multicast_receiver_priv_data == NULL)
|
||||
{
|
||||
close(socket_fd);
|
||||
RETURNFUNC(-RIG_ENOMEM);
|
||||
}
|
||||
|
||||
mcast_receiver_priv = (multicast_receiver_priv_data *)
|
||||
rs->multicast_receiver_priv_data;
|
||||
mcast_receiver_priv->args.socket_fd = socket_fd;
|
||||
mcast_receiver_priv->args.multicast_addr = multicast_addr;
|
||||
mcast_receiver_priv->args.multicast_port = multicast_port;
|
||||
mcast_receiver_priv->args.rig = rig;
|
||||
|
||||
int err = pthread_create(&mcast_receiver_priv->thread_id, NULL,
|
||||
multicast_receiver,
|
||||
&mcast_receiver_priv->args);
|
||||
|
||||
if (err)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__,
|
||||
strerror(errno));
|
||||
free(mcast_receiver_priv);
|
||||
rs->multicast_receiver_priv_data = NULL;
|
||||
close(socket_fd);
|
||||
RETURNFUNC(-RIG_EINTERNAL);
|
||||
}
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop multicast receiver
|
||||
*
|
||||
* Stop multicast receiver
|
||||
*
|
||||
* \return RIG_OK or < 0 if error
|
||||
*/
|
||||
int network_multicast_receiver_stop(RIG *rig)
|
||||
{
|
||||
struct rig_state *rs = &rig->state;
|
||||
multicast_receiver_priv_data *mcast_receiver_priv;
|
||||
|
||||
ENTERFUNC;
|
||||
|
||||
rs->multicast_receiver_run = 0;
|
||||
|
||||
mcast_receiver_priv = (multicast_receiver_priv_data *)
|
||||
rs->multicast_receiver_priv_data;
|
||||
|
||||
if (mcast_receiver_priv == NULL)
|
||||
{
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
// Close the socket first to stop the routine
|
||||
if (mcast_receiver_priv->args.socket_fd >= 0)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
shutdown(mcast_receiver_priv->args.socket_fd, SD_BOTH);
|
||||
#else
|
||||
shutdown(mcast_receiver_priv->args.socket_fd, SHUT_RDWR);
|
||||
#endif
|
||||
close(mcast_receiver_priv->args.socket_fd);
|
||||
}
|
||||
|
||||
if (mcast_receiver_priv->thread_id != 0)
|
||||
{
|
||||
int err = pthread_join(mcast_receiver_priv->thread_id, NULL);
|
||||
|
||||
if (err)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s(%d): pthread_join error %s\n", __FILE__, __LINE__,
|
||||
strerror(errno));
|
||||
// just ignore it
|
||||
}
|
||||
|
||||
mcast_receiver_priv->thread_id = 0;
|
||||
}
|
||||
|
||||
if (mcast_receiver_priv->args.socket_fd >= 0)
|
||||
{
|
||||
mcast_receiver_priv->args.socket_fd = -1;
|
||||
}
|
||||
|
||||
free(rs->multicast_receiver_priv_data);
|
||||
rs->multicast_receiver_priv_data = NULL;
|
||||
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
|
|
@ -34,8 +34,11 @@ void network_flush(hamlib_port_t *rp);
|
|||
int network_publish_rig_poll_data(RIG *rig);
|
||||
int network_publish_rig_transceive_data(RIG *rig);
|
||||
int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line);
|
||||
int network_publish_rig_status_change(RIG *rig, int32_t status);
|
||||
HAMLIB_EXPORT(int) network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items);
|
||||
HAMLIB_EXPORT(int) network_multicast_publisher_stop(RIG *rig);
|
||||
HAMLIB_EXPORT(int) network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port);
|
||||
HAMLIB_EXPORT(int) network_multicast_receiver_stop(RIG *rig);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
88
src/rig.c
88
src/rig.c
|
@ -604,6 +604,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
|
|||
#if defined(HAVE_PTHREAD)
|
||||
rs->rigport.asyncio = 0;
|
||||
#endif
|
||||
rig->state.comm_status = RIG_COMM_STATUS_CONNECTING;
|
||||
|
||||
rs->tuner_control_pathname = DEFAULT_TUNER_CONTROL_PATHNAME;
|
||||
|
||||
|
@ -682,7 +683,11 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
|
|||
rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */
|
||||
rs->rx_vfo = RIG_VFO_CURR; /* we don't know yet! */
|
||||
rs->tx_vfo = RIG_VFO_CURR; /* we don't know yet! */
|
||||
rs->poll_interval = 0; // disable polling by default
|
||||
rs->poll_interval = 1000; // enable polling by default
|
||||
rs->multicast_data_addr = "224.0.0.1"; // enable multicast data publishing by default
|
||||
rs->multicast_data_port = 4532;
|
||||
rs->multicast_cmd_addr = "224.0.0.2"; // enable multicast command server by default
|
||||
rs->multicast_cmd_port = 4532;
|
||||
rs->lo_freq = 0;
|
||||
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
|
||||
rs->cache.ptt = 0;
|
||||
|
@ -1054,6 +1059,8 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
RETURNFUNC2(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
rs->comm_status = RIG_COMM_STATUS_CONNECTING;
|
||||
|
||||
rs->rigport.fd = -1;
|
||||
|
||||
if (rs->rigport.type.rig == RIG_PORT_SERIAL)
|
||||
|
@ -1102,6 +1109,7 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
rig_debug(RIG_DEBUG_VERBOSE, "%s: rs->comm_state==0?=%d\n", __func__,
|
||||
rs->comm_state);
|
||||
rs->comm_state = 0;
|
||||
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
|
||||
RETURNFUNC2(status);
|
||||
}
|
||||
|
||||
|
@ -1320,6 +1328,7 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
if (status < 0)
|
||||
{
|
||||
port_close(&rs->rigport, rs->rigport.type.rig);
|
||||
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
|
||||
RETURNFUNC2(status);
|
||||
}
|
||||
|
||||
|
@ -1328,11 +1337,10 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
if (status < 0)
|
||||
{
|
||||
port_close(&rs->rigport, rs->rigport.type.rig);
|
||||
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
|
||||
RETURNFUNC2(status);
|
||||
}
|
||||
|
||||
add_opened_rig(rig);
|
||||
|
||||
rs->comm_state = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: %p rs->comm_state==1?=%d\n", __func__,
|
||||
&rs->comm_state,
|
||||
|
@ -1385,6 +1393,7 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
port_close(&rs->rigport, rs->rigport.type.rig);
|
||||
memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated));
|
||||
rs->comm_state = 0;
|
||||
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
|
||||
RETURNFUNC2(status);
|
||||
}
|
||||
}
|
||||
|
@ -1489,22 +1498,40 @@ int HAMLIB_API rig_open(RIG *rig)
|
|||
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);
|
||||
// if (rig->caps->rig_model != RIG_MODEL_NETRIGCTL) multicast_init(rig, "224.0.0.1", 4532);
|
||||
// multicast_init(rig, "224.0.0.1", 4532);
|
||||
char *multicast_addr = "224.0.0.1";
|
||||
int multicast_port = 4532;
|
||||
enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE;
|
||||
// | RIG_MULTICAST_SPECTRUM;
|
||||
retval = network_multicast_publisher_start(rig, multicast_addr,
|
||||
multicast_port, items);
|
||||
|
||||
enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE
|
||||
| RIG_MULTICAST_SPECTRUM;
|
||||
retval = network_multicast_publisher_start(rig, rs->multicast_data_addr,
|
||||
rs->multicast_data_port, items);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_server failed: %s\n", __FILE__,
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_publisher_start failed: %s\n", __FILE__,
|
||||
rigerror(retval));
|
||||
// we will consider this non-fatal for now
|
||||
}
|
||||
|
||||
retval = network_multicast_receiver_start(rig, rs->multicast_cmd_addr, rs->multicast_cmd_port);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_receiver_start failed: %s\n", __FILE__,
|
||||
rigerror(retval));
|
||||
// we will consider this non-fatal for now
|
||||
}
|
||||
|
||||
retval = rig_poll_routine_start(rig);
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: rig_poll_routine_start failed: %s\n", __FILE__,
|
||||
rigerror(retval));
|
||||
// we will consider this non-fatal for now
|
||||
}
|
||||
|
||||
rig->state.comm_status = RIG_COMM_STATUS_OK;
|
||||
|
||||
add_opened_rig(rig);
|
||||
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
|
||||
|
@ -1544,11 +1571,15 @@ int HAMLIB_API rig_close(RIG *rig)
|
|||
RETURNFUNC(-RIG_EINVAL);
|
||||
}
|
||||
|
||||
remove_opened_rig(rig);
|
||||
|
||||
rig->state.comm_status = RIG_COMM_STATUS_DISCONNECTED;
|
||||
|
||||
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);
|
||||
//while(rs->multicast_publisher_run != 2) hl_usleep(10*1000);
|
||||
//multicast_stop(rig);
|
||||
|
||||
/*
|
||||
* Let the backend say 73s to the rig.
|
||||
|
@ -1663,8 +1694,6 @@ int HAMLIB_API rig_close(RIG *rig)
|
|||
|
||||
port_close(&rs->rigport, rs->rigport.type.rig);
|
||||
|
||||
remove_opened_rig(rig);
|
||||
|
||||
// zero split so it will allow it to be set again on open for rigctld
|
||||
rig->state.cache.split = 0;
|
||||
rs->comm_state = 0;
|
||||
|
@ -1892,6 +1921,28 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
rig_strvfo(vfo), freq);
|
||||
#endif
|
||||
|
||||
if (rig->state.doppler == 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainA);
|
||||
}
|
||||
freq += rig->state.offset_vfoa;
|
||||
}
|
||||
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)
|
||||
{
|
||||
rig->state.doppler = 1;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, rig->state.cache.freqMainB);
|
||||
}
|
||||
freq += rig->state.offset_vfob;
|
||||
}
|
||||
}
|
||||
|
||||
if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq += rig->state.offset_vfoa; }
|
||||
else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { freq += rig->state.offset_vfob; }
|
||||
|
||||
|
@ -2300,9 +2351,11 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|||
__LINE__, rig->state.vfo_opt, rig->caps->rig_model);
|
||||
|
||||
// If we're in vfo_mode then rigctld will do any VFO swapping we need
|
||||
// If we detected doppler we skip the frequency check to make timing more consistent for relay control
|
||||
if ((caps->targetable_vfo & RIG_TARGETABLE_FREQ)
|
||||
|| vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo
|
||||
|| (rig->state.vfo_opt == 1 && rig->caps->rig_model == RIG_MODEL_NETRIGCTL))
|
||||
|| (rig->state.vfo_opt == 1 && rig->caps->rig_model == RIG_MODEL_NETRIGCTL
|
||||
&& rig->state.doppler == 0))
|
||||
{
|
||||
// If rig does not have set_vfo we need to change vfo
|
||||
if (vfo == RIG_VFO_CURR && caps->set_vfo == NULL)
|
||||
|
@ -3484,6 +3537,7 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
|
|||
|
||||
memcpy(&rig->state.pttport_deprecated, &rig->state.pttport,
|
||||
sizeof(rig->state.pttport_deprecated));
|
||||
if (rig->state.rigport.post_ptt_delay > 0) hl_usleep(rig->state.rigport.post_ptt_delay*1000);
|
||||
ELAPSED2;
|
||||
|
||||
RETURNFUNC(retcode);
|
||||
|
|
|
@ -15,35 +15,21 @@
|
|||
#define SPECTRUM_MODE_FIXED "FIXED"
|
||||
#define SPECTRUM_MODE_CENTER "CENTER"
|
||||
|
||||
char snapshot_data_pid[20];
|
||||
|
||||
static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig)
|
||||
{
|
||||
cJSON *node;
|
||||
char buf[1024];
|
||||
|
||||
#if 0
|
||||
// TODO: need to assign rig an ID, e.g. from command line
|
||||
snprintf(buf, sizeof(buf), "%s:%s:%d", rig->caps->model_name,
|
||||
rig->state.rigport.pathname, getpid());
|
||||
|
||||
node = cJSON_AddStringToObject(rig_node, "id", buf);
|
||||
if (node == NULL)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
#else
|
||||
cJSON *id_node = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(id_node, "model", rig->caps->model_name);
|
||||
cJSON_AddStringToObject(id_node, "endpoint", rig->state.rigport.pathname);
|
||||
char pid[16];
|
||||
sprintf(pid,"%d",getpid());
|
||||
cJSON_AddStringToObject(id_node, "process", pid);
|
||||
cJSON_AddStringToObject(id_node, "process", snapshot_data_pid);
|
||||
cJSON_AddStringToObject(id_node, "deviceId", rig->state.device_id);
|
||||
cJSON_AddItemToObject(rig_node, "id", id_node);
|
||||
#endif
|
||||
|
||||
// TODO: what kind of status should this reflect?
|
||||
node = cJSON_AddStringToObject(rig_node, "status",
|
||||
rig->state.comm_state ? "OK" : "CLOSED");
|
||||
node = cJSON_AddStringToObject(rig_node, "status", rig_strcommstatus(rig->state.comm_status));
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
|
@ -161,19 +147,26 @@ static int snapshot_serialize_vfo(cJSON *vfo_node, RIG *rig, vfo_t vfo)
|
|||
}
|
||||
}
|
||||
|
||||
split = rig->state.cache.split;
|
||||
split_vfo = rig->state.cache.split_vfo;
|
||||
|
||||
is_rx = (split == RIG_SPLIT_OFF && vfo == rig->state.current_vfo)
|
||||
|| (split == RIG_SPLIT_ON && vfo != split_vfo);
|
||||
is_tx = (split == RIG_SPLIT_OFF && vfo == rig->state.current_vfo)
|
||||
|| (split == RIG_SPLIT_ON && vfo == split_vfo);
|
||||
ptt = rig->state.cache.ptt;
|
||||
|
||||
if (is_tx)
|
||||
node = cJSON_AddBoolToObject(vfo_node, "ptt", ptt == RIG_PTT_OFF ? 0 : 1);
|
||||
else
|
||||
node = cJSON_AddBoolToObject(vfo_node, "ptt", 0);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
split = rig->state.cache.split;
|
||||
split_vfo = rig->state.cache.split_vfo;
|
||||
|
||||
is_rx = (split == RIG_SPLIT_OFF && vfo == rig->state.current_vfo)
|
||||
|| (split == RIG_SPLIT_ON && vfo != split_vfo);
|
||||
node = cJSON_AddBoolToObject(vfo_node, "rx", is_rx);
|
||||
|
||||
if (node == NULL)
|
||||
|
@ -181,8 +174,6 @@ static int snapshot_serialize_vfo(cJSON *vfo_node, RIG *rig, vfo_t vfo)
|
|||
goto error;
|
||||
}
|
||||
|
||||
is_tx = (split == RIG_SPLIT_OFF && vfo == rig->state.current_vfo)
|
||||
|| (split == RIG_SPLIT_ON && vfo == split_vfo);
|
||||
node = cJSON_AddBoolToObject(vfo_node, "tx", is_tx);
|
||||
|
||||
if (node == NULL)
|
||||
|
@ -325,6 +316,11 @@ error:
|
|||
RETURNFUNC2(-RIG_EINTERNAL);
|
||||
}
|
||||
|
||||
void snapshot_init()
|
||||
{
|
||||
snprintf(snapshot_data_pid, sizeof(snapshot_data_pid), "%d", getpid());
|
||||
}
|
||||
|
||||
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig,
|
||||
struct rig_spectrum_line *spectrum_line)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _SNAPSHOT_DATA_H
|
||||
#define _SNAPSHOT_DATA_H
|
||||
|
||||
void snapshot_init();
|
||||
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line);
|
||||
|
||||
#endif
|
||||
|
|
11
src/token.h
11
src/token.h
|
@ -97,6 +97,8 @@
|
|||
#define TOK_TUNER_CONTROL_PATHNAME TOKEN_FRONTEND(38)
|
||||
/** \brief Number of retries permitted in case of read timeouts */
|
||||
#define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39)
|
||||
#define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40)
|
||||
#define TOK_DEVICE_ID TOKEN_FRONTEND(41)
|
||||
|
||||
/*
|
||||
* rig specific tokens
|
||||
|
@ -131,6 +133,15 @@
|
|||
#define TOK_OFFSET_VFOA TOKEN_FRONTEND(130)
|
||||
/** \brief rig: Add Hz to VFOB/Sub frequency set */
|
||||
#define TOK_OFFSET_VFOB TOKEN_FRONTEND(131)
|
||||
/** \brief rig: Multicast data UDP address for publishing rig data and state, default 224.0.0.1, value of 0.0.0.0 disables multicast data publishing */
|
||||
#define TOK_MULTICAST_DATA_ADDR TOKEN_FRONTEND(132)
|
||||
/** \brief rig: Multicast data UDP port, default 4532 */
|
||||
#define TOK_MULTICAST_DATA_PORT TOKEN_FRONTEND(133)
|
||||
/** \brief rig: Multicast command server UDP address for sending commands to rig, default 224.0.0.2, value of 0.0.0.0 disables multicast command server */
|
||||
#define TOK_MULTICAST_CMD_ADDR TOKEN_FRONTEND(134)
|
||||
/** \brief rig: Multicast command server UDP port, default 4532 */
|
||||
#define TOK_MULTICAST_CMD_PORT TOKEN_FRONTEND(135)
|
||||
|
||||
/*
|
||||
* rotator specific tokens
|
||||
* (strictly, should be documented as rotator_internal)
|
||||
|
|
|
@ -19,8 +19,8 @@ bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom rig
|
|||
#check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid testsecurity
|
||||
check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels testmW2power
|
||||
|
||||
RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h
|
||||
ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h
|
||||
RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h dumpcaps.h
|
||||
ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h dumpcaps_rot.h
|
||||
AMPCOMMONSRC = ampctl_parse.c ampctl_parse.h dumpcaps_amp.c uthash.h
|
||||
|
||||
rigctl_SOURCES = rigctl.c $(RIGCOMMONSRC)
|
||||
|
|
|
@ -298,12 +298,28 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_amp, conf_parms);
|
||||
char *token=strtok(conf_parms,",");
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = amp_token_lookup(my_amp,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = amp_set_conf(my_amp, amp_token_lookup(my_amp,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (amp_file)
|
||||
|
|
|
@ -1630,7 +1630,7 @@ int set_conf(AMP *my_amp, char *conf_parms)
|
|||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_WARN, "%s: invalid token %s for this rig\n", __func__, p);
|
||||
rig_debug(RIG_DEBUG_WARN, "%s: invalid token %s for this amp\n", __func__, p);
|
||||
}
|
||||
|
||||
p = n;
|
||||
|
|
|
@ -323,17 +323,30 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
#if 0
|
||||
retcode = set_conf(my_amp, conf_parms);
|
||||
char *token=strtok(conf_parms,",");
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = amp_token_lookup(my_amp,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = amp_set_conf(my_amp, amp_token_lookup(my_amp,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (amp_file)
|
||||
{
|
||||
strncpy(my_amp->state.ampport.pathname, amp_file, HAMLIB_FILPATHLEN - 1);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "sprintflst.h"
|
||||
#include "rigctl_parse.h"
|
||||
#include "../rigs/icom/icom.h"
|
||||
#include "dumpcaps.h"
|
||||
|
||||
void range_print(FILE *fout, const struct freq_range_list range_list[], int rx);
|
||||
int range_sanity_check(const struct freq_range_list range_list[], int rx);
|
||||
|
@ -1255,3 +1256,15 @@ int dumpconf(RIG *rig, FILE *fout)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dumpconf_list(RIG *rig, FILE *fout)
|
||||
{
|
||||
rig_token_foreach(rig, print_conf_list2, (rig_ptr_t)rig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dumpconf_list_rot(ROT *rot, FILE *fout)
|
||||
{
|
||||
rot_token_foreach(rot, print_conf_list2, rot);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#include <hamlib/rig.h>
|
||||
|
||||
int dumpconf_list(RIG *rig, FILE *fout);
|
|
@ -242,3 +242,10 @@ int dumpcaps_rot(ROT *rot, FILE *fout)
|
|||
|
||||
return backend_warnings;
|
||||
}
|
||||
|
||||
int dumpconf_list(ROT *rot, FILE *fout)
|
||||
{
|
||||
rot_token_foreach(rot, print_conf_list, rot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#include <hamlib/rig.h>
|
||||
|
||||
int dumpconf_list(ROT *rot, FILE *fout);
|
180
tests/rigctl.c
180
tests/rigctl.c
|
@ -30,6 +30,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
# if defined(HAVE_READLINE_READLINE_H)
|
||||
|
@ -113,11 +114,86 @@ static struct option long_options[] =
|
|||
extern char rig_resp_sep;
|
||||
extern powerstat_t rig_powerstat;
|
||||
|
||||
static RIG *my_rig; /* handle to rig (instance) */
|
||||
|
||||
#ifdef HAVE_SIG_ATOMIC_T
|
||||
static sig_atomic_t volatile ctrl_c = 0;
|
||||
#else
|
||||
static int volatile ctrl_c = 0;
|
||||
#endif
|
||||
|
||||
#define MAXCONFLEN 2048
|
||||
|
||||
#ifdef WIN32
|
||||
static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__);
|
||||
|
||||
switch (fdwCtrlType)
|
||||
{
|
||||
case CTRL_C_EVENT:
|
||||
case CTRL_CLOSE_EVENT:
|
||||
ctrl_c = 1;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void signal_handler(int sig)
|
||||
{
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
|
||||
// Close stdin to stop reading input
|
||||
fclose(stdin);
|
||||
ctrl_c = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_error(enum rig_debug_level_e lvl, const char *msg)
|
||||
{
|
||||
int e;
|
||||
#ifdef __MINGW32__
|
||||
LPVOID lpMsgBuf;
|
||||
|
||||
lpMsgBuf = (LPVOID)"Unknown error";
|
||||
e = WSAGetLastError();
|
||||
|
||||
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, e,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
// Default language
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL))
|
||||
{
|
||||
|
||||
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
rig_debug(lvl, "%s: Network error %d\n", msg, e);
|
||||
}
|
||||
|
||||
#else
|
||||
e = errno;
|
||||
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e));
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
RIG *my_rig; /* handle to rig (instance) */
|
||||
rig_model_t my_model = RIG_MODEL_DUMMY;
|
||||
|
||||
int retcode; /* generic return code from functions */
|
||||
|
@ -151,6 +227,9 @@ int main(int argc, char *argv[])
|
|||
char rigstartup[1024];
|
||||
char vbuf[1024];
|
||||
rig_powerstat = RIG_POWER_ON; // defaults to power on
|
||||
#if HAVE_SIGACTION
|
||||
struct sigaction act;
|
||||
#endif
|
||||
|
||||
int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf));
|
||||
|
||||
|
@ -476,12 +555,28 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rig, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
char *token=strtok(conf_parms,",");
|
||||
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = rig_token_lookup(my_rig,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = rig_set_conf(my_rig, rig_token_lookup(my_rig,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (rig_file)
|
||||
|
@ -648,6 +743,77 @@ int main(int argc, char *argv[])
|
|||
#endif /* HAVE_LIBREADLINE */
|
||||
int rig_opened = 1; // our rig is already open
|
||||
|
||||
#if HAVE_SIGACTION
|
||||
|
||||
#ifdef SIGPIPE
|
||||
/* Ignore SIGPIPE as we will handle it at the write()/send() calls
|
||||
that will consequently fail with EPIPE. All child threads will
|
||||
inherit this disposition which is what we want. */
|
||||
memset(&act, 0, sizeof act);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_flags = SA_RESTART;
|
||||
|
||||
if (sigaction(SIGPIPE, &act, NULL))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SIGINT
|
||||
memset(&act, 0, sizeof act);
|
||||
act.sa_handler = signal_handler;
|
||||
|
||||
if (sigaction(SIGINT, &act, NULL))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
memset(&act, 0, sizeof act);
|
||||
act.sa_handler = signal_handler;
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
|
||||
}
|
||||
|
||||
#endif
|
||||
#elif defined (WIN32)
|
||||
|
||||
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler");
|
||||
}
|
||||
|
||||
#elif HAVE_SIGNAL
|
||||
#ifdef SIGPIPE
|
||||
|
||||
if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "signal SIGPIPE");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SIGINT
|
||||
|
||||
if (SIG_ERR == signal(SIGINT, signal_handler))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "signal SIGINT");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
|
||||
if (SIG_ERR == signal(SIGTERM, signal_handler))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
if (!rig_opened)
|
||||
|
@ -695,7 +861,7 @@ int main(int argc, char *argv[])
|
|||
while (retry-- > 0 && retcode != RIG_OK);
|
||||
}
|
||||
}
|
||||
while (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode));
|
||||
while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode)));
|
||||
|
||||
if (interactive && prompt)
|
||||
{
|
||||
|
|
|
@ -270,6 +270,8 @@ declare_proto_rig(hamlib_version);
|
|||
declare_proto_rig(test);
|
||||
declare_proto_rig(cm108_get_bit);
|
||||
declare_proto_rig(cm108_set_bit);
|
||||
declare_proto_rig(set_conf);
|
||||
declare_proto_rig(get_conf);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -390,6 +392,8 @@ static struct test_table test_list[] =
|
|||
{ 0xa8, "hamlib_version", ACTION(hamlib_version), ARG_NOVFO },
|
||||
{ 0xa9, "get_gpio", ACTION(cm108_get_bit), ARG_NOVFO | ARG_IN1 | ARG_OUT1, "GPIO#", "0/1" },
|
||||
{ 0xaa, "set_gpio", ACTION(cm108_set_bit), ARG_NOVFO | ARG_IN , "GPIO#", "0/1" },
|
||||
{ 0xac, "set_conf", ACTION(set_conf), ARG_NOVFO | ARG_IN , "Token", "Token Value" },
|
||||
{ 0xad, "get_conf", ACTION(get_conf), ARG_NOVFO | ARG_IN1 | ARG_OUT2, "Token", "Value"},
|
||||
{ 0x00, "", NULL },
|
||||
};
|
||||
|
||||
|
@ -1989,6 +1993,21 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data)
|
|||
return 1; /* !=0, we want them all ! */
|
||||
}
|
||||
|
||||
// short list for rigctl/rigctld display
|
||||
int print_conf_list2(const struct confparams *cfp, rig_ptr_t data)
|
||||
{
|
||||
RIG *rig = (RIG *) data;
|
||||
char buf[128] = "";
|
||||
|
||||
rig_get_conf(rig, cfp->token, buf);
|
||||
fprintf(stdout,"%s: \"%s\"\n" "\t" "Default: %s, Value: %s\n",
|
||||
cfp->name,
|
||||
cfp->tooltip,
|
||||
cfp->dflt,
|
||||
buf);
|
||||
|
||||
return 1; /* !=0, we want them all ! */
|
||||
}
|
||||
|
||||
static int hash_model_list(const struct rig_caps *caps, void *data)
|
||||
{
|
||||
|
@ -2040,58 +2059,6 @@ void list_models()
|
|||
hash_delete_all();
|
||||
}
|
||||
|
||||
|
||||
int set_conf(RIG *my_rig, char *conf_parms)
|
||||
{
|
||||
char *p, *n;
|
||||
int token;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
p = conf_parms;
|
||||
|
||||
while (p && *p != '\0')
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* FIXME: left hand value of = cannot be null */
|
||||
char *q = strchr(p, '=');
|
||||
|
||||
if (!q)
|
||||
{
|
||||
return (-RIG_EINVAL);
|
||||
}
|
||||
|
||||
*q++ = '\0';
|
||||
n = strchr(q, ',');
|
||||
|
||||
if (n)
|
||||
{
|
||||
*n++ = '\0';
|
||||
}
|
||||
|
||||
token = rig_token_lookup(my_rig, p);
|
||||
|
||||
if (token != 0)
|
||||
{
|
||||
ret = rig_set_conf(my_rig, rig_token_lookup(my_rig, p), q);
|
||||
|
||||
if (ret != RIG_OK)
|
||||
{
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_WARN, "%s: invalid token %s for this rig\n", __func__, p);
|
||||
}
|
||||
|
||||
p = n;
|
||||
}
|
||||
|
||||
return (RIG_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* static int (f)(RIG *rig, FILE *fout, int interactive, const struct test_table *cmd,
|
||||
* vfo_t vfo, const void *arg1, const void *arg2, const void *arg3)
|
||||
|
@ -5790,3 +5757,62 @@ declare_proto_rig(cm108_set_bit)
|
|||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
declare_proto_rig(get_conf)
|
||||
{
|
||||
int ret;
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: \n", __func__);
|
||||
if (arg1 == NULL || arg1[0] == '?')
|
||||
{
|
||||
dumpconf_list(rig, stdout);
|
||||
debugmsgsave[0] = 0;
|
||||
debugmsgsave2[0] = 0;
|
||||
return RIG_OK;
|
||||
}
|
||||
token_t mytoken = rig_token_lookup(rig, arg1);
|
||||
if (mytoken == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rig\n", __func__, arg1);
|
||||
ret = -RIG_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char value[4096]; // no max value known -- should we limit it?
|
||||
ret = rig_get_conf(rig, mytoken, value);
|
||||
if (ret != RIG_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
fprintf(fout, "%s=%s\n", arg1, value);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
declare_proto_rig(set_conf)
|
||||
{
|
||||
int ret;
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
|
||||
if (arg1[0] == '?')
|
||||
{
|
||||
dumpconf_list(rig, fout);
|
||||
debugmsgsave[0] = 0;
|
||||
debugmsgsave2[0] = 0;
|
||||
return RIG_OK;
|
||||
}
|
||||
token_t mytoken = rig_token_lookup(rig, arg1);
|
||||
if (mytoken == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rig\n", __func__, arg1);
|
||||
ret = -RIG_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = rig_set_conf(rig, rig_token_lookup(rig, arg1), arg2);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
int dumpcaps(RIG *, FILE *);
|
||||
int dumpstate(RIG *, FILE *);
|
||||
int dumpconf(RIG *, FILE *);
|
||||
int dumpconf_list(RIG *, FILE *);
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
|
@ -47,6 +48,7 @@ void version();
|
|||
void list_models();
|
||||
int dump_chan(FILE *, RIG *, channel_t *);
|
||||
int print_conf_list(const struct confparams *cfp, rig_ptr_t data);
|
||||
int print_conf_list2(const struct confparams *cfp, rig_ptr_t data);
|
||||
int set_conf(RIG *my_rig, char *conf_parms);
|
||||
|
||||
typedef void (*sync_cb_t)(int);
|
||||
|
|
|
@ -492,7 +492,8 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rig, conf_parms);
|
||||
retcode = -RIG_ENIMPL;
|
||||
// retcode = set_conf(my_rig, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
|
|
100
tests/rigctld.c
100
tests/rigctld.c
|
@ -105,8 +105,6 @@ static struct option long_options[] =
|
|||
{"twiddle_rit", 1, 0, 'w'},
|
||||
{"uplink", 1, 0, 'x'},
|
||||
{"debug-time-stamps", 0, 0, 'Z'},
|
||||
{"multicast-addr", 1, 0, 'M'},
|
||||
{"multicast-port", 1, 0, 'n'},
|
||||
{"password", 1, 0, 'A'},
|
||||
{"rigctld-idle", 0, 0, 'R'},
|
||||
{"bind-all", 0, 0, 'b'},
|
||||
|
@ -138,15 +136,13 @@ static volatile int rig_opened = 0;
|
|||
static int verbose;
|
||||
|
||||
#ifdef HAVE_SIG_ATOMIC_T
|
||||
static sig_atomic_t volatile ctrl_c;
|
||||
static sig_atomic_t volatile ctrl_c = 0;
|
||||
#else
|
||||
static int volatile ctrl_c;
|
||||
static int volatile ctrl_c = 0;
|
||||
#endif
|
||||
|
||||
const char *portno = "4532";
|
||||
const char *src_addr = NULL; /* INADDR_ANY */
|
||||
const char *multicast_addr = "0.0.0.0";
|
||||
int multicast_port = 4532;
|
||||
extern char rigctld_password[65];
|
||||
char resp_sep = '\n';
|
||||
extern int lock_mode;
|
||||
|
@ -200,6 +196,10 @@ static void signal_handler(int sig)
|
|||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
|
||||
// Close stdin to stop reading input
|
||||
fclose(stdin);
|
||||
ctrl_c = 1;
|
||||
break;
|
||||
|
||||
|
@ -618,33 +618,6 @@ int main(int argc, char *argv[])
|
|||
rig_set_debug_time_stamp(1);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
multicast_addr = optarg;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
multicast_port = atoi(optarg);
|
||||
|
||||
if (multicast_port == 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid multicast port: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(); /* unknown option? */
|
||||
exit(1);
|
||||
|
@ -686,13 +659,28 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "Please check with --list option.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rig, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
|
||||
char *token=strtok(conf_parms,",");
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = rig_token_lookup(my_rig,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = rig_set_conf(my_rig, rig_token_lookup(my_rig,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (rig_file)
|
||||
|
@ -867,18 +855,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
saved_result = result;
|
||||
|
||||
enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE |
|
||||
RIG_MULTICAST_SPECTRUM;
|
||||
retcode = network_multicast_publisher_start(my_rig, multicast_addr,
|
||||
multicast_port, items);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_server failed: %s\n", __FILE__,
|
||||
rigerror(retcode));
|
||||
// we will consider this non-fatal for now
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
sock_listen = socket(result->ai_family,
|
||||
|
@ -992,6 +968,16 @@ int main(int argc, char *argv[])
|
|||
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
memset(&act, 0, sizeof act);
|
||||
act.sa_handler = signal_handler;
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
|
||||
}
|
||||
|
||||
#endif
|
||||
#elif defined (WIN32)
|
||||
|
||||
|
@ -1016,6 +1002,14 @@ int main(int argc, char *argv[])
|
|||
handle_error(RIG_DEBUG_ERR, "signal SIGINT");
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
|
||||
if (SIG_ERR == signal(SIGTERM, signal_handler))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1148,8 +1142,6 @@ int main(int argc, char *argv[])
|
|||
rig_close(my_rig); /* close port */
|
||||
#endif
|
||||
|
||||
network_multicast_publisher_stop(my_rig);
|
||||
|
||||
rig_cleanup(my_rig); /* if you care about memory */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
@ -1464,8 +1456,6 @@ void usage(void)
|
|||
" -w, --twiddle_rit suppress VFOB getfreq so RIT can be twiddled\n"
|
||||
" -x, --uplink set uplink get_freq ignore, 1=Sub, 2=Main\n"
|
||||
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
|
||||
" -M, --multicast-addr=addr set multicast UDP address, default 0.0.0.0 (off), recommend 224.0.1.1\n"
|
||||
" -n, --multicast-port=port set multicast UDP port, default 4532\n"
|
||||
" -A, --password set password for rigctld access\n"
|
||||
" -R, --rigctld-idle make rigctld close the rig when no clients are connected\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
|
|
|
@ -674,7 +674,8 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rig, conf_parms);
|
||||
retcode = -RIG_ENIMPL;
|
||||
// retcode = set_conf(my_rig, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
|
|
|
@ -339,12 +339,28 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rot, conf_parms);
|
||||
char *token=strtok(conf_parms,",");
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = rot_token_lookup(my_rot,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s', use -L switch to see\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = rot_set_conf(my_rot, rot_token_lookup(my_rot,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (rot_file)
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
// TODO: Add "symmetric" set_conf + get_conf to rigctl+rotctl
|
||||
|
||||
#include <hamlib/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -65,7 +63,7 @@ extern int read_history();
|
|||
#include <hamlib/rotator.h>
|
||||
#include "iofunc.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "dumpcaps_rot.h"
|
||||
|
||||
/* HAVE_SSLEEP is defined when Windows Sleep is found
|
||||
* HAVE_SLEEP is defined when POSIX sleep is found
|
||||
|
@ -189,10 +187,12 @@ declare_proto_rot(set_parm);
|
|||
declare_proto_rot(get_parm);
|
||||
declare_proto_rot(get_info);
|
||||
declare_proto_rot(get_status);
|
||||
declare_proto_rot(inter_set_conf); /* interactive mode set_conf */
|
||||
declare_proto_rot(set_conf);
|
||||
declare_proto_rot(get_conf);
|
||||
declare_proto_rot(send_cmd);
|
||||
declare_proto_rot(dump_state);
|
||||
declare_proto_rot(dump_caps);
|
||||
declare_proto_rot(dump_conf);
|
||||
/* Follows are functions from locator.c */
|
||||
declare_proto_rot(loc2lonlat);
|
||||
declare_proto_rot(lonlat2loc);
|
||||
|
@ -224,11 +224,12 @@ struct test_table test_list[] =
|
|||
{ 'u', "get_func", ACTION(get_func), ARG_IN1 | ARG_OUT2, "Func", "Func Status" },
|
||||
{ 'X', "set_parm", ACTION(set_parm), ARG_IN, "Parm", "Parm Value" },
|
||||
{ 'x', "get_parm", ACTION(get_parm), ARG_IN1 | ARG_OUT2, "Parm", "Parm Value" },
|
||||
{ 'C', "set_conf", ACTION(inter_set_conf), ARG_IN, "Token", "Value" },
|
||||
{ 'C', "set_conf", ACTION(set_conf), ARG_IN, "Token", "Value" },
|
||||
{ '_', "get_info", ACTION(get_info), ARG_OUT, "Info" },
|
||||
{ 's', "get_status", ACTION(get_status), ARG_OUT, "Status flags" },
|
||||
{ 'w', "send_cmd", ACTION(send_cmd), ARG_IN1 | ARG_IN_LINE | ARG_OUT2, "Cmd", "Reply" },
|
||||
{ '1', "dump_caps", ACTION(dump_caps), },
|
||||
{ '3', "dump_conf", ACTION(dump_conf), },
|
||||
{ 0x8f, "dump_state", ACTION(dump_state), ARG_OUT },
|
||||
{ 'L', "lonlat2loc", ACTION(lonlat2loc), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_OUT1, "Longitude", "Latitude", "Loc Len [2-12]", "Locator" },
|
||||
{ 'l', "loc2lonlat", ACTION(loc2lonlat), ARG_IN1 | ARG_OUT1 | ARG_OUT2, "Locator", "Longitude", "Latitude" },
|
||||
|
@ -240,6 +241,7 @@ struct test_table test_list[] =
|
|||
{ 'A', "a_sp2a_lp", ACTION(az_sp2az_lp), ARG_IN1 | ARG_OUT1, "Short Path Deg", "Long Path Deg" },
|
||||
{ 'a', "d_sp2d_lp", ACTION(dist_sp2dist_lp), ARG_IN1 | ARG_OUT1, "Short Path km", "Long Path km" },
|
||||
{ 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" },
|
||||
{ 0xad, "get_conf", ACTION(get_conf), ARG_IN1 | ARG_OUT2, "Token", "Value"},
|
||||
{ 0x00, "", NULL },
|
||||
|
||||
};
|
||||
|
@ -1574,7 +1576,7 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data)
|
|||
char buf[128] = "";
|
||||
|
||||
rot_get_conf2(rot, cfp->token, buf, sizeof(buf));
|
||||
printf("%s: \"%s\"\n" "\tDefault: %s, Value: %s\n",
|
||||
fprintf(stdout,"%s: \"%s\"\n" "\tDefault: %s, Value: %s\n",
|
||||
cfp->name,
|
||||
cfp->tooltip,
|
||||
cfp->dflt,
|
||||
|
@ -1583,14 +1585,14 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data)
|
|||
switch (cfp->type)
|
||||
{
|
||||
case RIG_CONF_NUMERIC:
|
||||
printf("\tRange: %.1f..%.1f, step %.1f\n",
|
||||
fprintf(stdout,"\tRange: %.1f..%.1f, step %.1f\n",
|
||||
cfp->u.n.min,
|
||||
cfp->u.n.max,
|
||||
cfp->u.n.step);
|
||||
break;
|
||||
|
||||
case RIG_CONF_CHECKBUTTON:
|
||||
printf("\tCheckbox: 0,1\n");
|
||||
fprintf(stdout,"\tCheckbox: 0,1\n");
|
||||
break;
|
||||
|
||||
case RIG_CONF_COMBO:
|
||||
|
@ -1599,14 +1601,14 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data)
|
|||
break;
|
||||
}
|
||||
|
||||
printf("\tCombo: %s", cfp->u.c.combostr[0]);
|
||||
fprintf(stdout,"\tCombo: %s", cfp->u.c.combostr[0]);
|
||||
|
||||
for (i = 1 ; i < RIG_COMBO_MAX && cfp->u.c.combostr[i]; i++)
|
||||
{
|
||||
printf(", %s", cfp->u.c.combostr[i]);
|
||||
fprintf(stdout,", %s", cfp->u.c.combostr[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
fprintf(stdout,"\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1666,55 +1668,64 @@ void list_models()
|
|||
hash_delete_all();
|
||||
}
|
||||
|
||||
|
||||
int set_conf(ROT *my_rot, char *conf_parms)
|
||||
declare_proto_rot(get_conf)
|
||||
{
|
||||
char *p;
|
||||
|
||||
rot_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
p = conf_parms;
|
||||
|
||||
while (p && *p != '\0')
|
||||
int ret;
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: \n", __func__);
|
||||
if (arg1 == NULL || arg1[0] == '?')
|
||||
{
|
||||
int token;
|
||||
char *q, *n = NULL;
|
||||
/* FIXME: left hand value of = cannot be null */
|
||||
q = strchr(p, '=');
|
||||
|
||||
if (!q)
|
||||
dumpconf_list(rot, fout);
|
||||
debugmsgsave[0] = 0;
|
||||
debugmsgsave2[0] = 0;
|
||||
return RIG_OK;
|
||||
}
|
||||
token_t mytoken = rot_token_lookup(rot, arg1);
|
||||
if (mytoken == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rot\n", __func__, arg1);
|
||||
ret = -RIG_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char value[4096];
|
||||
ret = rot_get_conf(rot, rot_token_lookup(rot, arg1), value);
|
||||
if (ret != RIG_OK)
|
||||
{
|
||||
return RIG_EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*q++ = '\0';
|
||||
n = strchr(q, ',');
|
||||
|
||||
if (n)
|
||||
{
|
||||
*n++ = '\0';
|
||||
}
|
||||
|
||||
token = rot_token_lookup(my_rot, p);
|
||||
|
||||
if (token != 0)
|
||||
{
|
||||
int ret;
|
||||
ret = rot_set_conf(my_rot, token, q);
|
||||
|
||||
if (ret != RIG_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_WARN, "%s: invalid token %s for this rig\n", __func__, p);
|
||||
}
|
||||
|
||||
p = n;
|
||||
fprintf(fout, "%s=%s\n", arg1, value);
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/* 'C' */
|
||||
declare_proto_rot(set_conf)
|
||||
{
|
||||
int ret;
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
if (arg1[0] == '?')
|
||||
{
|
||||
dumpconf_list(rot, fout);
|
||||
debugmsgsave[0] = 0;
|
||||
debugmsgsave2[0] = 0;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
token_t mytoken = rot_token_lookup(rot, arg1);
|
||||
if (mytoken == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rot\n", __func__, arg1);
|
||||
ret = -RIG_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = rot_set_conf(rot, rot_token_lookup(rot, arg1), arg2);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2344,6 +2355,7 @@ declare_proto_rot(get_parm)
|
|||
}
|
||||
|
||||
|
||||
#if 0 // replace by set_conf
|
||||
/* 'C' */
|
||||
declare_proto_rot(inter_set_conf)
|
||||
{
|
||||
|
@ -2361,6 +2373,7 @@ declare_proto_rot(inter_set_conf)
|
|||
SNPRINTF(buf, sizeof(buf), "%s=%s", arg1, arg2);
|
||||
return set_conf(rot, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* '1' */
|
||||
declare_proto_rot(dump_caps)
|
||||
|
@ -2370,6 +2383,14 @@ declare_proto_rot(dump_caps)
|
|||
return RIG_OK;
|
||||
}
|
||||
|
||||
declare_proto_rot(dump_conf)
|
||||
{
|
||||
ENTERFUNC2;
|
||||
|
||||
dumpconf_list(rot, fout);
|
||||
|
||||
RETURNFUNC2(RIG_OK);
|
||||
}
|
||||
|
||||
/* For rotctld internal use
|
||||
* '0x8f'
|
||||
|
@ -2862,3 +2883,20 @@ declare_proto_rot(pause)
|
|||
sleep(seconds);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
// short list for rigctl/rigctld display
|
||||
int print_conf_list2(const struct confparams *cfp, rig_ptr_t data, FILE *fout)
|
||||
{
|
||||
ROT *rot = (ROT *) data;
|
||||
char buf[128] = "";
|
||||
|
||||
rot_get_conf(rot, cfp->token, buf);
|
||||
fprintf(fout,"%s: \"%s\"\n" "\t" "Default: %s, Value: %s\n",
|
||||
cfp->name,
|
||||
cfp->tooltip,
|
||||
cfp->dflt,
|
||||
buf);
|
||||
|
||||
return 1; /* !=0, we want them all ! */
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ void usage_rot(FILE *);
|
|||
void version();
|
||||
void list_models();
|
||||
int print_conf_list(const struct confparams *cfp, rig_ptr_t data);
|
||||
int print_conf_list2(const struct confparams *cfp, rig_ptr_t data, FILE *fout);
|
||||
int set_conf(ROT *my_rot, char *conf_parms);
|
||||
|
||||
int rotctl_parse(ROT *my_rot, FILE *fin, FILE *fout, const char **argv, int argc,
|
||||
|
|
|
@ -345,12 +345,28 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_rot, conf_parms);
|
||||
char *token=strtok(conf_parms,",");
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
while(token)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
char mytoken[100], myvalue[100];
|
||||
token_t lookup;
|
||||
sscanf(token,"%99[^=]=%99s", mytoken, myvalue);
|
||||
//printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue);
|
||||
lookup = rot_token_lookup(my_rot,mytoken);
|
||||
if (lookup == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s', use -L switch to see\n", __func__, mytoken);
|
||||
token = strtok(NULL, ",");
|
||||
continue;
|
||||
}
|
||||
retcode = rot_set_conf(my_rot, rot_token_lookup(my_rot,mytoken), myvalue);
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (rot_file)
|
||||
|
|
Ładowanie…
Reference in New Issue