Implemented emulation of rig transceive mode using polling (based on SIGALRM),

moved all transceive and event related functions from rig.c to event.c.


git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1468 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.0
Stéphane Fillod, F8CFE 2003-05-03 13:17:25 +00:00
rodzic 98e75bb16c
commit f8135d52df
7 zmienionych plików z 623 dodań i 366 usunięć

Wyświetl plik

@ -2,7 +2,7 @@
* Hamlib Interface - API header
* Copyright (c) 2000-2003 by Stephane Fillod and Frank Singleton
*
* $Id: rig.h,v 1.80 2003-04-27 22:15:04 fillods Exp $
* $Id: rig.h,v 1.81 2003-05-03 13:17:25 fillods Exp $
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -1245,12 +1245,17 @@ struct rig_state {
int hold_decode; /*!< set to 1 to hold the event decoder (async) otherwise 0 */
vfo_t current_vfo; /*!< VFO currently set */
int transceive; /*!< Whether the transceive mode is on */
int vfo_list; /*!< Complete list of VFO for this rig */
int comm_state; /*!< Comm port state, opened/closed. */
rig_ptr_t priv; /*!< Pointer to private rig state data. */
rig_ptr_t obj; /*!< Internal use by hamlib++ for event handling. */
int transceive; /*!< Whether the transceive mode is on */
int poll_interval; /*!< Event notification polling period in milliseconds */
freq_t current_freq; /*!< Frequency currently set */
rmode_t current_mode; /*!< Mode currently set */
pbwidth_t current_width; /*!< Passband width currently set */
};

Wyświetl plik

@ -9,7 +9,7 @@
* Hamlib Interface - configuration interface
* Copyright (c) 2000-2003 by Stephane Fillod
*
* $Id: conf.c,v 1.9 2003-02-23 22:38:54 fillods Exp $
* $Id: conf.c,v 1.10 2003-05-03 13:17:25 fillods Exp $
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -100,6 +100,11 @@ static const struct confparams frontend_cfg_params[] = {
"Serial port set state of DTR signal for external powering",
"Unset", RIG_CONF_COMBO, { .c = {{ "Unset", "ON", "OFF", NULL }} }
},
{ TOK_POLL_INTERVAL, "poll_interval", "Polling interval",
"Polling interval in millisecond for transceive emulation",
"500", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
},
{ RIG_CONF_END, NULL, }
};
@ -209,6 +214,10 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
case TOK_VFO_COMP:
rs->vfo_comp = atof(val);
break;
case TOK_POLL_INTERVAL:
rs->poll_interval = atof(val);
break;
default:
return -RIG_EINVAL;
@ -300,6 +309,9 @@ static int frontend_get_conf(RIG *rig, token_t token, char *val)
case TOK_VFO_COMP:
sprintf(val, "%f", rs->vfo_comp);
break;
case TOK_POLL_INTERVAL:
sprintf(val, "%d", rs->poll_interval);
break;
default:
return -RIG_EINVAL;

Wyświetl plik

