Esempio n. 1
0
static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_scpi_hw_info *hw_info;

	sdi = NULL;
	devc = NULL;
	hw_info = NULL;

	if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
		sr_info("Couldn't get IDN response.");
		goto fail;
	}

	if (std_str_idx_s(hw_info->manufacturer, ARRAY_AND_SIZE(manufacturers)) < 0)
		goto fail;

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->vendor = g_strdup(hw_info->manufacturer);
	sdi->model = g_strdup(hw_info->model);
	sdi->version = g_strdup(hw_info->firmware_version);
	sdi->serial_num = g_strdup(hw_info->serial_number);
	sdi->driver = &hameg_hmo_driver_info;
	sdi->inst_type = SR_INST_SCPI;
	sdi->conn = scpi;

	sr_scpi_hw_info_free(hw_info);
	hw_info = NULL;

	devc = g_malloc0(sizeof(struct dev_context));

	sdi->priv = devc;

	if (hmo_init_device(sdi) != SR_OK)
		goto fail;

	return sdi;

fail:
	sr_scpi_hw_info_free(hw_info);
	sr_dev_inst_free(sdi);
	g_free(devc);

	return NULL;
}
Esempio n. 2
0
/**
 * Free the specified input instance and all associated resources.
 *
 * @since 0.4.0
 */
SR_API void sr_input_free(const struct sr_input *in)
{
	if (!in)
		return;

	if (in->module->cleanup)
		in->module->cleanup((struct sr_input *)in);
	if (in->sdi)
		sr_dev_inst_free(in->sdi);
	if (in->buf->len > 64) {
		/* That seems more than just some sub-unitsize leftover... */
		sr_warn("Found %d unprocessed bytes at free time.", in->buf->len);
	}
	g_string_free(in->buf, TRUE);
	g_free(in->priv);
	g_free((gpointer)in);
}
Esempio n. 3
0
/*
 * Standard driver dev_clear() helper.
 *
 * This function can be used to implement the dev_clear() driver API
 * callback. dev_close() is called before every sr_dev_inst is cleared.
 *
 * The only limitation is driver-specific device contexts (sdi->priv).
 * These are freed, but any dynamic allocation within structs stored
 * there cannot be freed.
 *
 * @param driver The driver which will have its instances released.
 * @param clear_private If not NULL, this points to a function called
 * with sdi->priv as argument. The function can then clear any device
 * instance-specific resources kept there. It must also clear the struct
 * pointed to by sdi->priv.
 *
 * @return SR_OK on success.
 */
SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver,
		std_dev_clear_t clear_private)
{
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	GSList *l;
	int ret;

	if (!(drvc = driver->priv))
		/* Driver was never initialized, nothing to do. */
		return SR_OK;

	ret = SR_OK;
	for (l = drvc->instances; l; l = l->next) {
		if (!(sdi = l->data)) {
			ret = SR_ERR_BUG;
			continue;
		}
		if (driver->dev_close)
			driver->dev_close(sdi);

		if (sdi->conn) {
#ifdef HAVE_LIBSERIALPORT
			if (sdi->inst_type == SR_INST_SERIAL)
				sr_serial_dev_inst_free(sdi->conn);
#endif
#ifdef HAVE_LIBUSB_1_0
			if (sdi->inst_type == SR_INST_USB)
				sr_usb_dev_inst_free(sdi->conn);
#endif
			if (sdi->inst_type == SR_INST_SCPI)
				sr_scpi_free(sdi->conn);
		}
		if (clear_private)
			clear_private(sdi->priv);
		else
			g_free(sdi->priv);
		sr_dev_inst_free(sdi);
	}

	g_slist_free(drvc->instances);
	drvc->instances = NULL;

	return ret;
}
Esempio n. 4
0
File: api.c Progetto: jeras/sigrok
static int hw_cleanup(void)
{
	GSList *l;
	struct sr_dev_inst *sdi;
	struct context *ctx;

	/* Properly close and free all devices. */
	for (l = genericdmm_dev_insts; l; l = l->next) {
		if (!(sdi = l->data)) {
			/* Log error, but continue cleaning up the rest. */
			sr_err("genericdmm: sdi was NULL, continuing.");
			continue;
		}
		if (!(ctx = sdi->priv)) {
			/* Log error, but continue cleaning up the rest. */
			sr_err("genericdmm: sdi->priv was NULL, continuing.");
			continue;
		}

		if (ctx->profile) {
			switch (ctx->profile->transport) {
			case DMM_TRANSPORT_USBHID:
				/* TODO */
				break;
			case DMM_TRANSPORT_SERIAL:
				if (ctx->serial && ctx->serial->fd != -1)
					serial_close(ctx->serial->fd);
				sr_serial_dev_inst_free(ctx->serial);
				break;
			}
		}

		sr_dev_inst_free(sdi);
	}

	g_slist_free(genericdmm_dev_insts);
	genericdmm_dev_insts = NULL;

	if (genericdmm_usb_context)
		libusb_exit(genericdmm_usb_context);

	return SR_OK;
}
Esempio n. 5
0
static int hw_cleanup(void)
{
	GSList *l;
	struct sr_dev_inst *sdi;

	for (l = dev_insts; l; l = l->next) {
		sdi = l->data;
		/* Properly close all devices... */
		close_dev(sdi);
		/* ...and free all their memory. */
		sr_dev_inst_free(sdi);
	}
	g_slist_free(dev_insts);
	dev_insts = NULL;

	if (usb_context)
		libusb_exit(usb_context);
	usb_context = NULL;

	return SR_OK;
}
Esempio n. 6
0
static GSList *hw_scan(GSList *options)
{
	int i;
	GSList *devices = NULL;
	const char *conn = NULL;
	const char *serialcomm = NULL;
	GSList *l;
	struct sr_config *src;
	struct udev *udev;

	(void)options;

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

	udev = udev_new();
	if (!udev) {
		sr_err("Failed to initialize udev.");
	}

	struct udev_enumerate *enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
	udev_enumerate_scan_devices(enumerate);
	struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate);
	struct udev_list_entry *dev_list_entry;
	for (dev_list_entry = devs;
	     dev_list_entry != NULL;
	     dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
		const char *syspath = udev_list_entry_get_name(dev_list_entry);
		struct udev_device *dev =
		    udev_device_new_from_syspath(udev, syspath);
		const char *sysname = udev_device_get_sysname(dev);
		struct udev_device *parent =
		    udev_device_get_parent_with_subsystem_devtype(dev, "usb",
								  "usb_device");

		if (!parent) {
			sr_err("Unable to find parent usb device for %s",
			       sysname);
			continue;
		}

		const char *idVendor =
		    udev_device_get_sysattr_value(parent, "idVendor");
		const char *idProduct =
		    udev_device_get_sysattr_value(parent, "idProduct");
		if (strcmp(USB_VENDOR, idVendor)
		    || strcmp(USB_PRODUCT, idProduct))
			continue;

		const char *iSerial =
		    udev_device_get_sysattr_value(parent, "serial");
		const char *iProduct =
		    udev_device_get_sysattr_value(parent, "product");

		char path[32];
		snprintf(path, sizeof(path), "/dev/%s", sysname);
		conn = path;

		size_t s = strcspn(iProduct, " ");
		char product[32];
		char manufacturer[32];
		if (s > sizeof(product) ||
		    strlen(iProduct) - s > sizeof(manufacturer)) {
			sr_err("Could not parse iProduct: %s.", iProduct);
			continue;
		}
		strncpy(product, iProduct, s);
		product[s] = 0;
		strcpy(manufacturer, iProduct + s + 1);

		//Create the device context and set its params
		struct dev_context *devc;
		if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
			sr_err("Device context malloc failed.");
			return devices;
		}

		if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) {
			sr_err("Invalid iSerial: %s.", iSerial);
			g_free(devc);
			return devices;
		}

		char hwrev[32];
		sprintf(hwrev, "r%d", devc->hwrev);
		devc->ctlbase1 = 0;
		devc->protocol_trigger.spimode = 0;
		for (i = 0; i < 4; i++) {
			devc->protocol_trigger.word[i] = 0;
			devc->protocol_trigger.mask[i] = 0xff;
		}

		if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm))) {
			g_free(devc);
			return devices;
		}

		struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
						manufacturer, product, hwrev);

		if (!sdi) {
			sr_err("Unable to create device instance for %s",
			       sysname);
			sr_dev_inst_free(sdi);
			g_free(devc);
			return devices;
		}

		sdi->driver = di;
		sdi->priv = devc;

		for (i = 0; i < NUM_PROBES; i++) {
			struct sr_probe *probe;
			if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
						   mso19_probe_names[i])))
				return 0;
			sdi->probes = g_slist_append(sdi->probes, probe);
		}

		//Add the driver
		struct drv_context *drvc = di->priv;
		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);
	}

	return devices;
}
Esempio n. 7
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	int i, model_id;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	GSList *devices, *l;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;
	char reply[50], **tokens, *dummy;

	drvc = di->context;
	drvc->instances = NULL;
	devices = NULL;
	conn = NULL;
	serialcomm = NULL;
	devc = 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;
		default:
			sr_err("Unknown option %d, skipping.", src->key);
			break;
		}
	}

	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = "9600/8n1";

	serial = sr_serial_dev_inst_new(conn, serialcomm);

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

	serial_flush(serial);

	sr_info("Probing serial port %s.", conn);

	/* Get the device model. */
	memset(&reply, 0, sizeof(reply));
	if ((hcs_send_cmd(serial, "GMOD\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		return NULL;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);

	model_id = -1;
	for (i = 0; models[i].id != NULL; i++) {
		if (!strcmp(models[i].id, tokens[0]))
			model_id = i;
	}
	if (model_id < 0) {
		sr_err("Unknown model ID '%s' detected, aborting.", tokens[0]);
		g_strfreev(tokens);
		return NULL;
	}
	g_strfreev(tokens);

	/* Init device instance, etc. */
	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Manson");
	sdi->model = g_strdup(models[model_id].name);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->driver = di;

	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	devc->model = &models[model_id];

	sdi->priv = devc;

	/* Get current voltage, current, status. */
	if ((hcs_send_cmd(serial, "GETD\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		goto exit_err;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);
	if (hcs_parse_volt_curr_mode(sdi, tokens) < 0) {
		g_strfreev(tokens);
		goto exit_err;
	}
	g_strfreev(tokens);

	/* Get max. voltage and current. */
	if ((hcs_send_cmd(serial, "GMAX\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		goto exit_err;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);
	devc->current_max_device = g_strtod(&tokens[0][3], &dummy) * devc->model->current[2];
	tokens[0][3] = '\0';
	devc->voltage_max_device = g_strtod(tokens[0], &dummy) * devc->model->voltage[2];
	g_strfreev(tokens);

	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;

exit_err:
	sr_dev_inst_free(sdi);
	g_free(devc);

	return NULL;
}
Esempio n. 8
0
/**
 * Scan for Metrahit 2x in a bidirectional mode using Gossen Metrawatt
 * 'BD 232' interface.
 */
static GSList *scan_2x_bd232(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	int cnt, byte;
	gint64 timeout_us;

	sdi = NULL;
	devc = NULL;
	conn = serialcomm = NULL;
	devices = NULL;

	drvc = di->context;
	drvc->instances = NULL;

	sr_spew("scan_2x_bd232() called!");

	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_2X;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		goto exit_err;

	devc = g_malloc0(sizeof(struct dev_context));

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(VENDOR_GMC);
	sdi->priv = devc;

	/* Send message 03 "Query multimeter version and status" */
	sdi->conn = serial;
	if (req_stat14(sdi, TRUE) != SR_OK)
		goto exit_err;

	/* Wait for reply from device(s) for up to 2s. */
	timeout_us = g_get_monotonic_time() + (2 * 1000 * 1000);

	while (timeout_us > g_get_monotonic_time()) {
		/* Receive reply (14 bytes) */
		devc->buflen = 0;
		for (cnt = 0; cnt < GMC_REPLY_SIZE; cnt++) {
			byte = read_byte(serial, timeout_us);
			if (byte != -1)
				devc->buf[devc->buflen++] = (byte & MASK_6BITS);
		}

		if (devc->buflen != GMC_REPLY_SIZE)
			continue;

		devc->addr = devc->buf[0];
		process_msg14(sdi);
		devc->buflen = 0;

		if (devc->model != METRAHIT_NONE) {
			sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(devc->model));
			devc->elapsed_msec = g_timer_new();
			sdi->model = g_strdup(gmc_model_str(devc->model));
			sdi->version = g_strdup_printf("Firmware %d.%d", devc->fw_ver_maj, devc->fw_ver_min);
			sdi->conn = serial;
			sdi->priv = devc;
			sdi->driver = di;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");
			drvc->instances = g_slist_append(drvc->instances, sdi);
			devices = g_slist_append(devices, sdi);
			devc = g_malloc0(sizeof(struct dev_context));
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup(VENDOR_GMC);
		}
	};

	/* Free last alloc if no device found */
	if (devc->model == METRAHIT_NONE) {
		g_free(devc);
		sr_dev_inst_free(sdi);
	}

	return devices;

exit_err:
	sr_info("scan_2x_bd232(): Error!");

	if (serial)
		sr_serial_dev_inst_free(serial);
	g_free(devc);
	if (sdi)
		sr_dev_inst_free(sdi);

	return NULL;
}
Esempio n. 9
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	GSList *devices, *l;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;
	char reply[50];
	int i, model_id;
	unsigned int len;

	devices = NULL;
	conn = NULL;
	serialcomm = NULL;
	drvc = di->context;
	drvc->instances = 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;
		default:
			sr_err("Unknown option %d, skipping.", src->key);
			break;
		}
	}

	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = "9600/8n1";

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

	serial_flush(serial);

	/* Get the device model. */
	len = 0;
	for (i = 0; models[i].id; i++) {
		if (strlen(models[i].id) > len)
			len = strlen(models[i].id);
	}
	memset(&reply, 0, sizeof(reply));
	sr_dbg("Want max %d bytes.", len);
	if ((korad_kdxxxxp_send_cmd(serial, "*IDN?") < 0))
		return NULL;

	/* i is used here for debug purposes only. */
	if ((i = korad_kdxxxxp_read_chars(serial, len, reply)) < 0)
		return NULL;
	sr_dbg("Received: %d, %s", i, reply);
	model_id = -1;
	for (i = 0; models[i].id; i++) {
		if (!strcmp(models[i].id, reply))
			model_id = i;
	}
	if (model_id < 0) {
		sr_err("Unknown model ID '%s' detected, aborting.", reply);
		return NULL;
	}
	sr_dbg("Found: %s %s", models[model_id].vendor, models[model_id].name);

	/* Init device instance, etc. */
	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(models[model_id].vendor);
	sdi->model = g_strdup(models[model_id].name);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->driver = di;

	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	devc = g_malloc0(sizeof(struct dev_context));
	devc->model = &models[model_id];
	devc->reply[5] = 0;
	devc->req_sent_at = 0;
	sdi->priv = devc;

	/* Get current status of device. */
	if (korad_kdxxxxp_get_all_values(serial, devc) < 0)
		goto exit_err;
	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;

exit_err:
	sr_dev_inst_free(sdi);
	g_free(devc);
	sr_dbg("Scan failed.");

	return NULL;
}