From f754c1469188a5e1a82c98532cb21b334530a91a Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Sun, 12 Jan 2014 00:05:02 +0100 Subject: [PATCH] scpi: make the scpi_dev_inst_new more generic --- hardware/common/scpi.c | 67 +++++++++++++++++++---------------- hardware/common/scpi_serial.c | 64 ++++++++++++++++----------------- hardware/common/scpi_tcp.c | 62 ++++++++++++++++++-------------- hardware/common/scpi_usbtmc.c | 64 ++++++++++++++++----------------- hardware/common/scpi_vxi.c | 60 +++++++++++++++++-------------- libsigrok-internal.h | 26 +++----------- 6 files changed, 172 insertions(+), 171 deletions(-) diff --git a/hardware/common/scpi.c b/hardware/common/scpi.c index 80287330..c2221c11 100644 --- a/hardware/common/scpi.c +++ b/hardware/common/scpi.c @@ -65,42 +65,48 @@ static int parse_strict_bool(const char *str, gboolean *ret) return SR_ERR; } +SR_PRIV extern const struct sr_scpi_dev_inst scpi_serial_dev; +SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_dev; +SR_PRIV extern const struct sr_scpi_dev_inst scpi_usbtmc_dev; +SR_PRIV extern const struct sr_scpi_dev_inst scpi_vxi_dev; + +static const struct sr_scpi_dev_inst *scpi_devs[] = { + &scpi_tcp_dev, + &scpi_usbtmc_dev, +#ifdef HAVE_RPC + &scpi_vxi_dev, +#endif +#ifdef HAVE_LIBSERIALPORT + &scpi_serial_dev, /* must be last as it matches any resource */ +#endif +}; + SR_PRIV struct sr_scpi_dev_inst *scpi_dev_inst_new(const char *resource, const char *serialcomm) { struct sr_scpi_dev_inst *scpi = NULL; - const char *usbtmc_prefix = "/dev/usbtmc"; - const char *tcp_prefix = "tcp/"; - const char *vxi_prefix = "vxi/"; - gchar **tokens, *address, *port, *instrument; + const struct sr_scpi_dev_inst *scpi_dev; + gchar **params; + unsigned i; - if (strncmp(resource, usbtmc_prefix, strlen(usbtmc_prefix)) == 0) { - sr_dbg("Opening USBTMC device %s.", resource); - scpi = scpi_usbtmc_dev_inst_new(resource); - } else if (strncmp(resource, tcp_prefix, strlen(tcp_prefix)) == 0) { - sr_dbg("Opening TCP connection %s.", resource); - tokens = g_strsplit(resource + strlen(tcp_prefix), "/", 0); - address = tokens[0]; - port = tokens[1]; - if (address && port && !tokens[2]) - scpi = scpi_tcp_dev_inst_new(address, port); - else - sr_err("Invalid parameters."); - g_strfreev(tokens); - } else if (HAVE_RPC && !strncmp(resource, vxi_prefix, strlen(vxi_prefix))) { - sr_dbg("Opening VXI connection %s.", resource); - tokens = g_strsplit(resource + strlen(tcp_prefix), "/", 0); - address = tokens[0]; - instrument = tokens[1]; - if (address && (!instrument || !tokens[2])) - scpi = scpi_vxi_dev_inst_new(address, instrument); - else - sr_err("Invalid parameters."); - g_strfreev(tokens); - } else { - sr_dbg("Opening serial device %s.", resource); - scpi = scpi_serial_dev_inst_new(resource, serialcomm); + for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) { + scpi_dev = scpi_devs[i]; + if (!strncmp(resource, scpi_dev->prefix, strlen(scpi_dev->prefix))) { + sr_dbg("Opening %s device %s.", scpi_dev->name, resource); + scpi = g_malloc(sizeof(*scpi)); + *scpi = *scpi_dev; + scpi->priv = g_malloc0(scpi->priv_size); + params = g_strsplit(resource, "/", 0); + if (scpi->dev_inst_new(scpi->priv, resource, + params, serialcomm) != SR_OK) { + sr_scpi_free(scpi); + scpi = NULL; + } + g_strfreev(params); + break; + } } + return scpi; } @@ -264,6 +270,7 @@ SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi) SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi) { scpi->free(scpi->priv); + g_free(scpi->priv); g_free(scpi); } diff --git a/hardware/common/scpi_serial.c b/hardware/common/scpi_serial.c index 0ee58947..d4c3add2 100644 --- a/hardware/common/scpi_serial.c +++ b/hardware/common/scpi_serial.c @@ -34,6 +34,19 @@ struct scpi_serial { char last_character; }; +static int scpi_serial_dev_inst_new(void *priv, const char *resource, + char **params, const char *serialcomm) +{ + struct scpi_serial *sscpi = priv; + + (void)params; + + if (!(sscpi->serial = sr_serial_dev_inst_new(resource, serialcomm))) + return SR_ERR; + + return SR_OK; +} + SR_PRIV int scpi_serial_open(void *priv) { struct scpi_serial *sscpi = priv; @@ -184,46 +197,29 @@ SR_PRIV int scpi_serial_read_complete(void *priv) static int scpi_serial_close(void *priv) { struct scpi_serial *sscpi = priv; - struct sr_serial_dev_inst *serial = sscpi->serial; - return serial_close(serial); + return serial_close(sscpi->serial); } static void scpi_serial_free(void *priv) { struct scpi_serial *sscpi = priv; - struct sr_serial_dev_inst *serial = sscpi->serial; - sr_serial_dev_inst_free(serial); - g_free(sscpi); + sr_serial_dev_inst_free(sscpi->serial); } -SR_PRIV struct sr_scpi_dev_inst *scpi_serial_dev_inst_new(const char *port, - const char *serialcomm) -{ - struct sr_scpi_dev_inst *scpi; - struct scpi_serial *sscpi; - struct sr_serial_dev_inst *serial; - - if (!(serial = sr_serial_dev_inst_new(port, serialcomm))) - return NULL; - - sscpi = g_malloc(sizeof(struct scpi_serial)); - - sscpi->serial = serial; - - scpi = g_malloc(sizeof(struct sr_scpi_dev_inst)); - - scpi->open = scpi_serial_open; - scpi->source_add = scpi_serial_source_add; - scpi->source_remove = scpi_serial_source_remove; - scpi->send = scpi_serial_send; - scpi->read_begin = scpi_serial_read_begin; - scpi->read_data = scpi_serial_read_data; - scpi->read_complete = scpi_serial_read_complete; - scpi->close = scpi_serial_close; - scpi->free = scpi_serial_free; - scpi->priv = sscpi; - - return scpi; -} +SR_PRIV const struct sr_scpi_dev_inst scpi_serial_dev = { + .name = "serial", + .prefix = "", + .priv_size = sizeof(struct scpi_serial), + .dev_inst_new = scpi_serial_dev_inst_new, + .open = scpi_serial_open, + .source_add = scpi_serial_source_add, + .source_remove = scpi_serial_source_remove, + .send = scpi_serial_send, + .read_begin = scpi_serial_read_begin, + .read_data = scpi_serial_read_data, + .read_complete = scpi_serial_read_complete, + .close = scpi_serial_close, + .free = scpi_serial_free, +}; diff --git a/hardware/common/scpi_tcp.c b/hardware/common/scpi_tcp.c index 44557937..0de2ff54 100644 --- a/hardware/common/scpi_tcp.c +++ b/hardware/common/scpi_tcp.c @@ -51,6 +51,26 @@ struct scpi_tcp { int response_bytes_read; }; +static int scpi_tcp_dev_inst_new(void *priv, const char *resource, + char **params, const char *serialcomm) +{ + struct scpi_tcp *tcp = priv; + + (void)resource; + (void)serialcomm; + + if (!params || !params[1] || !params[2]) { + sr_err("Invalid parameters."); + return SR_ERR; + } + + tcp->address = g_strdup(params[1]); + tcp->port = g_strdup(params[2]); + tcp->socket = -1; + + return SR_OK; +} + SR_PRIV int scpi_tcp_open(void *priv) { struct scpi_tcp *tcp = priv; @@ -205,32 +225,20 @@ SR_PRIV void scpi_tcp_free(void *priv) g_free(tcp->address); g_free(tcp->port); - g_free(tcp); } -SR_PRIV struct sr_scpi_dev_inst *scpi_tcp_dev_inst_new(const char *address, - const char *port) -{ - struct sr_scpi_dev_inst *scpi; - struct scpi_tcp *tcp; - - scpi = g_malloc(sizeof(struct sr_scpi_dev_inst)); - tcp = g_malloc0(sizeof(struct scpi_tcp)); - - tcp->address = g_strdup(address); - tcp->port = g_strdup(port); - tcp->socket = -1; - - scpi->open = scpi_tcp_open; - scpi->source_add = scpi_tcp_source_add; - scpi->source_remove = scpi_tcp_source_remove; - scpi->send = scpi_tcp_send; - scpi->read_begin = scpi_tcp_read_begin; - scpi->read_data = scpi_tcp_read_data; - scpi->read_complete = scpi_tcp_read_complete; - scpi->close = scpi_tcp_close; - scpi->free = scpi_tcp_free; - scpi->priv = tcp; - - return scpi; -} +SR_PRIV const struct sr_scpi_dev_inst scpi_tcp_dev = { + .name = "TCP", + .prefix = "tcp", + .priv_size = sizeof(struct scpi_tcp), + .dev_inst_new = scpi_tcp_dev_inst_new, + .open = scpi_tcp_open, + .source_add = scpi_tcp_source_add, + .source_remove = scpi_tcp_source_remove, + .send = scpi_tcp_send, + .read_begin = scpi_tcp_read_begin, + .read_data = scpi_tcp_read_data, + .read_complete = scpi_tcp_read_complete, + .close = scpi_tcp_close, + .free = scpi_tcp_free, +}; diff --git a/hardware/common/scpi_usbtmc.c b/hardware/common/scpi_usbtmc.c index dba1a2e3..c734890a 100644 --- a/hardware/common/scpi_usbtmc.c +++ b/hardware/common/scpi_usbtmc.c @@ -37,6 +37,20 @@ struct usbtmc_scpi { int response_bytes_read; }; +static int scpi_usbtmc_dev_inst_new(void *priv, const char *resource, + char **params, const char *serialcomm) +{ + struct usbtmc_scpi *uscpi = priv; + + (void)params; + (void)serialcomm; + + if (!(uscpi->usbtmc = sr_usbtmc_dev_inst_new(resource))) + return SR_ERR; + + return SR_OK; +} + SR_PRIV int scpi_usbtmc_open(void *priv) { struct usbtmc_scpi *uscpi = priv; @@ -147,9 +161,8 @@ SR_PRIV int scpi_usbtmc_read_complete(void *priv) SR_PRIV int scpi_usbtmc_close(void *priv) { struct usbtmc_scpi *uscpi = priv; - struct sr_usbtmc_dev_inst *usbtmc = uscpi->usbtmc; - if (close(usbtmc->fd) < 0) + if (close(uscpi->usbtmc->fd) < 0) return SR_ERR; return SR_OK; @@ -158,37 +171,22 @@ SR_PRIV int scpi_usbtmc_close(void *priv) static void scpi_usbtmc_free(void *priv) { struct usbtmc_scpi *uscpi = priv; - struct sr_usbtmc_dev_inst *usbtmc = uscpi->usbtmc; - g_free(uscpi); - sr_usbtmc_dev_inst_free(usbtmc); + sr_usbtmc_dev_inst_free(uscpi->usbtmc); } -SR_PRIV struct sr_scpi_dev_inst *scpi_usbtmc_dev_inst_new(const char *device) -{ - struct sr_scpi_dev_inst *scpi; - struct usbtmc_scpi *uscpi; - struct sr_usbtmc_dev_inst *usbtmc; - - if (!(usbtmc = sr_usbtmc_dev_inst_new(device))) - return NULL; - - uscpi = g_malloc(sizeof(struct usbtmc_scpi)); - - uscpi->usbtmc = usbtmc; - - scpi = g_malloc(sizeof(struct sr_scpi_dev_inst)); - - scpi->open = scpi_usbtmc_open; - scpi->source_add = scpi_usbtmc_source_add; - scpi->source_remove = scpi_usbtmc_source_remove; - scpi->send = scpi_usbtmc_send; - scpi->read_begin = scpi_usbtmc_read_begin; - scpi->read_data = scpi_usbtmc_read_data; - scpi->read_complete = scpi_usbtmc_read_complete; - scpi->close = scpi_usbtmc_close; - scpi->free = scpi_usbtmc_free; - scpi->priv = uscpi; - - return scpi; -} +SR_PRIV const struct sr_scpi_dev_inst scpi_usbtmc_dev = { + .name = "USBTMC", + .prefix = "/dev/usbtmc", + .priv_size = sizeof(struct usbtmc_scpi), + .dev_inst_new = scpi_usbtmc_dev_inst_new, + .open = scpi_usbtmc_open, + .source_add = scpi_usbtmc_source_add, + .source_remove = scpi_usbtmc_source_remove, + .send = scpi_usbtmc_send, + .read_begin = scpi_usbtmc_read_begin, + .read_data = scpi_usbtmc_read_data, + .read_complete = scpi_usbtmc_read_complete, + .close = scpi_usbtmc_close, + .free = scpi_usbtmc_free, +}; diff --git a/hardware/common/scpi_vxi.c b/hardware/common/scpi_vxi.c index 7648f3e7..4d713dce 100644 --- a/hardware/common/scpi_vxi.c +++ b/hardware/common/scpi_vxi.c @@ -37,6 +37,25 @@ struct scpi_vxi { unsigned int read_complete; }; +static int scpi_vxi_dev_inst_new(void *priv, const char *resource, + char **params, const char *serialcomm) +{ + struct scpi_vxi *vxi = priv; + + (void)resource; + (void)serialcomm; + + if (!params || !params[1]) { + sr_err("Invalid parameters."); + return SR_ERR; + } + + vxi->address = g_strdup(params[1]); + vxi->instrument = g_strdup(params[2] ? params[2] : "inst0"); + + return SR_OK; +} + static int scpi_vxi_open(void *priv) { struct scpi_vxi *vxi = priv; @@ -193,31 +212,20 @@ static void scpi_vxi_free(void *priv) g_free(vxi->address); g_free(vxi->instrument); - g_free(vxi); } -SR_PRIV struct sr_scpi_dev_inst *scpi_vxi_dev_inst_new(const char *address, - const char *instrument) -{ - struct sr_scpi_dev_inst *scpi; - struct scpi_vxi *vxi; - - scpi = g_malloc(sizeof(struct sr_scpi_dev_inst)); - vxi = g_malloc0(sizeof(struct scpi_vxi)); - - vxi->address = g_strdup(address); - vxi->instrument = g_strdup(instrument ? instrument : "inst0"); - - scpi->open = scpi_vxi_open; - scpi->source_add = scpi_vxi_source_add; - scpi->source_remove = scpi_vxi_source_remove; - scpi->send = scpi_vxi_send; - scpi->read_begin = scpi_vxi_read_begin; - scpi->read_data = scpi_vxi_read_data; - scpi->read_complete = scpi_vxi_read_complete; - scpi->close = scpi_vxi_close; - scpi->free = scpi_vxi_free; - scpi->priv = vxi; - - return scpi; -} +SR_PRIV const struct sr_scpi_dev_inst scpi_vxi_dev = { + .name = "VXI", + .prefix = "vxi", + .priv_size = sizeof(struct scpi_vxi), + .dev_inst_new = scpi_vxi_dev_inst_new, + .open = scpi_vxi_open, + .source_add = scpi_vxi_source_add, + .source_remove = scpi_vxi_source_remove, + .send = scpi_vxi_send, + .read_begin = scpi_vxi_read_begin, + .read_data = scpi_vxi_read_data, + .read_complete = scpi_vxi_read_complete, + .close = scpi_vxi_close, + .free = scpi_vxi_free, +}; diff --git a/libsigrok-internal.h b/libsigrok-internal.h index d72c4dc5..13ee2652 100644 --- a/libsigrok-internal.h +++ b/libsigrok-internal.h @@ -374,6 +374,11 @@ struct sr_scpi_hw_info { }; struct sr_scpi_dev_inst { + const char *name; + const char *prefix; + int priv_size; + int (*dev_inst_new)(void *priv, const char *resource, char **params, + const char *serialcomm); int (*open)(void *priv); int (*source_add)(void *priv, int events, int timeout, sr_receive_data_callback_t cb, void *cb_data); @@ -422,27 +427,6 @@ SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi, struct sr_scpi_hw_info **scpi_response); SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info); -/*--- hardware/common/scpi_vxi.c --------------------------------------------*/ - -SR_PRIV struct sr_scpi_dev_inst *scpi_vxi_dev_inst_new(const char *address, - const char *instrument); - -/*--- hardware/common/scpi_serial.c -----------------------------------------*/ - -#ifdef HAVE_LIBSERIALPORT -SR_PRIV struct sr_scpi_dev_inst *scpi_serial_dev_inst_new(const char *port, - const char *serialcomm); -#endif - -/*--- hardware/common/scpi_tcp.c --------------------------------------------*/ - -SR_PRIV struct sr_scpi_dev_inst *scpi_tcp_dev_inst_new(const char *address, - const char *port); - -/*--- hardware/common/scpi_usbtmc.c -----------------------------------------*/ - -SR_PRIV struct sr_scpi_dev_inst *scpi_usbtmc_dev_inst_new(const char *device); - /*--- hardware/common/dmm/es519xx.c -----------------------------------------*/ /**