summaryrefslogtreecommitdiff
path: root/iiod-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'iiod-client.c')
-rw-r--r--iiod-client.c674
1 files changed, 0 insertions, 674 deletions
diff --git a/iiod-client.c b/iiod-client.c
deleted file mode 100644
index 1798cd6..0000000
--- a/iiod-client.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * libiio - Library for interfacing industrial I/O (IIO) devices
- *
- * Copyright (C) 2014-2016 Analog Devices, Inc.
- * Author: Paul Cercueil <paul.cercueil@analog.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- */
-
-#include "debug.h"
-#include "iiod-client.h"
-#include "iio-lock.h"
-#include "iio-private.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <string.h>
-#include <stdio.h>
-
-struct iiod_client {
- struct iio_context_pdata *pdata;
- const struct iiod_client_ops *ops;
- struct iio_mutex *lock;
-};
-
-static ssize_t iiod_client_read_integer(struct iiod_client *client,
- void *desc, int *val)
-{
- unsigned int i;
- char buf[1024], *ptr = NULL, *end;
- ssize_t ret;
- int value;
-
- do {
- ret = client->ops->read_line(client->pdata,
- desc, buf, sizeof(buf));
- if (ret < 0)
- return ret;
-
- for (i = 0; i < (unsigned int) ret; i++) {
- if (buf[i] != '\n') {
- if (!ptr)
- ptr = &buf[i];
- } else if (!!ptr) {
- break;
- }
- }
- } while (!ptr);
-
- buf[i] = '\0';
-
- value = (int) strtol(ptr, &end, 10);
- if (ptr == end)
- return -EINVAL;
-
- *val = value;
- return 0;
-}
-
-static int iiod_client_exec_command(struct iiod_client *client,
- void *desc, const char *cmd)
-{
- int resp;
- ssize_t ret;
-
- ret = client->ops->write(client->pdata, desc, cmd, strlen(cmd));
- if (ret < 0)
- return (int) ret;
-
- ret = iiod_client_read_integer(client, desc, &resp);
- return ret < 0 ? (int) ret : resp;
-}
-
-static ssize_t iiod_client_write_all(struct iiod_client *client,
- void *desc, const void *src, size_t len)
-{
- struct iio_context_pdata *pdata = client->pdata;
- const struct iiod_client_ops *ops = client->ops;
- uintptr_t ptr = (uintptr_t) src;
-
- while (len) {
- ssize_t ret = ops->write(pdata, desc, (const void *) ptr, len);
-
- if (ret < 0) {
- if (ret == -EINTR)
- continue;
- else
- return ret;
- }
-
- if (ret == 0)
- return -EPIPE;
-
- ptr += ret;
- len -= ret;
- }
-
- return (ssize_t) (ptr - (uintptr_t) src);
-}
-
-static ssize_t iiod_client_read_all(struct iiod_client *client,
- void *desc, void *dst, size_t len)
-{
- struct iio_context_pdata *pdata = client->pdata;
- const struct iiod_client_ops *ops = client->ops;
- uintptr_t ptr = (uintptr_t) dst;
-
- while (len) {
- ssize_t ret = ops->read(pdata, desc, (void *) ptr, len);
-
- if (ret < 0) {
- if (ret == -EINTR)
- continue;
- else
- return ret;
- }
-
- if (ret == 0)
- return -EPIPE;
-
- ptr += ret;
- len -= ret;
- }
-
- return (ssize_t) (ptr - (uintptr_t) dst);
-}
-
-struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata,
- struct iio_mutex *lock, const struct iiod_client_ops *ops)
-{
- struct iiod_client *client;
-
- client = malloc(sizeof(*client));
- if (!client) {
- errno = ENOMEM;
- return NULL;
- }
-
- client->lock = lock;
- client->pdata = pdata;
- client->ops = ops;
- return client;
-}
-
-void iiod_client_destroy(struct iiod_client *client)
-{
- free(client);
-}
-
-int iiod_client_get_version(struct iiod_client *client, void *desc,
- unsigned int *major, unsigned int *minor, char *git_tag)
-{
- struct iio_context_pdata *pdata = client->pdata;
- const struct iiod_client_ops *ops = client->ops;
- char buf[256], *ptr = buf, *end;
- long maj, min;
- int ret;
-
- iio_mutex_lock(client->lock);
-
- ret = ops->write(pdata, desc, "VERSION\r\n", sizeof("VERSION\r\n") - 1);
- if (ret < 0) {
- iio_mutex_unlock(client->lock);
- return ret;
- }
-
- ret = ops->read_line(pdata, desc, buf, sizeof(buf));
- iio_mutex_unlock(client->lock);
-
- if (ret < 0)
- return ret;
-
- maj = strtol(ptr, &end, 10);
- if (ptr == end)
- return -EIO;
-
- ptr = end + 1;
- min = strtol(ptr, &end, 10);
- if (ptr == end)
- return -EIO;
-
- ptr = end + 1;
- if (buf + ret < ptr + 8)
- return -EIO;
-
- /* Strip the \n */
- ptr[buf + ret - ptr - 1] = '\0';
-
- if (major)
- *major = (unsigned int) maj;
- if (minor)
- *minor = (unsigned int) min;
- if (git_tag)
- strncpy(git_tag, ptr, 8);
- return 0;
-}
-
-int iiod_client_get_trigger(struct iiod_client *client, void *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;
-
- iio_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;
-}
-
-int iiod_client_set_trigger(struct iiod_client *client, void *desc,
- const struct iio_device *dev, const struct iio_device *trigger)
-{
- char buf[1024];
- int ret;
-
- if (trigger) {
- iio_snprintf(buf, sizeof(buf), "SETTRIG %s %s\r\n",
- iio_device_get_id(dev),
- iio_device_get_id(trigger));
- } else {
- iio_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;
-}
-
-int iiod_client_set_kernel_buffers_count(struct iiod_client *client, void *desc,
- const struct iio_device *dev, unsigned int nb_blocks)
-{
- int ret;
- char buf[1024];
-
- iio_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;
-}
-
-int iiod_client_set_timeout(struct iiod_client *client,
- void *desc, unsigned int timeout)
-{
- int ret;
- char buf[1024];
-
- iio_snprintf(buf, sizeof(buf), "TIMEOUT %u\r\n", timeout);
-
- iio_mutex_lock(client->lock);
- ret = iiod_client_exec_command(client, desc, buf);
- iio_mutex_unlock(client->lock);
- return ret;
-}
-
-static int iiod_client_discard(struct iiod_client *client, void *desc,
- char *buf, size_t buf_len, size_t to_discard)
-{
- do {
- size_t read_len;
- ssize_t ret;
-
- if (to_discard > buf_len)
- read_len = buf_len;
- else
- read_len = to_discard;
-
- ret = iiod_client_read_all(client, desc, buf, read_len);
- if (ret < 0)
- return ret;
-
- to_discard -= (size_t) ret;
- } while (to_discard);
-
- return 0;
-}
-
-ssize_t iiod_client_read_attr(struct iiod_client *client, void *desc,
- const struct iio_device *dev, const struct iio_channel *chn,
- const char *attr, char *dest, size_t len, enum iio_attr_type type)
-{
- 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 {
- switch (type) {
- case IIO_ATTR_TYPE_DEVICE:
- if (!iio_device_find_attr(dev, attr))
- return -ENOENT;
- break;
- case IIO_ATTR_TYPE_DEBUG:
- if (!iio_device_find_debug_attr(dev, attr))
- return -ENOENT;
- break;
- case IIO_ATTR_TYPE_BUFFER:
- if (!iio_device_find_buffer_attr(dev, attr))
- return -ENOENT;
- break;
- default:
- return -EINVAL;
- }
- }
- }
-
- if (chn) {
- iio_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 {
- switch (type) {
- case IIO_ATTR_TYPE_DEVICE:
- iio_snprintf(buf, sizeof(buf), "READ %s %s\r\n",
- id, attr ? attr : "");
- break;
- case IIO_ATTR_TYPE_DEBUG:
- iio_snprintf(buf, sizeof(buf), "READ %s DEBUG %s\r\n",
- id, attr ? attr : "");
- break;
- case IIO_ATTR_TYPE_BUFFER:
- iio_snprintf(buf, sizeof(buf), "READ %s BUFFER %s\r\n",
- id, attr ? attr : "");
- break;
- }
- }
-
- 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) {
- iiod_client_discard(client, desc, dest, len, ret + 1);
- 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;
-}
-
-ssize_t iiod_client_write_attr(struct iiod_client *client, void *desc,
- const struct iio_device *dev, const struct iio_channel *chn,
- const char *attr, const char *src, size_t len, enum iio_attr_type type)
-{
- 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 {
- switch (type) {
- case IIO_ATTR_TYPE_DEVICE:
- if (!iio_device_find_attr(dev, attr))
- return -ENOENT;
- break;
- case IIO_ATTR_TYPE_DEBUG:
- if (!iio_device_find_debug_attr(dev, attr))
- return -ENOENT;
- break;
- case IIO_ATTR_TYPE_BUFFER:
- if (!iio_device_find_buffer_attr(dev, attr))
- return -ENOENT;
- break;
- default:
- return -EINVAL;
- }
- }
- }
-
- if (chn) {
- iio_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 {
- switch (type) {
- case IIO_ATTR_TYPE_DEVICE:
- iio_snprintf(buf, sizeof(buf), "WRITE %s %s %lu\r\n",
- id, attr ? attr : "", (unsigned long) len);
- break;
- case IIO_ATTR_TYPE_DEBUG:
- iio_snprintf(buf, sizeof(buf), "WRITE %s DEBUG %s %lu\r\n",
- id, attr ? attr : "", (unsigned long) len);
- break;
- case IIO_ATTR_TYPE_BUFFER:
- iio_snprintf(buf, sizeof(buf), "WRITE %s BUFFER %s %lu\r\n",
- id, attr ? attr : "", (unsigned long) len);
- break;
- }
- }
-
- 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;
-}
-
-struct iio_context * iiod_client_create_context(
- struct iiod_client *client, void *desc)
-{
- struct iio_context *ctx = NULL;
- size_t xml_len;
- char *xml;
- int ret;
-
- iio_mutex_lock(client->lock);
- ret = iiod_client_exec_command(client, desc, "PRINT\r\n");
- if (ret < 0)
- goto out_unlock;
-
- xml_len = (size_t) ret;
- xml = malloc(xml_len + 1);
- if (!xml) {
- ret = -ENOMEM;
- goto out_unlock;
- }
-
- /* +1: Also read the trailing \n */
- ret = (int) iiod_client_read_all(client, desc, xml, xml_len + 1);
- if (ret < 0)
- goto out_free_xml;
-
- ctx = iio_create_xml_context_mem(xml, xml_len);
- if (!ctx)
- ret = -errno;
-
-out_free_xml:
- free(xml);
-out_unlock:
- iio_mutex_unlock(client->lock);
- if (!ctx)
- errno = -ret;
- return ctx;
-}
-
-int iiod_client_open_unlocked(struct iiod_client *client, void *desc,
- const struct iio_device *dev, size_t samples_count, bool cyclic)
-{
- char buf[1024], *ptr;
- size_t i;
-
- iio_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) {
- iio_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);
-}
-
-int iiod_client_close_unlocked(struct iiod_client *client, void *desc,
- const struct iio_device *dev)
-{
- char buf[1024];
-
- iio_snprintf(buf, sizeof(buf), "CLOSE %s\r\n", iio_device_get_id(dev));
- return iiod_client_exec_command(client, desc, buf);
-}
-
-static int iiod_client_read_mask(struct iiod_client *client,
- void *desc, uint32_t *mask, size_t words)
-{
- size_t i;
- ssize_t ret;
- char *buf, *ptr;
-
- buf = malloc(words * 8 + 1);
- if (!buf)
- return -ENOMEM;
-
- ret = iiod_client_read_all(client, desc, buf, words * 8 + 1);
- if (ret < 0)
- goto out_buf_free;
- else
- ret = 0;
-
- buf[words*8] = '\0';
-
- DEBUG("Reading mask\n");
-
- for (i = words, ptr = buf; i > 0; i--) {
- sscanf(ptr, "%08" PRIx32, &mask[i - 1]);
- DEBUG("mask[%lu] = 0x%08" PRIx32 "\n",
- (unsigned long)(i - 1), mask[i - 1]);
-
- ptr = (char *) ((uintptr_t) ptr + 8);
- }
-
-out_buf_free:
- free(buf);
- return (int) ret;
-}
-
-ssize_t iiod_client_read_unlocked(struct iiod_client *client, void *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;
-
- iio_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;
-}
-
-ssize_t iiod_client_write_unlocked(struct iiod_client *client, void *desc,
- const struct iio_device *dev, const void *src, size_t len)
-{
- ssize_t ret;
- char buf[1024];
- int val;
-
- iio_snprintf(buf, sizeof(buf), "WRITEBUF %s %lu\r\n",
- dev->id, (unsigned long) len);
-
- ret = iiod_client_write_all(client, desc, buf, strlen(buf));
- if (ret < 0)
- return ret;
-
- ret = iiod_client_read_integer(client, desc, &val);
- if (ret < 0)
- return ret;
- if (val < 0)
- return (ssize_t) val;
-
- ret = iiod_client_write_all(client, desc, src, len);
- if (ret < 0)
- return ret;
-
- ret = iiod_client_read_integer(client, desc, &val);
- if (ret < 0)
- return ret;
- if (val < 0)
- return (ssize_t) val;
-
- return (ssize_t) len;
-}