Exemple #1
0
/**
 * Set serial parameters for the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param[in] baudrate The baudrate to set.
 * @param[in] bits The number of data bits to use (5, 6, 7 or 8).
 * @param[in] parity The parity setting to use (0 = none, 1 = even, 2 = odd).
 * @param[in] stopbits The number of stop bits to use (1 or 2).
 * @param[in] flowcontrol The flow control settings to use (0 = none,
 *                      1 = RTS/CTS, 2 = XON/XOFF).
 * @param[in] rts Status of RTS line (0 or 1; required by some interfaces).
 * @param[in] dtr Status of DTR line (0 or 1; required by some interfaces).
 *
 * @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,
			      int flowcontrol, int rts, int dtr)
{
	int ret;
	char *error;
	struct sp_port_config *config;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->data) {
		sr_dbg("Cannot configure unopened serial port %s.", serial->port);
		return SR_ERR;
	}

	sr_spew("Setting serial parameters on port %s.", serial->port);

	sp_new_config(&config);
	sp_set_config_baudrate(config, baudrate);
	sp_set_config_bits(config, bits);
	switch (parity) {
	case 0:
		sp_set_config_parity(config, SP_PARITY_NONE);
		break;
	case 1:
		sp_set_config_parity(config, SP_PARITY_EVEN);
		break;
	case 2:
		sp_set_config_parity(config, SP_PARITY_ODD);
		break;
	default:
		return SR_ERR_ARG;
	}
	sp_set_config_stopbits(config, stopbits);
	sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts);
	sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE);
	sp_set_config_dtr(config, dtr);
	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);
	sp_free_config(config);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Invalid arguments for setting serial port parameters.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error setting serial port parameters (%d): %s.",
			sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	return SR_OK;
}
Exemple #2
0
/**
 * Write a number of bytes to the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer containing the bytes to write.
 * @param count Number of bytes to write.
 *
 * @return The number of bytes written, or a negative error code upon failure.
 */
SR_PRIV int serial_write(struct sr_serial_dev_inst *serial,
		const void *buf, size_t count)
{
	ssize_t ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (serial->fd == -1) {
		sr_dbg("Cannot use unopened serial port %s (fd %d).",
				serial->port, serial->fd);
		return SR_ERR;
	}

	ret = sp_write(serial->data, buf, count);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempted serial port write with invalid arguments.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Write error: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	sr_spew("Wrote %d/%d bytes (fd %d).", ret, count, serial->fd);

	return ret;
}
Exemple #3
0
/**
 * Flush serial port buffers.
 *
 * @param serial Previously initialized serial port structure.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR Failure.
 *
 * @private
 */
SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
{
	int ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->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);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempt to flush an invalid serial port.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error flushing port (%d): %s.",
			sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	return SR_OK;
}
Exemple #4
0
/**
 * Drain serial port buffers.
 *
 * @param serial Previously initialized serial port structure.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR Failure.
 *
 * @private
 */
