UDP interface support besides IPC

git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2743 7ae35d74-ebe9-4afe-98af-79ac388436b8
Hamlib-1.2.10
Stéphane Fillod, F8CFE 2009-10-30 23:43:50 +00:00
rodzic 8a9a351e9d
commit 033d4f6519
1 zmienionych plików z 157 dodań i 85 usunięć

Wyświetl plik

@ -1,6 +1,9 @@
/*
* Hamlib DttSP backend - main file
* Copyright (c) 2001-2008 by Stephane Fillod
* Copyright (c) 2001-2009 by Stephane Fillod
*
* Some code derived from DttSP
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by Frank Brickle, AB2KT and Bob McGwier, N4HY
*
* $Id: dttsp.c,v 1.2 2008-05-07 22:18:25 fillods Exp $
*
@ -33,6 +36,7 @@
#include <math.h>
#include "hamlib/rig.h"
#include "iofunc.h"
#include "misc.h"
#include "token.h"
#include "register.h"
@ -40,8 +44,11 @@
#include "flexradio.h"
/*
* TODO:
* This backend is a two layer rig control: DttSP core over a mundane tuner
*
* 2 interfaces of DttSP are supported: IPC & UDP
*
* TODO: Transmit setup
*/
#define DEFAULT_DTTSP_CMD_PATH "/dev/shm/SDRcommands"
@ -51,6 +58,13 @@
#define MAXRX 4
#define RXMETERPTS 5
#define TXMETERPTS 9
#define MAXMETERPTS 9
#define DTTSP_PORT_CLIENT_COMMAND 19001
#define DTTSP_PORT_CLIENT_SPECTRUM 19002
#define DTTSP_PORT_CLIENT_METER 19003
#define DTTSP_PORT_CLIENT_BUFSIZE 65536
struct dttsp_priv_data {
/* tuner providing IF */
@ -58,17 +72,39 @@ struct dttsp_priv_data {
RIG *tuner;
shortfreq_t IF_center_freq;
/* DttSP meter handle */
int meter_fd;
int sample_rate;
int rx_delta_f;
hamlib_port_t meter_port;
#if 0
union {
/* IPC specific */
struct {
/* DttSP meter handle */
int meter_fd;
};
/* UDP specific RIG_PORT_NETWORK_UDP */
struct {
unsigned short port;
struct sockaddr_in clnt;
int clen, flags, sock;
char buff[DTTSP_PORT_CLIENT_BUFSIZE];
int size, used;
};
#endif
};
static int dttsp_init(RIG *rig);
static int dttsp_cleanup(RIG *rig);
static int dttsp_open(RIG *rig);
static int dttsp_close(RIG *rig);
static int dttsp_ipc_init(RIG *rig);
static int dttsp_ipc_cleanup(RIG *rig);
static int dttsp_ipc_open(RIG *rig);
static int dttsp_ipc_close(RIG *rig);
static int dttsp_udp_init(RIG *rig);
static int dttsp_udp_cleanup(RIG *rig);
static int dttsp_udp_open(RIG *rig);
static int dttsp_udp_close(RIG *rig);
static int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
static int dttsp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
static int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width);
@ -140,7 +176,7 @@ static const struct hamlib_vs_dttsp {
const struct rig_caps dttsp_rig_caps = {
.rig_model = RIG_MODEL_DTTSP,
.model_name = "DttSP",
.model_name = "DttSP IPC",
.mfg_name = "DTTS Microwave Society",
.version = "0.1",
.copyright = "GPL",
@ -166,14 +202,15 @@ const struct rig_caps dttsp_rig_caps = {
.transceive = RIG_TRN_OFF,
.attenuator = { RIG_DBLST_END, },
.preamp = { RIG_DBLST_END, },
/* In fact, RX and TX ranges are dependant on the tuner */
.rx_range_list1 = { {.start=kHz(150),.end=MHz(1500),.modes=DTTSP_MODES,
.low_power=-1,.high_power=-1,DTTSP_VFO},
RIG_FRNG_END, },
.tx_range_list1 = { RIG_FRNG_END, },
.tx_range_list1 = { RIG_FRNG_END, }, /* TODO */
.rx_range_list2 = { {.start=kHz(150),.end=MHz(1500),.modes=DTTSP_MODES,
.low_power=-1,.high_power=-1,DTTSP_VFO},
RIG_FRNG_END, },
.tx_range_list2 = { RIG_FRNG_END, },
.tx_range_list2 = { RIG_FRNG_END, }, /* TODO */
.tuning_steps = { {DTTSP_MODES,1}, {DTTSP_MODES,RIG_TS_ANY}, RIG_TS_END, },
.filters = {
{RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR, kHz(2.4)},
@ -187,10 +224,10 @@ const struct rig_caps dttsp_rig_caps = {
.priv = NULL,
.rig_init = dttsp_init,
.rig_cleanup = dttsp_cleanup,
.rig_open = dttsp_open,
.rig_close = dttsp_close,
.rig_init = dttsp_ipc_init,
.rig_cleanup = dttsp_ipc_cleanup,
.rig_open = dttsp_ipc_open,
.rig_close = dttsp_ipc_close,
.cfgparams = dttsp_cfg_params,
.set_conf = dttsp_set_conf,
@ -213,38 +250,61 @@ const struct rig_caps dttsp_rig_caps = {
};
int dttsp_init(RIG *rig)
static int send_command(RIG *rig, const char *cmdstr, size_t buflen)
{
struct dttsp_priv_data *priv;
const char *cmdpath;
char *p;
int ret;
priv = (struct dttsp_priv_data*)malloc(sizeof(struct dttsp_priv_data));
if (!priv)
return -RIG_ENOMEM;
rig->state.priv = (void*)priv;
if (rig->state.rigport.type.rig == RIG_PORT_NETWORK) {
} else {
/* IPC */
ret = write_block (&rig->state.rigport, cmdstr, buflen);
}
rig_debug(RIG_DEBUG_VERBOSE,"%s called\n", __FUNCTION__ );
return ret;
}
priv->tuner = NULL;
priv->tuner_model = RIG_MODEL_DUMMY;
priv->IF_center_freq = 0;
static int fetch_meter (RIG *rig, int *label, float *data, int npts)
{
struct dttsp_priv_data *priv = (struct dttsp_priv_data*)rig->state.priv;
int ret, buf_len;
char buf[sizeof(float)*MAXMETERPTS*MAXRX];
if (priv->meter_port.type.rig == RIG_PORT_NETWORK) {
#if 0
if (!select(cp->sock + 1, &fds, 0, 0, &tv))
return -1;
if (recvfrom(cp->sock, cp->buff, cp->size, cp->flags,
(struct sockaddr *) &cp->clnt, &cp->clen) <= 0)
return -2;
#endif
buf_len = sizeof(int) + npts * sizeof(float);
p = getenv ( "SDR_DEFRATE" );
if (p)
priv->sample_rate = atoi(p);
else
priv->sample_rate = DEFAULT_SAMPLE_RATE;
ret = read_block(&priv->meter_port, buf, buf_len);
if (ret != buf_len)
ret = -RIG_EIO;
cmdpath = getenv ( "SDR_PARMPATH" );
if (!cmdpath)
cmdpath = DEFAULT_DTTSP_CMD_PATH;
/* copy payload back to client space */
memcpy((char *) label, buf, sizeof(int));
memcpy((char *) data, buf + sizeof(int), npts * sizeof(float));
strncpy(rig->state.rigport.pathname, cmdpath, FILPATHLEN);
} else {
/* IPC */
buf_len = sizeof(int);
ret = read_block(&priv->meter_port, (char*)label, buf_len);
if (ret != buf_len)
ret = -RIG_EIO;
if (ret < 0)
return ret;
return RIG_OK;
buf_len = sizeof(float) * npts;
ret = read_block(&priv->meter_port, (char*)data, buf_len);
if (ret != buf_len)
ret = -RIG_EIO;
if (ret < 0)
return ret;
}
return ret;
}
@ -300,12 +360,46 @@ int dttsp_get_conf(RIG *rig, token_t token, char *val)
return RIG_OK;
}
int dttsp_open(RIG *rig)
int dttsp_ipc_init(RIG *rig)
{
struct dttsp_priv_data *priv;
const char *cmdpath;
char *p;
priv = (struct dttsp_priv_data*)malloc(sizeof(struct dttsp_priv_data));
if (!priv)
return -RIG_ENOMEM;
rig->state.priv = (void*)priv;
rig_debug(RIG_DEBUG_VERBOSE,"%s called\n", __FUNCTION__ );
priv->tuner = NULL;
priv->tuner_model = RIG_MODEL_DUMMY;
priv->IF_center_freq = 0;
p = getenv ( "SDR_DEFRATE" );
if (p)
priv->sample_rate = atoi(p);
else
priv->sample_rate = DEFAULT_SAMPLE_RATE;
cmdpath = getenv ( "SDR_PARMPATH" );
if (!cmdpath)
cmdpath = DEFAULT_DTTSP_CMD_PATH;
strncpy(rig->state.rigport.pathname, cmdpath, FILPATHLEN);
return RIG_OK;
}
int dttsp_ipc_open(RIG *rig)
{
struct dttsp_priv_data *priv = (struct dttsp_priv_data*)rig->state.priv;
int ret;
char *p;
char meterpath[FILPATHLEN];
char *meterpath;
rig_debug(RIG_DEBUG_TRACE,"%s called\n", __FUNCTION__);
@ -333,6 +427,7 @@ int dttsp_open(RIG *rig)
/* open DttSP meter pipe */
p = getenv ( "SDR_METERPATH" );
if (!p) {
meterpath = priv->meter_port.pathname;
strncpy(meterpath, rig->state.rigport.pathname, FILPATHLEN);
p = strrchr(meterpath, '/');
strcpy(p+1, "SDRmeter");
@ -340,9 +435,12 @@ int dttsp_open(RIG *rig)
}
if (!p) {
/* disabled */
priv->meter_fd = -1;
priv->meter_port.fd = -1;
} else {
priv->meter_fd = open(p, O_RDWR);
priv->meter_port.type.rig = RIG_PORT_DEVICE;
ret = port_open(&priv->meter_port);
if (ret < 0)
return ret;
}
@ -370,20 +468,19 @@ int dttsp_open(RIG *rig)
}
int dttsp_close(RIG *rig)
int dttsp_ipc_close(RIG *rig)
{
struct dttsp_priv_data *priv = (struct dttsp_priv_data*)rig->state.priv;
rig_debug(RIG_DEBUG_VERBOSE,"%s called\n", __FUNCTION__);
close(priv->meter_fd);
port_close(&priv->meter_port, priv->meter_port.type.rig);
rig_close(priv->tuner);
/* TODO: close meter */
return RIG_OK;
}
int dttsp_cleanup(RIG *rig)
int dttsp_ipc_cleanup(RIG *rig)
{
struct dttsp_priv_data *priv = (struct dttsp_priv_data*)rig->state.priv;
@ -401,6 +498,7 @@ int dttsp_cleanup(RIG *rig)
return RIG_OK;
}
/*
* rig_set_freq is a good candidate for the GNUradio GUI setFrequency callback?
*/
@ -449,11 +547,7 @@ int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
/* setRxFrequenc */
buf_len = sprintf (buf, "setOsc %d\n", priv->rx_delta_f );
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret == buf_len)
ret = RIG_OK;
else
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
return ret;
}
@ -531,18 +625,10 @@ int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
/* DttSP set mode */
buf_len = sprintf (buf, "setMode %d\n", rmode2dttsp(mode) );
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret == buf_len)
ret = RIG_OK;
else
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
buf_len = sprintf (buf, "setFilter %d %d\n", filter_l, filter_h );
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret == buf_len)
ret = RIG_OK;
else
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
rig_debug(RIG_DEBUG_VERBOSE,"%s: %s\n",
__FUNCTION__, buf);
@ -575,11 +661,7 @@ int dttsp_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val)
switch (level) {
case RIG_LEVEL_AGC:
buf_len = sprintf (buf, "setRXAGC %d\n", agc_level2dttsp(val.i));
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret == buf_len)
ret = RIG_OK;
else
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
break;
default:
rig_debug(RIG_DEBUG_TRACE, "%s: level %s, try tuner\n",
@ -606,21 +688,15 @@ int dttsp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val)
case RIG_LEVEL_RAWSTR:
case RIG_LEVEL_STRENGTH:
buf_len = sprintf (buf, "reqRXMeter %d\n", getpid());
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret != buf_len)
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
if (ret < 0)
return ret;
buf_len = sizeof(int);
ret = read(priv->meter_fd, buf, buf_len);
if (ret != buf_len)
ret = -RIG_EIO;
ret = fetch_meter (rig, (int*)buf, (float*)rxm, MAXRX * RXMETERPTS);
if (ret < 0)
return ret;
buf_len = sizeof(float) * MAXRX * RXMETERPTS;
ret = read(priv->meter_fd, rxm, buf_len);
if (ret != buf_len)
ret = -RIG_EIO;
val->i = rxm[0][0];
val->i = (int)rxm[0][0];
if (level == RIG_LEVEL_STRENGTH)
val->i = (int)rig_raw2val(val->i,&rig->state.str_cal);
@ -666,11 +742,7 @@ int dttsp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status)
}
buf_len = sprintf (buf, "%s %d\n", cmd, status);
ret = write (rig->state.rigport.fd, buf, buf_len );
if (ret == buf_len)
ret = RIG_OK;
else
ret = -RIG_EIO;
ret = send_command (rig, buf, buf_len);
return ret;
}