Esempio n. 1
0
/**
 * Allocate and initialize a struct for a Modbus device instance.
 *
 * @param resource The resource description string.
 * @param serialcomm Additionnal parameters for serial port resources.
 *
 * @return The allocated sr_modbus_dev_inst structure or NULL on failure.
 */
SR_PRIV struct sr_modbus_dev_inst *modbus_dev_inst_new(const char *resource,
        const char *serialcomm, int modbusaddr)
{
    struct sr_modbus_dev_inst *modbus = NULL;
    const struct sr_modbus_dev_inst *modbus_dev;
    gchar **params;
    unsigned int i;

    for (i = 0; i < modbus_devs_size; i++) {
        modbus_dev = modbus_devs[i];
        if (!strncmp(resource, modbus_dev->prefix, strlen(modbus_dev->prefix))) {
            sr_dbg("Opening %s device %s.", modbus_dev->name, resource);
            modbus = g_malloc(sizeof(*modbus));
            *modbus = *modbus_dev;
            modbus->priv = g_malloc0(modbus->priv_size);
            modbus->read_timeout_ms = 1000;
            params = g_strsplit(resource, "/", 0);
            if (modbus->dev_inst_new(modbus->priv, resource,
                                     params, serialcomm, modbusaddr) != SR_OK) {
                sr_modbus_free(modbus);
                modbus = NULL;
            }
            g_strfreev(params);
            break;
        }
    }

    return modbus;
}
Esempio n. 2
0
/**
 * Standard driver dev_clear() helper.
 *
 * Clear driver, this means, close all instances.
 *
 * 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_callback clear_private)
{
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	GSList *l;
	int ret;

	if (!(drvc = driver->context))
		/* 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 (sdi->inst_type == SR_INST_MODBUS)
				sr_modbus_free(sdi->conn);
		}
		if (clear_private)
			/* The helper function is responsible for freeing
			 * its own sdi->priv! */
			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. 3
0
static struct sr_dev_inst *sr_modbus_scan_resource(const char *resource,
        const char *serialcomm, int modbusaddr,
        struct sr_dev_inst *(*probe_device)(struct sr_modbus_dev_inst *modbus))
{
    struct sr_modbus_dev_inst *modbus;
    struct sr_dev_inst *sdi;

    if (!(modbus = modbus_dev_inst_new(resource, serialcomm, modbusaddr)))
        return NULL;

    if (sr_modbus_open(modbus) != SR_OK) {
        sr_info("Couldn't open Modbus device.");
        sr_modbus_free(modbus);
        return NULL;
    };

    if ((sdi = probe_device(modbus)))
        return sdi;

    sr_modbus_close(modbus);
    sr_modbus_free(modbus);

    return NULL;
}