libiio
iiopp.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3  * libiio - Library for interfacing industrial I/O (IIO) devices
4  *
5  * Copyright (C) 2023, DIFITEC GmbH
6  * Author: Tilman Blumhagen <tilman.blumhagen@difitec.de>
7  */
8 
15 #pragma once
16 
17 #include <iio.h>
18 #include <string>
19 
20 #if __cplusplus < 201703L
21 #include <boost/optional.hpp>
22 #else
23 #include <optional>
24 #endif
25 #include <stdexcept>
26 #include <system_error>
27 #include <cassert>
28 #include <memory>
29 
56 namespace iiopp
57 {
58 
59 #if __cplusplus < 201703L
60 using boost::optional;
61 #else
62 using std::optional;
63 #endif
64 
65 class Context;
66 class Device;
67 class Buffer;
68 
75 class cstr
76 {
77  char const * const s;
78 public:
79  cstr(std::string const & s) : s(s.c_str()){}
80  cstr(char const * s) : s(s){assert(s);}
81 
82  char const * c_str() const {return s;}
83  operator char const * () const {return s;}
84 };
85 
88 class error : public std::system_error
89 {
90 public:
91  using std::system_error::system_error;
92 };
93 
96 class IAttr
97 {
98 public:
99  virtual ~IAttr(){}
100 
101  virtual cstr name() const = 0;
102 
103  virtual size_t read(char * dst, size_t size) const = 0; // Flawfinder: ignore
104  virtual bool read_bool() const = 0;
105  virtual double read_double() const = 0;
106  virtual long long read_longlong() const = 0;
107 
108  virtual size_t write(cstr src) = 0;
109  virtual void write_bool(bool val) = 0;
110  virtual void write_double(double val) = 0;
111  virtual void write_longlong(long long val) = 0;
112 
113  operator bool () const {return read_bool();}
114  operator double () const {return read_double();}
115  operator long long () const {return read_longlong();}
116 
117  cstr operator = (cstr val){write(val); return val;}
118  bool operator = (bool val){write_bool(val); return val;}
119  double operator = (double val){write_double(val); return val;}
120  long long operator = (long long val){write_longlong(val); return val;}
121 };
122 
125 typedef optional<cstr> optstr;
126 
127 namespace impl
128 {
129 
130 std::shared_ptr<Context> new_ctx(iio_context * ctx);
131 
132 inline optstr opt(char const * s)
133 {
134  return s ? optstr{{s}} : optstr{};
135 }
136 
137 inline std::string err_str(int err)
138 {
139  char buf[1024]; // Flawfinder: ignore
140  iio_strerror(err, buf, sizeof(buf));
141  return buf;
142 }
143 
144 [[noreturn]] inline void err(int err, char const * ctx)
145 {
146  assert(err > 0);
147  throw error(err, std::generic_category(), ctx);
148 }
149 
150 inline void check(int ret, char const * ctx)
151 {
152  if (ret)
153  {
154  assert(ret < 0);
155  err(-ret, ctx);
156  }
157 }
158 
159 template <class T>
160 T check_n(T n, char const * s)
161 {
162  if (n < 0)
163  impl::err(static_cast<int>(-n), s);
164  return n;
165 }
166 
171 template <class container_T, class element_T>
173 {
174  container_T & _me() {return *static_cast<container_T*>(this);}
175 public:
176 
179  class Iterator
180  {
181  container_T & c;
182  size_t i;
183  public:
184  typedef std::random_access_iterator_tag iterator_category;
185  typedef element_T value_type;
186  typedef std::ptrdiff_t difference_type;
187  typedef element_T *pointer;
188  typedef element_T &reference;
189  Iterator(container_T &cont, size_t idx) : c(cont), i(idx) {assert(idx <= cont.size());}
190 
191  element_T operator*() const { return c[i]; }
192  Iterator& operator++() { assert(i <= c.size()); ++i; return *this;}
193  Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
194  bool operator == (const Iterator& rhs) const { assert(&c == &rhs.c); return i == rhs.i; }
195  bool operator != (const Iterator& rhs) const { assert(&c == &rhs.c); return i != rhs.i; }
196  bool operator < (const Iterator& rhs) const { assert(&c == &rhs.c); return i < rhs.i; }
197  bool operator > (const Iterator& rhs) const { assert(&c == &rhs.c); return i > rhs.i; }
198  bool operator <= (const Iterator& rhs) const { assert(&c == &rhs.c); return i <= rhs.i; }
199  bool operator >= (const Iterator& rhs) const { assert(&c == &rhs.c); return i >= rhs.i; }
200  Iterator operator + (ssize_t x) const { return Iterator(c, i + x); }
201  ssize_t operator - (Iterator rhs) const { assert(&c == &rhs.c); return i - rhs.i; }
202  };
203 
204  Iterator begin() {return Iterator(_me(), 0);}
205  Iterator end() {return Iterator(_me(), _me().size());}
206 };
207 
208 template <class obj_T,
209  ssize_t read_T(obj_T const *, char const *, char *, size_t),
210  int read_bool_T(obj_T const *, char const *, bool *),
211  int read_double_T(obj_T const *, char const *, double *),
212  int read_longlong_T(obj_T const *, char const *, long long *),
213  ssize_t write_T(obj_T const *, char const *, char const *),
214  int write_bool_T(obj_T const *, char const *, bool),
215  int write_double_T(obj_T const *, char const *, double),
216  int write_longlong_T(obj_T const *, char const *, long long)
217  >
218 class AttrT : public IAttr
219 {
220  obj_T const * const _obj;
221  cstr const _name;
222 public:
223 
224  AttrT(obj_T const * obj, cstr name) : _obj(obj), _name(name){assert(obj && name);}
225 
226  cstr name() const override {return _name;}
227 
228  size_t read(char * dst, size_t size) const override {return check_n(read_T(_obj, _name, dst, size), "iio_..._attr_read");} // Flawfinder: ignore
229  bool read_bool() const override {bool val; check(read_bool_T(_obj, _name, &val), "iio_..._attr_read_bool"); return val;}
230  double read_double() const override {double val; check(read_double_T(_obj, _name, &val), "iio_..._attr_read_double"); return val;}
231  long long read_longlong() const override {long long val; check(read_longlong_T(_obj, _name, &val), "iio_..._attr_read_longlong"); return val;}
232 
233  size_t write(cstr src) override {return check_n(write_T(_obj, _name, src), "iio_..._attr_write");}
234  void write_bool(bool val) override {check(write_bool_T(_obj, _name, val), "iio_..._attr_write_bool");}
235  void write_double(double val) override {check(write_double_T(_obj, _name, val), "iio_..._attr_write_double");}
236  void write_longlong(long long val) override {check(write_longlong_T(_obj, _name, val), "iio_..._attr_write_longlong");}
237 };
238 
239 template <class obj_T, class attr_T, char const * find_attr_T(obj_T const *, char const *)>
240 optional<attr_T> attr(obj_T const * obj, cstr name)
241 {
242  char const * s = find_attr_T(obj, name);
243  if (s)
244  return {attr_T(obj, s)};
245  return {};
246 }
247 
248 template <class obj_T, class attr_T, char const * get_attr_T(obj_T const *, unsigned int)>
249 optional<attr_T> attr(obj_T const * obj, unsigned int idx)
250 {
251  char const * s = get_attr_T(obj, idx);
252  if (s)
253  return {attr_T(obj, s)};
254  return {};
255 }
256 
259 #ifdef DOXYGEN
260 template <class obj_T, class attr_T>
261 class AttrSeqT : public IndexedSequence<AttrSeqT<obj_T, attr_T>, attr_T>
262 #else
263 template <class obj_T, class attr_T,
264  unsigned int get_attrs_count_T(obj_T const *),
265  char const * get_attr_T(obj_T const *, unsigned int),
266  char const * find_attr_T(obj_T const *, char const *)
267  >
268 class AttrSeqT : public IndexedSequence<AttrSeqT<obj_T, attr_T, get_attrs_count_T, get_attr_T, find_attr_T>, attr_T>
269 #endif
270 {
271  obj_T const * const _obj;
272 public:
273  AttrSeqT(obj_T const * obj) : _obj(obj){assert(obj);}
274 
277  size_t size() const {return get_attrs_count_T(_obj);}
278 
281  attr_T operator [](size_t idx)
282  {
283  if (auto ret = attr<obj_T, attr_T, get_attr_T>(_obj, idx))
284  return *ret;
285  throw std::out_of_range("invalid attribute index");
286  }
287 
290  attr_T operator [](cstr name)
291  {
292  if (auto ret = attr<obj_T, attr_T, find_attr_T>(_obj, name))
293  return *ret;
294  throw std::out_of_range("invalid attribute name");
295  }
296 };
297 
298 } // namespace impl
299 
302 class Channel
303 {
304  iio_channel * const p;
305 public:
306 
307  Channel() = delete;
308  Channel(iio_channel * chan) : p(chan), attrs(chan){}
309  operator iio_channel * () const {return p;}
310 
311 #ifndef DOXYGEN
312  typedef impl::AttrT<iio_channel,
314  iio_channel_attr_read_bool,
315  iio_channel_attr_read_double,
316  iio_channel_attr_read_longlong,
318  iio_channel_attr_write_bool,
319  iio_channel_attr_write_double,
320  iio_channel_attr_write_longlong
321  > Attr;
322 
323  typedef impl::AttrSeqT<iio_channel, Attr,
327  > AttrSeq;
328 #else
329  typedef IAttr Attr;
330  typedef impl::AttrSeqT<Channel, Attr> AttrSeq;
331 #endif
332 
333  optional<Attr> attr(cstr name) {return impl::attr<iio_channel, Attr, iio_channel_find_attr>(p, name);}
334  optional<Attr> attr(unsigned int idx) {return impl::attr<iio_channel, Attr, iio_channel_get_attr>(p, idx);}
335 
336  AttrSeq attrs;
337 
338  void disable() {iio_channel_disable(p);}
339  void enable() {iio_channel_enable(p);}
340  optstr find_attr(cstr name) {return impl::opt(iio_channel_find_attr(p, name));}
341  unsigned int attrs_count() const {return iio_channel_get_attrs_count(p);}
342  void * data() const {return iio_channel_get_data(p);}
343  Device device();
344  cstr id() const {return iio_channel_get_id(p);}
345  iio_modifier modifier() const {return iio_channel_get_modifier(p);}
346  optstr name() const { return impl::opt(iio_channel_get_name(p));}
347  iio_chan_type type() const {return iio_channel_get_type(p);}
348  bool is_enabled() const { return iio_channel_is_enabled(p);}
349  bool is_output() const { return iio_channel_is_output(p);}
350  bool is_scan_element() const { return iio_channel_is_scan_element(p);}
351  size_t read(Buffer buffer, void * dst, size_t len) const; // Flawfinder: ignore
352  size_t read_raw(Buffer buffer, void * dst, size_t len) const;
353  void set_data(void * data){iio_channel_set_data(p, data);}
354  size_t write(Buffer buffer, void const * src, size_t len);
355  size_t write_raw(Buffer buffer, void const * src, size_t len);
356 
357  void convert(void * dst, void const * src) const {iio_channel_convert(p, dst, src);}
358  void convert_inverse(void * dst, void const * src) const {iio_channel_convert_inverse(p, dst, src);}
359  iio_data_format const * data_format() const {return iio_channel_get_data_format(p);}
360  unsigned long index() const { return impl::check_n(iio_channel_get_index(p), "iio_channel_get_index");}
361 };
362 
365 class Buffer
366 {
367  iio_buffer * const p;
368 public:
369  Buffer(iio_buffer * buffer) : p(buffer){}
370  operator iio_buffer * () const {return p;}
371  void cancel() {iio_buffer_cancel(p);}
372  void * end() {return iio_buffer_end(p);}
373  void * first(Channel channel){ return iio_buffer_first(p, channel);}
374  ssize_t for_each(ssize_t (*callback)(const struct iio_channel *chn, void *src, size_t bytes, void *d), void *data){return iio_buffer_foreach_sample(p, callback, data);}
375  void * data() {return iio_buffer_get_data(p);}
376  Device device();
377  int poll_fd() const {
378  int const ret = iio_buffer_get_poll_fd(p);
379  if (ret < 0)
380  impl::err(-ret, "iio_buffer_get_poll_fd");
381  return ret;
382  }
383  size_t push() const { return impl::check_n(iio_buffer_push(p), "iio_buffer_push");}
384  size_t push_partial(size_t samples_count) const {return impl::check_n(iio_buffer_push_partial(p, samples_count), "iio_buffer_push_partial");}
385  size_t refill() const { return impl::check_n(iio_buffer_refill(p), "iio_buffer_refill");}
386  void set_blocking_mode(bool blocking){impl::check(iio_buffer_set_blocking_mode(p, blocking), "iio_buffer_set_blocking_mode");}
387  void set_data(void * data){iio_buffer_set_data(p, data);}
388  void * start() {return iio_buffer_start(p);}
389  ptrdiff_t step() const {return iio_buffer_step(p);}
390 };
391 
394 class Device : public impl::IndexedSequence<Device, Channel>
395 {
396  iio_device * const p;
397 public:
398 
399  size_t size() const
400  {
401  return channels_count();
402  }
403 
404  Channel operator [](size_t i)
405  {
406  assert(i < channels_count());
407  return channel(i);
408  }
409 
410 #ifndef DOXYGEN
411  typedef impl::AttrT<iio_device,
413  iio_device_attr_read_bool,
414  iio_device_attr_read_double,
415  iio_device_attr_read_longlong,
417  iio_device_attr_write_bool,
418  iio_device_attr_write_double,
419  iio_device_attr_write_longlong
420  > Attr;
421 
422  typedef impl::AttrSeqT<iio_device, Attr,
426  > AttrSeq;
427 #else
428  typedef IAttr Attr;
429  typedef impl::AttrSeqT<Channel, Attr> AttrSeq;
430 #endif
431  optional<Attr> attr(cstr name) {return impl::attr<iio_device, Attr, iio_device_find_attr>(p, name);}
432  optional<Attr> attr(unsigned int idx) {return impl::attr<iio_device, Attr, iio_device_get_attr>(p, idx);}
433 
434  AttrSeq attrs;
435 
436 #ifndef DOXYGEN
437  typedef impl::AttrT<iio_device,
439  iio_device_debug_attr_read_bool,
440  iio_device_debug_attr_read_double,
441  iio_device_debug_attr_read_longlong,
443  iio_device_debug_attr_write_bool,
444  iio_device_debug_attr_write_double,
445  iio_device_debug_attr_write_longlong
446  > DebugAttr;
447 
448  typedef impl::AttrSeqT<iio_device, DebugAttr,
452  > DebugAttrSeq;
453 #else
454  typedef IAttr DebugAttr;
455  typedef impl::AttrSeqT<Channel, DebugAttr> DebugAttrSeq;
456 #endif
457 
458  optional<DebugAttr> debug_attr(cstr name) {return impl::attr<iio_device, DebugAttr, iio_device_find_debug_attr>(p, name);}
459  optional<DebugAttr> debug_attr(unsigned int idx) {return impl::attr<iio_device, DebugAttr, iio_device_get_debug_attr>(p, idx);}
460 
461  DebugAttrSeq debug_attrs;
462 
463 #ifndef DOXYGEN
464  typedef impl::AttrT<iio_device,
466  iio_device_buffer_attr_read_bool,
467  iio_device_buffer_attr_read_double,
468  iio_device_buffer_attr_read_longlong,
470  iio_device_buffer_attr_write_bool,
471  iio_device_buffer_attr_write_double,
472  iio_device_buffer_attr_write_longlong
473  > BufferAttr;
474 
475  typedef impl::AttrSeqT<iio_device, BufferAttr,
479  > BufferAttrSeq;
480 #else
481  typedef IAttr BufferAttr;
482  typedef impl::AttrSeqT<Channel, BufferAttr> BufferAttrSeq;
483 #endif
484 
485  optional<BufferAttr> buffer_attr(cstr name) {return impl::attr<iio_device, BufferAttr, iio_device_find_buffer_attr>(p, name);}
486  optional<BufferAttr> buffer_attr(unsigned int idx) {return impl::attr<iio_device, BufferAttr, iio_device_get_buffer_attr>(p, idx);}
487 
488  BufferAttrSeq buffer_attrs;
489 
490  Device() = delete;
491  Device(iio_device * dev) : p(dev), attrs(dev), debug_attrs(dev), buffer_attrs(dev){}
492  operator iio_device * () const {return p;}
493 
494  optstr find_attr(cstr name) const {return impl::opt(iio_device_find_attr(p, name));}
495  optstr find_buffer_attr(cstr name) const {return impl::opt(iio_device_find_buffer_attr(p, name));}
496  Channel find_channel(cstr name, bool output) const {return Channel{iio_device_find_channel(p, name, output)};}
497  unsigned int attrs_count() const {return iio_device_get_attrs_count(p);}
498  unsigned int buffer_attrs_count() const {return iio_device_get_buffer_attrs_count(p);}
499  Channel channel(unsigned int idx) const {return Channel{iio_device_get_channel(p, idx)};}
500  unsigned int channels_count() const {return iio_device_get_channels_count(p);}
501  Context context();
502  void * data() const {return iio_device_get_data(p);}
503  cstr id() const { return iio_device_get_id(p);}
504  optstr label() const { return impl::opt(iio_device_get_label(p));}
505  optstr name() const { return impl::opt(iio_device_get_name(p));}
506  Device trigger() const {iio_device const * ret; impl::check(iio_device_get_trigger(p, &ret), "iio_device_get_trigger"); return const_cast<iio_device*>(ret);}
507  bool is_trigger() const {return iio_device_is_trigger(p);}
508  void set_data(void * data){iio_device_set_data(p, data);}
509  void set_kernel_buffers_count(unsigned int nb_buffers) {impl::check(iio_device_set_kernel_buffers_count(p, nb_buffers), "iio_device_set_kernel_buffers_count");}
510  void set_trigger(iio_device const * trigger) {impl::check(iio_device_set_trigger(p, trigger), "iio_device_set_trigger");}
511  std::shared_ptr<Buffer> create_buffer(size_t samples_count, bool cyclic)
512  {
513  iio_buffer * buffer = iio_device_create_buffer(p, samples_count, cyclic);
514  if (!buffer)
515  impl::err(errno, "iio_device_create_buffer");
516 
517  auto deleter = [](Buffer * buf) {
518  if (buf)
519  {
520  iio_buffer_destroy(*buf);
521  delete buf;
522  }
523  };
524 
525  return std::shared_ptr<Buffer>{new Buffer(buffer), deleter};
526  }
527 };
528 
531 class Context : public impl::IndexedSequence<Context, Device>
532 {
533  iio_context * const p;
534 public:
535  size_t size() const
536  {
537  return devices_count();
538  }
539 
540  Device operator [](size_t i)
541  {
542  assert(i < devices_count());
543  return device(i);
544  }
545 
546  Context() = delete;
547  Context(iio_context * ctx) : p(ctx){assert(ctx);}
548  operator iio_context * () const {return p;}
549 
550  std::shared_ptr<Context> clone() const {
551  iio_context * ctx = iio_context_clone(p);
552  if (!ctx)
553  impl::err(errno, "iio_context_clone");
554 
555  return impl::new_ctx(ctx);
556  }
557 
558  Device find_device(cstr name) const {return iio_context_find_device(p, name);}
559  std::pair<cstr, cstr> attr(unsigned int idx) const
560  {
561  char const * name, * value;
562  impl::check(iio_context_get_attr(p, idx, &name, &value), "iio_context_get_attr");
563  return {name, value};
564  }
565  optstr attr_value(cstr name) const {return impl::opt(iio_context_get_attr_value(p, name));}
566  unsigned int attrs_count() const {return iio_context_get_attrs_count(p);}
567  cstr description() const {return iio_context_get_description(p);}
568  Device device(unsigned int idx) const
569  {
570  return Device{iio_context_get_device(p, idx)};
571  }
572  unsigned int devices_count() const {return iio_context_get_devices_count(p);}
573  cstr name() const {return iio_context_get_name(p);}
574 
575  struct Version
576  {
577  unsigned int major, minor;
578  std::string git_tag;
579  };
580 
581  Version version() const {
582  Version ver;
583  char git_tag[8]; // Flawfinder: ignore
584  impl::check(iio_context_get_version(p, &ver.major, &ver.minor, git_tag), "iio_context_get_version");
585  ver.git_tag = git_tag;
586  return ver;
587  }
588 
589  cstr xml() const {return iio_context_get_xml(p);}
590  void set_timeout(unsigned int timeout_ms){impl::check(iio_context_set_timeout(p, timeout_ms), "iio_context_set_timeout");}
591 };
592 
593 inline Context Device::context(){return const_cast<iio_context*>(iio_device_get_context(p));}
594 inline Device Channel::device() {return const_cast<iio_device*>(iio_channel_get_device(p));}
595 inline Device Buffer::device() {return const_cast<iio_device*>(iio_buffer_get_device(p));}
596 inline size_t Channel::read(Buffer buffer, void * dst, size_t len) const {return iio_channel_read(p, buffer, dst, len);} // Flawfinder: ignore
597 inline size_t Channel::read_raw(Buffer buffer, void * dst, size_t len) const {return iio_channel_read_raw(p, buffer, dst, len);}
598 inline size_t Channel::write(Buffer buffer, void const * src, size_t len) {return iio_channel_write(p, buffer, src, len);}
599 inline size_t Channel::write_raw(Buffer buffer, void const * src, size_t len) {return iio_channel_write_raw(p, buffer, src, len);}
600 
601 namespace impl
602 {
603 inline std::shared_ptr<Context> new_ctx(iio_context * ctx)
604 {
605  assert(ctx);
606 
607  auto deleter = [](Context * ctx) {
608  if (ctx)
609  {
610  iio_context_destroy(*ctx);
611  delete ctx;
612  }
613  };
614 
615  return std::shared_ptr<Context>{new Context(ctx), deleter};
616 }
617 } // namespace impl
618 
619 
622 inline std::shared_ptr<Context> create_from_uri(cstr uri)
623 {
625  if (!ctx)
626  impl::err(errno, "iio_create_context_from_uri");
627 
628  return impl::new_ctx(ctx);
629 }
630 
633 inline std::shared_ptr<Context> create_default_context()
634 {
636  if (!ctx)
637  impl::err(errno, "iio_create_default_context");
638 
639  return impl::new_ctx(ctx);
640 }
641 
644 inline std::shared_ptr<Context> create_local_context()
645 {
647  if (!ctx)
648  impl::err(errno, "iio_create_local_context");
649 
650  return impl::new_ctx(ctx);
651 }
652 
655 inline std::shared_ptr<Context> create_network_context(cstr host)
656 {
658  if (!ctx)
659  impl::err(errno, "iio_create_network_context");
660 
661  return impl::new_ctx(ctx);
662 }
663 
666 inline std::shared_ptr<Context> create_xml_context(cstr xml_file)
667 {
668  iio_context * ctx = iio_create_xml_context(xml_file);
669  if (!ctx)
670  impl::err(errno, "iio_create_xml_context");
671 
672  return impl::new_ctx(ctx);
673 }
674 
677 inline std::shared_ptr<Context> create_xml_context_mem(char const * xml, size_t len)
678 {
679  iio_context * ctx = iio_create_xml_context_mem(xml, len);
680  if (!ctx)
681  impl::err(errno, "iio_create_xml_context_mem");
682 
683  return impl::new_ctx(ctx);
684 }
685 
687 {
688  iio_context_info const * const p;
689 public:
690  ContextInfo() = delete;
691  ContextInfo(iio_context_info const * i) : p(i){assert(i);}
692  operator iio_context_info const * () const {return p;}
693 
694  cstr description() const {return iio_context_info_get_description(p);}
695  cstr uri() const {return iio_context_info_get_uri(p);}
696 };
697 
699 {
700  iio_scan_context * const p;
701 public:
702  ScanContext() = delete;
703  ScanContext(iio_scan_context * ctx) : p(ctx){assert(ctx);}
704  operator iio_scan_context * () const {return p;}
705 
706  class InfoList : public impl::IndexedSequence<InfoList, ContextInfo>
707  {
708  iio_context_info ** const p;
709  size_t const n;
710  public:
711  InfoList() = delete;
712  InfoList(iio_context_info ** p, size_t n) : p(p), n(n){assert(p);}
713  operator iio_context_info ** () const {return p;}
714 
715  size_t size() const {return n;}
716 
717  ContextInfo operator [] (size_t i) const
718  {
719  if (i >= n)
720  throw std::out_of_range("invalid info index");
721 
722  return ContextInfo(p[i]);
723  }
724  };
725 
726  std::shared_ptr<InfoList> info_list() const
727  {
728  iio_context_info ** lst;
729  ssize_t const n = iio_scan_context_get_info_list(p, &lst);
730  if (n < 0)
731  impl::err(static_cast<int>(-n), "iio_scan_context_get_info_list");
732 
733 
734  auto deleter = [](InfoList * lst) {
735  if (lst)
736  {
738  delete lst;
739  }
740  };
741 
742  return std::shared_ptr<InfoList>{new InfoList(lst, n), deleter};
743  }
744 };
745 
746 std::shared_ptr<ScanContext> create_scan_context(optstr backend, int flags)
747 {
748  iio_scan_context * ctx = iio_create_scan_context(backend ? static_cast<char const*>(*backend) : nullptr, flags);
749  if (!ctx)
750  impl::err(errno, "iio_create_scan_context");
751 
752  auto deleter = [](ScanContext * ctx) {
753  if (ctx)
754  {
756  delete ctx;
757  }
758  };
759 
760  return std::shared_ptr<ScanContext>{new ScanContext(ctx), deleter};
761 }
762 
763 class ScanBlock : public impl::IndexedSequence<ScanBlock, ContextInfo>
764 {
765  iio_scan_block * const p;
766  size_t const n;
767 public:
768  ScanBlock() = delete;
769  ScanBlock(iio_scan_block * blk) : p(blk), n(impl::check_n(iio_scan_block_scan(blk), "iio_scan_block_scan")){assert(blk);}
770  operator iio_scan_block * () const {return p;}
771 
772 
773  size_t size() const {return n;}
774 
775  ContextInfo operator [] (unsigned int i) const
776  {
778  return ContextInfo(info);
779  impl::err(errno, "iio_scan_block_get_info");
780  }
781 
782 };
783 
784 std::shared_ptr<ScanBlock> create_scan_block(optstr backend, int flags)
785 {
786  iio_scan_block * blk = iio_create_scan_block(backend ? static_cast<char const*>(*backend) : nullptr, flags);
787  if (!blk)
788  impl::err(errno, "iio_create_scan_block");
789 
790  auto deleter = [](ScanBlock * blk) {
791  if (blk)
792  {
794  delete blk;
795  }
796  };
797 
798  return std::shared_ptr<ScanBlock>{new ScanBlock(blk), deleter};
799 }
800 
801 
806 inline double value(Channel ch)
807 {
808  {
809  double val;
810  if (!iio_channel_attr_read_double(ch, "input", &val))
811  return val / 1000.;
812  }
813 
814  double scale = 1;
815  iio_channel_attr_read_double(ch, "scale", &scale);
816 
817  double offset = 0;
818  iio_channel_attr_read_double(ch, "offset", &offset);
819 
820  double raw;
821  impl::check(iio_channel_attr_read_double(ch, "raw", &raw), "reading raw value");
822 
823  return (raw + offset) * scale / 1000.;
824 }
825 
826 } // namespace iiopp
const char * iio_channel_get_name(const struct iio_channel *chn)
Retrieve the channel name (e.g.
Definition: channel.c:308
Definition: compat.c:303
__api __check_ret ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx, struct iio_context_info ***info)
Enumerate available contexts.
Non-owning immutable null terminated string.
Definition: iiopp.h:75
void iio_context_info_list_free(struct iio_context_info **list)
Free a context info list.
Definition: compat.c:553
const char * iio_channel_get_id(const struct iio_channel *chn)
Retrieve the channel ID (e.g.
Definition: channel.c:303
std::shared_ptr< Context > create_network_context(cstr host)
C++ wrapper for iio_create_network_context.
Definition: iiopp.h:655
bool iio_channel_is_output(const struct iio_channel *chn)
Return True if the given channel is an output channel.
Definition: channel.c:313
unsigned int iio_device_get_buffer_attrs_count(const struct iio_device *dev)
Enumerate the buffer-specific attributes of the given device.
Definition: compat.c:867
unsigned int iio_context_get_devices_count(const struct iio_context *ctx)
Enumerate the devices found in the given context.
Definition: compat.c:753
std::shared_ptr< Context > create_default_context()
C++ wrapper for iio_create_default_context.
Definition: iiopp.h:633
struct iio_scan * iio_create_scan_context(const char *backends, unsigned int flags)
Create a scan context.
Definition: compat.c:571
struct iio_scan_block * iio_create_scan_block(const char *backend, unsigned int flags)
Create a scan block.
Definition: compat.c:696
bool iio_device_is_trigger(const struct iio_device *dev)
Return True if the given device is a trigger.
Definition: compat.c:1328
size_t size() const
Count of attributes.
Definition: iiopp.h:277
void * iio_buffer_get_data(const struct iio_buffer *buf)
Retrieve a previously associated pointer of an iio_buffer structure.
Definition: buffer.c:22
void iio_context_destroy(struct iio_context *ctx)
Destroy the given context.
Definition: compat.c:492
const struct iio_device * iio_buffer_get_device(const struct iio_buffer *buf)
Retrieve a pointer to the iio_device structure.
Definition: buffer.c:27
void iio_buffer_set_data(struct iio_buffer *buf, void *data)
Associate a pointer to an iio_buffer structure.
Definition: buffer.c:17
void iio_channel_convert_inverse(const struct iio_channel *chn, void *dst, const void *src)
Convert the sample from host format to hardware format.
Definition: channel.c:601
C++ wrapper for the Buffer C-API.
Definition: iiopp.h:365
const struct iio_data_format * iio_channel_get_data_format(const struct iio_channel *chn)
Get a pointer to a channel&#39;s data format structure.
Definition: channel.c:442
Definition: iiopp.h:218
struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev, unsigned int idx, const struct iio_channels_mask *mask)
Create an input or output buffer associated to the given device.
Definition: buffer.c:98
unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev)
Enumerate the debug attributes of the given device.
Definition: compat.c:884
const struct iio_device * iio_channel_get_device(const struct iio_channel *chn)
Retrieve a pointer to the iio_device structure.
Definition: channel.c:807
unsigned int iio_device_get_attrs_count(const struct iio_device *dev)
Enumerate the device-specific attributes of the given device.
Definition: compat.c:850
#define iio_device_attr_write(dev, attr, val)
Set the value of the given device-specific attribute.
Definition: iio.h:803
Represents an input or output channel of a device.
Definition: iio-private.h:106
struct iio_context_info * iio_scan_block_get_info(struct iio_scan_block *blk, unsigned int index)
Get the iio_context_info for a particular context.
Definition: compat.c:685
struct iio_context * iio_create_default_context(void)
Create a context from local or remote IIO devices.
Definition: compat.c:548
Definition: iio_stresstest.c:197
bool iio_channel_is_scan_element(const struct iio_channel *chn)
Return True if the given channel is a scan element.
Definition: channel.c:318
unsigned int iio_channel_get_attrs_count(const struct iio_channel *chn)
Enumerate the channel-specific attributes of the given channel.
Definition: channel.c:333
std::shared_ptr< Context > create_xml_context_mem(char const *xml, size_t len)
C++ wrapper for iio_create_xml_context_mem.
Definition: iiopp.h:677
struct iio_context * iio_create_context_from_uri(const char *uri)
Create a context from a URI description.
Definition: compat.c:438
Serves as base class to implement a vector-like interface.
Definition: iiopp.h:172
const char * iio_device_get_label(const struct iio_device *dev)
Retrieve the device label (e.g.
Definition: compat.c:807
int iio_context_get_attr(const struct iio_context *ctx, unsigned int index, const char **name, const char **value)
Retrieve the name and value of a context-specific attribute.
Definition: compat.c:780
#define iio_device_buffer_attr_write(dev, buf_id, attr, val)
Set the value of the given buffer-specific attribute.
Definition: iio.h:866
Represents a device in the IIO context.
Definition: iio-private.h:130
size_t iio_channel_read(const struct iio_channel *chn, const struct iio_block *block, void *dst, size_t len, bool raw)
Demultiplex and convert the samples of a given channel.
Definition: channel.c:638
__api void iio_scan_context_destroy(struct iio_scan_context *ctx)
Destroy the given scan context.
const char * iio_device_get_buffer_attr(const struct iio_device *dev, unsigned int index)
Get the buffer-specific attribute present at the given index.
Definition: compat.c:872
int iio_device_set_kernel_buffers_count(const struct iio_device *dev, unsigned int nb_buffers)
Configure the number of kernel buffers for a device.
Definition: compat.c:1333
C++ wrapper for the Channel C-API.
Definition: iiopp.h:302
struct iio_device * iio_context_find_device(const struct iio_context *ctx, const char *name)
Try to find a device structure by its ID, label or name.
Definition: compat.c:765
struct iio_channel * iio_device_find_channel(const struct iio_device *dev, const char *name, bool output)
Try to find a channel structure by its name of ID.
Definition: compat.c:907
#define iio_device_debug_attr_write(dev, attr, val)
Set the value of the given debug attribute.
Definition: iio.h:1600
iio_modifier
IIO channel modifier.
Definition: iio.h:207
double value(Channel ch)
Reads the value of a channel by using "input" or "raw" attribute and applying "scale" and "offset" if...
Definition: iiopp.h:806
#define iio_channel_attr_read(chn, attr, ptr)
Read the content of the given channel-specific attribute.
Definition: iio.h:1021
void iio_buffer_destroy(struct iio_buffer *buf)
Destroy the given buffer.
Definition: buffer.c:161
struct iio_channel * iio_device_get_channel(const struct iio_device *dev, unsigned int index)
Get the channel present at the given index.
Definition: compat.c:901
const char * iio_context_info_get_description(const struct iio_context_info *info)
Get a description of a discovered context.
Definition: compat.c:665
#define iio_device_debug_attr_read(dev, attr, ptr)
Read the content of the given debug attribute.
Definition: iio.h:1573
#define iio_channel_attr_write(chn, attr, val)
Set the value of the given channel-specific attribute.
Definition: iio.h:1048
struct iio_context * iio_create_local_context(void)
Create a context from local IIO devices (Linux only)
Definition: compat.c:543
const char * iio_context_get_attr_value(const struct iio_context *ctx, const char *name)
Retrieve the value of a context-specific attribute.
Definition: compat.c:786
optional< cstr > optstr
Optional string, used for C-functions that return nullptr for "no value".
Definition: iiopp.h:125
enum iio_modifier iio_channel_get_modifier(const struct iio_channel *chn)
Get the modifier type of the given channel.
Definition: channel.c:323
struct iio_context * iio_create_network_context(const char *hostname)
Create a context from the network.
Definition: compat.c:538
#define iio_device_attr_read(dev, attr, ptr)
Read the content of the given device-specific attribute.
Definition: iio.h:776
Public C++ API.
Definition: iiopp.h:56
const char * iio_context_get_name(const struct iio_context *ctx)
Get the name of the given context.
Definition: compat.c:738
void * iio_device_get_data(const struct iio_device *dev)
Retrieve a previously associated pointer of an iio_device structure.
Definition: compat.c:812
C++ wrapper for the Context C-API.
Definition: iiopp.h:531
const char * iio_device_find_buffer_attr(const struct iio_device *dev, const char *name)
Try to find a buffer-specific attribute by its name.
Definition: compat.c:878
const char * iio_device_get_attr(const struct iio_device *dev, unsigned int index)
Get the device-specific attribute present at the given index.
Definition: compat.c:855
bool iio_channel_is_enabled(const struct iio_channel *chn, const struct iio_channels_mask *mask)
Returns True if the channel is enabled.
Definition: channel.c:448
C++ wrapper for the Device C-API.
Definition: iiopp.h:394
const char * iio_device_get_id(const struct iio_device *dev)
Retrieve the device ID (e.g.
Definition: compat.c:797
A random access iterator for an IndexedSequence.
Definition: iiopp.h:179
const struct iio_context * iio_device_get_context(const struct iio_device *dev)
Retrieve a pointer to the iio_context structure.
Definition: compat.c:792
iio_chan_type
IIO channel type.
Definition: iio.h:161
Public interface.
const char * iio_device_find_debug_attr(const struct iio_device *dev, const char *name)
Try to find a debug attribute by its name.
Definition: compat.c:895
Thrown to report errors.
Definition: iiopp.h:88
void iio_buffer_cancel(struct iio_buffer *buf)
Cancel all buffer operations.
Definition: buffer.c:32
long iio_channel_get_index(const struct iio_channel *chn)
Get the index of the given channel.
Definition: channel.c:437
void iio_channel_convert(const struct iio_channel *chn, void *dst, const void *src)
Convert the sample from hardware format to host format.
Definition: channel.c:569
struct iio_context * iio_create_xml_context(const char *xml_file)
Create a context from a XML file.
Definition: compat.c:511
std::shared_ptr< Context > create_local_context()
C++ wrapper for iio_create_local_context.
Definition: iiopp.h:644
void * iio_channel_get_data(const struct iio_channel *chn)
Retrieve a previously associated pointer of an iio_channel structure.
Definition: channel.c:432
Definition: iiopp.h:763
void iio_channel_set_data(struct iio_channel *chn, void *data)
Associate a pointer to an iio_channel structure.
Definition: channel.c:427
ssize_t iio_scan_block_scan(struct iio_scan_block *blk)
Enumerate available contexts via scan block.
Definition: compat.c:675
int iio_context_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8])
Get the version of the backend in use.
Definition: compat.c:722
void iio_device_set_data(struct iio_device *dev, void *data)
Associate a pointer to an iio_device structure.
Definition: compat.c:819
unsigned int iio_context_get_attrs_count(const struct iio_context *ctx)
Get the number of context-specific attributes.
Definition: compat.c:775
An input or output buffer, used to read or write samples.
Definition: iio-private.h:145
std::shared_ptr< Context > create_xml_context(cstr xml_file)
C++ wrapper for iio_create_xml_context.
Definition: iiopp.h:666
void iio_strerror(int err, char *dst, size_t len)
Get a string description of an error code.
Definition: compat.c:1630
#define iio_device_buffer_attr_read(dev, buf_id, attr, ptr)
Read the content of the given buffer-specific attribute.
Definition: iio.h:836
Vector-like accessor for all attributes of an object.
Definition: iiopp.h:268
Definition: iiopp.h:706
void iio_channel_enable(const struct iio_channel *chn, struct iio_channels_mask *mask)
Enable the given channel.
Definition: channel.c:454
const char * iio_device_get_name(const struct iio_device *dev)
Retrieve the device name (e.g.
Definition: compat.c:802
const char * iio_context_get_xml(const struct iio_context *ctx)
Obtain a XML representation of the given context.
Definition: compat.c:748
Definition: compat.c:298
void iio_scan_block_destroy(struct iio_scan_block *blk)
Destroy the given scan block.
Definition: compat.c:715
const char * iio_device_find_attr(const struct iio_device *dev, const char *name)
Try to find a device-specific attribute by its name.
Definition: compat.c:861
void iio_channel_disable(const struct iio_channel *chn, struct iio_channels_mask *mask)
Disable the given channel.
Definition: channel.c:461
Common interface for attribute access.
Definition: iiopp.h:96
struct iio_device * iio_context_get_device(const struct iio_context *ctx, unsigned int index)
Get the device present at the given index.
Definition: compat.c:758
int iio_context_set_timeout(struct iio_context *ctx, unsigned int timeout_ms)
Set a timeout for I/O operations.
Definition: compat.c:770
const char * iio_channel_get_attr(const struct iio_channel *chn, unsigned int index)
Get the channel-specific attribute present at the given index.
Definition: channel.c:338
std::shared_ptr< Context > create_from_uri(cstr uri)
C++ wrapper for iio_create_context_from_uri.
Definition: iiopp.h:622
const char * iio_channel_find_attr(const struct iio_channel *chn, const char *name)
Try to find a channel-specific attribute by its name.
Definition: channel.c:361
const char * iio_context_info_get_uri(const struct iio_context_info *info)
Get the URI of a discovered context.
Definition: compat.c:670
int iio_device_set_trigger(const struct iio_device *dev, const struct iio_device *trigger)
Associate a trigger to a given device.
Definition: compat.c:1321
unsigned int iio_device_get_channels_count(const struct iio_device *dev)
Enumerate the channels of the given device.
Definition: compat.c:845
size_t iio_channel_write(const struct iio_channel *chn, struct iio_block *block, const void *src, size_t len, bool raw)
Convert and multiplex the samples of a given channel.
Definition: channel.c:679
int iio_device_get_trigger(const struct iio_device *dev, const struct iio_device **trigger)
Retrieve the trigger of a given device.
Definition: compat.c:1314
Definition: iiopp.h:686
const char * iio_context_get_description(const struct iio_context *ctx)
Get a description of the given context.
Definition: compat.c:743
const char * iio_device_get_debug_attr(const struct iio_device *dev, unsigned int index)
Get the debug attribute present at the given index.
Definition: compat.c:889
Contains the format of a data sample.
Definition: iio.h:1430
enum iio_chan_type iio_channel_get_type(const struct iio_channel *chn)
Get the type of the given channel.
Definition: channel.c:328
Contains the representation of an IIO context.
Definition: iio-private.h:81
Definition: iiopp.h:575
Definition: iiopp.h:698