static long exec_command(const char *cmd, int fd) { long resp; ssize_t ret = write_command(cmd, fd); if (ret < 0) return (long) ret; DEBUG("Reading response\n"); ret = read_integer(fd, &resp); if (ret < 0) { char buf[1024]; iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to read response: %s\n", buf); return (long) ret; } #if LOG_LEVEL >= DEBUG_L if (resp < 0) { char buf[1024]; iio_strerror(-resp, buf, sizeof(buf)); DEBUG("Server returned an error: %s\n", buf); } #endif return resp; }
static ssize_t network_read(const struct iio_device *dev, void *dst, size_t len, uint32_t *mask, size_t words) { uintptr_t ptr = (uintptr_t) dst; struct iio_device_pdata *pdata = dev->pdata; int fd = pdata->fd; ssize_t ret, read = 0; char buf[1024]; if (!len || words != (dev->nb_channels + 31) / 32) return -EINVAL; snprintf(buf, sizeof(buf), "READBUF %s %lu\r\n", dev->id, (unsigned long) len); network_lock_dev(pdata); ret = write_rwbuf_command(dev, buf, false); if (ret < 0) { network_unlock_dev(pdata); return ret; } do { ret = network_read_mask(fd, mask, words); if (!ret) break; if (ret < 0) { iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to read mask: %s\n", buf); network_unlock_dev(pdata); return read ? read : ret; } mask = NULL; /* We read the mask only once */ ret = read_all((void *) ptr, ret, fd); if (ret < 0) { iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to read response to READ: %s\n", buf); network_unlock_dev(pdata); return read ? read : ret; } ptr += ret; read += ret; len -= ret; } while (len); network_unlock_dev(pdata); return read; }
static ssize_t write_command(const char *cmd, int fd) { ssize_t ret; DEBUG("Writing command: %s\n", cmd); ret = write_all(cmd, strlen(cmd), fd); if (ret < 0) { char buf[1024]; iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to send command: %s\n", buf); } return ret; }
static int network_get_trigger(const struct iio_device *dev, const struct iio_device **trigger) { struct iio_context_pdata *pdata = dev->ctx->pdata; unsigned int i; char buf[1024]; ssize_t ret; long resp; snprintf(buf, sizeof(buf), "GETTRIG %s\r\n", dev->id); network_lock(dev->ctx->pdata); resp = exec_command(buf, pdata->fd); if (resp < 0) { network_unlock(pdata); return (int) resp; } else if (resp == 0) { *trigger = NULL; network_unlock(pdata); return 0; } else if ((unsigned long) resp > sizeof(buf)) { ERROR("Value returned by server is too large\n"); network_unlock(pdata); return -EIO; } ret = read_all(buf, resp, pdata->fd); network_unlock(pdata); if (ret < 0) { iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to read response to GETTRIG: %s\n", buf); return ret; } if (buf[0] == '\0') { *trigger = NULL; return 0; } for (i = 0; i < dev->ctx->nb_devices; i++) { struct iio_device *cur = dev->ctx->devices[i]; if (iio_device_is_trigger(cur) && !strncmp(cur->name, buf, resp)) { *trigger = cur; return 0; } } return -ENXIO; }
static int network_set_timeout(struct iio_context *ctx, unsigned int timeout) { int ret = set_socket_timeout(ctx->pdata->fd, timeout); if (!ret) { timeout = calculate_remote_timeout(timeout); ret = set_remote_timeout(ctx, timeout); } if (ret < 0) { char buf[1024]; iio_strerror(-ret, buf, sizeof(buf)); WARNING("Unable to set R/W timeout: %s\n", buf); } else { ctx->rw_timeout_ms = timeout; } return ret; }
static ssize_t network_read_attr_helper(const struct iio_device *dev, const struct iio_channel *chn, const char *attr, char *dst, size_t len, bool is_debug) { long read_len; ssize_t ret; char buf[1024]; struct iio_context_pdata *pdata = dev->ctx->pdata; int fd = pdata->fd; const char *id = dev->id; if (chn) snprintf(buf, sizeof(buf), "READ %s %s %s %s\r\n", id, chn->is_output ? "OUTPUT" : "INPUT", chn->id, 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 : ""); network_lock(pdata); read_len = exec_command(buf, fd); if (read_len < 0) { network_unlock(pdata); return (ssize_t) read_len; } if ((unsigned long) read_len > len) { ERROR("Value returned by server is too large\n"); network_unlock(pdata); return -EIO; } ret = read_all(dst, read_len, fd); network_unlock(pdata); if (ret < 0) { iio_strerror(-ret, buf, sizeof(buf)); ERROR("Unable to read response to READ: %s\n", buf); return ret; } return read_len; }
static struct iio_context *scan(void) { struct iio_scan_context *scan_ctx; struct iio_context_info **info; struct iio_context *ctx = NULL; unsigned int i; ssize_t ret; scan_ctx = iio_create_scan_context(NULL, 0); if (!scan_ctx) { fprintf(stderr, "Unable to create scan context\n"); return NULL; } ret = iio_scan_context_get_info_list(scan_ctx, &info); if (ret < 0) { char err_str[1024]; iio_strerror(-ret, err_str, sizeof(err_str)); fprintf(stderr, "Scanning for IIO contexts failed: %s\n", err_str); goto err_free_ctx; } if (ret == 0) { printf("No IIO context found.\n"); goto err_free_info_list; } if (ret == 1) { ctx = iio_create_context_from_uri(iio_context_info_get_uri(info[0])); } else { fprintf(stderr, "Multiple contexts found. Please select one using --uri:\n"); for (i = 0; i < (size_t) ret; i++) { fprintf(stderr, "\t%d: %s [%s]\n", i, iio_context_info_get_description(info[i]), iio_context_info_get_uri(info[i])); } } err_free_info_list: iio_context_info_list_free(info); err_free_ctx: iio_scan_context_destroy(scan_ctx); return ctx; }
int main(int argc, char **argv) { unsigned int i, nb_channels; unsigned int buffer_size = SAMPLES_PER_READ; const char *arg_uri = NULL; const char *arg_ip = NULL; int c, option_index = 0; struct iio_device *dev; size_t sample_size; int timeout = -1; bool scan_for_context = false; while ((c = getopt_long(argc, argv, "+hn:u:t:b:s:T:a", options, &option_index)) != -1) { switch (c) { case 'h': usage(); return EXIT_SUCCESS; case 'n': arg_ip = optarg; break; case 'u': arg_uri = optarg; break; case 'a': scan_for_context = true; break; case 't': trigger_name = optarg; break; case 'b': buffer_size = atoi(optarg); break; case 's': num_samples = atoi(optarg); break; case 'T': timeout = atoi(optarg); break; case '?': return EXIT_FAILURE; } } if (argc == optind) { fprintf(stderr, "Incorrect number of arguments.\n\n"); usage(); return EXIT_FAILURE; } setup_sig_handler(); if (scan_for_context) ctx = scan(); else if (arg_uri) ctx = iio_create_context_from_uri(arg_uri); else if (arg_ip) ctx = iio_create_network_context(arg_ip); else ctx = iio_create_default_context(); if (!ctx) { fprintf(stderr, "Unable to create IIO context\n"); return EXIT_FAILURE; } if (timeout >= 0) iio_context_set_timeout(ctx, timeout); dev = iio_context_find_device(ctx, argv[optind]); if (!dev) { fprintf(stderr, "Device %s not found\n", argv[optind]); iio_context_destroy(ctx); return EXIT_FAILURE; } if (trigger_name) { struct iio_device *trigger = iio_context_find_device( ctx, trigger_name); if (!trigger) { fprintf(stderr, "Trigger %s not found\n", trigger_name); iio_context_destroy(ctx); return EXIT_FAILURE; } if (!iio_device_is_trigger(trigger)) { fprintf(stderr, "Specified device is not a trigger\n"); iio_context_destroy(ctx); return EXIT_FAILURE; } /* * Fixed rate for now. Try new ABI first, * fail gracefully to remain compatible. */ if (iio_device_attr_write_longlong(trigger, "sampling_frequency", DEFAULT_FREQ_HZ) < 0) iio_device_attr_write_longlong(trigger, "frequency", DEFAULT_FREQ_HZ); iio_device_set_trigger(dev, trigger); } nb_channels = iio_device_get_channels_count(dev); if (argc == optind + 1) { /* Enable all channels */ for (i = 0; i < nb_channels; i++) iio_channel_enable(iio_device_get_channel(dev, i)); } else { for (i = 0; i < nb_channels; i++) { unsigned int j; struct iio_channel *ch = iio_device_get_channel(dev, i); for (j = optind + 1; j < (unsigned int) argc; j++) { const char *n = iio_channel_get_name(ch); if (!strcmp(argv[j], iio_channel_get_id(ch)) || (n && !strcmp(n, argv[j]))) iio_channel_enable(ch); } } } sample_size = iio_device_get_sample_size(dev); buffer = iio_device_create_buffer(dev, buffer_size, false); if (!buffer) { char buf[256]; iio_strerror(errno, buf, sizeof(buf)); fprintf(stderr, "Unable to allocate buffer: %s\n", buf); iio_context_destroy(ctx); return EXIT_FAILURE; } while (app_running) { int ret = iio_buffer_refill(buffer); if (ret < 0) { if (app_running) { char buf[256]; iio_strerror(-ret, buf, sizeof(buf)); fprintf(stderr, "Unable to refill buffer: %s\n", buf); } break; } /* If there are only the samples we requested, we don't need to * demux */ if (iio_buffer_step(buffer) == sample_size) { void *start = iio_buffer_start(buffer); size_t read_len, len = (intptr_t) iio_buffer_end(buffer) - (intptr_t) start; if (num_samples && len > num_samples * sample_size) len = num_samples * sample_size; for (read_len = len; len; ) { size_t nb = fwrite(start, 1, len, stdout); if (!nb) goto err_destroy_buffer; len -= nb; start = (void *)((intptr_t) start + nb); } if (num_samples) { num_samples -= read_len / sample_size; if (!num_samples) quit_all(EXIT_SUCCESS); } } else { iio_buffer_foreach_sample(buffer, print_sample, NULL); } } err_destroy_buffer: iio_buffer_destroy(buffer); iio_context_destroy(ctx); return exit_code; }