diff --git a/src/iofunc.c b/src/iofunc.c index d49c0f266..0b994ee41 100644 --- a/src/iofunc.c +++ b/src/iofunc.c @@ -49,6 +49,130 @@ #include "iofunc.h" #include "misc.h" +#include "serial.h" +#include "parallel.h" +#include "usb_port.h" +#include "network.h" + + +/** + * \brief Open a hamlib_port based on its rig port type + * \param p rig port descriptor + * \return status + */ +int HAMLIB_API port_open(hamlib_port_t *p) +{ + int status; + int want_state_delay = 0; + + p->fd = -1; + + switch(p->type.rig) { + case RIG_PORT_SERIAL: + status = serial_open(p); + if (status < 0) + return status; + if (p->parm.serial.rts_state != RIG_SIGNAL_UNSET && + p->parm.serial.handshake != RIG_HANDSHAKE_HARDWARE) { + status = ser_set_rts(p, + p->parm.serial.rts_state == RIG_SIGNAL_ON); + want_state_delay = 1; + } + if (status != 0) + return status; + if (p->parm.serial.dtr_state != RIG_SIGNAL_UNSET) { + status = ser_set_dtr(p, + p->parm.serial.dtr_state == RIG_SIGNAL_ON); + want_state_delay = 1; + } + if (status != 0) + return status; + /* + * Wait whatever electrolytics in the circuit come up to voltage. + * Is 100ms enough? Too much? + */ + if (want_state_delay) + usleep(100*1000); + + break; + + case RIG_PORT_PARALLEL: + status = par_open(p); + if (status < 0) + return status; + break; + + case RIG_PORT_DEVICE: + status = open(p->pathname, O_RDWR, 0); + if (status < 0) + return -RIG_EIO; + p->fd = status; + break; + + case RIG_PORT_USB: + status = usb_port_open(p); + if (status < 0) + return status; + break; + + case RIG_PORT_NONE: + case RIG_PORT_RPC: + break; /* ez :) */ + + case RIG_PORT_NETWORK: + /* FIXME: hardcoded network port */ + status = network_open(p, 4532); + if (status < 0) + return status; + break; + + default: + return -RIG_EINVAL; + } + + return RIG_OK; +} + +/** + * \brief Close a hamlib_port + * \param p rig port descriptor + * \param port_type equivalent rig port type + * \return status + * + * This function may also be used with ptt and dcd ports. + */ +int HAMLIB_API port_close(hamlib_port_t *p, rig_port_t port_type) +{ + int ret; + + if (p->fd != -1) { + switch (port_type) { + case RIG_PORT_SERIAL: + ret = ser_close(p); + break; + case RIG_PORT_PARALLEL: + ret = par_close(p); + break; + case RIG_PORT_USB: + ret = usb_port_close(p); + break; + case RIG_PORT_NETWORK: + ret = network_close(p); + break; + + default: + rig_debug(RIG_DEBUG_ERR, "%s: Unknown port type %d\n", + __func__, port_type); + /* fall through */ + case RIG_PORT_DEVICE: + ret = close(p->fd); + } + p->fd = -1; + } + + return ret; +} + #if defined(WIN32) && !defined(HAVE_TERMIOS_H) #include "win32termios.h" diff --git a/src/iofunc.h b/src/iofunc.h index 6fcd021b9..8273e2152 100644 --- a/src/iofunc.h +++ b/src/iofunc.h @@ -27,6 +27,9 @@ #include +extern HAMLIB_EXPORT(int) port_open(hamlib_port_t *p); +extern HAMLIB_EXPORT(int) port_close(hamlib_port_t *p, rig_port_t port_type); + extern HAMLIB_EXPORT(int) read_block(hamlib_port_t *p, char *rxbuffer, size_t count); extern HAMLIB_EXPORT(int) write_block(hamlib_port_t *p, const char *txbuffer, size_t count); extern HAMLIB_EXPORT(int) read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len); diff --git a/src/rig.c b/src/rig.c index ca6005e62..75e909e5e 100644 --- a/src/rig.c +++ b/src/rig.c @@ -419,7 +419,6 @@ int HAMLIB_API rig_open(RIG *rig) const struct rig_caps *caps; struct rig_state *rs; int status; - int want_state_delay = 0; rig_debug(RIG_DEBUG_VERBOSE,"rig:rig_open called \n"); @@ -434,69 +433,28 @@ int HAMLIB_API rig_open(RIG *rig) rs->rigport.fd = -1; - switch(rs->rigport.type.rig) { - case RIG_PORT_SERIAL: - status = serial_open(&rs->rigport); - if (status < 0) - return status; + if (rs->rigport.type.rig == RIG_PORT_SERIAL) { + if (rs->rigport.parm.serial.rts_state != RIG_SIGNAL_UNSET && - rs->rigport.type.ptt != RIG_PTT_SERIAL_RTS && - rs->rigport.parm.serial.handshake != RIG_HANDSHAKE_HARDWARE) { - status = ser_set_rts(&rs->rigport, - rs->rigport.parm.serial.rts_state == RIG_SIGNAL_ON); - want_state_delay = 1; + (rs->pttport.type.ptt == RIG_PTT_SERIAL_RTS || + rs->rigport.parm.serial.handshake == RIG_HANDSHAKE_HARDWARE)) { + + rig_debug(RIG_DEBUG_ERR, "Cannot set RTS with PTT by RTS or hardware handshare \"%s\"\n", + rs->rigport.pathname); + return -RIG_ECONF; } - if (status != 0) - return status; if (rs->rigport.parm.serial.dtr_state != RIG_SIGNAL_UNSET && - rs->rigport.type.ptt != RIG_PTT_SERIAL_DTR) { - status = ser_set_dtr(&rs->rigport, - rs->rigport.parm.serial.dtr_state == RIG_SIGNAL_ON); - want_state_delay = 1; + rs->pttport.type.ptt == RIG_PTT_SERIAL_DTR) { + rig_debug(RIG_DEBUG_ERR, "Cannot set DTR with PTT by DTR\"%s\"\n", + rs->rigport.pathname); + return -RIG_ECONF; } - if (status != 0) - return status; - /* - * Wait whatever electrolytics in the circuit come up to voltage. - * Is 100ms enough? Too much? - */ - if (want_state_delay) - usleep(100*1000); + } - break; + status = port_open(&rs->rigport); + if (status < 0) + return status; - case RIG_PORT_PARALLEL: - status = par_open(&rs->rigport); - if (status < 0) - return status; - break; - - case RIG_PORT_DEVICE: - status = open(rs->rigport.pathname, O_RDWR, 0); - if (status < 0) - return -RIG_EIO; - rs->rigport.fd = status; - break; - - case RIG_PORT_USB: - status = usb_port_open(&rs->rigport); - if (status < 0) - return status; - break; - - case RIG_PORT_NONE: - case RIG_PORT_RPC: - break; /* ez :) */ - - case RIG_PORT_NETWORK: - status = network_open(&rs->rigport, 4532); - if (status < 0) - return status; - break; - - default: - return -RIG_EINVAL; - } /* * FIXME: what to do if PTT open fails or PTT unsupported? @@ -633,10 +591,10 @@ int HAMLIB_API rig_close(RIG *rig) break; case RIG_PTT_SERIAL_RTS: case RIG_PTT_SERIAL_DTR: - ser_close(&rs->pttport); + port_close(&rs->pttport, RIG_PORT_SERIAL); break; case RIG_PTT_PARALLEL: - par_close(&rs->pttport); + port_close(&rs->pttport, RIG_PORT_PARALLEL); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported PTT type %d\n", @@ -650,10 +608,10 @@ int HAMLIB_API rig_close(RIG *rig) case RIG_DCD_SERIAL_DSR: case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_CAR: - ser_close(&rs->dcdport); + port_close(&rs->dcdport, RIG_PORT_SERIAL); break; case RIG_DCD_PARALLEL: - par_close(&rs->dcdport); + port_close(&rs->dcdport, RIG_PORT_PARALLEL); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported DCD type %d\n", @@ -662,26 +620,7 @@ int HAMLIB_API rig_close(RIG *rig) rs->dcdport.fd = rs->pttport.fd = -1; - if (rs->rigport.fd != -1) { - switch(rs->rigport.type.rig) { - case RIG_PORT_SERIAL: - ser_close(&rs->rigport); - break; - case RIG_PORT_PARALLEL: - par_close(&rs->rigport); - break; - case RIG_PORT_USB: - usb_port_close(&rs->rigport); - break; - case RIG_PORT_NETWORK: - network_close(&rs->rigport); - break; - - default: - close(rs->rigport.fd); - } - rs->rigport.fd = -1; - } + port_close(&rs->rigport, rs->rigport.type.rig); remove_opened_rig(rig);