#ifdef HAVE_SERIAL_COMM
-/* See if a (assumed opened) serial port is of any supported type. */
+/* See if an (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)
+ if (!serial || !serial->lib_funcs)
return 0;
return 1;
if (ret != SR_OK)
return ret;
- if (serial->serialcomm)
- return serial_set_paramstr(serial, serial->serialcomm);
- else
- return SR_OK;
+ if (serial->serialcomm) {
+ ret = serial_set_paramstr(serial, serial->serialcomm);
+ if (ret != SR_OK)
+ return ret;
+ }
+
+ /*
+ * Flush potentially dangling RX data. Availability of the
+ * flush primitive depends on the transport/cable, absense
+ * is non-fatal.
+ */
+ ret = serial_flush(serial);
+ if (ret == SR_ERR_NA)
+ ret = SR_OK;
+ if (ret != SR_OK)
+ return ret;
+
+ return SR_OK;
}
/**
* @retval SR_ERR_ARG Invalid parameters.
* @retval SR_OK Successful registration.
*
- * Callbacks get unregistered by specifying #NULL for the 'cb' parameter.
+ * Callbacks get unregistered by specifying NULL for the 'cb' parameter.
+ *
+ * @private
*/
SR_PRIV int serial_set_read_chunk_cb(struct sr_serial_dev_inst *serial,
serial_rx_chunk_callback cb, void *cb_data)
*
* @param[in] serial Previously opened serial port instance.
*
- * @internal
+ * @private
*/
SR_PRIV void sr_ser_discard_queued_data(struct sr_serial_dev_inst *serial)
{
- if (!serial)
- return;
- if (!serial->rcv_buffer)
+ if (!serial || !serial->rcv_buffer)
return;
g_string_truncate(serial->rcv_buffer, 0);
*
* @param[in] serial Previously opened serial port instance.
*
- * @internal
+ * @private
*/
SR_PRIV size_t sr_ser_has_queued_data(struct sr_serial_dev_inst *serial)
{
- if (!serial)
- return 0;
- if (!serial->rcv_buffer)
+ if (!serial || !serial->rcv_buffer)
return 0;
return serial->rcv_buffer->len;
* @param[in] data Pointer to data bytes to queue.
* @param[in] len Number of data bytes to queue.
*
- * @internal
+ * @private
*/
SR_PRIV void sr_ser_queue_rx_data(struct sr_serial_dev_inst *serial,
const uint8_t *data, size_t len)
{
- if (!serial)
- return;
- if (!data || !len)
+ if (!serial || !data || !len)
return;
if (serial->rx_chunk_cb_func)
* @param[out] data Pointer to store retrieved data bytes into.
* @param[in] len Number of data bytes to retrieve.
*
- * @internal
+ * @private
*/
SR_PRIV size_t sr_ser_unqueue_rx_data(struct sr_serial_dev_inst *serial,
uint8_t *data, size_t len)
size_t qlen;
GString *buf;
- if (!serial)
- return 0;
- if (!data || !len)
+ if (!serial || !data || !len)
return 0;
qlen = sr_ser_has_queued_data(serial);
*
* Returns 0 if no receive data is available, or if the amount of
* available receive data cannot get determined.
+ *
+ * @private
*/
SR_PRIV size_t serial_has_receive_data(struct sr_serial_dev_inst *serial)
{
return ret;
}
+/**
+ * Manipulate handshake state for the specified serial port.
+ *
+ * @param serial Previously initialized serial port structure.
+ * @param[in] rts Status of RTS line (0 or 1; or -1 to ignore).
+ * @param[in] dtr Status of DTR line (0 or 1; or -1 to ignore).
+ *
+ * @retval SR_OK Success.
+ * @retval SR_ERR Failure.
+ *
+ * @private
+ */
+SR_PRIV int serial_set_handshake(struct sr_serial_dev_inst *serial,
+ int rts, int dtr)
+{
+ int ret;
+
+ if (!serial) {
+ sr_dbg("Invalid serial port.");
+ return SR_ERR;
+ }
+
+ sr_spew("Modifying serial parameters on port %s.", serial->port);
+
+ if (!serial->lib_funcs || !serial->lib_funcs->set_handshake)
+ return SR_ERR_NA;
+ ret = serial->lib_funcs->set_handshake(serial, rts, dtr);
+
+ return ret;
+}
+
/**
* Set serial parameters for the specified serial port from parameter string.
*
const char *paramstr)
{
/** @cond PRIVATE */
-#define SERIAL_COMM_SPEC "^(\\d+)/([5678])([neo])([12])(.*)$"
+#define SERIAL_COMM_SPEC "^(\\d+)(/([5678])([neo])([12]))?(.*)$"
/** @endcond */
GRegex *reg;
int speed, databits, parity, stopbits, flow, rts, dtr, i;
char *mstr, **opts, **kv;
- speed = databits = parity = stopbits = flow = 0;
+ speed = flow = 0;
+ databits = 8;
+ parity = SP_PARITY_NONE;
+ stopbits = 1;
rts = dtr = -1;
sr_spew("Parsing parameters from \"%s\".", paramstr);
reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
if ((mstr = g_match_info_fetch(match, 1)))
speed = strtoul(mstr, NULL, 10);
g_free(mstr);
- if ((mstr = g_match_info_fetch(match, 2)))
+ if ((mstr = g_match_info_fetch(match, 3)) && mstr[0])
databits = strtoul(mstr, NULL, 10);
g_free(mstr);
- if ((mstr = g_match_info_fetch(match, 3))) {
+ if ((mstr = g_match_info_fetch(match, 4)) && mstr[0]) {
switch (mstr[0]) {
case 'n':
parity = SP_PARITY_NONE;
}
}
g_free(mstr);
- if ((mstr = g_match_info_fetch(match, 4)))
+ if ((mstr = g_match_info_fetch(match, 5)) && mstr[0])
stopbits = strtoul(mstr, NULL, 10);
g_free(mstr);
- if ((mstr = g_match_info_fetch(match, 5)) && mstr[0] != '\0') {
+ if ((mstr = g_match_info_fetch(match, 6)) && mstr[0] != '\0') {
if (mstr[0] != '/') {
sr_dbg("missing separator before extra options");
speed = 0;
}
g_match_info_unref(match);
g_regex_unref(reg);
+ sr_spew("Got params: rate %d, frame %d/%d/%d, flow %d, rts %d, dtr %d.",
+ speed, databits, parity, stopbits, flow, rts, dtr);
- if (speed) {
- return serial_set_params(serial, speed, databits, parity,
- stopbits, flow, rts, dtr);
- } else {
+ if (!speed) {
sr_dbg("Could not infer speed from parameter string.");
return SR_ERR_ARG;
}
+
+ return serial_set_params(serial, speed,
+ databits, parity, stopbits,
+ flow, rts, dtr);
}
/**
* @param is_valid Callback that assesses whether the packet is valid or not.
* @param[in] timeout_ms The timeout after which, if no packet is detected, to
* abort scanning.
- * @param[in] baudrate The baudrate of the serial port. This parameter is not
- * critical, but it helps fine tune the serial port polling
- * delay.
*
* @retval SR_OK Valid packet was found within the given timeout.
* @retval SR_ERR Failure.
uint8_t *buf, size_t *buflen,
size_t packet_size,
packet_valid_callback is_valid,
- uint64_t timeout_ms, int baudrate)
+ uint64_t timeout_ms)
{
uint64_t start, time, byte_delay_us;
size_t ibuf, i, maxlen;
maxlen = *buflen;
- sr_dbg("Detecting packets on %s (timeout = %" PRIu64
- "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);
+ sr_dbg("Detecting packets on %s (timeout = %" PRIu64 "ms).",
+ serial->port, timeout_ms);
- if (maxlen < (packet_size / 2) ) {
+ if (maxlen < (packet_size * 2) ) {
sr_err("Buffer size must be at least twice the packet size.");
return SR_ERR;
}
/* Assume 8n1 transmission. That is 10 bits for every byte. */
- byte_delay_us = 10 * ((1000 * 1000) / baudrate);
+ byte_delay_us = serial_timeout(serial, 1) * 1000;
start = g_get_monotonic_time();
i = ibuf = len = 0;
*buflen = ibuf;
- sr_err("Didn't find a valid packet (read %zu bytes).", *buflen);
+ sr_info("Didn't find a valid packet (read %zu bytes).", *buflen);
return SR_ERR;
}
/** @private */
SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes)
{
- int bits, baud;
- int ret;
- int timeout_ms;
+ int bits, baud, ret, timeout_ms;
/* Get the bitrate and frame length. */
bits = baud = 0;