Beispiel #1
0
static void handle_new_data(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	int len, status, offset = 0;
	struct sr_serial_dev_inst *serial;

	devc = sdi->priv;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = DMM_BUFSIZE - devc->buflen;
	len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len);
	if (len < 1) {
		sr_err("Serial port read error: %d.", len);
		return;
	}
	devc->buflen += len;
	status = PACKET_INVALID_HEADER;

	/* Now look for packets in that data. */
	while (status != PACKET_NEED_MORE_DATA) {
		/* We don't have a header, look for one. */
		if (devc->next_packet_len == 0) {
			len = devc->buflen - offset;
			status = brymen_packet_length(devc->buf + offset, &len);
			if (status == PACKET_HEADER_OK) {
				/* We know how large the packet will be. */
				devc->next_packet_len = len;
			} else if (status == PACKET_NEED_MORE_DATA) {
				/* We didn't yet receive the full header. */
				devc->next_packet_len = 0;
				break;
			} else {
				/* Invalid header. Move on. */
				devc->next_packet_len = 0;
				offset++;
				continue;
			}
		}

		/* We know how the packet size, but did we receive all of it? */
		if (devc->buflen - offset < devc->next_packet_len)
			break;

		/* We should have a full packet here, so we can check it. */
		if (brymen_packet_is_valid(devc->buf + offset)) {
			handle_packet(devc->buf + offset, sdi);
			offset += devc->next_packet_len;
		} else {
			offset++;
		}

		/* We are done with this packet. Look for a new one. */
		devc->next_packet_len = 0;
	}

	/* If we have any data left, move it to the beginning of our buffer. */
	memmove(devc->buf, devc->buf + offset, devc->buflen - offset);
	devc->buflen -= offset;
}
Beispiel #2
0
static void handle_new_data(struct sr_dev_inst *sdi, int idx)
{
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len, i, offset = 0;

	devc = sdi->priv;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = SERIAL_BUFSIZE - devc->buflen;
	len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len);
	if (len < 1) {
		sr_err("Serial port read error: %d.", len);
		return;
	}

	devc->buflen += len;

	/* Now look for packets in that data. */
	while ((devc->buflen - offset) >= mic_devs[idx].packet_size) {
		if (mic_devs[idx].packet_valid(devc->buf + offset)) {
			handle_packet(devc->buf + offset, sdi, idx);
			offset += mic_devs[idx].packet_size;
		} else {
			offset++;
		}
	}

	/* If we have any data left, move it to the beginning of our buffer. */
	for (i = 0; i < devc->buflen - offset; i++)
		devc->buf[i] = devc->buf[offset + i];
	devc->buflen -= offset;
}
Beispiel #3
0
SR_PRIV int pce_322a_receive_data(int fd, int revents, void *cb_data)
{
	const struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	unsigned char c;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	if (!(serial = sdi->conn))
		return TRUE;

	if (revents == G_IO_IN) {
		if (serial_read_nonblocking(serial, &c, 1) != 1)
			return TRUE;
		process_byte(sdi, c);
	}

	return TRUE;
}
Beispiel #4
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	struct sr_dev_inst *sdi;
	GSList *l, *devices;
	gint64 start;
	const char *conn;
	unsigned char c;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN)
			conn = g_variant_get_string(src->data, NULL);
	}
	if (!conn)
		return NULL;

	serial = sr_serial_dev_inst_new(conn, SERIALCOMM);

	if (serial_open(serial, SERIAL_RDONLY) != SR_OK)
		return NULL;

	devices = NULL;
	drvc = di->priv;
	start = g_get_monotonic_time();
	while (g_get_monotonic_time() - start < MAX_SCAN_TIME_US) {
		if (serial_read_nonblocking(serial, &c, 1) == 1 && c == 0xa5) {
			/* Found one. */
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup("CEM");
			sdi->model = g_strdup("DT-885x");
			devc = g_malloc0(sizeof(struct dev_context));
			devc->cur_mqflags = 0;
			devc->recording = -1;
			devc->cur_meas_range = 0;
			devc->cur_data_source = DATA_SOURCE_LIVE;
			devc->enable_data_source_memory = FALSE;
			sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM);
			sdi->inst_type = SR_INST_SERIAL;
			sdi->priv = devc;
			sdi->driver = di;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL");
			drvc->instances = g_slist_append(drvc->instances, sdi);
			devices = g_slist_append(devices, sdi);
			break;
		}
		/* It takes about 1ms for a byte to come in. */
		g_usleep(1000);
	}

	serial_close(serial);

	return devices;
}
Beispiel #5
0
SR_PRIV int appa_55ii_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int64_t time;
	const uint8_t *ptr, *next_ptr, *end_ptr;
	int len;

	(void)fd;

	if (!(sdi = cb_data) || !(devc = sdi->priv) || revents != G_IO_IN)
		return TRUE;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = sizeof(devc->buf) - devc->buf_len;
	len = serial_read_nonblocking(serial, devc->buf + devc->buf_len, len);
	if (len < 1) {
		sr_err("Serial port read error: %d.", len);
		return FALSE;
	}
	devc->buf_len += len;

	/* Now look for packets in that data. */
	ptr = devc->buf;
	end_ptr = ptr + devc->buf_len;
	while ((next_ptr = appa_55ii_parse_data(sdi, ptr, end_ptr - ptr)))
		ptr = next_ptr;

	/* If we have any data left, move it to the beginning of our buffer. */
	memmove(devc->buf, ptr, end_ptr - ptr);
	devc->buf_len -= ptr - devc->buf;

	/* If buffer is full and no valid packet was found, wipe buffer. */
	if (devc->buf_len >= sizeof(devc->buf)) {
		devc->buf_len = 0;
		return FALSE;
	}

	if (devc->limit_samples && devc->num_samples >= devc->limit_samples) {
		sr_info("Requested number of samples reached.");
		sdi->driver->dev_acquisition_stop(sdi, devc->session_cb_data);
		return TRUE;
	}

	if (devc->limit_msec) {
		time = (g_get_monotonic_time() - devc->start_time) / 1000;
		if (time > (int64_t)devc->limit_msec) {
			sr_info("Requested time limit reached.");
			sdi->driver->dev_acquisition_stop(sdi,
					devc->session_cb_data);
			return TRUE;
		}
	}

	return TRUE;
}
Beispiel #6
0
SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/*
				 * TODO: According to specs, should be \r, but
				 * then we'd have to get rid of the \n.
				 */
				devc->last_req_pending = FALSE;
				nma_process_line(sdi);
				break;
			}
		}
	}

	if (sr_sw_limits_check(&devc->limits)) {
		sr_dev_acquisition_stop(sdi);
	} else {
		/* Request next package. */
		if (devc->last_req_pending) {
			gint64 elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
			if (elapsed_us > NMADMM_TIMEOUT_MS * 1000) {/* Timeout! */
				sr_spew("Request timeout!");
				devc->last_req_pending = FALSE;
			}
		}
		if (!devc->last_req_pending) {
			if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK)
				return FALSE;
		}
	}

	return TRUE;
}
Beispiel #7
0
SR_PRIV int fluke_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;
	int64_t now, elapsed;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (FLUKEDMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen++;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\r') {
				*(devc->buf + --devc->buflen) = '\0';
				handle_line(sdi);
				break;
			}
		}
	}

	if (sr_sw_limits_check(&devc->limits)) {
		sdi->driver->dev_acquisition_stop(sdi);
		return TRUE;
	}

	now = g_get_monotonic_time() / 1000;
	elapsed = now - devc->cmd_sent_at;
	/* Send query command at poll_period interval, or after 1 second
	 * has elapsed. This will make it easier to recover from any
	 * out-of-sync or temporary disconnect issues. */
	if ((devc->expect_response == FALSE && elapsed > devc->profile->poll_period)
			|| elapsed > devc->profile->timeout) {
		if (serial_write_blocking(serial, "QM\r", 3, SERIAL_WRITE_TIMEOUT_MS) < 0)
			sr_err("Unable to send QM.");
		devc->cmd_sent_at = now;
		devc->expect_response = TRUE;
	}

	return TRUE;
}
Beispiel #8
0
size_t publish_callback(void *p, size_t size, size_t n, void *up)
{
  if (size * n < 1)
  {
    return 0;
  }
  char buf;
  if (serial_read_nonblocking((struct serial_device_t *)up, &buf, 1) < 0)
  {
    log_error("publish_callback: serial_read_nonblocking");
    return 0;
  }
  *(char *)p = buf;
  return 1;
}
Beispiel #9
0
/**
 * Read single byte from serial port.
 *
 * @retval -1 Timeout or error.
 * @retval other Byte.
 */
