#endif
#ifdef HAVE_LIBSERIALPORT
+struct ser_lib_functions;
struct sr_serial_dev_inst {
/** Port name, e.g. '/dev/tty42'. */
char *port;
/** Comm params for serial_set_paramstr(). */
char *serialcomm;
+ struct ser_lib_functions *lib_funcs;
struct {
int bit_rate;
int data_bits;
int parity_bits;
int stop_bits;
} comm_params;
+#ifdef HAVE_LIBSERIALPORT
/** libserialport port handle */
struct sp_port *sp_data;
+#endif
};
#endif
SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id);
SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes);
-SR_PRIV int sr_ser_libsp_open(struct sr_serial_dev_inst *serial, int flags);
-SR_PRIV int sr_ser_libsp_close(struct sr_serial_dev_inst *serial);
-SR_PRIV int sr_ser_libsp_flush(struct sr_serial_dev_inst *serial);
-SR_PRIV int sr_ser_libsp_drain(struct sr_serial_dev_inst *serial);
-SR_PRIV int sr_ser_libsp_write(struct sr_serial_dev_inst *serial,
- const void *buf, size_t count,
- int nonblocking, unsigned int timeout_ms);
-SR_PRIV int sr_ser_libsp_read(struct sr_serial_dev_inst *serial,
- void *buf, size_t count,
- int nonblocking, unsigned int timeout_ms);
-SR_PRIV int sr_ser_libsp_set_params(struct sr_serial_dev_inst *serial,
- int baudrate, int bits, int parity, int stopbits,
- int flowcontrol, int rts, int dtr);
-SR_PRIV int sr_ser_libsp_source_add(struct sr_session *session,
- struct sr_serial_dev_inst *serial,
- int events, int timeout,
- sr_receive_data_callback cb, void *cb_data);
-SR_PRIV int sr_ser_libsp_source_remove(struct sr_session *session,
- struct sr_serial_dev_inst *serial);
-SR_PRIV GSList *sr_ser_libsp_list(GSList *list, sr_ser_list_append_t append);
-SR_PRIV GSList *sr_ser_libsp_find_usb(GSList *list, sr_ser_find_append_t append,
- uint16_t vendor_id, uint16_t product_id);
-SR_PRIV int sr_ser_libsp_get_frame_format(struct sr_serial_dev_inst *serial,
- int *baud, int *bits);
-SR_PRIV size_t sr_ser_libsp_get_rx_avail(struct sr_serial_dev_inst *serial);
+struct ser_lib_functions {
+ int (*open)(struct sr_serial_dev_inst *serial, int flags);
+ int (*close)(struct sr_serial_dev_inst *serial);
+ int (*flush)(struct sr_serial_dev_inst *serial);
+ int (*drain)(struct sr_serial_dev_inst *serial);
+ int (*write)(struct sr_serial_dev_inst *serial,
+ const void *buf, size_t count,
+ int nonblocking, unsigned int timeout_ms);
+ int (*read)(struct sr_serial_dev_inst *serial,
+ void *buf, size_t count,
+ int nonblocking, unsigned int timeout_ms);
+ int (*set_params)(struct sr_serial_dev_inst *serial,
+ int baudrate, int bits, int parity, int stopbits,
+ int flowcontrol, int rts, int dtr);
+ int (*setup_source_add)(struct sr_session *session,
+ struct sr_serial_dev_inst *serial,
+ int events, int timeout,
+ sr_receive_data_callback cb, void *cb_data);
+ int (*setup_source_remove)(struct sr_session *session,
+ struct sr_serial_dev_inst *serial);
+ GSList *(*list)(GSList *list, sr_ser_list_append_t append);
+ GSList *(*find_usb)(GSList *list, sr_ser_find_append_t append,
+ uint16_t vendor_id, uint16_t product_id);
+ int (*get_frame_format)(struct sr_serial_dev_inst *serial,
+ int *baud, int *bits);
+ size_t (*get_rx_avail)(struct sr_serial_dev_inst *serial);
+};
+extern SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp;
#endif
/*--- ezusb.c ---------------------------------------------------------------*/
* @{
*/
+/* See if a (assumed opened) serial port is of any supported type. */
+static int dev_is_supported(struct sr_serial_dev_inst *serial)
+{
+ if (!serial)
+ return 0;
+ if (!serial->lib_funcs)
+ return 0;
+
+ return 1;
+}
+
/**
* Open the specified serial port.
*
sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
- ret = sr_ser_libsp_open(serial, flags);
+ /* Default to the libserialport transport layer. */
+ serial->lib_funcs = ser_lib_funcs_libsp;
+ if (!serial->lib_funcs)
+ return SR_ERR_NA;
+
+ /*
+ * Run the transport's open routine. Setup the bitrate and the
+ * UART frame format.
+ */
+ if (!serial->lib_funcs->open)
+ return SR_ERR_NA;
+ ret = serial->lib_funcs->open(serial, flags);
if (ret != SR_OK)
return ret;
sr_spew("Closing serial port %s.", serial->port);
- return sr_ser_libsp_close(serial);
+ if (!serial->lib_funcs || !serial->lib_funcs->close)
+ return SR_ERR_NA;
+
+ return serial->lib_funcs->close(serial);
}
/**
sr_spew("Flushing serial port %s.", serial->port);
- return sr_ser_libsp_flush(serial);
+ if (!serial->lib_funcs || !serial->lib_funcs->flush)
+ return SR_ERR_NA;
+
+ return serial->lib_funcs->flush(serial);
}
/**
sr_spew("Draining serial port %s.", serial->port);
- return sr_ser_libsp_drain(serial);
+ if (!serial->lib_funcs || !serial->lib_funcs->drain)
+ return SR_ERR_NA;
+
+ return serial->lib_funcs->drain(serial);
}
/**
*/
SR_PRIV size_t serial_has_receive_data(struct sr_serial_dev_inst *serial)
{
- return sr_ser_libsp_get_rx_avail(serial);
+ size_t lib_count;
+
+ if (!serial)
+ return 0;
+
+ lib_count = 0;
+ if (serial->lib_funcs && serial->lib_funcs->get_rx_avail)
+ lib_count = serial->lib_funcs->get_rx_avail(serial);
+
+ return lib_count;
}
static int _serial_write(struct sr_serial_dev_inst *serial,
return SR_ERR;
}
- ret = sr_ser_libsp_write(serial, buf, count, nonblocking, timeout_ms);
+ if (!serial->lib_funcs || !serial->lib_funcs->write)
+ return SR_ERR_NA;
+ ret = serial->lib_funcs->write(serial, buf, count,
+ nonblocking, timeout_ms);
sr_spew("Wrote %zd/%zu bytes.", ret, count);
return ret;
return SR_ERR;
}
- ret = sr_ser_libsp_read(serial, buf, count, nonblocking, timeout_ms);
+ if (!serial->lib_funcs || !serial->lib_funcs->read)
+ return SR_ERR_NA;
+ ret = serial->lib_funcs->read(serial, buf, count,
+ nonblocking, timeout_ms);
if (ret > 0)
sr_spew("Read %zd/%zu bytes.", ret, count);
sr_spew("Setting serial parameters on port %s.", serial->port);
- ret = sr_ser_libsp_set_params(serial,
- baudrate, bits, parity, stopbits, flowcontrol, rts, dtr);
+ if (!serial->lib_funcs || !serial->lib_funcs->set_params)
+ return SR_ERR_NA;
+ ret = serial->lib_funcs->set_params(serial,
+ baudrate, bits, parity, stopbits,
+ flowcontrol, rts, dtr);
if (ret == SR_OK) {
serial->comm_params.bit_rate = baudrate;
serial->comm_params.data_bits = bits;
return SR_ERR;
}
- if (!serial->sp_data) {
+ if (!dev_is_supported(serial)) {
sr_dbg("Cannot use unopened serial port %s.", serial->port);
return -1;
}
return SR_ERR_ARG;
}
- if (!serial->sp_data) {
+ if (!dev_is_supported(serial)) {
sr_err("Invalid serial port.");
return SR_ERR_ARG;
}
- return sr_ser_libsp_source_add(session, serial,
+ if (!serial->lib_funcs || !serial->lib_funcs->setup_source_add)
+ return SR_ERR_NA;
+
+ return serial->lib_funcs->setup_source_add(session, serial,
events, timeout, cb, cb_data);
}
SR_PRIV int serial_source_remove(struct sr_session *session,
struct sr_serial_dev_inst *serial)
{
- if (!serial->sp_data) {
+ if (!dev_is_supported(serial)) {
sr_err("Invalid serial port.");
return SR_ERR_ARG;
}
- return sr_ser_libsp_source_remove(session, serial);
+ if (!serial->lib_funcs || !serial->lib_funcs->setup_source_remove)
+ return SR_ERR_NA;
+
+ return serial->lib_funcs->setup_source_remove(session, serial);
}
/**
SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver)
{
GSList *tty_devs;
+ GSList *(*list_func)(GSList *list, sr_ser_list_append_t append);
/* Currently unused, but will be used by some drivers later on. */
(void)driver;
tty_devs = NULL;
- tty_devs = sr_ser_libsp_list(tty_devs, append_port_list);
+ if (ser_lib_funcs_libsp && ser_lib_funcs_libsp->list) {
+ list_func = ser_lib_funcs_libsp->list;
+ tty_devs = list_func(tty_devs, append_port_list);
+ }
return tty_devs;
}
SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
{
GSList *tty_devs;
+ GSList *(*find_func)(GSList *list, sr_ser_find_append_t append,
+ uint16_t vid, uint16_t pid);
tty_devs = NULL;
- tty_devs = sr_ser_libsp_find_usb(tty_devs, append_port_find,
- vendor_id, product_id);
+ if (ser_lib_funcs_libsp && ser_lib_funcs_libsp->find_usb) {
+ find_func = ser_lib_funcs_libsp->find_usb;
+ tty_devs = find_func(tty_devs, append_port_find,
+ vendor_id, product_id);
+ }
return tty_devs;
}
/* Get the bitrate and frame length. */
bits = baud = 0;
- ret = sr_ser_libsp_get_frame_format(port, &baud, &bits);
- if (ret != SR_OK)
- bits = baud = 0;
- if (!bits || !baud) {
+ if (port->lib_funcs && port->lib_funcs->get_frame_format) {
+ ret = port->lib_funcs->get_frame_format(port, &baud, &bits);
+ if (ret != SR_OK)
+ bits = baud = 0;
+ } else {
baud = port->comm_params.bit_rate;
bits = 1 + port->comm_params.data_bits +
port->comm_params.parity_bits +
* Serial port handling, wraps the external libserialport dependency.
*/
+#ifdef HAVE_LIBSERIALPORT
+
/**
* @defgroup grp_serial_libsp Serial port handling, libserialport group
*
* @{
*/
-SR_PRIV int sr_ser_libsp_open(struct sr_serial_dev_inst *serial, int flags)
+static int sr_ser_libsp_open(struct sr_serial_dev_inst *serial, int flags)
{
int ret;
char *error;
return SR_OK;
}
-SR_PRIV int sr_ser_libsp_close(struct sr_serial_dev_inst *serial)
+static int sr_ser_libsp_close(struct sr_serial_dev_inst *serial)
{
int ret;
char *error;
return SR_OK;
}
-SR_PRIV int sr_ser_libsp_flush(struct sr_serial_dev_inst *serial)
+static int sr_ser_libsp_flush(struct sr_serial_dev_inst *serial)
{
int ret;
char *error;
return SR_OK;
}
-SR_PRIV int sr_ser_libsp_drain(struct sr_serial_dev_inst *serial)
+static int sr_ser_libsp_drain(struct sr_serial_dev_inst *serial)
{
int ret;
char *error;
return SR_OK;
}
-SR_PRIV int sr_ser_libsp_write(struct sr_serial_dev_inst *serial,
+static int sr_ser_libsp_write(struct sr_serial_dev_inst *serial,
const void *buf, size_t count,
int nonblocking, unsigned int timeout_ms)
{
return ret;
}
-SR_PRIV int sr_ser_libsp_read(struct sr_serial_dev_inst *serial,
+static int sr_ser_libsp_read(struct sr_serial_dev_inst *serial,
void *buf, size_t count,
int nonblocking, unsigned int timeout_ms)
{
return ret;
}
-SR_PRIV int sr_ser_libsp_set_params(struct sr_serial_dev_inst *serial,
+static int sr_ser_libsp_set_params(struct sr_serial_dev_inst *serial,
int baudrate, int bits, int parity, int stopbits,
int flowcontrol, int rts, int dtr)
{
return SR_OK;
}
-SR_PRIV int sr_ser_libsp_source_add(struct sr_session *session,
+static int sr_ser_libsp_source_add(struct sr_session *session,
struct sr_serial_dev_inst *serial, int events, int timeout,
sr_receive_data_callback cb, void *cb_data)
{
timeout, cb, cb_data);
}
-SR_PRIV int sr_ser_libsp_source_remove(struct sr_session *session,
+static int sr_ser_libsp_source_remove(struct sr_session *session,
struct sr_serial_dev_inst *serial)
{
void *key;
return sr_session_source_remove_internal(session, key);
}
-SR_PRIV GSList *sr_ser_libsp_list(GSList *list, sr_ser_list_append_t append)
+static GSList *sr_ser_libsp_list(GSList *list, sr_ser_list_append_t append)
{
struct sp_port **ports;
size_t i;
return list;
}
-SR_PRIV GSList *sr_ser_libsp_find_usb(GSList *list, sr_ser_find_append_t append,
+static GSList *sr_ser_libsp_find_usb(GSList *list, sr_ser_find_append_t append,
uint16_t vendor_id, uint16_t product_id)
{
struct sp_port **ports;
return list;
}
-SR_PRIV int sr_ser_libsp_get_frame_format(struct sr_serial_dev_inst *serial,
+static int sr_ser_libsp_get_frame_format(struct sr_serial_dev_inst *serial,
int *baud, int *bits)
{
struct sp_port_config *config;
return ret;
}
-SR_PRIV size_t sr_ser_libsp_get_rx_avail(struct sr_serial_dev_inst *serial)
+static size_t sr_ser_libsp_get_rx_avail(struct sr_serial_dev_inst *serial)
{
int rc;
return rc;
}
+
+static struct ser_lib_functions serlib_sp = {
+ .open = sr_ser_libsp_open,
+ .close = sr_ser_libsp_close,
+ .flush = sr_ser_libsp_flush,
+ .drain = sr_ser_libsp_drain,
+ .write = sr_ser_libsp_write,
+ .read = sr_ser_libsp_read,
+ .set_params = sr_ser_libsp_set_params,
+ .setup_source_add = sr_ser_libsp_source_add,
+ .setup_source_remove = sr_ser_libsp_source_remove,
+ .list = sr_ser_libsp_list,
+ .find_usb = sr_ser_libsp_find_usb,
+ .get_frame_format = sr_ser_libsp_get_frame_format,
+ .get_rx_avail = sr_ser_libsp_get_rx_avail,
+};
+SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp = &serlib_sp;
+
+#else
+
+SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp = NULL;
+
+#endif