Add get_status command for rotator status flags. Add missing rotator caps in dumpcaps output.

(cherry picked from commit 457211a7e3)
Hamlib-4.0
Mikael Nousiainen 2020-12-03 21:40:34 +02:00 zatwierdzone przez Nate Bargmann
rodzic 2e9922b824
commit aa9caf574e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: F72625E2EDBED598
10 zmienionych plików z 270 dodań i 57 usunięć

Wyświetl plik

@ -397,6 +397,10 @@ extern HAMLIB_EXPORT(const char *) amp_strlevel(setting_t);
extern HAMLIB_EXPORT(const struct confparams *)
rig_ext_lookup HAMLIB_PARAMS((RIG *rig,
const char *name));
extern HAMLIB_EXPORT(setting_t) amp_parse_level(const char *s);
extern HAMLIB_EXPORT(const char *) amp_strlevel(setting_t);
//! @endcond

Wyświetl plik

@ -2787,16 +2787,6 @@ extern HAMLIB_EXPORT(scan_t) rig_parse_scan(const char *s);
extern HAMLIB_EXPORT(rptr_shift_t) rig_parse_rptr_shift(const char *s);
extern HAMLIB_EXPORT(chan_type_t) rig_parse_mtype(const char *s);
extern HAMLIB_EXPORT(setting_t) rot_parse_func(const char *s);
extern HAMLIB_EXPORT(setting_t) rot_parse_level(const char *s);
extern HAMLIB_EXPORT(setting_t) rot_parse_parm(const char *s);
extern HAMLIB_EXPORT(const char *) rot_strfunc(setting_t);
extern HAMLIB_EXPORT(const char *) rot_strlevel(setting_t);
extern HAMLIB_EXPORT(const char *) rot_strparm(setting_t);
extern HAMLIB_EXPORT(setting_t) amp_parse_level(const char *s);
extern HAMLIB_EXPORT(const char *) amp_strlevel(setting_t);
extern HAMLIB_EXPORT(const char *) rig_license HAMLIB_PARAMS(());
extern HAMLIB_EXPORT(const char *) rig_version HAMLIB_PARAMS(());
extern HAMLIB_EXPORT(const char *) rig_copyright HAMLIB_PARAMS(());

Wyświetl plik