@ -2,7 +2,7 @@
* Hamlib Interface - event handling
* Copyright (c) 2000-2003 by Stephane Fillod and Frank Singleton
*
* $Id: event.c,v 1.16 2003-04-16 22:33:18 fillods Exp $
* $Id: event.c,v 1.17 2003-05-03 13:17:25 fillods Exp $
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -29,7 +29,9 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <sys/stat.h>
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
@ -43,11 +45,17 @@
#include "event.h"
#ifndef DOC_HIDDEN
#define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !(r)->state.comm_state)
#ifdef HAVE_SIGINFO_T
static RETSIGTYPE sa_sigioaction(int signum, siginfo_t *si, void *data);
static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, void *data);
#else
static RETSIGTYPE sa_sigiohandler(int signum);
static RETSIGTYPE sa_sigalrmhandler(int signum);
#endif
/* This one should be in an include file */
@ -109,6 +117,45 @@ int add_trn_rig(RIG *rig)
return RIG_OK;
}
/*
* add_trn_poll_rig
* not exported in Hamlib API.
*/
int add_trn_poll_rig(RIG *rig)
{
struct sigaction act;
int status;
/*
* FIXME: multiple open will register several time SIGIO hndlr
*/
#ifdef HAVE_SIGINFO_T
act.sa_sigaction = sa_sigalrmaction;
#else
act.sa_handler = sa_sigalrmhandler;
#endif
sigemptyset(&act.sa_mask);
status = sigaction(SIGALRM, &act, NULL);
if (status < 0)
rig_debug(RIG_DEBUG_ERR,"%s sigaction failed: %s\n",
__FUNCTION__,
strerror(errno));
return RIG_OK;
}
/*
* remove_trn_poll_rig
* not exported in Hamlib API.
*/
int remove_trn_poll_rig(RIG *rig)
{
return -RIG_ENIMPL;
}
/*
* remove_trn_rig
* not exported in Hamlib API.
@ -116,9 +163,16 @@ int add_trn_rig(RIG *rig)
*/
int remove_trn_rig(RIG *rig)
{
return -RIG_ENIMPL;
if (rig->caps->transceive == RIG_TRN_RIG)
return -RIG_ENIMPL;
if (rig->state.transceive == RIG_TRN_POLL)
return remove_trn_poll_rig(rig);
return -RIG_EINVAL;
}
/*
* This is used by sa_sigio, the SIGIO handler
* to find out which rig generated this event,
@ -176,6 +230,65 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
return 1; /* process each opened rig */
}
/*
* This is used by sa_sigio, the SIGALRM handler
* to poll each RIG in RIG_TRN_POLL mode.
*
* assumes rig!=NULL
*/
static int search_rig_and_poll(RIG *rig, rig_ptr_t data)
{
struct rig_state *rs = &rig->state;
int retval;
if (rig->state.transceive != RIG_TRN_POLL)
return -1;
/*
* Do not disturb, the backend is currently receiving data
*/
if (rig->state.hold_decode)
return -1;
if (rig->caps->get_vfo && rig->callbacks.vfo_event) {
vfo_t vfo = RIG_VFO_CURR;
retval = rig->caps->get_vfo(rig, &vfo);
if (retval == RIG_OK) {
if (vfo != rs->current_vfo) {
rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg);
}
rs->current_vfo = vfo;
}
}
if (rig->caps->get_freq && rig->callbacks.freq_event) {
freq_t freq;
retval = rig->caps->get_freq(rig, RIG_VFO_CURR, &freq);
if (retval == RIG_OK) {
if (freq != rs->current_freq) {
rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq, rig->callbacks.freq_arg);
}
rs->current_freq = freq;
}
}
if (rig->caps->get_mode && rig->callbacks.mode_event) {
rmode_t rmode;
pbwidth_t width;
retval = rig->caps->get_mode(rig, RIG_VFO_CURR, &rmode, &width);
if (retval == RIG_OK) {
if (rmode != rs->current_mode || width != rs->current_width) {
rig->callbacks.mode_event(rig, RIG_VFO_CURR,
rmode, width, rig->callbacks.mode_arg);
}
rs->current_mode = rmode;
rs->current_width = width;
}
}
return 1; /* process each opened rig */
}
/*
* This is the SIGIO handler
@ -203,3 +316,284 @@ static RETSIGTYPE sa_sigiohandler(int signum)
#endif
/*
* This is the SIGALRM handler
*
* lookup in the list of open rigs,
* check the rig is not holding SIGALRM,
* then call get_freq and check for changes (this is done by search_rig)
*/
#ifdef HAVE_SIGINFO_T
static RETSIGTYPE sa_sigalrmaction(int signum, siginfo_t *si, rig_ptr_t data)
{
rig_debug(RIG_DEBUG_TRACE, "sa_sigalrmaction entered\n");
foreach_opened_rig(search_rig_and_poll, si);
}
#else
static RETSIGTYPE sa_sigalrmhandler(int signum)
{
rig_debug(RIG_DEBUG_TRACE, "sa_sigalrmaction entered\n");
foreach_opened_rig(search_rig_and_poll, NULL);
}
#endif
#endif /* !DOC_HIDDEN */
/**
* \brief set the callback for freq events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for freq events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_freq_callback(RIG *rig, freq_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.freq_event = cb;
rig->callbacks.freq_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for mode events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for mode events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_mode_callback(RIG *rig, mode_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.mode_event = cb;
rig->callbacks.mode_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for vfo events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for vfo events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_vfo_callback(RIG *rig, vfo_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.vfo_event = cb;
rig->callbacks.vfo_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for ptt events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for ptt events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_ptt_callback(RIG *rig, ptt_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.ptt_event = cb;
rig->callbacks.ptt_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for dcd events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for dcd events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_dcd_callback(RIG *rig, dcd_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.dcd_event = cb;
rig->callbacks.dcd_arg = arg;
return RIG_OK;
}
/**
* \brief control the transceive mode
* \param rig The rig handle
* \param trn The transceive status to set to
*
* Enable/disable the transceive handling of a rig and kick off async mode.
*
* \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 rig_get_trn()
*/
int rig_set_trn(RIG *rig, int trn)
{
const struct rig_caps *caps;
int retcode;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
caps = rig->caps;
if (trn == RIG_TRN_RIG) {
if (caps->transceive != RIG_TRN_RIG)
return -RIG_ENAVAIL;
if (rig->state.transceive == RIG_TRN_OFF) {
retcode = add_trn_rig(rig);
if (retcode == RIG_OK && caps->set_trn) {
retcode = caps->set_trn(rig, RIG_TRN_RIG);
}
} else {
return -RIG_ECONF;
}
} else if (trn == RIG_TRN_POLL) {
#ifdef HAVE_SETITIMER
struct itimerval value;
add_trn_poll_rig(rig);
/* install handler here */
value.it_value.tv_sec = 0;
value.it_value.tv_usec = rig->state.poll_interval*1000;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = rig->state.poll_interval*1000;
retcode = setitimer(ITIMER_REAL, &value, NULL);
if (retcode == -1) {
rig_debug(RIG_DEBUG_ERR, "%s: setitimer: %s\n",
__FUNCTION__,
strerror(errno));
remove_trn_rig(rig);
return -RIG_EINTERNAL;
}
#else
return -RIG_ENAVAIL;
#endif
} else if (trn == RIG_TRN_OFF) {
if (rig->state.transceive == RIG_TRN_POLL) {
#ifdef HAVE_SETITIMER
struct itimerval value;
retcode = remove_trn_rig(rig);
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = 0;
retcode = setitimer(ITIMER_REAL, &value, NULL);
if (retcode == -1) {
rig_debug(RIG_DEBUG_ERR, "%s: setitimer: %s\n",
__FUNCTION__,
strerror(errno));
return -RIG_EINTERNAL;
}
#else
return -RIG_ENAVAIL;
#endif
} else {
retcode = remove_trn_rig(rig);
if (caps->set_trn && caps->transceive == RIG_TRN_RIG) {
retcode = caps->set_trn(rig, RIG_TRN_OFF);
}
}
} else {
return -RIG_EINVAL;
}
if (retcode == RIG_OK)
rig->state.transceive = trn;
return retcode;
}
/**
* \brief get the current transceive mode
* \param rig The rig handle
* \param trn The location where to store the current transceive mode
*
* Retrieves the current status of the transceive mode, i.e. if radio
* sends new status automatically when some changes happened on the radio.
*
* \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 rig_set_trn()
*/
int rig_get_trn(RIG *rig, int *trn)
{
if (CHECK_RIG_ARG(rig) || !trn)
return -RIG_EINVAL;
if (rig->caps->get_trn != NULL)
return rig->caps->get_trn(rig, trn);
*trn = rig->state.transceive;
return RIG_OK;
}