static int read_byte(struct sr_serial_dev_inst *serial, gint64 timeout)
{
	uint8_t result = 0;
	int rc = 0;

	for (;;) {
		rc = serial_read_nonblocking(serial, &result, 1);
		if (rc == 1) {
			sr_spew("read: 0x%02x/%d", result, result);
			return result;
		}
		if (g_get_monotonic_time() > timeout)
			return -1;
		g_usleep(2000);
	}
}
Beispiel #10
0
static void handle_new_data(struct sr_dev_inst *sdi, void *info)
{
	struct dmm_info *dmm;
	struct dev_context *devc;
	int len, i, offset = 0;
	struct sr_serial_dev_inst *serial;

	dmm = (struct dmm_info *)sdi->driver;

	devc = sdi->priv;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = DMM_BUFSIZE - devc->buflen;
	len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len);
	if (len == 0)
		return; /* No new bytes, nothing to do. */
	if (len < 0) {
		sr_err("Serial port read error: %d.", len);
		return;
	}
	devc->buflen += len;

	/* Now look for packets in that data. */
	while ((devc->buflen - offset) >= dmm->packet_size) {
		if (dmm->packet_valid(devc->buf + offset)) {
			handle_packet(devc->buf + offset, sdi, info);
			offset += dmm->packet_size;

			/* Request next packet, if required. */
			if (!dmm->packet_request)
				break;
			if (dmm->req_timeout_ms || dmm->req_delay_ms)
				devc->req_next_at = g_get_monotonic_time() +
					dmm->req_delay_ms * 1000;
			req_packet(sdi);
		} else {
			offset++;
		}
	}

	/* If we have any data left, move it to the beginning of our buffer. */
	for (i = 0; i < devc->buflen - offset; i++)
		devc->buf[i] = devc->buf[offset + i];
	devc->buflen -= offset;
}
Beispiel #11
0
SR_PRIV int teleinfo_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	const uint8_t *ptr, *next_ptr, *end_ptr;
	int len;

	(void)fd;

	if (!(sdi = cb_data) || !(devc = sdi->priv) || revents != G_IO_IN)
		return TRUE;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = TELEINFO_BUF_SIZE - devc->buf_len;
	len = serial_read_nonblocking(serial, devc->buf + devc->buf_len, len);
	if (len < 1) {
		sr_err("Serial port read error: %d.", len);
		return FALSE;
	}
	devc->buf_len += len;

	/* Now look for packets in that data. */
	ptr = devc->buf;
	end_ptr = ptr + devc->buf_len;
	while ((next_ptr = teleinfo_parse_data(sdi, ptr, end_ptr - ptr, NULL)))
		ptr = next_ptr;

	/* If we have any data left, move it to the beginning of our buffer. */
	memmove(devc->buf, ptr, end_ptr - ptr);
	devc->buf_len -= ptr - devc->buf;

	/* If buffer is full and no valid packet was found, wipe buffer. */
	if (devc->buf_len >= TELEINFO_BUF_SIZE) {
		devc->buf_len = 0;
		return FALSE;
	}

	if (sr_sw_limits_check(&devc->sw_limits))
		sdi->driver->dev_acquisition_stop(sdi);

	return TRUE;
}
Beispiel #12
0
static int scpi_serial_read_data(void *priv, char *buf, int maxlen)
{
	struct scpi_serial *sscpi = priv;
	int len, ret;

	len = BUFFER_SIZE - sscpi->count;

	/* Try to read new data into the buffer if there is space. */
	if (len > 0) {
		ret = serial_read_nonblocking(sscpi->serial, sscpi->buffer + sscpi->read,
				BUFFER_SIZE - sscpi->count);

		if (ret < 0)
			return ret;

		sscpi->count += ret;

		if (ret > 0)
			sr_spew("Read %d bytes into buffer.", ret);
	}

	/* Return as many bytes as possible from buffer, excluding any trailing newline. */
	if (sscpi->read < sscpi->count) {
		len = sscpi->count - sscpi->read;
		if (len > maxlen)
			len = maxlen;
		if (sscpi->buffer[sscpi->read + len - 1] == '\n')
			len--;
		sr_spew("Returning %d bytes from buffer.", len);
		memcpy(buf, sscpi->buffer + sscpi->read, len);
		sscpi->read += len;
		if (sscpi->read == BUFFER_SIZE) {
			sr_spew("Resetting buffer.");
			sscpi->count = 0;
			sscpi->read = 0;
		}
		return len;
	}

	return 0;
}
Beispiel #13
0
SR_PRIV int agdmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	gboolean stop = FALSE;
	int len;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (AGDMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/* End of line */
				stop = receive_line(sdi);
				break;
			}
		}
	}

	if (sr_sw_limits_check(&devc->limits) || stop)
		sr_dev_acquisition_stop(sdi);
	else
		dispatch(sdi);

	return TRUE;
}
Beispiel #14
0
SR_PRIV int agdmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (AGDMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/* End of line */
				receive_line(sdi);
				break;
			}
		}
	}

	dispatch(sdi);

	if (devc->limit_samples && devc->num_samples >= devc->limit_samples)
		sdi->driver->dev_acquisition_stop(sdi, cb_data);

	return TRUE;
}
static void handle_new_data(struct sr_dev_inst *sdi, void *info)
{
	struct scale_info *scale;
	struct dev_context *devc;
	int len, i, offset = 0;
	struct sr_serial_dev_inst *serial;

	scale = (struct scale_info *)sdi->driver;

	devc = sdi->priv;
	serial = sdi->conn;

	/* Try to get as much data as the buffer can hold. */
	len = SCALE_BUFSIZE - devc->buflen;
	len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len);
	if (len == 0)
		return; /* No new bytes, nothing to do. */
	if (len < 0) {
		sr_err("Serial port read error: %d.", len);
		return;
	}
	devc->buflen += len;

	/* Now look for packets in that data. */
	while ((devc->buflen - offset) >= scale->packet_size) {
		if (scale->packet_valid(devc->buf + offset)) {
			handle_packet(devc->buf + offset, sdi, info);
			offset += scale->packet_size;
		} else {
			offset++;
		}
	}

	/* If we have any data left, move it to the beginning of our buffer. */
	for (i = 0; i < devc->buflen - offset; i++)
		devc->buf[i] = devc->buf[offset + i];
	devc->buflen -= offset;
}
Beispiel #16
0
static int scpi_serial_read_data(void *priv, char *buf, int maxlen)
{
	struct scpi_serial *sscpi = priv;
	int ret;

	/* Try to read new data into the buffer. */
	ret = serial_read_nonblocking(sscpi->serial, buf, maxlen);

	if (ret < 0)
		return ret;

	if (ret > 0) {
		sr_spew("Read %d bytes into buffer.", ret);

		if (buf[ret - 1] == '\n') {
			sscpi->got_newline = TRUE;
			sr_spew("Received terminator");
		} else {
			sscpi->got_newline = FALSE;
		}
	}

	return ret;
}
Beispiel #17
0
/**
 * Try to find a valid packet in a serial data stream.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer containing the bytes to write.
 * @param buflen Size of the buffer.
 * @param[in] packet_size Size, in bytes, of a valid packet.
 * @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.
 *
 * @private
 */
SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
				 uint8_t *buf, size_t *buflen,
				 size_t packet_size,
				 packet_valid_callback is_valid,
				 uint64_t timeout_ms, int baudrate)
{
	uint64_t start, time, byte_delay_us;
	size_t ibuf, i, maxlen;
	ssize_t len;

	maxlen = *buflen;

	sr_dbg("Detecting packets on %s (timeout = %" PRIu64
	       "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);

	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);
	start = g_get_monotonic_time();

	i = ibuf = len = 0;
	while (ibuf < maxlen) {
		len = serial_read_nonblocking(serial, &buf[ibuf], 1);
		if (len > 0) {
			ibuf += len;
		} else if (len == 0) {
			/* No logging, already done in serial_read(). */
		} else {
			/* Error reading byte, but continuing anyway. */
		}

		time = g_get_monotonic_time() - start;
		time /= 1000;

		if ((ibuf - i) >= packet_size) {
			/* We have at least a packet's worth of data. */
			if (is_valid(&buf[i])) {
				sr_spew("Found valid %zu-byte packet after "
					"%" PRIu64 "ms.", (ibuf - i), time);
				*buflen = ibuf;
				return SR_OK;
			} else {
				sr_spew("Got %zu bytes, but not a valid "
					"packet.", (ibuf - i));
			}
			/* Not a valid packet. Continue searching. */
			i++;
		}
		if (time >= timeout_ms) {
			/* Timeout */
			sr_dbg("Detection timed out after %" PRIu64 "ms.", time);
			break;
		}
		if (len < 1)
			g_usleep(byte_delay_us);
	}

	*buflen = ibuf;

	sr_err("Didn't find a valid packet (read %zu bytes).", *buflen);

	return SR_ERR;
}
Beispiel #18
0
SR_PRIV int norma_dmm_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;
	gboolean terminating;
	gdouble elapsed_s;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;
	if (revents == G_IO_IN) {
		/* Serial data arrived. */
		while (NMADMM_BUFSIZE - devc->buflen - 1 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;
			devc->buflen += len;
			*(devc->buf + devc->buflen) = '\0';
			if (*(devc->buf + devc->buflen - 1) == '\n') {
				/*
				 * TODO: According to specs, should be \r, but
				 * then we'd have to get rid of the \n.
				 */
				devc->last_req_pending = FALSE;
				nma_process_line(sdi);
				break;
			}
		}
	}

	/* If number of samples or time limit reached, stop acquisition. */
	terminating = FALSE;
	if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) {
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		terminating = TRUE;
	}

	if (devc->limit_msec) {
		elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
		if ((elapsed_s * 1000) >= devc->limit_msec) {
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			terminating = TRUE;
		}
	}

	/* Request next package. */
	if (!terminating) {
		if (devc->last_req_pending) {
			gint64 elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
			if (elapsed_us > NMADMM_TIMEOUT_MS * 1000) {/* Timeout! */
				sr_spew("Request timeout!");
				devc->last_req_pending = FALSE;
			}
		}
		if (!devc->last_req_pending) {
			if (nma_send_req(sdi, NMADMM_REQ_STATUS, NULL) != SR_OK)
				return FALSE;
		}
	}

	return TRUE;
}
Beispiel #19
0
/**
 * Try to find a valid packet in a serial data stream.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer containing the bytes to write.
 * @param buflen Size of the buffer.
 * @param get_packet_size Callback that assesses the size of incoming packets.
 * @param is_valid Callback that assesses whether the packet is valid or not.
 * @param timeout_ms The timeout after which, if no packet is detected, to
 *                   abort scanning.
 * @param baudrate The baudrate of the serial port. This parameter is not
 *                 critical, but it helps fine tune the serial port polling
 *                 delay.
 *
 * @return SR_OK if a valid packet is found within the given timeout,
 *         SR_ERR upon failure.
 */
