Added initial support for Block protocol in rigctld and documented same.

Rewrote testctld.pl for new block protocol and included it with 
source distribution.



git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2813 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.11
Nate Bargmann, N0NB 2010-01-24 23:24:20 +00:00
rodzic 37435ede91
commit 52a87d096c
6 zmienionych plików z 476 dodań i 313 usunięć

Wyświetl plik

@ -72,5 +72,5 @@ rigmatrix.html: rigmatrix_head.html rigmatrix listrigs
for f in `./listrigs | tail -n +2 | cut -f1` ; do ( ./rigctl -m $$f -u > sup-info/support/model$$f.txt || exit 0 ) ; done
./rigctl -l |sort -n | $(srcdir)/rig_split_lst.awk -v lst_dir="sup-info"
EXTRA_DIST = rigmatrix_head.html rig_split_lst.awk $(man_MANS)
EXTRA_DIST = rigmatrix_head.html rig_split_lst.awk $(man_MANS) testctld.pl

Wyświetl plik

@ -86,6 +86,7 @@ static struct option long_options[] =
int interactive = 1; /* if no cmd on command line, switch to interactive */
int prompt = 1; /* Print prompt in rigctl */
int opt_end= 0; /* only used by rigctld */
int opt_block = 0; /* only used by rigctld */
int vfo_mode; /* vfo_mode=0 means target VFO is current VFO */
char send_cmd_term = '\r'; /* send_cmd termination char */

Wyświetl plik