SR_PRIV int serial_drain(struct sr_serial_dev_inst *serial)
{
	int ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->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);

	if (ret == SP_ERR_FAIL) {
		error = sp_last_error_message();
		sr_err("Error draining port (%d): %s.",
			sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	return SR_OK;
}
Exemple #5
0
static int _serial_write(struct serial_device_t *serial,
                         const void *buf, size_t count,
                         int nonblocking, unsigned int timeout_ms)
{
  if (!serial) {
    log_error("serial_write: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  if (!serial->data) {
    log_error("serial_write: cannot use unopened serial port %s.", serial->port);
    return -DEVICE_CONN_ERROR;
  }
  int ret;
  if (nonblocking) {
    ret = sp_nonblocking_write(serial->data, buf, count);
  } else {
    ret = sp_blocking_write(serial->data, buf, count, timeout_ms);
  }
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_write: invalid serial port parameters.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_write: write error (%d): %s.", sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  return ret;
}
Exemple #6
0
int serial_close(struct serial_device_t *serial)
{
  if (!serial) {
    log_error("serial_close: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  if (!serial->data) {
    log_error("serial_close: cannot close unopened serial port %s.",
              serial->port);
    return -DEVICE_CONN_ERROR;
  }
  log_info("serial_close: closing serial port %s.", serial->port);
  int ret = sp_close(serial->data);
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_close: attempt to close an invalid serial port.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_close: error closing port (%d): %s.",
              sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  sp_free_port(serial->data);
  serial->data = NULL;
  return NO_ERROR;
}
Exemple #7
0
int serial_read_nonblocking(struct serial_device_t *serial,
                            void *buf,
                            size_t count)
{
  if (!serial) {
    log_error("serial_read_nonblocking: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  if (!serial->data) {
    log_error("serial_read_nonblocking: cannot use unopened serial port %s.",
              serial->port);
    return -DEVICE_CONN_ERROR;
  }
  int ret = sp_nonblocking_read(serial->data, buf, count);
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_read_nonblocking: invalid serial port parameters.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_read_nonblocking: read error (%d): %s.",
              sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  return ret;
}
Exemple #8
0
int serial_set_params(struct serial_device_t *serial,
                      int baudrate,
                      int bits,
                      int parity,
                      int stopbits,
                      int flowcontrol,
                      int rts,
                      int dtr)
{
  if (!serial) {
    log_error("serial_set_params: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  if (!serial->data) {
    log_error("serial_set_params: cannot configure unopened serial port %s.",
              serial->port);
    return -DEVICE_CONN_ERROR;
  }
  log_debug("serial_set_params: setting serial parameters on port %s.",
            serial->port);
  struct sp_port_config *config;
  sp_new_config(&config);
  sp_set_config_baudrate(config, baudrate);
  sp_set_config_bits(config, bits);
  sp_set_config_parity(config, parity);
  sp_set_config_stopbits(config, stopbits);
  sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts);
  sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE);
  sp_set_config_dtr(config, dtr);
  sp_set_config_dsr(config, SP_DSR_IGNORE);
  sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED);
  int ret = sp_set_config(serial->data, config);
  sp_free_config(config);
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_set_params: invalid serial port parameters.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_set_params: error setting serial port parameters (%d): %s.",
              sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  return NO_ERROR;
}
Exemple #9
0
/**
 * Set serial parameters for the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param baudrate The baudrate to set.
 * @param bits The number of data bits to use.
 * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
 * @param stopbits The number of stop bits to use (1 or 2).
 * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
 *                    2 = XON/XOFF).
 *
 * @return SR_OK upon success, SR_ERR upon failure.
 */
SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
			      int bits, int parity, int stopbits,
			      int flowcontrol, int rts, int dtr)
{
	int ret;
	char *error;
	struct sp_port_config config;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (serial->fd == -1) {
		sr_dbg("Cannot configure unopened serial port %s (fd %d).",
		       serial->port, serial->fd);
		return SR_ERR;
	}

	sr_spew("Setting serial parameters on port %s (fd %d).", serial->port,
		serial->fd);

	config.baudrate = baudrate;
	config.bits = bits;
	config.parity = parity;
	config.stopbits = stopbits;
	config.rts = flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts;
	config.cts = flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
	config.dtr = dtr;
	config.dsr = SP_DSR_IGNORE;
	config.xon_xoff = flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED;

	ret = sp_set_config(serial->data, &config);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Invalid arguments for setting serial port parameters.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error setting serial port parameters: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	return SR_OK;
}
Exemple #10
0
/**
 * Open the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param flags Flags to use when opening the serial port. Possible flags
 *              include SERIAL_RDWR, SERIAL_RDONLY, SERIAL_NONBLOCK.
 *
 * If the serial structure contains a serialcomm string, it will be
 * passed to serial_set_paramstr() after the port is opened.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
{
	int ret;
	char *error;
	int sp_flags = 0;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);

	sp_get_port_by_name(serial->port, &serial->data);

	if (flags & SERIAL_RDWR)
		sp_flags = (SP_MODE_READ | SP_MODE_WRITE);
	else if (flags & SERIAL_RDONLY)
		sp_flags = SP_MODE_READ;

	serial->nonblocking = (flags & SERIAL_NONBLOCK) ? 1 : 0;

	ret = sp_open(serial->data, sp_flags);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempt to open serial port with invalid parameters.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error opening port: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

#ifndef _WIN32
	sp_get_port_handle(serial->data, &serial->fd);
#endif

	if (serial->serialcomm)
		return serial_set_paramstr(serial, serial->serialcomm);
	else
		return SR_OK;
}
Exemple #11
0
/**
 * Read a number of bytes from the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer where to store the bytes that are read.
 * @param count The number of bytes to read.
 *
 * @return The number of bytes read, or a negative error code upon failure.
 */
SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf,
		size_t count)
{
	ssize_t ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (serial->fd == -1) {
		sr_dbg("Cannot use unopened serial port %s (fd %d).",
				serial->port, serial->fd);
		return SR_ERR;
	}

	if (serial->nonblocking)
		ret = sp_nonblocking_read(serial->data, buf, count);
	else
		ret = sp_blocking_read(serial->data, buf, count, 0);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempted serial port read with invalid arguments.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Read error: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	if (ret > 0)
		sr_spew("Read %d/%d bytes (fd %d).", ret, count, serial->fd);

	return ret;
}
Exemple #12
0
static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
		size_t count, int nonblocking, unsigned int timeout_ms)
{
	ssize_t ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->data) {
		sr_dbg("Cannot use unopened serial port %s.", serial->port);
		return SR_ERR;
	}

	if (nonblocking)
		ret = sp_nonblocking_read(serial->data, buf, count);
	else
		ret = sp_blocking_read(serial->data, buf, count, timeout_ms);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempted serial port read with invalid arguments.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Read error (%d): %s.", sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	if (ret > 0)
		sr_spew("Read %zd/%zu bytes.", ret, count);

	return ret;
}
Exemple #13
0
static int _serial_read(struct serial_device_t *serial,
                 void *buf,
                 size_t count,
                 int nonblocking,
                 unsigned int timeout_ms)
{
  if (!serial) {
    log_error("serial_read_nonblocking: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  if (!serial->data) {
    log_error("serial_read_nonblocking: cannot use unopened serial port %s.",
              serial->port);
    return -DEVICE_CONN_ERROR;
  }
  int ret;
  if (nonblocking) {
    ret = sp_nonblocking_read(serial->data, buf, count);
  } else {
    // TODO read or read_next? Bailing early is probably better than waiting.
    ret = sp_blocking_read_next(serial->data, buf, count, timeout_ms);
  }
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_read_nonblocking: invalid serial port parameters.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_read_nonblocking: read error (%d): %s.",
              sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  return ret;
}
Exemple #14
0
/**
 * Close the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR Failure.
 *
 * @private
 */
SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
{
	int ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->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);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempt to close an invalid serial port.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error closing port (%d): %s.",
			sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	sp_free_port(serial->data);
	serial->data = NULL;

	return SR_OK;
}
Exemple #15
0
int serial_open(struct serial_device_t *serial, int flags)
{
  if (!serial) {
    log_error("serial_open: invalid serial port device.");
    return -DEVICE_CONN_ERROR;
  }
  log_info("serial_open: opening serial port '%s' (flags %d).",
           serial->port, flags);
  sp_get_port_by_name(serial->port, &serial->data);
  int ret = sp_open(serial->data, flags);
  char *error;
  switch (ret) {
  case SP_ERR_ARG:
    log_error("serial_open: invalid serial port parameters.");
    return -DEVICE_CONF_ERROR;
  case SP_ERR_FAIL:
    error = sp_last_error_message();
    log_error("serial_open: error opening serial port (%d): %s.",
              sp_last_error_code(), error);
    sp_free_error_message(error);
    return -DEVICE_CONN_ERROR;
  }
  return NO_ERROR;
}
Exemple #16
0
static int _serial_write(struct sr_serial_dev_inst *serial,
		const void *buf, size_t count, int nonblocking)
{
	ssize_t ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (!serial->data) {
		sr_dbg("Cannot use unopened serial port %s.", serial->port);
		return SR_ERR;
	}

	if (nonblocking)
		ret = sp_nonblocking_write(serial->data, buf, count);
	else
		ret = sp_blocking_write(serial->data, buf, count, 0);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempted serial port write with invalid arguments.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Write error (%d): %s.", sp_last_error_code(), error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	sr_spew("Wrote %d/%d bytes.", ret, count);

	return ret;
}
Exemple #17
0
/**
 * Open the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param flags Flags to use when opening the serial port. Possible flags
 *              include SERIAL_RDWR, SERIAL_RDONLY, SERIAL_NONBLOCK.
 *
 * If the serial structure contains a serialcomm string, it will be
 * passed to serial_set_paramstr() after the port is opened.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
{
	int ret;
	char *error;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);

	sp_get_port_by_name(serial->port, &serial->data);

	ret = sp_open(serial->data, flags);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Attempt to open serial port with invalid parameters.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error opening port: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

#ifndef _WIN32
	serial->fd = serial->data->fd;
#endif

	if (serial->serialcomm)
		return serial_set_paramstr(serial, serial->serialcomm);
	else
		return SR_OK;
}