kopia lustrzana https://github.com/Hamlib/Hamlib
Merge pull request #715 from mikaelnousiainen/fix-icom-transceive-and-spectrum-data-conflicts
Attempt to handle asynchronous rig output data in Icom backendpull/719/head
commit
c4e6ed39e6
|
@ -23,9 +23,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h> /* String function definitions */
|
#include <string.h> /* String function definitions */
|
||||||
#include <unistd.h> /* UNIX standard function definitions */
|
|
||||||
|
|
||||||
#include "hamlib/rig.h"
|
#include "hamlib/rig.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
@ -90,6 +88,26 @@ int make_cmd_frame(char frame[], char re_id, char ctrl_id, char cmd, int subcmd,
|
||||||
RETURNFUNC(i);
|
RETURNFUNC(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int icom_frame_fix_preamble(int frame_len, unsigned char *frame)
|
||||||
|
{
|
||||||
|
if (frame[0] == PR)
|
||||||
|
{
|
||||||
|
// Sometimes the second preamble byte is missing -> TODO: Find out why!
|
||||||
|
if (frame[1] != PR)
|
||||||
|
{
|
||||||
|
memmove(frame + 1, frame, frame_len);
|
||||||
|
frame_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_WARN, "%s: invalid Icom CI-V frame, no preamble found\n", __func__);
|
||||||
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame_len;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* icom_one_transaction
|
* icom_one_transaction
|
||||||
*
|
*
|
||||||
|
@ -109,11 +127,12 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
const struct icom_priv_caps *priv_caps;
|
const struct icom_priv_caps *priv_caps;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
|
struct timeval start_time, current_time, elapsed_time;
|
||||||
// this buf needs to be large enough for 0xfe strings for power up
|
// this buf needs to be large enough for 0xfe strings for power up
|
||||||
// at 115,200 this is now at least 150
|
// at 115,200 this is now at least 150
|
||||||
unsigned char buf[200];
|
unsigned char buf[200];
|
||||||
unsigned char sendbuf[MAXFRAMELEN];
|
unsigned char sendbuf[MAXFRAMELEN];
|
||||||
int frm_len, retval;
|
int frm_len, frm_data_len, retval;
|
||||||
int ctrl_id;
|
int ctrl_id;
|
||||||
|
|
||||||
ENTERFUNC;
|
ENTERFUNC;
|
||||||
|
@ -168,12 +187,14 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
{
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
/* Other error, return it */
|
/* Other error, return it */
|
||||||
RETURNFUNC(retval);
|
RETURNFUNC(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval < 1)
|
if (retval < 1)
|
||||||
{
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
RETURNFUNC(-RIG_EPROTO);
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +244,9 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
RETURNFUNC(RIG_OK);
|
RETURNFUNC(RIG_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
|
||||||
|
read_another_frame:
|
||||||
/*
|
/*
|
||||||
* wait for ACK ...
|
* wait for ACK ...
|
||||||
* FIXME: handle padding/collisions
|
* FIXME: handle padding/collisions
|
||||||
|
@ -245,10 +269,9 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Unhold_Decode(rig);
|
|
||||||
|
|
||||||
if (frm_len < 0)
|
if (frm_len < 0)
|
||||||
{
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
/* RIG_TIMEOUT: timeout getting response, return timeout */
|
/* RIG_TIMEOUT: timeout getting response, return timeout */
|
||||||
/* other error: return it */
|
/* other error: return it */
|
||||||
RETURNFUNC(frm_len);
|
RETURNFUNC(frm_len);
|
||||||
|
@ -256,12 +279,23 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
|
|
||||||
if (frm_len < 1)
|
if (frm_len < 1)
|
||||||
{
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
RETURNFUNC(-RIG_EPROTO);
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval = icom_frame_fix_preamble(frm_len, buf);
|
||||||
|
if (retval < 0)
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
frm_len = retval;
|
||||||
|
|
||||||
switch (buf[frm_len - 1])
|
switch (buf[frm_len - 1])
|
||||||
{
|
{
|
||||||
case COL:
|
case COL:
|
||||||
|
Unhold_Decode(rig);
|
||||||
/* Collision */
|
/* Collision */
|
||||||
RETURNFUNC(-RIG_BUSBUSY);
|
RETURNFUNC(-RIG_BUSBUSY);
|
||||||
|
|
||||||
|
@ -270,30 +304,71 @@ int icom_one_transaction(RIG *rig, int cmd, int subcmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NAK:
|
case NAK:
|
||||||
|
Unhold_Decode(rig);
|
||||||
RETURNFUNC(-RIG_ERJCTED);
|
RETURNFUNC(-RIG_ERJCTED);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Unhold_Decode(rig);
|
||||||
/* Timeout after reading at least one character */
|
/* Timeout after reading at least one character */
|
||||||
/* Problem on ci-v bus? */
|
/* Problem on ci-v bus? */
|
||||||
RETURNFUNC(-RIG_EPROTO);
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm_len < ACKFRMLEN) { RETURNFUNC(-RIG_EPROTO); }
|
if (frm_len < ACKFRMLEN)
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
|
}
|
||||||
|
|
||||||
// if we send a bad command we will get back a NAK packet
|
// if we send a bad command we will get back a NAK packet
|
||||||
// e.g. fe fe e0 50 fa fd
|
// e.g. fe fe e0 50 fa fd
|
||||||
if (frm_len == 6 && NAK == buf[frm_len - 2]) { RETURNFUNC(-RIG_ERJCTED); }
|
if (frm_len == 6 && NAK == buf[frm_len - 2])
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(-RIG_ERJCTED);
|
||||||
|
}
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_TRACE, "%s: frm_len=%d, frm_len-1=%02x, frm_len-2=%02x\n",
|
rig_debug(RIG_DEBUG_TRACE, "%s: frm_len=%d, frm_len-1=%02x, frm_len-2=%02x\n",
|
||||||
__func__, frm_len, buf[frm_len - 1], buf[frm_len - 2]);
|
__func__, frm_len, buf[frm_len - 1], buf[frm_len - 2]);
|
||||||
|
|
||||||
// has to be one of these two now or frame is corrupt
|
// has to be one of these two now or frame is corrupt
|
||||||
if (FI != buf[frm_len - 1] && ACK != buf[frm_len - 1]) { RETURNFUNC(-RIG_BUSBUSY); }
|
if (FI != buf[frm_len - 1] && ACK != buf[frm_len - 1])
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(-RIG_BUSBUSY);
|
||||||
|
}
|
||||||
|
|
||||||
*data_len = frm_len - (ACKFRMLEN - 1);
|
frm_data_len = frm_len - (ACKFRMLEN - 1);
|
||||||
|
|
||||||
if (*data_len <= 0) { RETURNFUNC(-RIG_EPROTO); }
|
if (frm_data_len <= 0)
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Does ctrlid (detected by icom_is_async_frame) vary (seeing some code above using 0x80 for non-full-duplex)?
|
||||||
|
if (icom_is_async_frame(rig, frm_len, buf))
|
||||||
|
{
|
||||||
|
int elapsed_ms;
|
||||||
|
icom_process_async_frame(rig, frm_len, buf);
|
||||||
|
|
||||||
|
gettimeofday(¤t_time, NULL);
|
||||||
|
timersub(¤t_time, &start_time, &elapsed_time);
|
||||||
|
|
||||||
|
elapsed_ms = (int) (elapsed_time.tv_sec * 1000 + elapsed_time.tv_usec / 1000);
|
||||||
|
|
||||||
|
if (elapsed_ms > rs->rigport.timeout)
|
||||||
|
{
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
RETURNFUNC(-RIG_ETIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto read_another_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unhold_Decode(rig);
|
||||||
|
|
||||||
|
*data_len = frm_data_len;
|
||||||
memcpy(data, buf + 4, *data_len);
|
memcpy(data, buf + 4, *data_len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* helper functions
|
* helper functions
|
||||||
*/
|
*/
|
||||||
int make_cmd_frame(char frame[], char re_id, char ctrl_id, char cmd, int subcmd, const unsigned char *data, int data_len);
|
int make_cmd_frame(char frame[], char re_id, char ctrl_id, char cmd, int subcmd, const unsigned char *data, int data_len);
|
||||||
|
int icom_frame_fix_preamble(int frame_len, unsigned char *frame);
|
||||||
|
|
||||||
int icom_transaction (RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len);
|
int icom_transaction (RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len);
|
||||||
int read_icom_frame(hamlib_port_t *p, unsigned char rxbuffer[], int rxbuffer_len);
|
int read_icom_frame(hamlib_port_t *p, unsigned char rxbuffer[], int rxbuffer_len);
|
||||||
|
|
169
rigs/icom/icom.c
169
rigs/icom/icom.c
|
@ -7933,7 +7933,7 @@ int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq,
|
||||||
RETURNFUNC(RIG_OK);
|
RETURNFUNC(RIG_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int icom_parse_spectrum_frame(RIG *rig, int length, unsigned char *frame_data)
|
static int icom_parse_spectrum_frame(RIG *rig, int length, const unsigned char *frame_data)
|
||||||
{
|
{
|
||||||
struct rig_caps *caps = rig->caps;
|
struct rig_caps *caps = rig->caps;
|
||||||
struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) caps->priv;
|
struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) caps->priv;
|
||||||
|
@ -8059,6 +8059,85 @@ static int icom_parse_spectrum_frame(RIG *rig, int length, unsigned char *frame_
|
||||||
RETURNFUNC(RIG_OK);
|
RETURNFUNC(RIG_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int icom_is_async_frame(RIG *rig, int frame_len, const unsigned char *frame)
|
||||||
|
{
|
||||||
|
if (frame_len < ACKFRMLEN)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spectrum scope data is not CI-V transceive data, but handled the same way as it is pushed by the rig */
|
||||||
|
return frame[2] == BCASTID || (frame[2] == CTRLID && frame[4] == C_CTL_SCP && frame[5] == S_SCP_DAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int icom_process_async_frame(RIG *rig, int frame_len, const unsigned char *frame)
|
||||||
|
{
|
||||||
|
struct rig_state *rs = &rig->state;
|
||||||
|
struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv;
|
||||||
|
rmode_t mode;
|
||||||
|
pbwidth_t width;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the first 2 bytes must be 0xfe
|
||||||
|
* the 3rd one 0x00 since this is transceive mode
|
||||||
|
* the 4rd one the emitter
|
||||||
|
* then the command number
|
||||||
|
* the rest is data
|
||||||
|
* and don't forget one byte at the end for the EOM
|
||||||
|
*/
|
||||||
|
switch (frame[4])
|
||||||
|
{
|
||||||
|
case C_SND_FREQ:
|
||||||
|
/*
|
||||||
|
* TODO: the freq length might be less than 4 or 5 bytes
|
||||||
|
* on older rigs!
|
||||||
|
*/
|
||||||
|
if (rig->callbacks.freq_event)
|
||||||
|
{
|
||||||
|
freq_t freq;
|
||||||
|
freq = from_bcd(frame + 5, (priv->civ_731_mode ? 4 : 5) * 2);
|
||||||
|
RETURNFUNC(rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq,
|
||||||
|
rig->callbacks.freq_arg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETURNFUNC(-RIG_ENAVAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case C_SND_MODE:
|
||||||
|
if (rig->callbacks.mode_event)
|
||||||
|
{
|
||||||
|
icom2rig_mode(rig, frame[5], frame[6], &mode, &width);
|
||||||
|
RETURNFUNC(rig->callbacks.mode_event(rig, RIG_VFO_CURR,
|
||||||
|
mode, width, rig->callbacks.mode_arg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETURNFUNC(-RIG_ENAVAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case C_CTL_SCP:
|
||||||
|
if (frame[5] == S_SCP_DAT)
|
||||||
|
{
|
||||||
|
icom_parse_spectrum_frame(rig, frame_len - (6 + 1), frame + 6);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: transceive cmd unsupported %#2.2x\n",
|
||||||
|
__func__, frame[4]);
|
||||||
|
RETURNFUNC(-RIG_ENIMPL);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURNFUNC(RIG_OK);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* icom_decode is called by sa_sigio, when some asynchronous
|
* icom_decode is called by sa_sigio, when some asynchronous
|
||||||
* data has been received from the rig
|
* data has been received from the rig
|
||||||
|
@ -8068,9 +8147,7 @@ int icom_decode_event(RIG *rig)
|
||||||
struct icom_priv_data *priv;
|
struct icom_priv_data *priv;
|
||||||
struct rig_state *rs;
|
struct rig_state *rs;
|
||||||
unsigned char buf[MAXFRAMELEN];
|
unsigned char buf[MAXFRAMELEN];
|
||||||
int frm_len;
|
int retval, frm_len;
|
||||||
rmode_t mode;
|
|
||||||
pbwidth_t width;
|
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -8087,24 +8164,17 @@ int icom_decode_event(RIG *rig)
|
||||||
|
|
||||||
if (frm_len < 1)
|
if (frm_len < 1)
|
||||||
{
|
{
|
||||||
RETURNFUNC(0);
|
RETURNFUNC(RIG_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf[0] == PR)
|
retval = icom_frame_fix_preamble(frm_len, buf);
|
||||||
|
if (retval < 0)
|
||||||
{
|
{
|
||||||
// Sometimes the second preamble byte is missing -> TODO: Find out why!
|
RETURNFUNC(retval);
|
||||||
if (buf[1] != PR)
|
|
||||||
{
|
|
||||||
memmove(buf + 1, buf, frm_len);
|
|
||||||
frm_len++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s: invalid Icom CI-V frame, no preamble found\n", __func__);
|
|
||||||
RETURNFUNC(-RIG_EPROTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm_len = retval;
|
||||||
|
|
||||||
switch (buf[frm_len - 1])
|
switch (buf[frm_len - 1])
|
||||||
{
|
{
|
||||||
case COL:
|
case COL:
|
||||||
|
@ -8122,72 +8192,13 @@ int icom_decode_event(RIG *rig)
|
||||||
RETURNFUNC(-RIG_EPROTO);
|
RETURNFUNC(-RIG_EPROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spectrum scope data is not CI-V transceive data, but handled the same way as it is pushed by the rig */
|
if (!icom_is_async_frame(rig, frm_len, buf))
|
||||||
if (buf[3] != BCASTID && buf[3] != priv->re_civ_addr && buf[4] != C_CTL_SCP)
|
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s: CI-V %#x called for %#x!\n", __func__,
|
rig_debug(RIG_DEBUG_WARN, "%s: CI-V %#x called for %#x!\n", __func__,
|
||||||
priv->re_civ_addr, buf[3]);
|
priv->re_civ_addr, buf[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
RETURNFUNC(icom_process_async_frame(rig, frm_len, buf));
|
||||||
* the first 2 bytes must be 0xfe
|
|
||||||
* the 3rd one the emitter
|
|
||||||
* the 4rd one 0x00 since this is transceive mode
|
|
||||||
* then the command number
|
|
||||||
* the rest is data
|
|
||||||
* and don't forget one byte at the end for the EOM
|
|
||||||
*/
|
|
||||||
switch (buf[4])
|
|
||||||
{
|
|
||||||
case C_SND_FREQ:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: the freq length might be less than 4 or 5 bytes
|
|
||||||
* on older rigs!
|
|
||||||
*/
|
|
||||||
if (rig->callbacks.freq_event)
|
|
||||||
{
|
|
||||||
freq_t freq;
|
|
||||||
freq = from_bcd(buf + 5, (priv->civ_731_mode ? 4 : 5) * 2);
|
|
||||||
RETURNFUNC(rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq,
|
|
||||||
rig->callbacks.freq_arg));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RETURNFUNC(-RIG_ENAVAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_SND_MODE:
|
|
||||||
if (rig->callbacks.mode_event)
|
|
||||||
{
|
|
||||||
icom2rig_mode(rig, buf[5], buf[6], &mode, &width);
|
|
||||||
RETURNFUNC(rig->callbacks.mode_event(rig, RIG_VFO_CURR,
|
|
||||||
mode, width,
|
|
||||||
rig->callbacks.mode_arg));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RETURNFUNC(-RIG_ENAVAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_CTL_SCP:
|
|
||||||
if (buf[5] == S_SCP_DAT)
|
|
||||||
{
|
|
||||||
icom_parse_spectrum_frame(rig, frm_len - (6 + 1), buf + 6);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s: transceive cmd unsupported %#2.2x\n",
|
|
||||||
__func__, buf[4]);
|
|
||||||
RETURNFUNC(-RIG_ENIMPL);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURNFUNC(RIG_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen,
|
int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen,
|
||||||
|
|
|
@ -387,6 +387,8 @@ int icom_set_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf,
|
||||||
int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf,
|
int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf,
|
||||||
int *seconds);
|
int *seconds);
|
||||||
int icom_get_freq_range(RIG *rig);
|
int icom_get_freq_range(RIG *rig);
|
||||||
|
int icom_is_async_frame(RIG *rig, int frame_len, const unsigned char *frame);
|
||||||
|
int icom_process_async_frame(RIG *rig, int frame_len, const unsigned char *frame);
|
||||||
|
|
||||||
extern const struct confparams icom_cfg_params[];
|
extern const struct confparams icom_cfg_params[];
|
||||||
extern const struct confparams icom_ext_levels[];
|
extern const struct confparams icom_ext_levels[];
|
||||||
|
|
29
src/event.c
29
src/event.c
|
@ -56,9 +56,9 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#include <hamlib/rig.h>
|
#include <hamlib/rig.h>
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(HAVE_TERMIOS_H)
|
#if defined(WIN32) && !defined(HAVE_TERMIOS_H)
|
||||||
# include "win32termios.h"
|
# include "win32termios.h"
|
||||||
|
@ -300,6 +300,8 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
ENTERFUNC;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* so far, only file oriented ports have event reporting support
|
* so far, only file oriented ports have event reporting support
|
||||||
*/
|
*/
|
||||||
|
@ -309,6 +311,22 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: FIXME: We may end up calling decode_event right before or after the hold_decode lock is released
|
||||||
|
* by backend transaction routine. With the Icom backend this will end up waiting for the next CI-V frame
|
||||||
|
* to be read and this will interfere with reading of the next response to any command.
|
||||||
|
* => It is difficult to find a way to avoid this routine picking up regular responses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not disturb, the backend is currently receiving data
|
||||||
|
*/
|
||||||
|
if (rig->state.hold_decode)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: hold decode, backend is receiving data\n", __func__);
|
||||||
|
RETURNFUNC(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: siginfo is not portable, however use it where available */
|
/* FIXME: siginfo is not portable, however use it where available */
|
||||||
#if 0&&defined(HAVE_SIGINFO_T)
|
#if 0&&defined(HAVE_SIGINFO_T)
|
||||||
siginfo_t *si = (siginfo_t *)data;
|
siginfo_t *si = (siginfo_t *)data;
|
||||||
|
@ -334,10 +352,10 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR,
|
rig_debug(RIG_DEBUG_ERR,
|
||||||
"%s: select: %s\n",
|
"%s: select() failed: %s\n",
|
||||||
__func__,
|
__func__,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return -1;
|
RETURNFUNC(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -347,7 +365,8 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
|
||||||
*/
|
*/
|
||||||
if (rig->state.hold_decode)
|
if (rig->state.hold_decode)
|
||||||
{
|
{
|
||||||
return -1;
|
rig_debug(RIG_DEBUG_TRACE, "%s: hold decode, backend is receiving data\n", __func__);
|
||||||
|
RETURNFUNC(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rig->caps->decode_event)
|
if (rig->caps->decode_event)
|
||||||
|
@ -355,7 +374,7 @@ static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
|
||||||
rig->caps->decode_event(rig);
|
rig->caps->decode_event(rig);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* process each opened rig */
|
RETURNFUNC(1); /* process each opened rig */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1904,7 +1904,7 @@ int HAMLIB_API parse_hoststr(char *hoststr, char host[256], char port[6])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef RIG_FLUSH_REMOVE
|
#define RIG_FLUSH_REMOVE
|
||||||
int HAMLIB_API rig_flush(hamlib_port_t *port)
|
int HAMLIB_API rig_flush(hamlib_port_t *port)
|
||||||
{
|
{
|
||||||
#ifndef RIG_FLUSH_REMOVE
|
#ifndef RIG_FLUSH_REMOVE
|
||||||
|
|
|
@ -910,11 +910,19 @@ int main(int argc, char *argv[])
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
retcode = select(sock_listen + 1, &set, NULL, NULL, &timeout);
|
retcode = select(sock_listen + 1, &set, NULL, NULL, &timeout);
|
||||||
|
|
||||||
if (-1 == retcode)
|
if (retcode == -1)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR, "%s: select\n", __func__);
|
int errno_stored = errno;
|
||||||
|
rig_debug(RIG_DEBUG_ERR, "%s: select() failed: %s\n", __func__, strerror(errno_stored));
|
||||||
|
|
||||||
|
// TODO: FIXME: Why does this select() return EINTR after any command when set_trn RIG is enabled?
|
||||||
|
if (errno == EINTR)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: ignoring interrupted system call\n", __func__);
|
||||||
|
retcode = 0;
|
||||||
}
|
}
|
||||||
else if (!retcode)
|
}
|
||||||
|
else if (retcode == 0)
|
||||||
{
|
{
|
||||||
if (ctrl_c)
|
if (ctrl_c)
|
||||||
{
|
{
|
||||||
|
@ -1039,11 +1047,13 @@ void *handle_socket(void *arg)
|
||||||
int ext_resp = 0;
|
int ext_resp = 0;
|
||||||
char resp_sep = '\n';
|
char resp_sep = '\n';
|
||||||
|
|
||||||
|
ENTERFUNC;
|
||||||
|
|
||||||
fsockin = get_fsockin(handle_data_arg);
|
fsockin = get_fsockin(handle_data_arg);
|
||||||
|
|
||||||
if (!fsockin)
|
if (!fsockin)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR, "fdopen(0x%d) in: %s\n", handle_data_arg->sock,
|
rig_debug(RIG_DEBUG_ERR, "%s: fdopen(0x%d) in: %s\n", __func__, handle_data_arg->sock,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
goto handle_exit;
|
goto handle_exit;
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1062,7 @@ void *handle_socket(void *arg)
|
||||||
|
|
||||||
if (!fsockout)
|
if (!fsockout)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_ERR, "fdopen out: %s\n", strerror(errno));
|
rig_debug(RIG_DEBUG_ERR, "%s: fdopen out: %s\n", __func__, strerror(errno));
|
||||||
fclose(fsockin);
|
fclose(fsockin);
|
||||||
|
|
||||||
goto handle_exit;
|
goto handle_exit;
|
||||||
|
|
Ładowanie…
Reference in New Issue