@ -200,20 +200,27 @@ typedef enum {
* \brief Rotator status flags
*/
typedef enum {
ROT_STATUS_BUSY = (1 << 1), /*!< Rotator is busy, not accepting commands */
ROT_STATUS_MOVING = (1 << 2), /*!< Rotator is currently moving (direction type not specified) */
ROT_STATUS_MOVING_AZ = (1 << 3), /*!< Azimuth rotator is currently moving */
ROT_STATUS_MOVING_EL = (1 << 4), /*!< Elevation rotator is currently moving */
ROT_STATUS_UP_LIMIT = (1 << 5), /*!< The elevation rotator has reached its limit to move up */
ROT_STATUS_DOWN_LIMIT = (1 << 6), /*!< The elevation rotator has reached its limit to move down */
ROT_STATUS_LEFT_LIMIT = (1 << 7), /*!< The azimuth rotator has reached its limit to move left (CCW) */
ROT_STATUS_RIGHT_LIMIT = (1 << 8), /*!< The azimuth rotator has reached its limit to move right (CW) */
ROT_STATUS_UP_OVERLAP = (1 << 9), /*!< The elevation rotator has rotated up past 360 degrees */
ROT_STATUS_DOWN_OVERLAP = (1 << 10), /*!< The elevation rotator has rotated down past 0 degrees */
ROT_STATUS_LEFT_OVERLAP = (1 << 11), /*!< The azimuth rotator has rotated left (CCW) past 0 degrees */
ROT_STATUS_RIGHT_OVERLAP = (1 << 12), /*!< The azimuth rotator has rotated right (CW) past 360 degrees */
ROT_STATUS_NONE = 0,
ROT_STATUS_BUSY = (1 << 0), /*!< Rotator is busy, not accepting commands */
ROT_STATUS_MOVING = (1 << 1), /*!< Rotator is currently moving (direction type not specified) */
ROT_STATUS_MOVING_AZ = (1 << 2), /*!< Azimuth rotator is currently moving (direction not specified) */
ROT_STATUS_MOVING_LEFT = (1 << 3), /*!< Azimuth rotator is currently moving left */
ROT_STATUS_MOVING_RIGHT = (1 << 4), /*!< Azimuth rotator is currently moving right */
ROT_STATUS_MOVING_EL = (1 << 5), /*!< Elevation rotator is currently moving (direction not specified) */
ROT_STATUS_MOVING_UP = (1 << 6), /*!< Elevation rotator is currently moving up */
ROT_STATUS_MOVING_DOWN = (1 << 7), /*!< Elevation rotator is currently moving down */
ROT_STATUS_LIMIT_UP = (1 << 8), /*!< The elevation rotator has reached its limit to move up */
ROT_STATUS_LIMIT_DOWN = (1 << 9), /*!< The elevation rotator has reached its limit to move down */
ROT_STATUS_LIMIT_LEFT = (1 << 10), /*!< The azimuth rotator has reached its limit to move left (CCW) */
ROT_STATUS_LIMIT_RIGHT = (1 << 11), /*!< The azimuth rotator has reached its limit to move right (CW) */
ROT_STATUS_OVERLAP_UP = (1 << 12), /*!< The elevation rotator has rotated up past 360 degrees */
ROT_STATUS_OVERLAP_DOWN = (1 << 13), /*!< The elevation rotator has rotated down past 0 degrees */
ROT_STATUS_OVERLAP_LEFT = (1 << 14), /*!< The azimuth rotator has rotated left (CCW) past 0 degrees */
ROT_STATUS_OVERLAP_RIGHT = (1 << 16), /*!< The azimuth rotator has rotated right (CW) past 360 degrees */
} rot_status_t;
#define ROT_STATUS_N(n) (1u<<(n))
/**
* \brief Macro for not changing the rotator speed with move() function
@ -339,6 +346,8 @@ struct rot_caps {
setting_t has_get_parm; /*!< List of get parm */
setting_t has_set_parm; /*!< List of set parm */
rot_status_t has_status; /*!< Supported status flags */
gran_t level_gran[RIG_SETTING_MAX]; /*!< level granularity (i.e. steps) */
gran_t parm_gran[RIG_SETTING_MAX]; /*!< parm granularity (i.e. steps) */
@ -409,12 +418,9 @@ struct rot_caps {
int (*set_ext_parm)(ROT *rot, token_t token, value_t val);
int (*get_ext_parm)(ROT *rot, token_t token, value_t *val);
int (*get_status)(ROT *rot, rot_status_t *status);
const char *macro_name; /*!< Macro name. */
rot_status_t status_caps; /*!< Supported status flags */
rot_status_t (*get_status)(ROT *rot);
/* more to come... */
};
//! @endcond
@ -449,6 +455,8 @@ struct rot_state {
setting_t has_get_parm; /*!< List of get parm */
setting_t has_set_parm; /*!< List of set parm */
rot_status_t has_status; /*!< Supported status flags */
gran_t level_gran[RIG_SETTING_MAX]; /*!< level granularity */
gran_t parm_gran[RIG_SETTING_MAX]; /*!< parm granularity */
@ -614,6 +622,10 @@ rot_get_ext_parm HAMLIB_PARAMS((ROT *rig,
extern HAMLIB_EXPORT(const char *)
rot_get_info HAMLIB_PARAMS((ROT *rot));
extern HAMLIB_EXPORT(int)
rot_get_status HAMLIB_PARAMS((ROT *rot,
rot_status_t *status));
extern HAMLIB_EXPORT(int)
rot_register HAMLIB_PARAMS((const struct rot_caps *caps));
@ -734,6 +746,14 @@ dmmm2dec HAMLIB_PARAMS((int degrees,
double seconds,
int sw));
extern HAMLIB_EXPORT(setting_t) rot_parse_func(const char *s);
extern HAMLIB_EXPORT(setting_t) rot_parse_level(const char *s);
extern HAMLIB_EXPORT(setting_t) rot_parse_parm(const char *s);
extern HAMLIB_EXPORT(const char *) rot_strfunc(setting_t);
extern HAMLIB_EXPORT(const char *) rot_strlevel(setting_t);
extern HAMLIB_EXPORT(const char *) rot_strparm(setting_t);
extern HAMLIB_EXPORT(const char *) rot_strstatus(rot_status_t);
//! @endcond
/**

Wyświetl plik

@ -39,6 +39,10 @@
#define DUMMY_ROT_LEVEL ROT_LEVEL_SPEED
#define DUMMY_ROT_PARM 0
#define DUMMY_ROT_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \
ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \
ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT)
struct dummy_rot_priv_data
{
azimuth_t az;
@ -47,6 +51,7 @@ struct dummy_rot_priv_data
struct timeval tv; /* time last az/el update */
azimuth_t target_az;
elevation_t target_el;
rot_status_t status;
setting_t funcs;
value_t levels[RIG_SETTING_MAX];
@ -254,27 +259,13 @@ static int dummy_rot_set_position(ROT *rot, azimuth_t az, elevation_t el)
return RIG_OK;
}
/*
* Get position of rotor, simulating slow rotation
*/
static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
static void dummy_rot_simulate_rotation(ROT *rot)
{
struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *)
struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *)
rot->state.priv;
struct timeval tv;
unsigned elapsed; /* ms */
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (priv->az == priv->target_az &&
priv->el == priv->target_el)
{
*az = priv->az;
*el = priv->el;
return RIG_OK;
}
gettimeofday(&tv, NULL);
elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 +
@ -289,16 +280,19 @@ static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
{
/* target reached */
priv->az = priv->target_az;
priv->status &= ~(ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT);
}
else
{
if (priv->az < priv->target_az)
{
priv->az += (azimuth_t)elapsed * DEG_PER_MS;
priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_RIGHT;
}
else
{
priv->az -= (azimuth_t)elapsed * DEG_PER_MS;
priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT;
}
}
@ -306,23 +300,54 @@ static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
{
/* target reached */
priv->el = priv->target_el;
priv->status &= ~(ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN);
}
else
{
if (priv->el < priv->target_el)
{
priv->el += (elevation_t)elapsed * DEG_PER_MS;
priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP;
}
else
{
priv->el -= (elevation_t)elapsed * DEG_PER_MS;
priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_DOWN;
}
}
*az = priv->az;
*el = priv->el;
if (priv->status & (ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_EL)) {
priv->status |= ROT_STATUS_MOVING;
} else {
priv->status &= ~(ROT_STATUS_MOVING);
}
priv->tv = tv;
}
/*
* Get position of rotor, simulating slow rotation
*/
static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
{
struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *)
rot->state.priv;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (priv->az == priv->target_az &&
priv->el == priv->target_el)
{
*az = priv->az;
*el = priv->el;
return RIG_OK;
}
dummy_rot_simulate_rotation(rot);
*az = priv->az;
*el = priv->el;
return RIG_OK;
}
@ -839,16 +864,27 @@ static int dummy_get_ext_parm(ROT *rot, token_t token, value_t *val)
}
static int dummy_rot_get_status(ROT *rot, rot_status_t *status)
{
struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *)rot->state.priv;
dummy_rot_simulate_rotation(rot);
*status = priv->status;
return RIG_OK;
}
/*
* Dummy rotator capabilities.
*/
const struct rot_caps dummy_rot_caps =
{
ROT_MODEL(ROT_MODEL_DUMMY),
.model_name = "Dummy",
.mfg_name = "Hamlib",
.version = "20201202.0",
.version = "20201203.0",
.copyright = "LGPL",
.status = RIG_STATUS_STABLE,
.rot_type = ROT_TYPE_AZEL,
@ -875,6 +911,8 @@ const struct rot_caps dummy_rot_caps =
.extparms = dummy_ext_parms,
.cfgparams = dummy_cfg_params,
.has_status = DUMMY_ROT_STATUS,
.rot_init = dummy_rot_init,
.rot_cleanup = dummy_rot_cleanup,
.rot_open = dummy_rot_open,
@ -904,7 +942,8 @@ const struct rot_caps dummy_rot_caps =
.set_ext_parm = dummy_set_ext_parm,
.get_ext_parm = dummy_get_ext_parm,
.get_info = dummy_rot_get_info,
.get_info = dummy_rot_get_info,
.get_status = dummy_rot_get_status,
};
DECLARE_INITROT_BACKEND(dummy)

