1 /*
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
19 #include "debug.h"
20 #include "iio-private.h"
21
22 #include <inttypes.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26
get_attr_xml(const char * attr,size_t * length,enum iio_attr_type type)27 static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type)
28 {
29 size_t len = sizeof("<attribute name=\"\" />") + strlen(attr);
30 char *str;
31
32 switch(type){
33 case IIO_ATTR_TYPE_DEVICE:
34 break;
35 case IIO_ATTR_TYPE_DEBUG:
36 len += (sizeof("debug-") - 1);
37 break;
38 case IIO_ATTR_TYPE_BUFFER:
39 len += (sizeof("buffer-") - 1);
40 break;
41 default:
42 return NULL;
43 }
44
45 str = malloc(len);
46 if (!str)
47 return NULL;
48
49 *length = len - 1; /* Skip the \0 */
50 switch (type) {
51 case IIO_ATTR_TYPE_DEVICE:
52 iio_snprintf(str, len, "<attribute name=\"%s\" />", attr);
53 break;
54 case IIO_ATTR_TYPE_DEBUG:
55 iio_snprintf(str, len, "<debug-attribute name=\"%s\" />", attr);
56 break;
57 case IIO_ATTR_TYPE_BUFFER:
58 iio_snprintf(str, len, "<buffer-attribute name=\"%s\" />", attr);
59 break;
60 }
61
62 return str;
63 }
64
65 /* Returns a string containing the XML representation of this device */
iio_device_get_xml(const struct iio_device * dev,size_t * length)66 char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
67 {
68 size_t len = sizeof("<device id=\"\" name=\"\" ></device>")
69 + strlen(dev->id) + (dev->name ? strlen(dev->name) : 0);
70 char *ptr, *str, **attrs, **channels, **buffer_attrs, **debug_attrs;
71 size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len;
72 unsigned int i, j, k;
73
74 attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len));
75 if (!attrs_len)
76 return NULL;
77
78 attrs = malloc(dev->nb_attrs * sizeof(*attrs));
79 if (!attrs)
80 goto err_free_attrs_len;
81
82 for (i = 0; i < dev->nb_attrs; i++) {
83 char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], IIO_ATTR_TYPE_DEVICE);
84 if (!xml)
85 goto err_free_attrs;
86 attrs[i] = xml;
87 len += attrs_len[i];
88 }
89
90 channels_len = malloc(dev->nb_channels * sizeof(*channels_len));
91 if (!channels_len)
92 goto err_free_attrs;
93
94 channels = malloc(dev->nb_channels * sizeof(*channels));
95 if (!channels)
96 goto err_free_channels_len;
97
98 for (j = 0; j < dev->nb_channels; j++) {
99 char *xml = iio_channel_get_xml(dev->channels[j],
100 &channels_len[j]);
101 if (!xml)
102 goto err_free_channels;
103 channels[j] = xml;
104 len += channels_len[j];
105 }
106
107 buffer_attrs_len = malloc(dev->nb_buffer_attrs *
108 sizeof(*buffer_attrs_len));
109 if (!buffer_attrs_len)
110 goto err_free_channels;
111
112 buffer_attrs = malloc(dev->nb_buffer_attrs * sizeof(*buffer_attrs));
113 if (!buffer_attrs)
114 goto err_free_buffer_attrs_len;
115
116 for (k = 0; k < dev->nb_buffer_attrs; k++) {
117 char *xml = get_attr_xml(dev->buffer_attrs[k],
118 &buffer_attrs_len[k], IIO_ATTR_TYPE_BUFFER);
119 if (!xml)
120 goto err_free_buffer_attrs;
121 buffer_attrs[k] = xml;
122 len += buffer_attrs_len[k];
123 }
124
125 debug_attrs_len = malloc(dev->nb_debug_attrs *
126 sizeof(*debug_attrs_len));
127 if (!debug_attrs_len)
128 goto err_free_buffer_attrs;
129
130 debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs));
131 if (!debug_attrs)
132 goto err_free_debug_attrs_len;
133
134 for (k = 0; k < dev->nb_debug_attrs; k++) {
135 char *xml = get_attr_xml(dev->debug_attrs[k],
136 &debug_attrs_len[k], IIO_ATTR_TYPE_DEBUG);
137 if (!xml)
138 goto err_free_debug_attrs;
139 debug_attrs[k] = xml;
140 len += debug_attrs_len[k];
141 }
142
143 str = malloc(len);
144 if (!str)
145 goto err_free_debug_attrs;
146
147 iio_snprintf(str, len, "<device id=\"%s\"", dev->id);
148 ptr = strrchr(str, '\0');
149
150 if (dev->name) {
151 sprintf(ptr, " name=\"%s\"", dev->name);
152 ptr = strrchr(ptr, '\0');
153 }
154
155 strcpy(ptr, " >");
156 ptr += 2;
157
158 for (i = 0; i < dev->nb_channels; i++) {
159 strcpy(ptr, channels[i]);
160 ptr += channels_len[i];
161 free(channels[i]);
162 }
163
164 free(channels);
165 free(channels_len);
166
167 for (i = 0; i < dev->nb_attrs; i++) {
168 strcpy(ptr, attrs[i]);
169 ptr += attrs_len[i];
170 free(attrs[i]);
171 }
172
173 free(attrs);
174 free(attrs_len);
175
176 for (i = 0; i < dev->nb_buffer_attrs; i++) {
177 strcpy(ptr, buffer_attrs[i]);
178 ptr += buffer_attrs_len[i];
179 free(buffer_attrs[i]);
180 }
181
182 free(buffer_attrs);
183 free(buffer_attrs_len);
184
185 for (i = 0; i < dev->nb_debug_attrs; i++) {
186 strcpy(ptr, debug_attrs[i]);
187 ptr += debug_attrs_len[i];
188 free(debug_attrs[i]);
189 }
190
191 free(debug_attrs);
192 free(debug_attrs_len);
193
194 strcpy(ptr, "</device>");
195 *length = ptr - str + sizeof("</device>") - 1;
196 return str;
197
198 err_free_debug_attrs:
199 while (k--)
200 free(debug_attrs[k]);
201 free(debug_attrs);
202 err_free_debug_attrs_len:
203 free(debug_attrs_len);
204 err_free_buffer_attrs:
205 while (k--)
206 free(buffer_attrs[k]);
207 free(buffer_attrs);
208 err_free_buffer_attrs_len:
209 free(buffer_attrs_len);
210 err_free_channels:
211 while (j--)
212 free(channels[j]);
213 free(channels);
214 err_free_channels_len:
215 free(channels_len);
216 err_free_attrs:
217 while (i--)
218 free(attrs[i]);
219 free(attrs);
220 err_free_attrs_len:
221 free(attrs_len);
222 return NULL;
223 }
224
iio_device_get_id(const struct iio_device * dev)225 const char * iio_device_get_id(const struct iio_device *dev)
226 {
227 return dev->id;
228 }
229
iio_device_get_name(const struct iio_device * dev)230 const char * iio_device_get_name(const struct iio_device *dev)
231 {
232 return dev->name;
233 }
234
iio_device_get_channels_count(const struct iio_device * dev)235 unsigned int iio_device_get_channels_count(const struct iio_device *dev)
236 {
237 return dev->nb_channels;
238 }
239
iio_device_get_channel(const struct iio_device * dev,unsigned int index)240 struct iio_channel * iio_device_get_channel(const struct iio_device *dev,
241 unsigned int index)
242 {
243 if (index >= dev->nb_channels)
244 return NULL;
245 else
246 return dev->channels[index];
247 }
248
iio_device_find_channel(const struct iio_device * dev,const char * name,bool output)249 struct iio_channel * iio_device_find_channel(const struct iio_device *dev,
250 const char *name, bool output)
251 {
252 unsigned int i;
253 for (i = 0; i < dev->nb_channels; i++) {
254 struct iio_channel *chn = dev->channels[i];
255 if (iio_channel_is_output(chn) != output)
256 continue;
257
258 if (!strcmp(chn->id, name) ||
259 (chn->name && !strcmp(chn->name, name)))
260 return chn;
261 }
262 return NULL;
263 }
264
iio_device_get_attrs_count(const struct iio_device * dev)265 unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
266 {
267 return dev->nb_attrs;
268 }
269
iio_device_get_attr(const struct iio_device * dev,unsigned int index)270 const char * iio_device_get_attr(const struct iio_device *dev,
271 unsigned int index)
272 {
273 if (index >= dev->nb_attrs)
274 return NULL;
275 else
276 return dev->attrs[index];
277 }
278
iio_device_find_attr(const struct iio_device * dev,const char * name)279 const char * iio_device_find_attr(const struct iio_device *dev,
280 const char *name)
281 {
282 unsigned int i;
283 for (i = 0; i < dev->nb_attrs; i++) {
284 const char *attr = dev->attrs[i];
285 if (!strcmp(attr, name))
286 return attr;
287 }
288 return NULL;
289 }
290
iio_device_get_buffer_attrs_count(const struct iio_device * dev)291 unsigned int iio_device_get_buffer_attrs_count(const struct iio_device *dev)
292 {
293 return dev->nb_buffer_attrs;
294 }
295
iio_device_get_buffer_attr(const struct iio_device * dev,unsigned int index)296 const char * iio_device_get_buffer_attr(const struct iio_device *dev,
297 unsigned int index)
298 {
299 if (index >= dev->nb_buffer_attrs)
300 return NULL;
301 else
302 return dev->buffer_attrs[index];
303 }
304
iio_device_find_buffer_attr(const struct iio_device * dev,const char * name)305 const char * iio_device_find_buffer_attr(const struct iio_device *dev,
306 const char *name)
307 {
308 unsigned int i;
309 for (i = 0; i < dev->nb_buffer_attrs; i++) {
310 const char *attr = dev->buffer_attrs[i];
311 if (!strcmp(attr, name))
312 return attr;
313 }
314 return NULL;
315 }
316
iio_device_find_debug_attr(const struct iio_device * dev,const char * name)317 const char * iio_device_find_debug_attr(const struct iio_device *dev,
318 const char *name)
319 {
320 unsigned int i;
321 for (i = 0; i < dev->nb_debug_attrs; i++) {
322 const char *attr = dev->debug_attrs[i];
323 if (!strcmp(attr, name))
324 return attr;
325 }
326 return NULL;
327 }
328
iio_device_is_tx(const struct iio_device * dev)329 bool iio_device_is_tx(const struct iio_device *dev)
330 {
331 unsigned int i;
332
333 for (i = 0; i < dev->nb_channels; i++) {
334 struct iio_channel *ch = dev->channels[i];
335 if (iio_channel_is_output(ch) && iio_channel_is_enabled(ch))
336 return true;
337 }
338
339 return false;
340 }
341
iio_device_open(const struct iio_device * dev,size_t samples_count,bool cyclic)342 int iio_device_open(const struct iio_device *dev,
343 size_t samples_count, bool cyclic)
344 {
345 unsigned int i;
346 bool has_channels = false;
347
348 for (i = 0; !has_channels && i < dev->words; i++)
349 has_channels = !!dev->mask[i];
350 if (!has_channels)
351 return -EINVAL;
352
353 if (dev->ctx->ops->open)
354 return dev->ctx->ops->open(dev, samples_count, cyclic);
355 else
356 return -ENOSYS;
357 }
358
iio_device_close(const struct iio_device * dev)359 int iio_device_close(const struct iio_device *dev)
360 {
361 if (dev->ctx->ops->close)
362 return dev->ctx->ops->close(dev);
363 else
364 return -ENOSYS;
365 }
366
iio_device_get_poll_fd(const struct iio_device * dev)367 int iio_device_get_poll_fd(const struct iio_device *dev)
368 {
369 if (dev->ctx->ops->get_fd)
370 return dev->ctx->ops->get_fd(dev);
371 else
372 return -ENOSYS;
373 }
374
iio_device_set_blocking_mode(const struct iio_device * dev,bool blocking)375 int iio_device_set_blocking_mode(const struct iio_device *dev, bool blocking)
376 {
377 if (dev->ctx->ops->set_blocking_mode)
378 return dev->ctx->ops->set_blocking_mode(dev, blocking);
379 else
380 return -ENOSYS;
381 }
382
iio_device_read_raw(const struct iio_device * dev,void * dst,size_t len,uint32_t * mask,size_t words)383 ssize_t iio_device_read_raw(const struct iio_device *dev,
384 void *dst, size_t len, uint32_t *mask, size_t words)
385 {
386 if (dev->ctx->ops->read)
387 return dev->ctx->ops->read(dev, dst, len, mask, words);
388 else
389 return -ENOSYS;
390 }
391
iio_device_write_raw(const struct iio_device * dev,const void * src,size_t len)392 ssize_t iio_device_write_raw(const struct iio_device *dev,
393 const void *src, size_t len)
394 {
395 if (dev->ctx->ops->write)
396 return dev->ctx->ops->write(dev, src, len);
397 else
398 return -ENOSYS;
399 }
400
iio_device_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)401 ssize_t iio_device_attr_read(const struct iio_device *dev,
402 const char *attr, char *dst, size_t len)
403 {
404 if (dev->ctx->ops->read_device_attr)
405 return dev->ctx->ops->read_device_attr(dev,
406 attr, dst, len, IIO_ATTR_TYPE_DEVICE);
407 else
408 return -ENOSYS;
409 }
410
iio_device_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)411 ssize_t iio_device_attr_write_raw(const struct iio_device *dev,
412 const char *attr, const void *src, size_t len)
413 {
414 if (dev->ctx->ops->write_device_attr)
415 return dev->ctx->ops->write_device_attr(dev,
416 attr, src, len, IIO_ATTR_TYPE_DEVICE);
417 else
418 return -ENOSYS;
419 }
420
iio_device_attr_write(const struct iio_device * dev,const char * attr,const char * src)421 ssize_t iio_device_attr_write(const struct iio_device *dev,
422 const char *attr, const char *src)
423 {
424 return iio_device_attr_write_raw(dev, attr, src, strlen(src) + 1);
425 }
426
iio_device_buffer_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)427 ssize_t iio_device_buffer_attr_read(const struct iio_device *dev,
428 const char *attr, char *dst, size_t len)
429 {
430 if (dev->ctx->ops->read_device_attr)
431 return dev->ctx->ops->read_device_attr(dev,
432 attr, dst, len, IIO_ATTR_TYPE_BUFFER);
433 else
434 return -ENOSYS;
435 }
436
iio_device_buffer_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)437 ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev,
438 const char *attr, const void *src, size_t len)
439 {
440 if (dev->ctx->ops->write_device_attr)
441 return dev->ctx->ops->write_device_attr(dev,
442 attr, src, len, IIO_ATTR_TYPE_BUFFER);
443 else
444 return -ENOSYS;
445 }
446
iio_device_buffer_attr_write(const struct iio_device * dev,const char * attr,const char * src)447 ssize_t iio_device_buffer_attr_write(const struct iio_device *dev,
448 const char *attr, const char *src)
449 {
450 return iio_device_buffer_attr_write_raw(dev, attr, src, strlen(src) + 1);
451 }
452
iio_device_set_data(struct iio_device * dev,void * data)453 void iio_device_set_data(struct iio_device *dev, void *data)
454 {
455 dev->userdata = data;
456 }
457
iio_device_get_data(const struct iio_device * dev)458 void * iio_device_get_data(const struct iio_device *dev)
459 {
460 return dev->userdata;
461 }
462
iio_device_is_trigger(const struct iio_device * dev)463 bool iio_device_is_trigger(const struct iio_device *dev)
464 {
465 /* A trigger has a name, an id which starts by "trigger",
466 * and zero channels. */
467
468 unsigned int nb = iio_device_get_channels_count(dev);
469 const char *name = iio_device_get_name(dev),
470 *id = iio_device_get_id(dev);
471 return ((nb == 0) && !!name &&
472 !strncmp(id, "trigger", sizeof("trigger") - 1));
473 }
474
iio_device_set_kernel_buffers_count(const struct iio_device * dev,unsigned int nb_buffers)475 int iio_device_set_kernel_buffers_count(const struct iio_device *dev,
476 unsigned int nb_buffers)
477 {
478 if (nb_buffers == 0)
479 return -EINVAL;
480 else if (dev->ctx->ops->set_kernel_buffers_count)
481 return dev->ctx->ops->set_kernel_buffers_count(dev, nb_buffers);
482 else
483 return -ENOSYS;
484 }
485
iio_device_get_trigger(const struct iio_device * dev,const struct iio_device ** trigger)486 int iio_device_get_trigger(const struct iio_device *dev,
487 const struct iio_device **trigger)
488 {
489 if (!trigger)
490 return -EINVAL;
491 else if (dev->ctx->ops->get_trigger)
492 return dev->ctx->ops->get_trigger(dev, trigger);
493 else
494 return -ENOSYS;
495 }
496
iio_device_set_trigger(const struct iio_device * dev,const struct iio_device * trigger)497 int iio_device_set_trigger(const struct iio_device *dev,
498 const struct iio_device *trigger)
499 {
500 if (trigger && !iio_device_is_trigger(trigger))
501 return -EINVAL;
502 else if (dev->ctx->ops->set_trigger)
503 return dev->ctx->ops->set_trigger(dev, trigger);
504 else
505 return -ENOSYS;
506 }
507
free_device(struct iio_device * dev)508 void free_device(struct iio_device *dev)
509 {
510 unsigned int i;
511 for (i = 0; i < dev->nb_attrs; i++)
512 free(dev->attrs[i]);
513 if (dev->nb_attrs)
514 free(dev->attrs);
515 for (i = 0; i < dev->nb_buffer_attrs; i++)
516 free(dev->buffer_attrs[i]);
517 if (dev->nb_buffer_attrs)
518 free(dev->buffer_attrs);
519 for (i = 0; i < dev->nb_debug_attrs; i++)
520 free(dev->debug_attrs[i]);
521 if (dev->nb_debug_attrs)
522 free(dev->debug_attrs);
523 for (i = 0; i < dev->nb_channels; i++)
524 free_channel(dev->channels[i]);
525 if (dev->nb_channels)
526 free(dev->channels);
527 if (dev->mask)
528 free(dev->mask);
529 if (dev->name)
530 free(dev->name);
531 if (dev->id)
532 free(dev->id);
533 free(dev);
534 }
535
iio_device_get_sample_size_mask(const struct iio_device * dev,const uint32_t * mask,size_t words)536 ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev,
537 const uint32_t *mask, size_t words)
538 {
539 ssize_t size = 0;
540 unsigned int i;
541 const struct iio_channel *prev = NULL;
542
543 if (words != (dev->nb_channels + 31) / 32)
544 return -EINVAL;
545
546 for (i = 0; i < dev->nb_channels; i++) {
547 const struct iio_channel *chn = dev->channels[i];
548 unsigned int length = chn->format.length / 8 *
549 chn->format.repeat;
550
551 if (chn->index < 0)
552 break;
553 if (!TEST_BIT(mask, chn->number))
554 continue;
555
556 if (prev && chn->index == prev->index) {
557 prev = chn;
558 continue;
559 }
560
561 if (size % length)
562 size += 2 * length - (size % length);
563 else
564 size += length;
565
566 prev = chn;
567 }
568 return size;
569 }
570
iio_device_get_sample_size(const struct iio_device * dev)571 ssize_t iio_device_get_sample_size(const struct iio_device *dev)
572 {
573 return iio_device_get_sample_size_mask(dev, dev->mask, dev->words);
574 }
575
iio_device_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)576 int iio_device_attr_read_longlong(const struct iio_device *dev,
577 const char *attr, long long *val)
578 {
579 char *end, buf[1024];
580 long long value;
581 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
582 if (ret < 0)
583 return (int) ret;
584
585 value = strtoll(buf, &end, 0);
586 if (end == buf)
587 return -EINVAL;
588 *val = value;
589 return 0;
590 }
591
iio_device_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)592 int iio_device_attr_read_bool(const struct iio_device *dev,
593 const char *attr, bool *val)
594 {
595 long long value;
596 int ret = iio_device_attr_read_longlong(dev, attr, &value);
597 if (ret < 0)
598 return ret;
599
600 *val = !!value;
601 return 0;
602 }
603
iio_device_attr_read_double(const struct iio_device * dev,const char * attr,double * val)604 int iio_device_attr_read_double(const struct iio_device *dev,
605 const char *attr, double *val)
606 {
607 char buf[1024];
608 ssize_t ret = iio_device_attr_read(dev, attr, buf, sizeof(buf));
609 if (ret < 0)
610 return (int) ret;
611 else
612 return read_double(buf, val);
613 }
614
iio_device_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)615 int iio_device_attr_write_longlong(const struct iio_device *dev,
616 const char *attr, long long val)
617 {
618 ssize_t ret;
619 char buf[1024];
620
621 iio_snprintf(buf, sizeof(buf), "%lld", val);
622 ret = iio_device_attr_write(dev, attr, buf);
623
624 return ret < 0 ? ret : 0;
625 }
626
iio_device_attr_write_double(const struct iio_device * dev,const char * attr,double val)627 int iio_device_attr_write_double(const struct iio_device *dev,
628 const char *attr, double val)
629 {
630 ssize_t ret;
631 char buf[1024];
632
633 ret = (ssize_t) write_double(buf, sizeof(buf), val);
634 if (!ret)
635 ret = iio_device_attr_write(dev, attr, buf);
636 return ret < 0 ? ret : 0;
637 }
638
iio_device_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)639 int iio_device_attr_write_bool(const struct iio_device *dev,
640 const char *attr, bool val)
641 {
642 ssize_t ret;
643
644 if (val)
645 ret = iio_device_attr_write(dev, attr, "1");
646 else
647 ret = iio_device_attr_write(dev, attr, "0");
648
649 return ret < 0 ? ret : 0;
650 }
651
iio_device_buffer_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)652 int iio_device_buffer_attr_read_longlong(const struct iio_device *dev,
653 const char *attr, long long *val)
654 {
655 char *end, buf[1024];
656 long long value;
657 ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf));
658 if (ret < 0)
659 return (int) ret;
660
661 value = strtoll(buf, &end, 0);
662 if (end == buf)
663 return -EINVAL;
664 *val = value;
665 return 0;
666 }
667
iio_device_buffer_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)668 int iio_device_buffer_attr_read_bool(const struct iio_device *dev,
669 const char *attr, bool *val)
670 {
671 long long value;
672 int ret = iio_device_buffer_attr_read_longlong(dev, attr, &value);
673 if (ret < 0)
674 return ret;
675
676 *val = !!value;
677 return 0;
678 }
679
iio_device_buffer_attr_read_double(const struct iio_device * dev,const char * attr,double * val)680 int iio_device_buffer_attr_read_double(const struct iio_device *dev,
681 const char *attr, double *val)
682 {
683 char buf[1024];
684 ssize_t ret = iio_device_buffer_attr_read(dev, attr, buf, sizeof(buf));
685 if (ret < 0)
686 return (int) ret;
687 else
688 return read_double(buf, val);
689 }
690
iio_device_buffer_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)691 int iio_device_buffer_attr_write_longlong(const struct iio_device *dev,
692 const char *attr, long long val)
693 {
694 ssize_t ret;
695 char buf[1024];
696
697 iio_snprintf(buf, sizeof(buf), "%lld", val);
698 ret = iio_device_buffer_attr_write(dev, attr, buf);
699
700 return ret < 0 ? ret : 0;
701 }
702
iio_device_buffer_attr_write_double(const struct iio_device * dev,const char * attr,double val)703 int iio_device_buffer_attr_write_double(const struct iio_device *dev,
704 const char *attr, double val)
705 {
706 ssize_t ret;
707 char buf[1024];
708
709 ret = (ssize_t) write_double(buf, sizeof(buf), val);
710 if (!ret)
711 ret = iio_device_buffer_attr_write(dev, attr, buf);
712 return ret < 0 ? ret : 0;
713 }
714
iio_device_buffer_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)715 int iio_device_buffer_attr_write_bool(const struct iio_device *dev,
716 const char *attr, bool val)
717 {
718 ssize_t ret;
719
720 if (val)
721 ret = iio_device_buffer_attr_write(dev, attr, "1");
722 else
723 ret = iio_device_buffer_attr_write(dev, attr, "0");
724
725 return ret < 0 ? ret : 0;
726 }
727
iio_device_debug_attr_read(const struct iio_device * dev,const char * attr,char * dst,size_t len)728 ssize_t iio_device_debug_attr_read(const struct iio_device *dev,
729 const char *attr, char *dst, size_t len)
730 {
731 if (dev->ctx->ops->read_device_attr)
732 return dev->ctx->ops->read_device_attr(dev,
733 attr, dst, len, IIO_ATTR_TYPE_DEBUG);
734 else
735 return -ENOSYS;
736 }
737
iio_device_debug_attr_write_raw(const struct iio_device * dev,const char * attr,const void * src,size_t len)738 ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev,
739 const char *attr, const void *src, size_t len)
740 {
741 if (dev->ctx->ops->write_device_attr)
742 return dev->ctx->ops->write_device_attr(dev,
743 attr, src, len, IIO_ATTR_TYPE_DEBUG);
744 else
745 return -ENOSYS;
746 }
747
iio_device_debug_attr_write(const struct iio_device * dev,const char * attr,const char * src)748 ssize_t iio_device_debug_attr_write(const struct iio_device *dev,
749 const char *attr, const char *src)
750 {
751 return iio_device_debug_attr_write_raw(dev, attr, src, strlen(src) + 1);
752 }
753
iio_device_get_debug_attrs_count(const struct iio_device * dev)754 unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev)
755 {
756 return dev->nb_debug_attrs;
757 }
758
iio_device_get_debug_attr(const struct iio_device * dev,unsigned int index)759 const char * iio_device_get_debug_attr(const struct iio_device *dev,
760 unsigned int index)
761 {
762 if (index >= dev->nb_debug_attrs)
763 return NULL;
764 else
765 return dev->debug_attrs[index];
766 }
767
iio_device_debug_attr_read_longlong(const struct iio_device * dev,const char * attr,long long * val)768 int iio_device_debug_attr_read_longlong(const struct iio_device *dev,
769 const char *attr, long long *val)
770 {
771 char *end, buf[1024];
772 long long value;
773 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
774 if (ret < 0)
775 return (int) ret;
776
777 value = strtoll(buf, &end, 0);
778 if (end == buf)
779 return -EINVAL;
780 *val = value;
781 return 0;
782 }
783
iio_device_debug_attr_read_bool(const struct iio_device * dev,const char * attr,bool * val)784 int iio_device_debug_attr_read_bool(const struct iio_device *dev,
785 const char *attr, bool *val)
786 {
787 long long value;
788 int ret = iio_device_debug_attr_read_longlong(dev, attr, &value);
789 if (ret < 0)
790 return ret;
791
792 *val = !!value;
793 return 0;
794 }
795
iio_device_debug_attr_read_double(const struct iio_device * dev,const char * attr,double * val)796 int iio_device_debug_attr_read_double(const struct iio_device *dev,
797 const char *attr, double *val)
798 {
799 char buf[1024];
800 ssize_t ret = iio_device_debug_attr_read(dev, attr, buf, sizeof(buf));
801 if (ret < 0)
802 return (int) ret;
803 else
804 return read_double(buf, val);
805 }
806
iio_device_debug_attr_write_longlong(const struct iio_device * dev,const char * attr,long long val)807 int iio_device_debug_attr_write_longlong(const struct iio_device *dev,
808 const char *attr, long long val)
809 {
810 ssize_t ret;
811 char buf[1024];
812
813 iio_snprintf(buf, sizeof(buf), "%lld", val);
814 ret = iio_device_debug_attr_write(dev, attr, buf);
815
816 return ret < 0 ? ret : 0;
817 }
818
iio_device_debug_attr_write_double(const struct iio_device * dev,const char * attr,double val)819 int iio_device_debug_attr_write_double(const struct iio_device *dev,
820 const char *attr, double val)
821 {
822 ssize_t ret;
823 char buf[1024];
824
825 ret = (ssize_t) write_double(buf, sizeof(buf), val);
826 if (!ret)
827 ret = iio_device_debug_attr_write(dev, attr, buf);
828 return ret < 0 ? ret : 0;
829 }
830
iio_device_debug_attr_write_bool(const struct iio_device * dev,const char * attr,bool val)831 int iio_device_debug_attr_write_bool(const struct iio_device *dev,
832 const char *attr, bool val)
833 {
834 ssize_t ret;
835
836 if (val)
837 ret = iio_device_debug_attr_write_raw(dev, attr, "1", 2);
838 else
839 ret = iio_device_debug_attr_write_raw(dev, attr, "0", 2);
840
841 return ret < 0 ? ret : 0;
842 }
843
iio_device_identify_filename(const struct iio_device * dev,const char * filename,struct iio_channel ** chn,const char ** attr)844 int iio_device_identify_filename(const struct iio_device *dev,
845 const char *filename, struct iio_channel **chn,
846 const char **attr)
847 {
848 unsigned int i;
849
850 for (i = 0; i < dev->nb_channels; i++) {
851 struct iio_channel *ch = dev->channels[i];
852 unsigned int j;
853
854 for (j = 0; j < ch->nb_attrs; j++) {
855 if (!strcmp(ch->attrs[j].filename, filename)) {
856 *attr = ch->attrs[j].name;
857 *chn = ch;
858 return 0;
859 }
860 }
861 }
862
863 for (i = 0; i < dev->nb_attrs; i++) {
864 /* Devices attributes are named after their filename */
865 if (!strcmp(dev->attrs[i], filename)) {
866 *attr = dev->attrs[i];
867 *chn = NULL;
868 return 0;
869 }
870 }
871
872 for (i = 0; i < dev->nb_debug_attrs; i++) {
873 if (!strcmp(dev->debug_attrs[i], filename)) {
874 *attr = dev->debug_attrs[i];
875 *chn = NULL;
876 return 0;
877 }
878 }
879
880 return -EINVAL;
881 }
882
iio_device_reg_write(struct iio_device * dev,uint32_t address,uint32_t value)883 int iio_device_reg_write(struct iio_device *dev,
884 uint32_t address, uint32_t value)
885 {
886 ssize_t ret;
887 char buf[1024];
888
889 iio_snprintf(buf, sizeof(buf), "0x%" PRIx32 " 0x%" PRIx32,
890 address, value);
891 ret = iio_device_debug_attr_write(dev, "direct_reg_access", buf);
892
893 return ret < 0 ? ret : 0;
894 }
895
iio_device_reg_read(struct iio_device * dev,uint32_t address,uint32_t * value)896 int iio_device_reg_read(struct iio_device *dev,
897 uint32_t address, uint32_t *value)
898 {
899 /* NOTE: There is a race condition here. But it is extremely unlikely to
900 * happen, and as this is a debug function, it shouldn't be used for
901 * something else than debug. */
902
903 long long val;
904 int ret = iio_device_debug_attr_write_longlong(dev,
905 "direct_reg_access", (long long) address);
906 if (ret < 0)
907 return ret;
908
909 ret = iio_device_debug_attr_read_longlong(dev,
910 "direct_reg_access", &val);
911 if (!ret)
912 *value = (uint32_t) val;
913 return ret;
914 }
915
read_each_attr(struct iio_device * dev,enum iio_attr_type type,int (* cb)(struct iio_device * dev,const char * attr,const char * val,size_t len,void * d),void * data)916 static int read_each_attr(struct iio_device *dev, enum iio_attr_type type,
917 int (*cb)(struct iio_device *dev,
918 const char *attr, const char *val, size_t len, void *d),
919 void *data)
920 {
921 int ret, buf_size;
922 char *buf, *ptr;
923 unsigned int i, count;
924
925 /* We need a big buffer here; 1 MiB should be enough */
926 buf = malloc(0x100000);
927 if (!buf)
928 return -ENOMEM;
929
930 switch(type){
931 case IIO_ATTR_TYPE_DEVICE:
932 count = iio_device_get_attrs_count(dev);
933 ret = (int) iio_device_attr_read(dev,
934 NULL, buf, 0x100000);
935 break;
936 case IIO_ATTR_TYPE_DEBUG:
937 count = iio_device_get_debug_attrs_count(dev);
938 ret = (int) iio_device_debug_attr_read(dev,
939 NULL, buf, 0x100000);
940 break;
941 case IIO_ATTR_TYPE_BUFFER:
942 count = iio_device_get_buffer_attrs_count(dev);
943 ret = (int) iio_device_buffer_attr_read(dev,
944 NULL, buf, 0x100000);
945 break;
946 default:
947 ret = -EINVAL;
948 count = 0;
949 break;
950 }
951
952 if (ret < 0)
953 goto err_free_buf;
954
955 ptr = buf;
956 buf_size = ret;
957
958 for (i = 0; i < count; i++) {
959 const char *attr;
960 int32_t len;
961
962 if (buf_size < 4) {
963 ret = -EPROTO;
964 break;
965 }
966
967 len = (int32_t) iio_be32toh(*(uint32_t *) ptr);
968 ptr += 4;
969 buf_size -= 4;
970
971 if (len > 0 && buf_size < len) {
972 ret = -EPROTO;
973 break;
974 }
975
976 switch(type){
977 case IIO_ATTR_TYPE_DEVICE:
978 attr = iio_device_get_attr(dev, i);
979 break;
980 case IIO_ATTR_TYPE_DEBUG:
981 attr = iio_device_get_debug_attr(dev, i);
982 break;
983 case IIO_ATTR_TYPE_BUFFER:
984 attr = iio_device_get_buffer_attr(dev, i);
985 break;
986 default:
987 attr = NULL;
988 break;
989 }
990
991 if (len > 0) {
992 ret = cb(dev, attr, ptr, (size_t) len, data);
993 if (ret < 0)
994 goto err_free_buf;
995
996 if (len & 0x3)
997 len = ((len >> 2) + 1) << 2;
998 ptr += len;
999 if (len >= buf_size)
1000 buf_size = 0;
1001 else
1002 buf_size -= len;
1003 }
1004 }
1005
1006 err_free_buf:
1007 free(buf);
1008 return ret < 0 ? ret : 0;
1009 }
1010
write_each_attr(struct iio_device * dev,enum iio_attr_type type,ssize_t (* cb)(struct iio_device * dev,const char * attr,void * buf,size_t len,void * d),void * data)1011 static int write_each_attr(struct iio_device *dev, enum iio_attr_type type,
1012 ssize_t (*cb)(struct iio_device *dev,
1013 const char *attr, void *buf, size_t len, void *d),
1014 void *data)
1015 {
1016 char *buf, *ptr;
1017 unsigned int i, count;
1018 size_t len = 0x100000;
1019 int ret;
1020
1021 /* We need a big buffer here; 1 MiB should be enough */
1022 buf = malloc(len);
1023 if (!buf)
1024 return -ENOMEM;
1025
1026 ptr = buf;
1027
1028 switch(type){
1029 case IIO_ATTR_TYPE_DEVICE:
1030 count = iio_device_get_attrs_count(dev);
1031 break;
1032 case IIO_ATTR_TYPE_DEBUG:
1033 count = iio_device_get_debug_attrs_count(dev);
1034 break;
1035 case IIO_ATTR_TYPE_BUFFER:
1036 count = iio_device_get_buffer_attrs_count(dev);
1037 break;
1038 default:
1039 ret = -EINVAL;
1040 goto err_free_buf;
1041 }
1042
1043 for (i = 0; i < count; i++) {
1044 const char *attr;
1045
1046 switch(type){
1047 case IIO_ATTR_TYPE_DEVICE:
1048 attr = iio_device_get_attr(dev, i);
1049 break;
1050 case IIO_ATTR_TYPE_DEBUG:
1051 attr = iio_device_get_debug_attr(dev, i);
1052 break;
1053 case IIO_ATTR_TYPE_BUFFER:
1054 attr = iio_device_get_buffer_attr(dev, i);
1055 break;
1056 default:
1057 attr = NULL;
1058 break;
1059 }
1060
1061 ret = (int) cb(dev, attr, ptr + 4, len - 4, data);
1062 if (ret < 0)
1063 goto err_free_buf;
1064
1065 *(int32_t *) ptr = (int32_t) iio_htobe32((uint32_t) ret);
1066 ptr += 4;
1067 len -= 4;
1068
1069 if (ret > 0) {
1070 if (ret & 0x3)
1071 ret = ((ret >> 2) + 1) << 2;
1072 ptr += ret;
1073 len -= ret;
1074 }
1075 }
1076
1077 switch(type){
1078 case IIO_ATTR_TYPE_DEVICE:
1079 ret = (int) iio_device_attr_write_raw(dev,
1080 NULL, buf, ptr - buf);
1081 break;
1082 case IIO_ATTR_TYPE_DEBUG:
1083 ret = (int) iio_device_debug_attr_write_raw(dev,
1084 NULL, buf, ptr - buf);
1085 break;
1086 case IIO_ATTR_TYPE_BUFFER:
1087 ret = (int) iio_device_buffer_attr_write_raw(dev,
1088 NULL, buf, ptr - buf);
1089 break;
1090 default:
1091 ret = -EINVAL;
1092 break;
1093 }
1094
1095 err_free_buf:
1096 free(buf);
1097 return ret < 0 ? ret : 0;
1098 }
1099
iio_device_debug_attr_read_all(struct iio_device * dev,int (* cb)(struct iio_device * dev,const char * attr,const char * val,size_t len,void * d),void * data)1100 int iio_device_debug_attr_read_all(struct iio_device *dev,
1101 int (*cb)(struct iio_device *dev,
1102 const char *attr, const char *val, size_t len, void *d),
1103 void *data)
1104 {
1105 return read_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data);
1106 }
1107
iio_device_buffer_attr_read_all(struct iio_device * dev,int (* cb)(struct iio_device * dev,const char * attr,const char * val,size_t len,void * d),void * data)1108 int iio_device_buffer_attr_read_all(struct iio_device *dev,
1109 int (*cb)(struct iio_device *dev,
1110 const char *attr, const char *val, size_t len, void *d),
1111 void *data)
1112 {
1113 return read_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data);
1114 }
1115
iio_device_attr_read_all(struct iio_device * dev,int (* cb)(struct iio_device * dev,const char * attr,const char * val,size_t len,void * d),void * data)1116 int iio_device_attr_read_all(struct iio_device *dev,
1117 int (*cb)(struct iio_device *dev,
1118 const char *attr, const char *val, size_t len, void *d),
1119 void *data)
1120 {
1121 return read_each_attr(dev, IIO_ATTR_TYPE_DEVICE ,cb, data);
1122 }
1123
iio_device_debug_attr_write_all(struct iio_device * dev,ssize_t (* cb)(struct iio_device * dev,const char * attr,void * buf,size_t len,void * d),void * data)1124 int iio_device_debug_attr_write_all(struct iio_device *dev,
1125 ssize_t (*cb)(struct iio_device *dev,
1126 const char *attr, void *buf, size_t len, void *d),
1127 void *data)
1128 {
1129 return write_each_attr(dev, IIO_ATTR_TYPE_DEBUG, cb, data);
1130 }
1131
iio_device_buffer_attr_write_all(struct iio_device * dev,ssize_t (* cb)(struct iio_device * dev,const char * attr,void * buf,size_t len,void * d),void * data)1132 int iio_device_buffer_attr_write_all(struct iio_device *dev,
1133 ssize_t (*cb)(struct iio_device *dev,
1134 const char *attr, void *buf, size_t len, void *d),
1135 void *data)
1136 {
1137 return write_each_attr(dev, IIO_ATTR_TYPE_BUFFER, cb, data);
1138 }
1139
iio_device_attr_write_all(struct iio_device * dev,ssize_t (* cb)(struct iio_device * dev,const char * attr,void * buf,size_t len,void * d),void * data)1140 int iio_device_attr_write_all(struct iio_device *dev,
1141 ssize_t (*cb)(struct iio_device *dev,
1142 const char *attr, void *buf, size_t len, void *d),
1143 void *data)
1144 {
1145 return write_each_attr(dev, IIO_ATTR_TYPE_DEVICE, cb, data);
1146 }
1147
iio_device_get_context(const struct iio_device * dev)1148 const struct iio_context * iio_device_get_context(const struct iio_device *dev)
1149 {
1150 return dev->ctx;
1151 }
1152