2001-12-27 21:46:25 +00:00
|
|
|
/*
|
|
|
|
* Hamlib Interface - main file
|
2006-02-26 19:30:49 +00:00
|
|
|
* Copyright (c) 2000-2006 by Stephane Fillod and Frank Singleton
|
2001-12-27 21:46:25 +00:00
|
|
|
*
|
2006-10-07 13:08:19 +00:00
|
|
|
* $Id: rotator.c,v 1.20 2006-10-07 13:08:19 csete Exp $
|
2001-12-27 21:46:25 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Library 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 Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2002-11-28 22:33:48 +00:00
|
|
|
/**
|
|
|
|
* \file src/rotator.c
|
|
|
|
* \ingroup rot
|
|
|
|
* \brief Rotator interface
|
|
|
|
* \author Stephane Fillod
|
2006-02-26 19:30:49 +00:00
|
|
|
* \date 2000-2006
|
2002-11-28 22:33:48 +00:00
|
|
|
*
|
|
|
|
* Hamlib interface is a frontend implementing rotator wrapper functions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2002-09-24 21:42:56 +00:00
|
|
|
/*! \page rot Rotator interface
|
|
|
|
*
|
|
|
|
* Rotator can be any kind of azimuth or azimuth and elevation controlled
|
|
|
|
* antenna system.
|
|
|
|
*/
|
|
|
|
|
2001-12-27 21:46:25 +00:00
|
|
|
#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>
|
|
|
|
|
|
|
|
|
2004-10-02 20:37:24 +00:00
|
|
|
#include "hamlib/rotator.h"
|
|
|
|
#include "serial.h"
|
|
|
|
#include "parallel.h"
|
2001-12-27 21:46:25 +00:00
|
|
|
#include "rot_conf.h"
|
2002-01-27 14:55:30 +00:00
|
|
|
#include "token.h"
|
2001-12-27 21:46:25 +00:00
|
|
|
|
|
|
|
|
2002-09-24 21:42:56 +00:00
|
|
|
#ifndef DOC_HIDDEN
|
|
|
|
|
2003-08-25 22:33:38 +00:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
#define DEFAULT_SERIAL_PORT "\\\\.\\COM1"
|
|
|
|
#else
|
|
|
|
#define DEFAULT_SERIAL_PORT "/dev/ttyS0"
|
|
|
|
#endif
|
|
|
|
#if defined(WIN32)
|
|
|
|
#define DEFAULT_PARALLEL_PORT "\\\\.\\$VDMLPT1"
|
2005-02-20 02:38:29 +00:00
|
|
|
#elif defined(HAVE_DEV_PPBUS_PPI_H)
|
|
|
|
#define DEFAULT_PARALLEL_PORT "/dev/ppi0"
|
2003-08-25 22:33:38 +00:00
|
|
|
#else
|
2002-11-28 22:33:48 +00:00
|
|
|
#define DEFAULT_PARALLEL_PORT "/dev/parport0"
|
2003-08-25 22:33:38 +00:00
|
|
|
#endif
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2002-01-21 08:30:31 +00:00
|
|
|
#define CHECK_ROT_ARG(r) (!(r) || !(r)->caps || !(r)->state.comm_state)
|
|
|
|
|
2001-12-27 21:46:25 +00:00
|
|
|
/*
|
|
|
|
* Data structure to track the opened rot (by rot_open)
|
|
|
|
*/
|
|
|
|
struct opened_rot_l {
|
|
|
|
ROT *rot;
|
|
|
|
struct opened_rot_l *next;
|
|
|
|
};
|
|
|
|
static struct opened_rot_l *opened_rot_list = { NULL };
|
|
|
|
|
|
|
|
/*
|
|
|
|
* track which rot is opened (with rot_open)
|
|
|
|
* needed at least for transceive mode
|
|
|
|
*/
|
|
|
|
static int add_opened_rot(ROT *rot)
|
|
|
|
{
|
|
|
|
struct opened_rot_l *p;
|
|
|
|
p = (struct opened_rot_l *)malloc(sizeof(struct opened_rot_l));
|
|
|
|
if (!p)
|
|
|
|
return -RIG_ENOMEM;
|
|
|
|
p->rot = rot;
|
|
|
|
p->next = opened_rot_list;
|
|
|
|
opened_rot_list = p;
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int remove_opened_rot(ROT *rot)
|
|
|
|
{
|
|
|
|
struct opened_rot_l *p,*q;
|
|
|
|
q = NULL;
|
|
|
|
|
|
|
|
for (p=opened_rot_list; p; p=p->next) {
|
2005-04-04 18:31:00 +00:00
|
|
|
if (p->rot == rot) {
|
|
|
|
if (q == NULL) {
|
|
|
|
opened_rot_list = opened_rot_list->next;
|
|
|
|
} else {
|
|
|
|
q->next = p->next;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
2005-04-04 18:31:00 +00:00
|
|
|
free(p);
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
q = p;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
return -RIG_EINVAL; /* Not found in list ! */
|
|
|
|
}
|
2002-09-24 21:42:56 +00:00
|
|
|
#endif /* !DOC_HIDDEN */
|
2001-12-27 21:46:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief execs cfunc() on each opened rot
|
|
|
|
* \param cfunc The function to be executed on each rot
|
|
|
|
* \param data Data pointer to be passed to cfunc()
|
|
|
|
*
|
|
|
|
* Calls cfunc() function for each opened rot.
|
|
|
|
* The contents of the opened rot 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 #ROT 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 rot table is stopped
|
|
|
|
* when cfunc() returns 0.
|
|
|
|
* \internal
|
|
|
|
*
|
|
|
|
* \return always RIG_OK.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int foreach_opened_rot(int (*cfunc)(ROT *, rig_ptr_t), rig_ptr_t data)
|
|
|
|
{
|
|
|
|
struct opened_rot_l *p;
|
|
|
|
|
|
|
|
for (p=opened_rot_list; p; p=p->next) {
|
2005-04-04 18:31:00 +00:00
|
|
|
if ((*cfunc)(p->rot,data) == 0)
|
|
|
|
return RIG_OK;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
return RIG_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief allocate a new #ROT handle
|
|
|
|
* \param rot_model The rot model for this new handle
|
|
|
|
*
|
|
|
|
* Allocates a new #ROT handle and initializes the associated data
|
|
|
|
* for \a rot_model.
|
|
|
|
*
|
|
|
|
* \return a pointer to the #ROT handle otherwise NULL if memory allocation
|
|
|
|
* failed or \a rot_model is unknown (e.g. backend autoload failed).
|
|
|
|
*
|
|
|
|
* \sa rot_cleanup(), rot_open()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
ROT * HAMLIB_API rot_init(rot_model_t rot_model)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
ROT *rot;
|
|
|
|
const struct rot_caps *caps;
|
|
|
|
struct rot_state *rs;
|
|
|
|
int retcode;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rot_debug(RIG_DEBUG_VERBOSE,"rot:rot_init called \n");
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rot_check_backend(rot_model);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot_get_caps(rot_model);
|
|
|
|
if (!caps)
|
|
|
|
return NULL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
/*
|
|
|
|
* okay, we've found it. Allocate some memory and set it to zeros,
|
|
|
|
* and especially the initialize the callbacks
|
|
|
|
*/
|
|
|
|
rot = calloc(1, sizeof(ROT));
|
|
|
|
if (rot == NULL) {
|
2001-12-27 21:46:25 +00:00
|
|
|
/*
|
2005-04-04 18:31:00 +00:00
|
|
|
* FIXME: how can the caller know it's a memory shortage,
|
|
|
|
* and not "rot not found" ?
|
2001-12-27 21:46:25 +00:00
|
|
|
*/
|
2005-04-04 18:31:00 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2006-10-07 13:08:19 +00:00
|
|
|
/* caps is const, so we need to tell compiler
|
|
|
|
that we now what we are doing */
|
|
|
|
rot->caps = (struct rot_caps *) caps;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
/*
|
|
|
|
* populate the rot->state
|
|
|
|
* TODO: read the Preferences here!
|
|
|
|
*/
|
2002-11-28 22:33:48 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs = &rot->state;
|
2002-11-28 22:33:48 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->comm_state = 0;
|
|
|
|
rs->rotport.type.rig = caps->port_type; /* default from caps */
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->rotport.write_delay = caps->write_delay;
|
|
|
|
rs->rotport.post_write_delay = caps->post_write_delay;
|
|
|
|
rs->rotport.timeout = caps->timeout;
|
|
|
|
rs->rotport.retry = caps->retry;
|
2002-11-28 22:33:48 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
switch (caps->port_type) {
|
|
|
|
case RIG_PORT_SERIAL:
|
|
|
|
strncpy(rs->rotport.pathname, DEFAULT_SERIAL_PORT, FILPATHLEN);
|
|
|
|
rs->rotport.parm.serial.rate = caps->serial_rate_max; /* fastest ! */
|
|
|
|
rs->rotport.parm.serial.data_bits = caps->serial_data_bits;
|
|
|
|
rs->rotport.parm.serial.stop_bits = caps->serial_stop_bits;
|
|
|
|
rs->rotport.parm.serial.parity = caps->serial_parity;
|
|
|
|
rs->rotport.parm.serial.handshake = caps->serial_handshake;
|
|
|
|
break;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
case RIG_PORT_PARALLEL:
|
|
|
|
strncpy(rs->rotport.pathname, DEFAULT_PARALLEL_PORT, FILPATHLEN);
|
|
|
|
break;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
default:
|
|
|
|
strncpy(rs->rotport.pathname, "", FILPATHLEN);
|
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->min_el = caps->min_el;
|
|
|
|
rs->max_el = caps->max_el;
|
|
|
|
rs->min_az = caps->min_az;
|
|
|
|
rs->max_az = caps->max_az;
|
|
|
|
|
|
|
|
rs->rotport.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 rot_state.
|
|
|
|
*/
|
|
|
|
if (caps->rot_init != NULL) {
|
|
|
|
retcode = caps->rot_init(rot);
|
|
|
|
if (retcode != RIG_OK) {
|
|
|
|
rot_debug(RIG_DEBUG_VERBOSE,"rot:backend_init failed!\n");
|
|
|
|
/* cleanup and exit */
|
|
|
|
free(rot);
|
|
|
|
return NULL;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
2005-04-04 18:31:00 +00:00
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return rot;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief open the communication to the rot
|
2002-01-07 17:28:36 +00:00
|
|
|
* \param rot The #ROT handle of the rotator to be opened
|
2001-12-27 21:46:25 +00:00
|
|
|
*
|
2002-01-07 17:28:36 +00:00
|
|
|
* Opens communication to a rotator which \a ROT handle has been passed
|
2001-12-27 21:46:25 +00:00
|
|
|
* 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 rot is NULL or unconsistent.
|
|
|
|
* \retval RIG_ENIMPL port type communication is not implemented yet.
|
|
|
|
*
|
|
|
|
* \sa rot_init(), rot_close()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_open(ROT *rot)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
|
|
|
struct rot_state *rs;
|
|
|
|
int status;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rot_debug(RIG_DEBUG_VERBOSE,"rot:rot_open called \n");
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rot || !rot->caps)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
|
|
|
rs = &rot->state;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (rs->comm_state)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->rotport.fd = -1;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
switch(rs->rotport.type.rig) {
|
|
|
|
case RIG_PORT_SERIAL:
|
|
|
|
status = serial_open(&rs->rotport);
|
|
|
|
if (status != 0)
|
|
|
|
return status;
|
|
|
|
break;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
case RIG_PORT_PARALLEL:
|
|
|
|
status = par_open(&rs->rotport);
|
|
|
|
if (status < 0)
|
|
|
|
return status;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_PORT_DEVICE:
|
|
|
|
status = open(rs->rotport.pathname, O_RDWR, 0);
|
|
|
|
if (status < 0)
|
|
|
|
return -RIG_EIO;
|
|
|
|
rs->rotport.fd = status;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RIG_PORT_NONE:
|
|
|
|
case RIG_PORT_RPC:
|
|
|
|
break; /* ez :) */
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
case RIG_PORT_NETWORK: /* not implemented yet! */
|
|
|
|
return -RIG_ENIMPL;
|
|
|
|
default:
|
|
|
|
return -RIG_EINVAL;
|
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
add_opened_rot(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->comm_state = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Maybe the backend has something to initialize
|
|
|
|
* In case of failure, just close down and report error code.
|
|
|
|
*/
|
|
|
|
if (caps->rot_open != NULL) {
|
|
|
|
status = caps->rot_open(rot);
|
|
|
|
if (status != RIG_OK) {
|
|
|
|
return status;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
2005-04-04 18:31:00 +00:00
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return RIG_OK;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief close the communication to the rot
|
2002-01-07 17:28:36 +00:00
|
|
|
* \param rot The #ROT handle of the rotator to be closed
|
2001-12-27 21:46:25 +00:00
|
|
|
*
|
|
|
|
* Closes communication to a radio which \a ROT handle has been passed
|
|
|
|
* by argument that was previously open with rot_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 rot_cleanup(), rot_open()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_close(ROT *rot)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
|
|
|
struct rot_state *rs;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rot_debug(RIG_DEBUG_VERBOSE,"rot:rot_close called \n");
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rot || !rot->caps)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
|
|
|
rs = &rot->state;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rs->comm_state)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
/*
|
|
|
|
* Let the backend say 73s to the rot.
|
|
|
|
* and ignore the return code.
|
|
|
|
*/
|
|
|
|
if (caps->rot_close)
|
|
|
|
caps->rot_close(rot);
|
|
|
|
|
|
|
|
|
|
|
|
if (rs->rotport.fd != -1) {
|
|
|
|
switch(rs->rotport.type.rig) {
|
|
|
|
case RIG_PORT_SERIAL:
|
|
|
|
ser_close(&rs->rotport);
|
|
|
|
break;
|
|
|
|
case RIG_PORT_PARALLEL:
|
|
|
|
par_close(&rs->rotport);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
close(rs->rotport.fd);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->rotport.fd = -1;
|
|
|
|
}
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
remove_opened_rot(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
rs->comm_state = 0;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return RIG_OK;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief release a rot handle and free associated memory
|
|
|
|
* \param rot The #ROT handle of the radio to be closed
|
|
|
|
*
|
|
|
|
* Releases a rot struct which port has eventualy been closed already
|
|
|
|
* with rot_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 rot_init(), rot_close()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_cleanup(ROT *rot)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
rot_debug(RIG_DEBUG_VERBOSE,"rot:rot_cleanup called \n");
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rot || !rot->caps)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
/*
|
|
|
|
* check if they forgot to close the rot
|
|
|
|
*/
|
|
|
|
if (rot->state.comm_state)
|
|
|
|
rot_close(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
/*
|
|
|
|
* basically free up the priv struct
|
|
|
|
*/
|
|
|
|
if (rot->caps->rot_cleanup)
|
|
|
|
rot->caps->rot_cleanup(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
free(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return RIG_OK;
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief set a rotator configuration parameter
|
|
|
|
* \param rot The rot 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 rot_get_conf()
|
|
|
|
*/
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_set_conf(ROT *rot, token_t token, const char *val)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rot || !rot->caps)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (IS_TOKEN_FRONTEND(token))
|
|
|
|
return frontrot_set_conf(rot, token, val);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (rot->caps->set_conf == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return rot->caps->set_conf(rot, token, val);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief get the value of a configuration parameter
|
|
|
|
* \param rot The rot 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 rot_set_conf()
|
|
|
|
*/
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_get_conf(ROT *rot, token_t token, char *val)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
if (!rot || !rot->caps || !val)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (IS_TOKEN_FRONTEND(token))
|
|
|
|
return frontrot_get_conf(rot, token, val);
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (rot->caps->get_conf == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return rot->caps->get_conf(rot, token, val);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief set the azimuth and elevation of the rotator
|
|
|
|
* \param rot The rot handle
|
|
|
|
* \param azimuth The azimuth to set to
|
|
|
|
* \param elevation The elevation to set to
|
|
|
|
*
|
|
|
|
* Sets the azimuth and elevation of the rotator.
|
|
|
|
*
|
2002-01-16 17:08:31 +00:00
|
|
|
* \return RIG_OK if the operation has been sucessful, otherwise
|
|
|
|
* a negative value if an error occured (in which case, cause is
|
2001-12-27 21:46:25 +00:00
|
|
|
* set appropriately).
|
|
|
|
*
|
|
|
|
* \sa rot_get_position()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_set_position (ROT *rot, azimuth_t azimuth, elevation_t elevation)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
|
|
|
const struct rot_state *rs;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
|
|
|
rs = &rot->state;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (azimuth < rs->min_az || azimuth > rs->max_az ||
|
|
|
|
elevation < rs->min_el || elevation > rs->max_el)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (caps->set_position == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return caps->set_position(rot, azimuth, elevation);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief get the azimuth and elevation of the rotator
|
|
|
|
* \param rot The rot handle
|
|
|
|
* \param azimuth The location where to store the current azimuth
|
|
|
|
* \param elevation The location where to store the current elevation
|
|
|
|
*
|
|
|
|
* Retrieves the current azimuth and elevation of the rotator.
|
|
|
|
*
|
|
|
|
* \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 rot_set_position()
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_get_position (ROT *rot, azimuth_t *azimuth, elevation_t *elevation)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot) || !azimuth || !elevation)
|
|
|
|
return -RIG_EINVAL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (caps->get_position == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return caps->get_position(rot, azimuth, elevation);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|
2001-12-28 20:34:43 +00:00
|
|
|
/**
|
|
|
|
* \brief park the antenna
|
|
|
|
* \param rot The rot handle
|
|
|
|
*
|
|
|
|
* Park the antenna.
|
|
|
|
*
|
|
|
|
* \return RIG_OK if the operation has been sucessful, otherwise
|
|
|
|
* a negative value if an error occured (in which case, cause is
|
|
|
|
* set appropriately).
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_park (ROT *rot)
|
2001-12-28 20:34:43 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
|
|
|
return -RIG_EINVAL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (caps->park == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return caps->park(rot);
|
2001-12-28 20:34:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief stop the rotator
|
|
|
|
* \param rot The rot handle
|
|
|
|
*
|
|
|
|
* Stop the rotator.
|
|
|
|
*
|
|
|
|
* \return RIG_OK if the operation has been sucessful, otherwise
|
|
|
|
* a negative value if an error occured (in which case, cause is
|
|
|
|
* set appropriately).
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_stop (ROT *rot)
|
2001-12-28 20:34:43 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
|
|
|
return -RIG_EINVAL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (caps->stop == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return caps->stop(rot);
|
2001-12-28 20:34:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief reset the rotator
|
|
|
|
* \param rot The rot handle
|
|
|
|
* \param reset The reset operation to perform
|
|
|
|
*
|
|
|
|
* Resets the rotator.
|
|
|
|
*
|
|
|
|
* \return RIG_OK if the operation has been sucessful, otherwise
|
|
|
|
* a negative value if an error occured (in which case, cause is
|
|
|
|
* set appropriately).
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_reset (ROT *rot, rot_reset_t reset)
|
2001-12-28 20:34:43 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
const struct rot_caps *caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
|
|
|
return -RIG_EINVAL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
caps = rot->caps;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (caps->reset == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return caps->reset(rot, reset);
|
2001-12-28 20:34:43 +00:00
|
|
|
}
|
|
|
|
|
2002-01-16 17:08:31 +00:00
|
|
|
/**
|
2003-04-23 21:06:05 +00:00
|
|
|
* \brief move the rotator in the specified direction
|
2002-01-16 17:08:31 +00:00
|
|
|
* \param rot The rot handle
|
|
|
|
* \param direction Direction of movement
|
|
|
|
* \param speed Speed of movement
|
|
|
|
*
|
2003-04-23 21:06:05 +00:00
|
|
|
* Move the rotator in the specified direction. The speed is a value
|
2002-01-16 17:08:31 +00:00
|
|
|
* between 1 and 100.
|
|
|
|
*/
|
2004-10-02 10:32:09 +00:00
|
|
|
int HAMLIB_API rot_move (ROT *rot, int direction, int speed)
|
2002-01-16 17:08:31 +00:00
|
|
|
{
|
|
|
|
const struct rot_caps *caps;
|
|
|
|
|
2002-01-21 08:30:31 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
2002-01-16 17:08:31 +00:00
|
|
|
return -RIG_EINVAL;
|
|
|
|
|
|
|
|
caps = rot->caps;
|
|
|
|
|
|
|
|
if (caps->move == NULL)
|
|
|
|
return -RIG_ENAVAIL;
|
|
|
|
|
|
|
|
return caps->move(rot, direction, speed);
|
|
|
|
}
|
2001-12-28 20:34:43 +00:00
|
|
|
|
2001-12-27 21:46:25 +00:00
|
|
|
/**
|
|
|
|
* \brief get general information from the rotator
|
|
|
|
* \param rot The rot handle
|
|
|
|
*
|
|
|
|
* Retrieves some general information from the rotator.
|
|
|
|
* 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.
|
|
|
|
*/
|
2004-10-02 10:32:09 +00:00
|
|
|
const char* HAMLIB_API rot_get_info(ROT *rot)
|
2001-12-27 21:46:25 +00:00
|
|
|
{
|
2005-04-04 18:31:00 +00:00
|
|
|
if (CHECK_ROT_ARG(rot))
|
|
|
|
return NULL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
if (rot->caps->get_info == NULL)
|
|
|
|
return NULL;
|
2001-12-27 21:46:25 +00:00
|
|
|
|
2005-04-04 18:31:00 +00:00
|
|
|
return rot->caps->get_info(rot);
|
2001-12-27 21:46:25 +00:00
|
|
|
}
|
|
|
|
|