Wyświetl plik

@ -48,7 +48,6 @@
# include <sys/time.h>
#endif
#include <unistd.h>
#include <math.h>
#include <hamlib/rig.h>
@ -1759,6 +1758,54 @@ int HAMLIB_API rig_flush(hamlib_port_t *port)
return serial_flush(port); // we must be on serial port
}
static struct
{
rot_status_t status;
const char *str;
} rot_status_str[] =
{
{ ROT_STATUS_BUSY, "BUSY" },
{ ROT_STATUS_MOVING, "MOVING" },
{ ROT_STATUS_MOVING_AZ, "MOVING_AZ" },
{ ROT_STATUS_MOVING_LEFT, "MOVING_LEFT" },
{ ROT_STATUS_MOVING_RIGHT, "MOVING_RIGHT" },
{ ROT_STATUS_MOVING_EL, "MOVING_EL" },
{ ROT_STATUS_MOVING_UP, "MOVING_UP" },
{ ROT_STATUS_MOVING_DOWN, "MOVING_DOWN" },
{ ROT_STATUS_LIMIT_UP, "LIMIT_UP" },
{ ROT_STATUS_LIMIT_DOWN, "LIMIT_DOWN" },
{ ROT_STATUS_LIMIT_LEFT, "LIMIT_LEFT" },
{ ROT_STATUS_LIMIT_RIGHT, "LIMIT_RIGHT" },
{ ROT_STATUS_OVERLAP_UP, "OVERLAP_UP" },
{ ROT_STATUS_OVERLAP_DOWN, "OVERLAP_DOWN" },
{ ROT_STATUS_OVERLAP_LEFT, "OVERLAP_LEFT" },
{ ROT_STATUS_OVERLAP_RIGHT, "OVERLAP_RIGHT" },
{ 0xffffff, "" },
};
/**
* \brief Convert enum ROT_STATUS_... to a string
* \param status ROT_STATUS_...
* \return the corresponding string value
*/
const char *HAMLIB_API rot_strstatus(rot_status_t status)
{
int i;
for (i = 0 ; rot_status_str[i].str[0] != '\0'; i++)
{
if (status == rot_status_str[i].status)
{
return rot_status_str[i].str;
}
}
return "";
}
//! @endcond
/** @} */

