Esempio n. 1
0
static int process_buffer(struct sr_input *in)
{
	struct context *inc;
	struct sr_datafeed_meta meta;
	struct sr_datafeed_packet packet;
	struct sr_config *src;
	unsigned int offset, chunk_size;

	inc = in->priv;
	if (!inc->started) {
		std_session_send_df_header(in->sdi, LOG_PREFIX);

		if (inc->samplerate) {
			packet.type = SR_DF_META;
			packet.payload = &meta;
			src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate));
			meta.config = g_slist_append(NULL, src);
			sr_session_send(in->sdi, &packet);
			g_slist_free(meta.config);
			sr_config_free(src);
		}

		inc->started = TRUE;
	}

	/* Round down to the last channels * unitsize boundary. */
	inc->analog.num_samples = CHUNK_SIZE / inc->samplesize;
	chunk_size = inc->analog.num_samples * inc->samplesize;
	offset = 0;

	while ((offset + chunk_size) < in->buf->len) {
		inc->analog.data = in->buf->str + offset;
		sr_session_send(in->sdi, &inc->packet);
		offset += chunk_size;
	}

	inc->analog.num_samples = (in->buf->len - offset) / inc->samplesize;
	chunk_size = inc->analog.num_samples * inc->samplesize;
	if (chunk_size > 0) {
		inc->analog.data = in->buf->str + offset;
		sr_session_send(in->sdi, &inc->packet);
		offset += chunk_size;
	}

	if ((unsigned int)offset < in->buf->len) {
		/*
		 * The incoming buffer wasn't processed completely. Stash
		 * the leftover data for next time.
		 */
		g_string_erase(in->buf, 0, offset);
	} else {
		g_string_truncate(in->buf, 0);
	}

	return SR_OK;
}
Esempio n. 2
0
static int process_buffer(struct sr_input *in)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_datafeed_logic logic;
	struct sr_config *src;
	struct context *inc;
	gsize chunk_size, i;
	gsize chunk;
	uint16_t unitsize;

	inc = in->priv;
	unitsize = (g_slist_length(in->sdi->channels) + 7) / 8;

	if (!inc->started) {
		std_session_send_df_header(in->sdi);

		if (inc->samplerate) {
			packet.type = SR_DF_META;
			packet.payload = &meta;
			src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate));
			meta.config = g_slist_append(NULL, src);
			sr_session_send(in->sdi, &packet);
			g_slist_free(meta.config);
			sr_config_free(src);
		}

		inc->samples_remain = CHRONOVU_LA8_DATASIZE;
		inc->samples_remain /= unitsize;

		inc->started = TRUE;
	}

	packet.type = SR_DF_LOGIC;
	packet.payload = &logic;
	logic.unitsize = unitsize;

	/* Cut off at multiple of unitsize. Avoid sending the "header". */
	chunk_size = in->buf->len / logic.unitsize * logic.unitsize;
	chunk_size = MIN(chunk_size, inc->samples_remain * unitsize);

	for (i = 0; i < chunk_size; i += chunk) {
		logic.data = in->buf->str + i;
		chunk = MIN(CHUNK_SIZE, chunk_size - i);
		if (chunk) {
			logic.length = chunk;
			sr_session_send(in->sdi, &packet);
			inc->samples_remain -= chunk / unitsize;
		}
	}
	g_string_erase(in->buf, 0, chunk_size);

	return SR_OK;
}
Esempio n. 3
0
static int loadfile(struct sr_input *in, const char *filename)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_datafeed_logic logic;
	struct sr_config *src;
	unsigned char buffer[CHUNKSIZE];
	int fd, size, num_probes;
	struct context *ctx;

	ctx = in->internal;
    packet.status = SR_PKT_OK;

	if ((fd = open(filename, O_RDONLY)) == -1)
		return SR_ERR;

	num_probes = g_slist_length(in->sdi->channels);

	/* Send header packet to the session bus. */
	std_session_send_df_header(in->sdi, LOG_PREFIX);

	if (ctx->samplerate) {
		packet.type = SR_DF_META;
		packet.payload = &meta;
		src = sr_config_new(SR_CONF_SAMPLERATE,
				g_variant_new_uint64(ctx->samplerate));
		meta.config = g_slist_append(NULL, src);
		sr_session_send(in->sdi, &packet);
		sr_config_free(src);
	}

	/* Chop up the input file into chunks & send it to the session bus. */
	packet.type = SR_DF_LOGIC;
	packet.payload = &logic;
	logic.unitsize = (num_probes + 7) / 8;
	logic.data = buffer;
	while ((size = read(fd, buffer, CHUNKSIZE)) > 0) {
		logic.length = size;
		sr_session_send(in->sdi, &packet);
	}
	close(fd);

	/* Send end packet to the session bus. */
	packet.type = SR_DF_END;
	sr_session_send(in->sdi, &packet);

	g_free(ctx);
	in->internal = NULL;

	return SR_OK;
}
Esempio n. 4
0
static int loadfile(struct sr_input *in, const char *filename)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	FILE *file;
	struct context *ctx;
	uint64_t samplerate;

	ctx = in->internal;

	if ((file = fopen(filename, "r")) == NULL)
		return SR_ERR;

	if (!parse_header(file, ctx))
	{
		sr_err("VCD parsing failed");
		fclose(file);
		return SR_ERR;
	}

	/* Send header packet to the session bus. */
	std_session_send_df_header(in->sdi, LOG_PREFIX);

	/* Send metadata about the SR_DF_LOGIC packets to come. */
	packet.type = SR_DF_META;
	packet.payload = &meta;
	samplerate = ctx->samplerate / ctx->downsample;
	src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(samplerate));
	meta.config = g_slist_append(NULL, src);
	sr_session_send(in->sdi, &packet);
	sr_config_free(src);

	/* Parse the contents of the VCD file */
	parse_contents(file, in->sdi, ctx);
	
	/* Send end packet to the session bus. */
	packet.type = SR_DF_END;
	sr_session_send(in->sdi, &packet);

	fclose(file);
	release_context(ctx);
	in->internal = NULL;

	return SR_OK;
}
Esempio n. 5
0
static int process_buffer(struct sr_input *in)
{
	struct context *inc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	int offset, chunk_samples, total_samples, processed, max_chunk_samples;
	int num_samples, i;
	char channelname[8];

	inc = in->priv;
	if (!inc->started) {
		for (i = 0; i < inc->num_channels; i++) {
			snprintf(channelname, 8, "CH%d", i + 1);
			sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname);
		}

		std_session_send_df_header(in->sdi, LOG_PREFIX);

		packet.type = SR_DF_META;
		packet.payload = &meta;
		src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate));
		meta.config = g_slist_append(NULL, src);
		sr_session_send(in->sdi, &packet);
		sr_config_free(src);

		inc->started = TRUE;
	}

	if (!inc->found_data) {
		/* Skip past size of 'fmt ' chunk. */
		i = 20 + RL32(in->buf->str + 16);
		offset = find_data_chunk(in->buf, i);
		if (offset < 0) {
			if (in->buf->len > MAX_DATA_CHUNK_OFFSET) {
				sr_err("Couldn't find data chunk.");
				return SR_ERR;
			}
		}
		inc->found_data = TRUE;
	} else
		offset = 0;

	/* Round off up to the last channels * unitsize boundary. */
	chunk_samples = (in->buf->len - offset) / inc->num_channels / inc->unitsize;
	max_chunk_samples = CHUNK_SIZE / inc->num_channels / inc->unitsize;
	processed = 0;
	total_samples = chunk_samples;
	while (processed < total_samples) {
		if (chunk_samples > max_chunk_samples)
			num_samples = max_chunk_samples;
		else
			num_samples = chunk_samples;
		send_chunk(in, offset, num_samples);
		offset += num_samples * inc->unitsize;
		chunk_samples -= num_samples;
		processed += num_samples;
	}

	if ((unsigned int)offset < in->buf->len) {
		/*
		 * The incoming buffer wasn't processed completely. Stash
		 * the leftover data for next time.
		 */
		g_string_erase(in->buf, 0, offset);
	} else
		g_string_truncate(in->buf, 0);

	return SR_OK;
}
Esempio n. 6
0
static int loadfile(struct sr_input *in, const char *filename)
{
	int res;
	struct context *ctx;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *cfg;
	GIOStatus status;
	gboolean read_new_line;
	gsize term_pos;
	char **columns;
	gsize num_columns;
	int max_columns;

	(void)filename;

	ctx = in->internal;

	/* Send header packet to the session bus. */
	std_session_send_df_header(in->sdi, LOG_PREFIX);

	if (ctx->samplerate) {
		packet.type = SR_DF_META;
		packet.payload = &meta;
		cfg = sr_config_new(SR_CONF_SAMPLERATE,
			g_variant_new_uint64(ctx->samplerate));
		meta.config = g_slist_append(NULL, cfg);
		sr_session_send(in->sdi, &packet);
		sr_config_free(cfg);
	}

	read_new_line = FALSE;

	/* Limit the number of columns to parse. */
	if (ctx->multi_column_mode)
		max_columns = ctx->num_probes;
	else
		max_columns = 1;

	while (TRUE) {
		/*
		 * Skip reading a new line for the first time if the last read
		 * line was not a header because the sample data is not parsed
		 * yet.
		 */
		if (read_new_line || ctx->header) {
			ctx->line_number++;
			status = g_io_channel_read_line_string(ctx->channel,
				ctx->buffer, &term_pos, NULL);

			if (status == G_IO_STATUS_EOF)
				break;

			if (status != G_IO_STATUS_NORMAL) {
				sr_err("Error while reading line %zu.",
					ctx->line_number);
				free_context(ctx);
				return SR_ERR;
			}

			/* Remove line termination character(s). */
			g_string_truncate(ctx->buffer, term_pos);
		}

		read_new_line = TRUE;

		if (!ctx->buffer->len) {
			sr_spew("Blank line %zu skipped.", ctx->line_number);
			continue;
		}

		/* Remove trailing comment. */
		strip_comment(ctx->buffer, ctx->comment);

		if (!ctx->buffer->len) {
			sr_spew("Comment-only line %zu skipped.",
				ctx->line_number);
			continue;
		}

		if (!(columns = parse_line(ctx, max_columns))) {
			sr_err("Error while parsing line %zu.",
				ctx->line_number);
			free_context(ctx);
			return SR_ERR;
		}

		num_columns = g_strv_length(columns);

		/* Ensure that the first column is not out of bounds. */
		if (!num_columns) {
			sr_err("Column %zu in line %zu is out of bounds.",
				ctx->first_column, ctx->line_number);
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		/*
		 * Ensure that the number of probes does not exceed the number
		 * of columns in multi column mode.
		 */
		if (ctx->multi_column_mode && num_columns < ctx->num_probes) {
			sr_err("Not enough columns for desired number of probes in line %zu.",
				ctx->line_number);
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		if (ctx->multi_column_mode)
			res = parse_multi_columns(columns, ctx);
		else
			res = parse_single_column(columns[0], ctx);

		if (res != SR_OK) {
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		g_strfreev(columns);

		/*
		 * TODO: Parse sample numbers / timestamps and use it for
		 * decompression.
		 */

		/* Send sample data to the session bus. */
		res = send_samples(in->sdi, ctx->sample_buffer,
			ctx->sample_buffer_size, 1);

		if (res != SR_OK) {
			sr_err("Sending samples failed.");
			free_context(ctx);
			return SR_ERR;
		}
	}

	/* Send end packet to the session bus. */
	packet.type = SR_DF_END;
	sr_session_send(in->sdi, &packet);

	free_context(ctx);

	return SR_OK;
}
Esempio n. 7
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
	struct sr_dev_driver *di = sdi->driver;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	struct sr_usb_dev_inst *usb;
	GVariant *gvar, *rational[2];
	const uint64_t *si;
	int req_len, buf_len, len, ret;
	unsigned char buf[9];

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	drvc = di->context;
	devc = sdi->priv;
	usb = sdi->conn;

	devc->num_samples = 0;

	std_session_send_df_header(sdi);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		/* Force configuration. */
		kecheng_kc_330b_configure(sdi);

		if (kecheng_kc_330b_status_get(sdi, &ret) != SR_OK)
			return SR_ERR;
		if (ret != DEVICE_ACTIVE) {
			sr_err("Device is inactive");
			/* Still continue though, since the device will
			 * just return 30.0 until the user hits the button
			 * on the device -- and then start feeding good
			 * samples back. */
		}
	} else {
		if (kecheng_kc_330b_log_info_get(sdi, buf) != SR_OK)
			return SR_ERR;
		devc->mqflags = buf[4] ? SR_MQFLAG_SPL_TIME_WEIGHT_S : SR_MQFLAG_SPL_TIME_WEIGHT_F;
		devc->mqflags |= buf[5] ? SR_MQFLAG_SPL_FREQ_WEIGHT_C : SR_MQFLAG_SPL_FREQ_WEIGHT_A;
		devc->stored_samples = (buf[7] << 8) | buf[8];
		if (devc->stored_samples == 0) {
			/* Notify frontend of empty log by sending start/end packets. */
			std_session_send_df_end(sdi);
			return SR_OK;
		}

		if (devc->limit_samples && devc->limit_samples < devc->stored_samples)
			devc->stored_samples = devc->limit_samples;

		si = kecheng_kc_330b_sample_intervals[buf[1]];
		rational[0] = g_variant_new_uint64(si[0]);
		rational[1] = g_variant_new_uint64(si[1]);
		gvar = g_variant_new_tuple(rational, 2);
		src = sr_config_new(SR_CONF_SAMPLE_INTERVAL, gvar);
		packet.type = SR_DF_META;
		packet.payload = &meta;
		meta.config = g_slist_append(NULL, src);
		sr_session_send(sdi, &packet);
		g_free(src);
	}

	if (!(devc->xfer = libusb_alloc_transfer(0)))
		return SR_ERR;

	usb_source_add(sdi->session, drvc->sr_ctx, 10,
		kecheng_kc_330b_handle_events, (void *)sdi);

	if (devc->data_source == DATA_SOURCE_LIVE) {
		buf[0] = CMD_GET_LIVE_SPL;
		buf_len = 1;
		devc->state = LIVE_SPL_WAIT;
		devc->last_live_request = g_get_monotonic_time() / 1000;
		req_len = 3;
	} else {
		buf[0] = CMD_GET_LOG_DATA;
		buf[1] = 0;
		buf[2] = 0;
		buf_len = 4;
		devc->state = LOG_DATA_WAIT;
		if (devc->stored_samples < 63)
			buf[3] = devc->stored_samples;
		else
			buf[3] = 63;
		/* Command ack byte + 2 bytes per sample. */
		req_len = 1 + buf[3] * 2;
	}

	ret = libusb_bulk_transfer(usb->devhdl, EP_OUT, buf, buf_len, &len, 5);
	if (ret != 0 || len != 1) {
		sr_dbg("Failed to start acquisition: %s", libusb_error_name(ret));
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	libusb_fill_bulk_transfer(devc->xfer, usb->devhdl, EP_IN, devc->buf,
			req_len, kecheng_kc_330b_receive_transfer, (void *)sdi, 15);
	if (libusb_submit_transfer(devc->xfer) != 0) {
		libusb_free_transfer(devc->xfer);
		return SR_ERR;
	}

	return SR_OK;
}
Esempio n. 8
0
static int loadfile(struct sr_input *in, const char *filename)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_datafeed_analog analog;
	struct sr_config *src;
	struct context *ctx;
	float fdata[CHUNK_SIZE];
	uint64_t sample;
	int num_samples, chunk_samples, s, c, fd, l;
	char buf[CHUNK_SIZE];

	ctx = in->sdi->priv;

	/* Send header packet to the session bus. */
	std_session_send_df_header(in->sdi, LOG_PREFIX);

	packet.type = SR_DF_META;
	packet.payload = &meta;
	src = sr_config_new(SR_CONF_SAMPLERATE,
			g_variant_new_uint64(ctx->samplerate));
	meta.config = g_slist_append(NULL, src);
	sr_session_send(in->sdi, &packet);
	sr_config_free(src);

	if ((fd = open(filename, O_RDONLY)) == -1)
		return SR_ERR;

	lseek(fd, 40, SEEK_SET);
	l = read(fd, buf, 4);
	num_samples = GUINT32_FROM_LE((uint32_t)*(buf));
	num_samples /= ctx->samplesize / ctx->num_channels;
	while (TRUE) {
		if ((l = read(fd, buf, CHUNK_SIZE)) < 1)
			break;
		chunk_samples = l / ctx->samplesize / ctx->num_channels;
		for (s = 0; s < chunk_samples; s++) {
			for (c = 0; c < ctx->num_channels; c++) {
				sample = 0;
				memcpy(&sample, buf + s * ctx->samplesize + c, ctx->samplesize);
				switch (ctx->samplesize) {
				case 1:
					/* 8-bit PCM samples are unsigned. */
					fdata[s + c] = (uint8_t)sample / 255.0;
					break;
				case 2:
					fdata[s + c] = GINT16_FROM_LE(sample) / 32767.0;
					break;
				case 4:
					fdata[s + c] = GINT32_FROM_LE(sample) / 65535.0;
					break;
				}
			}
		}
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		analog.probes = in->sdi->probes;
		analog.num_samples = chunk_samples;
		analog.mq = 0;
		analog.unit = 0;
		analog.data = fdata;
		sr_session_send(in->sdi, &packet);
	}

	close(fd);
	packet.type = SR_DF_END;
	sr_session_send(in->sdi, &packet);

	return SR_OK;
}