diff --git a/player/plutoplayer_win/ad9361.h b/player/plutoplayer_win/ad9361.h
new file mode 100644
index 0000000..6b0aa79
--- /dev/null
+++ b/player/plutoplayer_win/ad9361.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2015 Analog Devices, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+
+ /** @file ad9361.h
+ * @brief Public interface */
+
+#ifndef __AD9361_H__
+#define __AD9361_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup FLAGS MCS Flags
+ *
+ * @{
+ */
+/** Flag for ad9361_multichip_sync which verifies interface timing between
+ master and all slaves is identical
+*/
+#define FIXUP_INTERFACE_TIMING 1
+/** Flag for ad9361_multichip_sync which checks if master and associated slaves
+ have the same sample rate
+*/
+#define CHECK_SAMPLE_RATES 2
+
+/** @} */
+
+#ifdef _WIN32
+# ifdef LIBAD9361_EXPORTS
+# define __api __declspec(dllexport)
+# else
+# define __api __declspec(dllimport)
+# endif
+#elif __GNUC__ >= 4 && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY)
+# define __api __attribute__((visibility ("default")))
+#else
+# define __api
+#endif
+
+struct iio_context;
+struct iio_device;
+
+/**
+ * @struct filter_design_parameters
+ * @brief Custom Filter Design Parameters
+ *
+ * A structure for custom filter designs for the AD936X programmable FIR
+ * in both TX and RX paths.
+ */
+struct filter_design_parameters {
+ double Rdata; /**< Data rate of digital interface */
+ double Fpass; /**< Stop edge frequency in hertz of passband */
+ double Fstop; /**< Start edge frequency in hertz of stopband */
+ double caldiv; /**< Baseband analog filter calibration divider setting [1-511] */
+ double FIR; /**< Decimation/Interpolation setting of FIR [1,2,4] */
+ double HB1; /**< Decimation/Interpolation setting of HB1 [1,2] */
+ double DAC_div; /**< Divider enable setting of DAC clock [0,1] */
+ const char *Type; /**< Designer mode (only Lowpass supported) */
+ const char *RxTx; /**< Filter path [Tx,Rx] */
+ double RFbw; /**< 3dB corner of analog filter in hertz */
+ double converter_rate; /**< Rate of ADC in hertz */
+ double PLL_rate; /**< Rate of PLL in hertz */
+ double Fcenter; /**< Center frequency in hertz of bandpass (Unused) */
+ double wnom; /**< RF bandwidth of analog filter in hertz */
+ double FIRdBmin; /**< Minimum stop band attentuation of the FIR in dB */
+ double int_FIR; /**< Enable use of internal FIR filter [0,1] */
+ double PLL_mult; /**< Ratio of converter to PLL rate */
+ double Apass; /**< Desired passband ripple in dB */
+ double Astop; /**< Desired stopband attenuation in dB */
+ double phEQ; /**< Enable phase equalization [0,1] */
+ double HB2; /**< Decimation/Interpolation setting of HB2 [1,2] */
+ double HB3; /**< Decimation/Interpolation setting of HB3 [1,2,3] */
+ double maxTaps; /**< Maximum allowed FIR taps */
+};
+
+/* ---------------------------------------------------------------------------*/
+/* ------------------------- Top-level functions -----------------------------*/
+/** @defgroup TopLevel Top-level functions
+ * @{ */
+
+
+/** @brief Multi-chip synchronization (MCS) management
+ * @param master A pointer to an iio_device structure
+ * @param slaves A double pointer to an iio_device structure
+ * @param num_slaves Number of slave devices associated with the master
+ * @param flags Control flags for MCS configuration
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_multichip_sync(struct iio_device *master,
+ struct iio_device **slaves, unsigned int num_slaves,
+ unsigned int flags);
+
+/** @brief FMComms5 specific MCS management
+ * @param ctx A pointer to an iio_context structure
+ * @param flags Control flags for MCS configuration
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_fmcomms5_multichip_sync(
+ struct iio_context *ctx, unsigned int flags);
+
+/** @brief Baseband rate configuration with generic filter support
+ * @param dev A pointer to an iio_device structure
+ * @param rate Rate in samples per second of desired baseband rate
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: Three possible filters are loaded based on required rate and
+ * associated decimation/interpolation. These filters are generally very wide
+ * band and not waveform specific. */
+__api int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate);
+
+/** @brief Enable or disable transmit and receiver FIRs simultaneously
+ * @param dev A pointer to an iio_device structure
+ * @param enable Integer to enable FIRs when 1 or disable when 0
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_set_trx_fir_enable(struct iio_device *dev, int enable);
+
+/** @brief Get current enable value of transmit and receiver FIRs
+ * @param dev A pointer to an iio_device structure
+ * @param enable Returned integer value of FIR enabled
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_get_trx_fir_enable(struct iio_device *dev, int *enable);
+
+/** @brief Design custom FIR filter from specific design criteria
+ * @param parameters A pointer filter designer structure
+ * @param taps A pointer to taps of designed filter
+ * @param num_taps A pointer to integer number of taps designed in taps
+ * @param gain Integer gain for designed filter
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_generate_fir_taps(struct filter_design_parameters *parameters,
+ short *taps, int *num_taps, int *gain);
+
+/** @brief Calculate the clock path rates for both transmit and receiver paths
+ * @param tx_sample_rate Sample rate in samples per second of desired baseband rate
+ * @param rate_gov Rate governor enable setting forcing HB3=3 when enabled
+ * @param rx_path_clks A pointer to a unsigned long variable where the 6 RX path rates should be stored
+ * @param tx_path_clks A pointer to a unsigned long variable where the 6 TX path rates should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_calculate_rf_clock_chain(unsigned long tx_sample_rate,
+ unsigned long rate_gov,
+ unsigned long *rx_path_clks,
+ unsigned long *tx_path_clks);
+
+/** @brief Calculate the clock path rates and default filter settings for both transmit and receiver for a desired baseband rate
+ * @param fdpTX Filter design parameters structure where TX filter design parameters will be stored
+ * @param fdpRX Filter design parameters structure where RX filter design parameters will be stored
+ * @param sample_rate Desired basedband sample rate in samples per second for both RX and TX filter configurations
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_calculate_rf_clock_chain_fdp(struct filter_design_parameters *fdpTX,
+ struct filter_design_parameters *fdpRX,
+ unsigned long sample_rate);
+
+/** @brief Baseband rate configuration with custom filter support based on desired baseband sample rate
+ * @param dev A pointer to an iio_device structure
+ * @param rate Rate in samples per second of desired baseband rate
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: Designed filter will have the following configuration:
+ * Fpass = rate / 3
+ * Fstop = Fpass * 1.25
+ * wnomTX = 1.6 * Fstop
+ * wnomRX = 1.4 * Fstop */
+__api int ad9361_set_bb_rate_custom_filter_auto(struct iio_device *dev,
+ unsigned long rate);
+
+/** @brief Baseband rate configuration with custom filter support based on desired baseband sample rate and simplified filter configuration
+ * @param dev A pointer to an iio_device structure
+ * @param rate Rate in samples per second of desired baseband rate
+ * @param Fpass Stop edge frequency in hertz of passband
+ * @param Fstop Start edge frequency in hertz of stopband
+ * @param wnom_tx TX RF bandwidth of analog filter in hertz
+ * @param wnom_rx RX RF bandwidth of analog filter in hertz
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api int ad9361_set_bb_rate_custom_filter_manual(struct iio_device *dev,
+ unsigned long rate, unsigned long Fpass,
+ unsigned long Fstop, unsigned long wnom_tx,
+ unsigned long wnom_rx);
+
+/** @brief FMComms5 phase synchronize all TX and RX channels together
+ * @param ctx A pointer to an iio_context structure
+ * @param lo Frequency in hertz of LO for TX and RX
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned. If -2 is returned calibration failed
+ *
+ * NOTES: To perform calibration the following side effects occur:
+ * - RF bandwidths of both TX and RX are expanded to the current sample rate. It can be changed after calibration without effecting phase synchronization.
+ * - DDSs are enabled and left on after synchronization. Changing these DDSs or switching to DMA sources will not effect phase synchronization.
+ * - TX and RX LOs are set to the same frequency based on the input provided. LO changes can invalidate phase synchronization.
+ * - AGCs are set to manual mode at predetermined hardware gains for TX and RX. Gain changes can invalidate phase synchronization.
+ *
+ * Phase synchronization is valid until the LOs are retuned or sample rates change or gains are modified.
+ *
+ * External Links:
+ * - Detailed information on synchronization process
+ * - Phase synchronization performance can depend on revision of hardware*/
+__api int ad9361_fmcomms5_phase_sync(struct iio_context *ctx, long long lo);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef __api
+
+#endif /* __AD9361_H__ */
diff --git a/player/plutoplayer_win/ad9361_baseband_auto_rate.c b/player/plutoplayer_win/ad9361_baseband_auto_rate.c
new file mode 100644
index 0000000..5a38973
--- /dev/null
+++ b/player/plutoplayer_win/ad9361_baseband_auto_rate.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2016 Analog Devices, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "ad9361.h"
+
+#include
+#include
+#ifdef _WIN32
+#include
+#include "iio.h"
+#else
+#include
+#include
+#endif
+
+#ifdef _MSC_BUILD
+#define snprintf sprintf_s
+#endif
+
+static int16_t fir_128_4[] = {
+ -15,-27,-23,-6,17,33,31,9,-23,-47,-45,-13,34,69,67,21,-49,-102,-99,-32,69,146,143,48,-96,-204,-200,-69,129,278,275,97,-170,
+ -372,-371,-135,222,494,497,187,-288,-654,-665,-258,376,875,902,363,-500,-1201,-1265,-530,699,1748,1906,845,-1089,-2922,-3424,
+ -1697,2326,7714,12821,15921,15921,12821,7714,2326,-1697,-3424,-2922,-1089,845,1906,1748,699,-530,-1265,-1201,-500,363,902,875,
+ 376,-258,-665,-654,-288,187,497,494,222,-135,-371,-372,-170,97,275,278,129,-69,-200,-204,-96,48,143,146,69,-32,-99,-102,-49,21,
+ 67,69,34,-13,-45,-47,-23,9,31,33,17,-6,-23,-27,-15};
+
+static int16_t fir_128_2[] = {
+ -0,0,1,-0,-2,0,3,-0,-5,0,8,-0,-11,0,17,-0,-24,0,33,-0,-45,0,61,-0,-80,0,104,-0,-134,0,169,-0,
+ -213,0,264,-0,-327,0,401,-0,-489,0,595,-0,-724,0,880,-0,-1075,0,1323,-0,-1652,0,2114,-0,-2819,0,4056,-0,-6883,0,20837,32767,
+ 20837,0,-6883,-0,4056,0,-2819,-0,2114,0,-1652,-0,1323,0,-1075,-0,880,0,-724,-0,595,0,-489,-0,401,0,-327,-0,264,0,-213,-0,
+ 169,0,-134,-0,104,0,-80,-0,61,0,-45,-0,33,0,-24,-0,17,0,-11,-0,8,0,-5,-0,3,0,-2,-0,1,0,-0, 0 };
+
+static int16_t fir_96_2[] = {
+ -4,0,8,-0,-14,0,23,-0,-36,0,52,-0,-75,0,104,-0,-140,0,186,-0,-243,0,314,-0,-400,0,505,-0,-634,0,793,-0,
+ -993,0,1247,-0,-1585,0,2056,-0,-2773,0,4022,-0,-6862,0,20830,32767,20830,0,-6862,-0,4022,0,-2773,-0,2056,0,-1585,-0,1247,0,-993,-0,
+ 793,0,-634,-0,505,0,-400,-0,314,0,-243,-0,186,0,-140,-0,104,0,-75,-0,52,0,-36,-0,23,0,-14,-0,8,0,-4,0};
+
+static int16_t fir_64_2[] = {
+ -58,0,83,-0,-127,0,185,-0,-262,0,361,-0,-488,0,648,-0,-853,0,1117,-0,-1466,0,1954,-0,-2689,0,3960,-0,-6825,0,20818,32767,
+ 20818,0,-6825,-0,3960,0,-2689,-0,1954,0,-1466,-0,1117,0,-853,-0,648,0,-488,-0,361,0,-262,-0,185,0,-127,-0,83,0,-58,0};
+
+#define FIR_BUF_SIZE 8192
+
+int ad9361_set_trx_fir_enable(struct iio_device *dev, int enable)
+{
+ int ret = iio_device_attr_write_bool(dev,
+ "in_out_voltage_filter_fir_en", !!enable);
+ if (ret < 0)
+ ret = iio_channel_attr_write_bool(iio_device_find_channel(dev, "out", false),
+ "voltage_filter_fir_en", !!enable);
+ return ret;
+}
+
+int ad9361_get_trx_fir_enable(struct iio_device *dev, int *enable)
+{
+ bool value;
+
+ int ret = iio_device_attr_read_bool(dev, "in_out_voltage_filter_fir_en", &value);
+
+ if (ret < 0)
+ ret = iio_channel_attr_read_bool(iio_device_find_channel(dev, "out", false),
+ "voltage_filter_fir_en", &value);
+
+ if (!ret)
+ *enable = value;
+
+ return ret;
+}
+
+int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate)
+{
+ struct iio_channel *chan;
+ long long current_rate;
+ int dec, taps, ret, i, enable, len = 0;
+ int16_t *fir;
+ char *buf;
+
+ if (rate <= 20000000UL) {
+ dec = 4;
+ taps = 128;
+ fir = fir_128_4;
+ } else if (rate <= 40000000UL) {
+ dec = 2;
+ fir = fir_128_2;
+ taps = 128;
+ } else if (rate <= 53333333UL) {
+ dec = 2;
+ fir = fir_96_2;
+ taps = 96;
+ } else {
+ dec = 2;
+ fir = fir_64_2;
+ taps = 64;
+ }
+
+ chan = iio_device_find_channel(dev, "voltage0", true);
+ if (chan == NULL)
+ return -ENODEV;
+
+ ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", ¤t_rate);
+ if (ret < 0)
+ return ret;
+
+ ret = ad9361_get_trx_fir_enable(dev, &enable);
+ if (ret < 0)
+ return ret;
+
+ if (enable) {
+ if (current_rate <= (25000000 / 12))
+ iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
+
+ ret = ad9361_set_trx_fir_enable(dev, false);
+ if (ret < 0)
+ return ret;
+ }
+
+ buf = malloc(FIR_BUF_SIZE);
+ if (!buf)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN -6 DEC %d\n", dec);
+ len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN 0 INT %d\n", dec);
+
+ for (i = 0; i < taps; i++)
+ len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", fir[i], fir[i]);
+
+ len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n");
+
+ ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len);
+ free (buf);
+
+ if (ret < 0)
+ return ret;
+
+ if (rate <= (25000000 / 12)) {
+ int dacrate, txrate, max;
+ char readbuf[100];
+
+ ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf));
+ if (ret < 0)
+ return ret;
+ ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d", &dacrate, &txrate);
+ if (ret != 2)
+ return -EFAULT;
+
+ if (txrate == 0)
+ return -EINVAL;
+
+ max = (dacrate / txrate) * 16;
+ if (max < taps)
+ iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
+
+ ret = ad9361_set_trx_fir_enable(dev, true);
+ if (ret < 0)
+ return ret;
+ ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
+ if (ret < 0)
+ return ret;
+ ret = ad9361_set_trx_fir_enable(dev, true);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/player/plutoplayer_win/getopt.c b/player/plutoplayer_win/getopt.c
new file mode 100644
index 0000000..dab5fd8
--- /dev/null
+++ b/player/plutoplayer_win/getopt.c
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 1987, 1993, 1994
+* The Regents of the University of California. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* 3. All advertising materials mentioning features or use of this software
+* must display the following acknowledgement:
+* This product includes software developed by the University of
+* California, Berkeley and its contributors.
+* 4. Neither the name of the University nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+*/
+
+#include "getopt.h"
+#include
+#include
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * Note: Unlike GNU getopt(), after a non-option argument, all further
+ * arguments are considered also non-options. This is similar to
+ * the way non-GNU Unix systems work.
+ */
+int getopt(int nargc, char * const nargv[], const char *ostr)
+{
+ static char *place = EMSG; /* option letter processing */
+ const char *oli; /* option letter list index */
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)printf("illegal option -- %c\n", optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)printf("option requires an argument -- %c\n", optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
+
\ No newline at end of file
diff --git a/player/plutoplayer_win/getopt.h b/player/plutoplayer_win/getopt.h
new file mode 100644
index 0000000..5978e22
--- /dev/null
+++ b/player/plutoplayer_win/getopt.h
@@ -0,0 +1,9 @@
+#ifndef GETOPT_H
+#define GETOPT_H
+
+extern char *optarg;
+extern int optind;
+
+int getopt(int nargc, char * const nargv[], const char *ostr) ;
+
+#endif
diff --git a/player/plutoplayer_win/iio.h b/player/plutoplayer_win/iio.h
new file mode 100644
index 0000000..cefac60
--- /dev/null
+++ b/player/plutoplayer_win/iio.h
@@ -0,0 +1,1974 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * libiio - Library for interfacing industrial I/O (IIO) devices
+ *
+ * Copyright (C) 2014 Analog Devices, Inc.
+ * Author: Paul Cercueil
+ */
+
+/** @file iio.h
+ * @brief Public interface */
+
+#ifndef __IIO_H__
+#define __IIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+#include
+
+#if (defined(_WIN32) || defined(__MBED__))
+#ifndef _SSIZE_T_DEFINED
+typedef ptrdiff_t ssize_t;
+#define _SSIZE_T_DEFINED
+#endif
+#else
+#include
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER < 1800) && !defined(__BOOL_DEFINED)
+#undef bool
+#undef false
+#undef true
+#define bool char
+#define false 0
+#define true 1
+#else
+#include
+#endif
+
+#if defined(__GNUC__) && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY)
+#ifndef __cnst
+#define __cnst __attribute__((const))
+#endif
+#ifndef __pure
+#define __pure __attribute__((pure))
+#endif
+#define __notused __attribute__((unused))
+#ifdef IIO_CHECK_RET
+#define __check_ret __attribute__((warn_unused_result))
+#else
+#define __check_ret
+#endif
+#else
+#define __cnst
+#define __pure
+#define __notused
+#define __check_ret
+#endif
+
+#ifdef _WIN32
+# ifdef LIBIIO_STATIC
+# define __api
+# elif defined(LIBIIO_EXPORTS)
+# define __api __declspec(dllexport)
+# else
+# define __api __declspec(dllimport)
+# endif
+#elif __GNUC__ >= 4 && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY)
+# define __api __attribute__((visibility ("default")))
+#else
+# define __api
+#endif
+
+struct iio_context;
+struct iio_device;
+struct iio_channel;
+struct iio_buffer;
+
+struct iio_context_info;
+struct iio_scan_context;
+struct iio_scan_block;
+
+/*
+ * header guard to protect these enums from being defined
+ * twice
+ */
+#ifndef _IIO_TYPES_H_
+#define _IIO_TYPES_H_
+
+/**
+ * @enum iio_chan_type
+ * @brief IIO channel type
+ *
+ * A IIO channel has a type specifying the type of data associated with the
+ * channel.
+ */
+enum iio_chan_type {
+ IIO_VOLTAGE,
+ IIO_CURRENT,
+ IIO_POWER,
+ IIO_ACCEL,
+ IIO_ANGL_VEL,
+ IIO_MAGN,
+ IIO_LIGHT,
+ IIO_INTENSITY,
+ IIO_PROXIMITY,
+ IIO_TEMP,
+ IIO_INCLI,
+ IIO_ROT,
+ IIO_ANGL,
+ IIO_TIMESTAMP,
+ IIO_CAPACITANCE,
+ IIO_ALTVOLTAGE,
+ IIO_CCT,
+ IIO_PRESSURE,
+ IIO_HUMIDITYRELATIVE,
+ IIO_ACTIVITY,
+ IIO_STEPS,
+ IIO_ENERGY,
+ IIO_DISTANCE,
+ IIO_VELOCITY,
+ IIO_CONCENTRATION,
+ IIO_RESISTANCE,
+ IIO_PH,
+ IIO_UVINDEX,
+ IIO_ELECTRICALCONDUCTIVITY,
+ IIO_COUNT,
+ IIO_INDEX,
+ IIO_GRAVITY,
+ IIO_POSITIONRELATIVE,
+ IIO_PHASE,
+ IIO_MASSCONCENTRATION,
+ IIO_CHAN_TYPE_UNKNOWN = INT_MAX
+};
+
+/**
+ * @enum iio_modifier
+ * @brief IIO channel modifier
+ *
+ * In a addition to a type a IIO channel can optionally have a channel modifier
+ * further specifying the data type of of the channel.
+ */
+enum iio_modifier {
+ IIO_NO_MOD,
+ IIO_MOD_X,
+ IIO_MOD_Y,
+ IIO_MOD_Z,
+ IIO_MOD_X_AND_Y,
+ IIO_MOD_X_AND_Z,
+ IIO_MOD_Y_AND_Z,
+ IIO_MOD_X_AND_Y_AND_Z,
+ IIO_MOD_X_OR_Y,
+ IIO_MOD_X_OR_Z,
+ IIO_MOD_Y_OR_Z,
+ IIO_MOD_X_OR_Y_OR_Z,
+ IIO_MOD_LIGHT_BOTH,
+ IIO_MOD_LIGHT_IR,
+ IIO_MOD_ROOT_SUM_SQUARED_X_Y,
+ IIO_MOD_SUM_SQUARED_X_Y_Z,
+ IIO_MOD_LIGHT_CLEAR,
+ IIO_MOD_LIGHT_RED,
+ IIO_MOD_LIGHT_GREEN,
+ IIO_MOD_LIGHT_BLUE,
+ IIO_MOD_QUATERNION,
+ IIO_MOD_TEMP_AMBIENT,
+ IIO_MOD_TEMP_OBJECT,
+ IIO_MOD_NORTH_MAGN,
+ IIO_MOD_NORTH_TRUE,
+ IIO_MOD_NORTH_MAGN_TILT_COMP,
+ IIO_MOD_NORTH_TRUE_TILT_COMP,
+ IIO_MOD_RUNNING,
+ IIO_MOD_JOGGING,
+ IIO_MOD_WALKING,
+ IIO_MOD_STILL,
+ IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
+ IIO_MOD_I,
+ IIO_MOD_Q,
+ IIO_MOD_CO2,
+ IIO_MOD_VOC,
+ IIO_MOD_LIGHT_UV,
+ IIO_MOD_LIGHT_DUV,
+ IIO_MOD_PM1,
+ IIO_MOD_PM2P5,
+ IIO_MOD_PM4,
+ IIO_MOD_PM10,
+ IIO_MOD_ETHANOL,
+ IIO_MOD_H2,
+ IIO_MOD_O2,
+};
+
+/**
+ * @enum iio_event_type
+ * @brief IIO event type
+ *
+ * Some IIO devices can deliver events. The type of the event can be specified
+ * by one of the iio_event_type values.
+ */
+enum iio_event_type {
+ IIO_EV_TYPE_THRESH,
+ IIO_EV_TYPE_MAG,
+ IIO_EV_TYPE_ROC,
+ IIO_EV_TYPE_THRESH_ADAPTIVE,
+ IIO_EV_TYPE_MAG_ADAPTIVE,
+ IIO_EV_TYPE_CHANGE,
+};
+
+/**
+ * @enum iio_event_direction
+ * @brief IIO event direction
+ *
+ * When applicable, this enum specifies the direction of the iio_event_type.
+ */
+enum iio_event_direction {
+ IIO_EV_DIR_EITHER,
+ IIO_EV_DIR_RISING,
+ IIO_EV_DIR_FALLING,
+ IIO_EV_DIR_NONE,
+};
+
+#endif /* _IIO_TYPES_H_ */
+
+/* ---------------------------------------------------------------------------*/
+/* ------------------------- Scan functions ----------------------------------*/
+/** @defgroup Scan Functions for scanning available contexts
+ * @{
+ * @struct iio_scan_context
+ * @brief The scanning context
+ *
+ * @struct iio_context_info
+ * @brief The information related to a discovered context
+ */
+
+
+/** @brief Create a scan context
+ * @param backend A NULL-terminated string containing a comma-separated
+ * list of the backend(s) to use for scanning.
+ * @param flags Unused for now. Set to 0.
+ * @return on success, a pointer to a iio_scan_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: Libiio version 0.20 and above can handle multiple
+ * strings, for instance "local:usb:", "ip:usb:", "local:usb:ip:", and
+ * require a colon as the delimiter.
+ * Libiio version 0.24 and above prefer a comma instead of colon as the
+ * delimiter, and handle specifying backend-specific information. For
+ * instance, "local,usb=0456:*" will scan the local backend and limit
+ * scans on USB to vendor ID 0x0456, and accept all product IDs. The
+ * "usb=0456:b673" string would limit the scan to the device with this
+ * particular VID/PID. Both IDs are expected in hexadecimal, no 0x
+ * prefix needed. */
+__api __check_ret struct iio_scan_context * iio_create_scan_context(
+ const char *backend, unsigned int flags);
+
+
+/** @brief Destroy the given scan context
+ * @param ctx A pointer to an iio_scan_context structure
+ *
+ * NOTE: After that function, the iio_scan_context pointer shall be invalid. */
+__api void iio_scan_context_destroy(struct iio_scan_context *ctx);
+
+
+/** @brief Enumerate available contexts
+ * @param ctx A pointer to an iio_scan_context structure
+ * @param info A pointer to a 'const struct iio_context_info **' typed variable.
+ * The pointed variable will be initialized on success.
+ * @returns On success, the number of contexts found.
+ * @returns On failure, a negative error number.
+ */
+__api __check_ret ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx,
+ struct iio_context_info ***info);
+
+
+/** @brief Free a context info list
+ * @param info A pointer to a 'const struct iio_context_info *' typed variable
+ */
+__api void iio_context_info_list_free(struct iio_context_info **info);
+
+
+/** @brief Get a description of a discovered context
+ * @param info A pointer to an iio_context_info structure
+ * @return A pointer to a static NULL-terminated string
+ */
+__api __check_ret __pure const char * iio_context_info_get_description(
+ const struct iio_context_info *info);
+
+
+/** @brief Get the URI of a discovered context
+ * @param info A pointer to an iio_context_info structure
+ * @return A pointer to a static NULL-terminated string
+ */
+__api __check_ret __pure const char * iio_context_info_get_uri(
+ const struct iio_context_info *info);
+
+
+/** @brief Create a scan block
+ * @param backend A NULL-terminated string containing the backend to use for
+ * scanning. If NULL, all the available backends are used.
+ * @param flags Unused for now. Set to 0.
+ * @return on success, a pointer to a iio_scan_block structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * Introduced in version 0.20. */
+__api struct iio_scan_block * iio_create_scan_block(
+ const char *backend, unsigned int flags);
+
+
+/** @brief Destroy the given scan block
+ * @param blk A pointer to an iio_scan_block structure
+ *
+ * NOTE: After that function, the iio_scan_block pointer shall be invalid.
+ *
+ * Introduced in version 0.20. */
+__api void iio_scan_block_destroy(struct iio_scan_block *blk);
+
+
+/** @brief Enumerate available contexts via scan block
+ * @param blk A pointer to a iio_scan_block structure.
+ * @returns On success, the number of contexts found.
+ * @returns On failure, a negative error number.
+ *
+ * Introduced in version 0.20. */
+__api ssize_t iio_scan_block_scan(struct iio_scan_block *blk);
+
+
+/** @brief Get the iio_context_info for a particular context
+ * @param blk A pointer to an iio_scan_block structure
+ * @param index The index corresponding to the context.
+ * @return A pointer to the iio_context_info for the context
+ * @returns On success, a pointer to the specified iio_context_info
+ * @returns On failure, NULL is returned and errno is set appropriately
+ *
+ * Introduced in version 0.20. */
+__api struct iio_context_info *iio_scan_block_get_info(
+ struct iio_scan_block *blk, unsigned int index);
+
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Top-level functions -----------------------------*/
+/** @defgroup TopLevel Top-level functions
+ * @{ */
+
+
+/** @brief Get the version of the libiio library
+ * @param major A pointer to an unsigned integer (NULL accepted)
+ * @param minor A pointer to an unsigned integer (NULL accepted)
+ * @param git_tag A pointer to a 8-characters buffer (NULL accepted) */
+__api void iio_library_get_version(unsigned int *major,
+ unsigned int *minor, char git_tag[8]);
+
+
+/** @brief Get a string description of an error code
+ * @param err The error code
+ * @param dst A pointer to the memory area where the NULL-terminated string
+ * corresponding to the error message will be stored
+ * @param len The available length of the memory area, in bytes */
+__api void iio_strerror(int err, char *dst, size_t len);
+
+
+/** @brief Check if the specified backend is available
+ * @param backend The name of the backend to query
+ * @return True if the backend is available, false otherwise
+ *
+ * Introduced in version 0.9. */
+__api __check_ret __cnst bool iio_has_backend(const char *backend);
+
+
+/** @brief Get the number of available backends
+ * @return The number of available backends
+ *
+ * Introduced in version 0.9. */
+__api __check_ret __cnst unsigned int iio_get_backends_count(void);
+
+
+/** @brief Retrieve the name of a given backend
+ * @param index The index corresponding to the attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the index is invalid, NULL is returned
+ *
+ * Introduced in version 0.9. */
+__api __check_ret __cnst const char * iio_get_backend(unsigned int index);
+
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Context functions -------------------------------*/
+/** @defgroup Context Context
+ * @{
+ * @struct iio_context
+ * @brief Contains the representation of an IIO context */
+
+
+/** @brief Create a context from local or remote IIO devices
+ * @return On success, A pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: This function will create a context with the URI
+ * provided in the IIOD_REMOTE environment variable. If not set, a local
+ * context will be created instead. */
+__api __check_ret struct iio_context * iio_create_default_context(void);
+
+
+/** @brief Create a context from local IIO devices (Linux only)
+ * @return On success, A pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately */
+__api __check_ret struct iio_context * iio_create_local_context(void);
+
+
+/** @brief Create a context from a XML file
+ * @param xml_file Path to the XML file to open
+ * @return On success, A pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: The format of the XML must comply to the one returned by
+ * iio_context_get_xml. */
+__api __check_ret struct iio_context * iio_create_xml_context(const char *xml_file);
+
+
+/** @brief Create a context from XML data in memory
+ * @param xml Pointer to the XML data in memory
+ * @param len Length of the XML string in memory (excluding the final \0)
+ * @return On success, A pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: The format of the XML must comply to the one returned by
+ * iio_context_get_xml */
+__api __check_ret struct iio_context * iio_create_xml_context_mem(
+ const char *xml, size_t len);
+
+
+/** @brief Create a context from the network
+ * @param host Hostname, IPv4 or IPv6 address where the IIO Daemon is running
+ * @return On success, a pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately */
+__api __check_ret struct iio_context * iio_create_network_context(const char *host);
+
+
+/** @brief Create a context from a URI description
+ * @param uri A URI describing the context location
+ * @return On success, a pointer to a iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: The following URIs are supported based on compile time backend
+ * support:
+ * - Local backend, "local:"\n
+ * Does not have an address part. For example "local:"
+ * - XML backend, "xml:"\n Requires a path to the XML file for the address part.
+ * For example "xml:/home/user/file.xml"
+ * - Network backend, "ip:"\n Requires a hostname, IPv4, or IPv6 to connect to
+ * a specific running IIO Daemon or no address part for automatic discovery
+ * when library is compiled with ZeroConf support. For example
+ * "ip:192.168.2.1", or "ip:localhost", or "ip:"
+ * or "ip:plutosdr.local". To support alternative port numbers the
+ * standard ip:host:port format is used. A special format is required as
+ * defined in RFC2732 for IPv6 literal hostnames, (adding '[]' around the host)
+ * to use a ip:[x:x:x:x:x:x:x:x]:port format.
+ * Valid examples would be:
+ * - ip: Any host on default port
+ * - ip::40000 Any host on port 40000
+ * - ip:analog.local Default port
+ * - ip:brain.local:40000 Port 40000
+ * - ip:192.168.1.119 Default Port
+ * - ip:192.168.1.119:40000 Port 40000
+ * - ip:2601:190:400:da:47b3:55ab:3914:bff1 Default Port
+ * - ip:[2601:190:400:da:9a90:96ff:feb5:acaa]:40000 Port 40000
+ * - USB backend, "usb:"\n When more than one usb device is attached, requires
+ * bus, address, and interface parts separated with a dot. For example
+ * "usb:3.32.5". Where there is only one USB device attached, the shorthand
+ * "usb:" can be used.
+ * - Serial backend, "serial:"\n Requires:
+ * - a port (/dev/ttyUSB0),
+ * - baud_rate (default 115200)
+ * - serial port configuration
+ * - data bits (5 6 7 8 9)
+ * - parity ('n' none, 'o' odd, 'e' even, 'm' mark, 's' space)
+ * - stop bits (1 2)
+ * - flow control ('\0' none, 'x' Xon Xoff, 'r' RTSCTS, 'd' DTRDSR)
+ *
+ * For example "serial:/dev/ttyUSB0,115200" or "serial:/dev/ttyUSB0,115200,8n1"*/
+__api __check_ret struct iio_context * iio_create_context_from_uri(const char *uri);
+
+
+/** @brief Duplicate a pre-existing IIO context
+ * @param ctx A pointer to an iio_context structure
+ * @return On success, A pointer to an iio_context structure
+ * @return On failure, NULL is returned and errno is set appropriately
+ *
+ * NOTE: This function is not supported on 'usb:' contexts, since libusb
+ * can only claim the interface once. "Function not implemented" is the expected errno.
+ * Any context which is cloned, must be destroyed via calling iio_context_destroy() */
+__api __check_ret struct iio_context * iio_context_clone(const struct iio_context *ctx);
+
+
+/** @brief Destroy the given context
+ * @param ctx A pointer to an iio_context structure
+ *
+ * NOTE: After that function, the iio_context pointer shall be invalid. */
+__api void iio_context_destroy(struct iio_context *ctx);
+
+
+/** @brief Get the version of the backend in use
+ * @param ctx A pointer to an iio_context structure
+ * @param major A pointer to an unsigned integer (NULL accepted)
+ * @param minor A pointer to an unsigned integer (NULL accepted)
+ * @param git_tag A pointer to a 8-characters buffer (NULL accepted)
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_context_get_version(const struct iio_context *ctx,
+ unsigned int *major, unsigned int *minor, char git_tag[8]);
+
+
+/** @brief Obtain a XML representation of the given context
+ * @param ctx A pointer to an iio_context structure
+ * @return A pointer to a static NULL-terminated string */
+__api __check_ret __pure const char * iio_context_get_xml(const struct iio_context *ctx);
+
+
+/** @brief Get the name of the given context
+ * @param ctx A pointer to an iio_context structure
+ * @return A pointer to a static NULL-terminated string
+ *
+ * NOTE:The returned string will be local,
+ * xml or network when the context has been
+ * created with the local, xml and network backends respectively.*/
+__api __check_ret __pure const char * iio_context_get_name(const struct iio_context *ctx);
+
+
+/** @brief Get a description of the given context
+ * @param ctx A pointer to an iio_context structure
+ * @return A pointer to a static NULL-terminated string
+ *
+ * NOTE:The returned string will contain human-readable information about
+ * the current context. */
+__api __check_ret __pure const char * iio_context_get_description(
+ const struct iio_context *ctx);
+
+
+/** @brief Get the number of context-specific attributes
+ * @param ctx A pointer to an iio_context structure
+ * @return The number of context-specific attributes
+ *
+ * Introduced in version 0.9. */
+__api __check_ret __pure unsigned int iio_context_get_attrs_count(
+ const struct iio_context *ctx);
+
+
+/** @brief Retrieve the name and value of a context-specific attribute
+ * @param ctx A pointer to an iio_context structure
+ * @param index The index corresponding to the attribute
+ * @param name A pointer to a const char * pointer (NULL accepted)
+ * @param value A pointer to a const char * pointer (NULL accepted)
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * Introduced in version 0.9. */
+__api __check_ret int iio_context_get_attr(
+ const struct iio_context *ctx, unsigned int index,
+ const char **name, const char **value);
+
+
+/** @brief Retrieve the value of a context-specific attribute
+ * @param ctx A pointer to an iio_context structure
+ * @param name The name of the context attribute to read
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the name does not correspond to any attribute, NULL is
+ * returned
+ *
+ * Introduced in version 0.9. */
+__api __check_ret const char * iio_context_get_attr_value(
+ const struct iio_context *ctx, const char *name);
+
+
+/** @brief Enumerate the devices found in the given context
+ * @param ctx A pointer to an iio_context structure
+ * @return The number of devices found */
+__api __check_ret __pure unsigned int iio_context_get_devices_count(
+ const struct iio_context *ctx);
+
+
+/** @brief Get the device present at the given index
+ * @param ctx A pointer to an iio_context structure
+ * @param index The index corresponding to the device
+ * @return On success, a pointer to an iio_device structure
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure struct iio_device * iio_context_get_device(
+ const struct iio_context *ctx, unsigned int index);
+
+
+/** @brief Try to find a device structure by its ID, label or name
+ * @param ctx A pointer to an iio_context structure
+ * @param name A NULL-terminated string corresponding to the ID, label or name
+ * of the device to search for
+ * @return On success, a pointer to an iio_device structure
+ * @return If the parameter does not correspond to the ID, label or name of
+ * any known device, NULL is returned */
+__api __check_ret __pure struct iio_device * iio_context_find_device(
+ const struct iio_context *ctx, const char *name);
+
+
+/** @brief Set a timeout for I/O operations
+ * @param ctx A pointer to an iio_context structure
+ * @param timeout_ms A positive integer representing the time in milliseconds
+ * after which a timeout occurs. A value of 0 is used to specify that no
+ * timeout should occur.
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_context_set_timeout(
+ struct iio_context *ctx, unsigned int timeout_ms);
+
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Device functions --------------------------------*/
+/** @defgroup Device Device
+ * @{
+ * @struct iio_device
+ * @brief Represents a device in the IIO context */
+
+
+/** @brief Retrieve a pointer to the iio_context structure
+ * @param dev A pointer to an iio_device structure
+ * @return A pointer to an iio_context structure */
+__api __check_ret __pure const struct iio_context * iio_device_get_context(
+ const struct iio_device *dev);
+
+
+/** @brief Retrieve the device ID (e.g. iio:device0)
+ * @param dev A pointer to an iio_device structure
+ * @return A pointer to a static NULL-terminated string */
+__api __check_ret __pure const char * iio_device_get_id(const struct iio_device *dev);
+
+
+/** @brief Retrieve the device name (e.g. xadc)
+ * @param dev A pointer to an iio_device structure
+ * @return A pointer to a static NULL-terminated string
+ *
+ * NOTE: if the device has no name, NULL is returned. */
+__api __check_ret __pure const char * iio_device_get_name(const struct iio_device *dev);
+
+
+/** @brief Retrieve the device label (e.g. lo_pll0_rx_adf4351)
+ * @param dev A pointer to an iio_device structure
+ * @return A pointer to a static NULL-terminated string
+ *
+ * NOTE: if the device has no label, NULL is returned. */
+__api __check_ret __pure const char * iio_device_get_label(const struct iio_device *dev);
+
+
+/** @brief Enumerate the channels of the given device
+ * @param dev A pointer to an iio_device structure
+ * @return The number of channels found */
+__api __check_ret __pure unsigned int iio_device_get_channels_count(
+ const struct iio_device *dev);
+
+
+/** @brief Enumerate the device-specific attributes of the given device
+ * @param dev A pointer to an iio_device structure
+ * @return The number of device-specific attributes found */
+__api __check_ret __pure unsigned int iio_device_get_attrs_count(
+ const struct iio_device *dev);
+
+/** @brief Enumerate the buffer-specific attributes of the given device
+ * @param dev A pointer to an iio_device structure
+ * @return The number of buffer-specific attributes found */
+__api __check_ret __pure unsigned int iio_device_get_buffer_attrs_count(
+ const struct iio_device *dev);
+
+/** @brief Get the channel present at the given index
+ * @param dev A pointer to an iio_device structure
+ * @param index The index corresponding to the channel
+ * @return On success, a pointer to an iio_channel structure
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure struct iio_channel * iio_device_get_channel(
+ const struct iio_device *dev, unsigned int index);
+
+
+/** @brief Get the device-specific attribute present at the given index
+ * @param dev A pointer to an iio_device structure
+ * @param index The index corresponding to the attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure const char * iio_device_get_attr(
+ const struct iio_device *dev, unsigned int index);
+
+/** @brief Get the buffer-specific attribute present at the given index
+ * @param dev A pointer to an iio_device structure
+ * @param index The index corresponding to the attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure const char * iio_device_get_buffer_attr(
+ const struct iio_device *dev, unsigned int index);
+
+/** @brief Try to find a channel structure by its name of ID
+ * @param dev A pointer to an iio_device structure
+ * @param name A NULL-terminated string corresponding to the name or the ID of
+ * the channel to search for
+ * @param output True if the searched channel is output, False otherwise
+ * @return On success, a pointer to an iio_channel structure
+ * @return If the name or ID does not correspond to any known channel of the
+ * given device, NULL is returned */
+__api __check_ret __pure struct iio_channel * iio_device_find_channel(
+ const struct iio_device *dev, const char *name, bool output);
+
+
+/** @brief Try to find a device-specific attribute by its name
+ * @param dev A pointer to an iio_device structure
+ * @param name A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the name does not correspond to any known attribute of the given
+ * device, NULL is returned
+ *
+ * NOTE: This function is useful to detect the presence of an attribute.
+ * It can also be used to retrieve the name of an attribute as a pointer to a
+ * static string from a dynamically allocated string. */
+__api __check_ret __pure const char * iio_device_find_attr(
+ const struct iio_device *dev, const char *name);
+
+/** @brief Try to find a buffer-specific attribute by its name
+ * @param dev A pointer to an iio_device structure
+ * @param name A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the name does not correspond to any known attribute of the given
+ * device, NULL is returned
+ *
+ * NOTE: This function is useful to detect the presence of an attribute.
+ * It can also be used to retrieve the name of an attribute as a pointer to a
+ * static string from a dynamically allocated string. */
+__api __check_ret __pure const char * iio_device_find_buffer_attr(
+ const struct iio_device *dev, const char *name);
+
+/** @brief Read the content of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param dst A pointer to the memory area where the NULL-terminated string
+ * corresponding to the value read will be stored
+ * @param len The available length of the memory area, in bytes
+ * @return On success, the number of bytes written to the buffer
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to iio_device_attr_read,
+ * it is now possible to read all of the attributes of a device.
+ *
+ * The buffer is filled with one block of data per attribute of the device,
+ * by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, it corresponds to the errno code that were
+ * returned when reading the attribute; if positive, it corresponds to the
+ * length of the data read. In that case, the rest of the block contains
+ * the data. */
+__api __check_ret ssize_t iio_device_attr_read(const struct iio_device *dev,
+ const char *attr, char *dst, size_t len);
+
+
+/** @brief Read the content of all device-specific attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the device-specific attributes are read in one single
+ * command. */
+__api __check_ret int iio_device_attr_read_all(struct iio_device *dev,
+ int (*cb)(struct iio_device *dev, const char *attr,
+ const char *value, size_t len, void *d),
+ void *data);
+
+
+/** @brief Read the content of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a bool variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_read_bool(const struct iio_device *dev,
+ const char *attr, bool *val);
+
+
+/** @brief Read the content of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a long long variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_read_longlong(const struct iio_device *dev,
+ const char *attr, long long *val);
+
+
+/** @brief Read the content of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a double variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_read_double(const struct iio_device *dev,
+ const char *attr, double *val);
+
+
+/** @brief Set the value of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A NULL-terminated string to set the attribute to
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to iio_device_attr_write,
+ * it is now possible to write all of the attributes of a device.
+ *
+ * The buffer must contain one block of data per attribute of the device,
+ * by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, the attribute is not written; if positive,
+ * it corresponds to the length of the data to write. In that case, the rest
+ * of the block must contain the data. */
+__api __check_ret ssize_t iio_device_attr_write(const struct iio_device *dev,
+ const char *attr, const char *src);
+
+
+/** @brief Set the value of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A pointer to the data to be written
+ * @param len The number of bytes that should be written
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned */
+__api __check_ret ssize_t iio_device_attr_write_raw(const struct iio_device *dev,
+ const char *attr, const void *src, size_t len);
+
+
+/** @brief Set the values of all device-specific attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the device-specific attributes are written in one single
+ * command. */
+__api __check_ret int 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);
+
+
+/** @brief Set the value of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A bool value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_write_bool(const struct iio_device *dev,
+ const char *attr, bool val);
+
+
+/** @brief Set the value of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A long long value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_write_longlong(const struct iio_device *dev,
+ const char *attr, long long val);
+
+
+/** @brief Set the value of the given device-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A double value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_attr_write_double(const struct iio_device *dev,
+ const char *attr, double val);
+
+/** @brief Read the content of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param dst A pointer to the memory area where the NULL-terminated string
+ * corresponding to the value read will be stored
+ * @param len The available length of the memory area, in bytes
+ * @return On success, the number of bytes written to the buffer
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to
+ * iio_device_buffer_attr_read, it is now possible to read all of the attributes
+ * of a device.
+ *
+ * The buffer is filled with one block of data per attribute of the buffer,
+ * by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, it corresponds to the errno code that were
+ * returned when reading the attribute; if positive, it corresponds to the
+ * length of the data read. In that case, the rest of the block contains
+ * the data. */
+__api __check_ret ssize_t iio_device_buffer_attr_read(const struct iio_device *dev,
+ const char *attr, char *dst, size_t len);
+
+/** @brief Read the content of all buffer-specific attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the buffer-specific attributes are read in one single
+ * command. */
+__api __check_ret int iio_device_buffer_attr_read_all(struct iio_device *dev,
+ int (*cb)(struct iio_device *dev, const char *attr,
+ const char *value, size_t len, void *d),
+ void *data);
+
+
+/** @brief Read the content of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a bool variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_read_bool(const struct iio_device *dev,
+ const char *attr, bool *val);
+
+
+/** @brief Read the content of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a long long variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_read_longlong(const struct iio_device *dev,
+ const char *attr, long long *val);
+
+
+/** @brief Read the content of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a double variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_read_double(const struct iio_device *dev,
+ const char *attr, double *val);
+
+
+/** @brief Set the value of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A NULL-terminated string to set the attribute to
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to
+ * iio_device_buffer_attr_write, it is now possible to write all of the
+ * attributes of a device.
+ *
+ * The buffer must contain one block of data per attribute of the buffer,
+ * by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, the attribute is not written; if positive,
+ * it corresponds to the length of the data to write. In that case, the rest
+ * of the block must contain the data. */
+__api __check_ret ssize_t iio_device_buffer_attr_write(const struct iio_device *dev,
+ const char *attr, const char *src);
+
+
+/** @brief Set the value of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A pointer to the data to be written
+ * @param len The number of bytes that should be written
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned */
+__api __check_ret ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev,
+ const char *attr, const void *src, size_t len);
+
+
+/** @brief Set the values of all buffer-specific attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the buffer-specific attributes are written in one single
+ * command. */
+__api __check_ret int 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);
+
+
+/** @brief Set the value of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A bool value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_write_bool(const struct iio_device *dev,
+ const char *attr, bool val);
+
+
+/** @brief Set the value of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A long long value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_write_longlong(const struct iio_device *dev,
+ const char *attr, long long val);
+
+
+/** @brief Set the value of the given buffer-specific attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A double value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_buffer_attr_write_double(const struct iio_device *dev,
+ const char *attr, double val);
+
+
+/** @brief Associate a pointer to an iio_device structure
+ * @param dev A pointer to an iio_device structure
+ * @param data The pointer to be associated */
+__api void iio_device_set_data(struct iio_device *dev, void *data);
+
+
+/** @brief Retrieve a previously associated pointer of an iio_device structure
+ * @param dev A pointer to an iio_device structure
+ * @return The pointer previously associated if present, or NULL */
+__api void * iio_device_get_data(const struct iio_device *dev);
+
+
+/** @brief Retrieve the trigger of a given device
+ * @param dev A pointer to an iio_device structure
+ * @param trigger a pointer to a pointer of an iio_device structure. The pointed
+ * pointer will be set to the address of the iio_device structure corresponding
+ * to the associated trigger device.
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_get_trigger(const struct iio_device *dev,
+ const struct iio_device **trigger);
+
+
+/** @brief Associate a trigger to a given device
+ * @param dev A pointer to an iio_device structure
+ * @param trigger a pointer to the iio_device structure corresponding to the
+ * trigger that should be associated.
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_set_trigger(const struct iio_device *dev,
+ const struct iio_device *trigger);
+
+
+/** @brief Return True if the given device is a trigger
+ * @param dev A pointer to an iio_device structure
+ * @return True if the device is a trigger, False otherwise */
+__api __check_ret __pure bool iio_device_is_trigger(const struct iio_device *dev);
+
+/** @brief Configure the number of kernel buffers for a device
+ *
+ * This function allows to change the number of buffers on kernel side.
+ * @param dev A pointer to an iio_device structure
+ * @param nb_buffers The number of buffers
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_set_kernel_buffers_count(const struct iio_device *dev,
+ unsigned int nb_buffers);
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Channel functions -------------------------------*/
+/** @defgroup Channel Channel
+ * @{
+ * @struct iio_channel
+ * @brief Represents an input or output channel of a device */
+
+
+/** @brief Retrieve a pointer to the iio_device structure
+ * @param chn A pointer to an iio_channel structure
+ * @return A pointer to an iio_device structure */
+__api __check_ret __pure const struct iio_device * iio_channel_get_device(
+ const struct iio_channel *chn);
+
+
+/** @brief Retrieve the channel ID (e.g. voltage0)
+ * @param chn A pointer to an iio_channel structure
+ * @return A pointer to a static NULL-terminated string */
+__api __check_ret __pure const char * iio_channel_get_id(const struct iio_channel *chn);
+
+
+/** @brief Retrieve the channel name (e.g. vccint)
+ * @param chn A pointer to an iio_channel structure
+ * @return A pointer to a static NULL-terminated string
+ *
+ * NOTE: if the channel has no name, NULL is returned. */
+__api __check_ret __pure const char * iio_channel_get_name(const struct iio_channel *chn);
+
+
+/** @brief Return True if the given channel is an output channel
+ * @param chn A pointer to an iio_channel structure
+ * @return True if the channel is an output channel, False otherwise */
+__api __check_ret __pure bool iio_channel_is_output(const struct iio_channel *chn);
+
+
+/** @brief Return True if the given channel is a scan element
+ * @param chn A pointer to an iio_channel structure
+ * @return True if the channel is a scan element, False otherwise
+ *
+ * NOTE: a channel that is a scan element is a channel that can
+ * generate samples (for an input channel) or receive samples (for an output
+ * channel) after being enabled. */
+__api __check_ret __pure bool iio_channel_is_scan_element(const struct iio_channel *chn);
+
+
+/** @brief Enumerate the channel-specific attributes of the given channel
+ * @param chn A pointer to an iio_channel structure
+ * @return The number of channel-specific attributes found */
+__api __check_ret __pure unsigned int iio_channel_get_attrs_count(
+ const struct iio_channel *chn);
+
+
+/** @brief Get the channel-specific attribute present at the given index
+ * @param chn A pointer to an iio_channel structure
+ * @param index The index corresponding to the attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure const char * iio_channel_get_attr(
+ const struct iio_channel *chn, unsigned int index);
+
+
+/** @brief Try to find a channel-specific attribute by its name
+ * @param chn A pointer to an iio_channel structure
+ * @param name A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the name does not correspond to any known attribute of the given
+ * channel, NULL is returned
+ *
+ * NOTE: This function is useful to detect the presence of an attribute.
+ * It can also be used to retrieve the name of an attribute as a pointer to a
+ * static string from a dynamically allocated string. */
+__api __check_ret __pure const char * iio_channel_find_attr(
+ const struct iio_channel *chn, const char *name);
+
+
+/** @brief Retrieve the filename of an attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr a NULL-terminated string corresponding to the name of the
+ * attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the attribute name is unknown, NULL is returned */
+__api __check_ret __pure const char * iio_channel_attr_get_filename(
+ const struct iio_channel *chn, const char *attr);
+
+
+/** @brief Read the content of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param dst A pointer to the memory area where the NULL-terminated string
+ * corresponding to the value read will be stored
+ * @param len The available length of the memory area, in bytes
+ * @return On success, the number of bytes written to the buffer
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to iio_channel_attr_read,
+ * it is now possible to read all of the attributes of a channel.
+ *
+ * The buffer is filled with one block of data per attribute of the channel,
+ * by the order they appear in the iio_channel structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, it corresponds to the errno code that were
+ * returned when reading the attribute; if positive, it corresponds to the
+ * length of the data read. In that case, the rest of the block contains
+ * the data. */
+__api __check_ret ssize_t iio_channel_attr_read(const struct iio_channel *chn,
+ const char *attr, char *dst, size_t len);
+
+
+/** @brief Read the content of all channel-specific attributes
+ * @param chn A pointer to an iio_channel structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the channel-specific attributes are read in one single
+ * command. */
+__api __check_ret int iio_channel_attr_read_all(struct iio_channel *chn,
+ int (*cb)(struct iio_channel *chn,
+ const char *attr, const char *val, size_t len, void *d),
+ void *data);
+
+
+/** @brief Read the content of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a bool variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_read_bool(const struct iio_channel *chn,
+ const char *attr, bool *val);
+
+
+/** @brief Read the content of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a long long variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_read_longlong(const struct iio_channel *chn,
+ const char *attr, long long *val);
+
+
+/** @brief Read the content of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A pointer to a double variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_read_double(const struct iio_channel *chn,
+ const char *attr, double *val);
+
+
+/** @brief Set the value of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A NULL-terminated string to set the attribute to
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to iio_channel_attr_write,
+ * it is now possible to write all of the attributes of a channel.
+ *
+ * The buffer must contain one block of data per attribute of the channel,
+ * by the order they appear in the iio_channel structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, the attribute is not written; if positive,
+ * it corresponds to the length of the data to write. In that case, the rest
+ * of the block must contain the data. */
+__api __check_ret ssize_t iio_channel_attr_write(const struct iio_channel *chn,
+ const char *attr, const char *src);
+
+
+/** @brief Set the value of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param src A pointer to the data to be written
+ * @param len The number of bytes that should be written
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned */
+__api __check_ret ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn,
+ const char *attr, const void *src, size_t len);
+
+
+/** @brief Set the values of all channel-specific attributes
+ * @param chn A pointer to an iio_channel structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the channel-specific attributes are written in one single
+ * command. */
+__api __check_ret int iio_channel_attr_write_all(struct iio_channel *chn,
+ ssize_t (*cb)(struct iio_channel *chn,
+ const char *attr, void *buf, size_t len, void *d),
+ void *data);
+
+
+/** @brief Set the value of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A bool value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_write_bool(const struct iio_channel *chn,
+ const char *attr, bool val);
+
+
+/** @brief Set the value of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A long long value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_write_longlong(const struct iio_channel *chn,
+ const char *attr, long long val);
+
+
+/** @brief Set the value of the given channel-specific attribute
+ * @param chn A pointer to an iio_channel structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * attribute
+ * @param val A double value to set the attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_channel_attr_write_double(const struct iio_channel *chn,
+ const char *attr, double val);
+
+
+/** @brief Enable the given channel
+ * @param chn A pointer to an iio_channel structure
+ *
+ * NOTE:Before creating an iio_buffer structure with
+ * iio_device_create_buffer, it is required to enable at least one channel of
+ * the device to read from. */
+__api void iio_channel_enable(struct iio_channel *chn);
+
+
+/** @brief Disable the given channel
+ * @param chn A pointer to an iio_channel structure */
+__api void iio_channel_disable(struct iio_channel *chn);
+
+
+/** @brief Returns True if the channel is enabled
+ * @param chn A pointer to an iio_channel structure
+ * @return True if the channel is enabled, False otherwise */
+__api __check_ret bool iio_channel_is_enabled(const struct iio_channel *chn);
+
+
+/** @brief Demultiplex the samples of a given channel
+ * @param chn A pointer to an iio_channel structure
+ * @param buffer A pointer to an iio_buffer structure
+ * @param dst A pointer to the memory area where the demultiplexed data will be
+ * stored
+ * @param len The available length of the memory area, in bytes
+ * @return The size of the demultiplexed data, in bytes */
+__api __check_ret size_t iio_channel_read_raw(const struct iio_channel *chn,
+ struct iio_buffer *buffer, void *dst, size_t len);
+
+
+/** @brief Demultiplex and convert the samples of a given channel
+ * @param chn A pointer to an iio_channel structure
+ * @param buffer A pointer to an iio_buffer structure
+ * @param dst A pointer to the memory area where the converted data will be
+ * stored
+ * @param len The available length of the memory area, in bytes
+ * @return The size of the converted data, in bytes */
+__api __check_ret size_t iio_channel_read(const struct iio_channel *chn,
+ struct iio_buffer *buffer, void *dst, size_t len);
+
+
+/** @brief Multiplex the samples of a given channel
+ * @param chn A pointer to an iio_channel structure
+ * @param buffer A pointer to an iio_buffer structure
+ * @param src A pointer to the memory area where the sequential data will
+ * be read from
+ * @param len The length of the memory area, in bytes
+ * @return The number of bytes actually multiplexed */
+__api __check_ret size_t iio_channel_write_raw(const struct iio_channel *chn,
+ struct iio_buffer *buffer, const void *src, size_t len);
+
+
+/** @brief Convert and multiplex the samples of a given channel
+ * @param chn A pointer to an iio_channel structure
+ * @param buffer A pointer to an iio_buffer structure
+ * @param src A pointer to the memory area where the sequential data will
+ * be read from
+ * @param len The length of the memory area, in bytes
+ * @return The number of bytes actually converted and multiplexed */
+__api __check_ret size_t iio_channel_write(const struct iio_channel *chn,
+ struct iio_buffer *buffer, const void *src, size_t len);
+
+
+/** @brief Associate a pointer to an iio_channel structure
+ * @param chn A pointer to an iio_channel structure
+ * @param data The pointer to be associated */
+__api void iio_channel_set_data(struct iio_channel *chn, void *data);
+
+
+/** @brief Retrieve a previously associated pointer of an iio_channel structure
+ * @param chn A pointer to an iio_channel structure
+ * @return The pointer previously associated if present, or NULL */
+__api void * iio_channel_get_data(const struct iio_channel *chn);
+
+
+/** @brief Get the type of the given channel
+ * @param chn A pointer to an iio_channel structure
+ * @return The type of the channel */
+__api __check_ret __pure enum iio_chan_type iio_channel_get_type(
+ const struct iio_channel *chn);
+
+
+/** @brief Get the modifier type of the given channel
+ * @param chn A pointer to an iio_channel structure
+ * @return The modifier type of the channel */
+__api __check_ret __pure enum iio_modifier iio_channel_get_modifier(
+ const struct iio_channel *chn);
+
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Buffer functions --------------------------------*/
+/** @defgroup Buffer Buffer
+ * @{
+ * @struct iio_buffer
+ * @brief An input or output buffer, used to read or write samples */
+
+
+/** @brief Retrieve a pointer to the iio_device structure
+ * @param buf A pointer to an iio_buffer structure
+ * @return A pointer to an iio_device structure */
+__api __check_ret __pure const struct iio_device * iio_buffer_get_device(
+ const struct iio_buffer *buf);
+
+
+/** @brief Create an input or output buffer associated to the given device
+ * @param dev A pointer to an iio_device structure
+ * @param samples_count The number of samples that the buffer should contain
+ * @param cyclic If True, enable cyclic mode
+ * @return On success, a pointer to an iio_buffer structure
+ * @return On error, NULL is returned, and errno is set to the error code
+ *
+ * NOTE: Channels that have to be written to / read from must be enabled
+ * before creating the buffer. */
+__api __check_ret struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev,
+ size_t samples_count, bool cyclic);
+
+
+/** @brief Destroy the given buffer
+ * @param buf A pointer to an iio_buffer structure
+ *
+ * NOTE: After that function, the iio_buffer pointer shall be invalid. */
+__api void iio_buffer_destroy(struct iio_buffer *buf);
+
+/** @brief Get a pollable file descriptor
+ *
+ * Can be used to know when iio_buffer_refill() or iio_buffer_push() can be
+ * called
+ * @param buf A pointer to an iio_buffer structure
+ * @return On success, valid file descriptor
+ * @return On error, a negative errno code is returned
+ */
+__api __check_ret int iio_buffer_get_poll_fd(struct iio_buffer *buf);
+
+/** @brief Make iio_buffer_refill() and iio_buffer_push() blocking or not
+ *
+ * After this function has been called with blocking == false,
+ * iio_buffer_refill() and iio_buffer_push() will return -EAGAIN if no data is
+ * ready.
+ * A device is blocking by default.
+ * @param buf A pointer to an iio_buffer structure
+ * @param blocking true if the buffer API should be blocking, else false
+ * @return On success, 0
+ * @return On error, a negative errno code is returned
+ */
+__api __check_ret int iio_buffer_set_blocking_mode(struct iio_buffer *buf, bool blocking);
+
+
+/** @brief Fetch more samples from the hardware
+ * @param buf A pointer to an iio_buffer structure
+ * @return On success, the number of bytes read is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: Only valid for input buffers */
+__api __check_ret ssize_t iio_buffer_refill(struct iio_buffer *buf);
+
+
+/** @brief Send the samples to the hardware
+ * @param buf A pointer to an iio_buffer structure
+ * @return On success, the number of bytes written is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: Only valid for output buffers */
+__api __check_ret ssize_t iio_buffer_push(struct iio_buffer *buf);
+
+
+/** @brief Send a given number of samples to the hardware
+ * @param buf A pointer to an iio_buffer structure
+ * @param samples_count The number of samples to submit
+ * @return On success, the number of bytes written is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: Only valid for output buffers */
+__api __check_ret ssize_t iio_buffer_push_partial(struct iio_buffer *buf,
+ size_t samples_count);
+
+/** @brief Cancel all buffer operations
+ * @param buf The buffer for which operations should be canceled
+ *
+ * This function cancels all outstanding buffer operations previously scheduled.
+ * This means any pending iio_buffer_push() or iio_buffer_refill() operation
+ * will abort and return immediately, any further invocations of these functions
+ * on the same buffer will return immediately with an error.
+ *
+ * Usually iio_buffer_push() and iio_buffer_refill() will block until either all
+ * data has been transferred or a timeout occurs. This can depending on the
+ * configuration take a significant amount of time. iio_buffer_cancel() is
+ * useful to bypass these conditions if the buffer operation is supposed to be
+ * stopped in response to an external event (e.g. user input).
+ *
+ * To be able to capture additional data after calling this function the buffer
+ * should be destroyed and then re-created.
+ *
+ * This function can be called multiple times for the same buffer, but all but
+ * the first invocation will be without additional effect.
+ *
+ * This function is thread-safe, but not signal-safe, i.e. it must not be called
+ * from a signal handler.
+ */
+__api void iio_buffer_cancel(struct iio_buffer *buf);
+
+
+/** @brief Get the start address of the buffer
+ * @param buf A pointer to an iio_buffer structure
+ * @return A pointer corresponding to the start address of the buffer */
+__api void * iio_buffer_start(const struct iio_buffer *buf);
+
+
+/** @brief Find the first sample of a channel in a buffer
+ * @param buf A pointer to an iio_buffer structure
+ * @param chn A pointer to an iio_channel structure
+ * @return A pointer to the first sample found, or to the end of the buffer if
+ * no sample for the given channel is present in the buffer
+ *
+ * NOTE: This function, coupled with iio_buffer_step and iio_buffer_end,
+ * can be used to iterate on all the samples of a given channel present in the
+ * buffer, doing the following:
+ *
+ * @verbatim
+ for (void *ptr = iio_buffer_first(buffer, chn); ptr < iio_buffer_end(buffer); ptr += iio_buffer_step(buffer)) {
+ ....
+ }
+ @endverbatim */
+__api void * iio_buffer_first(const struct iio_buffer *buf,
+ const struct iio_channel *chn);
+
+
+/** @brief Get the step size between two samples of one channel
+ * @param buf A pointer to an iio_buffer structure
+ * @return the difference between the addresses of two consecutive samples of
+ * one same channel */
+__api __check_ret ptrdiff_t iio_buffer_step(const struct iio_buffer *buf);
+
+
+/** @brief Get the address that follows the last sample in a buffer
+ * @param buf A pointer to an iio_buffer structure
+ * @return A pointer corresponding to the address that follows the last sample
+ * present in the buffer */
+__api void * iio_buffer_end(const struct iio_buffer *buf);
+
+
+/** @brief Call the supplied callback for each sample found in a buffer
+ * @param buf A pointer to an iio_buffer structure
+ * @param callback A pointer to a function to call for each sample found
+ * @param data A user-specified pointer that will be passed to the callback
+ * @return number of bytes processed.
+ *
+ * NOTE: The callback receives four arguments:
+ * * A pointer to the iio_channel structure corresponding to the sample,
+ * * A pointer to the sample itself,
+ * * The length of the sample in bytes,
+ * * The user-specified pointer passed to iio_buffer_foreach_sample. */
+__api __check_ret ssize_t iio_buffer_foreach_sample(struct iio_buffer *buf,
+ ssize_t (*callback)(const struct iio_channel *chn,
+ void *src, size_t bytes, void *d), void *data);
+
+
+/** @brief Associate a pointer to an iio_buffer structure
+ * @param buf A pointer to an iio_buffer structure
+ * @param data The pointer to be associated */
+__api void iio_buffer_set_data(struct iio_buffer *buf, void *data);
+
+
+/** @brief Retrieve a previously associated pointer of an iio_buffer structure
+ * @param buf A pointer to an iio_buffer structure
+ * @return The pointer previously associated if present, or NULL */
+__api void * iio_buffer_get_data(const struct iio_buffer *buf);
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ---------------------------- HWMON support --------------------------------*/
+/** @defgroup Hwmon Compatibility with hardware monitoring (hwmon) devices
+ * @{
+ * @enum hwmon_chan_type
+ * @brief Hwmon channel type
+ *
+ * Libiio support hardware-monitoring (hwmon) devices as well. This enum
+ * specifies the type of data associated with the hwmon channel.
+ *
+ * NOTE: as of 2021 only the current hwmon API is supported. The old
+ * and deprecated APIs are not supported, and won't be supported unless we
+ * have a case where updating a hwmon driver is not possible.
+ */
+enum hwmon_chan_type {
+ HWMON_VOLTAGE,
+ HWMON_FAN,
+ HWMON_PWM,
+ HWMON_TEMP,
+ HWMON_CURRENT,
+ HWMON_POWER,
+ HWMON_ENERGY,
+ HWMON_HUMIDITY,
+ HWMON_INTRUSION,
+ HWMON_CHAN_TYPE_UNKNOWN = IIO_CHAN_TYPE_UNKNOWN,
+};
+
+/**
+ * @brief Get the type of the given hwmon channel
+ * @param chn A pointer to an iio_channel structure
+ * @return The type of the hwmon channel */
+static inline enum hwmon_chan_type
+hwmon_channel_get_type(const struct iio_channel *chn)
+{
+ return (enum hwmon_chan_type) iio_channel_get_type(chn);
+}
+
+/**
+ * @brief Get whether or not the device is a hardware monitoring device
+ * @param dev A pointer to an iio_device structure
+ * @return True if the device is a hardware monitoring device,
+ * false if it is a IIO device */
+static inline bool iio_device_is_hwmon(const struct iio_device *dev)
+{
+ const char *id = iio_device_get_id(dev);
+
+ return id[0] == 'h';
+}
+
+
+/** @} *//* ------------------------------------------------------------------*/
+/* ------------------------- Low-level functions -----------------------------*/
+/** @defgroup Debug Debug and low-level functions
+ * @{
+ * @struct iio_data_format
+ * @brief Contains the format of a data sample.
+ *
+ * The different fields inform about the correct way to convert one sample from
+ * its raw format (as read from / generated by the hardware) to its real-world
+ * value.
+ */
+struct iio_data_format {
+ /** @brief Total length of the sample, in bits */
+ unsigned int length;
+
+ /** @brief Length of valuable data in the sample, in bits */
+ unsigned int bits;
+
+ /** @brief Right-shift to apply when converting sample */
+ unsigned int shift;
+
+ /** @brief Contains True if the sample is signed */
+ bool is_signed;
+
+ /** @brief Contains True if the sample is fully defined, sign extended, etc. */
+ bool is_fully_defined;
+
+ /** @brief Contains True if the sample is in big-endian format */
+ bool is_be;
+
+ /** @brief Contains True if the sample should be scaled when converted */
+ bool with_scale;
+
+ /** @brief Contains the scale to apply if with_scale is set */
+ double scale;
+
+ /** @brief Number of times length repeats (added in v0.8) */
+ unsigned int repeat;
+};
+
+
+/** @brief Get the current sample size
+ * @param dev A pointer to an iio_device structure
+ * @return On success, the sample size in bytes
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: The sample size is not constant and will change when channels
+ * get enabled or disabled. */
+__api __check_ret ssize_t iio_device_get_sample_size(const struct iio_device *dev);
+
+
+/** @brief Get the index of the given channel
+ * @param chn A pointer to an iio_channel structure
+ * @return On success, the index of the specified channel
+ * @return On error, a negative errno code is returned */
+__api __check_ret __pure long iio_channel_get_index(const struct iio_channel *chn);
+
+
+/** @brief Get a pointer to a channel's data format structure
+ * @param chn A pointer to an iio_channel structure
+ * @return A pointer to the channel's iio_data_format structure */
+__api __check_ret __cnst const struct iio_data_format * iio_channel_get_data_format(
+ const struct iio_channel *chn);
+
+
+/** @brief Convert the sample from hardware format to host format
+ * @param chn A pointer to an iio_channel structure
+ * @param dst A pointer to the destination buffer where the converted sample
+ * should be written
+ * @param src A pointer to the source buffer containing the sample */
+__api void iio_channel_convert(const struct iio_channel *chn,
+ void *dst, const void *src);
+
+
+/** @brief Convert the sample from host format to hardware format
+ * @param chn A pointer to an iio_channel structure
+ * @param dst A pointer to the destination buffer where the converted sample
+ * should be written
+ * @param src A pointer to the source buffer containing the sample */
+__api void iio_channel_convert_inverse(const struct iio_channel *chn,
+ void *dst, const void *src);
+
+
+/** @brief Enumerate the debug attributes of the given device
+ * @param dev A pointer to an iio_device structure
+ * @return The number of debug attributes found */
+__api __check_ret __pure unsigned int iio_device_get_debug_attrs_count(
+ const struct iio_device *dev);
+
+
+/** @brief Get the debug attribute present at the given index
+ * @param dev A pointer to an iio_device structure
+ * @param index The index corresponding to the debug attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the index is invalid, NULL is returned */
+__api __check_ret __pure const char * iio_device_get_debug_attr(
+ const struct iio_device *dev, unsigned int index);
+
+
+/** @brief Try to find a debug attribute by its name
+ * @param dev A pointer to an iio_device structure
+ * @param name A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @return On success, a pointer to a static NULL-terminated string
+ * @return If the name does not correspond to any known debug attribute of the
+ * given device, NULL is returned
+ *
+ * NOTE: This function is useful to detect the presence of a debug
+ * attribute.
+ * It can also be used to retrieve the name of a debug attribute as a pointer
+ * to a static string from a dynamically allocated string. */
+__api __check_ret __pure const char * iio_device_find_debug_attr(
+ const struct iio_device *dev, const char *name);
+
+
+/** @brief Read the content of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param dst A pointer to the memory area where the NULL-terminated string
+ * corresponding to the value read will be stored
+ * @param len The available length of the memory area, in bytes
+ * @return On success, the number of bytes written to the buffer
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to
+ * iio_device_debug_attr_read, it is now possible to read all of the debug
+ * attributes of a device.
+ *
+ * The buffer is filled with one block of data per debug attribute of the
+ * device, by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, it corresponds to the errno code that were
+ * returned when reading the debug attribute; if positive, it corresponds
+ * to the length of the data read. In that case, the rest of the block contains
+ * the data. */
+__api __check_ret ssize_t iio_device_debug_attr_read(const struct iio_device *dev,
+ const char *attr, char *dst, size_t len);
+
+
+/** @brief Read the content of all debug attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the debug attributes are read in one single command. */
+__api __check_ret int iio_device_debug_attr_read_all(struct iio_device *dev,
+ int (*cb)(struct iio_device *dev, const char *attr,
+ const char *value, size_t len, void *d),
+ void *data);
+
+
+/** @brief Set the value of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param src A NULL-terminated string to set the debug attribute to
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE:By passing NULL as the "attr" argument to
+ * iio_device_debug_attr_write, it is now possible to write all of the
+ * debug attributes of a device.
+ *
+ * The buffer must contain one block of data per debug attribute of the device,
+ * by the order they appear in the iio_device structure.
+ *
+ * The first four bytes of one block correspond to a 32-bit signed value in
+ * network order. If negative, the debug attribute is not written; if positive,
+ * it corresponds to the length of the data to write. In that case, the rest
+ * of the block must contain the data. */
+__api __check_ret ssize_t iio_device_debug_attr_write(const struct iio_device *dev,
+ const char *attr, const char *src);
+
+
+/** @brief Set the value of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param src A pointer to the data to be written
+ * @param len The number of bytes that should be written
+ * @return On success, the number of bytes written
+ * @return On error, a negative errno code is returned */
+__api __check_ret ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev,
+ const char *attr, const void *src, size_t len);
+
+
+/** @brief Set the values of all debug attributes
+ * @param dev A pointer to an iio_device structure
+ * @param cb A pointer to a callback function
+ * @param data A pointer that will be passed to the callback function
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned
+ *
+ * NOTE: This function is especially useful when used with the network
+ * backend, as all the debug attributes are written in one single command. */
+__api __check_ret int 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);
+
+
+/** @brief Read the content of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A pointer to a bool variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_read_bool(const struct iio_device *dev,
+ const char *attr, bool *val);
+
+
+/** @brief Read the content of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A pointer to a long long variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_read_longlong(const struct iio_device *dev,
+ const char *attr, long long *val);
+
+
+/** @brief Read the content of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A pointer to a double variable where the value should be stored
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_read_double(const struct iio_device *dev,
+ const char *attr, double *val);
+
+
+/** @brief Set the value of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A bool value to set the debug attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_write_bool(const struct iio_device *dev,
+ const char *attr, bool val);
+
+
+/** @brief Set the value of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A long long value to set the debug attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_write_longlong(const struct iio_device *dev,
+ const char *attr, long long val);
+
+
+/** @brief Set the value of the given debug attribute
+ * @param dev A pointer to an iio_device structure
+ * @param attr A NULL-terminated string corresponding to the name of the
+ * debug attribute
+ * @param val A double value to set the debug attribute to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_debug_attr_write_double(const struct iio_device *dev,
+ const char *attr, double val);
+
+
+/** @brief Identify the channel or debug attribute corresponding to a filename
+ * @param dev A pointer to an iio_device structure
+ * @param filename A NULL-terminated string corresponding to the filename
+ * @param chn A pointer to a pointer of an iio_channel structure. The pointed
+ * pointer will be set to the address of the iio_channel structure if the
+ * filename correspond to the attribute of a channel, or NULL otherwise.
+ * @param attr A pointer to a NULL-terminated string. The pointer
+ * pointer will be set to point to the name of the attribute corresponding to
+ * the filename.
+ * @return On success, 0 is returned, and *chn and *attr are modified.
+ * @return On error, a negative errno code is returned. *chn and *attr are not
+ * modified. */
+__api __check_ret int iio_device_identify_filename(const struct iio_device *dev,
+ const char *filename, struct iio_channel **chn,
+ const char **attr);
+
+
+/** @brief Set the value of a hardware register
+ * @param dev A pointer to an iio_device structure
+ * @param address The address of the register
+ * @param value The value to set the register to
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_reg_write(struct iio_device *dev,
+ uint32_t address, uint32_t value);
+
+
+/** @brief Get the value of a hardware register
+ * @param dev A pointer to an iio_device structure
+ * @param address The address of the register
+ * @param value A pointer to the variable where the value will be written
+ * @return On success, 0 is returned
+ * @return On error, a negative errno code is returned */
+__api __check_ret int iio_device_reg_read(struct iio_device *dev,
+ uint32_t address, uint32_t *value);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef __api
+
+#endif /* __IIO_H__ */
diff --git a/player/plutoplayer_win/plutoplayer.c b/player/plutoplayer_win/plutoplayer.c
new file mode 100644
index 0000000..b16b608
--- /dev/null
+++ b/player/plutoplayer_win/plutoplayer.c
@@ -0,0 +1,254 @@
+#define _CRT_SECURE_NO_WARNINGS
+
+#include
+#include
+#ifdef _WIN32
+#include "getopt.h"
+#include "ad9361.h"
+#include "iio.h"
+#else
+#include
+#include
+#include
+#endif
+#include
+#include
+#include
+
+#define NOTUSED(V) ((void) V)
+#define MHZ(x) ((long long)(x*1000000.0 + .5))
+#define GHZ(x) ((long long)(x*1000000000.0 + .5))
+#define NUM_SAMPLES 2600000
+#define BUFFER_SIZE (NUM_SAMPLES * 2 * sizeof(int16_t))
+
+
+struct stream_cfg {
+ long long bw_hz; // Analog banwidth in Hz
+ long long fs_hz; // Baseband sample rate in Hz
+ long long lo_hz; // Local oscillator frequency in Hz
+ const char* rfport; // Port name
+ double gain_db; // Hardware gain
+};
+
+static void usage() {
+ fprintf(stderr, "Usage: plutoplayer [options]\n"
+ " -t Transmit data from file (required)\n"
+ " -a Set TX attenuation [dB] (default -20.0)\n"
+ " -b Set RF bandwidth [MHz] (default 5.0)\n"
+ " -u ADALM-Pluto URI\n"
+ " -n ADALM-Pluto network IP or hostname (default pluto.local)\n");
+ return;
+}
+
+static bool stop = false;
+
+static void handle_sig(int sig)
+{
+ NOTUSED(sig);
+ stop = true;
+}
+
+static char* readable_fs(double size, char* buf, size_t buf_size) {
+ int i = 0;
+ const char* units[] = { "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
+ while (size > 1024) {
+ size /= 1024;
+ i++;
+ }
+ snprintf(buf, buf_size, "%.*f %s", i, size, units[i]);
+ return buf;
+}
+
+/*
+ *
+ */
+int main(int argc, char** argv) {
+ char buf[1024];
+ int opt;
+ const char* path = NULL;
+ struct stream_cfg txcfg;
+ FILE* fp = NULL;
+ const char* uri = NULL;
+ const char* ip = NULL;
+
+ // TX stream default config
+ txcfg.bw_hz = MHZ(3.0); // 3.0 MHz RF bandwidth
+ txcfg.fs_hz = MHZ(2.6); // 2.6 MS/s TX sample rate
+ txcfg.lo_hz = GHZ(1.575420); // 1.57542 GHz RF frequency
+ txcfg.rfport = "A";
+ txcfg.gain_db = -20.0;
+
+ struct iio_context* ctx = NULL;
+ struct iio_device* tx = NULL;
+ struct iio_device* phydev = NULL;
+ struct iio_channel* tx0_i = NULL;
+ struct iio_channel* tx0_q = NULL;
+ struct iio_buffer* tx_buffer = NULL;
+
+ while ((opt = getopt(argc, argv, "t:a:b:n:u:")) != EOF) {
+ switch (opt) {
+ case 't':
+ path = optarg;
+ break;
+ case 'a':
+ txcfg.gain_db = atof(optarg);
+ if (txcfg.gain_db > 0.0) txcfg.gain_db = 0.0;
+ if (txcfg.gain_db < -80.0) txcfg.gain_db = -80.0;
+ break;
+ case 'b':
+ txcfg.bw_hz = MHZ(atof(optarg));
+ if (txcfg.bw_hz > MHZ(5.0)) txcfg.bw_hz = MHZ(5.0);
+ if (txcfg.bw_hz < MHZ(1.0)) txcfg.bw_hz = MHZ(1.0);
+ break;
+ case 'u':
+ uri = optarg;
+ break;
+ case 'n':
+ ip = optarg;
+ break;
+ default:
+ printf("Unknown argument '-%c %s'\n", opt, optarg);
+ usage();
+ return EXIT_FAILURE;
+ }
+ }
+
+ //signal(SIGINT, handle_sig);
+
+ if (path == NULL) {
+ printf("Specify a path to a file to transmit\n");
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ fp = fopen(path, "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "ERROR: Failed to open TX file: %s\n", path);
+ return EXIT_FAILURE;
+ }
+ fseek(fp, 0L, SEEK_END);
+ size_t sz = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+ readable_fs((double)sz, buf, sizeof(buf));
+ printf("* Transmit file size: %s\n", buf);
+
+ printf("* Acquiring IIO context\n");
+ ctx = iio_create_default_context();
+ if (ctx == NULL) {
+ if (ip != NULL) {
+ ctx = iio_create_network_context(ip);
+ }
+ else if (uri != NULL) {
+ ctx = iio_create_context_from_uri(uri);
+ }
+ else {
+ ctx = iio_create_network_context("pluto.local");
+ }
+ }
+
+ if (ctx == NULL) {
+ iio_strerror(errno, buf, sizeof(buf));
+ fprintf(stderr, "Failed creating IIO context: %s\n", buf);
+ return false;
+ }
+
+ struct iio_scan_context* scan_ctx;
+ struct iio_context_info** info;
+ scan_ctx = iio_create_scan_context(NULL, 0);
+ if (scan_ctx) {
+ int info_count = iio_scan_context_get_info_list(scan_ctx, &info);
+ if (info_count > 0) {
+ printf("* Found %s\n", iio_context_info_get_description(info[0]));
+ iio_context_info_list_free(info);
+ }
+ iio_scan_context_destroy(scan_ctx);
+ }
+
+ printf("* Acquiring devices\n");
+ int device_count = iio_context_get_devices_count(ctx);
+ if (!device_count) {
+ fprintf(stderr, "No supported PLUTOSDR devices found.\n");
+ goto error_exit;
+ }
+ fprintf(stderr, "* Context has %d device(s).\n", device_count);
+
+ printf("* Acquiring TX device\n");
+ tx = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");
+ if (tx == NULL) {
+ iio_strerror(errno, buf, sizeof(buf));
+ fprintf(stderr, "Error opening PLUTOSDR TX device: %s\n", buf);
+ goto error_exit;
+ }
+
+ iio_device_set_kernel_buffers_count(tx, 8);
+
+ phydev = iio_context_find_device(ctx, "ad9361-phy");
+ struct iio_channel* phy_chn = iio_device_find_channel(phydev, "voltage0", true);
+ iio_channel_attr_write(phy_chn, "rf_port_select", txcfg.rfport);
+ iio_channel_attr_write_longlong(phy_chn, "rf_bandwidth", txcfg.bw_hz);
+ iio_channel_attr_write_longlong(phy_chn, "sampling_frequency", txcfg.fs_hz);
+ iio_channel_attr_write_double(phy_chn, "hardwaregain", txcfg.gain_db);
+
+ iio_channel_attr_write_bool(
+ iio_device_find_channel(phydev, "altvoltage0", true)
+ , "powerdown", true); // Turn OFF RX LO
+
+ iio_channel_attr_write_longlong(
+ iio_device_find_channel(phydev, "altvoltage1", true)
+ , "frequency", txcfg.lo_hz); // Set TX LO frequency
+
+ printf("* Initializing streaming channels\n");
+ tx0_i = iio_device_find_channel(tx, "voltage0", true);
+ if (!tx0_i)
+ tx0_i = iio_device_find_channel(tx, "altvoltage0", true);
+
+ tx0_q = iio_device_find_channel(tx, "voltage1", true);
+ if (!tx0_q)
+ tx0_q = iio_device_find_channel(tx, "altvoltage1", true);
+
+ printf("* Enabling IIO streaming channels\n");
+ iio_channel_enable(tx0_i);
+ iio_channel_enable(tx0_q);
+
+ ad9361_set_bb_rate(iio_context_find_device(ctx, "ad9361-phy"), txcfg.fs_hz);
+
+ printf("* Creating TX buffer\n");
+
+ tx_buffer = iio_device_create_buffer(tx, NUM_SAMPLES, false);
+ if (!tx_buffer) {
+ fprintf(stderr, "Could not create TX buffer.\n");
+ goto error_exit;
+ }
+
+ iio_channel_attr_write_bool(
+ iio_device_find_channel(iio_context_find_device(ctx, "ad9361-phy"), "altvoltage1", true)
+ , "powerdown", false); // Turn ON TX LO
+
+ int32_t ntx = 0;
+ short* ptx_buffer = (short*)iio_buffer_start(tx_buffer);
+
+ printf("* Transmit starts...\n");
+ // Keep writing samples while there is more data to send and no failures have occurred.
+ while (!feof(fp) && !stop) {
+ fread(ptx_buffer, sizeof(short), BUFFER_SIZE / sizeof(short), fp);
+ // Schedule TX buffer
+ ntx = iio_buffer_push(tx_buffer);
+ if (ntx < 0) {
+ printf("Error pushing buf %d\n", (int)ntx);
+ break;
+ }
+ }
+ printf("Done.\n");
+
+error_exit:
+ fclose(fp);
+ iio_channel_attr_write_bool(
+ iio_device_find_channel(iio_context_find_device(ctx, "ad9361-phy"), "altvoltage1", true)
+ , "powerdown", true); // Turn OFF TX LO
+
+ if (tx_buffer) { iio_buffer_destroy(tx_buffer); }
+ if (tx0_i) { iio_channel_disable(tx0_i); }
+ if (tx0_q) { iio_channel_disable(tx0_q); }
+ if (ctx) { iio_context_destroy(ctx); }
+ return EXIT_SUCCESS;
+}