* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include <stdio.h>
#include <glib.h>
-#include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
-#include "libsigrok.h"
+#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
/** @cond PRIVATE */
*/
/** @private
- * Allocate and initialize new struct sr_channel
+ * Allocate and initialize new struct sr_channel and add to sdi.
+ * @param[in] sdi The device instance the channel is connected to.
* @param[in] index @copydoc sr_channel::index
* @param[in] type @copydoc sr_channel::type
* @param[in] enabled @copydoc sr_channel::enabled
*
* @return A new struct sr_channel*.
*/
-SR_PRIV struct sr_channel *sr_channel_new(int index, int type,
- gboolean enabled, const char *name)
+SR_PRIV struct sr_channel *sr_channel_new(struct sr_dev_inst *sdi,
+ int index, int type, gboolean enabled, const char *name)
{
struct sr_channel *ch;
ch = g_malloc0(sizeof(struct sr_channel));
+ ch->sdi = sdi;
ch->index = index;
ch->type = type;
ch->enabled = enabled;
if (name)
ch->name = g_strdup(name);
+ sdi->channels = g_slist_append(sdi->channels, ch);
+
return ch;
}
/**
- * Set the name of the specified channel in the specified device.
+ * Set the name of the specified channel.
*
* If the channel already has a different name assigned to it, it will be
* removed, and the new name will be saved instead.
*
- * @param sdi The device instance the channel is connected to.
- * @param[in] channelnum The number of the channel whose name to set.
- * Note that the channel numbers start at 0.
- * @param[in] name The new name that the specified channel should get. A copy
- * of the string is made.
+ * @param[in] channel The channel whose name to set.
+ * @param[in] name The new name that the specified channel should get. A
+ * copy of the string is made.
*
* @return SR_OK on success, or SR_ERR_ARG on invalid arguments.
*
* @since 0.3.0
*/
-SR_API int sr_dev_channel_name_set(const struct sr_dev_inst *sdi,
- int channelnum, const char *name)
+SR_API int sr_dev_channel_name_set(struct sr_channel *channel,
+ const char *name)
{
- GSList *l;
- struct sr_channel *ch;
- int ret;
-
- if (!sdi) {
- sr_err("%s: sdi was NULL", __func__);
+ if (!channel) {
+ sr_err("%s: channel was NULL", __func__);
return SR_ERR_ARG;
}
- ret = SR_ERR_ARG;
- for (l = sdi->channels; l; l = l->next) {
- ch = l->data;
- if (ch->index == channelnum) {
- g_free(ch->name);
- ch->name = g_strdup(name);
- ret = SR_OK;
- break;
- }
- }
-
- return ret;
+ g_free(channel->name);
+ channel->name = g_strdup(name);
+ return SR_OK;
}
/**
- * Enable or disable a channel on the specified device.
+ * Enable or disable a channel.
*
- * @param sdi The device instance the channel is connected to.
- * @param channelnum The channel number, starting from 0.
- * @param state TRUE to enable the channel, FALSE to disable.
+ * @param[in] channel The channel to enable or disable.
+ * @param[in] state TRUE to enable the channel, FALSE to disable.
*
* @return SR_OK on success or SR_ERR on failure. In case of invalid
* arguments, SR_ERR_ARG is returned and the channel enabled state
*
* @since 0.3.0
*/
-SR_API int sr_dev_channel_enable(const struct sr_dev_inst *sdi, int channelnum,
+SR_API int sr_dev_channel_enable(struct sr_channel *channel,
gboolean state)
{
- GSList *l;
- struct sr_channel *ch;
int ret;
gboolean was_enabled;
+ struct sr_dev_inst *sdi;
- if (!sdi)
+ if (!channel)
return SR_ERR_ARG;
- ret = SR_ERR_ARG;
- for (l = sdi->channels; l; l = l->next) {
- ch = l->data;
- if (ch->index == channelnum) {
- was_enabled = ch->enabled;
- ch->enabled = state;
- ret = SR_OK;
- if (!state != !was_enabled && sdi->driver
- && sdi->driver->config_channel_set) {
- ret = sdi->driver->config_channel_set(
- sdi, ch, SR_CHANNEL_SET_ENABLED);
- /* Roll back change if it wasn't applicable. */
- if (ret == SR_ERR_ARG)
- ch->enabled = was_enabled;
- }
- break;
- }
+ sdi = channel->sdi;
+ was_enabled = channel->enabled;
+ channel->enabled = state;
+ if (!state != !was_enabled && sdi->driver
+ && sdi->driver->config_channel_set) {
+ ret = sdi->driver->config_channel_set(
+ sdi, channel, SR_CHANNEL_SET_ENABLED);
+ /* Roll back change if it wasn't applicable. */
+ if (ret != SR_OK)
+ return ret;
}
- return ret;
+ return SR_OK;
+}
+
+/* Returns the next enabled channel, wrapping around if necessary. */
+SR_PRIV struct sr_channel *sr_next_enabled_channel(const struct sr_dev_inst *sdi,
+ struct sr_channel *cur_channel)
+{
+ struct sr_channel *next_channel;
+ GSList *l;
+
+ next_channel = cur_channel;
+ do {
+ l = g_slist_find(sdi->channels, next_channel);
+ if (l && l->next)
+ next_channel = l->next->data;
+ else
+ next_channel = sdi->channels->data;
+ } while (!next_channel->enabled);
+
+ return next_channel;
}
/**
*/
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);
- sdi->channels = g_slist_append(sdi->channels, ch);
+ sr_channel_new(sdi, index, type, TRUE, name);
return SR_OK;
}
}
g_slist_free(sdi->channel_groups);
+ if (sdi->session)
+ sr_session_dev_remove(sdi->session, sdi);
+
g_free(sdi->vendor);
g_free(sdi->model);
g_free(sdi->version);
SR_API GSList *sr_dev_list(const struct sr_dev_driver *driver)
{
if (driver && driver->dev_list)
- return driver->dev_list();
+ return driver->dev_list(driver);
else
return NULL;
}
}
if (driver->dev_clear)
- ret = driver->dev_clear();
+ ret = driver->dev_clear(driver);
else
ret = std_dev_clear(driver, NULL);
*/
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 r, cnt, i, a, b;
+ int 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)
}
#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;
+ drvc = sdi->driver->context;
usb = sdi->conn;
if ((cnt = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist)) < 0) {
}
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]);