blob: 4a9b9422c394e474447fac6ac3b914c7d5997eb7 [file] [log] [blame]
Paul Cercueilbb4401d2014-02-28 16:10:49 +01001/*
2 * libiio - Library for interfacing industrial I/O (IIO) devices
3 *
4 * Copyright (C) 2014 Analog Devices, Inc.
5 * Author: Paul Cercueil <paul.cercueil@analog.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * */
18
Paul Cercueil42090d12014-02-24 12:32:23 +010019#include "debug.h"
Paul Cercueil0b2ce712014-02-17 15:04:18 +010020#include "iio-private.h"
21
Paul Cercueil6a013602014-02-19 12:37:39 +010022#include <errno.h>
Paul Cercueil0b2ce712014-02-17 15:04:18 +010023#include <stdio.h>
Paul Cercueil42090d12014-02-24 12:32:23 +010024#include <string.h>
25
26static char *get_attr_xml(const char *attr, size_t *length)
27{
28 size_t len = sizeof("<attribute name=\"\" />") + strlen(attr);
29 char *str = malloc(len);
30 if (!str) {
31 ERROR("Unable to allocate memory\n");
32 return NULL;
33 }
34
35 *length = len - 1; /* Skip the \0 */
36 sprintf(str, "<attribute name=\"%s\" />", attr);
37 return str;
38}
39
40/* Returns a string containing the XML representation of this device */
41char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
42{
43 size_t len = sizeof("<device id=\"\" name=\"\" ></device>");
44 char *ptr, *str, *attrs[dev->nb_attrs], *channels[dev->nb_channels];
45 size_t attrs_len[dev->nb_attrs], channels_len[dev->nb_channels];
46 unsigned int i, j;
47
48 for (i = 0; i < dev->nb_attrs; i++) {
49 char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i]);
50 if (!xml)
51 goto err_free_attrs;
52 attrs[i] = xml;
53 len += attrs_len[i];
54 }
55
56 for (j = 0; j < dev->nb_channels; j++) {
57 char *xml = iio_channel_get_xml(dev->channels[j],
58 &channels_len[j]);
59 if (!xml)
60 goto err_free_channels;
61 channels[j] = xml;
62 len += channels_len[j];
63 }
64
65 len += strlen(dev->id);
66 if (dev->name)
67 len += strlen(dev->name);
68
69 str = malloc(len);
70 if (!str)
71 goto err_free_channels;
72
73 sprintf(str, "<device id=\"%s\"", dev->id);
74 ptr = strrchr(str, '\0');
75
76 if (dev->name) {
77 sprintf(ptr, " name=\"%s\"", dev->name);
78 ptr = strrchr(ptr, '\0');
79 }
80
81 strcpy(ptr, " >");
82 ptr += 2;
83
84 for (i = 0; i < dev->nb_channels; i++) {
85 strcpy(ptr, channels[i]);
86 ptr += channels_len[i];
87 free(channels[i]);
88 }
89
90 for (i = 0; i < dev->nb_attrs; i++) {
91 strcpy(ptr, attrs[i]);
92 ptr += attrs_len[i];
93 free(attrs[i]);
94 }
95
96 strcpy(ptr, "</device>");
97 *length = ptr - str + sizeof("</device>") - 1;
98 return str;
99
100err_free_channels:
101 while (j--)
102 free(channels[j]);
103err_free_attrs:
104 while (i--)
105 free(attrs[i]);
106 return NULL;
107}
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100108
109const char * iio_device_get_id(const struct iio_device *dev)
110{
111 return dev->id;
112}
113
114const char * iio_device_get_name(const struct iio_device *dev)
115{
116 return dev->name;
117}
118
119unsigned int iio_device_get_channels_count(const struct iio_device *dev)
120{
121 return dev->nb_channels;
122}
123
124struct iio_channel * iio_device_get_channel(const struct iio_device *dev,
125 unsigned int index)
126{
127 if (index >= dev->nb_channels)
128 return NULL;
129 else
130 return dev->channels[index];
131}
132
133unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
134{
135 return dev->nb_attrs;
136}
137
138const char * iio_device_get_attr(const struct iio_device *dev,
139 unsigned int index)
140{
141 if (index >= dev->nb_attrs)
142 return NULL;
143 else
144 return dev->attrs[index];
145}
146
Paul Cercueilec1760d2014-02-21 11:31:20 +0100147int iio_device_open(const struct iio_device *dev)
148{
149 if (dev->ctx->ops->open)
150 return dev->ctx->ops->open(dev);
151 else
152 return -ENOSYS;
153}
154
155int iio_device_close(const struct iio_device *dev)
156{
157 if (dev->ctx->ops->close)
158 return dev->ctx->ops->close(dev);
159 else
160 return -ENOSYS;
161}
162
163ssize_t iio_device_read_raw(const struct iio_device *dev,
164 void *dst, size_t len)
165{
166 if (dev->ctx->ops->read)
167 return dev->ctx->ops->read(dev, dst, len);
168 else
169 return -ENOSYS;
170}
171
172ssize_t iio_device_write_raw(const struct iio_device *dev,
173 const void *src, size_t len)
174{
175 if (dev->ctx->ops->write)
176 return dev->ctx->ops->write(dev, src, len);
177 else
178 return -ENOSYS;
179}
180
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100181ssize_t iio_device_attr_read(const struct iio_device *dev,
182 const char *attr, char *dst, size_t len)
183{
Paul Cercueil6a013602014-02-19 12:37:39 +0100184 if (dev->ctx->ops->read_device_attr)
185 return dev->ctx->ops->read_device_attr(dev, attr, dst, len);
186 else
187 return -ENOSYS;
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100188}
189
190ssize_t iio_device_attr_write(const struct iio_device *dev,
191 const char *attr, const char *src)
192{
Paul Cercueil6a013602014-02-19 12:37:39 +0100193 if (dev->ctx->ops->write_device_attr)
194 return dev->ctx->ops->write_device_attr(dev, attr, src);
195 else
196 return -ENOSYS;
Paul Cercueil0b2ce712014-02-17 15:04:18 +0100197}
Paul Cercueil00236242014-02-18 15:09:06 +0100198
199void free_device(struct iio_device *dev)
200{
201 unsigned int i;
202 for (i = 0; i < dev->nb_attrs; i++)
203 free((char *) dev->attrs[i]);
204 if (dev->nb_attrs)
205 free(dev->attrs);
206 for (i = 0; i < dev->nb_channels; i++)
207 free_channel(dev->channels[i]);
208 if (dev->nb_channels)
209 free(dev->channels);
210 if (dev->name)
211 free((char *) dev->name);
212 if (dev->id)
213 free((char *) dev->id);
214 free(dev);
215}