}
/** @private
- * Allocate and init new device instance struct.
- * @param[in] index @copydoc sr_dev_inst::index
- * @param[in] status @copydoc sr_dev_inst::status
- * @param[in] vendor @copydoc sr_dev_inst::vendor
- * @param[in] model @copydoc sr_dev_inst::model
- * @param[in] version @copydoc sr_dev_inst::version
+ * Allocate and init a new device instance struct.
*
- * @retval NULL Error
* @retval struct sr_dev_inst *. Dynamically allocated, free using
* sr_dev_inst_free().
*/
-SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int status,
- const char *vendor, const char *model, const char *version)
+SR_PRIV struct sr_dev_inst *sr_dev_inst_new(void)
{
struct sr_dev_inst *sdi;
- if (!(sdi = g_try_malloc(sizeof(struct sr_dev_inst)))) {
- sr_err("Device instance malloc failed.");
- return NULL;
- }
+ sdi = g_malloc0(sizeof(struct sr_dev_inst));
sdi->driver = NULL;
- sdi->status = status;
+ sdi->status = -1;
sdi->inst_type = -1;
- sdi->vendor = vendor ? g_strdup(vendor) : NULL;
- sdi->model = model ? g_strdup(model) : NULL;
- sdi->version = version ? g_strdup(version) : NULL;
+ sdi->vendor = NULL;
+ sdi->model = NULL;
+ sdi->version = NULL;
sdi->serial_num = NULL;
sdi->connection_id = NULL;
sdi->channels = NULL;
return sdi;
}
+/**
+ * Allocate and init a new user-generated device instance.
+ */
+SR_API struct sr_dev_inst *sr_dev_inst_user_new(const char *vendor,
+ const char *model, const char *version)
+{
+ struct sr_dev_inst *sdi;
+
+ sdi = sr_dev_inst_new();
+ sdi->vendor = g_strdup(vendor);
+ sdi->model = g_strdup(model);
+ sdi->version = g_strdup(version);
+ sdi->inst_type = SR_INST_USER;
+
+ return sdi;
+}
+
+/**
+ * Add a new channel to the specified device instance.
+ */
+SR_API int sr_dev_inst_channel_add(struct sr_dev_inst *sdi, int index, int type, const char *name)
+{
+ struct sr_channel *ch;
+
+ if (!sdi || sdi->inst_type != SR_INST_USER || index < 0)
+ return SR_ERR_ARG;
+
+ ch = sr_channel_new(index, type, TRUE, name);
+ if (!ch)
+ return SR_ERR;
+
+ sdi->channels = g_slist_append(sdi->channels, ch);
+
+ return SR_OK;
+}
+
/** @private
* Free device instance struct created by sr_dev_inst().
- * @param sdi struct* to free.
+ * @param sdi device instance to free.
*/
SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
{
struct sr_channel *ch;
+ struct sr_channel_group *cg;
GSList *l;
for (l = sdi->channels; l; l = l->next) {
}
g_slist_free(sdi->channels);
- if (sdi->channel_groups)
- g_slist_free(sdi->channel_groups);
+ for (l = sdi->channel_groups; l; l = l->next) {
+ cg = l->data;
+ g_free(cg->name);
+ g_slist_free(cg->channels);
+ g_free(cg->priv);
+ g_free(cg);
+ }
+ g_slist_free(sdi->channel_groups);
g_free(sdi->vendor);
g_free(sdi->model);
return ret;
}
+/**
+ * Queries a device instances' driver.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The driver instance or NULL on error.
+ */
+SR_API struct sr_dev_driver *sr_dev_inst_driver_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi || !sdi->driver)
+ return NULL;
+
+ return sdi->driver;
+}
+
+/**
+ * Queries a device instances' vendor.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The vendor string or NULL.
+ */
+SR_API const char *sr_dev_inst_vendor_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->vendor;
+}
+
+/**
+ * Queries a device instances' model.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The model string or NULL.
+ */
+SR_API const char *sr_dev_inst_model_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->model;
+}
+
+/**
+ * Queries a device instances' version.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The version string or NULL.
+ */
+SR_API const char *sr_dev_inst_version_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->version;
+}
+
+/**
+ * Queries a device instances' serial number.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The serial number string or NULL.
+ */
+SR_API const char *sr_dev_inst_sernum_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->serial_num;
+}
+
+/**
+ * Queries a device instances' connection identifier.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return A copy of the connection id string or NULL. The caller is responsible
+ * for g_free()ing the string when it is no longer needed.
+ */
+SR_API const char *sr_dev_inst_connid_get(const struct sr_dev_inst *sdi)
+{
+ struct drv_context *drvc;
+ int r, cnt, i, a, b;
+ char connection_id[64];
+
+#ifdef HAVE_LIBUSB_1_0
+ struct sr_usb_dev_inst *usb;
+ struct libusb_device **devlist;
+ struct libusb_device_descriptor des;
+#endif
+
+ if (!sdi)
+ return NULL;
+
+#ifdef HAVE_LIBSERIALPORT
+ struct sr_serial_dev_inst *serial;
+
+ if ((!sdi->connection_id) && (sdi->inst_type == SR_INST_SERIAL)) {
+ /* connection_id isn't populated, let's do that here. */
+
+ serial = sdi->conn;
+ ((struct sr_dev_inst *)sdi)->connection_id = g_strdup(serial->port);
+ }
+#endif
+
+
+#ifdef HAVE_LIBUSB_1_0
+ if ((!sdi->connection_id) && (sdi->inst_type == SR_INST_USB)) {
+ /* connection_id isn't populated, let's do that here. */
+
+ drvc = sdi->driver->priv;
+ usb = sdi->conn;
+
+ if ((cnt = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist)) < 0) {
+ sr_err("Failed to retrieve device list: %s.",
+ libusb_error_name(cnt));
+ return NULL;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ if ((r = libusb_get_device_descriptor(devlist[i], &des)) < 0) {
+ sr_err("Failed to get device descriptor: %s.",
+ libusb_error_name(r));
+ continue;
+ }
+
+ /* Find the USB device by the logical address we know. */
+ b = libusb_get_bus_number(devlist[i]);
+ a = libusb_get_device_address(devlist[i]);
+ if (b != usb->bus || a != usb->address)
+ continue;
+
+ usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
+ ((struct sr_dev_inst *)sdi)->connection_id = g_strdup(connection_id);
+ break;
+ }
+
+ libusb_free_device_list(devlist, 1);
+ }
+#endif
+
+ return sdi->connection_id;
+}
+
+/**
+ * Queries a device instances' channel list.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The GSList of channels or NULL.
+ */
+SR_API GSList *sr_dev_inst_channels_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->channels;
+}
+
+/**
+ * Queries a device instances' channel groups list.
+ *
+ * @param sdi Device instance to use. Must not be NULL.
+ *
+ * @return The GSList of channel groups or NULL.
+ */
+SR_API GSList *sr_dev_inst_channel_groups_get(const struct sr_dev_inst *sdi)
+{
+ if (!sdi)
+ return NULL;
+
+ return sdi->channel_groups;
+}
+
/** @} */