kopia lustrzana https://github.com/Hamlib/Hamlib
Merge branch 'master' of https://github.com/mdblack98/Hamlib into mdblack98-master
commit
cf75f3fdf7
|
@ -15,6 +15,7 @@ doc_DATA = ChangeLog COPYING COPYING.LIB LICENSE \
|
|||
SUBDIRS = macros include lib \
|
||||
$(BACKEND_LIST) \
|
||||
$(ROT_BACKEND_LIST) \
|
||||
$(AMP_BACKEND_LIST) \
|
||||
src \
|
||||
$(BINDINGS) \
|
||||
tests doc
|
||||
|
@ -25,7 +26,8 @@ DIST_SUBDIRS = macros include lib src c++ bindings tests doc android scripts\
|
|||
adat alinco aor barrett drake dorji dummy elad flexradio icom icmarine jrc\
|
||||
kachina kenwood kit lowe pcr prm80 racal rft rs skanti tapr tentec\
|
||||
tuner uniden wj yaesu winradio\
|
||||
$(ROT_BACKEND_LIST)
|
||||
amplifiers/elecraft
|
||||
$(ROT_BACKEND_LIST) $(AMP_BACKEND_LIST)
|
||||
|
||||
# Install any third party macros into our tree for distribution
|
||||
ACLOCAL_AMFLAGS = -I macros --install
|
||||
|
|
|
@ -9,14 +9,14 @@ See README for frontend/backend outline.
|
|||
See README.betatester for background on testing Hamlib.
|
||||
|
||||
|
||||
The library provides functions for both radio and rotator control,
|
||||
and data retrieval from the radio or rotator. A number of functions useful
|
||||
The library provides functions for both radio, rotator, and amplifier control,
|
||||
and data retrieval from the radio, rotator, or amplifier. A number of functions useful
|
||||
for calculating distance and bearing and grid square conversion are included.
|
||||
|
||||
libhamlib.so - library that provides generic API for all RIG types.
|
||||
This is what Application programmers will "see". Will have different
|
||||
names on other platforms, e.g. libhamlib-2.dll on MS windows. Also
|
||||
contains all radio and rotator "backends" (formerly in their own
|
||||
contains all radio, rotator, and amplifier "backends" (formerly in their own
|
||||
dlopen'ed libraries) provided by Hamlib.
|
||||
|
||||
Backend Examples are:
|
||||
|
@ -401,7 +401,8 @@ So far, Hamlib has been tested successfully under the following systems:
|
|||
Makefile.am (not needed for rotators)
|
||||
|
||||
2.3. Add the backend name to the BACKEND_LIST variable (add to
|
||||
ROT_BACKEND_LIST for a new rotor backend) in configure.ac.
|
||||
ROT_BACKEND_LIST for a new rotor backend or to AMP_BACKEND_LIST for
|
||||
a new amplifier) in configure.ac.
|
||||
|
||||
2.4. Add "mybackend/Makefile" in the AC_CONFIG_FILES macro at the bottom
|
||||
of configure.ac.
|
||||
|
@ -414,8 +415,10 @@ So far, Hamlib has been tested successfully under the following systems:
|
|||
the rig_backend_list structure in src/register.c or, add
|
||||
{ ROT_MYROTBACKEND, ROT_BACKEND_MYROTBACKEND, ROT_FUNCNAMA(myrotbackend) },
|
||||
to the rot_backend_list structure in src/rot_reg.c.
|
||||
{ AMP_MYAMPBACKEND, AMP_BACKEND_MYAMPBACKEND, AMP_FUNCNAMA(myaotbackend) },
|
||||
to the aot_backend_list structure in src/amp_reg.c.
|
||||
|
||||
2.7. Add the new backend to include/hamlib/riglist.h or include/hamlib/rotlist.h
|
||||
2.7. Add the new backend to include/hamlib/riglist.h or include/hamlib/rotlist.h or include/hamlib/amplist.h
|
||||
by selecting the next higher backend ID number.
|
||||
|
||||
2.8. Create mybackend/Makefile.am, mybackend.c mybackend.h
|
||||
|
@ -465,7 +468,7 @@ So far, Hamlib has been tested successfully under the following systems:
|
|||
3. How to add a new model to an existing backend
|
||||
|
||||
3.1. make sure there's already a (unique) ID for the model to be added
|
||||
in include/hamlib/riglist.h or include/hamlib/rotlist.h
|
||||
in include/hamlib/riglist.h or include/hamlib/rotlist.h or include/hamlib/amplist.h
|
||||
|
||||
3.2. locate the existing backend
|
||||
3.3. Clone the most similar model in the backend
|
||||
|
@ -539,7 +542,7 @@ Contributed code to the Hamlib frontend must be released under the LGPL.
|
|||
Contributed code to Hamlib backends must follow backend current license.
|
||||
Needless to say, the LGPL is the license of choice.
|
||||
|
||||
End user applications like rigctl, rotctl and networked daemons should be
|
||||
End user applications like rigctl, rotctl, ampctl and networked daemons should be
|
||||
released under the GPL, so any contributed code must follow the license.
|
||||
|
||||
|
||||
|
@ -577,7 +580,7 @@ Hamlib should also compile with the following common compilers:
|
|||
* gcc-3.0 and gcc-3.2+ (nearly deprecated?)
|
||||
* gcc-4.x and newer
|
||||
* in shared and static
|
||||
* C++ compiler against rig.h, riglist.h, rotator.h
|
||||
* C++ compiler against rig.h, riglist.h, rotator.h, amplifier.h
|
||||
* clang compiler
|
||||
|
||||
Portability issues to watch:
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := elecraft.c kpa.c kpa1500.c
|
||||
LOCAL_MODULE := elecraft
|
||||
|
||||
LOCAL_CFLAGS := -DHAVE_CONFIG_H
|
||||
LOCAL_C_INCLUDES := android include src
|
||||
LOCAL_LDLIBS := -lhamlib
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
|
@ -0,0 +1,8 @@
|
|||
SRC = kpa1500.c
|
||||
|
||||
ELECRAFTSRC = kpa.c kpa.h
|
||||
|
||||
noinst_LTLIBRARIES = libhamlib-elecraft.la
|
||||
libhamlib_elecraft_la_SOURCES = $(SRC) $(ELECRAFTSRC)
|
||||
|
||||
EXTRA_DIST = README.elecraft Android.mk
|
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
* Hamlib Elecraft amplifier backend - low level communication routines
|
||||
* Copyright (c) 2019 by Michael Black W9MDB
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "kpa.h"
|
||||
|
||||
struct fault_list
|
||||
{
|
||||
int code;
|
||||
char *errmsg;
|
||||
};
|
||||
const struct fault_list kpa_fault_list [] =
|
||||
{
|
||||
{0, "No fault condition"},
|
||||
{0x10, "Watchdog Timer was reset"},
|
||||
{0x20, "PA Current is too high"},
|
||||
{0x40, "Temperature is too high"},
|
||||
{0x60, "Input power is too high"},
|
||||
{0x61, "Gain is too low"},
|
||||
{0x70, "Invalid frequency"},
|
||||
{0x80, "50V supply voltage too low or too high"},
|
||||
{0x81, "5V supply voltage too low or too high"},
|
||||
{0x82, "10V supply voltage too low or too high"},
|
||||
{0x83, "12V supply voltage too low or too high"},
|
||||
{0x84, "-12V supply voltage too low or too high"},
|
||||
{0x85, "5V or 400V LPF board supply voltages not detected"},
|
||||
{0x90, "Reflected power is too high"},
|
||||
{0x91, "SWR very high"},
|
||||
{0x92, "ATU no match"},
|
||||
{0xB0, "Dissipated power too high"},
|
||||
{0xC0, "Forward power too high"},
|
||||
{0xE0, "Forward power too high for current setting"},
|
||||
{0xF0, "Gain is too high"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize data structures
|
||||
*/
|
||||
|
||||
int kpa_init(AMP *amp)
|
||||
{
|
||||
struct kpa_priv_data *priv;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
priv = (struct kpa_priv_data *)
|
||||
malloc(sizeof(struct kpa_priv_data));
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
amp->state.priv = (void *)priv;
|
||||
|
||||
amp->state.ampport.type.rig = RIG_PORT_SERIAL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int kpa_flushbuffer(AMP *amp)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s\n", __func__);
|
||||
|
||||
rs = &->state;
|
||||
|
||||
return serial_flush(&rs->ampport);
|
||||
}
|
||||
|
||||
int kpa_transaction(AMP *amp, const char *cmd, char *response, int response_len)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
int err;
|
||||
int len = 0;
|
||||
char responsebuf[KPABUFSZ];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s\n", __func__, cmd);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
kpa_flushbuffer(amp);
|
||||
|
||||
rs = &->state;
|
||||
|
||||
int loop = 3;
|
||||
|
||||
do // wake up the amp by sending ; until we receive ;
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__);
|
||||
char c = ';';
|
||||
err = write_block(&rs->ampport, &c, 1);
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
int len = read_string(&rs->ampport, responsebuf, KPABUFSZ, ";", 1);
|
||||
|
||||
if (len < 0) { return len; }
|
||||
}
|
||||
while (--loop > 0 && (len != 1 || responsebuf[0] != ';'));
|
||||
|
||||
// Now send our command
|
||||
err = write_block(&rs->ampport, cmd, strlen(cmd));
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
if (response) // if response expected get it
|
||||
{
|
||||
responsebuf[0] = 0;
|
||||
int len = read_string(&rs->ampport, responsebuf, KPABUFSZ, ";", 1);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, error=%s\n", __func__,
|
||||
rigerror(len));
|
||||
return len;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
}
|
||||
else // if no response expected try to get one
|
||||
{
|
||||
loop = 3;
|
||||
|
||||
do
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__);
|
||||
char c = ';';
|
||||
err = write_block(&rs->ampport, &c, 1);
|
||||
|
||||
if (err != RIG_OK) { return err; }
|
||||
|
||||
int len = read_string(&rs->ampport, responsebuf, KPABUFSZ, ";", 1);
|
||||
|
||||
if (len < 0) { return len; }
|
||||
}
|
||||
while (--loop > 0 && (len != 1 || responsebuf[0] != ';'));
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Info
|
||||
* returns the model name string
|
||||
*/
|
||||
const char *kpa_get_info(AMP *amp)
|
||||
{
|
||||
const struct amp_caps *rc;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return (const char *) - RIG_EINVAL; }
|
||||
|
||||
rc = amp->caps;
|
||||
|
||||
return rc->model_name;
|
||||
}
|
||||
|
||||
int kpa_get_freq(AMP *amp, freq_t *freq)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
int retval = kpa_transaction(amp, "^FR;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
unsigned long tfreq;
|
||||
int nargs = sscanf(responsebuf, "^FR%ld", &tfreq);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^FR response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
*freq = tfreq * 1000;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int kpa_set_freq(AMP *amp, freq_t freq)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, freq=%ld\n", __func__, freq);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
char cmd[KPABUFSZ];
|
||||
sprintf(cmd, "^FR%05ld;", (long)freq / 1000);
|
||||
int retval = kpa_transaction(amp, cmd, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
unsigned long tfreq;
|
||||
int nargs = sscanf(responsebuf, "^FR%ld", &tfreq);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s Error: ^FR response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
if (tfreq * 1000 != freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s Error setting freq: ^FR freq!=freq2, %ld!=%ld '%s'\n", __func__,
|
||||
freq, tfreq * 1000);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int kpa_get_level(AMP *amp, setting_t level, value_t *val)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
char *cmd;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
// get the current antenna selected
|
||||
cmd = "^AE;";
|
||||
int retval = kpa_transaction(amp, cmd, responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
int antenna = 0;
|
||||
int nargs = sscanf(responsebuf, "^AE%d", &antenna);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s antenna=%d\n", __func__, cmd, antenna);
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
cmd = "^SW;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_NH:
|
||||
cmd = "^DF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PF:
|
||||
cmd = "^DF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_INPUT:
|
||||
cmd = "^PWI;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_FWD:
|
||||
cmd = "^PWF;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_REFLECTED:
|
||||
cmd = "^PWR;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_PEAK:
|
||||
cmd = "^PWK;";
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_FAULT:
|
||||
cmd = "^SF;";
|
||||
break;
|
||||
}
|
||||
|
||||
retval = kpa_transaction(amp, cmd, responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
float float_value = 0;
|
||||
int int_value = 0, int_value2 = 0;
|
||||
struct amp_state *rs = &->state;
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
nargs = sscanf(responsebuf, "^SW%f", &float_value);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->f = float_value / 10.0f;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_NH:
|
||||
case AMP_LEVEL_PF:
|
||||
nargs = sscanf(responsebuf, "^DF%d,%d", &int_value, &int_value2);
|
||||
|
||||
if (nargs != 2)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s freq range=%dKHz,%dKHz\n", __func__, cmd,
|
||||
int_value, int_value2);
|
||||
|
||||
//
|
||||
do
|
||||
{
|
||||
retval = read_string(&rs->ampport, responsebuf, sizeof(responsebuf), ";", 1);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
if (strstr(responsebuf, "BYPASS") != 0)
|
||||
{
|
||||
int antenna2 = 0;
|
||||
nargs = sscanf(responsebuf, "AN%d Side TX %d %*s %*s %d", &antenna2, &int_value,
|
||||
&int_value2);
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s response='%s'\n", __func__, responsebuf);
|
||||
|
||||
if (nargs != 3)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s antenna=%d,nH=%d\n", __func__, antenna2,
|
||||
int_value);
|
||||
|
||||
val->i = level == AMP_LEVEL_NH ? int_value : int_value2;
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
while (strstr(responsebuf, "BYPASS"));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case AMP_LEVEL_PWR_INPUT:
|
||||
cmd = "^PWI;";
|
||||
int pwrinput;
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrinput);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrinput;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_FWD:
|
||||
cmd = "^PWF;";
|
||||
int pwrfwd;
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrfwd);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrfwd;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_REFLECTED:
|
||||
cmd = "^PWR;";
|
||||
int pwrref;
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrref);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrref;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_PWR_PEAK:
|
||||
cmd = "^PWK;";
|
||||
int pwrpeak;
|
||||
nargs = sscanf(responsebuf, "^SW%d", &pwrpeak);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
val->i = pwrpeak;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
case AMP_LEVEL_FAULT:
|
||||
cmd = "^SF;";
|
||||
int fault;
|
||||
nargs = sscanf(responsebuf, "^SW%d", &fault);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; kpa_fault_list[i].errmsg != NULL; ++i)
|
||||
{
|
||||
if (kpa_fault_list[i].code == fault)
|
||||
{
|
||||
val->s = kpa_fault_list[i].errmsg;
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_ERR, "%s unknown fault=%s\n", __func__, cmd, responsebuf);
|
||||
struct kpa_priv_data *priv = amp->state.priv;
|
||||
sprintf(priv->tmpbuf, "Unknown fault code=0x%02x", fault);
|
||||
val->s = priv->tmpbuf;
|
||||
return RIG_OK;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s unknown level=%s\n", __func__, cmd, level);
|
||||
|
||||
}
|
||||
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
int kpa_get_powerstat(AMP *amp, powerstat_t *status)
|
||||
{
|
||||
char responsebuf[KPABUFSZ];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
*status = RIG_POWER_UNKNOWN;
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
int retval = kpa_transaction(amp, "^ON;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
int ampon;
|
||||
int nargs = sscanf(responsebuf, "^ON%d", &on);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
switch (ampon)
|
||||
{
|
||||
case 0: *status = RIG_POWER_OFF; return RIG_OK;
|
||||
|
||||
case 1: *status = RIG_POWER_ON; break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON unknown response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
retval = kpa_transaction(amp, "^OP;", responsebuf, sizeof(responsebuf));
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
int operate;
|
||||
nargs = sscanf(responsebuf, "^ON%d", &operate);
|
||||
|
||||
if (nargs != 1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__,
|
||||
responsebuf);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
*status = operate == 1 ? RIG_POWER_OPERATE : RIG_POWER_STANDBY;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int kpa_set_powerstat(AMP *amp, powerstat_t status)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp) { return -RIG_EINVAL; }
|
||||
|
||||
char *cmd = NULL;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case RIG_POWER_UNKNOWN: break;
|
||||
|
||||
case RIG_POWER_OFF: cmd = "^ON0;"; break;
|
||||
|
||||
case RIG_POWER_ON: cmd = "^ON1;"; break;
|
||||
|
||||
case RIG_POWER_OPERATE: cmd = "^OS1;"; break;
|
||||
|
||||
case RIG_POWER_STANDBY: cmd = "^OS0;"; break;
|
||||
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s invalid status=%d\n", __func__, status);
|
||||
|
||||
}
|
||||
|
||||
int retval = kpa_transaction(amp, cmd, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK) { return retval; }
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
int kpa_reset(AMP *amp, amp_reset_t reset)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
// toggling from standby to operate supposed to reset
|
||||
int retval = kpa_set_powerstat(amp, RIG_POWER_STANDBY);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s error setting RIG_POWER_STANDBY\n", __func__,
|
||||
strerror(retval));
|
||||
|
||||
}
|
||||
|
||||
return kpa_set_powerstat(amp, RIG_POWER_OPERATE);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Hamlib backend library for the Elecraft amplifier set.
|
||||
*
|
||||
* elecraft.h - (C) Michael Black W9MDB 2019
|
||||
*
|
||||
* This shared library provides an API for communicating
|
||||
* via serial interface to Elecraft amplifiers.
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMP_ELECRAFT_H
|
||||
#define _AMP_ELECRAFT_H 1
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
#include <iofunc.h>
|
||||
#include <serial.h>
|
||||
|
||||
// Is this big enough?
|
||||
#define KPABUFSZ 100
|
||||
|
||||
extern const struct amp_caps kpa1500_rot_caps;
|
||||
|
||||
/*
|
||||
* Private data structure
|
||||
*/
|
||||
struct kpa_priv_data
|
||||
{
|
||||
char tmpbuf[256]; // for unknown error msg
|
||||
};
|
||||
|
||||
|
||||
int kpa_init(AMP *amp);
|
||||
int kpa_reset(AMP *amp, amp_reset_t reset);
|
||||
int kpa_flush_buffer(AMP *amp);
|
||||
int kpa_transaction(AMP *amp, const char *cmd, char *reponse, int reponse_len);
|
||||
const char *kpa_get_info (AMP *amp);
|
||||
int kpa_get_freq (AMP *amp, freq_t *freq);
|
||||
int kpa_set_freq (AMP *amp, freq_t freq);
|
||||
|
||||
int kpa_get_level (AMP *amp, setting_t level, value_t *val);
|
||||
int kpa_get_powerstat (AMP *amp, powerstat_t *status);
|
||||
int kpa_set_powerstat (AMP *amp, powerstat_t status);
|
||||
|
||||
#endif /* _AMP_ELECRAFT_H */
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Hamlib backend library for the Elecraft KPA1500 command set.
|
||||
*
|
||||
* kpa1500.c - (C) Michael Black W9MDB 2019
|
||||
*
|
||||
* This shared library provides an API for communicating
|
||||
* to an Elecraft KPA1500 amplifier.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* Standard library definitions */
|
||||
#include <string.h> /* String function definitions */
|
||||
|
||||
#include "register.h"
|
||||
|
||||
#include "kpa.h"
|
||||
|
||||
|
||||
struct kpa_priv_data *kpa1500_priv;
|
||||
/*
|
||||
* API local implementation
|
||||
*
|
||||
*/
|
||||
|
||||
static int kpa1500_init(AMP *amp);
|
||||
static int kpa1500_cleanup(AMP *amp);
|
||||
|
||||
/*
|
||||
* Private helper function prototypes
|
||||
*/
|
||||
|
||||
//static int kpa1500_send_priv_cmd(AMP *amp, const char *cmd);
|
||||
//static int kpa1500_flush_buffer(AMP *amp);
|
||||
|
||||
/* *************************************
|
||||
*
|
||||
* Separate model capabilities
|
||||
*
|
||||
* *************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Elecraft KPA1500
|
||||
*/
|
||||
|
||||
const struct amp_caps kpa1500_amp_caps =
|
||||
{
|
||||
.amp_model = AMP_MODEL_ELECRAFT_KPA1500,
|
||||
.model_name = "KPA1500",
|
||||
.mfg_name = "Elecraft",
|
||||
.version = "2019-05-26",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_ALPHA,
|
||||
.amp_type = AMP_TYPE_OTHER,
|
||||
.port_type = RIG_PORT_SERIAL,
|
||||
.serial_rate_min = 4800,
|
||||
.serial_rate_max = 230400,
|
||||
.serial_data_bits = 8,
|
||||
.serial_stop_bits = 1,
|
||||
.serial_parity = RIG_PARITY_NONE,
|
||||
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||
.write_delay = 0,
|
||||
.post_write_delay = 0,
|
||||
.timeout = 2000,
|
||||
.retry = 2,
|
||||
|
||||
.amp_open = amp_open,
|
||||
.amp_init = kpa1500_init,
|
||||
.amp_cleanup = kpa1500_cleanup,
|
||||
.reset = kpa_reset,
|
||||
.get_info = kpa_get_info,
|
||||
.get_powerstat = kpa_get_powerstat,
|
||||
.set_powerstat = kpa_set_powerstat,
|
||||
.set_freq = kpa_set_freq,
|
||||
.get_freq = kpa_get_freq,
|
||||
.get_level = kpa_get_level,
|
||||
};
|
||||
|
||||
|
||||
/* ************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
* ************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Initialize data structures
|
||||
*/
|
||||
|
||||
static int kpa1500_init(AMP *amp)
|
||||
{
|
||||
struct kpa_priv_data *priv;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
priv = (struct kpa_priv_data *)
|
||||
malloc(sizeof(struct kpa_priv_data));
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
amp->state.priv = (void *)priv;
|
||||
|
||||
amp->state.ampport.type.rig = RIG_PORT_SERIAL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up allocated memory structures
|
||||
*/
|
||||
|
||||
static int kpa1500_cleanup(AMP *amp)
|
||||
{
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (amp->state.priv)
|
||||
{
|
||||
free(amp->state.priv);
|
||||
}
|
||||
|
||||
amp->state.priv = NULL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Send command string to amplifier
|
||||
*/
|
||||
|
||||
static int kpa1500_send_priv_cmd(AMP *amp, const char *cmdstr)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
int err;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs = &->state;
|
||||
err = write_block(&rs->ampport, cmdstr, strlen(cmdstr));
|
||||
|
||||
if (err != RIG_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize backend
|
||||
*/
|
||||
|
||||
DECLARE_INITAMP_BACKEND(kpa1500)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
amp_register(&kpa1500_amp_caps);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
CC kpa.lo
|
||||
kpa.c: In function ‘kpa_get_freq’:
|
||||
kpa.c:150:12: warning: returning ‘const char *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
|
||||
return (const char *) - RIG_EINVAL;
|
||||
^
|
||||
kpa.c:153:3: error: ‘rs’ undeclared (first use in this function)
|
||||
rs = &->state;
|
||||
^~
|
||||
kpa.c:153:3: note: each undeclared identifier is reported only once for each function it appears in
|
||||
kpa.c:156:45: warning: passing argument 3 of ‘kpa_transaction’ makes integer from pointer without a cast [-Wint-conversion]
|
||||
int retval = kpa_transaction(amp, "^FR;", reponsebuf, sizeof(reponsebuf));
|
||||
^~~~~~~~~~
|
||||
kpa.c:68:52: note: expected ‘int’ but argument is of type ‘char *’
|
||||
int kpa_transaction(AMP *amp, const char *cmd, int cmd_len, char *response,
|
||||
~~~~^~~~~~~
|
||||
kpa.c:156:57: warning: passing argument 4 of ‘kpa_transaction’ makes pointer from integer without a cast [-Wint-conversion]
|
||||
int retval = kpa_transaction(amp, "^FR;", reponsebuf, sizeof(reponsebuf));
|
||||
^~~~~~~~~~~~~~~~~~
|
||||
kpa.c:68:67: note: expected ‘char *’ but argument is of type ‘long unsigned int’
|
||||
int kpa_transaction(AMP *amp, const char *cmd, int cmd_len, char *response,
|
||||
~~~~~~^~~~~~~~
|
||||
kpa.c:156:16: error: too few arguments to function ‘kpa_transaction’
|
||||
int retval = kpa_transaction(amp, "^FR;", reponsebuf, sizeof(reponsebuf));
|
||||
^~~~~~~~~~~~~~~
|
||||
kpa.c:68:5: note: declared here
|
||||
int kpa_transaction(AMP *amp, const char *cmd, int cmd_len, char *response,
|
||||
^~~~~~~~~~~~~~~
|
||||
kpa.c:160:12: error: ‘err’ undeclared (first use in this function)
|
||||
return err;
|
||||
^~~
|
||||
kpa.c:167:1: warning: control reaches end of non-void function [-Wreturn-type]
|
||||
}
|
||||
^
|
||||
make: *** [Makefile:479: kpa.lo] Error 1
|
18
configure.ac
18
configure.ac
|
@ -51,6 +51,8 @@ dnl rotor definitions, e.g. "dummy". Optional backends will not be listed
|
|||
dnl here but will be added later, e.g. "winradio".
|
||||
BACKEND_LIST="adat alinco aor barrett dorji drake dummy elad flexradio icom icmarine jrc kachina kenwood kit lowe pcr prm80 racal rft rs skanti tapr tentec tuner uniden wj yaesu"
|
||||
ROT_BACKEND_LIST="amsat ars celestron cnctrk easycomm ether6 fodtrack gs232a heathkit m2 meade rotorez sartek spid ts7400 prosistel ioptron"
|
||||
# Amplifiers are all in the amplifiers directory
|
||||
AMP_BACKEND_LIST="amplifiers/elecraft"
|
||||
|
||||
dnl See README.release on setting these values
|
||||
# Values given to -version-info when linking. See libtool documentation.
|
||||
|
@ -721,6 +723,21 @@ done
|
|||
AC_SUBST([ROT_BACKEND_LIST])
|
||||
AC_SUBST([ROT_BACKENDEPS])
|
||||
|
||||
## ---------------------------------- ##
|
||||
## Prepare amplifier backend dependencies ##
|
||||
## ---------------------------------- ##
|
||||
|
||||
# otherwise parallel 'make -jn' will fail
|
||||
|
||||
for be in ${AMP_BACKEND_LIST} ; do
|
||||
AMPDIR=`echo $be | awk -F "/" '{print $2}'`
|
||||
AMP_BACKENDEPS="${AMP_BACKENDEPS} \$(top_builddir)/amplifiers/${AMPDIR}/libhamlib-${AMPDIR}.la"
|
||||
done
|
||||
|
||||
AC_SUBST([AMP_BACKEND_LIST])
|
||||
AC_SUBST([AMP_BACKENDEPS])
|
||||
|
||||
|
||||
|
||||
## ------------ ##
|
||||
## Final output ##
|
||||
|
@ -790,6 +807,7 @@ dorji/Makefile
|
|||
barrett/Makefile
|
||||
meade/Makefile
|
||||
ioptron/Makefile
|
||||
amplifiers/elecraft/Makefile
|
||||
hamlib.pc
|
||||
])
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DUMMYSRC = dummy.c dummy.h rot_dummy.c rot_dummy.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h
|
||||
DUMMYSRC = dummy.c dummy.h rot_dummy.c rot_dummy.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h amp_dummy.c amp_dummy.h netampctl.c
|
||||
|
||||
noinst_LTLIBRARIES = libhamlib-dummy.la
|
||||
libhamlib_dummy_la_SOURCES = $(DUMMYSRC)
|
||||
|
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Hamlib Dummy backend - main file
|
||||
* Copyright (c) 2001-2009 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* String function definitions */
|
||||
#include <unistd.h> /* UNIX standard function definitions */
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "hamlib/amplifier.h"
|
||||
#include "serial.h"
|
||||
#include "misc.h"
|
||||
#include "register.h"
|
||||
|
||||
#include "amp_dummy.h"
|
||||
|
||||
#if 0
|
||||
static const struct confparams dummy_amp_ext_levels[] =
|
||||
{
|
||||
{
|
||||
AMP_LEVEL_SWR, "SWR", "SWR", "SWR",
|
||||
NULL, RIG_CONF_NUMERIC, { .n = { 1, 99, .1 } }
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#define AMP_LEVELS (AMP_LEVEL_SWR|AMP_LEVEL_PF|AMP_LEVEL_NH|AMP_LEVEL_PWR_INPUT|AMP_LEVEL_PWR_FWD|AMP_LEVEL_PWR_REFLECTED|AMP_LEVEL_PWR_PEAK|AMP_LEVEL_FAULT)
|
||||
|
||||
struct dummy_amp_priv_data
|
||||
{
|
||||
freq_t freq;
|
||||
powerstat_t powerstat;
|
||||
};
|
||||
|
||||
|
||||
static int dummy_amp_init(AMP *amp)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv;
|
||||
|
||||
priv = (struct dummy_amp_priv_data *)
|
||||
malloc(sizeof(struct dummy_amp_priv_data));
|
||||
|
||||
if (!priv)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
amp->state.priv = (void *)priv;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
amp->state.ampport.type.rig = RIG_PORT_NONE;
|
||||
|
||||
priv->freq = 0;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int dummy_amp_cleanup(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (amp->state.priv)
|
||||
{
|
||||
free(amp->state.priv);
|
||||
}
|
||||
|
||||
amp->state.priv = NULL;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int dummy_amp_open(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int dummy_amp_close(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int dummy_amp_reset(AMP *amp, amp_reset_t reset)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
switch (reset)
|
||||
{
|
||||
case AMP_RESET_MEM:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "Reset memory\n");
|
||||
break;
|
||||
|
||||
case AMP_RESET_FAULT:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "Reset fault\n");
|
||||
break;
|
||||
|
||||
case AMP_RESET_AMP:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "Reset amplifier\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "Reset unknown=%d\n", reset);
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
^ON1 turns amp on
|
||||
^ON0 turns amp off
|
||||
^OP0 amp in standby
|
||||
^OP1 amp in operate
|
||||
|
||||
^PWF which gets forward power from amp. Reply would be ^PWFnnnn format
|
||||
|
||||
^PWK which gets peak forward power. Response is ^PWKnnnn
|
||||
|
||||
^PWR peak reflected power. Response is ^PWRnnnn
|
||||
|
||||
^SW gets SWR. Response is ^SWnnn. Example return of ^SW025 would be 2.5:1
|
||||
|
||||
Also a way to display faults (there are commands)
|
||||
*/
|
||||
|
||||
static int dummy_amp_get_freq(AMP *amp, freq_t *freq)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *)
|
||||
amp->state.priv;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
*freq = priv->freq;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int dummy_amp_set_freq(AMP *amp, freq_t freq)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *)
|
||||
amp->state.priv;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
priv->freq = freq;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static const char *dummy_amp_get_info(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
return "Dummy amplifier";
|
||||
}
|
||||
|
||||
static int dummy_amp_get_level(AMP *amp, setting_t level, value_t *val)
|
||||
{
|
||||
static int flag = 1;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
flag = !flag;
|
||||
|
||||
// values toggle between two expected min/~max values for dev purposes
|
||||
switch (level)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_SWR\n", __func__);
|
||||
val->f = flag == 0 ? 1.0 : 99.0;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_PF:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PF\n", __func__);
|
||||
val->f = flag == 0 ? 0 : 2701.2;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_NH:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_UH\n", __func__);
|
||||
val->i = flag == 0 ? 0 : 8370;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_PWR_INPUT:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRINPUT\n", __func__);
|
||||
val->i = flag == 0 ? 0 : 1499 ;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_PWR_FWD:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRFWD\n", __func__);
|
||||
val->i = flag == 0 ? 0 : 1499 ;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_PWR_REFLECTED:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRREFLECTED\n", __func__);
|
||||
val->i = flag == 0 ? 0 : 1499 ;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_PWR_PEAK:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRPEAK\n", __func__);
|
||||
val->i = flag == 0 ? 0 : 1500 ;
|
||||
return RIG_OK;
|
||||
|
||||
case AMP_LEVEL_FAULT:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_FAULT\n", __func__);
|
||||
val->s = flag == 0 ? "No Fault" : "SWR too high"; // SWR too high for KPA1500
|
||||
return RIG_OK;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s Unknownd AMP_LEVEL=%d\n", __func__, level);
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s flag=%d\n", __func__, flag);
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
static int dummy_amp_set_powerstat(AMP *amp, powerstat_t status)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *)
|
||||
amp->state.priv;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case RIG_POWER_OFF:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OFF\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case RIG_POWER_ON:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_ON\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case RIG_POWER_STANDBY:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_STANDBY\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case RIG_POWER_OPERATE:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OPERATE\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case RIG_POWER_UNKNOWN:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_UNKNOWN\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called invalid power status=%d\n",
|
||||
__FUNCTION__, status);
|
||||
return -RIG_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
priv->powerstat = status;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
static int dummy_amp_get_powerstat(AMP *amp, powerstat_t *status)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *)
|
||||
amp->state.priv;
|
||||
|
||||
*status = priv->powerstat;
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int dummy_amp_get_ext_level(AMP *amp, token_t token, value_t *val)
|
||||
{
|
||||
struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *)
|
||||
amp->state.priv;
|
||||
const struct confparams *cfp;
|
||||
struct ext_list *elp;
|
||||
|
||||
cfp = amp_ext_lookup_tok(amp, token);
|
||||
|
||||
if (!cfp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case AMP_LEVEL_SWR:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
elp = find_ext(curr->ext_levels, token);
|
||||
|
||||
if (!elp)
|
||||
{
|
||||
return -RIG_EINTERNAL;
|
||||
}
|
||||
|
||||
/* load value */
|
||||
*val = elp->val;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __FUNCTION__,
|
||||
cfp->name);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Dummy amplifier capabilities.
|
||||
*/
|
||||
|
||||
const struct amp_caps dummy_amp_caps =
|
||||
{
|
||||
.amp_model = AMP_MODEL_DUMMY,
|
||||
.model_name = "Dummy",
|
||||
.mfg_name = "Hamlib",
|
||||
.version = "0.1",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_ALPHA,
|
||||
.amp_type = AMP_TYPE_OTHER,
|
||||
.port_type = RIG_PORT_NONE,
|
||||
|
||||
.has_get_level = AMP_LEVELS,
|
||||
.has_set_level = RIG_LEVEL_SET(AMP_LEVELS),
|
||||
|
||||
.priv = NULL, /* priv */
|
||||
|
||||
.amp_init = dummy_amp_init,
|
||||
.amp_cleanup = dummy_amp_cleanup,
|
||||
.amp_open = dummy_amp_open,
|
||||
.amp_close = dummy_amp_close,
|
||||
|
||||
.get_freq = dummy_amp_get_freq,
|
||||
.set_freq = dummy_amp_set_freq,
|
||||
.get_info = dummy_amp_get_info,
|
||||
.get_level = dummy_amp_get_level,
|
||||
|
||||
.set_powerstat = dummy_amp_set_powerstat,
|
||||
.get_powerstat = dummy_amp_get_powerstat,
|
||||
|
||||
.reset = dummy_amp_reset,
|
||||
|
||||
};
|
||||
|
||||
DECLARE_INITAMP_BACKEND(dummy)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "dummy: _init called\n");
|
||||
|
||||
amp_register(&dummy_amp_caps);
|
||||
amp_register(&netampctl_caps);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Hamlib Dummy backend - main header
|
||||
* Copyright (c) 2001-2008 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMP_DUMMY_H
|
||||
#define _AMP_DUMMY_H 1
|
||||
|
||||
|
||||
extern const struct amp_caps dummy_amp_caps;
|
||||
extern const struct amp_caps netampctl_caps;
|
||||
|
||||
#endif /* _AMP_DUMMY_H */
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Hamlib Netampctl backend - main file
|
||||
* Copyright (c) 2001-2009 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* String function definitions */
|
||||
#include <unistd.h> /* UNIX standard function definitions */
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "hamlib/amplifier.h"
|
||||
#include "iofunc.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "amp_dummy.h"
|
||||
|
||||
#define CMD_MAX 32
|
||||
#define BUF_MAX 64
|
||||
|
||||
/*
|
||||
* Helper function with protocol return code parsing
|
||||
*/
|
||||
static int netampctl_transaction(AMP *amp, char *cmd, int len, char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = write_block(&->state.ampport, cmd, len);
|
||||
|
||||
if (ret != RIG_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = read_string(&->state.ampport, buf, BUF_MAX, "\n", sizeof("\n"));
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!memcmp(buf, NETAMPCTL_RET, strlen(NETAMPCTL_RET)))
|
||||
{
|
||||
return atoi(buf + strlen(NETAMPCTL_RET));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int netampctl_open(AMP *amp)
|
||||
{
|
||||
int ret, len;
|
||||
//struct amp_state *rs = &->state;
|
||||
int pamp_ver;
|
||||
char cmd[CMD_MAX];
|
||||
char buf[BUF_MAX];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
|
||||
|
||||
len = sprintf(cmd, "\\dump_state\n");
|
||||
|
||||
ret = netampctl_transaction(amp, cmd, len, buf);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
return (ret < 0) ? ret : -RIG_EPROTO;
|
||||
}
|
||||
|
||||
pamp_ver = atoi(buf);
|
||||
#define AMPCTLD_PAMP_VER 0
|
||||
|
||||
if (pamp_ver < AMPCTLD_PAMP_VER)
|
||||
{
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
ret = read_string(&->state.ampport, buf, BUF_MAX, "\n", sizeof("\n"));
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
return (ret < 0) ? ret : -RIG_EPROTO;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
ret = read_string(&->state.ampport, buf, BUF_MAX, "\n", sizeof("\n"));
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
return (ret < 0) ? ret : -RIG_EPROTO;
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called, string=%s\n", __FUNCTION__, buf);
|
||||
}
|
||||
while (ret > 0);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int netampctl_close(AMP *amp)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
|
||||
/* clean signoff, no read back */
|
||||
write_block(&->state.ampport, "q\n", 2);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int netampctl_set_freq(AMP *amp, freq_t freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
static int netampctl_get_freq(AMP *amp, freq_t *freq)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
*freq = 12345;
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int netampctl_reset(AMP *amp, amp_reset_t reset)
|
||||
{
|
||||
int ret, len;
|
||||
char cmd[CMD_MAX];
|
||||
char buf[BUF_MAX];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
|
||||
len = sprintf(cmd, "R %d\n", reset);
|
||||
|
||||
ret = netampctl_transaction(amp, cmd, len, buf);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *netampctl_get_info(AMP *amp)
|
||||
{
|
||||
int ret, len;
|
||||
char cmd[CMD_MAX];
|
||||
static char buf[BUF_MAX];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||
|
||||
len = sprintf(cmd, "_\n");
|
||||
|
||||
ret = netampctl_transaction(amp, cmd, len, buf);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf [ret] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NET ampctl capabilities.
|
||||
*/
|
||||
|
||||
const struct amp_caps netampctl_caps =
|
||||
{
|
||||
.amp_model = AMP_MODEL_NETAMPCTL,
|
||||
.model_name = "NET ampctl",
|
||||
.mfg_name = "Hamlib",
|
||||
.version = "0.1",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_ALPHA,
|
||||
.amp_type = AMP_TYPE_OTHER,
|
||||
.port_type = RIG_PORT_NETWORK,
|
||||
.timeout = 2000,
|
||||
.retry = 3,
|
||||
|
||||
.priv = NULL, /* priv */
|
||||
|
||||
/* .amp_init = netampctl_init, */
|
||||
/* .amp_cleanup = netampctl_cleanup, */
|
||||
.amp_open = netampctl_open,
|
||||
.amp_close = netampctl_close,
|
||||
|
||||
.get_freq = netampctl_get_freq,
|
||||
.set_freq = netampctl_set_freq,
|
||||
|
||||
.get_info = netampctl_get_info
|
||||
};
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Hamlib C++ bindings - rotator API header
|
||||
* Copyright (c) 2002 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ROTCLASS_H
|
||||
#define _ROTCLASS_H 1
|
||||
|
||||
#include <hamlib/rotator.h>
|
||||
|
||||
|
||||
|
||||
class BACKEND_IMPEXP Rotator
|
||||
{
|
||||
private:
|
||||
ROT *theRot; // Global ref. to the rot
|
||||
|
||||
protected:
|
||||
public:
|
||||
Rotator(rot_model_t rot_model);
|
||||
|
||||
virtual ~Rotator();
|
||||
|
||||
const struct rot_caps *caps;
|
||||
|
||||
// This method opens the communication port to the rot
|
||||
void open(void);
|
||||
|
||||
// This method closes the communication port to the rot
|
||||
void close(void);
|
||||
|
||||
void setConf(token_t token, const char *val);
|
||||
void setConf(const char *name, const char *val);
|
||||
void getConf(token_t token, char *val);
|
||||
void getConf(const char *name, char *val);
|
||||
token_t tokenLookup(const char *name);
|
||||
|
||||
void setPosition(azimuth_t az, elevation_t el);
|
||||
void getPosition(azimuth_t& az, elevation_t& el);
|
||||
void stop();
|
||||
void park();
|
||||
void reset(rot_reset_t reset);
|
||||
|
||||
void move(int direction, int speed);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _ROTCLASS_H
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Hamlib Interface - Amplifier API header
|
||||
* Copyright (c) 2000-2005 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMPLIFIER_H
|
||||
#define _AMPLIFIER_H 1
|
||||
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/amplist.h>
|
||||
|
||||
/**
|
||||
* \addtogroup amp
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file amp.h
|
||||
* \brief Hamlib amplifier data structures.
|
||||
*
|
||||
* This file contains the data structures and declarations for the Hamlib
|
||||
* amplifier API. see the amplifier.c file for more details on the amplifier API.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Forward struct references */
|
||||
|
||||
struct amp;
|
||||
struct amp_state;
|
||||
|
||||
|
||||
/**
|
||||
* \typedef typedef struct amp AMP
|
||||
* \brief Amplifier structure definition (see amp for details).
|
||||
*/
|
||||
typedef struct amp AMP;
|
||||
|
||||
|
||||
/**
|
||||
* \typedef typedef float swr_t
|
||||
* \brief Type definition for SWR.
|
||||
*
|
||||
* The swr_t type is used as a parameter for the amp_get_swr() function.
|
||||
*
|
||||
* Unless specified otherwise, the unit of swr_t is 1.0 to max reported by tuner
|
||||
*/
|
||||
typedef float swr_t;
|
||||
|
||||
|
||||
/**
|
||||
* \typedef typedef float tune_value_t
|
||||
* \brief Type definition for tuning values capacitance and resistance.
|
||||
*
|
||||
* The tune_value_t type is used as a parameter for the amp_get_level()
|
||||
*
|
||||
* Unless specified otherwise, the units of tune_value_t is pF and nH
|
||||
*/
|
||||
typedef int tune_value_t;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Token in the netampctl protocol for returning error code
|
||||
*/
|
||||
#define NETAMPCTL_RET "RPRT "
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AMP_RESET_MEM, // erase tuner memory
|
||||
AMP_RESET_FAULT, // reset any fault
|
||||
AMP_RESET_AMP // for kpa1500
|
||||
} amp_reset_t;
|
||||
|
||||
/**
|
||||
* \brief Amplifier type flags
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AMP_FLAG_1 = (1 << 1), /*!< TBD */
|
||||
AMP_FLAG_2 = (1 << 2) /*!< TBD */
|
||||
} amp_type_t;
|
||||
|
||||
// TBD AMP_TYPE
|
||||
#define AMP_TYPE_MASK (AMP_FLAG_1|AMP_FLAG_2)
|
||||
|
||||
#define AMP_TYPE_OTHER 0
|
||||
#define AMP_TYPE_1 AMP_FLAG_1
|
||||
#define AMP_TYPE_2 AMP_FLAG_2
|
||||
#define AMP_TYPE_ALL (AMP_FLAG_1|AMP_FLAG_2)
|
||||
|
||||
|
||||
enum amp_level_e
|
||||
{
|
||||
AMP_LEVEL_NONE = 0, /*!< '' -- No Level */
|
||||
AMP_LEVEL_SWR = (1 << 0), /*!< \c SWR 1.0 or greater */
|
||||
AMP_LEVEL_NH = (1 << 1), /*!< \c Tune setting nanohenries */
|
||||
AMP_LEVEL_PF = (1 << 2), /*!< \c Tune setting picofarads */
|
||||
AMP_LEVEL_PWR_INPUT = (1 << 3), /*!< \c Power reading from amp */
|
||||
AMP_LEVEL_PWR_FWD = (1 << 4), /*!< \c Power reading forward */
|
||||
AMP_LEVEL_PWR_REFLECTED = (1 << 5), /*!< \c Power reading reverse */
|
||||
AMP_LEVEL_PWR_PEAK = (1 << 6), /*!< \c Power reading peak */
|
||||
AMP_LEVEL_FAULT = (1 << 7) /*!< \c Fault code */
|
||||
};
|
||||
|
||||
#define AMP_LEVEL_FLOAT_LIST (AMP_LEVEL_SWR)
|
||||
#define AMP_LEVEL_STRING_LIST (AMP_LEVEL_FAULT)
|
||||
#define AMP_LEVEL_IS_FLOAT(l) ((l)&_LEVEL_FLOAT_LIST)
|
||||
#define AMP_LEVEL_IS_STRING(l) ((l)&_LEVEL_STRING_LIST)
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_UP
|
||||
* \brief A macro that returns the flag for the \b UP direction.
|
||||
*
|
||||
* This macro defines the value of the \b UP direction which can be
|
||||
* used with the amp_move() function.
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_DOWN, AMP_MOVE_LEFT, AMP_MOVE_CCW,
|
||||
* AMP_MOVE_RIGHT, AMP_MOVE_CW
|
||||
*/
|
||||
#define AMP_MOVE_UP (1<<1)
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_DOWN
|
||||
* \brief A macro that returns the flag for the \b DOWN direction.
|
||||
*
|
||||
* This macro defines the value of the \b DOWN direction which can be
|
||||
* used with the amp_move() function.
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_UP, AMP_MOVE_LEFT, AMP_MOVE_CCW, AMP_MOVE_RIGHT,
|
||||
* AMP_MOVE_CW
|
||||
*/
|
||||
#define AMP_MOVE_DOWN (1<<2)
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_LEFT
|
||||
* \brief A macro that returns the flag for the \b LEFT direction.
|
||||
*
|
||||
* This macro defines the value of the \b LEFT direction which can be
|
||||
* used with the amp_move function.
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_UP, AMP_MOVE_DOWN, AMP_MOVE_CCW, AMP_MOVE_RIGHT,
|
||||
* AMP_MOVE_CW
|
||||
*/
|
||||
#define AMP_MOVE_LEFT (1<<3)
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_CCW
|
||||
* \brief A macro that returns the flag for the \b counterclockwise direction.
|
||||
*
|
||||
* This macro defines the value of the \b counterclockwise direction which
|
||||
* can be used with the amp_move() function. This value is equivalent to
|
||||
* AMP_MOVE_LEFT .
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_UP, AMP_MOVE_DOWN, AMP_MOVE_LEFT, AMP_MOVE_RIGHT,
|
||||
* AMP_MOVE_CW
|
||||
*/
|
||||
#define AMP_MOVE_CCW AMP_MOVE_LEFT
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_RIGHT
|
||||
* \brief A macro that returns the flag for the \b RIGHT direction.
|
||||
*
|
||||
* This macro defines the value of the \b RIGHT direction which can be used
|
||||
* with the amp_move() function.
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_UP, AMP_MOVE_DOWN, AMP_MOVE_LEFT, AMP_MOVE_CCW,
|
||||
* AMP_MOVE_CW
|
||||
*/
|
||||
#define AMP_MOVE_RIGHT (1<<4)
|
||||
|
||||
/**
|
||||
* \def AMP_MOVE_CW
|
||||
* \brief A macro that returns the flag for the \b clockwise direction.
|
||||
*
|
||||
* This macro defines the value of the \b clockwise direction wich can be
|
||||
* used with the amp_move() function. This value is equivalent to
|
||||
* AMP_MOVE_RIGHT .
|
||||
*
|
||||
* \sa amp_move(), AMP_MOVE_UP, AMP_MOVE_DOWN, AMP_MOVE_LEFT, AMP_MOVE_CCW,
|
||||
* AMP_MOVE_RIGHT
|
||||
*/
|
||||
#define AMP_MOVE_CW AMP_MOVE_RIGHT
|
||||
|
||||
|
||||
/* Basic amp type, can store some useful info about different amplifiers. Each
|
||||
* lib must be able to populate this structure, so we can make useful
|
||||
* enquiries about capablilities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Amplifier Caps
|
||||
* \struct amp_caps
|
||||
* \brief Amplifier data structure.
|
||||
*
|
||||
* The main idea of this struct is that it will be defined by the backend
|
||||
* amplifier driver, and will remain readonly for the application. Fields that
|
||||
* need to be modifiable by the application are copied into the struct
|
||||
* amp_state, which is a kind of private of the AMP instance.
|
||||
*
|
||||
* This way, you can have several rigs running within the same application,
|
||||
* sharing the struct amp_caps of the backend, while keeping their own
|
||||
* customized data.
|
||||
*
|
||||
* n.b.: Don't move fields around, as the backends depend on it when
|
||||
* initializing their caps.
|
||||
*/
|
||||
struct amp_caps
|
||||
{
|
||||
amp_model_t amp_model; /*!< Amplifier model. */
|
||||
const char *model_name; /*!< Model name. */
|
||||
const char *mfg_name; /*!< Manufacturer. */
|
||||
const char *version; /*!< Driver version. */
|
||||
const char *copyright; /*!< Copyright info. */
|
||||
enum rig_status_e status; /*!< Driver status. */
|
||||
|
||||
int amp_type; /*!< Amplifier type. */
|
||||
enum rig_port_e port_type; /*!< Type of communication port. */
|
||||
|
||||
int serial_rate_min; /*!< Minimal serial speed. */
|
||||
int serial_rate_max; /*!< Maximal serial speed. */
|
||||
int serial_data_bits; /*!< Number of data bits. */
|
||||
int serial_stop_bits; /*!< Number of stop bits. */
|
||||
enum serial_parity_e serial_parity; /*!< Parity. */
|
||||
enum serial_handshake_e serial_handshake; /*!< Handshake. */
|
||||
|
||||
int write_delay; /*!< Write delay. */
|
||||
int post_write_delay; /*!< Post-write delay. */
|
||||
int timeout; /*!< Timeout. */
|
||||
int retry; /*!< Number of retry if command fails. */
|
||||
|
||||
const struct confparams *cfgparams; /*!< Configuration parametres. */
|
||||
const rig_ptr_t priv; /*!< Private data. */
|
||||
|
||||
setting_t has_get_level;
|
||||
setting_t has_set_level;
|
||||
|
||||
gran_t level_gran[RIG_SETTING_MAX]; /*!< level granularity */
|
||||
gran_t parm_gran[RIG_SETTING_MAX]; /*!< level granularity */
|
||||
|
||||
/*
|
||||
* Amp Admin API
|
||||
*
|
||||
*/
|
||||
|
||||
int (*amp_init)(AMP *amp);
|
||||
int (*amp_cleanup)(AMP *amp);
|
||||
int (*amp_open)(AMP *amp);
|
||||
int (*amp_close)(AMP *amp);
|
||||
|
||||
int (*set_freq)(AMP *amp, freq_t val);
|
||||
int (*get_freq)(AMP *amp, freq_t *val);
|
||||
|
||||
int (*set_conf)(AMP *amp, token_t token, const char *val);
|
||||
int (*get_conf)(AMP *amp, token_t token, char *val);
|
||||
|
||||
/*
|
||||
* General API commands, from most primitive to least.. :()
|
||||
* List Set/Get functions pairs
|
||||
*/
|
||||
|
||||
int (*reset)(AMP *amp, amp_reset_t reset);
|
||||
int (*get_level)(AMP *amp, setting_t level, value_t *val);
|
||||
int (*get_ext_level)(AMP *amp, token_t level, value_t *val);
|
||||
int (*set_powerstat)(AMP *amp, powerstat_t status);
|
||||
int (*get_powerstat)(AMP *amp, powerstat_t *status);
|
||||
|
||||
|
||||
/* get firmware info, etc. */
|
||||
const char *(*get_info)(AMP *amp);
|
||||
|
||||
setting_t levels;
|
||||
unsigned ext_levels;
|
||||
const struct confparams *extlevels;
|
||||
const struct confparams *extparms;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Amplifier state
|
||||
* \struct amp_state
|
||||
* \brief Live data and customized fields.
|
||||
*
|
||||
* This struct contains live data, as well as a copy of capability fields
|
||||
* that may be updated (ie. customized)
|
||||
*
|
||||
* It is fine to move fields around, as this kind of struct should
|
||||
* not be initialized like caps are.
|
||||
*/
|
||||
struct amp_state
|
||||
{
|
||||
/*
|
||||
* overridable fields
|
||||
*/
|
||||
|
||||
/*
|
||||
* non overridable fields, internal use
|
||||
*/
|
||||
hamlib_port_t ampport; /*!< Amplifier port (internal use). */
|
||||
|
||||
int comm_state; /*!< Comm port state, opened/closed. */
|
||||
rig_ptr_t priv; /*!< Pointer to private amplifier state data. */
|
||||
rig_ptr_t obj; /*!< Internal use by hamlib++ for event handling. */
|
||||
|
||||
setting_t has_get_level;
|
||||
|
||||
gran_t level_gran[RIG_SETTING_MAX]; /*!< level granularity */
|
||||
gran_t parm_gran[RIG_SETTING_MAX]; /*!< level granularity */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Amplifier structure
|
||||
* \struct amp
|
||||
* \brief This is the master data structure,
|
||||
* acting as a handle for the controlled amplifier.
|
||||
*
|
||||
* This is the master data structure, acting as a handle for the controlled
|
||||
* amplifier. A pointer to this structure is returned by the amp_init() API
|
||||
* function and is passed as a parameter to every amplifier specific API call.
|
||||
*
|
||||
* \sa amp_init(), amp_caps(), amp_state()
|
||||
*/
|
||||
struct amp
|
||||
{
|
||||
struct amp_caps *caps; /*!< Amplifier caps. */
|
||||
struct amp_state state; /*!< Amplifier state. */
|
||||
};
|
||||
|
||||
|
||||
/* --------------- API function prototypes -----------------*/
|
||||
|
||||
extern HAMLIB_EXPORT(AMP *)
|
||||
amp_init HAMLIB_PARAMS((amp_model_t amp_model));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_open HAMLIB_PARAMS((AMP *amp));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_close HAMLIB_PARAMS((AMP *amp));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_cleanup HAMLIB_PARAMS((AMP *amp));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_set_conf HAMLIB_PARAMS((AMP *amp,
|
||||
token_t token,
|
||||
const char *val));
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_get_conf HAMLIB_PARAMS((AMP *amp,
|
||||
token_t token,
|
||||
char *val));
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_set_powerstat HAMLIB_PARAMS((AMP *amp,
|
||||
powerstat_t status));
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_get_powerstat HAMLIB_PARAMS((AMP *amp,
|
||||
powerstat_t *status));
|
||||
|
||||
|
||||
/*
|
||||
* General API commands, from most primitive to least.. )
|
||||
* List Set/Get functions pairs
|
||||
*/
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_get_freq HAMLIB_PARAMS((AMP *amp,
|
||||
freq_t *freq));
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_set_freq HAMLIB_PARAMS((AMP *amp,
|
||||
freq_t freq));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_reset HAMLIB_PARAMS((AMP *amp,
|
||||
amp_reset_t reset));
|
||||
|
||||
extern HAMLIB_EXPORT(const char *)
|
||||
amp_get_info HAMLIB_PARAMS((AMP *amp));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_get_level HAMLIB_PARAMS((AMP *amp, setting_t level, value_t *val));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_register HAMLIB_PARAMS((const struct amp_caps *caps));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_unregister HAMLIB_PARAMS((amp_model_t amp_model));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_list_foreach HAMLIB_PARAMS((int (*cfunc)(const struct amp_caps *,
|
||||
rig_ptr_t),
|
||||
rig_ptr_t data));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_load_backend HAMLIB_PARAMS((const char *be_name));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_check_backend HAMLIB_PARAMS((amp_model_t amp_model));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_load_all_backends HAMLIB_PARAMS((void));
|
||||
|
||||
extern HAMLIB_EXPORT(amp_model_t)
|
||||
amp_probe_all HAMLIB_PARAMS((hamlib_port_t *p));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_token_foreach HAMLIB_PARAMS((AMP *amp,
|
||||
int (*cfunc)(const struct confparams *,
|
||||
rig_ptr_t),
|
||||
rig_ptr_t data));
|
||||
|
||||
extern HAMLIB_EXPORT(const struct confparams *)
|
||||
amp_confparam_lookup HAMLIB_PARAMS((AMP *amp,
|
||||
const char *name));
|
||||
|
||||
extern HAMLIB_EXPORT(token_t)
|
||||
amp_token_lookup HAMLIB_PARAMS((AMP *amp,
|
||||
const char *name));
|
||||
|
||||
extern HAMLIB_EXPORT(const struct amp_caps *)
|
||||
amp_get_caps HAMLIB_PARAMS((amp_model_t amp_model));
|
||||
|
||||
extern HAMLIB_EXPORT(setting_t)
|
||||
amp_has_get_level HAMLIB_PARAMS((AMP *amp,
|
||||
setting_t level));
|
||||
|
||||
extern HAMLIB_EXPORT(const struct confparams *)
|
||||
amp_ext_lookup HAMLIB_PARAMS((AMP *amp,
|
||||
const char *name));
|
||||
|
||||
extern HAMLIB_EXPORT(int)
|
||||
amp_get_ext_level HAMLIB_PARAMS((AMP *amp,
|
||||
token_t token,
|
||||
value_t *val));
|
||||
|
||||
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));
|
||||
|
||||
|
||||
/**
|
||||
* \def amp_debug
|
||||
* \brief Convenience definition for debug level.
|
||||
*
|
||||
* This is just as convenience definition of the amplifier debug level,
|
||||
* and is the same as for the rig debug level.
|
||||
*
|
||||
* \sa rig_debug()
|
||||
*/
|
||||
#define amp_debug rig_debug
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _AMPLIFIER_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Hamlib Interface - list of known amplifiers
|
||||
* Copyright (c) 2000-2011 by Stephane Fillod
|
||||
* Copyright (c) 2000-2002 by Frank Singleton
|
||||
* Copyright (C) 2019 by Michael Black W9MDB. Derived from rotlist.h
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMPLIST_H
|
||||
#define _AMPLIST_H 1
|
||||
|
||||
#define AMP_MAKE_MODEL(a,b) ((a)*100+(b))
|
||||
#define AMP_BACKEND_NUM(a) ((a)/100)
|
||||
|
||||
|
||||
/**
|
||||
* \addtogroup amplifier
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file rotlist.h
|
||||
* \brief Hamlib amplifier model definitions.
|
||||
*
|
||||
* This file contains amplifier model definitions for the Hamlib amplifier API.
|
||||
* Each distinct amplifier type has a unique model number (ID) and is used by
|
||||
* hamlib to identify and distinguish between the different hardware drivers.
|
||||
* The exact model numbers can be acquired using the macros in this file. To
|
||||
* obtain a list of supported amplifier branches, one can use the statically
|
||||
* defined AMP_BACKEND_LIST macro. To obtain a full list of supported
|
||||
* amplifier (including each model in every branch), the foreach_opened_rot()
|
||||
* API function can be used.
|
||||
*
|
||||
* The model number, or ID, is used to tell Hamlib which amplifier the client
|
||||
* whishes to use. It is done with the amp_init() API call.
|
||||
*/
|
||||
|
||||
|
||||
#define AMP_MODEL_NONE 0
|
||||
|
||||
|
||||
/**
|
||||
* \def AMP_MODEL_DUMMY
|
||||
* \brief A macro that returns the model number for the dummy backend.
|
||||
*
|
||||
* The dummy backend, as the name suggests, is a backend which performs
|
||||
* no hardware operations and always behaves as one would expect. It can
|
||||
* be thought of as a hardware simulator and is very usefull for testing
|
||||
* client applications.
|
||||
*/
|
||||
/**
|
||||
* \def AMP_MODEL_NETAMPCTL
|
||||
* \brief A macro that returns the model number for the Network backend.
|
||||
*
|
||||
* This backend allows use of the rotctld daemon through the normal
|
||||
* Hamlib API.
|
||||
*/
|
||||
#define AMP_DUMMY 0
|
||||
#define AMP_BACKEND_DUMMY "dummy"
|
||||
#define AMP_MODEL_DUMMY AMP_MAKE_MODEL(AMP_DUMMY, 1)
|
||||
#define AMP_MODEL_NETAMPCTL AMP_MAKE_MODEL(AMP_DUMMY, 2)
|
||||
|
||||
|
||||
/*
|
||||
* Elecraft
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def AMP_MODEL_ELECRAFT1
|
||||
* \brief A macro that returns the model number of the EasyComm 1 backend.
|
||||
*
|
||||
* The Elecraft 1 backend can be used with amplifiers that support the
|
||||
* KPA1500 protocol.
|
||||
*/
|
||||
#define AMP_ELECRAFT 2
|
||||
#define AMP_BACKEND_ELECRAFT "elecraft"
|
||||
#define AMP_MODEL_ELECRAFT_KPA1500 AMP_MAKE_MODEL(AMP_ELECRAFT, 1)
|
||||
//#define AMP_MODEL_ELECRAFT_KPA500 AMP_MAKE_MODEL(AMP_ELECRAFT, 2)
|
||||
|
||||
/**
|
||||
* \typedef typedef int amp_model_t
|
||||
* \brief Convenience type definition for amplifier model.
|
||||
*/
|
||||
typedef int amp_model_t;
|
||||
|
||||
|
||||
#endif /* _AMPLIST_H */
|
||||
|
||||
/** @} */
|
|
@ -69,9 +69,11 @@
|
|||
|| defined(__cplusplus)
|
||||
# define HAMLIB_PARAMS(protos) protos
|
||||
# define rig_ptr_t void *
|
||||
# define amp_ptr_t void *
|
||||
#else
|
||||
# define HAMLIB_PARAMS(protos) ()
|
||||
# define rig_ptr_t char *
|
||||
# define amp_ptr_t char *
|
||||
#endif
|
||||
|
||||
#include <hamlib/rig_dll.h>
|
||||
|
@ -482,7 +484,9 @@ typedef enum {
|
|||
typedef enum {
|
||||
RIG_POWER_OFF = 0, /*!< Power off */
|
||||
RIG_POWER_ON = (1 << 0), /*!< Power on */
|
||||
RIG_POWER_STANDBY = (1 << 1) /*!< Standby */
|
||||
RIG_POWER_STANDBY = (1 << 1), /*!< Standby */
|
||||
RIG_POWER_OPERATE = (1 << 2), /*!< Operate (from Standby) */
|
||||
RIG_POWER_UNKNOWN = (1 << 3) /*!< Unknown power status */
|
||||
} powerstat_t;
|
||||
|
||||
|
||||
|
@ -772,9 +776,6 @@ enum rig_parm_e {
|
|||
#define RIG_PARM_IS_FLOAT(l) ((l)&RIG_PARM_FLOAT_LIST)
|
||||
#define RIG_PARM_SET(l) ((l)&~RIG_PARM_READONLY_LIST)
|
||||
|
||||
|
||||
#define RIG_SETTING_MAX 64
|
||||
|
||||
/**
|
||||
* \brief Setting
|
||||
*
|
||||
|
@ -783,6 +784,9 @@ enum rig_parm_e {
|
|||
*/
|
||||
typedef uint64_t setting_t;
|
||||
|
||||
|
||||
#define RIG_SETTING_MAX 64
|
||||
|
||||
/**
|
||||
* \brief Tranceive mode
|
||||
*
|
||||
|
@ -2387,6 +2391,7 @@ extern HAMLIB_EXPORT(rmode_t) rig_parse_mode(const char *s);
|
|||
extern HAMLIB_EXPORT(vfo_t) rig_parse_vfo(const char *s);
|
||||
extern HAMLIB_EXPORT(setting_t) rig_parse_func(const char *s);
|
||||
extern HAMLIB_EXPORT(setting_t) rig_parse_level(const char *s);
|
||||
extern HAMLIB_EXPORT(setting_t) amp_parse_level(const char *s);
|
||||
extern HAMLIB_EXPORT(setting_t) rig_parse_parm(const char *s);
|
||||
extern HAMLIB_EXPORT(vfo_op_t) rig_parse_vfo_op(const char *s);
|
||||
extern HAMLIB_EXPORT(scan_t) rig_parse_scan(const char *s);
|
||||
|
|
146
kenwood/thd72.c
146
kenwood/thd72.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "hamlib/rig.h"
|
||||
#include "kenwood.h"
|
||||
|
@ -35,6 +36,9 @@
|
|||
#include "misc.h"
|
||||
|
||||
|
||||
// Some commands are very slow to process so we put a DELAY in those places
|
||||
#define DELAY usleep(300*1000)
|
||||
|
||||
#define THD72_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM)
|
||||
#define THD72_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN)
|
||||
|
||||
|
@ -77,18 +81,19 @@ static rptr_shift_t thd72_rshf_table[3] =
|
|||
[2] = RIG_RPT_SHIFT_MINUS,
|
||||
};
|
||||
|
||||
static int thd72tuningstep[10] =
|
||||
static int thd72tuningstep[11] =
|
||||
{
|
||||
[0] = 5000,
|
||||
[1] = 6250,
|
||||
[2] = 8330,
|
||||
[2] = 0, // not used in thd72
|
||||
[3] = 10000,
|
||||
[4] = 12500,
|
||||
[5] = 15000,
|
||||
[6] = 20000,
|
||||
[7] = 25000,
|
||||
[8] = 30000,
|
||||
[9] = 50000, /* or 100 kHz? */
|
||||
[9] = 50000,
|
||||
[10] = 100000
|
||||
};
|
||||
|
||||
static int thd72voxdelay[7] =
|
||||
|
@ -152,7 +157,9 @@ int thd72_open(RIG *rig)
|
|||
struct kenwood_priv_data *priv = rig->state.priv;
|
||||
strcpy(priv->verify_cmd, "ID\r");
|
||||
|
||||
ret = kenwood_transaction(rig, "", NULL, 0);
|
||||
//ret = kenwood_transaction(rig, "", NULL, 0);
|
||||
//DELAY;
|
||||
ret = rig_set_vfo(rig, RIG_VFO_A);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -187,6 +194,30 @@ static int thd72_set_vfo(RIG *rig, vfo_t vfo)
|
|||
return kenwood_simple_transaction(rig, cmd, 4);
|
||||
}
|
||||
|
||||
static int thd72_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
|
||||
{
|
||||
char vfobuf[16];
|
||||
struct kenwood_priv_data *priv = rig->state.priv;
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
char vfonum = '0';
|
||||
|
||||
if (vfo == RIG_VFO_B || priv->split)
|
||||
{
|
||||
vfonum = '1';
|
||||
}
|
||||
|
||||
sprintf(vfobuf, "BC %c", vfonum);
|
||||
int retval = kenwood_transaction(rig, vfobuf, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", NULL, 0);
|
||||
}
|
||||
|
||||
static int thd72_get_vfo(RIG *rig, vfo_t *vfo)
|
||||
{
|
||||
int retval;
|
||||
|
@ -209,7 +240,7 @@ static int thd72_get_vfo(RIG *rig, vfo_t *vfo)
|
|||
}
|
||||
else
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length '%c'\n", __func__,
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length '%d'\n", __func__,
|
||||
length);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
@ -228,6 +259,88 @@ static int thd72_get_vfo(RIG *rig, vfo_t *vfo)
|
|||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int thd72_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo)
|
||||
{
|
||||
struct kenwood_priv_data *priv = rig->state.priv;
|
||||
char vfobuf[16];
|
||||
int retval;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo));
|
||||
|
||||
if (txvfo != RIG_VFO_B) // Only split with RIG_VFO_B as tx
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
/* Set VFO mode */
|
||||
sprintf(vfobuf, "VMC 0,0");
|
||||
retval = kenwood_transaction(rig, vfobuf, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
sprintf(vfobuf, "VMC 1,0");
|
||||
retval = kenwood_transaction(rig, vfobuf, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
sprintf(vfobuf, "BC 1"); // leave VFOB as selected VFO
|
||||
retval = kenwood_transaction(rig, vfobuf, NULL, 0);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Remember whether split is on, for thd72_set_vfo */
|
||||
priv->split = split;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
static int thd72_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split,
|
||||
vfo_t *txvfo)
|
||||
{
|
||||
struct kenwood_priv_data *priv = rig->state.priv;
|
||||
char buf[10];
|
||||
int retval;
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
|
||||
/* Get VFO band */
|
||||
|
||||
retval = kenwood_safe_transaction(rig, "BC", buf, 10, 4);
|
||||
|
||||
if (retval != RIG_OK)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
switch (buf[5])
|
||||
{
|
||||
case '0': *txvfo = RIG_VFO_A; break;
|
||||
|
||||
case '1': *txvfo = RIG_VFO_B; break;
|
||||
|
||||
default:
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]);
|
||||
return -RIG_EPROTO;
|
||||
}
|
||||
|
||||
*split = (buf[3] == buf[5]) ? RIG_SPLIT_OFF : RIG_SPLIT_ON;
|
||||
|
||||
/* Remember whether split is on, for th_set_vfo */
|
||||
priv->split = *split;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
static int thd72_vfoc(RIG *rig, vfo_t vfo, char *vfoc)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s\n", __func__, rig_strvfo(vfo));
|
||||
|
@ -320,7 +433,9 @@ static int thd72_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
int retval;
|
||||
char buf[64], fbuf[11];
|
||||
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__);
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: called, vfo=%s, freq="PRIfreq"\n", __func__,
|
||||
rig_strvfo(vfo), freq);
|
||||
|
||||
|
||||
retval = thd72_get_freq_info(rig, vfo, buf);
|
||||
|
||||
|
@ -329,6 +444,14 @@ static int thd72_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int tsindex = buf[16] - '0';
|
||||
|
||||
if (buf[16] >= 'A') { tsindex = buf[16] - 'A' + 10; }
|
||||
|
||||
shortfreq_t ts = thd72tuningstep[tsindex];
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex,
|
||||
ts);
|
||||
freq = roundl(freq / ts) * ts;
|
||||
sprintf(fbuf, "%010"PRIll, (int64_t)freq);
|
||||
memcpy(buf + 5, fbuf, 10);
|
||||
retval = kenwood_simple_transaction(rig, buf, 52);
|
||||
|
@ -349,6 +472,10 @@ static int thd72_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int tsindex = buf[16] - '0';
|
||||
shortfreq_t ts = thd72tuningstep[tsindex];
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex,
|
||||
ts);
|
||||
sscanf(buf + 5, "%"SCNfreq, freq);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
@ -1479,7 +1606,7 @@ const struct rig_caps thd72a_caps =
|
|||
.rig_model = RIG_MODEL_THD72A,
|
||||
.model_name = "TH-D72A",
|
||||
.mfg_name = "Kenwood",
|
||||
.version = TH_VER ".2",
|
||||
.version = TH_VER ".3",
|
||||
.copyright = "LGPL",
|
||||
.status = RIG_STATUS_BETA,
|
||||
.rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER,
|
||||
|
@ -1494,7 +1621,7 @@ const struct rig_caps thd72a_caps =
|
|||
.serial_handshake = RIG_HANDSHAKE_XONXOFF,
|
||||
.write_delay = 0,
|
||||
.post_write_delay = 0,
|
||||
.timeout = 500,
|
||||
.timeout = 300,
|
||||
.retry = 3,
|
||||
.has_get_func = THD72_FUNC_ALL,
|
||||
.has_set_func = THD72_FUNC_ALL,
|
||||
|
@ -1565,6 +1692,9 @@ const struct rig_caps thd72a_caps =
|
|||
.get_mode = thd72_get_mode,
|
||||
.set_vfo = thd72_set_vfo,
|
||||
.get_vfo = thd72_get_vfo,
|
||||
.set_ptt = thd72_set_ptt,
|
||||
.set_split_vfo = thd72_set_split_vfo,
|
||||
.get_split_vfo = thd72_get_split_vfo,
|
||||
.set_rptr_shift = thd72_set_rptr_shft,
|
||||
.get_rptr_shift = thd72_get_rptr_shft,
|
||||
.set_rptr_offs = thd72_set_rptr_offs,
|
||||
|
|
|
@ -468,11 +468,73 @@ const char *ts590_get_info(RIG *rig)
|
|||
*/
|
||||
int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
|
||||
{
|
||||
int lvl_len;
|
||||
int retval;
|
||||
char lvlbuf[50];
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case RIG_LEVEL_AF:
|
||||
return get_kenwood_level(rig, "AG0", &val->f);
|
||||
|
||||
case RIG_LEVEL_METER:
|
||||
retval = kenwood_transaction (rig, "RM0", lvlbuf, sizeof (lvlbuf));
|
||||
if (retval != RIG_OK)
|
||||
return retval;
|
||||
lvl_len = strlen (lvlbuf);
|
||||
if (lvl_len != 7) {
|
||||
rig_debug(RIG_DEBUG_ERR,"ts590_get_level: "
|
||||
"unexpected answer len=%d\n", lvl_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
// returns the raw value in dots
|
||||
sscanf(lvlbuf+3, "%d", &val->i);
|
||||
return retval;
|
||||
|
||||
case RIG_LEVEL_SWR:
|
||||
retval = kenwood_transaction (rig, "RM1", lvlbuf, sizeof (lvlbuf));
|
||||
if (retval != RIG_OK)
|
||||
return retval;
|
||||
lvl_len = strlen (lvlbuf);
|
||||
if (lvl_len != 7) {
|
||||
rig_debug(RIG_DEBUG_ERR,"ts590_get_level: "
|
||||
"unexpected answer len=%d\n", lvl_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
// returns the raw value in dots
|
||||
sscanf(lvlbuf+3, "%d", &val->i);
|
||||
return retval;
|
||||
|
||||
case RIG_LEVEL_COMP:
|
||||
retval = kenwood_transaction (rig, "RM2", lvlbuf, sizeof (lvlbuf));
|
||||
if (retval != RIG_OK)
|
||||
return retval;
|
||||
lvl_len = strlen (lvlbuf);
|
||||
if (lvl_len != 7) {
|
||||
rig_debug(RIG_DEBUG_ERR,"ts590_get_level: "
|
||||
"unexpected answer len=%d\n", lvl_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
// returns the raw value in dots
|
||||
sscanf(lvlbuf+3, "%d", &val->i);
|
||||
return retval;
|
||||
|
||||
case RIG_LEVEL_ALC:
|
||||
retval = kenwood_transaction (rig, "RM3", lvlbuf, sizeof (lvlbuf));
|
||||
if (retval != RIG_OK)
|
||||
return retval;
|
||||
lvl_len = strlen (lvlbuf);
|
||||
if (lvl_len != 7) {
|
||||
rig_debug(RIG_DEBUG_ERR,"ts590_get_level: "
|
||||
"unexpected answer len=%d\n", lvl_len);
|
||||
return -RIG_ERJCTED;
|
||||
}
|
||||
// returns the raw value in dots
|
||||
sscanf(lvlbuf+3, "%d", &val->i);
|
||||
return retval;
|
||||
|
||||
default: return rig_get_level(rig, vfo, level, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1444,7 +1444,7 @@ int win32_serial_read( int fd, void *vb, int size )
|
|||
err = ReadFile( index->hComm, dest + total, size, &nBytes, &index->rol );
|
||||
#ifdef DEBUG_VERBOSE
|
||||
/* warning Roy Rogers! */
|
||||
sprintf(message, " ========== ReadFile = %i %s\n",
|
||||
sprintf(message, " ========== ReadFile = %i 0x%x\n",
|
||||
( int ) nBytes, *((char *) dest + total) );
|
||||
report( message );
|
||||
#endif /* DEBUG_VERBOSE */
|
||||
|
|
|
@ -4,15 +4,16 @@ RIGSRC = rig.c serial.c serial.h misc.c misc.h register.c register.h event.c \
|
|||
event.h cal.c cal.h conf.c tones.c tones.h rotator.c locator.c rot_reg.c \
|
||||
rot_conf.c rot_conf.h iofunc.c iofunc.h ext.c mem.c settings.c \
|
||||
parallel.c parallel.h usb_port.c usb_port.h debug.c network.c network.h \
|
||||
cm108.c cm108.h gpio.c gpio.h idx_builtin.h token.h par_nt.h microham.c microham.h
|
||||
cm108.c cm108.h gpio.c gpio.h idx_builtin.h token.h par_nt.h microham.c microham.h \
|
||||
amplifier.c amp_reg.c amp_conf.c amp_conf.h extamp.c
|
||||
|
||||
lib_LTLIBRARIES = libhamlib.la
|
||||
libhamlib_la_SOURCES = $(RIGSRC)
|
||||
libhamlib_la_LDFLAGS = $(WINLDFLAGS) $(OSXLDFLAGS) -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE)
|
||||
|
||||
libhamlib_la_LIBADD = $(top_builddir)/lib/libmisc.la \
|
||||
$(BACKENDEPS) $(ROT_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS)
|
||||
$(BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS)
|
||||
|
||||
libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(BACKENDEPS) $(ROT_BACKENDEPS)
|
||||
libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS)
|
||||
|
||||
EXTRA_DIST = Android.mk
|
||||
|
|
|
@ -0,0 +1,695 @@
|
|||
/*
|
||||
* Hamlib Interface - amplifier configuration interface
|
||||
* Copyright (c) 2000-2010 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup amplifier
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Amplifier Configuration Interface
|
||||
* \file amp_conf.c
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* Standard input/output definitions */
|
||||
#include <string.h> /* String function definitions */
|
||||
#include <unistd.h> /* UNIX standard function definitions */
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#include "amp_conf.h"
|
||||
#include "token.h"
|
||||
|
||||
|
||||
/*
|
||||
* Configuration options available in the amp->state struct.
|
||||
*/
|
||||
static const struct confparams ampfrontend_cfg_params[] =
|
||||
{
|
||||
{
|
||||
TOK_PATHNAME, "amp_pathname", "Rig path name",
|
||||
"Path name to the device file of the amplifier",
|
||||
"/dev/amplifier", RIG_CONF_STRING,
|
||||
},
|
||||
{
|
||||
TOK_WRITE_DELAY, "write_delay", "Write delay",
|
||||
"Delay in ms between each byte sent out",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_POST_WRITE_DELAY, "post_write_delay", "Post write delay",
|
||||
"Delay in ms between each command sent out",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_RETRY, "retry", "Retry", "Max number of retry",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } }
|
||||
},
|
||||
|
||||
{
|
||||
TOK_MIN_AZ, "min_az", "Minimum azimuth",
|
||||
"Minimum amplifier azimuth in degrees",
|
||||
"-180", RIG_CONF_NUMERIC, { .n = { -360, 360, .001 } }
|
||||
},
|
||||
{
|
||||
TOK_MAX_AZ, "max_az", "Maximum azimuth",
|
||||
"Maximum amplifier azimuth in degrees",
|
||||
"180", RIG_CONF_NUMERIC, { .n = { -360, 360, .001 } }
|
||||
},
|
||||
{
|
||||
TOK_MIN_EL, "min_el", "Minimum elevation",
|
||||
"Minimum amplifier elevation in degrees",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { -90, 180, .001 } }
|
||||
},
|
||||
{
|
||||
TOK_MAX_EL, "max_el", "Maximum elevation",
|
||||
"Maximum amplifier elevation in degrees",
|
||||
"90", RIG_CONF_NUMERIC, { .n = { -90, 180, .001 } }
|
||||
},
|
||||
|
||||
{ RIG_CONF_END, NULL, }
|
||||
};
|
||||
|
||||
|
||||
static const struct confparams ampfrontend_serial_cfg_params[] =
|
||||
{
|
||||
{
|
||||
TOK_SERIAL_SPEED, "serial_speed", "Serial speed",
|
||||
"Serial port baud rate",
|
||||
"0", RIG_CONF_NUMERIC, { .n = { 300, 115200, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_DATA_BITS, "data_bits", "Serial data bits",
|
||||
"Serial port data bits",
|
||||
"8", RIG_CONF_NUMERIC, { .n = { 5, 8, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_STOP_BITS, "stop_bits", "Serial stop bits",
|
||||
"Serial port stop bits",
|
||||
"1", RIG_CONF_NUMERIC, { .n = { 0, 3, 1 } }
|
||||
},
|
||||
{
|
||||
TOK_PARITY, "serial_parity", "Serial parity",
|
||||
"Serial port parity",
|
||||
"None", RIG_CONF_COMBO, { .c = {{ "None", "Odd", "Even", "Mark", "Space", NULL }} }
|
||||
},
|
||||
{
|
||||
TOK_HANDSHAKE, "serial_handshake", "Serial handshake",
|
||||
"Serial port handshake",
|
||||
"None", RIG_CONF_COMBO, { .c = {{ "None", "XONXOFF", "Hardware", NULL }} }
|
||||
},
|
||||
|
||||
{ RIG_CONF_END, NULL, }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set amplifier state info from alpha input
|
||||
* \param amp
|
||||
* \param token TOK_... specifying which info to set
|
||||
* \param val input
|
||||
* \return RIG_OK or < 0 error
|
||||
*
|
||||
* assumes amp!=NULL, val!=NULL
|
||||
*/
|
||||
int frontamp_set_conf(AMP *amp, token_t token, const char *val)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
int val_i;
|
||||
|
||||
rs = &->state;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case TOK_PATHNAME:
|
||||
strncpy(rs->ampport.pathname, val, FILPATHLEN - 1);
|
||||
break;
|
||||
|
||||
case TOK_WRITE_DELAY:
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.write_delay = val_i;
|
||||
break;
|
||||
|
||||
case TOK_POST_WRITE_DELAY:
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.post_write_delay = val_i;
|
||||
break;
|
||||
|
||||
case TOK_TIMEOUT:
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.timeout = val_i;
|
||||
break;
|
||||
|
||||
case TOK_RETRY:
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.retry = val_i;
|
||||
break;
|
||||
|
||||
case TOK_SERIAL_SPEED:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.parm.serial.rate = val_i;
|
||||
break;
|
||||
|
||||
case TOK_DATA_BITS:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.parm.serial.data_bits = val_i;
|
||||
break;
|
||||
|
||||
case TOK_STOP_BITS:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (1 != sscanf(val, "%d", &val_i))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.parm.serial.stop_bits = val_i;
|
||||
break;
|
||||
|
||||
case TOK_PARITY:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (!strcmp(val, "None"))
|
||||
{
|
||||
rs->ampport.parm.serial.parity = RIG_PARITY_NONE;
|
||||
}
|
||||
else if (!strcmp(val, "Odd"))
|
||||
{
|
||||
rs->ampport.parm.serial.parity = RIG_PARITY_ODD;
|
||||
}
|
||||
else if (!strcmp(val, "Even"))
|
||||
{
|
||||
rs->ampport.parm.serial.parity = RIG_PARITY_EVEN;
|
||||
}
|
||||
else if (!strcmp(val, "Mark"))
|
||||
{
|
||||
rs->ampport.parm.serial.parity = RIG_PARITY_MARK;
|
||||
}
|
||||
else if (!strcmp(val, "Space"))
|
||||
{
|
||||
rs->ampport.parm.serial.parity = RIG_PARITY_SPACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TOK_HANDSHAKE:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (!strcmp(val, "None"))
|
||||
{
|
||||
rs->ampport.parm.serial.handshake = RIG_HANDSHAKE_NONE;
|
||||
}
|
||||
else if (!strcmp(val, "XONXOFF"))
|
||||
{
|
||||
rs->ampport.parm.serial.handshake = RIG_HANDSHAKE_XONXOFF;
|
||||
}
|
||||
else if (!strcmp(val, "Hardware"))
|
||||
{
|
||||
rs->ampport.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if 0
|
||||
|
||||
case TOK_MIN_AZ:
|
||||
rs->min_az = atof(val);
|
||||
break;
|
||||
|
||||
case TOK_MAX_AZ:
|
||||
rs->max_az = atof(val);
|
||||
break;
|
||||
|
||||
case TOK_MIN_EL:
|
||||
rs->min_el = atof(val);
|
||||
break;
|
||||
|
||||
case TOK_MAX_EL:
|
||||
rs->max_el = atof(val);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get data from amplifier state in alpha form
|
||||
* \param amp non-null
|
||||
* \param token TOK_... specifying which data to get
|
||||
* \param val result non-null
|
||||
* \return RIG_OK or < 0 if error
|
||||
*/
|
||||
int frontamp_get_conf(AMP *amp, token_t token, char *val)
|
||||
{
|
||||
struct amp_state *rs;
|
||||
const char *s;
|
||||
|
||||
rs = &->state;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case TOK_PATHNAME:
|
||||
strcpy(val, rs->ampport.pathname);
|
||||
break;
|
||||
|
||||
case TOK_WRITE_DELAY:
|
||||
sprintf(val, "%d", rs->ampport.write_delay);
|
||||
break;
|
||||
|
||||
case TOK_POST_WRITE_DELAY:
|
||||
sprintf(val, "%d", rs->ampport.post_write_delay);
|
||||
break;
|
||||
|
||||
case TOK_TIMEOUT:
|
||||
sprintf(val, "%d", rs->ampport.timeout);
|
||||
break;
|
||||
|
||||
case TOK_RETRY:
|
||||
sprintf(val, "%d", rs->ampport.retry);
|
||||
break;
|
||||
|
||||
case TOK_SERIAL_SPEED:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
sprintf(val, "%d", rs->ampport.parm.serial.rate);
|
||||
break;
|
||||
|
||||
case TOK_DATA_BITS:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
sprintf(val, "%d", rs->ampport.parm.serial.data_bits);
|
||||
break;
|
||||
|
||||
case TOK_STOP_BITS:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
sprintf(val, "%d", rs->ampport.parm.serial.stop_bits);
|
||||
break;
|
||||
|
||||
case TOK_PARITY:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
switch (rs->ampport.parm.serial.parity)
|
||||
{
|
||||
case RIG_PARITY_NONE:
|
||||
s = "None";
|
||||
break;
|
||||
|
||||
case RIG_PARITY_ODD:
|
||||
s = "Odd";
|
||||
break;
|
||||
|
||||
case RIG_PARITY_EVEN:
|
||||
s = "Even";
|
||||
break;
|
||||
|
||||
case RIG_PARITY_MARK:
|
||||
s = "Mark";
|
||||
break;
|
||||
|
||||
case RIG_PARITY_SPACE:
|
||||
s = "Space";
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
strcpy(val, s);
|
||||
break;
|
||||
|
||||
case TOK_HANDSHAKE:
|
||||
if (rs->ampport.type.rig != RIG_PORT_SERIAL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
switch (rs->ampport.parm.serial.handshake)
|
||||
{
|
||||
case RIG_HANDSHAKE_NONE:
|
||||
s = "None";
|
||||
break;
|
||||
|
||||
case RIG_HANDSHAKE_XONXOFF:
|
||||
s = "XONXOFF";
|
||||
break;
|
||||
|
||||
case RIG_HANDSHAKE_HARDWARE:
|
||||
s = "Hardware";
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
strcpy(val, s);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
|
||||
case TOK_MIN_AZ:
|
||||
sprintf(val, "%f", rs->min_az);
|
||||
break;
|
||||
|
||||
case TOK_MAX_AZ:
|
||||
sprintf(val, "%f", rs->max_az);
|
||||
break;
|
||||
|
||||
case TOK_MIN_EL:
|
||||
sprintf(val, "%f", rs->min_el);
|
||||
break;
|
||||
|
||||
case TOK_MAX_EL:
|
||||
sprintf(val, "%f", rs->max_el);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Executes cfunc on all the elements stored in the conf table
|
||||
* \param amp non-null
|
||||
* \param cfunc function(..)
|
||||
* \param data
|
||||
*
|
||||
* start first with backend conf table, then finish with frontend table
|
||||
*/
|
||||
int HAMLIB_API amp_token_foreach(AMP *amp,
|
||||
int (*cfunc)(const struct confparams *,
|
||||
rig_ptr_t),
|
||||
rig_ptr_t data)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps || !cfunc)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
for (cfp = ampfrontend_cfg_params; cfp->name; cfp++)
|
||||
{
|
||||
if ((*cfunc)(cfp, data) == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (amp->caps->port_type == RIG_PORT_SERIAL)
|
||||
{
|
||||
for (cfp = ampfrontend_serial_cfg_params; cfp->name; cfp++)
|
||||
{
|
||||
if ((*cfunc)(cfp, data) == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->cfgparams; cfp && cfp->name; cfp++)
|
||||
{
|
||||
if ((*cfunc)(cfp, data) == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief lookup conf token by its name, return pointer to confparams struct.
|
||||
* \param amp
|
||||
* \param name
|
||||
* \return confparams or NULL
|
||||
*
|
||||
* lookup backend config table first, then fall back to frontend.
|
||||
* TODO: should use Lex to speed it up, strcmp hurts!
|
||||
*/
|
||||
const struct confparams *HAMLIB_API amp_confparam_lookup(AMP *amp,
|
||||
const char *name)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
token_t token;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 0 returned for invalid format */
|
||||
token = strtol(name, NULL, 0);
|
||||
|
||||
for (cfp = amp->caps->cfgparams; cfp && cfp->name; cfp++)
|
||||
{
|
||||
if (!strcmp(cfp->name, name) || token == cfp->token)
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
for (cfp = ampfrontend_cfg_params; cfp->name; cfp++)
|
||||
{
|
||||
if (!strcmp(cfp->name, name) || token == cfp->token)
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
if (amp->caps->port_type == RIG_PORT_SERIAL)
|
||||
{
|
||||
for (cfp = ampfrontend_serial_cfg_params; cfp->name; cfp++)
|
||||
{
|
||||
if (!strcmp(cfp->name, name) || token == cfp->token)
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Simple lookup returning token id associated with name
|
||||
* \param amp
|
||||
* \param name
|
||||
* \return token enum
|
||||
*/
|
||||
token_t HAMLIB_API amp_token_lookup(AMP *amp, const char *name)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
cfp = amp_confparam_lookup(amp, name);
|
||||
|
||||
if (!cfp)
|
||||
{
|
||||
return RIG_CONF_END;
|
||||
}
|
||||
|
||||
return cfp->token;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief set a amplifier configuration parameter
|
||||
* \param amp The amp handle
|
||||
* \param token The parameter
|
||||
* \param val The value to set the parameter to
|
||||
*
|
||||
* Sets a configuration parameter.
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \sa amp_get_conf()
|
||||
*/
|
||||
int HAMLIB_API amp_set_conf(AMP *amp, token_t token, const char *val)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (rig_need_debug(RIG_DEBUG_VERBOSE))
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
char tokenstr[12];
|
||||
sprintf(tokenstr, "%ld", token);
|
||||
cfp = amp_confparam_lookup(amp, tokenstr);
|
||||
|
||||
if (!cfp)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s: %s='%s'\n", __func__, cfp->name, val);
|
||||
}
|
||||
|
||||
if (IS_TOKEN_FRONTEND(token))
|
||||
{
|
||||
return frontamp_set_conf(amp, token, val);
|
||||
}
|
||||
|
||||
if (amp->caps->set_conf == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
return amp->caps->set_conf(amp, token, val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief get the value of a configuration parameter
|
||||
* \param amp The amp handle
|
||||
* \param token The parameter
|
||||
* \param val The location where to store the value of config \a token
|
||||
*
|
||||
* Retrieves the value of a configuration paramter associated with \a token.
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \sa amp_set_conf()
|
||||
*/
|
||||
int HAMLIB_API amp_get_conf(AMP *amp, token_t token, char *val)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps || !val)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (IS_TOKEN_FRONTEND(token))
|
||||
{
|
||||
return frontamp_get_conf(amp, token, val);
|
||||
}
|
||||
|
||||
if (amp->caps->get_conf == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
return amp->caps->get_conf(amp, token, val);
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Hamlib Interface - configuration header
|
||||
* Copyright (c) 2000,2001,2002 by Stephane Fillod and Frank Singleton
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMP_CONF_H
|
||||
#define _AMP_CONF_H 1
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
int frontamp_set_conf(AMP *amp, token_t token, const char *val);
|
||||
int frontamp_get_conf(AMP *amp, token_t token, char *val);
|
||||
|
||||
|
||||
#endif /* _AMP_CONF_H */
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
* Hamlib Interface - provides registering for dynamically loadable backends.
|
||||
* Copyright (c) 2000-2004 by Stephane Fillod
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Dynamic registration of amplifier backends
|
||||
* \file amp_reg.c
|
||||
*
|
||||
* Similar to register.c
|
||||
* doc todo: Let's explain what's going on here!
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#include "register.h"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
#define AMP_BACKEND_MAX 32
|
||||
|
||||
#define DEFINE_INITAMP_BACKEND(backend) \
|
||||
int MAKE_VERSIONED_FN(PREFIX_INITAMPS, \
|
||||
ABI_VERSION, \
|
||||
backend(void *be_handle)); \
|
||||
rig_model_t MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, \
|
||||
ABI_VERSION, \
|
||||
backend(hamlib_port_t *port, \
|
||||
rig_probe_func_t cfunc, \
|
||||
rig_ptr_t data))
|
||||
|
||||
#define AMP_FUNCNAMA(backend) MAKE_VERSIONED_FN(PREFIX_INITAMPS, ABI_VERSION, backend)
|
||||
#define AMP_FUNCNAMB(backend) MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, ABI_VERSION, backend)
|
||||
|
||||
#define AMP_FUNCNAM(backend) AMP_FUNCNAMA(backend),AMP_FUNCNAMB(backend)
|
||||
|
||||
|
||||
DEFINE_INITAMP_BACKEND(dummy);
|
||||
DEFINE_INITAMP_BACKEND(kpa1500);
|
||||
|
||||
/**
|
||||
* \def AMP_BACKEND_LIST
|
||||
* \brief Static list of amplifier models.
|
||||
*
|
||||
* This is a NULL terminated list of available amplifier backends. Each entry
|
||||
* in the list consists of two fields: The branch number, which is an integer,
|
||||
* and the branch name, which is a character string.
|
||||
* An external library, loaded dynamically, could add its own functions
|
||||
* pointers in this array.
|
||||
*/
|
||||
static struct
|
||||
{
|
||||
int be_num;
|
||||
const char *be_name;
|
||||
int (*be_init)(void *);
|
||||
amp_model_t (*be_probe)(hamlib_port_t *);
|
||||
} amp_backend_list[AMP_BACKEND_MAX] =
|
||||
{
|
||||
{ AMP_DUMMY, AMP_BACKEND_DUMMY, AMP_FUNCNAMA(dummy) },
|
||||
{ AMP_ELECRAFT, AMP_BACKEND_ELECRAFT, AMP_FUNCNAMA(kpa1500) },
|
||||
{ 0, NULL }, /* end */
|
||||
};
|
||||
|
||||
|
||||
// Apparently, no amplifier can be probed.
|
||||
|
||||
/*
|
||||
* AMP_BACKEND_LIST is here, please keep it up to date,
|
||||
* i.e. each time you implement a new backend.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This struct to keep track of known amp models.
|
||||
* It is chained, and used in a hash table, see below.
|
||||
*/
|
||||
struct amp_list
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
struct amp_list *next;
|
||||
};
|
||||
|
||||
|
||||
#define AMPLSTHASHSZ 16
|
||||
#define HASH_FUNC(a) ((a)%AMPLSTHASHSZ)
|
||||
|
||||
|
||||
/*
|
||||
* The amp_hash_table is a hash table pointing to a list of next==NULL
|
||||
* terminated caps.
|
||||
*/
|
||||
static struct amp_list *amp_hash_table[AMPLSTHASHSZ] = { NULL, };
|
||||
|
||||
|
||||
static int amp_lookup_backend(amp_model_t amp_model);
|
||||
|
||||
|
||||
/*
|
||||
* Basically, this is a hash insert function that doesn't check for dup!
|
||||
*/
|
||||
int HAMLIB_API amp_register(const struct amp_caps *caps)
|
||||
{
|
||||
int hval;
|
||||
struct amp_list *p;
|
||||
|
||||
if (!caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "amp_register (%d)\n", caps->amp_model);
|
||||
|
||||
#ifndef DONT_WANT_DUP_CHECK
|
||||
|
||||
if (amp_get_caps(caps->amp_model) != NULL)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
p = (struct amp_list *)malloc(sizeof(struct amp_list));
|
||||
|
||||
if (!p)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
hval = HASH_FUNC(caps->amp_model);
|
||||
p->caps = caps;
|
||||
// p->handle = NULL;
|
||||
p->next = amp_hash_table[hval];
|
||||
amp_hash_table[hval] = p;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get amp capabilities.
|
||||
* i.e. amp_hash_table lookup
|
||||
*/
|
||||
const struct amp_caps *HAMLIB_API amp_get_caps(amp_model_t amp_model)
|
||||
{
|
||||
struct amp_list *p;
|
||||
|
||||
for (p = amp_hash_table[HASH_FUNC(amp_model)]; p; p = p->next)
|
||||
{
|
||||
if (p->caps->amp_model == amp_model)
|
||||
{
|
||||
return p->caps;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* sorry, caps not registered! */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lookup for backend index in amp_backend_list table,
|
||||
* according to BACKEND_NUM
|
||||
* return -1 if not found.
|
||||
*/
|
||||
static int amp_lookup_backend(amp_model_t amp_model)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++)
|
||||
{
|
||||
if (AMP_BACKEND_NUM(amp_model) ==
|
||||
amp_backend_list[i].be_num)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* amp_check_backend
|
||||
* check the backend declaring this model has been loaded
|
||||
* and if not loaded already, load it!
|
||||
* This permits seamless operation in amp_init.
|
||||
*/
|
||||
int HAMLIB_API amp_check_backend(amp_model_t amp_model)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
int be_idx;
|
||||
int retval;
|
||||
|
||||
/* already loaded ? */
|
||||
caps = amp_get_caps(amp_model);
|
||||
|
||||
if (caps)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
be_idx = amp_lookup_backend(amp_model);
|
||||
|
||||
/*
|
||||
* Never heard about this backend family!
|
||||
*/
|
||||
if (be_idx == -1)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: unsupported backend %d for model %d\n",
|
||||
__func__,
|
||||
AMP_BACKEND_NUM(amp_model),
|
||||
amp_model);
|
||||
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
retval = amp_load_backend(amp_backend_list[be_idx].be_name);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int HAMLIB_API amp_unregister(amp_model_t amp_model)
|
||||
{
|
||||
int hval;
|
||||
struct amp_list *p, *q;
|
||||
|
||||
hval = HASH_FUNC(amp_model);
|
||||
q = NULL;
|
||||
|
||||
for (p = amp_hash_table[hval]; p; p = p->next)
|
||||
{
|
||||
if (p->caps->amp_model == amp_model)
|
||||
{
|
||||
if (q == NULL)
|
||||
{
|
||||
amp_hash_table[hval] = p->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->next = p->next;
|
||||
}
|
||||
|
||||
free(p);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
q = p;
|
||||
}
|
||||
|
||||
return -RIG_EINVAL; /* sorry, caps not registered! */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* amp_list_foreach
|
||||
* executes cfunc on all the elements stored in the amp hash list
|
||||
*/
|
||||
int HAMLIB_API amp_list_foreach(int (*cfunc)(const struct amp_caps *,
|
||||
rig_ptr_t),
|
||||
rig_ptr_t data)
|
||||
{
|
||||
struct amp_list *p;
|
||||
int i;
|
||||
|
||||
if (!cfunc)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < AMPLSTHASHSZ; i++)
|
||||
{
|
||||
for (p = amp_hash_table[i]; p; p = p->next)
|
||||
if ((*cfunc)(p->caps, data) == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* amp_probe_all
|
||||
* called straight by amp_probe
|
||||
*/
|
||||
amp_model_t HAMLIB_API amp_probe_all(hamlib_port_t *p)
|
||||
{
|
||||
int i;
|
||||
amp_model_t amp_model;
|
||||
|
||||
for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++)
|
||||
{
|
||||
if (amp_backend_list[i].be_probe)
|
||||
{
|
||||
amp_model = (*amp_backend_list[i].be_probe)(p);
|
||||
|
||||
if (amp_model != AMP_MODEL_NONE)
|
||||
{
|
||||
return amp_model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AMP_MODEL_NONE;
|
||||
}
|
||||
|
||||
|
||||
int amp_load_all_backends()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++)
|
||||
{
|
||||
amp_load_backend(amp_backend_list[i].be_name);
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* amp_load_backend
|
||||
* Dynamically load a amp backend through dlopen mechanism
|
||||
*/
|
||||
int HAMLIB_API amp_load_backend(const char *be_name)
|
||||
{
|
||||
int status;
|
||||
int (*be_init)(rig_ptr_t);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++)
|
||||
{
|
||||
if (!strcmp(be_name, amp_backend_list[i].be_name))
|
||||
{
|
||||
be_init = amp_backend_list[i].be_init;
|
||||
|
||||
if (be_init == NULL)
|
||||
{
|
||||
printf("Null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = (*be_init)(NULL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
||||
}
|
|
@ -0,0 +1,708 @@
|
|||
/*
|
||||
* Hamlib Interface - main file
|
||||
* Copyright (c) 2000-2012 by Stephane Fillod
|
||||
* Copyright (c) 2000-2003 by Frank Singleton
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup amplifier
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file src/amplifier.c
|
||||
* \brief Amplifier interface
|
||||
* \author Stephane Fillod
|
||||
* \date 2000-2012
|
||||
*
|
||||
* Hamlib interface is a frontend implementing amplifier wrapper functions.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \page amp Amplifier interface
|
||||
*
|
||||
* Amplifier can be any kind of azimuth or azimuth and elevation controlled
|
||||
* antenna system.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
#include "serial.h"
|
||||
#include "parallel.h"
|
||||
#include "usb_port.h"
|
||||
#include "network.h"
|
||||
#include "amp_conf.h"
|
||||
#include "token.h"
|
||||
|
||||
#define CHECK_AMP_ARG(r) (!(r) || !(r)->caps || !(r)->state.comm_state)
|
||||
|
||||
/*
|
||||
* Data structure to track the opened amp (by amp_open)
|
||||
*/
|
||||
struct opened_amp_l
|
||||
{
|
||||
AMP *amp;
|
||||
struct opened_amp_l *next;
|
||||
};
|
||||
static struct opened_amp_l *opened_amp_list = { NULL };
|
||||
|
||||
|
||||
/*
|
||||
* track which amp is opened (with amp_open)
|
||||
* needed at least for transceive mode
|
||||
*/
|
||||
static int add_opened_amp(AMP *amp)
|
||||
{
|
||||
struct opened_amp_l *p;
|
||||
p = (struct opened_amp_l *)malloc(sizeof(struct opened_amp_l));
|
||||
|
||||
if (!p)
|
||||
{
|
||||
return -RIG_ENOMEM;
|
||||
}
|
||||
|
||||
p->amp = amp;
|
||||
p->next = opened_amp_list;
|
||||
opened_amp_list = p;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
static int remove_opened_amp(AMP *amp)
|
||||
{
|
||||
struct opened_amp_l *p, *q;
|
||||
q = NULL;
|
||||
|
||||
for (p = opened_amp_list; p; p = p->next)
|
||||
{
|
||||
if (p->amp == amp)
|
||||
{
|
||||
if (q == NULL)
|
||||
{
|
||||
opened_amp_list = opened_amp_list->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
q->next = p->next;
|
||||
}
|
||||
|
||||
free(p);
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
q = p;
|
||||
}
|
||||
|
||||
return -RIG_EINVAL; /* Not found in list ! */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief execs cfunc() on each opened amp
|
||||
* \param cfunc The function to be executed on each amp
|
||||
* \param data Data pointer to be passed to cfunc()
|
||||
*
|
||||
* Calls cfunc() function for each opened amp. The contents of the opened
|
||||
* amp table is processed in random order according to a function pointed to
|
||||
* by \a cfunc, whic is called with two arguments, the first pointing to the
|
||||
* #AMP handle, the second to a data pointer \a data.
|
||||
*
|
||||
* If \a data is not needed, then it can be set to NULL. The processing of
|
||||
* the opened amp table is stopped when cfunc() returns 0.
|
||||
* \internal
|
||||
*
|
||||
* \return always RIG_OK.
|
||||
*/
|
||||
int foreach_opened_amp(int (*cfunc)(AMP *, rig_ptr_t), rig_ptr_t data)
|
||||
{
|
||||
struct opened_amp_l *p;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
for (p = opened_amp_list; p; p = p->next)
|
||||
{
|
||||
if ((*cfunc)(p->amp, data) == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief allocate a new #AMP handle
|
||||
* \param amp_model The amp model for this new handle
|
||||
*
|
||||
* Allocates a new #AMP handle and initializes the associated data
|
||||
* for \a amp_model.
|
||||
*
|
||||
* \return a pointer to the #AMP handle otherwise NULL if memory allocation
|
||||
* failed or \a amp_model is unknown (e.g. backend autoload failed).
|
||||
*
|
||||
* \sa amp_cleanup(), amp_open()
|
||||
*/
|
||||
AMP *HAMLIB_API amp_init(amp_model_t amp_model)
|
||||
{
|
||||
AMP *amp;
|
||||
const struct amp_caps *caps;
|
||||
struct amp_state *rs;
|
||||
int retcode;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
amp_check_backend(amp_model);
|
||||
|
||||
caps = amp_get_caps(amp_model);
|
||||
|
||||
if (!caps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* okay, we've found it. Allocate some memory and set it to zeros,
|
||||
* and especially the initialize the callbacks
|
||||
*/
|
||||
amp = calloc(1, sizeof(AMP));
|
||||
|
||||
if (amp == NULL)
|
||||
{
|
||||
/*
|
||||
* FIXME: how can the caller know it's a memory shortage,
|
||||
* and not "amp not found" ?
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* caps is const, so we need to tell compiler
|
||||
that we know what we are doing */
|
||||
amp->caps = (struct amp_caps *) caps;
|
||||
|
||||
/*
|
||||
* populate the amp->state
|
||||
* TODO: read the Preferences here!
|
||||
*/
|
||||
rs = &->state;
|
||||
|
||||
rs->comm_state = 0;
|
||||
rs->ampport.type.rig = caps->port_type; /* default from caps */
|
||||
|
||||
rs->ampport.write_delay = caps->write_delay;
|
||||
rs->ampport.post_write_delay = caps->post_write_delay;
|
||||
rs->ampport.timeout = caps->timeout;
|
||||
rs->ampport.retry = caps->retry;
|
||||
rs->has_get_level = caps->has_get_level;
|
||||
|
||||
switch (caps->port_type)
|
||||
{
|
||||
case RIG_PORT_SERIAL:
|
||||
// Dont' think we need a default port here
|
||||
//strncpy(rs->ampport.pathname, DEFAULT_SERIAL_PORT, FILPATHLEN - 1);
|
||||
rs->ampport.parm.serial.rate = caps->serial_rate_max; /* fastest ! */
|
||||
rs->ampport.parm.serial.data_bits = caps->serial_data_bits;
|
||||
rs->ampport.parm.serial.stop_bits = caps->serial_stop_bits;
|
||||
rs->ampport.parm.serial.parity = caps->serial_parity;
|
||||
rs->ampport.parm.serial.handshake = caps->serial_handshake;
|
||||
break;
|
||||
|
||||
case RIG_PORT_NETWORK:
|
||||
case RIG_PORT_UDP_NETWORK:
|
||||
strncpy(rs->ampport.pathname, "127.0.0.1:4534", FILPATHLEN - 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
strncpy(rs->ampport.pathname, "", FILPATHLEN - 1);
|
||||
}
|
||||
|
||||
rs->ampport.fd = -1;
|
||||
|
||||
/*
|
||||
* let the backend a chance to setup his private data
|
||||
* This must be done only once defaults are setup,
|
||||
* so the backend init can override amp_state.
|
||||
*/
|
||||
if (caps->amp_init != NULL)
|
||||
{
|
||||
retcode = caps->amp_init(amp);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: backend_init failed!\n",
|
||||
__func__);
|
||||
/* cleanup and exit */
|
||||
free(amp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return amp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief open the communication to the amp
|
||||
* \param amp The #AMP handle of the amplifier to be opened
|
||||
*
|
||||
* Opens communication to a amplifier which \a AMP handle has been passed
|
||||
* by argument.
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \retval RIG_EINVAL \a amp is NULL or unconsistent.
|
||||
* \retval RIG_ENIMPL port type communication is not implemented yet.
|
||||
*
|
||||
* \sa amp_init(), amp_close()
|
||||
*/
|
||||
int HAMLIB_API amp_open(AMP *amp)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
struct amp_state *rs;
|
||||
int status;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
rs = &->state;
|
||||
|
||||
if (rs->comm_state)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
rs->ampport.fd = -1;
|
||||
|
||||
switch (rs->ampport.type.rig)
|
||||
{
|
||||
case RIG_PORT_SERIAL:
|
||||
status = serial_open(&rs->ampport);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RIG_PORT_PARALLEL:
|
||||
status = par_open(&rs->ampport);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RIG_PORT_DEVICE:
|
||||
status = open(rs->ampport.pathname, O_RDWR, 0);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
rs->ampport.fd = status;
|
||||
break;
|
||||
|
||||
case RIG_PORT_USB:
|
||||
status = usb_port_open(&rs->ampport);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RIG_PORT_NONE:
|
||||
case RIG_PORT_RPC:
|
||||
break; /* ez :) */
|
||||
|
||||
case RIG_PORT_NETWORK:
|
||||
case RIG_PORT_UDP_NETWORK:
|
||||
/* FIXME: default port */
|
||||
status = network_open(&rs->ampport, 4533);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
add_opened_amp(amp);
|
||||
|
||||
rs->comm_state = 1;
|
||||
|
||||
/*
|
||||
* Maybe the backend has something to initialize
|
||||
* In case of failure, just close down and report error code.
|
||||
*/
|
||||
if (caps->amp_open != NULL)
|
||||
{
|
||||
status = caps->amp_open(amp);
|
||||
|
||||
if (status != RIG_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief close the communication to the amp
|
||||
* \param amp The #AMP handle of the amplifier to be closed
|
||||
*
|
||||
* Closes communication to a amplifier which \a AMP handle has been passed
|
||||
* by argument that was previously open with amp_open().
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \sa amp_cleanup(), amp_open()
|
||||
*/
|
||||
int HAMLIB_API amp_close(AMP *amp)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
struct amp_state *rs;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
rs = &->state;
|
||||
|
||||
if (!rs->comm_state)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let the backend say 73s to the amp.
|
||||
* and ignore the return code.
|
||||
*/
|
||||
if (caps->amp_close)
|
||||
{
|
||||
caps->amp_close(amp);
|
||||
}
|
||||
|
||||
|
||||
if (rs->ampport.fd != -1)
|
||||
{
|
||||
switch (rs->ampport.type.rig)
|
||||
{
|
||||
case RIG_PORT_SERIAL:
|
||||
ser_close(&rs->ampport);
|
||||
break;
|
||||
|
||||
case RIG_PORT_PARALLEL:
|
||||
par_close(&rs->ampport);
|
||||
break;
|
||||
|
||||
case RIG_PORT_USB:
|
||||
usb_port_close(&rs->ampport);
|
||||
break;
|
||||
|
||||
case RIG_PORT_NETWORK:
|
||||
case RIG_PORT_UDP_NETWORK:
|
||||
network_close(&rs->ampport);
|
||||
break;
|
||||
|
||||
default:
|
||||
close(rs->ampport.fd);
|
||||
}
|
||||
|
||||
rs->ampport.fd = -1;
|
||||
}
|
||||
|
||||
remove_opened_amp(amp);
|
||||
|
||||
rs->comm_state = 0;
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief release a amp handle and free associated memory
|
||||
* \param amp The #AMP handle of the radio to be closed
|
||||
*
|
||||
* Releases a amp struct which port has eventualy been closed already
|
||||
* with amp_close().
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \sa amp_init(), amp_close()
|
||||
*/
|
||||
int HAMLIB_API amp_cleanup(AMP *amp)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if they forgot to close the amp
|
||||
*/
|
||||
if (amp->state.comm_state)
|
||||
{
|
||||
amp_close(amp);
|
||||
}
|
||||
|
||||
/*
|
||||
* basically free up the priv struct
|
||||
*/
|
||||
if (amp->caps->amp_cleanup)
|
||||
{
|
||||
amp->caps->amp_cleanup(amp);
|
||||
}
|
||||
|
||||
free(amp);
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief reset the amplifier
|
||||
* \param amp The amp handle
|
||||
* \param reset The reset operation to perform
|
||||
*
|
||||
* Resets the amplifier.
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, otherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
*/
|
||||
int HAMLIB_API amp_reset(AMP *amp, amp_reset_t reset)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
|
||||
if (caps->reset == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
return caps->reset(amp, reset);
|
||||
}
|
||||
|
||||
int HAMLIB_API amp_get_freq(AMP *amp, freq_t *freq)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
|
||||
if (caps->get_freq == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
return caps->get_freq(amp, freq);
|
||||
}
|
||||
|
||||
int HAMLIB_API amp_set_freq(AMP *amp, freq_t freq)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
|
||||
if (caps->set_freq == NULL)
|
||||
{
|
||||
return -RIG_ENAVAIL;
|
||||
}
|
||||
|
||||
return caps->set_freq(amp, freq);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get general information from the amplifier
|
||||
* \param amp The amp handle
|
||||
*
|
||||
* Retrieves some general information from the amplifier.
|
||||
* This can include firmware revision, exact model name, or just nothing.
|
||||
*
|
||||
* \return a pointer to static memory containing the ASCIIZ string
|
||||
* if the operation has been sucessful, otherwise NULL if an error occured
|
||||
* or get_info not part of capabilities.
|
||||
*/
|
||||
const char *HAMLIB_API amp_get_info(AMP *amp)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (amp->caps->get_info == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return amp->caps->get_info(amp);
|
||||
}
|
||||
|
||||
int HAMLIB_API amp_get_level(AMP *amp, setting_t level, value_t *val)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (amp->caps->get_level == NULL)
|
||||
{
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
return amp->caps->get_level(amp, level, val);
|
||||
}
|
||||
|
||||
int HAMLIB_API amp_get_ext_level(AMP *amp, token_t level, value_t *val)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (amp->caps->get_ext_level == NULL)
|
||||
{
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
return amp->caps->get_ext_level(amp, level, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief turn on/off the amplifier or standby/operate toggle
|
||||
* \param amp The amp handle
|
||||
* \param status The status to set to
|
||||
*
|
||||
* turns on/off the amplifier.
|
||||
* See #RIG_POWER_ON, #RIG_POWER_OFF and #RIG_POWER_STANDBY #RIG_POWER_OPERATE defines
|
||||
* for the \a status.
|
||||
*
|
||||
* \return RIG_OK if the operation has been sucessful, ortherwise
|
||||
* a negative value if an error occured (in which case, cause is
|
||||
* set appropriately).
|
||||
*
|
||||
* \sa amp_get_powerstat()
|
||||
*/
|
||||
|
||||
int HAMLIB_API amp_set_powerstat(AMP *amp, powerstat_t status)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (amp->caps->set_powerstat == NULL)
|
||||
{
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
return amp->caps->set_powerstat(amp, status);
|
||||
}
|
||||
|
||||
int HAMLIB_API amp_get_powerstat(AMP *amp, powerstat_t *status)
|
||||
{
|
||||
amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (CHECK_AMP_ARG(amp))
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
if (amp->caps->get_powerstat == NULL)
|
||||
{
|
||||
return -RIG_ENIMPL;
|
||||
}
|
||||
|
||||
return amp->caps->get_powerstat(amp, status);
|
||||
}
|
||||
|
||||
|
||||
/*! @} */
|
|
@ -182,7 +182,6 @@ const struct confparams *HAMLIB_API rig_ext_lookup(RIG *rig, const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param rig
|
||||
* \param token
|
||||
|
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Hamlib Interface - extra parameter interface for amplifiers
|
||||
* Copyright (c) 2000-2008 by Stephane Fillod
|
||||
* Derived from ext.c
|
||||
* Copyright (c) 2019 by Michael Black W9MDB
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup amp
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file ext.c
|
||||
* \brief Extension request parameter interface
|
||||
*
|
||||
* An open-ended set of extension parameters and levels are available for each
|
||||
* amp, as provided in the ampcaps extparms and extlevels lists. These
|
||||
* provide a way to work with amp-specific functions that don't fit into the
|
||||
* basic "virtual amp" of Hamlib. See amplifiers/kpa.c for an example.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* Standard input/output definitions */
|
||||
#include <string.h> /* String function definitions */
|
||||
#include <unistd.h> /* UNIX standard function definitions */
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#include "token.h"
|
||||
|
||||
|
||||
/**
|
||||
* \param amp The amp handle
|
||||
* \param cfunc callback function of each extlevel
|
||||
* \param data cookie to be passed to \a cfunc callback
|
||||
* \brief Executes cfunc on all the elements stored in the extlevels table
|
||||
*
|
||||
* The callback \a cfunc is called until it returns a value which is not
|
||||
* strictly positive. A zero value means a normal end of iteration, and a
|
||||
* negative value an abnormal end, which will be the return value of
|
||||
* amp_ext_level_foreach.
|
||||
*/
|
||||
int HAMLIB_API amp_ext_level_foreach(AMP *amp,
|
||||
int (*cfunc)(AMP *,
|
||||
const struct confparams *,
|
||||
amp_ptr_t),
|
||||
amp_ptr_t data)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
int ret;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps || !cfunc)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extlevels; cfp && cfp->name; cfp++)
|
||||
{
|
||||
ret = (*cfunc)(amp, cfp, data);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param amp The amp handle
|
||||
* \param cfunc callback function of each extparm
|
||||
* \param data cookie to be passed to \a cfunc callback
|
||||
* \brief Executes cfunc on all the elements stored in the extparms table
|
||||
*
|
||||
* The callback \a cfunc is called until it returns a value which is not
|
||||
* strictly positive. A zero value means a normal end of iteration, and a
|
||||
* negative value an abnormal end, which will be the return value of
|
||||
* amp_ext_parm_foreach.
|
||||
*/
|
||||
int HAMLIB_API amp_ext_parm_foreach(AMP *amp,
|
||||
int (*cfunc)(AMP *,
|
||||
const struct confparams *,
|
||||
amp_ptr_t),
|
||||
amp_ptr_t data)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
int ret;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps || !cfunc)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extparms; cfp && cfp->name; cfp++)
|
||||
{
|
||||
ret = (*cfunc)(amp, cfp, data);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param amp
|
||||
* \param name
|
||||
* \brief lookup ext token by its name, return pointer to confparams struct.
|
||||
*
|
||||
* Lookup extlevels table first, then fall back to extparms.
|
||||
*
|
||||
* Returns NULL if nothing found
|
||||
*
|
||||
* TODO: should use Lex to speed it up, strcmp hurts!
|
||||
*/
|
||||
const struct confparams *HAMLIB_API amp_ext_lookup(AMP *amp, const char *name)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extlevels; cfp && cfp->name; cfp++)
|
||||
{
|
||||
if (!strcmp(cfp->name, name))
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extparms; cfp && cfp->name; cfp++)
|
||||
{
|
||||
if (!strcmp(cfp->name, name))
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param amp
|
||||
* \param token
|
||||
* \brief lookup ext token, return pointer to confparams struct.
|
||||
*
|
||||
* lookup extlevels table first, then fall back to extparms.
|
||||
*
|
||||
* Returns NULL if nothing found
|
||||
*/
|
||||
const struct confparams * HAMLIB_API amp_ext_lookup_tok(AMP *amp, token_t token)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extlevels; cfp && cfp->token; cfp++)
|
||||
{
|
||||
if (cfp->token == token)
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
for (cfp = amp->caps->extparms; cfp && cfp->token; cfp++)
|
||||
{
|
||||
if (cfp->token == token)
|
||||
{
|
||||
return cfp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \param amp
|
||||
* \param name
|
||||
* \brief Simple lookup returning token id assicated with name
|
||||
*/
|
||||
token_t HAMLIB_API amp_ext_token_lookup(AMP *amp, const char *name)
|
||||
{
|
||||
const struct confparams *cfp;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
cfp = amp_ext_lookup(amp, name);
|
||||
|
||||
if (!cfp)
|
||||
{
|
||||
return RIG_CONF_END;
|
||||
}
|
||||
|
||||
return cfp->token;
|
||||
}
|
||||
|
||||
/** @} */
|
73
src/misc.c
73
src/misc.c
|
@ -51,6 +51,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
|
@ -637,6 +638,23 @@ static struct
|
|||
{ RIG_LEVEL_NONE, "" },
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
setting_t level;
|
||||
const char *str;
|
||||
} levelamp_str[] =
|
||||
{
|
||||
{ AMP_LEVEL_SWR, "SWR" },
|
||||
{ AMP_LEVEL_NH, "NH" },
|
||||
{ AMP_LEVEL_PF, "PF" },
|
||||
{ AMP_LEVEL_PWR_INPUT, "PWRINPUT" },
|
||||
{ AMP_LEVEL_PWR_FWD, "PWRFORWARD" },
|
||||
{ AMP_LEVEL_PWR_REFLECTED, "PWRREFLECTED" },
|
||||
{ AMP_LEVEL_PWR_PEAK, "PWRPEAK" },
|
||||
{ AMP_LEVEL_FAULT, "FAULT" },
|
||||
{ AMP_LEVEL_NONE, "" },
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Convert alpha string to enum RIG_LEVEL_...
|
||||
|
@ -662,6 +680,32 @@ setting_t HAMLIB_API rig_parse_level(const char *s)
|
|||
return RIG_LEVEL_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert alpha string to enum AMP_LEVEL_...
|
||||
* \param s input alpha string
|
||||
* \return AMP_LEVEL_...
|
||||
*
|
||||
* \sa amp_level_e()
|
||||
*/
|
||||
setting_t HAMLIB_API amp_parse_level(const char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called level=%s\n", __func__, s);
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called str=%s\n", __func__, levelamp_str[0].str);
|
||||
for (i = 0 ; levelamp_str[i].str[0] != '\0'; i++)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called checking=%s\n", __func__, levelamp_str[i].str);
|
||||
if (!strcmp(s, levelamp_str[i].str))
|
||||
{
|
||||
return levelamp_str[i].level;
|
||||
}
|
||||
}
|
||||
|
||||
return RIG_LEVEL_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Convert enum RIG_LEVEL_... to alpha string
|
||||
|
@ -692,6 +736,35 @@ const char * HAMLIB_API rig_strlevel(setting_t level)
|
|||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert enum AMP_LEVEL_... to alpha string
|
||||
* \param level AMP_LEVEL_...
|
||||
* \return alpha string
|
||||
*
|
||||
* \sa amp_level_e()
|
||||
*/
|
||||
const char * HAMLIB_API amp_strlevel(setting_t level)
|
||||
{
|
||||
int i;
|
||||
|
||||
//rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (level == AMP_LEVEL_NONE)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i = 0; levelamp_str[i].str[0] != '\0'; i++)
|
||||
{
|
||||
if (level == levelamp_str[i].level)
|
||||
{
|
||||
return levelamp_str[i].str;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/rotator.h>
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
|
@ -69,4 +70,19 @@
|
|||
rig_probe_func_t cfunc, \
|
||||
rig_ptr_t data))
|
||||
|
||||
#define PREFIX_INITAMPS initamps
|
||||
#define PREFIX_PROBEAMPS probeallamps
|
||||
|
||||
#define DECLARE_INITAMP_BACKEND(backend) \
|
||||
EXTERN_C BACKEND_EXPORT(int) \
|
||||
MAKE_VERSIONED_FN(PREFIX_INITAMPS, ABI_VERSION, backend(void *be_handle))
|
||||
|
||||
#define DECLARE_PROBEAMP_BACKEND(backend) \
|
||||
EXTERN_C BACKEND_EXPORT(amp_model_t) \
|
||||
MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, \
|
||||
ABI_VERSION, \
|
||||
backend(hamlib_port_t *port, \
|
||||
rig_probe_func_t cfunc, \
|
||||
rig_ptr_t data))
|
||||
|
||||
#endif /* _REGISTER_H */
|
||||
|
|
|
@ -1962,10 +1962,10 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
|||
return par_ptt_get(&rig->state.pttport, ptt);
|
||||
|
||||
case RIG_PTT_CM108:
|
||||
if (caps->get_ptt)
|
||||
{
|
||||
return caps->get_ptt(rig, vfo, ptt);
|
||||
}
|
||||
//if (caps->get_ptt)
|
||||
//{
|
||||
// return caps->get_ptt(rig, vfo, ptt);
|
||||
//}
|
||||
|
||||
return cm108_ptt_get(&rig->state.pttport, ptt);
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/amplifier.h>
|
||||
#include "cal.h"
|
||||
|
||||
|
||||
|
@ -310,6 +311,35 @@ setting_t HAMLIB_API rig_has_get_level(RIG *rig, setting_t level)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief check retrieval ability of level settings
|
||||
* \param amp The amp handle
|
||||
* \param level The level settings
|
||||
*
|
||||
* Checks if an amp is capable of *getting* a level setting.
|
||||
* Since the \a level is an OR'ed bitwise argument, more than
|
||||
* one level can be checked at the same time.
|
||||
*
|
||||
* EXAMPLE: if (amp_has_get_level(my_amp, AMP_LVL_SWR)) disp_SWR();
|
||||
*
|
||||
* \return a bit map of supported level settings that can be retrieved,
|
||||
* otherwise 0 if none supported.
|
||||
*
|
||||
* \sa amp_has_set_level(), amp_get_level()
|
||||
*/
|
||||
setting_t HAMLIB_API amp_has_get_level(AMP *amp, setting_t level)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (amp->state.has_get_level & level);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief check settable ability of level settings
|
||||
* \param rig The rig handle
|
||||
|
|
|
@ -6,18 +6,21 @@
|
|||
|
||||
DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum
|
||||
|
||||
bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom
|
||||
bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom ampctl ampctld
|
||||
|
||||
check_PROGRAMS = dumpmem testrig testtrn testbcd testfreq listrigs testloc rig_bench
|
||||
|
||||
RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c sprintflst.c sprintflst.h uthash.h
|
||||
ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h
|
||||
AMPCOMMONSRC = ampctl_parse.c ampctl_parse.h dumpcaps_amp.c sprintflst.c sprintflst.h uthash.h
|
||||
|
||||
rigctl_SOURCES = rigctl.c $(RIGCOMMONSRC)
|
||||
rigctld_SOURCES = rigctld.c $(RIGCOMMONSRC)
|
||||
rigctlcom_SOURCES = rigctlcom.c $(RIGCOMMONSRC)
|
||||
rotctl_SOURCES = rotctl.c $(ROTCOMMONSRC)
|
||||
rotctld_SOURCES = rotctld.c $(ROTCOMMONSRC)
|
||||
ampctl_SOURCES = ampctl.c $(AMPCOMMONSRC)
|
||||
ampctld_SOURCES = ampctld.c $(AMPCOMMONSRC)
|
||||
rigswr_SOURCES = rigswr.c
|
||||
rigsmtr_SOURCES = rigsmtr.c
|
||||
rigmem_SOURCES = rigmem.c memsave.c memload.c memcsv.c sprintflst.c sprintflst.h
|
||||
|
@ -29,12 +32,15 @@ LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la
|
|||
rigmem_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS)
|
||||
rigctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
|
||||
rotctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
|
||||
ampctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
|
||||
rigctlcom_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
|
||||
|
||||
rigctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
rigctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
rotctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
rotctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
ampctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
ampctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
rigmem_LDADD = $(LIBXML2_LIBS) $(LDADD)
|
||||
rigctlcom_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS)
|
||||
|
||||
|
@ -44,8 +50,10 @@ rigswr_LDFLAGS = $(WINEXELDFLAGS)
|
|||
rigsmtr_LDFLAGS = $(WINEXELDFLAGS)
|
||||
rigmem_LDFLAGS = $(WINEXELDFLAGS)
|
||||
rotctl_LDFLAGS = $(WINEXELDFLAGS)
|
||||
ampctl_LDFLAGS = $(WINEXELDFLAGS)
|
||||
rigctld_LDFLAGS = $(WINEXELDFLAGS)
|
||||
rotctld_LDFLAGS = $(WINEXELDFLAGS)
|
||||
ampctld_LDFLAGS = $(WINEXELDFLAGS)
|
||||
rigctlcom_LDFLAGS = $(WINEXELDFLAGS)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* ampctl.c - (C) Stephane Fillod 2000-2010
|
||||
* (C) Nate Bargmann 2003,2007,2010,2011,2012,2013
|
||||
* (C) The Hamlib Group 2002,2006
|
||||
* (C) Derived from rotctl.c Michael Black W9MDB 2019
|
||||
*
|
||||
* This program tests/controls an amplifier using Hamlib.
|
||||
* It takes commands in interactive mode as well as
|
||||
* from command line options.
|
||||
*
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
# if defined(HAVE_READLINE_READLINE_H)
|
||||
# include <readline/readline.h>
|
||||
# elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */
|
||||
# include <readline.h>
|
||||
# else /* !defined(HAVE_READLINE_H) */
|
||||
extern char *readline();
|
||||
# endif /* HAVE_READLINE_H */
|
||||
#else
|
||||
/* no readline */
|
||||
#endif /* HAVE_LIBREADLINE */
|
||||
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
# include <sys/stat.h>
|
||||
# define HST_SHRT_OPTS "iI"
|
||||
# if defined(HAVE_READLINE_HISTORY_H)
|
||||
# include <readline/history.h>
|
||||
# elif defined(HAVE_HISTORY_H)
|
||||
# include <history.h>
|
||||
# else /* !defined(HAVE_HISTORY_H) */
|
||||
extern void add_history();
|
||||
extern int write_history();
|
||||
extern int read_history();
|
||||
# endif /* defined(HAVE_READLINE_HISTORY_H) */
|
||||
#else
|
||||
/* no history */
|
||||
# define HST_SHRT_OPTS ""
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
#include "misc.h"
|
||||
|
||||
#include "ampctl_parse.h"
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
void usage();
|
||||
|
||||
/*
|
||||
* 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:s:C:t:LvhVluZ"
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"model", 1, 0, 'm'},
|
||||
{"amp-file", 1, 0, 'r'},
|
||||
{"serial-speed", 1, 0, 's'},
|
||||
{"send-cmd-term", 1, 0, 't'},
|
||||
{"list", 0, 0, 'l'},
|
||||
{"set-conf", 1, 0, 'C'},
|
||||
{"show-conf", 0, 0, 'L'},
|
||||
{"dump-caps", 0, 0, 'u'},
|
||||
{"debug-time-stamps", 0, 0, 'Z'},
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
{"read-history", 0, 0, 'i'},
|
||||
{"save-history", 0, 0, 'I'},
|
||||
#endif
|
||||
{"verbose", 0, 0, 'v'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#define MAXCONFLEN 128
|
||||
|
||||
/* variable for readline support */
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
static const int have_rl = 1;
|
||||
#endif
|
||||
|
||||
|
||||
int interactive = 1; /* if no cmd on command line, switch to interactive */
|
||||
int prompt = 1; /* Print prompt in ampctl */
|
||||
|
||||
char send_cmd_term = '\r'; /* send_cmd termination char */
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AMP *my_amp; /* handle to amp (instance) */
|
||||
amp_model_t my_model = AMP_MODEL_DUMMY;
|
||||
|
||||
int retcode; /* generic return code from functions */
|
||||
int exitcode;
|
||||
|
||||
int verbose = 0;
|
||||
int show_conf = 0;
|
||||
int dump_caps_opt = 0;
|
||||
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
int rd_hist = 0;
|
||||
int sv_hist = 0;
|
||||
const char *hist_dir = NULL;
|
||||
const char hist_file[] = "/.ampctl_history";
|
||||
char *hist_path = NULL;
|
||||
struct stat hist_dir_stat;
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
|
||||
const char *amp_file = NULL;
|
||||
int serial_rate = 0;
|
||||
char conf_parms[MAXCONFLEN] = "";
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc,
|
||||
argv,
|
||||
SHORT_OPTIONS HST_SHRT_OPTS,
|
||||
long_options,
|
||||
&option_index);
|
||||
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
|
||||
case 'V':
|
||||
version();
|
||||
exit(0);
|
||||
|
||||
case 'm':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my_model = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
amp_file = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
serial_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (*conf_parms != '\0')
|
||||
{
|
||||
strcat(conf_parms, ",");
|
||||
}
|
||||
|
||||
strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strlen(optarg) > 1)
|
||||
{
|
||||
send_cmd_term = strtol(optarg, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_cmd_term = optarg[0];
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
|
||||
case 'i':
|
||||
rd_hist++;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
sv_hist++;
|
||||
break;
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
show_conf++;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
rig_set_debug(0);
|
||||
list_models();
|
||||
exit(0);
|
||||
|
||||
case 'u':
|
||||
dump_caps_opt++;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
rig_set_debug_time_stamp(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(); /* unknown option? */
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rig_set_debug(verbose);
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "ampctl, %s\n", hamlib_version);
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Report bugs to <hamlib-developer@lists.sourceforge.net>\n\n");
|
||||
|
||||
/*
|
||||
* at least one command on command line,
|
||||
* disable interactive mode
|
||||
*/
|
||||
if (optind < argc)
|
||||
{
|
||||
interactive = 0;
|
||||
}
|
||||
|
||||
my_amp = amp_init(my_model);
|
||||
|
||||
if (!my_amp)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Unknown amp num %d, or initialization error.\n",
|
||||
my_model);
|
||||
|
||||
fprintf(stderr, "Please check with --list option.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
retcode = set_conf(my_amp, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (amp_file)
|
||||
{
|
||||
strncpy(my_amp->state.ampport.pathname, amp_file, FILPATHLEN - 1);
|
||||
}
|
||||
|
||||
/* FIXME: bound checking and port type == serial */
|
||||
if (serial_rate != 0)
|
||||
{
|
||||
my_amp->state.ampport.parm.serial.rate = serial_rate;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* print out conf parameters
|
||||
*/
|
||||
if (show_conf)
|
||||
{
|
||||
amp_token_foreach(my_amp, print_conf_list, (rig_ptr_t)my_amp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print out capabilities, and exits immediately as we may be interested
|
||||
* only in caps, and rig_open may fail.
|
||||
*/
|
||||
if (dump_caps_opt)
|
||||
{
|
||||
dumpcaps_amp(my_amp, stdout);
|
||||
amp_cleanup(my_amp); /* if you care about memory */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
retcode = amp_open(my_amp);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "amp_open: error = %s \n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (verbose > 0)
|
||||
{
|
||||
printf("Opened amp model %d, '%s'\n",
|
||||
my_amp->caps->amp_model,
|
||||
my_amp->caps->model_name);
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Backend version: %s, Status: %s\n",
|
||||
my_amp->caps->version,
|
||||
rig_strstatus(my_amp->caps->status));
|
||||
|
||||
exitcode = 0;
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
|
||||
if (interactive && prompt && have_rl)
|
||||
{
|
||||
rl_readline_name = "ampctl";
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
using_history(); /* Initialize Readline History */
|
||||
|
||||
if (rd_hist || sv_hist)
|
||||
{
|
||||
if (!(hist_dir = getenv("AMPCTL_HIST_DIR")))
|
||||
{
|
||||
hist_dir = getenv("HOME");
|
||||
}
|
||||
|
||||
if (((stat(hist_dir, &hist_dir_stat) == -1) && (errno == ENOENT))
|
||||
|| !(S_ISDIR(hist_dir_stat.st_mode)))
|
||||
{
|
||||
|
||||
fprintf(stderr, "Warning: %s is not a directory!\n", hist_dir);
|
||||
}
|
||||
|
||||
int hist_path_size = sizeof(char) * (strlen(hist_dir) + strlen(hist_file) + 1);
|
||||
hist_path = (char *)calloc(hist_path_size, sizeof(char));
|
||||
|
||||
snprintf(hist_path, hist_path_size, "%s%s", hist_dir, hist_file);
|
||||
|
||||
}
|
||||
|
||||
if (rd_hist && hist_path)
|
||||
{
|
||||
if (read_history(hist_path) == ENOENT)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Warning: Could not read history from %s\n",
|
||||
hist_path);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBREADLINE */
|
||||
|
||||
do
|
||||
{
|
||||
retcode = ampctl_parse(my_amp, stdin, stdout, argv, argc);
|
||||
|
||||
if (retcode == 2)
|
||||
{
|
||||
exitcode = 2;
|
||||
}
|
||||
}
|
||||
while (retcode == 0 || retcode == 2);
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
|
||||
if (interactive && prompt && have_rl)
|
||||
{
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
|
||||
if (sv_hist && hist_path)
|
||||
{
|
||||
if (write_history(hist_path) == ENOENT)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\nWarning: Could not write history to %s\n",
|
||||
hist_path);
|
||||
}
|
||||
}
|
||||
|
||||
if ((rd_hist || sv_hist) && hist_path)
|
||||
{
|
||||
free(hist_path);
|
||||
hist_path = (char *)NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBREADLINE */
|
||||
amp_close(my_amp); /* close port */
|
||||
amp_cleanup(my_amp); /* if you care about memory */
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("Usage: ampctl [OPTION]... [COMMAND]...\n"
|
||||
"Send COMMANDs to a connected amplifier.\n\n");
|
||||
|
||||
printf(
|
||||
" -m, --model=ID select amplifier model number. See model list\n"
|
||||
" -r, --amp-file=DEVICE set device of the amplifier to operate on\n"
|
||||
" -s, --serial-speed=BAUD set serial speed of the serial port\n"
|
||||
" -t, --send-cmd-term=CHAR set send_cmd command termination char\n"
|
||||
" -C, --set-conf=PARM=VAL set config parameters\n"
|
||||
" -L, --show-conf list all config parameters\n"
|
||||
" -l, --list list all model numbers and exit\n"
|
||||
" -u, --dump-caps dump capabilities and exit\n"
|
||||
#ifdef HAVE_READLINE_HISTORY
|
||||
" -i, --read-history read prior interactive session history\n"
|
||||
" -I, --save-history save current interactive session history\n"
|
||||
#endif
|
||||
" -v, --verbose set verbose mode, cumulative\n"
|
||||
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n\n"
|
||||
);
|
||||
|
||||
usage_amp(stdout);
|
||||
|
||||
printf("\nReport bugs to <hamlib-developer@lists.sourceforge.net>.\n");
|
||||
}
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* ampctl_parse.h - (C) Stephane Fillod 2000-2008
|
||||
* Derived from rotctl_parse.h - (C) Michael Black 2019
|
||||
*
|
||||
* This program test/control an amplifier using Hamlib.
|
||||
* It takes commands in interactive mode as well as
|
||||
* from command line options.
|
||||
*
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AMPCTL_PARSE_H
|
||||
#define AMPCTL_PARSE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
/*
|
||||
* external prototype
|
||||
*/
|
||||
|
||||
int dumpcaps_amp(AMP *, FILE *);
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
void usage_amp(FILE *);
|
||||
void version();
|
||||
void list_models();
|
||||
int print_conf_list(const struct confparams *cfp, rig_ptr_t data);
|
||||
int set_conf(AMP *my_amp, char *conf_parms);
|
||||
|
||||
int ampctl_parse(AMP *my_amp, FILE *fin, FILE *fout, char *argv[], int argc);
|
||||
|
||||
#endif /* AMPCTL_PARSE_H */
|
|
@ -0,0 +1,715 @@
|
|||
/*
|
||||
* ampctld.c - (C) Stephane Fillod 2000-2011
|
||||
* (C) Nate Bargmann 2010,2011,2012,2013
|
||||
*
|
||||
* This program test/control an amplifier using Hamlib.
|
||||
* It takes commands from network connection.
|
||||
*
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/types.h> /* See NOTES */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#elif HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
# include <fcntl.h>
|
||||
# if defined(HAVE_WSPIAPI_H)
|
||||
# include <wspiapi.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <hamlib/amplifier.h>
|
||||
#include "misc.h"
|
||||
|
||||
#include "ampctl_parse.h"
|
||||
|
||||
struct handle_data
|
||||
{
|
||||
AMP *amp;
|
||||
int sock;
|
||||
struct sockaddr_storage cli_addr;
|
||||
socklen_t clilen;
|
||||
};
|
||||
|
||||
void *handle_socket(void *arg);
|
||||
|
||||
void usage();
|
||||
|
||||
/*
|
||||
* 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:s:C:t:T:LuvhVlZ"
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"model", 1, 0, 'm'},
|
||||
{"amp-file", 1, 0, 'r'},
|
||||
{"serial-speed", 1, 0, 's'},
|
||||
{"port", 1, 0, 't'},
|
||||
{"listen-addr", 1, 0, 'T'},
|
||||
{"list", 0, 0, 'l'},
|
||||
{"set-conf", 1, 0, 'C'},
|
||||
{"show-conf", 0, 0, 'L'},
|
||||
{"dump-caps", 0, 0, 'u'},
|
||||
{"debug-time-stamps", 0, 0, 'Z'},
|
||||
{"verbose", 0, 0, 'v'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int interactive = 1; /* no cmd because of daemon */
|
||||
int prompt = 0 ; /* Daemon mode for rigparse return string */
|
||||
|
||||
const char *portno = "4533";
|
||||
const char *src_addr = NULL; /* INADDR_ANY */
|
||||
|
||||
char send_cmd_term = '\r'; /* send_cmd termination char */
|
||||
|
||||
#define MAXCONFLEN 128
|
||||
|
||||
|
||||
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,
|
||||
// Default language
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL))
|
||||
{
|
||||
|
||||
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, 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[])
|
||||
{
|
||||
AMP *my_amp; /* handle to amp (instance) */
|
||||
amp_model_t my_model = AMP_MODEL_DUMMY;
|
||||
|
||||
int retcode; /* generic return code from functions */
|
||||
|
||||
int verbose = 0;
|
||||
int show_conf = 0;
|
||||
int dump_caps_opt = 0;
|
||||
const char *amp_file = NULL;
|
||||
int serial_rate = 0;
|
||||
char conf_parms[MAXCONFLEN] = "";
|
||||
|
||||
struct addrinfo hints, *result, *saved_result;
|
||||
int sock_listen;
|
||||
int reuseaddr = 1;
|
||||
int sockopt;
|
||||
char host[NI_MAXHOST];
|
||||
char serv[NI_MAXSERV];
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_t thread;
|
||||
pthread_attr_t attr;
|
||||
#endif
|
||||
struct handle_data *arg;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
usage();
|
||||
exit(0);
|
||||
|
||||
case 'V':
|
||||
version();
|
||||
exit(0);
|
||||
|
||||
case 'm':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my_model = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
amp_file = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
serial_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (*conf_parms != '\0')
|
||||
{
|
||||
strcat(conf_parms, ",");
|
||||
}
|
||||
|
||||
strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
portno = optarg;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (!optarg)
|
||||
{
|
||||
usage(); /* wrong arg count */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
src_addr = optarg;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
show_conf++;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
list_models();
|
||||
exit(0);
|
||||
|
||||
case 'u':
|
||||
dump_caps_opt++;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
rig_set_debug_time_stamp(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(); /* unknown option? */
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rig_set_debug(verbose);
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "ampctld, %s\n", hamlib_version);
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Report bugs to <hamlib-developer@lists.sourceforge.net>\n\n");
|
||||
|
||||
my_amp = amp_init(my_model);
|
||||
|
||||
if (!my_amp)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Unknown amp num %d, or initialization error.\n",
|
||||
my_model);
|
||||
|
||||
fprintf(stderr, "Please check with --list option.\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
#if 0
|
||||
retcode = set_conf(my_amp, conf_parms);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (amp_file)
|
||||
{
|
||||
strncpy(my_amp->state.ampport.pathname, amp_file, FILPATHLEN - 1);
|
||||
}
|
||||
|
||||
/* FIXME: bound checking and port type == serial */
|
||||
if (serial_rate != 0)
|
||||
{
|
||||
my_amp->state.ampport.parm.serial.rate = serial_rate;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* print out conf parameters
|
||||
*/
|
||||
if (show_conf)
|
||||
{
|
||||
amp_token_foreach(my_amp, print_conf_list, (rig_ptr_t)my_amp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print out conf parameters, and exits immediately as we may be
|
||||
* interested only in only caps, and rig_open may fail.
|
||||
*/
|
||||
if (dump_caps_opt)
|
||||
{
|
||||
dumpcaps_amp(my_amp, stdout);
|
||||
amp_cleanup(my_amp); /* if you care about memory */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
retcode = amp_open(my_amp);
|
||||
|
||||
if (retcode != RIG_OK)
|
||||
{
|
||||
fprintf(stderr, "amp_open: error = %s \n", rigerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (verbose > 0)
|
||||
{
|
||||
printf("Opened amp model %d, '%s'\n",
|
||||
my_amp->caps->amp_model,
|
||||
my_amp->caps->model_name);
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Backend version: %s, Status: %s\n",
|
||||
my_amp->caps->version,
|
||||
rig_strstatus(my_amp->caps->status));
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# ifndef SO_OPENTYPE
|
||||
# define SO_OPENTYPE 0x7008
|
||||
# endif
|
||||
# ifndef SO_SYNCHRONOUS_NONALERT
|
||||
# define SO_SYNCHRONOUS_NONALERT 0x20
|
||||
# endif
|
||||
# ifndef INVALID_SOCKET
|
||||
# define INVALID_SOCKET -1
|
||||
# endif
|
||||
|
||||
WSADATA wsadata;
|
||||
|
||||
if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR)
|
||||
{
|
||||
fprintf(stderr, "WSAStartup socket error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sockopt = SO_SYNCHRONOUS_NONALERT;
|
||||
setsockopt(INVALID_SOCKET,
|
||||
SOL_SOCKET,
|
||||
SO_OPENTYPE,
|
||||
(char *)&sockopt,
|
||||
sizeof(sockopt));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prepare listening socket
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = SOCK_STREAM; /* TCP socket */
|
||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||
hints.ai_protocol = 0; /* Any protocol */
|
||||
|
||||
retcode = getaddrinfo(src_addr, portno, &hints, &result);
|
||||
|
||||
if (retcode != 0)
|
||||
{
|
||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
saved_result = result;
|
||||
|
||||
do
|
||||
{
|
||||
sock_listen = socket(result->ai_family,
|
||||
result->ai_socktype,
|
||||
result->ai_protocol);
|
||||
|
||||
if (sock_listen < 0)
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "socket");
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&reuseaddr, sizeof(reuseaddr)) < 0)
|
||||
{
|
||||
|
||||
handle_error(RIG_DEBUG_ERR, "setsockopt");
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
|
||||
if (AF_INET6 == result->ai_family)
|
||||
{
|
||||
/* allow IPv4 mapped to IPv6 clients, MS & BSD default this
|
||||
to 1 i.e. disallowed */
|
||||
sockopt = 0;
|
||||
|
||||
if (setsockopt(sock_listen,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_V6ONLY,
|
||||
(char *)&sockopt,
|
||||
sizeof(sockopt))
|
||||
< 0)
|
||||
{
|
||||
|
||||
handle_error(RIG_DEBUG_ERR, "setsockopt");
|
||||
freeaddrinfo(saved_result); /* No longer needed */
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (0 == bind(sock_listen, result->ai_addr, result->ai_addrlen))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)");
|
||||
#ifdef __MINGW32__
|
||||
closesocket(sock_listen);
|
||||
#else
|
||||
close(sock_listen);
|
||||
#endif
|
||||
}
|
||||
while ((result = result->ai_next) != NULL);
|
||||
|
||||
freeaddrinfo(saved_result); /* No longer needed */
|
||||
|
||||
if (NULL == result)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "bind error - no available interface\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listen(sock_listen, 4) < 0)
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "listening");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#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. */
|
||||
#if HAVE_SIGACTION
|
||||
struct sigaction act;
|
||||
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");
|
||||
}
|
||||
|
||||
#elif HAVE_SIGNAL
|
||||
|
||||
if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "signal");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main loop accepting connections
|
||||
*/
|
||||
do
|
||||
{
|
||||
arg = malloc(sizeof(struct handle_data));
|
||||
|
||||
if (!arg)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "malloc: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
arg->amp = my_amp;
|
||||
arg->clilen = sizeof(arg->cli_addr);
|
||||
arg->sock = accept(sock_listen,
|
||||
(struct sockaddr *) &arg->cli_addr,
|
||||
&arg->clilen);
|
||||
|
||||
if (arg->sock < 0)
|
||||
{
|
||||
handle_error(RIG_DEBUG_ERR, "accept");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((retcode = getnameinfo((struct sockaddr const *)&arg->cli_addr,
|
||||
arg->clilen,
|
||||
host,
|
||||
sizeof(host),
|
||||
serv,
|
||||
sizeof(serv),
|
||||
NI_NOFQDN))
|
||||
< 0)
|
||||
{
|
||||
|
||||
rig_debug(RIG_DEBUG_WARN,
|
||||
"Peer lookup error: %s",
|
||||
gai_strerror(retcode));
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Connection opened from %s:%s\n",
|
||||
host,
|
||||
serv);
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
retcode = pthread_create(&thread, &attr, handle_socket, arg);
|
||||
|
||||
if (retcode != 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "pthread_create: %s\n", strerror(retcode));
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
handle_socket(arg);
|
||||
#endif
|
||||
}
|
||||
while (retcode == 0);
|
||||
|
||||
amp_close(my_amp); /* close port */
|
||||
amp_cleanup(my_amp); /* if you care about memory */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is the function run by the threads
|
||||
*/
|
||||
void *handle_socket(void *arg)
|
||||
{
|
||||
struct handle_data *handle_data_arg = (struct handle_data *)arg;
|
||||
FILE *fsockin;
|
||||
FILE *fsockout;
|
||||
int retcode;
|
||||
char host[NI_MAXHOST];
|
||||
char serv[NI_MAXSERV];
|
||||
|
||||
#ifdef __MINGW32__
|
||||
int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY);
|
||||
|
||||
if (sock_osfhandle == -1)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "_open_osfhandle error: %s\n", strerror(errno));
|
||||
goto handle_exit;
|
||||
}
|
||||
|
||||
fsockin = _fdopen(sock_osfhandle, "rb");
|
||||
#else
|
||||
fsockin = fdopen(handle_data_arg->sock, "rb");
|
||||
#endif
|
||||
|
||||
if (!fsockin)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "fdopen in: %s\n", strerror(errno));
|
||||
goto handle_exit;
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
fsockout = _fdopen(sock_osfhandle, "wb");
|
||||
#else
|
||||
fsockout = fdopen(handle_data_arg->sock, "wb");
|
||||
#endif
|
||||
|
||||
if (!fsockout)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "fdopen out: %s\n", strerror(errno));
|
||||
fclose(fsockin);
|
||||
goto handle_exit;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
retcode = ampctl_parse(handle_data_arg->amp, fsockin, fsockout, NULL, 0);
|
||||
|
||||
if (ferror(fsockin) || ferror(fsockout))
|
||||
{
|
||||
retcode = 1;
|
||||
}
|
||||
}
|
||||
while (retcode == 0 || retcode == 2);
|
||||
|
||||
if ((retcode = getnameinfo((struct sockaddr const *)&handle_data_arg->cli_addr,
|
||||
handle_data_arg->clilen,
|
||||
host,
|
||||
sizeof(host),
|
||||
serv,
|
||||
sizeof(serv),
|
||||
NI_NOFQDN))
|
||||
< 0)
|
||||
{
|
||||
|
||||
rig_debug(RIG_DEBUG_WARN,
|
||||
"Peer lookup error: %s",
|
||||
gai_strerror(retcode));
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"Connection closed from %s:%s\n",
|
||||
host,
|
||||
serv);
|
||||
|
||||
fclose(fsockin);
|
||||
#ifndef __MINGW32__
|
||||
fclose(fsockout);
|
||||
#endif
|
||||
|
||||
handle_exit:
|
||||
#ifdef __MINGW32__
|
||||
closesocket(handle_data_arg->sock);
|
||||
#else
|
||||
close(handle_data_arg->sock);
|
||||
#endif
|
||||
free(arg);
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("Usage: ampctld [OPTION]... [COMMAND]...\n"
|
||||
"Daemon serving COMMANDs to a connected amplifier.\n\n");
|
||||
|
||||
printf(
|
||||
" -m, --model=ID select amplifier model number. See model list\n"
|
||||
" -r, --amp-file=DEVICE set device of the amplifier to operate on\n"
|
||||
" -s, --serial-speed=BAUD set serial speed of the serial port\n"
|
||||
" -t, --port=NUM set TCP listening port, default %s\n"
|
||||
" -T, --listen-addr=IPADDR set listening IP address, default ANY\n"
|
||||
" -C, --set-conf=PARM=VAL set config parameters\n"
|
||||
" -L, --show-conf list all config parameters\n"
|
||||
" -l, --list list all model numbers and exit\n"
|
||||
" -u, --dump-caps dump capabilities and exit\n"
|
||||
" -v, --verbose set verbose mode, cumulative\n"
|
||||
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n\n",
|
||||
portno);
|
||||
|
||||
usage_amp(stdout);
|
||||
|
||||
printf("\nReport bugs to <hamlib-developer@lists.sourceforge.net>.\n");
|
||||
}
|
|
@ -764,17 +764,17 @@ void range_print(FILE *fout, const struct freq_range_list range_list[], int rx)
|
|||
|
||||
fprintf(fout, "\t\tVFO list: ");
|
||||
sprintf_vfo(prntbuf, range_list[i].vfo);
|
||||
fprintf(fout, prntbuf);
|
||||
fprintf(fout, "%s", prntbuf);
|
||||
fprintf(fout, "\n");
|
||||
|
||||
fprintf(fout, "\t\tMode list: ");
|
||||
sprintf_mode(prntbuf, range_list[i].modes);
|
||||
fprintf(fout, prntbuf);
|
||||
fprintf(fout, "%s", prntbuf);
|
||||
fprintf(fout, "\n");
|
||||
|
||||
fprintf(fout, "\t\tAntenna list: ");
|
||||
sprintf_ant(prntbuf, range_list[i].ant);
|
||||
fprintf(fout, prntbuf);
|
||||
fprintf(fout, "%s", prntbuf);
|
||||
fprintf(fout, "\n");
|
||||
|
||||
if (!rx) {
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* dumpcaps_amp.c - Copyright (C) 2000-2012 Stephane Fillod
|
||||
* This programs dumps the capabilities of a backend rig.
|
||||
*
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <hamlib/rig.h>
|
||||
#include "misc.h"
|
||||
|
||||
#include "sprintflst.h"
|
||||
#include "ampctl_parse.h"
|
||||
|
||||
|
||||
/*
|
||||
* the amp may be in amp_init state, but not openned
|
||||
*/
|
||||
int dumpcaps_amp(AMP *amp, FILE *fout)
|
||||
{
|
||||
const struct amp_caps *caps;
|
||||
int backend_warnings = 0;
|
||||
static char prntbuf[1024];
|
||||
|
||||
if (!amp || !amp->caps)
|
||||
{
|
||||
return -RIG_EINVAL;
|
||||
}
|
||||
|
||||
caps = amp->caps;
|
||||
|
||||
fprintf(fout, "Caps dump for model:\t%d\n", caps->amp_model);
|
||||
fprintf(fout, "Model name:\t\t%s\n", caps->model_name);
|
||||
fprintf(fout, "Mfg name:\t\t%s\n", caps->mfg_name);
|
||||
fprintf(fout, "Backend version:\t%s\n", caps->version);
|
||||
fprintf(fout, "Backend copyright:\t%s\n", caps->copyright);
|
||||
fprintf(fout, "Backend status:\t\t%s\n", rig_strstatus(caps->status));
|
||||
fprintf(fout, "Amp type:\t\t");
|
||||
|
||||
switch (caps->amp_type & AMP_TYPE_MASK)
|
||||
{
|
||||
case AMP_TYPE_OTHER:
|
||||
fprintf(fout, "Other\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(fout, "Unknown type=%d\n", caps->amp_type);
|
||||
backend_warnings++;
|
||||
}
|
||||
|
||||
fprintf(fout, "Port type:\t\t");
|
||||
|
||||
switch (caps->port_type)
|
||||
{
|
||||
case RIG_PORT_SERIAL:
|
||||
fprintf(fout, "RS-232\n");
|
||||
fprintf(fout,
|
||||
"Serial speed:\t\t%d..%d bauds, %d%c%d%s\n",
|
||||
caps->serial_rate_min,
|
||||
caps->serial_rate_max,
|
||||
caps->serial_data_bits,
|
||||
caps->serial_parity == RIG_PARITY_NONE ? 'N' :
|
||||
caps->serial_parity == RIG_PARITY_ODD ? 'O' :
|
||||
caps->serial_parity == RIG_PARITY_EVEN ? 'E' :
|
||||
caps->serial_parity == RIG_PARITY_MARK ? 'M' : 'S',
|
||||
caps->serial_stop_bits,
|
||||
caps->serial_handshake == RIG_HANDSHAKE_NONE ? "" :
|
||||
(caps->serial_handshake == RIG_HANDSHAKE_XONXOFF ? " XONXOFF" : " CTS/RTS")
|
||||
);
|
||||
break;
|
||||
|
||||
case RIG_PORT_PARALLEL:
|
||||
fprintf(fout, "Parallel\n");
|
||||
break;
|
||||
|
||||
case RIG_PORT_DEVICE:
|
||||
fprintf(fout, "Device driver\n");
|
||||
break;
|
||||
|
||||
case RIG_PORT_USB:
|
||||
fprintf(fout, "USB\n");
|
||||
break;
|
||||
|
||||
case RIG_PORT_NETWORK:
|
||||
fprintf(fout, "Network link\n");
|
||||
break;
|
||||
|
||||
case RIG_PORT_UDP_NETWORK:
|
||||
fprintf(fout, "UDP Network link\n");
|
||||
break;
|
||||
|
||||
case RIG_PORT_NONE:
|
||||
fprintf(fout, "None\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(fout, "Unknown\n");
|
||||
backend_warnings++;
|
||||
}
|
||||
|
||||
fprintf(fout,
|
||||
"Write delay:\t\t%dmS, timeout %dmS, %d retr%s\n",
|
||||
caps->write_delay,
|
||||
caps->timeout, caps->retry,
|
||||
(caps->retry == 1) ? "y" : "ies");
|
||||
|
||||
fprintf(fout,
|
||||
"Post Write delay:\t%dmS\n",
|
||||
caps->post_write_delay);
|
||||
|
||||
fprintf(fout, "Has priv data:\t\t%c\n", caps->priv != NULL ? 'Y' : 'N');
|
||||
|
||||
sprintf_level_amp(prntbuf, caps->has_get_level);
|
||||
fprintf(fout, "Get level: %s\n", prntbuf);
|
||||
|
||||
/*
|
||||
* Status is either 'Y'es, 'E'mulated, 'N'o
|
||||
*
|
||||
* TODO: keep me up-to-date with API call list!
|
||||
*/
|
||||
fprintf(fout, "Has Init:\t\t%c\n", caps->amp_init != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Has Cleanup:\t\t%c\n", caps->amp_cleanup != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Has Open:\t\t%c\n", caps->amp_open != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Has Close:\t\t%c\n", caps->amp_close != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Can set Conf:\t\t%c\n", caps->set_conf != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Can get Conf:\t\t%c\n", caps->get_conf != NULL ? 'Y' : 'N');
|
||||
|
||||
fprintf(fout, "Can Reset:\t\t%c\n", caps->reset != NULL ? 'Y' : 'N');
|
||||
fprintf(fout, "Can get Info:\t\t%c\n", caps->get_info != NULL ? 'Y' : 'N');
|
||||
|
||||
fprintf(fout, "\nOverall backend warnings: %d\n", backend_warnings);
|
||||
|
||||
return backend_warnings;
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <hamlib/rig.h>
|
||||
#include <hamlib/amplifier.h>
|
||||
|
||||
#include "sprintflst.h"
|
||||
#include "misc.h"
|
||||
|
@ -207,6 +208,34 @@ int sprintf_level(char *str, setting_t level)
|
|||
return len;
|
||||
}
|
||||
|
||||
int sprintf_level_amp(char *str, setting_t level)
|
||||
{
|
||||
int i, len = 0;
|
||||
|
||||
*str = '\0';
|
||||
|
||||
if (level == AMP_LEVEL_NONE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < RIG_SETTING_MAX; i++)
|
||||
{
|
||||
const char *ms = amp_strlevel(level & rig_idx2setting(i));
|
||||
|
||||
if (!ms || !ms[0])
|
||||
{
|
||||
continue; /* unknown, FIXME! */
|
||||
}
|
||||
|
||||
strcat(str, ms);
|
||||
strcat(str, " ");
|
||||
len += strlen(ms) + 1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int sprintf_level_ext(char *str, const struct confparams *extlevels)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ extern int sprintf_vfo(char *str, vfo_t);
|
|||
extern int sprintf_ant(char *str, ant_t);
|
||||
extern int sprintf_func(char *str, setting_t);
|
||||
extern int sprintf_level(char *str, setting_t);
|
||||
extern int sprintf_level_amp(char *str, setting_t);
|
||||
extern int sprintf_level_ext(char *str, const struct confparams *);
|
||||
extern int sprintf_level_gran(char *str, setting_t, const gran_t gran[]);
|
||||
extern int sprintf_parm(char *str, setting_t);
|
||||
|
|
Ładowanie…
Reference in New Issue