@ -3,26 +3,26 @@
* (C) Terry Embry 2008-2009
*
* This program test/control a radio using Hamlib.
* It takes commands in interactive mode as well as
* It takes commands in interactive mode as well as
* from command line options.
*
* $Id: rigctl_parse.c,v 1.16 2009-02-06 17:28:38 fillods Exp $
* $Id: rigctl_parse.c,v 1.16 2009-02-06 17:28:38 fillods Exp $
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*/
#ifdef HAVE_CONFIG_H
@ -73,7 +73,7 @@ static pthread_mutex_t rig_mutex = PTHREAD_MUTEX_INITIALIZER;
struct test_table {
unsigned char cmd;
const char *name;
int (*rig_routine)(RIG*, FILE*, int, const struct test_table*, vfo_t,
int (*rig_routine)(RIG*, FILE*, int, const struct test_table*, vfo_t,
const char*, const char*, const char*);
int flags;
const char *arg1;
@ -167,20 +167,20 @@ static struct test_table test_list[] = {
{ 'm', "get_mode", get_mode, ARG_OUT, "Mode", "Passband" },
{ 'I', "set_split_freq", set_split_freq, ARG_IN, "Tx frequency" },
{ 'i', "get_split_freq", get_split_freq, ARG_OUT, "Tx frequency" },
{ 'X', "set_split_mode", set_split_mode, ARG_IN, "Mode", "Passband" },
{ 'x', "get_split_mode", get_split_mode, ARG_OUT, "Mode", "Passband" },
{ 'S', "set_split_vfo", set_split_vfo, ARG_IN, "Split mode", "TxVFO" },
{ 's', "get_split_vfo", get_split_vfo, ARG_OUT, "Split mode", "TxVFO" },
{ 'X', "set_split_mode", set_split_mode, ARG_IN, "Tx mode", "Tx passband" },
{ 'x', "get_split_mode", get_split_mode, ARG_OUT, "Tx mode", "Tx passband" },
{ 'S', "set_split_vfo", set_split_vfo, ARG_IN, "Split", "Tx VFO" },
{ 's', "get_split_vfo", get_split_vfo, ARG_OUT, "Split", "Tx VFO" },
{ 'N', "set_ts", set_ts, ARG_IN, "Tuning step" },
{ 'n', "get_ts", get_ts, ARG_OUT, "Tuning step" },
{ 'L', "set_level", set_level, ARG_IN, "Level", "Value" },
{ 'l', "get_level", get_level, ARG_IN1|ARG_OUT2, "Level", "Value" },
{ 'L', "set_level", set_level, ARG_IN, "Level", "Level value" },
{ 'l', "get_level", get_level, ARG_IN1|ARG_OUT2, "Level", "Level value" },
{ 'U', "set_func", set_func, ARG_IN, "Func", "Func status" },
{ 'u', "get_func", get_func, ARG_IN1|ARG_OUT2, "Func", "Func status" },
{ 'P', "set_parm", set_parm, ARG_IN|ARG_NOVFO, "Parm", "Value" },
{ 'p', "get_parm", get_parm, ARG_IN1|ARG_OUT2|ARG_NOVFO, "Parm", "Value" },
{ 'P', "set_parm", set_parm, ARG_IN|ARG_NOVFO, "Parm", "Parm value" },
{ 'p', "get_parm", get_parm, ARG_IN1|ARG_OUT2|ARG_NOVFO, "Parm", "Parm value" },
{ 'G', "vfo_op", vfo_op, ARG_IN, "Mem/VFO op" },
{ 'g', "scan", scan, ARG_IN, "Scan fct", "Channel" },
{ 'g', "scan", scan, ARG_IN, "Scan fct", "Scan channel" },
{ 'A', "set_trn", set_trn, ARG_IN|ARG_NOVFO, "Transceive" },
{ 'a', "get_trn", get_trn, ARG_OUT|ARG_NOVFO, "Transceive" },
{ 'R', "set_rptr_shift", set_rptr_shift, ARG_IN, "Rptr shift" },
@ -191,10 +191,10 @@ static struct test_table test_list[] = {
{ 'c', "get_ctcss_tone", get_ctcss_tone, ARG_OUT, "CTCSS tone" },
{ 'D', "set_dcs_code", set_dcs_code, ARG_IN, "DCS code" },
{ 'd', "get_dcs_code", get_dcs_code, ARG_OUT, "DCS code" },
{ 0x90, "set_ctcss_sql", set_ctcss_sql, ARG_IN, "CTCSS tone" },
{ 0x91, "get_ctcss_sql", get_ctcss_sql, ARG_OUT, "CTCSS tone" },
{ 0x92, "set_dcs_sql", set_dcs_sql, ARG_IN, "DCS code" },
{ 0x93, "get_dcs_sql", get_dcs_sql, ARG_OUT, "DCS code" },
{ 0x90, "set_ctcss_sql", set_ctcss_sql, ARG_IN, "CTCSS sql" },
{ 0x91, "get_ctcss_sql", get_ctcss_sql, ARG_OUT, "CTCSS sql" },
{ 0x92, "set_dcs_sql", set_dcs_sql, ARG_IN, "DCS sql" },
{ 0x93, "get_dcs_sql", get_dcs_sql, ARG_OUT, "DCS sql" },
{ 'V', "set_vfo", set_vfo, ARG_IN|ARG_NOVFO, "VFO" },
{ 'v', "get_vfo", get_vfo, ARG_OUT, "VFO" },
{ 'T', "set_ptt", set_ptt, ARG_IN, "PTT" },
@ -216,14 +216,13 @@ static struct test_table test_list[] = {
{ 0x89, "send_dtmf", send_dtmf, ARG_IN, "Digits" },
{ 0x8a, "recv_dtmf", recv_dtmf, ARG_OUT, "Digits" },
{ '*', "reset", reset, ARG_IN, "Reset" },
{ '2', "power2mW", power2mW, ARG_NOVFO },
{ 'w', "send_cmd", send_cmd, ARG_IN1|ARG_IN_LINE|ARG_OUT2|ARG_NOVFO, "Cmd", "Reply" },
{ 'b', "send_morse", send_morse, ARG_IN|ARG_IN_LINE, "Morse" },
{ 0x8b, "get_dcd", get_dcd, ARG_OUT, "DCD" },
{ '2', "power2mW", power2mW, ARG_NOVFO },
{ '1', "dump_caps", dump_caps, ARG_NOVFO },
{ '3', "dump_conf", dump_conf, ARG_NOVFO },
{ 0x8f,"dump_state", dump_state, ARG_OUT|ARG_NOVFO },
/* next one is 0x89 */
{ 0x00, "", NULL },
};
@ -231,7 +230,7 @@ static struct test_table test_list[] = {
static struct test_table *find_cmd_entry(int cmd)
{
int i;
for (i=0; i<MAXNBOPT && test_list[i].cmd != 0x00; i++)
for (i = 0; i < MAXNBOPT && test_list[i].cmd != 0x00; i++)
if (test_list[i].cmd == cmd)
break;
@ -246,14 +245,14 @@ static struct test_table *find_cmd_entry(int cmd)
static char parse_arg(const char *arg)
{
int i;
for (i=0; i<MAXNBOPT && test_list[i].cmd != 0; i++)
for (i = 0; i < MAXNBOPT && test_list[i].cmd != 0; i++)
if (!strncmp(arg, test_list[i].name, MAXNAMSIZ))
return test_list[i].cmd;
return 0;
}
/*
/*
* This scanf works even in presence of signals (timer, SIGIO, ..)
*/
static int scanfc(FILE *fin, const char *format, void *p)
@ -276,6 +275,7 @@ static int scanfc(FILE *fin, const char *format, void *p)
extern int interactive;
extern int prompt;
extern int opt_end;
extern int opt_block;
extern int vfo_mode;
extern char send_cmd_term;
@ -312,7 +312,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
return -1;
*pcmd = '\0';
cmd = parse_arg((char *) cmd_name);
cmd = parse_arg((char *)cmd_name);
break;
}
@ -371,7 +371,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
vfo = rig_parse_vfo(arg1);
} else {
if (!argv[optind]) {
fprintf(stderr, "Invalid arg for command '%s'\n",
fprintf(stderr, "Invalid arg for command '%s'\n",
cmd_entry->name);
exit(2);
}
@ -379,7 +379,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
}
}
if ((cmd_entry->flags & ARG_IN_LINE) &&
if ((cmd_entry->flags & ARG_IN_LINE) &&
(cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) {
if (interactive) {
char *nl;
@ -390,16 +390,16 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
fgets(arg1, MAXARGSZ, fin);
nl = strchr(arg1, 0xa);
if (nl) *nl = '\0'; /* chomp */
p1 = arg1[0]==' '?arg1+1:arg1;
p1 = arg1[0] == ' ' ? arg1 + 1 : arg1;
} else {
if (!argv[optind]) {
fprintf(stderr, "Invalid arg for command '%s'\n",
fprintf(stderr, "Invalid arg for command '%s'\n",
cmd_entry->name);
exit(2);
}
p1 = argv[optind++];
}
} else
} else
if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) {
if (interactive) {
if (prompt)
@ -409,14 +409,14 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
p1 = arg1;
} else {
if (!argv[optind]) {
fprintf(stderr, "Invalid arg for command '%s'\n",
fprintf(stderr, "Invalid arg for command '%s'\n",
cmd_entry->name);
exit(2);
}
p1 = argv[optind++];
}
}
if (p1 && p1[0]!='?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) {
if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) {
if (interactive) {
if (prompt)
fprintf(fout, "%s: ", cmd_entry->arg2);
@ -425,14 +425,14 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
p2 = arg2;
} else {
if (!argv[optind]) {
fprintf(stderr, "Invalid arg for command '%s'\n",
fprintf(stderr, "Invalid arg for command '%s'\n",
cmd_entry->name);
exit(2);
}
p2 = argv[optind++];
}
}
if (p1 && p1[0]!='?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) {
if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) {
if (interactive) {
if (prompt)
fprintf(fout, "%s: ", cmd_entry->arg3);
@ -441,7 +441,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
p3 = arg3;
} else {
if (!argv[optind]) {
fprintf(stderr, "Invalid arg for command '%s'\n",
fprintf(stderr, "Invalid arg for command '%s'\n",
cmd_entry->name);
exit(2);
}
@ -458,10 +458,23 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
#endif
if (!prompt)
rig_debug(RIG_DEBUG_TRACE, "rigctl: %c '%s' '%s' '%s'\n",
rig_debug(RIG_DEBUG_TRACE, "rigctl(d): %c '%s' '%s' '%s'\n",
cmd, p1, p2, p3);
retcode = (*cmd_entry->rig_routine)(my_rig, fout, interactive,
/* Block protocol: output received command name and arguments response */
if (interactive && opt_block) {
char a1[MAXARGSZ+1];
char a2[MAXARGSZ+1];
char a3[MAXARGSZ+1];
p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1);
p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2);
p3 == NULL ? a3[0] = '\0' : snprintf(a3, sizeof(a3), " %s", p3);
fprintf(fout, "%s:%s%s%s\n", cmd_entry->name, a1, a2, a3);
}
retcode = (*cmd_entry->rig_routine)(my_rig, fout, interactive,
cmd_entry, vfo, p1, p2, p3);
#ifdef HAVE_PTHREAD
@ -469,17 +482,19 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc)
#endif
if (retcode != RIG_OK) {
if (interactive && !prompt)
if (interactive && !prompt && opt_block)
fprintf(fout, NETRIGCTL_RET "%d\n", retcode); /* only for rigctld */
else
fprintf(fout, "%s: error = %s\n", cmd_entry->name, rigerror(retcode));
} else {
if (interactive && !prompt) { /* only for rigctld */
if (!(cmd_entry->flags & ARG_OUT) && !opt_end) /* netrigctl RIG_OK */
if (!(cmd_entry->flags & ARG_OUT) && !opt_end) /* netrigctl RIG_OK */
fprintf(fout, NETRIGCTL_RET "0\n");
else if ((cmd_entry->flags & ARG_OUT) && opt_end) /* Nate's protocol */
fprintf(fout, "END\n");
}
else if (opt_block) /* block marker protocol */
fprintf(fout, NETRIGCTL_RET "0\n");
}
}
fflush(fout);
@ -500,7 +515,7 @@ void usage_rig(FILE *fout)
fprintf(fout, "Commands (some may not be available for this rig):\n");
for (i=0; test_list[i].cmd != 0; i++) {
fprintf(fout, "%c: %-16s(", isprint(test_list[i].cmd) ?
fprintf(fout, "%c: %-16s(", isprint(test_list[i].cmd) ?
test_list[i].cmd:'?', test_list[i].name);
nbspaces = 18;
@ -527,13 +542,13 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data)
rig_get_conf(rig, cfp->token, buf);
printf("%s: \"%s\"\n" "\t"
"Default: %s, Value: %s\n",
cfp->name, cfp->tooltip,
"Default: %s, Value: %s\n",
cfp->name, cfp->tooltip,
cfp->dflt, buf );
switch (cfp->type) {
case RIG_CONF_NUMERIC:
printf("\tRange: %.1f..%.1f, step %.1f\n",
printf("\tRange: %.1f..%.1f, step %.1f\n",
cfp->u.n.min, cfp->u.n.max, cfp->u.n.step);
break;
case RIG_CONF_COMBO:
@ -605,7 +620,7 @@ int set_conf(RIG *my_rig, char *conf_parms)
/*
* static int (f)(RIG *rig, FILE *fout, int interactive, const struct test_table *cmd,
* 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)
*/
@ -628,7 +643,7 @@ declare_proto_rig(get_freq)
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1); /* i.e. "Frequency" */
fprintf(fout, "%"PRIll"\n", (long long)freq);
@ -714,10 +729,10 @@ declare_proto_rig(get_mode)
status = rig_get_mode(rig, vfo, &mode, &width);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%s\n", rig_strrmode(mode));
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg2);
fprintf(fout, "%ld\n", width);
@ -738,7 +753,7 @@ declare_proto_rig(get_vfo)
status = rig_get_vfo(rig, &vfo);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%s\n", rig_strvfo(vfo));
@ -763,13 +778,14 @@ declare_proto_rig(get_ptt)
status = rig_get_ptt(rig, vfo, &ptt);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", ptt);
return status;
}
/* '0x8b' */
declare_proto_rig(get_dcd)
{
int status;
@ -778,7 +794,7 @@ declare_proto_rig(get_dcd)
status = rig_get_dcd(rig, vfo, &dcd);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", dcd);
@ -803,7 +819,7 @@ declare_proto_rig(get_rptr_shift)
status = rig_get_rptr_shift(rig, vfo, &rptr_shift);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%s\n", rig_strptrshift(rptr_shift));
@ -828,7 +844,7 @@ declare_proto_rig(get_rptr_offs)
status = rig_get_rptr_offs(rig, vfo, &rptr_offs);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%ld\n", rptr_offs);
@ -853,7 +869,7 @@ declare_proto_rig(get_ctcss_tone)
status = rig_get_ctcss_tone(rig, vfo, &tone);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", tone);
@ -878,13 +894,14 @@ declare_proto_rig(get_dcs_code)
status = rig_get_dcs_code(rig, vfo, &code);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", code);
return status;
}
/* '0x90' */
declare_proto_rig(set_ctcss_sql)
{
tone_t tone;
@ -893,6 +910,7 @@ declare_proto_rig(set_ctcss_sql)
return rig_set_ctcss_sql(rig, vfo, tone);
}
/* '0x91' */
declare_proto_rig(get_ctcss_sql)
{
int status;
@ -901,13 +919,14 @@ declare_proto_rig(get_ctcss_sql)
status = rig_get_ctcss_sql(rig, vfo, &tone);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", tone);
return status;
}
/* '0x92' */
declare_proto_rig(set_dcs_sql)
{
tone_t code;
@ -916,6 +935,7 @@ declare_proto_rig(set_dcs_sql)
return rig_set_dcs_sql(rig, vfo, code);
}
/* '0x93' */
declare_proto_rig(get_dcs_sql)
{
int status;
@ -924,7 +944,7 @@ declare_proto_rig(get_dcs_sql)
status = rig_get_dcs_sql(rig, vfo, &code);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", code);
@ -947,11 +967,11 @@ declare_proto_rig(get_split_freq)
int status;
freq_t txfreq;
vfo_t txvfo = RIG_VFO_TX;
status = rig_get_split_freq(rig, txvfo, &txfreq);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%"PRIll"\n", (long long)txfreq);
@ -989,10 +1009,10 @@ declare_proto_rig(get_split_mode)
status = rig_get_split_mode(rig, txvfo, &mode, &width);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%s\n", rig_strrmode(mode));
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg2);
fprintf(fout, "%ld\n", width);
@ -1018,10 +1038,10 @@ declare_proto_rig(get_split_vfo)
status = rig_get_split_vfo(rig, vfo, &split, &tx_vfo);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", split);
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg2);
fprintf(fout, "%s\n", rig_strvfo(tx_vfo));
@ -1046,7 +1066,7 @@ declare_proto_rig(get_ts)
status = rig_get_ts(rig, vfo, &ts);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%ld\n", ts);
@ -1165,7 +1185,7 @@ declare_proto_rig(get_level)
switch (cfp->type) {
case RIG_CONF_BUTTON:
/* there's not sense in retrieving value of stateless button */
/* there's no sense in retrieving value of stateless button */
return -RIG_EINVAL;
case RIG_CONF_CHECKBUTTON:
@ -1379,7 +1399,7 @@ declare_proto_rig(get_mem)
status = rig_get_mem(rig, vfo, &ch);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", ch);
@ -1506,7 +1526,7 @@ declare_proto_rig(set_channel)
chan.tx_vfo = rig_parse_vfo(s);
}
if (mem_caps->rptr_shift) {
printf("rptr shift (+-0): ");
printf("rptr shift (+-0): ");
status = scanf("%s", s);
chan.rptr_shift = rig_parse_rptr_shift(s);
}
@ -1580,7 +1600,7 @@ declare_proto_rig(get_channel)
{
int status;
channel_t chan;
memset(&chan, 0, sizeof(channel_t));
if (isdigit(arg1[0])) {
@ -1665,7 +1685,7 @@ declare_proto_rig(get_trn)
status = rig_get_trn(rig, &trn);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", trn);
@ -1678,7 +1698,7 @@ declare_proto_rig(get_info)
const char *s;
s = rig_get_info(rig);
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%s\n", s ? s : "None");
@ -1693,7 +1713,7 @@ void dump_chan(FILE *fout, RIG *rig, channel_t *chan)
char widthbuf[16];
char prntbuf[256];
fprintf(fout, "Channel: %d, Name: '%s'\n", chan->channel_num,
fprintf(fout, "Channel: %d, Name: '%s'\n", chan->channel_num,
chan->channel_desc);
fprintf(fout, "VFO: %s, Antenna: %d, Split: %s\n", rig_strvfo(chan->vfo),
@ -1701,12 +1721,12 @@ void dump_chan(FILE *fout, RIG *rig, channel_t *chan)
sprintf_freq(freqbuf, chan->freq);
sprintf_freq(widthbuf, chan->width);
fprintf(fout, "Freq: %s\tMode: %s\tWidth: %s\n",
fprintf(fout, "Freq: %s\tMode: %s\tWidth: %s\n",
freqbuf, rig_strrmode(chan->mode), widthbuf);
sprintf_freq(freqbuf, chan->tx_freq);
sprintf_freq(widthbuf, chan->tx_width);
fprintf(fout, "txFreq: %s\ttxMode: %s\ttxWidth: %s\n",
fprintf(fout, "txFreq: %s\ttxMode: %s\ttxWidth: %s\n",
freqbuf, rig_strrmode(chan->tx_mode), widthbuf);
sprintf_freq(freqbuf,chan->rptr_offs);
@ -1727,7 +1747,7 @@ void dump_chan(FILE *fout, RIG *rig, channel_t *chan)
sprintf_func(prntbuf, chan->funcs);
fprintf(fout, "Functions: %s\n", prntbuf);
fprintf(fout, "Levels:");
for (idx=0; idx<RIG_SETTING_MAX; idx++) {
setting_t level = rig_idx2setting(idx);
@ -1798,13 +1818,13 @@ declare_proto_rig(dump_state)
fprintf(fout, "0 0 0 0 0 0 0\n");
for (i=0; i<TSLSTSIZ && !RIG_IS_TS_END(rs->tuning_steps[i]); i++)
fprintf(fout, "0x%x %ld\n",
fprintf(fout, "0x%x %ld\n",
rs->tuning_steps[i].modes,
rs->tuning_steps[i].ts);
fprintf(fout, "0 0\n");
for (i=0; i<FLTLSTSIZ && !RIG_IS_FLT_END(rs->filters[i]); i++)
fprintf(fout, "0x%x %ld\n",
fprintf(fout, "0x%x %ld\n",
rs->filters[i].modes,
rs->filters[i].width);
fprintf(fout, "0 0\n");
@ -1866,7 +1886,7 @@ declare_proto_rig(get_ant)
status = rig_get_ant(rig, vfo, &ant);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", rig_setting2idx(ant));
@ -1928,7 +1948,7 @@ declare_proto_rig(get_powerstat)
status = rig_get_powerstat(rig, &stat);
if (status != RIG_OK)
return status;
if (interactive && prompt)
if ((interactive && prompt) || (interactive && !prompt && opt_block))
fprintf(fout, "%s: ", cmd->arg1);
fprintf(fout, "%d\n", stat);
@ -2004,12 +2024,12 @@ declare_proto_rig(send_cmd)
retval = read_string(&rs->rigport, buf, BUFSZ, eom_buf, strlen(eom_buf));
if (retval < 0)
break;
if (retval < BUFSZ)
buf[retval] = '\0';
else
buf[BUFSZ-1] = '\0';
fprintf(fout, "%s\n", buf);
} while (retval > 0);

Wyświetl plik

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH RIGCTLD "8" "January 14, 2009" "Hamlib" "Rig Control Daemon"
.TH RIGCTLD "8" "January 24, 2010" "Hamlib" "Rig Control Daemon"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -21,14 +21,15 @@ rigctld \- Hamlib rig control daemon
.B rigctld
[\fIOPTION\fR]...
.SH DESCRIPTION
The \fBrigctld\fP program is an EXPERIMENTAL \fBHamlib\fP rig daemon that
handles TCP client requests. This allows multiple user programs to share one
radio. Multiple radios can be controlled on different TCP ports. The syntax
of the commands are the same as \fBrigctl\fP. It is hoped that \fBrigctld\fP
will be especially useful for languages such as Perl, Python, and others.
The \fBrigctld\fP program is an EXPERIMENTAL \fBHamlib\fP rig control daemon
that handles TCP client requests. This allows multiple user programs to share
one radio. Multiple radios can be controlled on different TCP ports by use of
multiple \fBrigctld\fP processes. The syntax of the commands are the same as
\fBrigctl\fP. It is hoped that \fBrigctld\fP will be especially useful for
languages such as Perl, Python, PHP, and others.
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
.\" respectively.
\fBrigctld\fP communicates to a client through a TCP socket using text
commands shared with \fBrigctl\fP. The protocol is simple, commands are sent
@ -39,13 +40,19 @@ Commands that do not return values respond with the line "RPTR x", where x
is zero when successful, otherwise is a regative number indicating the error code.
Each line is terminated with a newline '\\n' character.
.PP
Keep in mind that \fBHamlib\fP is BETA level software.
A separate \fBblock\fP protocol (-b, or --block option) extends the above
behavior by echoing the received command string as a header, any returned values
as a key: value pair, and the "RPTR x" string as the end of block marker which
includes the \fBHamlib\fP success or failure value. See the \fIPROTOCOL\fP
section for details.
.PP
Keep in mind that \fBHamlib\fP is BETA level software.
While a lot of backend libraries lack complete rig support, the basic functions
are usually well supported. The API may change without publicized notice,
are usually well supported. The API may change without publicized notice,
while an advancement of the minor version (e.g. 1.1.x to 1.2.x) indicates such
a change.
.PP
Please report bugs and provide feedback at the e-mail address given in the
Please report bugs and provide feedback at the e-mail address given in the
REPORTING BUGS section. Patches and code enhancements are also welcome.
.SH OPTIONS
This program follows the usual GNU command line syntax, with long
@ -54,11 +61,11 @@ options starting with two dashes ('-').
Here is a summary of the supported options:
.TP
.B \-m, --model=id
Select radio model number. See -l, "list" option below.
Select radio model number. See the -l, --list option below.
.TP
.B \-r, --rig-file=device
Use \fIdevice\fP as the file name of the port the radio is connected.
Often a serial port, but could be a USB to serial adapter. Typically
Often a serial port, but could be a USB to serial adapter. Typically
/dev/ttyS0, /dev/ttyS1, /dev/ttyUSB0, etc.
.TP
.B \-p, --ptt-file=device
@ -74,7 +81,7 @@ Use \fItype\fP of Push-To-Talk device.
Supported types are RIG (CAT command), DTR, RTS, PARALLEL, NONE.
.TP
.B \-D, --dcd-type=type
Use \fItype\fP of Data Carrier Detect device.
Use \fItype\fP of Data Carrier Detect device.
Supported types are RIG (CAT command), DSR, CTS, CD, PARALLEL, NONE.
.TP
.B \-s, --serial-speed=baud
@ -82,32 +89,29 @@ Set serial speed to \fIbaud\fP rate. Uses maximum serial speed from rig
backend capabilities (set by -m above) as the default.
.TP
.B \-c, --civaddr=id
Use \fIid\fP as the CI-V address to communicate with the rig. Only useful for
Icom rigs.
Use \fIid\fP as the CI-V address to communicate with the rig. Only useful for
Icom rigs.
.br
NB: The \fIid\fP is in decimal notation, unless prefixed by
\fI0x\fP, in which case it is hexadecimal.
N.B.: The \fIid\fP is in decimal notation, unless prefixed by
\fI0x\fP for a hexadecimal value.
.TP
.B \-L, --show-conf
List all config parameters for the radio defined with -m above.
.B \-T, --listen-addr=IPADDR
Use \fIIPADDR\fP as the listening IP address. The default is ANY.
.TP
.B \-t, --port=number
Use \fInumber\fP as the TCP listening port. The default is 4532.
.TP
.B \-C, --set-conf=parm=val[,parm=val]*
Set config parameter. e.g. --set-conf=stop_bits=2
.br
Use -L option for a list.
.TP
.B \-e, --end-marker
Use END marker in rigctld protocol.
.TP
.B \-t, --port=number
Use \fInumber\fP as the TCP listening port. The default is 4532.
.TP
.B \-T, --listen-addr=IPADDR
Use \fIIPADDR\fP as the listening IP address. The default is ANY.
.TP
.B \-l, --list
List all model numbers defined in \fBHamlib\fP and exit.
.TP
.B \-L, --show-conf
List all config parameters for the radio defined with -m above.
.TP
.B \-u, --dump-caps
Dump capabilities for the radio defined with -m above and exit.
.TP
@ -115,8 +119,17 @@ Dump capabilities for the radio defined with -m above and exit.
Set vfo mode, requiring an extra VFO argument in front of each appropriate
command. Otherwise, VFO_CURR is assumed when this option is not set.
.TP
.B \-b, --block
Use the block rigctld protocol. \fIEXPERIMENTAL\fP
.TP
.B \-e, --end-marker
Use END marker in rigctld protocol.
.br
N.B.: This option can be considered obsolete. Please consider using the block
protocol instead (see \fIPROTOCOL\fP below).
.TP
.B \-v, --verbose
Set verbose mode, cumulative (see DIAGNOSTICS below).
Set verbose mode, cumulative (see \fIDIAGNOSTICS\fP below).
.TP
.B \-h, --help
Show a summary of these options and exit.
@ -125,232 +138,329 @@ Show a summary of these options and exit.
Show the version of \fBrigctld\fP and exit.
.PP
\fBN.B.\fP Some options may not be implemented by a given backend and will
return an error. This is most likely to occur with the \fI\-\-set-conf\fP
return an error. This is most likely to occur with the \fI\-\-set-conf\fP
and \fI\-\-show-conf\fP options.
.PP
Please note that the backend for the radio to be controlled,
or the radio itself may not support some commands. In that case,
Please note that the backend for the radio to be controlled,
or the radio itself may not support some commands. In that case,
the operation will fail with a \fBHamlib\fP error code.
.SH COMMANDS
Commands can be sent over the TCP socket either as a single char, or as a
long command name plus the value(s) on one '\\n' terminated line. See
PROTOCOL.
Commands can be sent over the TCP socket either as a single char, or as a
long command name plus the value(s) space separated on one '\\n' terminated
line. See \fIPROTOCOL\fP.
.PP
Since most of the \fBHamlib\fP operations have a \fIset\fP and a \fIget\fP method,
an upper case letter will be used for \fIset\fP method whereas the
an upper case letter will be used for \fIset\fP method whereas the
corresponding lower case letter refers to the \fIget\fP method. Each operation
also has a long name, prepend a backslash to send a long command name.
.PP
Example (Perl): `print $socket "\\\\dump_caps\\n";' to see what the radio's
backend can do.
backend can do (NOTE: In Perl and many other languages a '\\' will need to be
escaped with a preceding '\\' so that even though two backslash characters
appear in the code, only one will be passed to \fBrigctld\fP. This is a
possible bug!).
.PP
Please note that the backend for the radio to be controlled,
or the radio itself may not support some commands. In that case,
Please note that the backend for the radio to be controlled,
or the radio itself may not support some commands. In that case,
the operation will fail with a \fBHamlib\fP error message.
.PP
Here is a summary of the supported commands:
Here is a summary of the supported commands (In the case of "set" commands the
quoted string is replaced by the value in the description. In the case of "get"
commands the quoted string is the key name of the value returned.):
.TP
.B F, set_freq
Set frequency, in Hz.
.B F, set_freq 'Frequency'
Set 'Frequency', in Hz.
.TP
.B f, get_freq
Get frequency, in Hz.
Get 'Frequency', in Hz.
.TP
.B M, set_mode
Set mode/passband: AM, FM, CW, CWR, USB, LSB, RTTY, RTTYR, WFM, AMS,
.B M, set_mode 'Mode' 'Passband'
Set 'Mode': USB, LSB, CW, CWR, RTTY, RTTYR, AM, FM, WFM, AMS,
PKTLSB, PKTUSB, PKTFM, ECSSUSB, ECSSLSB, FAX, SAM, SAL, SAH, DSB.
The passband is the exact passband in Hz, or 0 for the default.
Set 'Passband' in Hz, or 0 for the default.
.TP
.B m, get_mode
Get mode/passband.
Get 'Mode' 'Passband'. Returns Mode as a string from \fIset_mode\fP above
and Passband in Hz.
.TP
.B V, set_vfo
Set VFO: VFOA, VFOB, VFOC, currVFO, VFO, MEM, Main, Sub, TX, RX.
.B V, set_vfo 'VFO'
Set 'VFO': VFOA, VFOB, VFOC, currVFO, VFO, MEM, Main, Sub, TX, RX.
.TP
.B v, get_vfo
Get current VFO.
Get current 'VFO'. Returns VFO as a string from \fIset_vfo\fP above.
.TP
.B J, set_rit
Set RIT, in Hz.
.B J, set_rit 'RIT'
Set 'RIT', in Hz.
.TP
.B j, get_rit
Get RIT, in Hz.
Get 'RIT', in Hz.
.TP
.B Z, set_xit
Set XIT, in Hz.
.B Z, set_xit 'XIT'
Set 'XIT', in Hz.
.TP
.B z, get_xit
Get XIT, in Hz.
Get 'XIT', in Hz.
.TP
.B T, set_ptt
Set PTT, 0 (RX) or 1 (TX).
.B T, set_ptt 'PTT'
Set 'PTT', 0 (RX) or 1 (TX).
.TP
.B t, get_ptt
Get PTT status.
Get 'PTT' status.
.TP
.B get_dcd
Get DCD status.
.B 0x8b, get_dcd
Get 'DCD' (squelch) status, 0 (Closed) or 1 (Open)
.TP
.B R, set_rptr_shift
Set repeater shift: "+", "-" or something else for none.
.B R, set_rptr_shift 'Rptr shift'
Set 'Rptr shift': "+", "-" or something else for none.
.TP
.B r, get_rptr_shift
Get repeater shift.
Get 'Rptr shift'. Returns "+", "-" or "None".
.TP
.B O, set_rptr_offs
Set repeater offset, in Hz.
.B O, set_rptr_offs 'Rptr offset'
Set 'Rptr offset', in Hz.
.TP
.B o, get_rptr_offs
Get repeater offset.
Get 'Rptr offset', in Hz.
.TP
.B C, set_ctcss_tone
Set CTCSS tone, in tenth of Hz.
.B C, set_ctcss_tone 'CTCSS tone'
Set 'CTCSS tone', in tenths of Hz.
.TP
.B c, get_ctcss_tone
Get CTCSS tone, in tenth of Hz.
Get 'CTCSS tone', in tenths of Hz.
.TP
.B D, set_dcs_code
Set DCS code.
.B D, set_dcs_code 'DCS code'
Set 'DCS code'.
.TP
.B d, get_dcs_code
Get DCS code.
Get 'DCS code'.
.TP
.B set_ctcss_sql
Set CTCSS squelch tone, in tenth of Hz.
.B 0x90, set_ctcss_sql 'CTCSS sql'
Set 'CTCSS sql' tone, in tenths of Hz.
.TP
.B get_ctcss_sql
Get CTCSS squelch tone, in tenth of Hz.
.B 0x91, get_ctcss_sql
Get 'CTCSS sql' tone, in tenths of Hz.
.TP
.B set_dcs_sql
Set DCS squelch code.
.B 0x92, set_dcs_sql 'DCS sql'
Set 'DCS sql' code.
.TP
.B get_dcs_sql
Get DCS squelch code.
.B 0x93, get_dcs_sql
Get 'DCS sql' code.
.TP
.B I, set_split_freq
Set TX frequency, in Hz.
.B I, set_split_freq 'Tx frequency'
Set 'TX frequency', in Hz.
.TP
.B i, get_split_freq
Get TX frequency.
Get 'TX frequency', in Hz.
.TP
.B X, set_split_mode
Set transmit mode/passband: AM, FM, CW, CWR, USB, LSB, RTTY, RTTYR, WFM, AMS,
.B X, set_split_mode 'Tx mode' 'Tx passband'
Set 'Tx mode': AM, FM, CW, CWR, USB, LSB, RTTY, RTTYR, WFM, AMS,
PKTLSB, PKTUSB, PKTFM, ECSSUSB, ECSSLSB, FAX, SAM, SAL, SAH, DSB.
The passband is the exact passband in Hz, or 0 for the default.
The 'Tx passband' is the exact passband in Hz, or 0 for the default.
.TP
.B x, get_split_mode
Get transmit mode/passband.
Get 'Tx mode' and 'Tx passband'. Returns Tx mode as a string from
\fIset_split_mode\fP above and Tx passband in Hz.
.TP
.B S, set_split_vfo
Set split mode, 0 or 1, and transmit VFO.
.B S, set_split_vfo 'Split' 'Tx VFO'
Set 'Split' mode, 0 or 1, and 'Tx VFO'.
.TP
.B s, get_split_vfo
Get split mode and transmit VFO.
Get 'Split' mode and 'Tx VFO'.
.TP
.B N, set_ts
Set tuning step, in Hz.
.B N, set_ts 'Tuning step'
Set 'Tuning step', in Hz.
.TP
.B n, get_ts
Get tuning step.
Get 'Tuning step', in Hz.
.TP
.B U, set_func
Set func/status:
FAGC, NB, COMP, VOX, TONE, TSQL, SBKIN, FBKIN, ANF, NR, AIP, APF, MON, MN,
RF, ARO, LOCK, MUTE, VSC, REV, SQL, ABM, BC, MBC, AFC, SATMODE, SCOPE,
RESUME, TBURST, TUNER.
.B U, set_func 'Func' 'Func status'
Set 'Func' 'Func status'. Func is one of: FAGC, NB, COMP, VOX, TONE, TSQL,
SBKIN, FBKIN, ANF, NR, AIP, APF, MON, MN, RF, ARO, LOCK, MUTE, VSC, REV, SQL,
ABM, BC, MBC, AFC, SATMODE, SCOPE, RESUME, TBURST, TUNER.
Func Status argument is a non null value for "activate", "de-activate"
otherwise, much as TRUE/FALSE definitions in C language.
.TP
.B u, get_func
Get func status.
Get 'Func' 'Func status'. Returns Func as a string from \fIset_func\fP above
and Func status as a non null value.
.TP
.B L, set_level
Set level/value:
PREAMP, ATT, VOX, AF, RF, SQL, IF, APF, NR, PBT_IN, PBT_OUT, CWPITCH, RFPOWER,
MICGAIN, KEYSPD, NOTCHF, COMP, AGC, BKINDL, BAL, METER, VOXGAIN, ANTIVOX.
SLOPE_LOW, SLOPE_HIGH, RAWSTR, SQLSTAT, SWR, ALC, STRENGTH.
.B L, set_level 'Level' 'Level value'
Set 'Level' and 'Level value'. Level is one of: PREAMP, ATT, VOX, AF, RF, SQL,
IF, APF, NR, PBT_IN, PBT_OUT, CWPITCH, RFPOWER, MICGAIN, KEYSPD, NOTCHF, COMP,
AGC, BKINDL, BAL, METER, VOXGAIN, ANTIVOX. SLOPE_LOW, SLOPE_HIGH, RAWSTR,
SQLSTAT, SWR, ALC, STRENGTH.
The Level value can be a float or an integer.
.TP
.B l, get_level
Get level value.
Get 'Level' 'Level value'. Returns Level as a string from \fIset_level\fP
above and Level value as a float or integer.
.TP
.B P, set_parm
Set parm/value:
ANN, APO, BACKLIGHT, BEEP, TIME, BAT, KEYLIGHT.
.B P, set_parm 'Parm' 'Parm value'
Set 'Parm' 'Parm value' Parm is one of: ANN, APO, BACKLIGHT, BEEP, TIME, BAT,
KEYLIGHT.
.TP
.B p, get_parm
Get parm value.
Get 'Parm' 'Parm value'. Returns Parm as a string from \fIset_parm\fP
above and Parm value as a float or integer.
.TP
.B B, set_bank
Set bank.
.B B, set_bank 'Bank'
Set 'Bank'. Sets the current memory bank number.
.TP
.B E, set_mem
Set memory channel number.
.B E, set_mem 'Memory#'
Set 'Memory#' channel number.
.TP
.B e, get_mem
Get memory channel number.
Get 'Memory#' channel number.
.TP
.B G, vfo_op
Perform VFO operation:
CPY, XCHG, FROM_VFO, TO_VFO, MCL, UP, DOWN, BAND_UP, BAND_DOWN, LEFT, RIGHT,
TUNE, TOGGLE.
.B G, vfo_op 'Mem/VFO op'
Perform 'Mem/VFO op'. Mem VFO operation is one of: CPY, XCHG, FROM_VFO, TO_VFO,
MCL, UP, DOWN, BAND_UP, BAND_DOWN, LEFT, RIGHT, TUNE, TOGGLE.
.TP
.B g, scan_op
Perform scan operation/channel: STOP, MEM, SLCT, PRIO, PROG, DELTA, VFO, PLT.
.B g, scan 'Scan fct' 'Scan channel'
Perform 'Scan fct' 'Scan channel'. Scan function/channel is one of: STOP, MEM,
SLCT, PRIO, PROG, DELTA, VFO, PLT.
.TP
.B H, set_channel
Set memory channel data. Not implemented yet.
.B H, set_channel 'Channel'
Set memory 'Channel' data. Not implemented yet.
.TP
.B h, get_channel
Get memory channel data.
Get memory 'Channel' data.
.TP
.B A, set_trn
Set transceive mode (reporting event): OFF, RIG, POLL.
.B A, set_trn 'Transceive'
Set 'Transceive' mode (reporting event): OFF, RIG, POLL.
.TP
.B a, get_trn
Get transceive mode (reporting event).
Get 'Transceive' mode (reporting event) as in \fIset_trn\fP above.
.TP
.B Y, set_ant
Set antenna number (0, 1, 2, ..).
.B Y, set_ant 'Antenna'
Set 'Antenna' number (0, 1, 2, ..).
.TP
.B y, get_ant
Get antenna number (0, 1, 2, ..).
Get 'Antenna' number (0, 1, 2, ..).
.TP
.B *, reset
Reset.
.B *, reset 'Reset'
Perform rig 'Reset'. 0 = None, 1 = Software reset, 2 = VFO reset, 4 = Memory
Clear reset, 8 = Master reset. Since these values are defined as a bitmask in
rig.h, it should be possible to AND these values together to do multiple resets
at once, if the backend supports it or supports a reset action via rig control
at all.
.TP
.B b, send_morse
Send morse symbols.
.B b, send_morse 'Morse'
Send 'Morse' symbols.
.TP
.B 0x87, set_powerstat
Set power status.
.B 0x87, set_powerstat 'Status'
Set power On/Off/Standby 'Status'. 0 = Power Off, 1 = Power On, 2 = Power
Standby. Defined as a bitmask in rig.h.
.TP
.B 0x88, get_powerstat
Get power status.
Get power On/Off/Standby 'Status' as in \fIset_powerstat\fP above.
.TP
.B 0x89, send_dtmf
Set DTMF digits.
.B 0x89, send_dtmf 'Digits'
Set DTMF 'Digits'.
.TP
.B 0x8a, recv_dtmf
Get DTMF digits.
Get DTMF 'Digits'.
.TP
.B _, get_info
Get misc information about the rig.
Get misc information about the rig (no value is passed).
.TP
.B 1, dump_caps
Not a real rig remote command, it just dumps capabilities, i.e. what the
Not a real rig remote command, it just dumps capabilities, i.e. what the
backend knows about this model, and what it can do. TODO: Ensure this is
in a consistent format so it can be read into a hash, dictionary, etc.
.TP
.B 2, power2mW
Converts a power value in a range of \fI0.0 ... 1.0\fP to the real transmit
power in milli-Watts. The \fIfrequency\fP and \fImode\fP also need to be
Converts a power value in a range of \fI0.0 ... 1.0\fP to the real transmit
power in milli-Watts. The \fIfrequency\fP and \fImode\fP also need to be
provided as output power may vary according to these values.
.TP
.B w, send_cmd
Send raw command string to rig.
.B w, send_cmd 'Cmd'
Send raw command string to rig.
.br
For binary protocols enter values as \\0xAA\\0xBB
For binary protocols enter values as \\0xAA\\0xBB. Expect a 'Reply' from the
rig which will likely be a binary block or an ASCII string.
.SH PROTOCOL
\fBDefault Protocol\fP
.br
The \fBrigctld\fP protocol is intentionally simple. Commands are entered on
a single line with any needed values. In Perl, reliable results are obtained
by terminating each command string with a newline character, '\\n'.
.PP
Example \fIset\fP (Perl code):
print $socket "F 14250000\\n";
.br
print $socket "\\\\set_mode LSB 2400\\n"; # escape leading '\\'
.PP
Responses from \fBrigctld\fP are text values and match the same tokens used
in the \fIset\fP commands. Each value is returned on its own line. To
signal the end of a response "0\\n" is returned.
.PP
Example \fIget\fP (Perl code):
print $socket "f\\n";
"14250000\\n"
.PP
Most \fIget\fP functions return one to three values. A notable exception is
the \fI\\dump_caps\fP function which returns many lines of key:value pairs.
Future work will focus on making this output compatible with assignment to a
hash, dictionary, or other key:value variable.
.PP
\fBBlock Protocol\fP
.br
An \fIEXPERIMENTAL\fP Block protocol has been introduced into \fBrigctld\fP
as of January 24, 2010. This protocol adds several rules to the strings
returned by \fBrigctld\fP.
.PP
1. The command received by \fBrigctld\fP is echoed with its long command name
followed by the value(s) received from the client terminated by a newline
as the first line of the block.
.PP
2. The last line of each block is the string "RPTR \fIx\fP\\n" wheren \fIx\fP is
the numeric return value of the Hamlib backend function that was called by the
command.
.PP
3. Any lines consisting of data values returned by the rig backend are prepended
by a string immediately followed by a colon then a space and then the value
terminated by a newline. e.g. "Frequency: 14250000\\n"
.PP
4. All commands received will be acknowledged by \fBrigctld\fP with lines from
rules 1 and 2. Lines from rule 3 are only returned when data values must be
returned to the client.
.PP
An example response to a \fI\\set_mode\fP command:
.br
set_mode: USB 2400
.br
RPRT 0
.PP
In this case the long command name and values are returned on the first line and
the second line contains the end of block marker and the numeric rig backend
return value indicating success.
.PP
An example response to a \fI\\get_mode\fP query:
.br
get_mode:
.br
Mode: CW
.br
Passband: 2400
.br
RPRT 0
.PP
In this case, as no value is passed to \fBrigctld\fP, the first line consists
only of the long command name. The final line shows that the command was
processed successfully by the rig backend.
.PP
The following commands have been tested with the Block protocol and the included
`testctld.pl' script:
.br
\fI\\set_freq\fP \fI\\get-freq\fP
.br
\fI\\set_mode\fP \fI\\get_mode\fP
.SH EXAMPLES
Start \fBrigctld\fP for a Yaesu FT-920 using an USB-to-serial adapter and
backgrounding:
@ -365,49 +475,23 @@ $ rigctld -m 114 -r /dev/ttyUSB1 -s 4800 -C stop_bits=2 &
Connect to the already running \fBrigctld\fP, and set current frequency to 14.266 MHz:
.PP
$ echo "\\set_freq 14266000" | nc localhost 4532
.SH PROTOCOL
The \fBrigctld\fP protocol is intentionally simple. Commands are entered on
a single line with any needed values. In Perl, reliable results are obtained
by terminating each command string with a newline character, '\\n'.
.PP
Example \fIset\fP (Perl code):
print $socket "F 14250000\\n";
.br
print $socket "\\\\set_mode LSB 2400\\n"; # escape leading '\\'
.PP
Responses from \fBrigctld\fP are text values and match the same tokens used
in the \fIset\fP commands. Each value is returned on its own line. To
signal the end of a response the "END\\n" string is sent when the '-e' option
is passed.
.PP
Example \fIget\fP (Perl code):
print $socket "f\\n";
"14250000\\n"
.br
"END\\n"
.PP
Most \fIget\fP functions return one to three values. A notable exception is
the \fIdump_caps\fP function which returns many lines of key:value pairs.
Future work will focus on making this output compatible with assignment to a
hash, dictionary, or other key:value variable.
.SH DIAGNOSTICS
The \fB-v\fP, \fB--version\fP option allows different levels of diagnostics
to be output to \fBstderr\fP and correspond to -v for BUG, -vv for ERR,
-vvv for WARN, -vvvv for VERBOSE, or -vvvvv for TRACE.
The \fB-v\fP, \fB--verbose\fP, option allows different levels of diagnostics
to be output to \fBstderr\fP and correspond to -v for BUG, -vv for ERR,
-vvv for WARN, -vvvv for VERBOSE, or -vvvvv for TRACE.
.PP
A given verbose level is useful for providing needed debugging information to
the email address below. For example, TRACE output shows all of the values
sent to and received from the radio which is very useful for radio backend
library development and may be requested by the developers.
library development and may be requested by the developers. See the
\fBREADME.betatester\fP and \fBREADME.developer\fP files for more information.
.SH SECURITY
No authentication whatsoever; DO NOT leave this TCP port open wide to the
Internet. Please ask if stronger security is needed.
No authentication whatsoever; DO NOT leave this TCP port open wide to the
Internet. Please ask if stronger security is needed or consider using an
SSH tunnel.
.SH BUGS
The daemon is not detaching and backgrounding itself.
.br
Much testing needs to be done.
.SH REPORTING BUGS
Report bugs to <hamlib-developer@lists.sourceforge.net>.
@ -418,7 +502,7 @@ Written by Stephane Fillod and the Hamlib Group
.br
<http://www.hamlib.org>.
.SH COPYRIGHT
Copyright \(co 2000-2009 Stephane Fillod and the Hamlib Group.
Copyright \(co 2000-2010 Stephane Fillod and the Hamlib Group.
.PP
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY

Wyświetl plik

@ -4,23 +4,23 @@
* This program test/control a radio using Hamlib.
* It takes commands from network connection.
*
* $Id: rigctld.c,v 1.11 2009-01-04 14:49:17 fillods Exp $
* $Id: rigctld.c,v 1.11 2009-01-04 14:49:17 fillods Exp $
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*/
#ifdef HAVE_CONFIG_H
@ -63,12 +63,12 @@
#include "rigctl_parse.h"
/*
* Reminder: when adding long options,
* Reminder: when adding long options,
* keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks.
* NB: do NOT use -W since it's reserved by POSIX.
* TODO: add an option to read from a file
*/
#define SHORT_OPTIONS "m:r:p:d:P:D:s:c:lC:t:T:LeuovhV"
#define SHORT_OPTIONS "m:r:p:d:P:D:s:c:T:t:C:lLuobevhV"
static struct option long_options[] =
{
{"model", 1, 0, 'm'},
@ -79,13 +79,14 @@ static struct option long_options[] =
{"dcd-type", 1, 0, 'D'},
{"serial-speed", 1, 0, 's'},
{"civaddr", 1, 0, 'c'},
{"port", 1, 0, 't'},
{"listen-addr", 1, 0, 'T'},
{"list", 0, 0, 'l'},
{"port", 1, 0, 't'},
{"set-conf", 1, 0, 'C'},
{"list", 0, 0, 'l'},
{"show-conf",0, 0, 'L'},
{"dump-caps", 0, 0, 'u'},
{"vfo", 0, 0, 'o'},
{"block", 0, 0, 'b'},
{"end-marker", 0, 0, 'e'},
{"verbose", 0, 0, 'v'},
{"help", 0, 0, 'h'},
@ -104,8 +105,9 @@ void * handle_socket(void * arg);
void usage(void);
int interactive = 1; /* no cmd because of daemon */
int prompt= 0 ; /* Daemon mode for rigparse return string */
int opt_end= 0 ; /* END marker for rigctld */
int prompt = 0; /* Daemon mode for rigparse return string */
int opt_end = 0; /* END marker for rigctld */
int opt_block = 0; /* Block markers for rigctld */
int vfo_mode; /* vfo_mode=0 means target VFO is current VFO */
char send_cmd_term = '\r'; /* send_cmd termination char */
@ -116,7 +118,7 @@ uint32_t src_addr = INADDR_ANY;
#define MAXCONFLEN 128
int main (int argc, char *argv[])
{
{
RIG *my_rig; /* handle to rig (instance) */
rig_model_t my_model = RIG_MODEL_DUMMY;
@ -278,13 +280,17 @@ int main (int argc, char *argv[])
case 'e':
opt_end = 1;
break;
case 'b':
opt_block = 1;
break;
default:
usage(); /* unknown option? */
exit(1);
}
}
rig_set_debug(verbose<2 ? RIG_DEBUG_WARN: verbose);
// rig_set_debug(verbose < 2 ? RIG_DEBUG_WARN: verbose);
rig_set_debug(verbose);
rig_debug(RIG_DEBUG_VERBOSE, "rigctld, %s\n", hamlib_version);
rig_debug(RIG_DEBUG_VERBOSE, "Report bugs to "
@ -293,7 +299,7 @@ int main (int argc, char *argv[])
my_rig = rig_init(my_model);
if (!my_rig) {
fprintf(stderr, "Unknown rig num %d, or initialization error.\n",
fprintf(stderr, "Unknown rig num %d, or initialization error.\n",
my_model);
fprintf(stderr, "Please check with --list option.\n");
exit(2);
@ -308,7 +314,7 @@ int main (int argc, char *argv[])
if (rig_file)
strncpy(my_rig->state.rigport.pathname, rig_file, FILPATHLEN);
/*
/*
* ex: RIG_PTT_PARALLEL and /dev/parport0
*/
if (ptt_type != RIG_PTT_NONE)
@ -351,18 +357,18 @@ int main (int argc, char *argv[])
if (verbose > 0)
printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model,
my_rig->caps->model_name);
rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n",
rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n",
my_rig->caps->version, rig_strstatus(my_rig->caps->status));
/*
* Prepare listening socket
*/
sock_listen = socket(AF_INET, SOCK_STREAM, 0);
sock_listen = socket(AF_INET, SOCK_STREAM, 0);
if (sock_listen < 0) {
perror("ERROR opening socket");
exit(2);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
@ -370,15 +376,15 @@ int main (int argc, char *argv[])
if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR,
(char *)&reuseaddr,sizeof(reuseaddr)) < 0) {
(char *)&reuseaddr, sizeof(reuseaddr)) < 0) {
rig_debug(RIG_DEBUG_ERR, "setsockopt: %s\n", strerror(errno));
exit (1);
}
if (bind(sock_listen, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
if (bind(sock_listen, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
rig_debug(RIG_DEBUG_ERR, "binding: %s\n", strerror(errno));
exit (1);
}
if (listen(sock_listen,4) < 0) {
if (listen(sock_listen, 4) < 0) {
rig_debug(RIG_DEBUG_ERR, "listening: %s\n", strerror(errno));
exit (1);
}
@ -401,7 +407,7 @@ int main (int argc, char *argv[])
arg->rig = my_rig;
arg->clilen = sizeof(arg->cli_addr);
arg->sock = accept(sock_listen, (struct sockaddr *) &arg->cli_addr,
arg->sock = accept(sock_listen, (struct sockaddr *)&arg->cli_addr,
&arg->clilen);
if (arg->sock < 0) {
rig_debug(RIG_DEBUG_ERR, "accept: %s\n", strerror(errno));
@ -511,6 +517,7 @@ void usage(void)
" -l, --list list all model numbers and exit\n"
" -u, --dump-caps dump capabilities and exit\n"
" -o, --vfo do not default to VFO_CURR, require extra vfo arg\n"
" -b, --block use block rigctld protocol\n",
" -e, --end-marker use END marker in rigctld protocol\n"
" -v, --verbose set verbose mode, cumulative\n"
" -h, --help display this help and exit\n"

Wyświetl plik

@ -3,7 +3,7 @@
# testctld.pl - (C) Nate Bargmann 2008
# A Perl test script for the rigctld program.
# $Id: testctld.pl,v 1.3 2008-01-10 03:42:35 n0nb Exp $
# $Id$
# It connects to the rigctld TCP port (default 4532) and queries
# the daemon for some common rig information. It also aims to provide
@ -13,12 +13,12 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@ -27,39 +27,71 @@
# Perl modules this script uses
use warnings;
use strict;
use IO::Socket;
use IO::Socket::INET;
# Local variables
my $socket;
my @answer;
my $freq = "14250000";
my $mode = "USB";
my $bw = "2400";
my $get_freq;
my $get_mode;
my $get_bw;
my $flags;
# values to set rig
my $set_freq = "14250000";
my $set_mode = "USB";
my $set_bw = "2400";
# Thanks to Uri Guttman on comp.lang.perl.misc for this function
sub get_results {
my ($sock) = @_;
my @lines;
my $errno;
my $line;
# my $x;
while (my $line = <$sock>) {
do {
while ( !($line = $sock->getline)) { ;}
print $line;
return @lines if $line =~ /^END$/;
push @lines, $line;
}
# return @lines if $line =~ /^RPRT\s+0$/;
if ($line) {
print $line;
push @lines, $line;
}
# else {
# return @lines;
# }
#if ($line =~ /^RPRT.*$/) {
#print $line;
#$errno = (split $line)[1];
#print $errno;
#unless ($errno) {
#return @lines;
#}
#else {
#return $errno * -1;
#}
#}
#else {
#push @lines, $line;
#}
} until ($line ne "");
return @lines;
}
# Create the new socket.
# 'localhost' may be replaced by any hostname or IP address where a
# Create the new socket.
# 'localhost' may be replaced by any hostname or IP address where a
# rigctld instance is running.
# Timeout is set to 5 seconds.
$socket = new IO::Socket::INET (PeerAddr => 'localhost',
$socket = IO::Socket::INET->new(PeerAddr => 'localhost',
PeerPort => 4532,
Proto => 'tcp',
Type => SOCK_STREAM,
Timeout => 5 )
Timeout => 5,
Blocking => 0 )
or die $@;
# Query rigctld for the rig's frequency
@ -69,8 +101,12 @@ print $socket "f\n";
# Get the rig's frequency from rigctld and print it to STDOUT
# N.B. Replies are newline terminated, so lines in @answer end with '\n'.
@answer = get_results($socket);
#$get_freq = <$socket>;
#$get_freq = $socket->getline;
#chomp($get_freq);
print "The rig's frequency is: $answer[0]";
#print "The rig's frequency is: $get_freq\n";
# Extra newline for screen formatting.
print "\n";
@ -78,26 +114,41 @@ print "\n";
# Do the same for the mode (reading the mode also returns the bandwidth)
print $socket "m\n";
@answer = get_results($socket);
#$get_mode = <$socket>;
#chomp($get_mode);
#$get_bw = <$socket>;
#chomp($get_bw);
#print "The rig's mode is: $get_mode\n";
#print "The rig's bandwidth is: $get_bw\n";
print "The rig's mode is: $answer[0]";
print "The rig's bandwidth is: $answer[1]";
print "\n";
# Now set the rig's frequency
print "Setting the rig's frequency to: $freq\n";
print $socket "F $freq\n";
print $socket "f\n";
@answer = get_results($socket);
print "The rig's frequency is now: $answer[0]";
print "\n";
#print "Setting the rig's frequency to: $set_freq\n";
#print $socket "F $set_freq\n";
#<$socket>;
#print $socket "f\n";
#@answer = get_results($socket);
#$get_freq = <$socket>;
#chomp($get_freq);
#print "The rig's frequency is now: $get_freq\n";
#print "\n";
# Setting the mode takes two parameters, mode and bandwidth
print "Setting the rig's mode to $mode and bandwidth to $bw\n";
print $socket "\\set_mode $mode $bw\n";
print $socket "\\get_mode\n";
@answer = get_results($socket);
print "The rig's mode is now: $answer[0]";
print "The rig's bandwidth is now: $answer[1]";
print "\n";
#print "Setting the rig's mode to $set_mode and bandwidth to $set_bw\n";
#print $socket "\\set_mode $set_mode $set_bw\n";
#<$socket>;
#print $socket "\\get_mode\n";
#@answer = get_results($socket);
#$get_mode = <$socket>;
#chomp($get_mode);
#$get_bw = <$socket>;
#chomp($get_bw);
#print "The rig's mode is now: $get_mode\n";
#print "The rig's bandwidth is now: $get_bw\n";
#print "\n";
# Close the connection before we exit.
close($socket);