+ sdi->status = SR_ST_INACTIVE;
+
+ sr_dbg("%s: Closing device instance.", sdi->driver->name);
+
+ return sdi->driver->dev_close(sdi);
+}
+
+/**
+ * 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)
+{
+#ifdef HAVE_LIBUSB_1_0
+ struct drv_context *drvc;
+ int cnt, i, a, b;
+ char conn_id_usb[64];
+ struct sr_usb_dev_inst *usb;
+ struct libusb_device **devlist;
+#endif
+
+#ifdef HAVE_SERIAL_COMM
+ struct sr_serial_dev_inst *serial;
+#endif
+
+ struct sr_scpi_dev_inst *scpi;
+ char *conn_id_scpi;
+
+ if (!sdi)
+ return NULL;
+
+#ifdef HAVE_SERIAL_COMM
+ if ((!sdi->connection_id) && (sdi->inst_type == SR_INST_SERIAL)) {
+ /* connection_id isn't populated, let's do that for serial devices. */
+
+ 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 for USB devices. */
+
+ drvc = sdi->driver->context;
+ 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++) {
+ /* 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;
+
+ if (usb_get_port_path(devlist[i], conn_id_usb, sizeof(conn_id_usb)) < 0)
+ continue;
+
+ ((struct sr_dev_inst *)sdi)->connection_id = g_strdup(conn_id_usb);
+ break;
+ }
+
+ libusb_free_device_list(devlist, 1);
+ }
+#endif
+
+ if ((!sdi->connection_id) && (sdi->inst_type == SR_INST_SCPI)) {
+ /* connection_id isn't populated, let's do that for SCPI devices. */
+
+ scpi = sdi->conn;
+ sr_scpi_connection_id(scpi, &conn_id_scpi);
+ ((struct sr_dev_inst *)sdi)->connection_id = g_strdup(conn_id_scpi);
+ g_free(conn_id_scpi);
+ }
+
+ 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;