static void init_device_list(void) { unsigned int i, num = iio_context_get_devices_count(ctx); GtkTreeIter iter; gtk_list_store_clear(device_list_store); for (i = 0; i < num; i++) { struct iio_device *dev = iio_context_get_device(ctx, i); unsigned int j, nch = iio_device_get_channels_count(dev); const char *id; bool found_valid_chan = false; for (j = 0; !found_valid_chan && j < nch; j++) { struct iio_channel *chn = iio_device_get_channel(dev, j); found_valid_chan = is_valid_dmm_channel(chn); } if (!found_valid_chan) continue; id = iio_device_get_name(dev); if (!id) id = iio_device_get_id(dev); gtk_list_store_append(device_list_store, &iter); gtk_list_store_set(device_list_store, &iter, 0, id, 1, 0, -1); } gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(GTK_TREE_MODEL(device_list_store)), 0, GTK_SORT_ASCENDING); }
static void iio_widget_init(struct iio_widget *widget, struct iio_device *dev, struct iio_channel *chn, const char *attr_name, const char *attr_name_avail, GtkWidget *gtk_widget, void *priv, void (*update)(struct iio_widget *), void (*update_value)(struct iio_widget *, const char *, size_t), void (*save)(struct iio_widget *)) { if (!gtk_widget) { const char *name = iio_device_get_name(dev) ?: iio_device_get_id(dev); printf("Missing widget for %s/%s\n", name, attr_name); } memset(widget, 0, sizeof(*widget)); widget->dev = dev; widget->chn = chn; widget->attr_name = attr_name; widget->attr_name_avail = attr_name_avail; widget->widget = gtk_widget; widget->update = update; widget->update_value = update_value; widget->save = save; widget->priv = priv; }
int iiod_client_close_unlocked(struct iiod_client *client, int desc, const struct iio_device *dev) { char buf[1024]; snprintf(buf, sizeof(buf), "CLOSE %s\r\n", iio_device_get_id(dev)); return iiod_client_exec_command(client, desc, buf); }
ssize_t iiod_client_read_attr(struct iiod_client *client, int desc, const struct iio_device *dev, const struct iio_channel *chn, const char *attr, char *dest, size_t len, bool is_debug) { const char *id = iio_device_get_id(dev); char buf[1024]; ssize_t ret; if (attr) { if (chn) { if (!iio_channel_find_attr(chn, attr)) return -ENOENT; } else if (is_debug) { if (!iio_device_find_debug_attr(dev, attr)) return -ENOENT; } else { if (!iio_device_find_attr(dev, attr)) return -ENOENT; } } if (chn) snprintf(buf, sizeof(buf), "READ %s %s %s %s\r\n", id, iio_channel_is_output(chn) ? "OUTPUT" : "INPUT", iio_channel_get_id(chn), attr ? attr : ""); else if (is_debug) snprintf(buf, sizeof(buf), "READ %s DEBUG %s\r\n", id, attr ? attr : ""); else snprintf(buf, sizeof(buf), "READ %s %s\r\n", id, attr ? attr : ""); iio_mutex_lock(client->lock); ret = (ssize_t) iiod_client_exec_command(client, desc, buf); if (ret < 0) goto out_unlock; if ((size_t) ret + 1 > len) { ret = -EIO; goto out_unlock; } /* +1: Also read the trailing \n */ ret = iiod_client_read_all(client, desc, dest, ret + 1); if (ret > 0) { /* Discard the trailing \n */ ret--; /* Replace it with a \0 just in case */ dest[ret] = '\0'; } out_unlock: iio_mutex_unlock(client->lock); return ret; }
int iiod_client_set_trigger(struct iiod_client *client, int desc, const struct iio_device *dev, const struct iio_device *trigger) { char buf[1024]; int ret; if (trigger) snprintf(buf, sizeof(buf), "SETTRIG %s %s\r\n", iio_device_get_id(dev), iio_device_get_id(trigger)); else snprintf(buf, sizeof(buf), "SETTRIG %s\r\n", iio_device_get_id(dev)); iio_mutex_lock(client->lock); ret = iiod_client_exec_command(client, desc, buf); iio_mutex_unlock(client->lock); return ret; }
ssize_t iiod_client_write_attr(struct iiod_client *client, int desc, const struct iio_device *dev, const struct iio_channel *chn, const char *attr, const char *src, size_t len, bool is_debug) { struct iio_context_pdata *pdata = client->pdata; const struct iiod_client_ops *ops = client->ops; const char *id = iio_device_get_id(dev); char buf[1024]; ssize_t ret; int resp; if (attr) { if (chn) { if (!iio_channel_find_attr(chn, attr)) return -ENOENT; } else if (is_debug) { if (!iio_device_find_debug_attr(dev, attr)) return -ENOENT; } else { if (!iio_device_find_attr(dev, attr)) return -ENOENT; } } if (chn) snprintf(buf, sizeof(buf), "WRITE %s %s %s %s %lu\r\n", id, iio_channel_is_output(chn) ? "OUTPUT" : "INPUT", iio_channel_get_id(chn), attr ? attr : "", (unsigned long) len); else if (is_debug) snprintf(buf, sizeof(buf), "WRITE %s DEBUG %s %lu\r\n", id, attr ? attr : "", (unsigned long) len); else snprintf(buf, sizeof(buf), "WRITE %s %s %lu\r\n", id, attr ? attr : "", (unsigned long) len); iio_mutex_lock(client->lock); ret = ops->write(pdata, desc, buf, strlen(buf)); if (ret < 0) goto out_unlock; ret = iiod_client_write_all(client, desc, src, len); if (ret < 0) goto out_unlock; ret = iiod_client_read_integer(client, desc, &resp); if (ret < 0) goto out_unlock; ret = (ssize_t) resp; out_unlock: iio_mutex_unlock(client->lock); return ret; }
bool iio_device_is_trigger(const struct iio_device *dev) { /* A trigger has a name, an id which starts by "trigger", * and zero channels. */ unsigned int nb = iio_device_get_channels_count(dev); const char *name = iio_device_get_name(dev), *id = iio_device_get_id(dev); return ((nb == 0) && !!name && !strncmp(id, "trigger", sizeof("trigger") - 1)); }
int iiod_client_get_trigger(struct iiod_client *client, int desc, const struct iio_device *dev, const struct iio_device **trigger) { const struct iio_context *ctx = iio_device_get_context(dev); unsigned int i, nb_devices = iio_context_get_devices_count(ctx); char buf[1024]; unsigned int name_len; int ret; snprintf(buf, sizeof(buf), "GETTRIG %s\r\n", iio_device_get_id(dev)); iio_mutex_lock(client->lock); ret = iiod_client_exec_command(client, desc, buf); if (ret == 0) *trigger = NULL; if (ret <= 0) goto out_unlock; if ((unsigned int) ret > sizeof(buf) - 1) { ret = -EIO; goto out_unlock; } name_len = ret; ret = (int) iiod_client_read_all(client, desc, buf, name_len + 1); if (ret < 0) goto out_unlock; ret = -ENXIO; for (i = 0; i < nb_devices; i++) { struct iio_device *cur = iio_context_get_device(ctx, i); if (iio_device_is_trigger(cur)) { const char *name = iio_device_get_name(cur); if (!name) continue; if (!strncmp(name, buf, name_len)) { *trigger = cur; ret = 0; goto out_unlock; } } } out_unlock: iio_mutex_unlock(client->lock); return ret; }
static struct iio_device * get_device(const char *id) { unsigned int i, nb = iio_context_get_devices_count(ctx); for (i = 0; i < nb; i++) { struct iio_device *dev = iio_context_get_device(ctx, i); const char *name = iio_device_get_name(dev); if (!strcmp(id, iio_device_get_id(dev)) || (name && !strcmp(name, id))) return dev; } return NULL; }
int iiod_client_set_kernel_buffers_count(struct iiod_client *client, int desc, const struct iio_device *dev, unsigned int nb_blocks) { int ret; char buf[1024]; snprintf(buf, sizeof(buf), "SET %s BUFFERS_COUNT %u\r\n", iio_device_get_id(dev), nb_blocks); iio_mutex_lock(client->lock); ret = iiod_client_exec_command(client, desc, buf); iio_mutex_unlock(client->lock); return ret; }
/* * Disconnect the callback of the "value-changed" event from the progress * spinbutton. */ void iio_spin_button_progress_deactivate(struct iio_widget *iio_w) { struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { const char *name = iio_device_get_name(iio_w->dev) ?: iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", iio_w->attr_name, name); return; } g_signal_handler_disconnect(iio_w->widget, pdata->value_changed_hid); }
/* * Remove all implementation made to convert a iio_widget to a progress * spinbutton. */ void iio_spin_button_remove_progress(struct iio_widget *iio_w) { if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { const char *name = iio_device_get_name(iio_w->dev) ?: iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", iio_w->attr_name, name); return; } iio_spin_button_progress_deactivate(iio_w); if (iio_w->priv_progress) free(iio_w->priv_progress); }
ssize_t iiod_client_read_unlocked(struct iiod_client *client, int desc, const struct iio_device *dev, void *dst, size_t len, uint32_t *mask, size_t words) { unsigned int nb_channels = iio_device_get_channels_count(dev); uintptr_t ptr = (uintptr_t) dst; char buf[1024]; ssize_t ret, read = 0; if (!len || words != (nb_channels + 31) / 32) return -EINVAL; snprintf(buf, sizeof(buf), "READBUF %s %lu\r\n", iio_device_get_id(dev), (unsigned long) len); ret = iiod_client_write_all(client, desc, buf, strlen(buf)); if (ret < 0) return ret; do { int to_read; ret = iiod_client_read_integer(client, desc, &to_read); if (ret < 0) return ret; if (to_read < 0) return (ssize_t) to_read; if (!to_read) break; if (mask) { ret = iiod_client_read_mask(client, desc, mask, words); if (ret < 0) return ret; mask = NULL; /* We read the mask only once */ } ret = iiod_client_read_all(client, desc, (char *) ptr, to_read); if (ret < 0) return ret; ptr += ret; read += ret; len -= ret; } while (len); return read; }
/* * In order for the progress spinbutton to work, this function must be called * to connect the required callback to the widget. */ void iio_spin_button_progress_activate(struct iio_widget *iio_w) { struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { const char *name = iio_device_get_name(iio_w->dev) ?: iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", iio_w->attr_name, name); return; } pdata->value_changed_hid = g_signal_connect(G_OBJECT(iio_w->widget), "value-changed", G_CALLBACK(delayed_spin_button_update_cb), iio_w); }
/* * Set a user function to be called when the progress is completed. The function * can take one generic pointer as parameter. */ void iio_spin_button_set_on_complete_function(struct iio_widget *iio_w, void(*on_complete)(void *), void *data) { struct progress_data *pdata = iio_w->priv_progress; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { const char *name = iio_device_get_name(iio_w->dev) ?: iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", iio_w->attr_name, name); return; } pdata->on_complete = on_complete; pdata->on_complete_data = data; }
int iiod_client_open_unlocked(struct iiod_client *client, int desc, const struct iio_device *dev, size_t samples_count, bool cyclic) { char buf[1024], *ptr; size_t i; snprintf(buf, sizeof(buf), "OPEN %s %lu ", iio_device_get_id(dev), (unsigned long) samples_count); ptr = buf + strlen(buf); for (i = dev->words; i > 0; i--, ptr += 8) snprintf(ptr, (ptr - buf) + i * 8, "%08" PRIx32, dev->mask[i - 1]); strcpy(ptr, cyclic ? " CYCLIC\r\n" : "\r\n"); return iiod_client_exec_command(client, desc, buf); }
/* * Customises a iio_widget that contains a GtkSpinButton widget to be able to * work as a progress spinbutton. */ void iio_spin_button_add_progress(struct iio_widget *iio_w) { struct progress_data *pdata; if (GTK_IS_SPIN_BUTTON(iio_w->widget) == FALSE) { const char *name = iio_device_get_name(iio_w->dev) ?: iio_device_get_id(iio_w->dev); printf("The widget connected to the attribute: %s of device: %s is not a GtkSpinButton\n", iio_w->attr_name, name); return; } pdata = malloc(sizeof(struct progress_data)); pdata->is_progress_spin_button = TRUE; pdata->progress = 0.0; pdata->timeoutID = -1; pdata->value_changed_hid = -1; pdata->skip_widget_save = FALSE; pdata->on_complete_data = NULL; pdata->on_complete = NULL; iio_w->priv_progress = pdata; }
static struct iio_device * get_device(const struct iio_context *ctx, const char *id) { unsigned int i, nb_devices = iio_context_get_devices_count(ctx); struct iio_device *device; for (i = 0; i < nb_devices; i++) { const char *name; device = iio_context_get_device(ctx, i); name = iio_device_get_name(device); if (name && !strcmp(name, id)) break; if (!strcmp(id, iio_device_get_id(device))) break; } if (i < nb_devices) return device; fprintf(stderr, "Device %s not found\n", id); return NULL; }
int main(int argc, char **argv) { struct iio_context *ctx; int c, option_index = 0, arg_index = 0; enum backend backend = LOCAL; unsigned int major, minor; char git_tag[8]; int ret; while ((c = getopt_long(argc, argv, "+hn:x:", options, &option_index)) != -1) { switch (c) { case 'h': usage(); return EXIT_SUCCESS; case 'n': if (backend != LOCAL) { ERROR("-x and -n are mutually exclusive\n"); return EXIT_FAILURE; } backend = NETWORK; arg_index += 2; break; case 'x': if (backend != LOCAL) { ERROR("-x and -n are mutually exclusive\n"); return EXIT_FAILURE; } backend = XML; arg_index += 2; break; case '?': return EXIT_FAILURE; } } if (arg_index >= argc) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(); return EXIT_FAILURE; } iio_library_get_version(&major, &minor, git_tag); INFO("Library version: %u.%u (git tag: %s)\n", major, minor, git_tag); if (backend == XML) ctx = iio_create_xml_context(argv[arg_index]); else if (backend == NETWORK) ctx = iio_create_network_context(argv[arg_index]); else ctx = iio_create_local_context(); if (!ctx) { ERROR("Unable to create IIO context\n"); return EXIT_FAILURE; } INFO("IIO context created with %s backend.\n", iio_context_get_name(ctx)); ret = iio_context_get_version(ctx, &major, &minor, git_tag); if (!ret) INFO("Backend version: %u.%u (git tag: %s)\n", major, minor, git_tag); else ERROR("Unable to get backend version: %i\n", ret); unsigned int nb_devices = iio_context_get_devices_count(ctx); INFO("IIO context has %u devices:\n", nb_devices); unsigned int i; for (i = 0; i < nb_devices; i++) { const struct iio_device *dev = iio_context_get_device(ctx, i); const char *name = iio_device_get_name(dev); INFO("\t%s: %s\n", iio_device_get_id(dev), name ? name : "" ); unsigned int nb_channels = iio_device_get_channels_count(dev); INFO("\t\t%u channels found:\n", nb_channels); unsigned int j; for (j = 0; j < nb_channels; j++) { struct iio_channel *ch = iio_device_get_channel(dev, j); const char *type_name; if (iio_channel_is_output(ch)) type_name = "output"; else type_name = "input"; name = iio_channel_get_name(ch); INFO("\t\t\t%s: %s (%s)\n", iio_channel_get_id(ch), name ? name : "", type_name); unsigned int nb_attrs = iio_channel_get_attrs_count(ch); if (!nb_attrs) continue; INFO("\t\t\t%u channel-specific attributes found:\n", nb_attrs); unsigned int k; for (k = 0; k < nb_attrs; k++) { const char *attr = iio_channel_get_attr(ch, k); char buf[1024]; ret = (int) iio_channel_attr_read(ch, attr, buf, 1024); if (ret > 0) INFO("\t\t\t\tattr %u: %s" " value: %s\n", k, attr, buf); else if (ret == -ENOSYS) INFO("\t\t\t\tattr %u: %s\n", k, attr); else ERROR("Unable to read attribute %s\n", attr); } } unsigned int nb_attrs = iio_device_get_attrs_count(dev); if (!nb_attrs) continue; INFO("\t\t%u device-specific attributes found:\n", nb_attrs); for (j = 0; j < nb_attrs; j++) { const char *attr = iio_device_get_attr(dev, j); char buf[1024]; ret = (int) iio_device_attr_read(dev, attr, buf, 1024); if (ret > 0) INFO("\t\t\t\tattr %u: %s value: %s\n", j, attr, buf); else if (ret == -ENOSYS) INFO("\t\t\t\tattr %u: %s\n", j, attr); else ERROR("Unable to read attribute: %s\n", attr); } } iio_context_destroy(ctx); return EXIT_SUCCESS; }
static void build_channel_list(void) { GtkTreeIter iter, iter2, iter3; unsigned int enabled; char *device, *device2; gboolean first = FALSE, iter3_valid = FALSE, loop, loop2, all = FALSE; char dev_ch[256]; loop = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (device_list_store), &iter); gtk_list_store_clear(channel_list_store); while (loop) { gtk_tree_model_get(GTK_TREE_MODEL (device_list_store), &iter, 0, &device, 1, &enabled, -1); if (enabled) { struct iio_device *dev; unsigned int i, nb_channels; all = true; /* is it already in the list? */ loop2 = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (channel_list_store), &iter2); if (loop2) { first = TRUE; iter3 = iter2; iter3_valid = TRUE; } while (loop2) { gtk_tree_model_get(GTK_TREE_MODEL (channel_list_store), &iter2, 2, &device2, -1); if (!strcmp(device, device2)) break; if (strcmp(device, device2) >= 0) { first = FALSE; iter3 = iter2; } g_free(device2); loop2 = gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter2); } /* it is, so skip the rest */ if (loop2) { loop = gtk_tree_model_iter_next(GTK_TREE_MODEL (device_list_store), &iter); continue; } dev = get_device(device); if (!dev) continue; nb_channels = iio_device_get_channels_count(dev); for (i = 0; i < nb_channels; i++) { struct iio_channel *chn = iio_device_get_channel(dev, i); const char *name, *id, *devid; /* Must be input */ if (!is_valid_dmm_channel(chn)) continue; /* find the name */ devid = iio_device_get_id(dev); name = iio_channel_get_name(chn); id = iio_channel_get_id(chn); if (!name) name = id; if (iter3_valid) { if (first) { gtk_list_store_insert_before(channel_list_store, &iter2, &iter3); first = FALSE; } else if(gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter3)) gtk_list_store_insert_before(channel_list_store, &iter2, &iter3); else gtk_list_store_append(channel_list_store, &iter2); } else { gtk_list_store_append(channel_list_store, &iter2); iter3_valid = TRUE; } snprintf(dev_ch, sizeof(dev_ch), "%s:%s", device, name); gtk_list_store_set(channel_list_store, &iter2, 0, dev_ch, /* device & channel name */ 1, 0, /* On/Off */ 2, devid, /* device ID */ 3, id, /* channel ID */ -1); iter3 = iter2; } } else { loop2 = gtk_tree_model_get_iter_first(GTK_TREE_MODEL (channel_list_store), &iter2); while (loop2) { gtk_tree_model_get(GTK_TREE_MODEL (channel_list_store), &iter2, 2, &device2, -1); if (!strcmp(device, device2)) { loop2 = gtk_list_store_remove(channel_list_store, &iter2); continue; } loop2 = gtk_tree_model_iter_next(GTK_TREE_MODEL (channel_list_store), &iter2); } } loop = gtk_tree_model_iter_next(GTK_TREE_MODEL (device_list_store), &iter); } gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(GTK_TREE_MODEL(channel_list_store)), 0, GTK_SORT_ASCENDING); if (all) gtk_widget_show(select_all_channels); else gtk_widget_hide(select_all_channels); }