Wyświetl plik

@ -283,6 +283,8 @@ ROT *HAMLIB_API rot_init(rot_model_t rot_model)
rs->has_get_parm = caps->has_get_parm;
rs->has_set_parm = caps->has_set_parm;
rs->has_status = caps->has_status;
memcpy(rs->level_gran, caps->level_gran, sizeof(gran_t)*RIG_SETTING_MAX);
memcpy(rs->parm_gran, caps->parm_gran, sizeof(gran_t)*RIG_SETTING_MAX);
@ -597,6 +599,9 @@ int HAMLIB_API rot_set_position(ROT *rot,
return -RIG_EINVAL;
}
azimuth += rot->state.az_offset;
elevation += rot->state.el_offset;
caps = rot->caps;
rs = &rot->state;
@ -648,6 +653,8 @@ int HAMLIB_API rot_get_position(ROT *rot,
{
const struct rot_caps *caps;
const struct rot_state *rs;
azimuth_t az;
elevation_t el;
int retval;
rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
@ -665,19 +672,21 @@ int HAMLIB_API rot_get_position(ROT *rot,
return -RIG_ENAVAIL;
}
retval = caps->get_position(rot, azimuth, elevation);
retval = caps->get_position(rot, &az, &el);
if (retval != RIG_OK) { return retval; }
rot_debug(RIG_DEBUG_VERBOSE, "%s: got az=%.2f, el=%.2f\n", __func__, *azimuth,
*elevation);
rot_debug(RIG_DEBUG_VERBOSE, "%s: got az=%.2f, el=%.2f\n", __func__, az, el);
if (rs->south_zero)
{
*azimuth += *azimuth >= 180 ? -180 : 180;
rot_debug(RIG_DEBUG_VERBOSE, "%s: south adj to az=%.2f\n", __func__, *azimuth);
az += az >= 180 ? -180 : 180;
rot_debug(RIG_DEBUG_VERBOSE, "%s: south adj to az=%.2f\n", __func__, az);
}
*azimuth = az - rot->state.az_offset;
*elevation = el - rot->state.el_offset;
return RIG_OK;
}
@ -841,4 +850,33 @@ const char *HAMLIB_API rot_get_info(ROT *rot)
return rot->caps->get_info(rot);
}
/**
* \brief get status flags from the rotator
* \param rot The rot handle
* \param status a pointer to a rot_status_t variable that will receive the status flags
*
* Gets the active status flags from the rotator.
*
* \return RIG_OK if the operation has been successful, otherwise
* a negative value if an error occurred (in which case, cause is
* set appropriately).
*/
int HAMLIB_API rot_get_status(ROT *rot, rot_status_t *status)
{
rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (CHECK_ROT_ARG(rot))
{
return -RIG_EINVAL;
}
if (rot->caps->get_status == NULL)
{
return -RIG_ENAVAIL;
}
return rot->caps->get_status(rot, status);
}
/*! @} */

Wyświetl plik

