sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
- sp_get_port_by_name(serial->port, &serial->data);
+ sp_get_port_by_name(serial->port, &serial->sp_data);
if (flags & SERIAL_RDWR)
sp_flags = (SP_MODE_READ | SP_MODE_WRITE);
else if (flags & SERIAL_RDONLY)
sp_flags = SP_MODE_READ;
- ret = sp_open(serial->data, sp_flags);
+ ret = sp_open(serial->sp_data, sp_flags);
switch (ret) {
case SP_ERR_ARG:
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot close unopened serial port %s.", serial->port);
return SR_ERR;
}
sr_spew("Closing serial port %s.", serial->port);
- ret = sp_close(serial->data);
+ ret = sp_close(serial->sp_data);
switch (ret) {
case SP_ERR_ARG:
return SR_ERR;
}
- sp_free_port(serial->data);
- serial->data = NULL;
+ sp_free_port(serial->sp_data);
+ serial->sp_data = NULL;
return SR_OK;
}
/**
- * Flush serial port buffers.
+ * Flush serial port buffers. Empty buffers, discard pending RX and TX data.
*
* @param serial Previously initialized serial port structure.
*
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot flush unopened serial port %s.", serial->port);
return SR_ERR;
}
sr_spew("Flushing serial port %s.", serial->port);
- ret = sp_flush(serial->data, SP_BUF_BOTH);
+ ret = sp_flush(serial->sp_data, SP_BUF_BOTH);
switch (ret) {
case SP_ERR_ARG:
}
/**
- * Drain serial port buffers.
+ * Drain serial port buffers. Wait for pending TX data to be sent.
*
* @param serial Previously initialized serial port structure.
*
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot drain unopened serial port %s.", serial->port);
return SR_ERR;
}
sr_spew("Draining serial port %s.", serial->port);
- ret = sp_drain(serial->data);
+ ret = sp_drain(serial->sp_data);
if (ret == SP_ERR_FAIL) {
error = sp_last_error_message();
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot use unopened serial port %s.", serial->port);
return SR_ERR;
}
if (nonblocking)
- ret = sp_nonblocking_write(serial->data, buf, count);
+ ret = sp_nonblocking_write(serial->sp_data, buf, count);
else
- ret = sp_blocking_write(serial->data, buf, count, timeout_ms);
+ ret = sp_blocking_write(serial->sp_data, buf, count, timeout_ms);
switch (ret) {
case SP_ERR_ARG:
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot use unopened serial port %s.", serial->port);
return SR_ERR;
}
if (nonblocking)
- ret = sp_nonblocking_read(serial->data, buf, count);
+ ret = sp_nonblocking_read(serial->sp_data, buf, count);
else
- ret = sp_blocking_read(serial->data, buf, count, timeout_ms);
+ ret = sp_blocking_read(serial->sp_data, buf, count, timeout_ms);
switch (ret) {
case SP_ERR_ARG:
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot configure unopened serial port %s.", serial->port);
return SR_ERR;
}
sp_set_config_dsr(config, SP_DSR_IGNORE);
sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED);
- ret = sp_set_config(serial->data, config);
+ ret = sp_set_config(serial->sp_data, config);
sp_free_config(config);
switch (ret) {
return SR_ERR;
}
+ serial->comm_params.bit_rate = baudrate;
+ serial->comm_params.data_bits = bits;
+ serial->comm_params.parity_bits = parity ? 1 : 0;
+ serial->comm_params.stop_bits = stopbits;
+ sr_dbg("DBG: %s() rate %d, %d%s%d", __func__,
+ baudrate, bits,
+ (parity == 0) ? "n" : "x",
+ stopbits);
+
return SR_OK;
}
/**
* Read a line from the specified serial port.
*
- * @param serial Previously initialized serial port structure.
- * @param buf Buffer where to store the bytes that are read.
- * @param buflen Size of the buffer.
+ * @param[in] serial Previously initialized serial port structure.
+ * @param[out] buf Buffer where to store the bytes that are read.
+ * @param[in] buflen Size of the buffer.
* @param[in] timeout_ms How long to wait for a line to come in.
*
- * Reading stops when CR of LR is found, which is stripped from the buffer.
+ * Reading stops when CR or LF is found, which is stripped from the buffer.
*
* @retval SR_OK Success.
* @retval SR_ERR Failure.
return SR_ERR;
}
- if (!serial->data) {
+ if (!serial->sp_data) {
sr_dbg("Cannot use unopened serial port %s.", serial->port);
return -1;
}
len = maxlen - *buflen - 1;
if (len < 1)
break;
- len = sp_blocking_read(serial->data, *buf + *buflen, 1, remaining);
+ len = sp_blocking_read(serial->sp_data, *buf + *buflen, 1, remaining);
if (len > 0) {
*buflen += len;
*(*buf + *buflen) = '\0';
time /= 1000;
if ((ibuf - i) >= packet_size) {
+ GString *text;
/* We have at least a packet's worth of data. */
+ text = sr_hexdump_new(&buf[i], packet_size);
+ sr_spew("Trying packet: %s", text->str);
+ sr_hexdump_free(text);
if (is_valid(&buf[i])) {
sr_spew("Found valid %zu-byte packet after "
"%" PRIu64 "ms.", (ibuf - i), time);
if (events & G_IO_ERR)
mask |= SP_EVENT_ERROR;
- if (sp_add_port_events(event_set, serial->data, mask) != SP_OK) {
+ if (sp_add_port_events(event_set, serial->sp_data, mask) != SP_OK) {
sp_free_event_set(event_set);
return SR_ERR;
}
if (mask & SP_EVENT_ERROR)
poll_events |= G_IO_ERR;
/*
- * Using serial->data as the key for the event source is not quite
+ * Using serial->sp_data as the key for the event source is not quite
* proper, as it makes it impossible to create another event source
* for the same serial port. However, these fixed keys will soon be
* removed from the API anyway, so this is OK for now.
*/
- return sr_session_fd_source_add(session, serial->data,
+ return sr_session_fd_source_add(session, serial->sp_data,
poll_fd, poll_events, timeout, cb, cb_data);
}
SR_PRIV int serial_source_remove(struct sr_session *session,
struct sr_serial_dev_inst *serial)
{
- return sr_session_source_remove_internal(session, serial->data);
+ return sr_session_source_remove_internal(session, serial->sp_data);
}
/**
if (!name)
return NULL;
- serial = g_malloc(sizeof(struct sr_serial_port));
+ serial = g_malloc0(sizeof(*serial));
serial->name = g_strdup(name);
serial->description = g_strdup(description ? description : "");
if (sp_new_config(&config) < 0)
return timeout_ms;
+ /* Get the bitrate and frame length. */
bits = baud = 0;
do {
- if (sp_get_config(port->data, config) < 0)
+ if (sp_get_config(port->sp_data, config) < 0)
break;
/* Start bit. */
break;
baud = tmp;
} while (FALSE);
+ if (!bits || !baud) {
+ baud = port->comm_params.bit_rate;
+ bits = 1 + port->comm_params.data_bits +
+ port->comm_params.parity_bits +
+ port->comm_params.stop_bits;
+ }
+ /* Derive the timeout. */
if (bits && baud) {
/* Throw in 10ms for misc OS overhead. */
timeout_ms = 10;