503
src/rig.c
Wyświetl plik

@ -2,7 +2,7 @@
* Hamlib Interface - main file
* Copyright (c) 2000-2003 by Stephane Fillod and Frank Singleton
*
* $Id: rig.c,v 1.71 2003-04-27 22:15:06 fillods Exp $
* $Id: rig.c,v 1.72 2003-05-03 13:17:25 fillods Exp $
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -69,7 +69,7 @@ const char hamlib_version[] = "Hamlib version " PACKAGE_VERSION;
* \brief Hamlib copyright notice
*/
const char hamlib_copyright[] =
"Copyright (C) 2000, 2001, 2002 Stephane Fillod and Frank Singleton\n"
"Copyright (C) 2000-2003 Stephane Fillod and Frank Singleton\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.";
@ -269,7 +269,8 @@ RIG *rig_init(rig_model_t rig_model)
rs->vfo_comp = 0.0; /* override it with preferences */
rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */
rs->transceive = caps->transceive;
rs->transceive = RIG_TRN_OFF;
rs->poll_interval = 500;
/* should it be a parameter to rig_init ? --SF */
rs->itu_region = RIG_ITU_REGION2;
@ -511,86 +512,83 @@ int rig_open(RIG *rig)
int rig_close(RIG *rig)
{
const struct rig_caps *caps;
struct rig_state *rs;
const struct rig_caps *caps;
struct rig_state *rs;
rig_debug(RIG_DEBUG_VERBOSE,"rig:rig_close called \n");
rig_debug(RIG_DEBUG_VERBOSE,"rig:rig_close called \n");
if (!rig || !rig->caps)
return -RIG_EINVAL;
if (!rig || !rig->caps)
return -RIG_EINVAL;
caps = rig->caps;
rs = &rig->state;
caps = rig->caps;
rs = &rig->state;
if (!rs->comm_state)
return -RIG_EINVAL;
if (!rs->comm_state)
return -RIG_EINVAL;
if (rs->transceive) {
/*
* TODO: check error codes et al.
*/
remove_trn_rig(rig);
}
if (rs->transceive != RIG_TRN_OFF) {
remove_trn_rig(rig);
}
/*
* Let the backend say 73s to the rig.
* and ignore the return code.
*/
if (caps->rig_close)
caps->rig_close(rig);
/*
* Let the backend say 73s to the rig.
* and ignore the return code.
*/
if (caps->rig_close)
caps->rig_close(rig);
/*
* FIXME: what happens if PTT and rig ports are the same?
* (eg. ptt_type = RIG_PTT_SERIAL)
*/
switch(rs->pttport.type.ptt) {
case RIG_PTT_NONE:
case RIG_PTT_RIG:
break;
case RIG_PTT_SERIAL_RTS:
case RIG_PTT_SERIAL_DTR:
ser_close(&rs->pttport);
break;
case RIG_PTT_PARALLEL:
par_close(&rs->pttport);
break;
default:
rig_debug(RIG_DEBUG_ERR, "Unsupported PTT type %d\n",
rs->pttport.type.ptt);
}
/*
* FIXME: what happens if PTT and rig ports are the same?
* (eg. ptt_type = RIG_PTT_SERIAL)
*/
switch(rs->pttport.type.ptt) {
case RIG_PTT_NONE:
case RIG_PTT_RIG:
break;
case RIG_PTT_SERIAL_RTS:
case RIG_PTT_SERIAL_DTR:
ser_close(&rs->pttport);
break;
case RIG_PTT_PARALLEL:
par_close(&rs->pttport);
break;
default:
rig_debug(RIG_DEBUG_ERR, "Unsupported PTT type %d\n",
rs->pttport.type.ptt);
}
switch(rs->dcdport.type.dcd) {
case RIG_DCD_NONE:
case RIG_DCD_RIG:
break;
case RIG_DCD_SERIAL_DSR:
case RIG_DCD_SERIAL_CTS:
ser_close(&rs->dcdport);
break;
case RIG_DCD_PARALLEL:
par_close(&rs->dcdport);
break;
default:
rig_debug(RIG_DEBUG_ERR, "Unsupported DCD type %d\n",
rs->dcdport.type.dcd);
}
switch(rs->dcdport.type.dcd) {
case RIG_DCD_NONE:
case RIG_DCD_RIG:
break;
case RIG_DCD_SERIAL_DSR:
case RIG_DCD_SERIAL_CTS:
ser_close(&rs->dcdport);
break;
case RIG_DCD_PARALLEL:
par_close(&rs->dcdport);
break;
default:
rig_debug(RIG_DEBUG_ERR, "Unsupported DCD type %d\n",
rs->dcdport.type.dcd);
}
rs->dcdport.fd = rs->pttport.fd = -1;
rs->dcdport.fd = rs->pttport.fd = -1;
if (rs->rigport.fd != -1) {
if (!rs->rigport.stream)
fclose(rs->rigport.stream); /* this closes also fd */
else
close(rs->rigport.fd);
rs->rigport.fd = -1;
rs->rigport.stream = NULL;
}
if (rs->rigport.fd != -1) {
if (!rs->rigport.stream)
fclose(rs->rigport.stream); /* this closes also fd */
else
close(rs->rigport.fd);
rs->rigport.fd = -1;
rs->rigport.stream = NULL;
}
remove_opened_rig(rig);
remove_opened_rig(rig);
rs->comm_state = 0;
rs->comm_state = 0;
return RIG_OK;
return RIG_OK;
}
/**
@ -649,35 +647,40 @@ int rig_cleanup(RIG *rig)
int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
caps = rig->caps;
caps = rig->caps;
if (rig->state.vfo_comp != 0.0)
freq += (freq_t)((double)rig->state.vfo_comp * freq);
if (rig->state.vfo_comp != 0.0)
freq += (freq_t)((double)rig->state.vfo_comp * freq);
if (caps->set_freq == NULL)
return -RIG_ENAVAIL;
if ((caps->targetable_vfo&RIG_TARGETABLE_FREQ) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo)
return caps->set_freq(rig, vfo, freq);
if (caps->set_freq == NULL)
return -RIG_ENAVAIL;
if ((caps->targetable_vfo&RIG_TARGETABLE_FREQ) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) {
retcode = caps->set_freq(rig, vfo, freq);
} else {
if (!caps->set_vfo)
return -RIG_ENTARGET;
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
return retcode;
return retcode;
retcode = caps->set_freq(rig, vfo, freq);
caps->set_vfo(rig, curr_vfo);
return retcode;
}
if (retcode == RIG_OK &&
(vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo))
rig->state.current_freq = freq;
return retcode;
}
/**
@ -699,35 +702,40 @@ int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
int rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
if (CHECK_RIG_ARG(rig) || !freq)
return -RIG_EINVAL;
if (CHECK_RIG_ARG(rig) || !freq)
return -RIG_EINVAL;
caps = rig->caps;
caps = rig->caps;
if (caps->get_freq == NULL)
if (caps->get_freq == NULL)
return -RIG_ENAVAIL;
if ((caps->targetable_vfo&RIG_TARGETABLE_FREQ) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) {
retcode = caps->get_freq(rig, vfo, freq);
} else {
if (!caps->set_vfo)
return -RIG_ENAVAIL;
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
return retcode;
retcode = caps->get_freq(rig, vfo, freq);
caps->set_vfo(rig, curr_vfo);
}
/* VFO compensation */
if (rig->state.vfo_comp != 0.0)
*freq += (freq_t)(rig->state.vfo_comp * (*freq));
if ((caps->targetable_vfo&RIG_TARGETABLE_FREQ) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) {
retcode = caps->get_freq(rig, vfo, freq);
} else {
if (!caps->set_vfo)
return -RIG_ENAVAIL;
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
return retcode;
retcode = caps->get_freq(rig, vfo, freq);
caps->set_vfo(rig, curr_vfo);
}
/* VFO compensation */
if (rig->state.vfo_comp != 0.0)
*freq += (freq_t)(rig->state.vfo_comp * (*freq));
return retcode;
if (retcode == RIG_OK &&
(vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo))
rig->state.current_freq = *freq;
return retcode;
}
@ -750,32 +758,41 @@ int rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
int rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
caps = rig->caps;
caps = rig->caps;
if (caps->set_mode == NULL)
return -RIG_ENAVAIL;
if (caps->set_mode == NULL)
return -RIG_ENAVAIL;
if ((caps->targetable_vfo&RIG_TARGETABLE_ALL) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo)
return caps->set_mode(rig, vfo, mode, width);
if ((caps->targetable_vfo&RIG_TARGETABLE_ALL) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) {
retcode = caps->set_mode(rig, vfo, mode, width);
} else {
if (!caps->set_vfo)
return -RIG_ENTARGET;
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
return retcode;
return retcode;
retcode = caps->set_mode(rig, vfo, mode, width);
caps->set_vfo(rig, curr_vfo);
return retcode;
}
if (retcode == RIG_OK &&
(vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo)) {
rig->state.current_mode = mode;
rig->state.current_width = width;
}
return retcode;
}
/**
@ -800,32 +817,41 @@ int rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
int rig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width)
{
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
const struct rig_caps *caps;
int retcode;
vfo_t curr_vfo;
if (CHECK_RIG_ARG(rig) || !mode || !width)
return -RIG_EINVAL;
if (CHECK_RIG_ARG(rig) || !mode || !width)
return -RIG_EINVAL;
caps = rig->caps;
caps = rig->caps;
if (caps->get_mode == NULL)
return -RIG_ENAVAIL;
if (caps->get_mode == NULL)
return -RIG_ENAVAIL;
if ((caps->targetable_vfo&RIG_TARGETABLE_ALL) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo)
return caps->get_mode(rig, vfo, mode, width);
if ((caps->targetable_vfo&RIG_TARGETABLE_ALL) ||
vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) {
retcode = caps->get_mode(rig, vfo, mode, width);
} else {
if (!caps->set_vfo)
return -RIG_ENTARGET;
curr_vfo = rig->state.current_vfo;
retcode = caps->set_vfo(rig, vfo);
if (retcode != RIG_OK)
return retcode;
return retcode;
retcode = caps->get_mode(rig, vfo, mode, width);
caps->set_vfo(rig, curr_vfo);
return retcode;
}
if (retcode == RIG_OK &&
(vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo)) {
rig->state.current_mode = *mode;
rig->state.current_width = *width;
}
return retcode;
}
/**
@ -2581,211 +2607,6 @@ rig_get_range(const freq_range_t range_list[], freq_t freq, rmode_t mode)
return NULL;
}
/**
* \brief set the callback for freq events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for freq events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_freq_callback(RIG *rig, freq_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.freq_event = cb;
rig->callbacks.freq_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for mode events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for mode events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_mode_callback(RIG *rig, mode_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.mode_event = cb;
rig->callbacks.mode_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for vfo events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for vfo events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_vfo_callback(RIG *rig, vfo_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.vfo_event = cb;
rig->callbacks.vfo_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for ptt events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for ptt events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_ptt_callback(RIG *rig, ptt_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.ptt_event = cb;
rig->callbacks.ptt_arg = arg;
return RIG_OK;
}
/**
* \brief set the callback for dcd events
* \param rig The rig handle
* \param cb The callback to install
* \param arg A Pointer to some private data to pass later on to the callback
*
* Install a callback for dcd events, to be called when in transceive mode.
*
* \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 rig_set_trn()
*/
int rig_set_dcd_callback(RIG *rig, dcd_cb_t cb, rig_ptr_t arg)
{
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
rig->callbacks.dcd_event = cb;
rig->callbacks.dcd_arg = arg;
return RIG_OK;
}
/**
* \brief control the transceive mode
* \param rig The rig handle
* \param trn The transceive status to set to
*
* Enable/disable the transceive handling of a rig and kick off async mode.
*
* \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 rig_get_trn()
*/
int rig_set_trn(RIG *rig, int trn)
{
const struct rig_caps *caps;
int status;
if (CHECK_RIG_ARG(rig))
return -RIG_EINVAL;
caps = rig->caps;
if (rig->state.transceive == RIG_TRN_OFF)
return -RIG_ENAVAIL;
if (trn == RIG_TRN_RIG) {
if (rig->state.transceive) {
/*
* TODO: check error codes et al.
*/
status = add_trn_rig(rig);
if (status == RIG_OK && caps->set_trn)
return caps->set_trn(rig, RIG_TRN_RIG);
else
return status;
} else {
return -RIG_ECONF;
}
} else {
status = remove_trn_rig(rig);
if (caps->set_trn)
return caps->set_trn(rig, RIG_TRN_OFF);
else
return status;
}
return RIG_OK;
}
/**
* \brief get the current transceive mode
* \param rig The rig handle
* \param trn The location where to store the current transceive mode
*
* Retrieves the current status of the transceive mode, i.e. if radio
* sends new status automatically when some changes happened on the radio.
*
* \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 rig_set_trn()
*/
int rig_get_trn(RIG *rig, int *trn)
{
if (CHECK_RIG_ARG(rig) || !trn)
return -RIG_EINVAL;
if (rig->caps->get_trn == NULL)
return -RIG_ENAVAIL;
return rig->caps->get_trn(rig, trn);
}
/**
* \brief get general information from the radio

Wyświetl plik

@ -2,7 +2,7 @@
* Hamlib Interface - token header
* Copyright (c) 2000-2003 by Stephane Fillod
*
* $Id: token.h,v 1.2 2003-02-23 22:38:54 fillods Exp $
* $Id: token.h,v 1.3 2003-05-03 13:17:25 fillods Exp $
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
@ -56,6 +56,7 @@
/* rx_range_list/tx_range_list, filters, announces, has(func,lvl,..) */
#define TOK_VFO_COMP TOKEN_FRONTEND(110)
#define TOK_POLL_INTERVAL TOKEN_FRONTEND(111)
#define TOK_ITU_REGION TOKEN_FRONTEND(120)
/*

Wyświetl plik

@ -245,7 +245,7 @@ Set memory channel data. Not implemented yet.
Get memory channel data.
.TP
.B A, set_trn
Set transceive mode (reporting event).
Set transceive mode (reporting event): OFF, RIG, POLL.
.TP
.B a, get_trn
Get transceive mode (reporting event).

Wyświetl plik

@ -5,7 +5,7 @@
* It takes commands in interactive mode as well as
* from command line options.
*
* $Id: rigctl.c,v 1.42 2003-04-06 18:40:35 fillods Exp $
* $Id: rigctl.c,v 1.43 2003-05-03 13:17:25 fillods Exp $
*
*
* This program is free software; you can redistribute it and/or
@ -33,6 +33,7 @@
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
@ -257,6 +258,21 @@ char parse_arg(const char *arg)
return 0;
}
static int scanfc(const char *format, void *p)
{
int ret;
do {
ret = scanf(format, p);
if (ret < 0) {
if (errno != EINTR)
rig_debug(RIG_DEBUG_ERR, "scanf: %s\n", strerror(errno));
continue;
}
return ret;
} while(1);
}
#define MAXCONFLEN 128
int main (int argc, char *argv[])
@ -493,16 +509,17 @@ int main (int argc, char *argv[])
printf("\nRig command: ");
do {
scanf("%c", &cmd);
scanfc("%c", &cmd);
/* command by name */
if (cmd == '\\') {
unsigned char cmd_name[MAXNAMSIZ], *pcmd = cmd_name;
int c_len = MAXNAMSIZ;
scanf("%c", pcmd);
scanfc("%c", pcmd);
while(c_len-- && (isalnum(*pcmd) || *pcmd == '_' ))
scanf("%c", ++pcmd);
scanfc("%c", ++pcmd);
*pcmd = '\0';
cmd = parse_arg(cmd_name);
break;
@ -523,7 +540,7 @@ int main (int argc, char *argv[])
/* comment line */
if (cmd == '#' || cmd == ';') {
while( cmd != '\n' && cmd != '\r')
scanf("%c", &cmd);
scanfc("%c", &cmd);
continue;
}
if (cmd == 'Q' || cmd == 'q')
@ -553,7 +570,7 @@ int main (int argc, char *argv[])
if (!(cmd_entry->flags & ARG_NOVFO) && vfo_mode) {
if (interactive) {
printf("VFO: ");
scanf("%s", arg1);
scanfc("%s", arg1);
vfo = parse_vfo(arg1);
} else {
if (!argv[optind]) {
@ -567,7 +584,7 @@ int main (int argc, char *argv[])
if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) {
if (interactive) {
printf("%s: ", cmd_entry->arg1);
scanf("%s", arg1);
scanfc("%s", arg1);
p1 = arg1;
} else {
if (!argv[optind]) {
@ -581,7 +598,7 @@ int main (int argc, char *argv[])
if ((cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) {
if (interactive) {
printf("%s: ", cmd_entry->arg2);
scanf("%s", arg2);
scanfc("%s", arg2);
p2 = arg2;
} else {
if (!argv[optind]) {
@ -595,7 +612,7 @@ int main (int argc, char *argv[])
if ((cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) {
if (interactive) {
printf("%s: ", cmd_entry->arg3);
scanf("%s", arg3);
scanfc("%s", arg3);
p3 = arg3;
} else {
if (!argv[optind]) {
@ -1446,7 +1463,14 @@ declare_proto_rig(set_trn)
{
int trn;
sscanf(arg1, "%d", &trn);
if (!strcmp(arg1, "OFF"))
trn = RIG_TRN_OFF;
else if (!strcmp(arg1, "RIG") || !strcmp(arg1, "ON"))
trn = RIG_TRN_RIG;
else if (!strcmp(arg1, "POLL"))
trn = RIG_TRN_POLL;
else
return -RIG_EINVAL;
if (trn != RIG_TRN_OFF) {
rig_set_freq_callback(rig, myfreq_event, NULL);
@ -1462,16 +1486,16 @@ declare_proto_rig(set_trn)
declare_proto_rig(get_trn)
{
int status;
int trn;
int status;
int trn;
status = rig_get_trn(rig, &trn);
if (status != RIG_OK)
return status;
if (interactive)
printf("%s: ", cmd->arg1);
printf("%d\n", trn);
status = rig_get_trn(rig, &trn);
if (status != RIG_OK)
return status;
if (interactive)
printf("%s: ", cmd->arg1);
printf("%d\n", trn);
return status;
}
declare_proto_rig(get_info)