@ -146,6 +146,17 @@ int dumpcaps_rot(ROT *rot, FILE *fout)
"Post Write delay:\t%dmS\n",
caps->post_write_delay);
if (rot->state.has_status != 0)
{
rot_sprintf_status(prntbuf, rot->state.has_status);
}
else
{
strcpy(prntbuf, "None\n");
}
fprintf(fout, "Status flags: %s\n", prntbuf);
rot_sprintf_func(prntbuf, caps->has_get_func);
fprintf(fout, "Get functions: %s\n", prntbuf);
@ -223,7 +234,16 @@ int dumpcaps_rot(ROT *rot, FILE *fout)
fprintf(fout, "Can Park:\t\t%c\n", caps->park != NULL ? 'Y' : 'N');
fprintf(fout, "Can Reset:\t\t%c\n", caps->reset != NULL ? 'Y' : 'N');
fprintf(fout, "Can Move:\t\t%c\n", caps->move != NULL ? 'Y' : 'N');
fprintf(fout, "Can get Info:\t\t%c\n", caps->get_info != NULL ? 'Y' : 'N');
fprintf(fout, "Can get Status:\t\t%c\n", caps->get_status != NULL ? 'Y' : 'N');
fprintf(fout, "Can set Func:\t%c\n", caps->set_func != NULL ? 'Y' : 'N');
fprintf(fout, "Can get Func:\t%c\n", caps->get_func != NULL ? 'Y' : 'N');
fprintf(fout, "Can set Level:\t%c\n", caps->set_level != NULL ? 'Y' : 'N');
fprintf(fout, "Can get Level:\t%c\n", caps->get_level != NULL ? 'Y' : 'N');
fprintf(fout, "Can set Param:\t%c\n", caps->set_parm != NULL ? 'Y' : 'N');
fprintf(fout, "Can get Param:\t%c\n", caps->get_parm != NULL ? 'Y' : 'N');
fprintf(fout, "\nOverall backend warnings: %d\n", backend_warnings);

Wyświetl plik

@ -187,6 +187,7 @@ declare_proto_rot(get_func);
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(send_cmd);
declare_proto_rot(dump_state);
@ -224,6 +225,7 @@ struct test_table test_list[] =
{ 'x', "get_parm", ACTION(get_parm), ARG_IN1 | ARG_OUT2, "Parm", "Parm Value" },
{ 'C', "set_conf", ACTION(inter_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), },
{ 0x8f, "dump_state", ACTION(dump_state), ARG_OUT },
@ -1729,7 +1731,7 @@ declare_proto_rot(set_position)
CHKSCN1ARG(sscanf(arg1, "%f", &az));
CHKSCN1ARG(sscanf(arg2, "%f", &el));
return rot_set_position(rot, az + rot->state.az_offset, el);
return rot_set_position(rot, az, el);
}
@ -1742,8 +1744,6 @@ declare_proto_rot(get_position)
status = rot_get_position(rot, &az, &el);
az -= rot->state.az_offset;
if (status != RIG_OK)
{
return status;
@ -1809,6 +1809,32 @@ declare_proto_rot(get_info)
}
/* 's' */
declare_proto_rot(get_status)
{
int result;
rot_status_t status;
char s[SPRINTF_MAX_SIZE];
result = rot_get_status(rot, &status);
if (result != RIG_OK)
{
return result;
}
if ((interactive && prompt) || (interactive && !prompt && ext_resp))
{
fprintf(fout, "%s: ", cmd->arg1);
}
rot_sprintf_status(s, status);
fprintf(fout, "%s%c", s, resp_sep);
return RIG_OK;
}
/* 'M' */
declare_proto_rot(move)
{

Wyświetl plik

@ -665,6 +665,33 @@ int rig_sprintf_scan(char *str, scan_t rscan)
}
int rot_sprintf_status(char *str, rot_status_t status)
{
int i, len = 0;
rig_debug(RIG_DEBUG_TRACE, "%s: status=%08x\n", __func__, status);
*str = '\0';
if (status == ROT_STATUS_NONE)
{
return 0;
}
for (i = 0; i < 32; i++)
{
const char *sv;
sv = rot_strstatus(status & ROT_STATUS_N(i));
if (sv && sv[0] && (strstr(sv, "None") == 0))
{
len += sprintf(str + len, "%s ", sv);
}
}
return len;
}
char *get_rig_conf_type(enum rig_conf_e type)
{
switch (type)

Wyświetl plik

@ -23,6 +23,7 @@
#define _SPRINTFLST_H 1
#include <hamlib/rig.h>
#include <hamlib/rotator.h>
#define SPRINTF_MAX_SIZE 512
@ -45,6 +46,7 @@ extern int rig_sprintf_parm_gran(char *str, setting_t parm, const gran_t *gran);
extern int rot_sprintf_parm_gran(char *str, setting_t parm, const gran_t *gran);
extern int rig_sprintf_vfop(char *str, vfo_op_t op);
extern int rig_sprintf_scan(char *str, scan_t rscan);
extern int rot_sprintf_status(char *str, rot_status_t status);
extern char *get_rig_conf_type(enum rig_conf_e type);
int print_ext_param(const struct confparams *cfp, rig_ptr_t ptr);