X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fserial.c;h=d9c611bd1164e401a16fc554fc3e29d7304f3eda;hb=0c536bcd004aa4b4f0ba9673b4d460551e8b16c1;hp=883bf27a020b26e6204aad3a27308142500a4921;hpb=24287ea9e3dd0c6f7fc2299eaf725346b8c1fea2;p=libsigrok.git diff --git a/src/serial.c b/src/serial.c index 883bf27a..d9c611bd 100644 --- a/src/serial.c +++ b/src/serial.c @@ -25,10 +25,29 @@ #include #include #include -#include "libsigrok.h" +#include #include "libsigrok-internal.h" +#ifdef G_OS_WIN32 +#include /* for HANDLE */ +#endif +/** @cond PRIVATE */ #define LOG_PREFIX "serial" +/** @endcond */ + +/** + * @file + * + * Serial port handling. + */ + +/** + * @defgroup grp_serial Serial port handling + * + * Serial port handling functions. + * + * @{ + */ /** * Open the specified serial port. @@ -42,6 +61,8 @@ * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags) { @@ -90,6 +111,8 @@ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags) * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_close(struct sr_serial_dev_inst *serial) { @@ -135,6 +158,8 @@ SR_PRIV int serial_close(struct sr_serial_dev_inst *serial) * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial) { @@ -177,6 +202,8 @@ SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial) * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_drain(struct sr_serial_dev_inst *serial) { @@ -240,7 +267,7 @@ static int _serial_write(struct sr_serial_dev_inst *serial, return SR_ERR; } - sr_spew("Wrote %d/%d bytes.", ret, count); + sr_spew("Wrote %zd/%zu bytes.", ret, count); return ret; } @@ -257,6 +284,8 @@ static int _serial_write(struct sr_serial_dev_inst *serial, * @retval SR_ERR Other error. * @retval other The number of bytes written. If this is less than the number * specified in the call, the timeout was reached. + * + * @private */ SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial, const void *buf, size_t count, unsigned int timeout_ms) @@ -274,7 +303,9 @@ SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial, * @retval SR_ERR_ARG Invalid argument. * @retval SR_ERR Other error. * @retval other The number of bytes written. -*/ + * + * @private + */ SR_PRIV int serial_write_nonblocking(struct sr_serial_dev_inst *serial, const void *buf, size_t count) { @@ -314,7 +345,7 @@ static int _serial_read(struct sr_serial_dev_inst *serial, void *buf, } if (ret > 0) - sr_spew("Read %d/%d bytes.", ret, count); + sr_spew("Read %zd/%zu bytes.", ret, count); return ret; } @@ -331,6 +362,8 @@ static int _serial_read(struct sr_serial_dev_inst *serial, void *buf, * @retval SR_ERR Other error. * @retval other The number of bytes read. If this is less than the number * requested, the timeout was reached. + * + * @private */ SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf, size_t count, unsigned int timeout_ms) @@ -349,6 +382,8 @@ SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf, * @retval SR_ERR_ARG Invalid argument. * @retval SR_ERR Other error. * @retval other The number of bytes read. + * + * @private */ SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf, size_t count) @@ -371,6 +406,8 @@ SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate, int bits, int parity, int stopbits, @@ -450,13 +487,18 @@ SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate, * rts=0|1 Set RTS off resp. on.\n * Please note that values and combinations of these parameters must be * supported by the concrete serial interface hardware and the drivers for it. + * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial, const char *paramstr) { +/** @cond PRIVATE */ #define SERIAL_COMM_SPEC "^(\\d+)/([5678])([neo])([12])(.*)$" +/** @endcond */ GRegex *reg; GMatchInfo *match; @@ -561,6 +603,8 @@ SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial, * * @retval SR_OK Success. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf, int *buflen, gint64 timeout_ms) @@ -583,7 +627,7 @@ SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf, maxlen = *buflen; *buflen = len = 0; - while(1) { + while (1) { len = maxlen - *buflen - 1; if (len < 1) break; @@ -628,6 +672,8 @@ SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf, * * @retval SR_OK Valid packet was found within the given timeout. * @retval SR_ERR Failure. + * + * @private */ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, uint8_t *buf, size_t *buflen, @@ -637,7 +683,7 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, { uint64_t start, time, byte_delay_us; size_t ibuf, i, maxlen; - int len; + ssize_t len; maxlen = *buflen; @@ -650,7 +696,7 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, } /* Assume 8n1 transmission. That is 10 bits for every byte. */ - byte_delay_us = 10 * (1000000 / baudrate); + byte_delay_us = 10 * ((1000 * 1000) / baudrate); start = g_get_monotonic_time(); i = ibuf = len = 0; @@ -670,12 +716,12 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, if ((ibuf - i) >= packet_size) { /* We have at least a packet's worth of data. */ if (is_valid(&buf[i])) { - sr_spew("Found valid %d-byte packet after " + sr_spew("Found valid %zu-byte packet after " "%" PRIu64 "ms.", (ibuf - i), time); *buflen = ibuf; return SR_OK; } else { - sr_spew("Got %d bytes, but not a valid " + sr_spew("Got %zu bytes, but not a valid " "packet.", (ibuf - i)); } /* Not a valid packet. Continue searching. */ @@ -683,7 +729,7 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, } if (time >= timeout_ms) { /* Timeout */ - sr_dbg("Detection timed out after %dms.", time); + sr_dbg("Detection timed out after %" PRIu64 "ms.", time); break; } if (len < 1) @@ -692,7 +738,7 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, *buflen = ibuf; - sr_err("Didn't find a valid packet (read %d bytes).", *buflen); + sr_err("Didn't find a valid packet (read %zu bytes).", *buflen); return SR_ERR; } @@ -701,12 +747,14 @@ SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial, * Extract the serial device and options from the options linked list. * * @param options List of options passed from the command line. - * @param serial_device Pointer where to store the exctracted serial device. + * @param serial_device Pointer where to store the extracted serial device. * @param serial_options Pointer where to store the optional extracted serial * options. * * @return SR_OK if a serial_device is found, SR_ERR if no device is found. The * returned string should not be freed by the caller. + * + * @private */ SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_device, const char **serial_options) @@ -721,30 +769,32 @@ SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_devic switch (src->key) { case SR_CONF_CONN: *serial_device = g_variant_get_string(src->data, NULL); - sr_dbg("Parsed serial device: %s", *serial_device); + sr_dbg("Parsed serial device: %s.", *serial_device); break; - case SR_CONF_SERIALCOMM: *serial_options = g_variant_get_string(src->data, NULL); - sr_dbg("Parsed serial options: %s", *serial_options); + sr_dbg("Parsed serial options: %s.", *serial_options); break; } } if (!*serial_device) { - sr_dbg("No serial device specified"); + sr_dbg("No serial device specified."); return SR_ERR; } return SR_OK; } -#ifdef _WIN32 +/** @cond PRIVATE */ +#ifdef G_OS_WIN32 typedef HANDLE event_handle; #else typedef int event_handle; #endif +/** @endcond */ +/** @private */ SR_PRIV int serial_source_add(struct sr_session *session, struct sr_serial_dev_inst *serial, int events, int timeout, sr_receive_data_callback cb, void *cb_data) @@ -767,12 +817,12 @@ SR_PRIV int serial_source_add(struct sr_session *session, return SR_ERR; } - serial->pollfds = (GPollFD *) g_malloc0(sizeof(GPollFD) * serial->event_set->count); + serial->pollfds = g_new0(GPollFD, serial->event_set->count); for (i = 0; i < serial->event_set->count; i++) { - serial->pollfds[i].fd = ((event_handle *) serial->event_set->handles)[i]; - + serial->pollfds[i].fd = (gintptr) + ((event_handle *)serial->event_set->handles)[i]; mask = serial->event_set->masks[i]; if (mask & SP_EVENT_RX_READY) @@ -790,11 +840,15 @@ SR_PRIV int serial_source_add(struct sr_session *session, return SR_OK; } +/** @private */ SR_PRIV int serial_source_remove(struct sr_session *session, struct sr_serial_dev_inst *serial) { unsigned int i; + if (!serial->event_set) + return SR_OK; + for (i = 0; i < serial->event_set->count; i++) if (sr_session_source_remove_pollfd(session, &serial->pollfds[i]) != SR_OK) return SR_ERR; @@ -808,6 +862,16 @@ SR_PRIV int serial_source_remove(struct sr_session *session, return SR_OK; } +/** + * Create/allocate a new sr_serial_port structure. + * + * @param name The OS dependent name of the serial port. Must not be NULL. + * @param description An end user friendly description for the serial port. + * Can be NULL (in that case the empty string is used + * as description). + * + * @return The newly allocated sr_serial_port struct. + */ static struct sr_serial_port *sr_serial_new(const char *name, const char *description) { @@ -816,15 +880,21 @@ static struct sr_serial_port *sr_serial_new(const char *name, if (!name) return NULL; - serial = g_malloc(sizeof(*serial)); + serial = g_malloc(sizeof(struct sr_serial_port)); serial->name = g_strdup(name); serial->description = g_strdup(description ? description : ""); + return serial; } +/** + * Free a previously allocated sr_serial_port structure. + * + * @param serial The sr_serial_port struct to free. Must not be NULL. + */ SR_API void sr_serial_free(struct sr_serial_port *serial) { - if (serial == NULL) + if (!serial) return; g_free(serial->name); g_free(serial->description); @@ -842,20 +912,23 @@ SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver) { GSList *tty_devs = NULL; struct sp_port **ports; + struct sr_serial_port *port; int i; + /* Currently unused, but will be used by some drivers later on. */ (void)driver; if (sp_list_ports(&ports) != SP_OK) return NULL; - for (i=0; ports[i]; i++) { - struct sr_serial_port *port = sr_serial_new(sp_get_port_name(ports[i]), - sp_get_port_description(ports[i])); + for (i = 0; ports[i]; i++) { + port = sr_serial_new(sp_get_port_name(ports[i]), + sp_get_port_description(ports[i])); tty_devs = g_slist_append(tty_devs, port); } sp_free_port_list(ports); + return tty_devs; } @@ -868,6 +941,8 @@ SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver) * @return A GSList of strings containing the path of the serial device or * NULL if no serial device is found. The returned list must be freed * by the caller. + * + * @private */ SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id) { @@ -878,17 +953,20 @@ SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id) if (sp_list_ports(&ports) != SP_OK) return NULL; - for (i=0; ports[i]; i++) + for (i = 0; ports[i]; i++) if (sp_get_port_transport(ports[i]) == SP_TRANSPORT_USB && sp_get_port_usb_vid_pid(ports[i], &vid, &pid) == SP_OK && - vid == vendor_id && pid == product_id) + vid == vendor_id && pid == product_id) { tty_devs = g_slist_prepend(tty_devs, - g_strdup(sp_get_port_name(ports[i]))); + g_strdup(sp_get_port_name(ports[i]))); + } sp_free_port_list(ports); + return tty_devs; } +/** @private */ SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes) { struct sp_port_config *config; @@ -928,3 +1006,5 @@ SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes) return timeout_ms; } + +/** @} */