SR_PRIV int brymen_stream_detect(struct sr_serial_dev_inst *serial,
				uint8_t *buf, size_t *buflen,
				packet_length_t get_packet_size,
				packet_valid_callback is_valid,
				uint64_t timeout_ms, int baudrate)
{
	int64_t start, time, byte_delay_us;
	size_t ibuf, i, maxlen;
	int status, len, packet_len, stream_len;

	maxlen = *buflen;

	sr_dbg("Detecting packets on %s (timeout = %" PRIu64
	       "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);

	/* Assume 8n1 transmission. That is 10 bits for every byte. */
	byte_delay_us = 10 * ((1000 * 1000) / baudrate);
	start = g_get_monotonic_time();

	packet_len = i = ibuf = len = 0;
	while (ibuf < maxlen) {
		len = serial_read_nonblocking(serial, &buf[ibuf], maxlen - ibuf);
		if (len > 0) {
			ibuf += len;
			sr_spew("Read %d bytes.", len);
		}

		time = g_get_monotonic_time() - start;
		time /= 1000;

		stream_len = ibuf - i;
		if (stream_len > 0 && packet_len == 0) {
			/* How large of a packet are we expecting? */
			packet_len = stream_len;
			status = get_packet_size(&buf[i], &packet_len);
			switch (status) {
			case PACKET_HEADER_OK:
				/* We know how much data we need to wait for. */
				break;
			case PACKET_NEED_MORE_DATA:
				/* We did not receive the full header. */
				packet_len = 0;
				break;
			case PACKET_INVALID_HEADER:
			default:
				/*
				 * We had enough data, but here was an error in
				 * parsing the header. Restart parsing from the
				 * next byte.
				 */
				packet_len = 0;
				i++;
				break;
			}
		}

		if ((stream_len >= packet_len) && (packet_len != 0)) {
			/* We have at least a packet's worth of data. */
			if (is_valid(&buf[i])) {
				sr_spew("Found valid %d-byte packet after "
					"%" PRIu64 "ms.", packet_len, time);
				*buflen = ibuf;
				return SR_OK;
			} else {
				sr_spew("Got %d bytes, but not a valid "
					"packet.", packet_len);

			}

			/* Not a valid packet. Continue searching. */
			i++;
			packet_len = 0;
		}

		if (time >= (int64_t)timeout_ms) {
			/* Timeout */
			sr_dbg("Detection timed out after %dms.", time);
			break;
		}
		g_usleep(byte_delay_us);
	}

	*buflen = ibuf;
	sr_err("Didn't find a valid packet (read %d bytes).", ibuf);

	return SR_ERR;
}
SR_PRIV int motech_lps_30x_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int len;
	gdouble elapsed_s;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	serial = sdi->conn;

	if (revents == G_IO_IN) { /* Serial data arrived. */
		while (LINELEN_MAX - devc->buflen - 2 > 0) {
			len = serial_read_nonblocking(serial, devc->buf + devc->buflen, 1);
			if (len < 1)
				break;

			/* Eliminate whitespace at beginning of line. */
			if (g_ascii_isspace(devc->buf[0])) {
				devc->buf[0] = '\0';
				devc->buflen = 0;
				continue;
			}

			devc->buflen += len;
			devc->buf[devc->buflen] = '\0';

			/* If line complete, process msg. */
			if ((devc->buflen > 0) && ((devc->buf[devc->buflen-1] == '\r') || devc->buf[devc->buflen-1] == '\n')) {
				devc->buflen--;
				devc->buf[devc->buflen] = '\0';

				sr_spew("Line complete: \"%s\"", devc->buf);
				process_line(sdi);
			}
		}
	}

	/* If number of samples or time limit reached, stop acquisition. */
	if (devc->limit_samples && (devc->num_samples >= devc->limit_samples))
		sdi->driver->dev_acquisition_stop(sdi, cb_data);

	if (devc->limit_msec) {
		elapsed_s = g_timer_elapsed(devc->elapsed_msec, NULL);
		if ((elapsed_s * 1000) >= devc->limit_msec)
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
	}

	/* Only request the next packet if required. */
	if (!((sdi->status == SR_ST_ACTIVE) && (devc->acq_running)))
		return TRUE;

	if (devc->acq_req_pending) {
		int64_t elapsed_us = g_get_monotonic_time() - devc->req_sent_at;
		if (elapsed_us > (REQ_TIMEOUT_MS * 1000)) {
			sr_spew("Request timeout: req=%d t=%" PRIi64 "us",
				(int)devc->acq_req, elapsed_us);
			devc->acq_req_pending = 0;
		}
	}

	if (devc->acq_req_pending == 0) {
		switch (devc->acq_req) {
		case AQ_NONE: /* Fall through */
		case AQ_STATUS:
			devc->acq_req = AQ_U1;
			lps_send_req(serial, "VOUT1");
			break;
		case AQ_U1:
			devc->acq_req = AQ_I1;
			lps_send_req(serial, "IOUT1");
			break;
		case AQ_I1:
			if (devc->model->num_channels == 1) {
				devc->acq_req = AQ_STATUS;
				lps_send_req(serial, "STATUS");
			} else {
				devc->acq_req = AQ_U2;
				lps_send_req(serial, "VOUT2");
			}
			break;
		case AQ_U2:
			devc->acq_req = AQ_I2;
			lps_send_req(serial, "IOUT2");
			break;
		case AQ_I2:
			devc->acq_req = AQ_STATUS;
			lps_send_req(serial, "STATUS");
			break;
		default:
			sr_err("Illegal devc->acq_req=%d", devc->acq_req);
			return SR_ERR;
		}
		devc->req_sent_at = g_get_real_time();
		devc->acq_req_pending = 1;
	}

	return TRUE;
}
Beispiel #21
0
static GSList *scan(GSList *options, int modelid)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_channel *ch;
	struct sr_channel_group *cg;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	struct pps_model *model;
	uint8_t packet[PACKET_SIZE];
	unsigned int i;
	int ret;
	const char *conn, *serialcomm;
	char channel[10];

	devices = NULL;
	drvc = di->priv;
	drvc->instances = NULL;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
		return NULL;

	if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
		return NULL;
	serial_flush(serial);

	/* This is how the vendor software channels for hardware. */
	memset(packet, 0, PACKET_SIZE);
	packet[0] = 0xaa;
	packet[1] = 0xaa;
	if (serial_write(serial, packet, PACKET_SIZE) == -1) {
		sr_err("Unable to write while probing for hardware: %s",
				strerror(errno));
		return NULL;
	}
	/* The device responds with a 24-byte packet when it receives a packet.
	 * At 9600 baud, 300ms is long enough for it to have arrived. */
	g_usleep(300 * 1000);
	memset(packet, 0, PACKET_SIZE);
	if ((ret = serial_read_nonblocking(serial, packet, PACKET_SIZE)) < 0) {
		sr_err("Unable to read while probing for hardware: %s",
				strerror(errno));
		return NULL;
	}
	if (ret != PACKET_SIZE || packet[0] != 0xaa || packet[1] != 0xaa) {
		/* Doesn't look like an Atten PPS. */
		return NULL;
	}

	model = NULL;
	for (i = 0; i < ARRAY_SIZE(models); i++) {
		if (models[i].modelid == modelid) {
			model = &models[i];
			break;
		}
	}
	if (!model) {
		sr_err("Unknown modelid %d", modelid);
		return NULL;
	}

	sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, "Atten", model->name, NULL);
	sdi->driver = di;
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	for (i = 0; i < MAX_CHANNELS; i++) {
		snprintf(channel, 10, "CH%d", i + 1);
		ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, channel);
		sdi->channels = g_slist_append(sdi->channels, ch);
		cg = g_malloc(sizeof(struct sr_channel_group));
		cg->name = g_strdup(channel);
		cg->channels = g_slist_append(NULL, ch);
		cg->priv = NULL;
		sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
	}

	devc = g_malloc0(sizeof(struct dev_context));
	devc->model = model;
	devc->config = g_malloc0(sizeof(struct per_channel_config) * model->num_channels);
	sdi->priv = devc;
	drvc->instances = g_slist_append(drvc->instances, sdi);
	devices = g_slist_append(devices, sdi);

	serial_close(serial);
	if (!devices)
		sr_serial_dev_inst_free(serial);

	return devices;
}