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