diff -Nru libiio-0.21/appveyor.yml libiio-0.23/appveyor.yml --- libiio-0.21/appveyor.yml 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/appveyor.yml 2021-08-20 11:01:14.000000000 +0000 @@ -29,6 +29,9 @@ - set OPT_PATH=C:\msys64\mingw32\bin;C:\msys64\mingw64\bin; - set PATH=%OPT_PATH%%PATH% - set GENERATOR=Unix Makefiles + - set MINGW_TOOLCHAIN_VERSION=10.0.0-3 + - set DOXYGEN_VERSION=1.8.18-1 + - set GRAPHVIZ_VERSION=2.40.1-13 - cd C:\projects\libiio - set folder-path=C:\projects\libiio\build-mingw-win32\%configuration% # MinGW 32 bit @@ -38,17 +41,22 @@ - C:\msys64\usr\bin\bash -lc "pwd" - mkdir C:\projects\libiio\build-mingw-win32\"%configuration%"& cd C:\projects\libiio\build-mingw-win32\"%configuration%" - C:\msys64\usr\bin\bash -lc "pwd" - # TODO: Check when the latest pacman version is fixed and revert this commit. - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U http://repo.msys2.org/msys/x86_64/pacman-5.2.1-6-x86_64.pkg.tar.xz" + # TODO: Revert this after appveyor supports the latest installer. + - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U http://repo.msys2.org/msys/x86_64/pacman-5.2.2-1-x86_64.pkg.tar.xz" + - C:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" + - C:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" + - C:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz{.sig,}" + - C:\msys64\usr\bin\bash -lc "pacman-key --populate" + - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syu" - C:\msys64\usr\bin\bash -lc "pacman -Rs --noconfirm mingw-w64-i686-gcc-ada mingw-w64-i686-gcc-fortran mingw-w64-i686-gcc-libgfortran mingw-w64-i686-gcc-objc" - C:\msys64\usr\bin\bash -lc "rm /mingw32/etc/gdbinit" - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy mingw-w64-i686-gcc mingw-w64-i686-libusb mingw-w64-i686-curl mingw-w64-i686-cmake mingw-w64-i686-libxml2 mingw-w64-i686-pkg-config mingw-w64-i686-libzip" # Newer llvm breaks doxygen, use old version for now - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-llvm-5.0.0-3-any.pkg.tar.xz http://repo.msys2.org/mingw/i686/mingw-w64-i686-clang-5.0.0-3-any.pkg.tar.xz" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/i686/mingw-w64-i686-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" # set the specific version of doxygen (06-Jun-2018), need to look at this later. - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-doxygen-1.8.14-2-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-graphviz-2.40.1-4-any.pkg.tar.xz" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-doxygen-%DOXYGEN_VERSION%-any.pkg.tar.zst" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-graphviz-%GRAPHVIZ_VERSION%-any.pkg.tar.zst" # Download a 32-bit version of windres.exe - appveyor DownloadFile http://swdownloads.analog.com/cse/build/windres.exe.gz -FileName C:\windres.exe.gz - C:\msys64\usr\bin\bash -lc "cd /c ; gunzip windres.exe.gz" @@ -67,11 +75,11 @@ - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy pacman" - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Su" # Newer llvm breaks doxygen, use old version for now - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-llvm-5.0.0-3-any.pkg.tar.xz http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-clang-5.0.0-3-any.pkg.tar.xz" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" # set the specific version of doxygen, need to look at this later. - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-1.8.14-2-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-2.40.1-4-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "cmake -G '%GENERATOR%' -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_INSTALL_PREFIX=/mingw64 -DCMAKE_C_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-g++.exe -DPKG_CONFIG_EXECUTABLE:FILEPATH=/mingw64/bin/pkg-config.exe -DENABLE_IPV6:BOOL=OFF -DLIBSERIALPORT_LIBRARIES=/c/libs/64/libserialport.dll.a -DLIBSERIALPORT_INCLUDE_DIR=/c/include /c/projects/libiio && make -j3" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-%DOXYGEN_VERSION%-any.pkg.tar.zst" + - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-%GRAPHVIZ_VERSION%-any.pkg.tar.zst" + - C:\msys64\usr\bin\bash -lc "cmake -G '%GENERATOR%' -DCMAKE_RC_COMPILER=/c/msys64/mingw64/bin/windres.exe -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_INSTALL_PREFIX=/mingw64 -DCMAKE_C_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-g++.exe -DPKG_CONFIG_EXECUTABLE:FILEPATH=/mingw64/bin/pkg-config.exe -DENABLE_IPV6:BOOL=OFF -DLIBSERIALPORT_LIBRARIES=/c/libs/64/libserialport.dll.a -DLIBSERIALPORT_INCLUDE_DIR=/c/include /c/projects/libiio && make -j3" # Move the tests folder - cd c:\projects\libiio diff -Nru libiio-0.21/azure-pipelines.yml libiio-0.23/azure-pipelines.yml --- libiio-0.21/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/azure-pipelines.yml 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,208 @@ +trigger: + branches: + include: + - main + - master + - staging/* + - 20* + tags: + include: + - v* + +pr: +- main +- master +- 20* + +stages: +- stage: Builds + jobs: + - job: LinuxBuilds + strategy: + matrix: + centos_7_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'centos_docker' + OS_VERSION: centos7 + artifactName: 'Linux-CentOS-7-x86_64' + centos_8_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'centos_docker' + OS_VERSION: centos8 + artifactName: 'Linux-CentOS-8-x86_64' + ubuntu_16_04_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'ubuntu_docker' + OS_VERSION: xenial + artifactName: 'Linux-Ubuntu-16.04-x86_64' + ubuntu_18_04_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'ubuntu_docker' + OS_VERSION: bionic + artifactName: 'Linux-Ubuntu-18.04-x86_64' + CI_BUILD_SPHINX_DOCS: 1 + ubuntu_20_04_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'ubuntu_docker' + OS_VERSION: focal + artifactName: 'Linux-Ubuntu-20.04-x86_64' + CHECK_AGAINST_KERNEL_HEADER: 1 + CI_BUILD_SPHINX_DOCS: 1 + debian_buster_arm32v7: + imageName: 'ubuntu-latest' + OS_TYPE: 'arm32v7/debian_docker' + OS_VERSION: 'buster' + artifactName: 'Linux-Debian-Buster-ARM' + debian_buster_arm64v8: + imageName: 'ubuntu-latest' + OS_TYPE: 'arm64v8/debian_docker' + OS_VERSION: 'buster' + artifactName: 'Linux-Debian-Buster-ARM64' + pool: + vmImage: $(imageName) + steps: + - checkout: self + fetchDepth: 1 + clean: true + - script: ./CI/travis/before_install_linux + displayName: "Install Dependencies" + - script: ./CI/travis/make_linux + displayName: "Build" + - task: CopyFiles@2 + inputs: + sourceFolder: '$(Agent.BuildDirectory)/s/build/' + contents: '$(Agent.BuildDirectory)/s/build/?(*.deb|*.rpm)' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishPipelineArtifact@1 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: '$(artifactName)' + + - job: macOSBuilds + strategy: + matrix: + macOS_10_14: + imageName: 'macOS-10.14' + artifactName: 'macOS-10.14' + macOS_10_15: + imageName: 'macOS-10.15' + artifactName: 'macOS-10.15' +# FIXME: uncomment after this is resolved: +# https://github.com/actions/virtual-environments/issues/2072 +# Mac OS X 11.0 is definitely a big thing (with their switch to ARM, +# so we should be quick to have it) +# macOS_11_0: +# imageName: 'macOS-11.0' +# artifactName: 'macOS-11.0' + pool: + vmImage: $(imageName) + steps: + - checkout: self + fetchDepth: 1 + clean: true + - script: ./CI/travis/before_install_darwin + displayName: "Install Dependencies" + - script: ./CI/travis/make_darwin + displayName: "Build" + - task: CopyFiles@2 + inputs: + sourceFolder: '$(Agent.BuildDirectory)/s/build/' + contents: '$(Agent.BuildDirectory)/s/build/?(*.pkg)' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishPipelineArtifact@1 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: '$(artifactName)' + + - job: WindowsBuilds + strategy: + matrix: + VS2019_Win32: + imageName: 'windows-2019' + COMPILER: 'Visual Studio 16 2019' + ARCH: 'Win32' + artifactName: 'Windows-VS-16-2019-Win32' + VS2019_Win64: + imageName: 'windows-2019' + COMPILER: 'Visual Studio 16 2019' + ARCH: 'x64' + artifactName: 'Windows-VS-16-2019-x64' + pool: + vmImage: $[ variables['imageName'] ] + steps: + - checkout: self + fetchDepth: 1 + clean: true + - task: PowerShell@2 + inputs: + targetType: 'filePath' + filePath: .\CI\install_deps_win.ps1 + displayName: Dependencies + - task: PowerShell@2 + inputs: + targetType: 'filePath' + filePath: .\CI\build_win.ps1 + displayName: Build + - task: CopyFiles@2 + displayName: 'Copy libraries' + inputs: + sourceFolder: '$(Agent.BuildDirectory)/s/build/Release' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: CopyFiles@2 + displayName: 'Copy iio.h header' + inputs: + sourceFolder: '$(Agent.BuildDirectory)/s/' + contents: 'iio.h' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishPipelineArtifact@1 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: '$(artifactName)' + +- stage: PushArtifacts + dependsOn: Builds + jobs: + - job: PushToSWDownloads + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + pool: + vmImage: 'ubuntu-latest' + steps: + - task: DownloadPipelineArtifact@2 + inputs: + path: /home/vsts/work/1/a + - task: DownloadSecureFile@1 + name: key + displayName: 'Download rsa key' + inputs: + secureFile: 'id_rsa' + - bash: chmod 600 $(key.secureFilePath) ; scp -2 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o HostKeyAlgorithms=+ssh-dss -vv -i $(key.secureFilePath) -r /home/vsts/work/1/a/* $MAPPED_VAR + env: + MAPPED_VAR: $(SERVER_ADDRESS) + displayName: "Push artifacts to SW Downloads" + - job: PushToGithubRelease + condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v')) + pool: + vmImage: 'ubuntu-latest' + steps: + - task: DownloadPipelineArtifact@2 + inputs: + path: '$(Build.ArtifactStagingDirectory)' + - bash: ./CI/travis/archive_artifacts.sh + env: + SOURCE_DIRECTORY: $(Build.ArtifactStagingDirectory) + displayName: "Archive artifacts" + - task: GithubRelease@0 + displayName: 'Attach artifacts to GitHub Release' + inputs: + gitHubConnection: libiio-release + repositoryName: $(Build.Repository.Name) + action: create + target: $(Build.SourceVersion) + tag: $(Build.SourceBranchName) + title: "$(Build.SourceBranchName): Version " + assets: $(Build.ArtifactStagingDirectory)/* + addChangeLog: true + isDraft: true diff -Nru libiio-0.21/backend.c libiio-0.23/backend.c --- libiio-0.21/backend.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/backend.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2017 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. */ #include "iio-config.h" @@ -24,51 +15,47 @@ { unsigned int count = 0; -#ifdef WITH_LOCAL_BACKEND - count++; -#endif -#ifdef WITH_XML_BACKEND - count++; -#endif -#ifdef WITH_NETWORK_BACKEND - count++; -#endif -#ifdef WITH_USB_BACKEND - count++; -#endif -#ifdef WITH_SERIAL_BACKEND - count++; -#endif + count += WITH_LOCAL_BACKEND; + count += WITH_XML_BACKEND; + count += WITH_NETWORK_BACKEND; + count += WITH_USB_BACKEND; + count += WITH_SERIAL_BACKEND; return count; } const char * iio_get_backend(unsigned int index) { -#ifdef WITH_LOCAL_BACKEND - if (index == 0) - return "local"; - index--; -#endif -#ifdef WITH_XML_BACKEND - if (index == 0) - return "xml"; - index--; -#endif -#ifdef WITH_NETWORK_BACKEND - if (index == 0) - return "ip"; - index--; -#endif -#ifdef WITH_USB_BACKEND - if (index == 0) - return "usb"; - index--; -#endif -#ifdef WITH_SERIAL_BACKEND - if (index == 0) - return "serial"; -#endif + if (WITH_LOCAL_BACKEND) { + if (index == 0) + return "local"; + index--; + } + + if (WITH_XML_BACKEND) { + if (index == 0) + return "xml"; + index--; + } + + if (WITH_NETWORK_BACKEND) { + if (index == 0) + return "ip"; + index--; + } + + if (WITH_USB_BACKEND) { + if (index == 0) + return "usb"; + index--; + } + + if (WITH_SERIAL_BACKEND) { + if (index == 0) + return "serial"; + index --; + } + return NULL; } diff -Nru libiio-0.21/bindings/csharp/Attr.cs libiio-0.23/bindings/csharp/Attr.cs --- libiio-0.21/bindings/csharp/Attr.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/Attr.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; diff -Nru libiio-0.21/bindings/csharp/Channel.cs libiio-0.23/bindings/csharp/Channel.cs --- libiio-0.21/bindings/csharp/Channel.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/Channel.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; @@ -116,7 +106,8 @@ IIO_MOD_PM4, IIO_MOD_PM10, IIO_MOD_ETHANOL, - IIO_MOD_H2 + IIO_MOD_H2, + IIO_MOD_O2 } /// class: diff -Nru libiio-0.21/bindings/csharp/Context.cs libiio-0.23/bindings/csharp/Context.cs --- libiio-0.21/bindings/csharp/Context.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/Context.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; @@ -99,7 +89,7 @@ private static extern uint iio_context_get_attrs_count(IntPtr ctx); [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_context_get_attr(IntPtr ctx, uint index, IntPtr name_ptr, IntPtr value_ptr); + private static extern int iio_context_get_attr(IntPtr ctx, uint index, out IntPtr name_ptr, out IntPtr value_ptr); [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr iio_context_find_device(IntPtr ctx, [In] string name); @@ -199,19 +189,16 @@ backend_version = new Version(major, minor, builder.ToString()); attrs = new Dictionary(); + uint nbAttrs = iio_context_get_attrs_count(ctx); - for (uint i = 0; i < iio_context_get_attrs_count(ctx); i++) + for (uint i = 0; i < nbAttrs; i++) { - string attr_name = ""; - GCHandle name_handle = GCHandle.Alloc(attr_name, GCHandleType.Pinned); - IntPtr name_ptr = GCHandle.ToIntPtr(name_handle); - string attr_value = ""; - GCHandle value_handle = GCHandle.Alloc(attr_value, GCHandleType.Pinned); - IntPtr value_ptr = GCHandle.ToIntPtr(value_handle); - - iio_context_get_attr(ctx, i, name_ptr, value_ptr); - attr_name = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(name_ptr)); - attr_value = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(value_ptr)); + IntPtr name_ptr; + IntPtr value_ptr; + + iio_context_get_attr(ctx, i, out name_ptr, out value_ptr); + string attr_name = Marshal.PtrToStringAnsi(name_ptr); + string attr_value = Marshal.PtrToStringAnsi(value_ptr); attrs[attr_name] = attr_value; } diff -Nru libiio-0.21/bindings/csharp/Device.cs libiio-0.23/bindings/csharp/Device.cs --- libiio-0.21/bindings/csharp/Device.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/Device.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; @@ -146,6 +136,9 @@ private static extern IntPtr iio_device_get_name(IntPtr dev); [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_device_get_label(IntPtr dev); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] private static extern uint iio_device_get_channels_count(IntPtr dev); [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] @@ -214,6 +207,9 @@ /// The name of this device. public readonly string name; + /// The label of this device. + public readonly string label { get; private set; } + /// A list of all the attributes that this device has. public readonly List attrs; @@ -271,6 +267,10 @@ { name = Marshal.PtrToStringAnsi(name_ptr); } + + IntPtr label_ptr = iio_device_get_label(dev); + + label = label_ptr == IntPtr.Zero ? "" : Marshal.PtrToStringAnsi(label_ptr); } /// Get the object of the specified name. diff -Nru libiio-0.21/bindings/csharp/IioLib.cs libiio-0.23/bindings/csharp/IioLib.cs --- libiio-0.21/bindings/csharp/IioLib.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/IioLib.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2020 Analog Devices, Inc. * Author: Paul Cristian Iacob - * - * 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. - * - * */ + */ using System; using System.Linq; diff -Nru libiio-0.21/bindings/csharp/IOBuffer.cs libiio-0.23/bindings/csharp/IOBuffer.cs --- libiio-0.21/bindings/csharp/IOBuffer.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/IOBuffer.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; diff -Nru libiio-0.21/bindings/csharp/ScanContext.cs libiio-0.23/bindings/csharp/ScanContext.cs --- libiio-0.21/bindings/csharp/ScanContext.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/ScanContext.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2020 Analog Devices, Inc. * Author: Cristian Iacob - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; diff -Nru libiio-0.21/bindings/csharp/Trigger.cs libiio-0.23/bindings/csharp/Trigger.cs --- libiio-0.21/bindings/csharp/Trigger.cs 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/csharp/Trigger.cs 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ using System; using System.Collections.Generic; diff -Nru libiio-0.21/bindings/python/doc/index.rst libiio-0.23/bindings/python/doc/index.rst --- libiio-0.21/bindings/python/doc/index.rst 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/python/doc/index.rst 2021-08-20 11:01:14.000000000 +0000 @@ -10,7 +10,7 @@ .. code-block:: bash - (sudo) pip install libiio + (sudo) pip install pylibiio or by grabbing the source directly diff -Nru libiio-0.21/bindings/python/examples/iio_readdev.py libiio-0.23/bindings/python/examples/iio_readdev.py --- libiio-0.21/bindings/python/examples/iio_readdev.py 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/python/examples/iio_readdev.py 2021-08-20 11:01:14.000000000 +0000 @@ -214,6 +214,7 @@ """ buffer_builder = BufferBuilder(ctx, arguments) self.buffer = buffer_builder.create() + self.device = buffer_builder.dev self.arguments = arguments def read(self): @@ -224,7 +225,7 @@ if self.arguments.num_samples > 0: sys.stdout.buffer.write( - samples[: min(self.arguments.num_samples, len(samples))] + samples[: min(self.arguments.num_samples * self.device.sample_size, len(samples))] ) self.arguments.num_samples -= min( self.arguments.num_samples, len(samples) diff -Nru libiio-0.21/bindings/python/iio.py libiio-0.23/bindings/python/iio.py --- libiio-0.21/bindings/python/iio.py 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/python/iio.py 2021-08-20 11:01:14.000000000 +0000 @@ -1,17 +1,10 @@ #!/usr/bin/env python +# SPDX-License-Identifier: LGPL-2.1-or-later """ +SPDX-License-Identifier: LGPL-2.1-or-later + Copyright (C) 2014 Analog Devices, Inc. Author: Paul Cercueil - -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. """ # Imports from package ctypes are not grouped @@ -44,7 +37,6 @@ from enum import Enum from os import strerror as _strerror from platform import system as _system -import weakref import abc if "Windows" in _system(): @@ -173,6 +165,7 @@ IIO_MOD_PM10 = 41 IIO_MOD_ETHANOL = 42 IIO_MOD_H2 = 43 + IIO_MOD_O2 = 44 class ChannelType(Enum): @@ -346,6 +339,10 @@ _get_device.argtypes = (_ContextPtr, c_uint) _get_device.errcheck = _check_null +_find_device = _lib.iio_context_find_device +_find_device.restype = _DevicePtr +_find_device.argtypes = (_ContextPtr, c_char_p) + _set_timeout = _lib.iio_context_set_timeout _set_timeout.restype = c_int _set_timeout.argtypes = ( @@ -368,6 +365,10 @@ _d_get_name.restype = c_char_p _d_get_name.argtypes = (_DevicePtr,) +_d_get_label = _lib.iio_device_get_label +_d_get_label.restype = c_char_p +_d_get_label.argtypes = (_DevicePtr,) + _d_attr_count = _lib.iio_device_get_attrs_count _d_attr_count.restype = c_uint _d_attr_count.argtypes = (_DevicePtr,) @@ -429,6 +430,10 @@ _d_get_context.restype = _ContextPtr _d_get_context.argtypes = (_DevicePtr,) +_d_find_channel = _lib.iio_device_find_channel +_d_find_channel.restype = _ChannelPtr +_d_find_channel.argtypes = (_DevicePtr, c_char_p, c_bool) + _d_reg_write = _lib.iio_device_reg_write _d_reg_write.restype = c_int _d_reg_write.argtypes = (_DevicePtr, c_uint, c_uint) @@ -461,7 +466,7 @@ _d_get_trigger.restype = c_int _d_get_trigger.argtypes = ( _DevicePtr, - _DevicePtr, + _POINTER(_DevicePtr), ) _d_get_trigger.errcheck = _check_negative @@ -821,7 +826,7 @@ class Channel(object): """Represents a channel of an IIO device.""" - def __init__(self, _channel): + def __init__(self, dev, _channel): """ Initialize a new instance of the Channel class. @@ -832,6 +837,7 @@ An new instance of this class """ self._channel = _channel + self._dev = dev self._attrs = { name: ChannelAttr(_channel, name) for name in [ @@ -929,8 +935,7 @@ Corresponding device for the channel. type: iio.Device """ - c_dev = _channel_get_device(self._channel) - return Device(_d_get_context(c_dev), c_dev) + return self._dev @property def index(self): @@ -1013,9 +1018,10 @@ raise self._length = samples_count * device.sample_size self._samples_count = samples_count - self._ctx = device.ctx() - # Holds a reference to the corresponding IIO Context. This ensures that - # every iio.Buffer object is destroyed before its corresponding IIO Context. + + # Hold a reference to the device, to ensure that every iio.Buffer object + # is destroyed before its corresponding IIO context. + self._dev = device def __del__(self): """Destroy this buffer.""" @@ -1096,7 +1102,7 @@ Device for the buffer. type: iio.Device """ - return Device(self._ctx, _buffer_get_device(self._buffer)) + return self._dev @property def poll_fd(self): @@ -1116,7 +1122,8 @@ class _DeviceOrTrigger(object): - def __init__(self, _device): + def __init__(self, _ctx, _device): + self._ctx = _ctx self._device = _device self._context = _d_get_context(_device) self._attrs = { @@ -1141,17 +1148,14 @@ ] } - # TODO(pcercuei): Use a dictionary for the channels. - chans = [ - Channel(_get_channel(self._device, x)) - for x in range(0, _channels_count(self._device)) - ] - self._channels = sorted(chans, key=lambda c: c.id) self._id = _d_get_id(self._device).decode("ascii") name_raw = _d_get_name(self._device) self._name = name_raw.decode("ascii") if name_raw is not None else None + label_raw = _d_get_label(self._device) + self._label = label_raw.decode("ascii") if label_raw is not None else None + def reg_write(self, reg, value): """ Set a value to one register of this device. @@ -1190,14 +1194,8 @@ returns: type=iio.Device or type=iio.Trigger The IIO Device """ - return next( - ( - x - for x in self.channels - if name_or_id == x.name or name_or_id == x.id and x.output == is_output - ), - None, - ) + chn = _d_find_channel(self._device, name_or_id.encode("ascii"), is_output) + return None if chn is None else Channel(self, chn) def set_kernel_buffers_count(self, count): """ @@ -1229,6 +1227,9 @@ name = property( lambda self: self._name, None, None, "The name of this device.\n\ttype=str" ) + label = property( + lambda self: self._label, None, None, "The label of this device.\n\ttype=str", + ) attrs = property( lambda self: self._attrs, None, @@ -1248,7 +1249,10 @@ "List of buffer attributes for this IIO device.\n\ttype=dict of iio.DeviceBufferAttr", ) channels = property( - lambda self: self._channels, + lambda self: sorted([ + Channel(self, _get_channel(self._device, x)) + for x in range(0, _channels_count(self._device)) + ], key=lambda c: c.id), None, None, "List of channels available with this IIO device.\n\ttype=list of iio.Channel objects", @@ -1258,7 +1262,7 @@ class Trigger(_DeviceOrTrigger): """Contains the representation of an IIO device that can act as a trigger.""" - def __init__(self, _device): + def __init__(self, ctx, _device): """ Initialize a new instance of the Trigger class. @@ -1268,13 +1272,13 @@ returns: type=iio.Trigger An new instance of this class """ - super(Trigger, self).__init__(_device) + super(Trigger, self).__init__(ctx, _device) def _get_rate(self): - return int(self._attrs["frequency"].value) + return int(self._attrs["sampling_frequency"].value) def _set_rate(self, value): - self._attrs["frequency"].value = str(value) + self._attrs["sampling_frequency"].value = str(value) frequency = property( _get_rate, @@ -1299,18 +1303,19 @@ returns: type=iio.Device An new instance of this class """ - super(Device, self).__init__(_device) - self.ctx = weakref.ref(ctx) + super(Device, self).__init__(ctx, _device) + self.ctx = ctx def _set_trigger(self, trigger): _d_set_trigger(self._device, trigger._device if trigger else None) def _get_trigger(self): - value = _Device() + value = _DevicePtr() _d_get_trigger(self._device, _byref(value)) + trig = Trigger(value.contents) - for dev in self.ctx()._devices: - if value == dev._device: + for dev in self.ctx.devices: + if trig.id == dev.id: return dev return None @@ -1327,7 +1332,7 @@ Context for the device. type: iio.Context """ - return self.ctx() + return self.ctx class Context(object): @@ -1361,14 +1366,6 @@ _get_attr(self._context, index, _byref(str1), _byref(str2)) self._attrs[str1.value.decode("ascii")] = str2.value.decode("ascii") - # TODO(pcercuei): Use a dictionary for the devices. - self._devices = [ - Trigger(dev) if _d_is_trigger(dev) else Device(self, dev) - for dev in [ - _get_device(self._context, x) - for x in range(0, _devices_count(self._context)) - ] - ] self._name = _get_name(self._context).decode("ascii") self._description = _get_description(self._context).decode("ascii") self._xml = _get_xml(self._context).decode("ascii") @@ -1402,18 +1399,19 @@ """ return Context(_clone(self._context)) - def find_device(self, name_or_id): + def find_device(self, name_or_id_or_label): """ - Find a IIO device by its name or ID. + Find a IIO device by its name, ID or label. - :param name_or_id: type=str - The name or ID of the device to find + :param name_or_id_or_label: type=str + The name, ID or label of the device to find returns: type=iio.Device or type=iio.Trigger The IIO Device """ - return next((x for x in self.devices if name_or_id in [x.name, x.id]), None,) + dev = _find_device(self._context, name_or_id_or_label.encode("ascii")) + return None if dev is None else Trigger(self, dev) if _d_is_trigger(dev) else Device(self, dev) name = property( lambda self: self._name, None, None, "Name of this IIO context.\n\ttype=str" @@ -1443,7 +1441,13 @@ "List of context-specific attributes\n\ttype=dict of str objects", ) devices = property( - lambda self: self._devices, + lambda self: [ + Trigger(self, dev) if _d_is_trigger(dev) else Device(self, dev) + for dev in [ + _get_device(self._context, x) + for x in range(0, _devices_count(self._context)) + ] + ], None, None, "List of devices contained in this context.\n\ttype=list of iio.Device and iio.Trigger objects", diff -Nru libiio-0.21/bindings/python/README.md libiio-0.23/bindings/python/README.md --- libiio-0.21/bindings/python/README.md 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/python/README.md 2021-08-20 11:01:14.000000000 +0000 @@ -4,8 +4,8 @@ libiio is used to interface to the Linux Industrial Input/Output (IIO) Subsystem. The Linux IIO subsystem is intended to provide support for devices that in some sense are analog to digital or digital to analog converters (ADCs, DACs). This includes, but is not limited to ADCs, Accelerometers, Gyros, IMUs, Capacitance to Digital Converters (CDCs), Pressure Sensors, Color, Light and Proximity Sensors, Temperature Sensors, Magnetometers, DACs, DDS (Direct Digital Synthesis), PLLs (Phase Locked Loops), Variable/Programmable Gain Amplifiers (VGA, PGA), and RF transceivers. You can use libiio natively on an embedded Linux target (local mode), or use libiio to communicate remotely to that same target from a host Linux, Windows or MAC over USB or Ethernet or Serial. -[![Build Status](https://travis-ci.org/analogdevicesinc/libiio.svg?branch=master)](https://travis-ci.org/analogdevicesinc/libiio) -[![PyPI version](https://badge.fury.io/py/libiio.svg)](https://badge.fury.io/py/libiio) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4bd027bfc5774029a30a9e1cedf5a434)](https://www.codacy.com/app/rgetz/libiio?utm_source=github.com&utm_medium=referral&utm_content=analogdevicesinc/libiio&utm_campaign=Badge_Grade) +[![Build Status](https://travis-ci.com/analogdevicesinc/libiio.svg?branch=master)](https://travis-ci.com/analogdevicesinc/libiio) +[![PyPI version](https://badge.fury.io/py/pylibiio.svg)](https://badge.fury.io/py/pylibiio) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4bd027bfc5774029a30a9e1cedf5a434)](https://www.codacy.com/app/rgetz/libiio?utm_source=github.com&utm_medium=referral&utm_content=analogdevicesinc/libiio&utm_campaign=Badge_Grade) ![open bugs](https://img.shields.io/github/issues/analogdevicesinc/libiio.svg) [[Docs](https://analogdevicesinc.github.io/libiio/v0.19/python/index.html)] @@ -20,7 +20,7 @@ ### Installing the bindings To install these bindings there are a few methods. If you already have the library itself and just need the bindings, pip is the most convenient method: ```shell -(sudo) pip install libiio +(sudo) pip install pylibiio ``` If you do not want to use pip, then installation is dependent on your operating system. #### Linux / macOS diff -Nru libiio-0.21/bindings/python/setup.py.cmakein libiio-0.23/bindings/python/setup.py.cmakein --- libiio-0.21/bindings/python/setup.py.cmakein 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/bindings/python/setup.py.cmakein 2021-08-20 11:01:14.000000000 +0000 @@ -1,17 +1,8 @@ #!/usr/bin/env python +# SPDX-License-Identifier: LGPL-2.1-or-later # # Copyright (C) 2015 Analog Devices, Inc. # Author: Paul Cercueil -# -# 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. import sys @@ -54,6 +45,13 @@ install.run(self) def _check_libiio_installed(self): + cross_compiling = ("${CMAKE_CROSSCOMPILING}" == "TRUE") + if cross_compiling: + # When cross-compiling, we generally cannot dlopen + # the libiio shared lib from the build platform. + # Simply skip this check in that case. + return + from platform import system as _system from ctypes import CDLL as _cdll from ctypes.util import find_library @@ -85,7 +83,7 @@ config.update( dict( - name="libiio", + name="pylibiio", version="${VERSION}", maintainer="Analog Devices, Inc", maintainer_email="travis.collins@analog.com", diff -Nru libiio-0.21/buffer.c libiio-0.23/buffer.c --- libiio-0.21/buffer.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/buffer.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ #include "iio-config.h" #include "iio-private.h" diff -Nru libiio-0.21/channel.c libiio-0.23/channel.c --- libiio-0.21/channel.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/channel.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// 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 - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-private.h" @@ -100,6 +90,7 @@ [IIO_MOD_CO2] = "co2", [IIO_MOD_ETHANOL] = "ethanol", [IIO_MOD_H2] = "h2", + [IIO_MOD_O2] = "o2", [IIO_MOD_VOC] = "voc", [IIO_MOD_PM1] = "pm1", [IIO_MOD_PM2P5] = "pm2p5", @@ -176,168 +167,92 @@ } } -static char *get_attr_xml(struct iio_channel_attr *attr, size_t *length) +static ssize_t iio_snprintf_chan_attr_xml(char *str, ssize_t len, + struct iio_channel_attr *attr) { - char *str; - size_t len; + ssize_t ret, alen = 0; - len = strnlen(attr->name, MAX_ATTR_NAME); - len += sizeof("") - 1; + if (!attr->filename) + return iio_snprintf(str, len, "", attr->name); - if (attr->filename) { - len += strnlen(attr->filename, NAME_MAX); - len += sizeof(" filename=\"\"") - 1; - } + ret = iio_snprintf(str, len, "name); + if (ret < 0) + return ret; - *length = len; /* just the chars */ - len++; /* room for terminating NULL */ - str = malloc(len); - if (!str) - return NULL; + iio_update_xml_indexes(ret, &str, &len, &alen); - if (attr->filename) - iio_snprintf(str, len, "", - attr->name, attr->filename); - else - iio_snprintf(str, len, "", attr->name); + ret = iio_xml_print_and_sanitized_param(str, len, "filename=\"", + attr->filename, "\" />"); + if (ret < 0) + return ret; - return str; + return alen + ret; } -static char * get_scan_element(const struct iio_channel *chn, size_t *length) +static ssize_t iio_snprintf_scan_element_xml(char *str, ssize_t len, + const struct iio_channel *chn) { - char buf[1024], repeat[12] = "", *str; char processed = (chn->format.is_fully_defined ? 'A' - 'a' : 0); + char repeat[12] = "", scale[48] = ""; if (chn->format.repeat > 1) iio_snprintf(repeat, sizeof(repeat), "X%u", chn->format.repeat); - iio_snprintf(buf, sizeof(buf), "", + if (chn->format.with_scale) + iio_snprintf(scale, sizeof(scale), "scale=\"%f\" ", chn->format.scale); + + return iio_snprintf(str, len, + "", chn->index, chn->format.is_be ? 'b' : 'l', chn->format.is_signed ? 's' + processed : 'u' + processed, chn->format.bits, chn->format.length, repeat, - chn->format.shift); - - if (chn->format.with_scale) { - char *ptr = strrchr(buf, '\0'); - iio_snprintf(ptr - 2, buf + sizeof(buf) - ptr + 2, - "scale=\"%f\" />", chn->format.scale); - } - - str = iio_strdup(buf); - if (str) - *length = strlen(str); - return str; + chn->format.shift, scale); } -/* Returns a string containing the XML representation of this channel */ -char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length) +ssize_t iio_snprintf_channel_xml(char *ptr, ssize_t len, + const struct iio_channel *chn) { - ssize_t len; - char *ptr, *eptr, *str, **attrs, *scan_element = NULL; - size_t *attrs_len, scan_element_len = 0; + ssize_t ret, alen = 0; unsigned int i; - len = sizeof("") - 1; - len += strnlen(chn->id, MAX_CHN_ID); - len += (chn->is_output ? sizeof("output") : sizeof("input")) - 1; - if (chn->name) { - len += sizeof(" name=\"\"") - 1; - len += strnlen(chn->name, MAX_CHN_NAME); - } - - if (chn->is_scan_element) { - scan_element = get_scan_element(chn, &scan_element_len); - if (!scan_element) - return NULL; - else - len += scan_element_len; - } - - attrs_len = malloc(chn->nb_attrs * sizeof(*attrs_len)); - if (!attrs_len) - goto err_free_scan_element; - attrs = malloc(chn->nb_attrs * sizeof(*attrs)); - if (!attrs) - goto err_free_attrs_len; + ret = iio_xml_print_and_sanitized_param(ptr, len, "id, "\""); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); - for (i = 0; i < chn->nb_attrs; i++) { - char *xml = get_attr_xml(&chn->attrs[i], &attrs_len[i]); - if (!xml) - goto err_free_attrs; - attrs[i] = xml; - len += attrs_len[i]; - } - - len++; /* room for terminating NULL */ - str = malloc(len); - if (!str) - goto err_free_attrs; - ptr = str; - eptr = str + len; - - if (len > 0) { - ptr += iio_snprintf(str, len, "id); - len = eptr - ptr; - } - - if (chn->name && len > 0) { - ptr += iio_snprintf(ptr, len, " name=\"%s\"", chn->name); - len = eptr - ptr; + if (chn->name) { + ret = iio_snprintf(ptr, len, " name=\"%s\"", chn->name); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - if (len > 0) { - ptr += iio_snprintf(ptr, len, " type=\"%s\" >", chn->is_output ? "output" : "input"); - len = eptr - ptr; - } + ret = iio_snprintf(ptr, len, " type=\"%s\" >", chn->is_output ? "output" : "input"); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); - if (chn->is_scan_element && len > (ssize_t) scan_element_len) { - memcpy(ptr, scan_element, scan_element_len); /* Flawfinder: ignore */ - ptr += scan_element_len; - len -= scan_element_len; + if (chn->is_scan_element) { + ret = iio_snprintf_scan_element_xml(ptr, len, chn); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); } for (i = 0; i < chn->nb_attrs; i++) { - if (len > (ssize_t) attrs_len[i]) { - memcpy(ptr, attrs[i], attrs_len[i]); /* Flawfinder: ignore */ - ptr += attrs_len[i]; - len -= attrs_len[i]; - } - free(attrs[i]); - } - - free(scan_element); - free(attrs); - free(attrs_len); - - if (len > 0) { - ptr += iio_strlcpy(ptr, "", len); - len -= sizeof("") -1; - } - - *length = ptr - str; - - /* NULL char should be left, and that is it */ - if (len != 1) { - IIO_ERROR("Internal libIIO error: iio_channel_get_xml str length issue\n"); - free(str); - return NULL; + ret = iio_snprintf_chan_attr_xml(ptr, len, &chn->attrs[i]); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - return str; + ret = iio_snprintf(ptr, len, ""); + if (ret < 0) + return ret; -err_free_attrs: - while (i--) - free(attrs[i]); - free(attrs); -err_free_attrs_len: - free(attrs_len); -err_free_scan_element: - if (chn->is_scan_element) - free(scan_element); - return NULL; + return alen + ret; } const char * iio_channel_get_id(const struct iio_channel *chn) @@ -468,12 +383,9 @@ free(chn->attrs[i].name); free(chn->attrs[i].filename); } - if (chn->nb_attrs) - free(chn->attrs); - if (chn->name) - free(chn->name); - if (chn->id) - free(chn->id); + free(chn->attrs); + free(chn->name); + free(chn->id); free(chn); } @@ -489,11 +401,7 @@ size_t i, shift_bytes = shift / 8; shift %= 8; -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - if (!left) -#else - if (left) -#endif + if (is_little_endian() ^ left) { if (shift_bytes) { memmove(dst, dst + shift_bytes, len - shift_bytes); @@ -501,15 +409,15 @@ } if (shift) { for (i = 0; i < len; i++) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - dst[i] >>= shift; - if (i < len - 1) - dst[i] |= dst[i + 1] << (8 - shift); -#else - dst[i] <<= shift; - if (i < len - 1) - dst[i] |= dst[i + 1] >> (8 - shift); -#endif + if (is_little_endian()) { + dst[i] >>= shift; + if (i < len - 1) + dst[i] |= dst[i + 1] << (8 - shift); + } else { + dst[i] <<= shift; + if (i < len - 1) + dst[i] |= dst[i + 1] >> (8 - shift); + } } } } else { @@ -519,15 +427,15 @@ } if (shift) { for (i = len; i > 0; i--) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - dst[i - 1] <<= shift; - if (i > 1) - dst[i - 1] |= dst[i - 2] >> (8 - shift); -#else - dst[i - 1] >>= shift; - if (i > 1) - dst[i - 1] |= dst[i - 2] << (8 - shift); -#endif + if (is_little_endian()) { + dst[i - 1] <<= shift; + if (i > 1) + dst[i - 1] |= dst[i - 2] >> (8 - shift); + } else { + dst[i - 1] >>= shift; + if (i > 1) + dst[i - 1] |= dst[i - 2] << (8 - shift); + } } } } @@ -538,22 +446,22 @@ size_t upper_bytes = ((len * 8 - bits) / 8); uint8_t msb, msb_bit = 1 << ((bits - 1) % 8); -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - msb = dst[len - 1 - upper_bytes] & msb_bit; - if (upper_bytes) - memset(dst + len - upper_bytes, msb ? 0xff : 0x00, upper_bytes); - if (msb) - dst[len - 1 - upper_bytes] |= ~(msb_bit - 1); - else - dst[len - 1 - upper_bytes] &= (msb_bit - 1); -#else - /* XXX: untested */ - msb = dst[upper_bytes] & msb_bit; - if (upper_bytes) - memset(dst, msb ? 0xff : 0x00, upper_bytes); - if (msb) - dst[upper_bytes] |= ~(msb_bit - 1); -#endif + if (is_little_endian()) { + msb = dst[len - 1 - upper_bytes] & msb_bit; + if (upper_bytes) + memset(dst + len - upper_bytes, msb ? 0xff : 0x00, upper_bytes); + if (msb) + dst[len - 1 - upper_bytes] |= ~(msb_bit - 1); + else + dst[len - 1 - upper_bytes] &= (msb_bit - 1); + } else { + /* XXX: untested */ + msb = dst[upper_bytes] & msb_bit; + if (upper_bytes) + memset(dst, msb ? 0xff : 0x00, upper_bytes); + if (msb) + dst[upper_bytes] |= ~(msb_bit - 1); + } } static void mask_upper_bits(uint8_t *dst, size_t bits, size_t len) @@ -577,11 +485,7 @@ unsigned int len = chn->format.length / 8; ptrdiff_t end = len * chn->format.repeat; uintptr_t end_ptr = src_ptr + end; -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - bool swap = chn->format.is_be; -#else - bool swap = !chn->format.is_be; -#endif + bool swap = is_little_endian() ^ !chn->format.is_be; for (src_ptr = (uintptr_t) src; src_ptr < end_ptr; src_ptr += len, dst_ptr += len) { @@ -613,11 +517,7 @@ unsigned int len = chn->format.length / 8; ptrdiff_t end = len * chn->format.repeat; uintptr_t end_ptr = dst_ptr + end; -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - bool swap = chn->format.is_be; -#else - bool swap = !chn->format.is_be; -#endif + bool swap = is_little_endian() ^ !chn->format.is_be; uint8_t buf[1024]; /* Somehow I doubt we will have samples of 8192 bits each. */ diff -Nru libiio-0.21/CI/build_win.ps1 libiio-0.23/CI/build_win.ps1 --- libiio-0.21/CI/build_win.ps1 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/CI/build_win.ps1 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,11 @@ + +$COMPILER=$Env:COMPILER +$ARCH=$Env:ARCH + +$src_dir=$pwd + +mkdir build +cd build + +cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. +cmake --build . --config Release diff -Nru libiio-0.21/CI/install_deps_win.ps1 libiio-0.23/CI/install_deps_win.ps1 --- libiio-0.21/CI/install_deps_win.ps1 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/CI/install_deps_win.ps1 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,30 @@ + +$ARCH=$Env:ARCH + +git submodule update --init + +if (!(Test-Path deps)) { + mkdir deps +} +cd deps + +mkdir libxml + +if ( "$ARCH" -eq "x64" ) { + wget https://www.zlatkovic.com/pub/libxml/64bit/libxml2-2.9.3-win32-x86_64.7z -OutFile "libxml.7z" +} else { + wget https://www.zlatkovic.com/pub/libxml/64bit/libxml2-2.9.3-win32-x86.7z -OutFile "libxml.7z" +} +7z x -y libxml.7z +rm libxml.7z + +echo "Downloading deps..." +cd C:\ +wget http://swdownloads.analog.com/cse/build/libiio-win-deps.zip -OutFile "libiio-win-deps.zip" +7z x -y "C:\libiio-win-deps.zip" + +# Note: InnoSetup is already installed on Azure images; so don't run this step +# Running choco seems a bit slow; seems to save about 40-60 seconds here +#choco install InnoSetup + +set PATH=%PATH%;"C:\Program Files (x86)\Inno Setup 6" diff -Nru libiio-0.21/CI/travis/archive_artifacts.sh libiio-0.23/CI/travis/archive_artifacts.sh --- libiio-0.21/CI/travis/archive_artifacts.sh 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/CI/travis/archive_artifacts.sh 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,36 @@ +#!/bin/bash -e + +archive_linux() { + local linux_dist='CentOS-7-x86_64 CentOS-8-x86_64 Ubuntu-16.04-x86_64 + Ubuntu-18.04-x86_64 Ubuntu-20.04-x86_64 Debian-Buster-ARM Debian-Buster-ARM64' + + cd "${SOURCE_DIRECTORY}" + for distribution in $linux_dist; do + tar -zcvf Linux-"${distribution}".tar.gz Linux-"${distribution}" + rm -r Linux-"${distribution}" + done +} + +archive_macOS() { + local macOS_dist='10.14 10.15' + + cd "${SOURCE_DIRECTORY}" + for distribution in $macOS_dist; do + tar -zcvf macOS-"${distribution}".tar.gz macOS-"${distribution}" + rm -r macOS-"${distribution}" + done +} + +archive_windows() { + local windows_dist='Win32 x64' + + cd "${SOURCE_DIRECTORY}" + for distribution in $windows_dist; do + zip -r Windows-VS-16-2019-"${distribution}".zip Windows-VS-16-2019-"${distribution}" + rm -r Windows-VS-16-2019-"${distribution}" + done +} + +archive_linux +archive_macOS +archive_windows diff -Nru libiio-0.21/CI/travis/before_install_darwin libiio-0.23/CI/travis/before_install_darwin --- libiio-0.21/CI/travis/before_install_darwin 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/before_install_darwin 2021-08-20 11:01:14.000000000 +0000 @@ -2,4 +2,4 @@ . CI/travis/lib.sh -brew_install_if_not_exists cmake doxygen libusb libxml2 ncurses cdk +brew_install_if_not_exists cmake doxygen libusb libxml2 ncurses cdk zstd diff -Nru libiio-0.21/CI/travis/before_install_linux libiio-0.23/CI/travis/before_install_linux --- libiio-0.21/CI/travis/before_install_linux 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/before_install_linux 2021-08-20 11:01:14.000000000 +0000 @@ -3,36 +3,21 @@ . CI/travis/lib.sh install_sphinx() { - if command_exists python ; then - python --version - command -v python - python -m pip install -U pip - python -m pip install -U setuptools - python -m pip install sphinx - python -m pip install sphinx-rtd-theme + if [ "$CI_BUILD_SPHINX_DOCS" != "1" ] ; then + return fi -} -install_pyenv() { - if ! command_exists pyenv ; then - echo installing pyenv - git clone git://github.com/yyuu/pyenv.git $HOME/.pyenv - export PATH="$HOME/.pyenv/bin:$PATH" - export PYENV_ROOT="$HOME/.pyenv" + if ! is_python_at_least_ver "$PYTHON" "3.6" ; then + echo_red "Python version is too old no python interpreter installed" + return 1 fi -} -install_python() { - echo "### installing python" - command -v pyenv - add_python_path - pyenv install --list | grep "^[[:space:]]*[0-9]" - pyenv install 3.6.3 - pyenv global 3.6.3 - add_python_path + $PYTHON --version + command -v $PYTHON + $PYTHON -m pip install sphinx + $PYTHON -m pip install sphinx-rtd-theme } - handle_centos() { # needed for man2html and a few other popular tools yum search epel-release @@ -41,35 +26,48 @@ # FIXME: see about adding `libserialport-dev` from EPEL ; maybe libusb-1.0.0-devel... yum -y groupinstall 'Development Tools' - yum -y install cmake libxml2-devel libusb1-devel libaio-devel \ - bzip2 gzip rpm rpm-build redhat-lsb-core - - # needed for building python with pyenv - yum install -y gcc gcc-c++ make git patch openssl-devel zlib-devel readline-devel sqlite-devel bzip2-devel - - # CentOS 6 & 7 don't work with doc, or the latest python. - # install_pyenv - # install_python if [ "$(get_version | head -c 1)" = "7" ] ; then - # install Cmake3, and make it the default - yum -y install cmake3 - alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \ - --slave /usr/local/bin/ctest ctest /usr/bin/ctest \ - --slave /usr/local/bin/cpack cpack /usr/bin/cpack \ - --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \ - --family cmake - alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \ - --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \ - --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \ - --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \ - --family cmake - fi + yum -y install cmake libxml2-devel libusb1-devel libaio-devel \ + bzip2 gzip rpm rpm-build libzstd-devel + + # install Cmake3, and make it the default + yum -y install cmake3 + alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \ + --slave /usr/local/bin/ctest ctest /usr/bin/ctest \ + --slave /usr/local/bin/cpack cpack /usr/bin/cpack \ + --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \ + --family cmake + alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \ + --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \ + --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \ + --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \ + --family cmake + fi + + if [ "$(get_version | head -c 1)" = "8" ] ; then + yum -y install wget + wget https://github.com/Kitware/CMake/releases/download/v3.15.2/cmake-3.15.2.tar.gz + tar -zxvf cmake-3.15.2.tar.gz + cd cmake-3.15.2 + ./bootstrap + make + make install + cd .. + yum -y install epel-release + yum -y install libzstd + + yum -y install dnf + dnf -y --enablerepo=powertools install doxygen + + yum -y install libxml2-devel libusb1-devel libaio-devel \ + bzip2 gzip rpm rpm-build libzstd-devel + fi if is_centos_at_least_ver "8" ; then # On CentOS 8, avahi-devel & doxygen are in this repo; enable it yum -y install yum-utils - yum config-manager --set-enabled PowerTools + yum config-manager --set-enabled powertools # On CentOS 6 & 7, have issues building or packaging doc yum -y install python3 doxygen man2html install_sphinx @@ -81,40 +79,29 @@ yum -y install avahi-devel } -handle_centos_docker() { - prepare_docker_image "centos:centos${OS_VERSION}" -} - -handle_ubuntu_docker() { - prepare_docker_image "ubuntu:${OS_VERSION}" +handle_generic_docker() { + prepare_docker_image } handle_default() { sudo apt-get -qq update - sudo apt-get install -y apt-utils sudo DEBIAN_FRONTEND=noninteractive apt-get install -y cmake graphviz \ - libaio-dev libavahi-client-dev \ + libaio-dev libavahi-client-dev libserialport-dev libzstd-dev \ libavahi-common-dev libusb-1.0-0-dev libxml2-dev rpm tar \ - bzip2 gzip flex bison git lsb-release libncurses5-dev libcdk5-dev + bzip2 gzip flex bison git libncurses5-dev libcdk5-dev \ + doxygen man2html python3 python3-pip python3-setuptools - # Most of these should be here, but are needed for building python by pyenv - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential \ - libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \ - wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev \ - libffi-dev liblzma-dev python-openssl git - - if ! is_arm ; then - install_pyenv - install_python - sudo apt-get install -y doxygen man2html - install_sphinx - fi - - if [ `sudo apt-cache search libserialport-dev | wc -l` -gt 0 ] ; then - sudo apt-get install -y libserialport-dev - fi + install_sphinx +} + +handle_ubuntu() { + handle_default +} + +handle_debian() { + handle_default } -OS_TYPE=${1:-default} +setup_build_type_env_vars -handle_${OS_TYPE} +handle_${BUILD_TYPE} diff -Nru libiio-0.21/CI/travis/inside_docker.sh libiio-0.23/CI/travis/inside_docker.sh --- libiio-0.21/CI/travis/inside_docker.sh 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/inside_docker.sh 2021-08-20 11:01:14.000000000 +0000 @@ -1,30 +1,30 @@ #!/bin/sh -e -LIBNAME="$1" -OS_TYPE="$2" - export INSIDE_DOCKER="1" -export TRAVIS_BUILD_DIR="/$LIBNAME" -cd "/$LIBNAME" +INSIDE_DOCKER_BUILD_DIR=/docker_build_dir + +export TRAVIS_BUILD_DIR="$INSIDE_DOCKER_BUILD_DIR" + +cd "$INSIDE_DOCKER_BUILD_DIR" -if [ -d "/$LIBNAME/CI" ] ; then - CI="/$LIBNAME/CI" -elif [ -d "/$LIBNAME/ci" ] ; then - CI="/$LIBNAME/ci" +if [ -d "/$INSIDE_DOCKER_BUILD_DIR/CI" ] ; then + CI="/$INSIDE_DOCKER_BUILD_DIR/CI" +elif [ -d "/$INSIDE_DOCKER_BUILD_DIR/ci" ] ; then + CI="/$INSIDE_DOCKER_BUILD_DIR/ci" else echo "No CI/ci directory present" exit 1 fi -if [ -f "/$LIBNAME/inside-travis-ci-docker-env" ] ; then - . "/$LIBNAME/inside-travis-ci-docker-env" +if [ -f "$INSIDE_DOCKER_BUILD_DIR/inside-travis-ci-docker-env" ] ; then + . "$INSIDE_DOCKER_BUILD_DIR/inside-travis-ci-docker-env" fi -"$CI/travis/before_install_linux" "$OS_TYPE" +"$CI/travis/before_install_linux" -"$CI/travis/make_linux" "$OS_TYPE" +"$CI/travis/make_linux" # need to find this out inside the container . "$CI/travis/lib.sh" -echo "$(get_ldist)" > "/${LIBNAME}/build/.LDIST" +echo "$(get_ldist)" > "${INSIDE_DOCKER_BUILD_DIR}/build/.LDIST" diff -Nru libiio-0.21/CI/travis/lib.sh libiio-0.23/CI/travis/lib.sh --- libiio-0.21/CI/travis/lib.sh 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/lib.sh 2021-08-20 11:01:14.000000000 +0000 @@ -4,12 +4,19 @@ exit 0 fi -export TRAVIS_API_URL="https://api.travis-ci.org" +export TRAVIS_API_URL="https://api.travis-ci.com" LOCAL_BUILD_DIR=${LOCAL_BUILD_DIR:-build} HOMEBREW_NO_INSTALL_CLEANUP=1 export HOMEBREW_NO_INSTALL_CLEANUP +PYTHON=python3 +export PYTHON + +# This needs to be duplicated inside 'inside_docker.sh' +# It's the common convention between host & container +INSIDE_DOCKER_BUILD_DIR=/docker_build_dir + # Add here all the common env-vars that should be propagated # to the docker image, simply by referencing the env-var name. # The values will be evaluated. @@ -19,7 +26,7 @@ # # If these nothing should be passed, then clear or #'unset INSIDE_DOCKER_TRAVIS_CI_ENV' after this script is included -INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_VERSION" +INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_TYPE OS_VERSION" COMMON_SCRIPTS="inside_docker.sh" @@ -42,33 +49,6 @@ fi } -add_python_path() { - echo "adding Python to the path" - if [ -d "$HOME/.pyenv/bin" -a "$(echo "$PATH" | grep .pyenv/bin | wc -c)" -eq "0" ] ; then - echo "adding $HOME/.pyenv/bin to path" - export PATH="$HOME/.pyenv/bin:$PATH" - fi - if [ -z "${PYENV_SHELL}" ] ; then - echo init pyenv - eval "$(pyenv init -)" - fi - if [ -d /opt/pyenv/versions/3.6.3/bin -a "$(echo "$PATH" | grep opt/pyenv/versions | wc -c)" -eq "0" ] ; then - echo adding python on opt to PATH - export PATH="/opt/pyenv/versions/3.6.3/bin:$PATH" - fi - if [ -d /root/.pyenv/versions/3.6.3/bin -a "$(echo "$PATH" | grep root/.pyenv/versions | wc -c)" -eq "0" ] ; then - echo adding python on root/.pyenv to PATH - export PATH="/root/.pyenv/versions/3.6.3/bin:$PATH" - fi - if ! command_exists python ; then - echo No python on path - echo "$PATH" - else - python --version - command -v python - fi -} - get_script_path() { local script="$1" @@ -145,7 +125,7 @@ -H "Travis-API-Version: 3" \ -H "Authorization: token $TRAVIS_API_TOKEN" \ -d "$body" \ - "https://api.travis-ci.org/repo/$repo_slug/requests" + "${TRAVIS_API_URL}/repo/$repo_slug/requests" } trigger_adi_build() { @@ -418,8 +398,15 @@ } prepare_docker_image() { - local DOCKER_IMAGE="$1" - sudo apt-get -qq update + local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}" + # If arch is specified, setup multiarch support + if [ -n "$OS_ARCH" ] ; then + sudo apt-get -qq update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y qemu \ + qemu binfmt-support qemu-user-static + sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}" + fi echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -s devicemapper"' | sudo tee /etc/default/docker > /dev/null sudo service docker restart sudo docker pull "$DOCKER_IMAGE" @@ -430,18 +417,21 @@ for env in $INSIDE_DOCKER_TRAVIS_CI_ENV ; do val="$(eval echo "\$${env}")" if [ -n "$val" ] ; then - echo "export ${env}=${val}" >> "${env_file}" + echo "export ${env}=\"${val}\"" >> "${env_file}" fi done } run_docker_script() { local DOCKER_SCRIPT="$(get_script_path $1)" - local DOCKER_IMAGE="$2" - local OS_TYPE="$3" - local MOUNTPOINT="${4:-docker_build_dir}" + local MOUNTPOINT="${INSIDE_DOCKER_BUILD_DIR}" + local DOCKER_IMAGE="${OS_TYPE}:${OS_VERSION}" + + if [ -n "$OS_ARCH" ] ; then + DOCKER_IMAGE="${OS_ARCH}/${DOCKER_IMAGE}" + fi - __save_env_for_docker "${TRAVIS_BUILD_DIR}" + __save_env_for_docker "$(pwd)" sudo docker run --rm=true \ -v "$(pwd):/${MOUNTPOINT}:rw" \ @@ -452,16 +442,22 @@ ensure_command_exists() { local cmd="$1" local package="$2" + local yes_confirm [ -n "$cmd" ] || return 1 [ -n "$package" ] || package="$cmd" ! command_exists "$cmd" || return 0 # go through known package managers for pacman in apt-get brew yum ; do command_exists $pacman || continue - "$pacman" install -y "$package" || { + if [ "$pacman" = "brew" ] ; then + yes_confirm= + else + yes_confirm="-y" + fi + "$pacman" install $yes_confirm "$package" || { # Try an update if install doesn't work the first time - "$pacman" -y update && \ - "$pacman" install -y "$package" + "$pacman" $yes_confirm update && \ + "$pacman" install $yes_confirm "$package" } return $? done @@ -474,30 +470,48 @@ version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" = "$1"; } get_codename() { - lsb_release -c -s + local VERSION_CODENAME + eval $(grep -w VERSION_CODENAME /etc/os-release) + echo "$VERSION_CODENAME" } get_dist_id() { - lsb_release -i -s + local ID + eval $(grep -w ID /etc/os-release) + echo "$ID" } get_version() { - lsb_release -r -s + local VERSION_ID + eval $(grep -w VERSION_ID /etc/os-release) + echo "$VERSION_ID" } is_ubuntu_at_least_ver() { - [ "$(get_dist_id)" = "Ubuntu" ] || return 1 + [ "$(get_dist_id)" = "ubuntu" ] || return 1 version_ge "$(get_version)" "$1" } is_centos_at_least_ver() { - [ "$(get_dist_id)" = "CentOS" ] || return 1 + [ "$(get_dist_id)" = "centos" ] || return 1 version_ge "$(get_version)" "$1" } +is_python_at_least_ver() { + local out python_exec + + python_exec="$1" + command_exists "$python_exec" || return 1 + out=$($python_exec --version) + version_ge "${out#* }" "$2" +} + is_arm() { [ "$(dpkg --print-architecture)" = "armhf" ] || return 1 - test "$(dpkg --print-architecture)" = "armhf" +} + +is_arm64() { + [ "$(dpkg --print-architecture)" = "arm64" ] || return 1 } print_github_api_rate_limits() { @@ -510,6 +524,29 @@ echo_green '-----------------------------------------' } +setup_build_type_env_vars() { + OS_TYPE=${OS_TYPE:-default} + + # For a 'arm32_v7/debian_docker' string, OS TYPE becomes 'debian' + # This also works for just 'debian_docker' + # And we're extracting OS_ARCH if present + if [ "${OS_TYPE#*_}" = "docker" ] ; then + BUILD_TYPE=generic_docker + OS_TYPE=${OS_TYPE%_*} + OS_ARCH=${OS_TYPE%/*} + OS_TYPE=${OS_TYPE#*/} + if [ "$OS_ARCH" = "$OS_TYPE" ] ; then + OS_ARCH= + fi + else + BUILD_TYPE="$OS_TYPE" + fi + + export OS_TYPE + export OS_ARCH + export BUILD_TYPE +} + ensure_command_exists sudo ensure_command_exists wget diff -Nru libiio-0.21/CI/travis/make_darwin libiio-0.23/CI/travis/make_darwin --- libiio-0.21/CI/travis/make_darwin 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/make_darwin 2021-08-20 11:01:14.000000000 +0000 @@ -1,5 +1,7 @@ #!/bin/sh -e +LIBIIO_BUILD_CONF="-DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=ON" + if [ "x${COVERITY_SCAN_PROJECT_NAME}" != "x" ] ; then exit 0; fi @@ -15,11 +17,16 @@ ls } -cd $TRAVIS_BUILD_DIR/build -build_osx "-DOSX_PACKAGE=ON -DPYTHON_BINDINGS=ON -DWITH_EXAMPLES=ON" +mkdir -p build + +cd build +build_osx "-DOSX_PACKAGE=ON -DPYTHON_BINDINGS=ON -DWITH_EXAMPLES=ON ${LIBIIO_BUILD_CONF}" + +cd .. -cd $TRAVIS_BUILD_DIR/build_tar -build_osx "-DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON" +mkdir -p build_tar +cd build_tar +build_osx "-DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON ${LIBIIO_BUILD_CONF}" echo "### make package" make package echo "### files are" diff -Nru libiio-0.21/CI/travis/make_linux libiio-0.23/CI/travis/make_linux --- libiio-0.21/CI/travis/make_linux 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CI/travis/make_linux 2021-08-20 11:01:14.000000000 +0000 @@ -4,20 +4,26 @@ . CI/travis/lib.sh +INSIDE_DOCKER_TRAVIS_CI_ENV="$INSIDE_DOCKER_TRAVIS_CI_ENV CHECK_AGAINST_KERNEL_HEADER CI_BUILD_SPHINX_DOCS" + handle_default() { echo "### making build dir" mkdir -p build cd build - add_python_path - if command_exists python ; then - command -v python - python --version + if command_exists $PYTHON ; then + command -v $PYTHON + $PYTHON --version PYTHON_HELP="-DPYTHON_BINDINGS=ON \ - -DPYTHON_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \ - -DPYTHON_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \ - -DPYTHON_EXECUTABLE=$(command -v python)" + -DPYTHON_INCLUDE_DIR=$($PYTHON -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \ + -DPYTHON_LIBRARY=$($PYTHON -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \ + -DPYTHON_EXECUTABLE=$(command -v $PYTHON)" + + # Add ~/.local dir to paths; this is where pip installs things (if no sudo) + export PATH="$PATH:$(readlink -f ~/.local/bin/)" + export PYTHONPATH="$(readlink -f ~/.local/lib/python*/site-packages/)" + if command_exists sphinx-build ; then DOC_HELP="-DWITH_DOC=ON" fi @@ -38,12 +44,20 @@ FLAGS="-DENABLE_PACKAGING=ON -DDEB_DETECT_DEPENDENCIES=ON -DWITH_EXAMPLES=ON ${PYTHON_HELP} ${DOC_HELP} ${MAN_HELP}" + # Ubuntu Xenial's libserialport and libzstd are too old + if [ "${OS_VERSION}" = xenial ] ; then + FLAGS="${FLAGS} -DWITH_SERIAL_BACKEND=OFF" + else + FLAGS="${FLAGS} -DWITH_SERIAL_BACKEND=ON -DWITH_ZSTD=ON" + fi + echo "### cmake ${FLAGS}" cmake ${FLAGS} .. if [ -f CMakeFiles/CMakeError.log ] ; then echo "### CMakeError.log" cat CMakeFiles/CMakeError.log + exit 1 fi echo "### make" @@ -86,7 +100,7 @@ cd .. # make sure we are up to date (once) - if [ "$LDIST" = "DO_NOT_DEPLOY" ] ; then + if [ "$CHECK_AGAINST_KERNEL_HEADER" = "1" ] ; then ./CI/travis/check_kernel.sh fi echo "### All done building" @@ -96,24 +110,30 @@ echo "handle centos" mkdir -p build cd build - cmake -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON .. + + FLAGS="-DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=ON" + + # CentOS 7's kernel headers are too old for USB support in IIOD + [ "${OS_VERSION}" = centos7 ] && FLAGS="${FLAGS} -DWITH_IIOD_USBD=OFF" + + cmake ${FLAGS} .. make make package cd .. } -handle_centos_docker() { - run_docker_script inside_docker.sh \ - "centos:centos${OS_VERSION}" "centos" +handle_ubuntu() { + handle_default } -handle_ubuntu_docker() { - run_docker_script inside_docker.sh \ - "ubuntu:${OS_VERSION}" +handle_debian() { + handle_default } -LIBNAME="$1" -OS_TYPE=${2:-default} +handle_generic_docker() { + run_docker_script inside_docker.sh +} -handle_${OS_TYPE} +setup_build_type_env_vars +handle_${BUILD_TYPE} diff -Nru libiio-0.21/cmake/LinuxPackaging.cmake libiio-0.23/cmake/LinuxPackaging.cmake --- libiio-0.21/cmake/LinuxPackaging.cmake 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/cmake/LinuxPackaging.cmake 2021-08-20 11:01:14.000000000 +0000 @@ -7,19 +7,19 @@ set(CPACK_PACKAGE_RELOCATABLE OFF) set(CPACK_GENERATOR ${CPACK_GENERATOR};RPM) set(CPACK_RPM_PACKAGE_REQUIRES "libaio >= 0.3.107, avahi >= 0.6.25, libusb1 >= 1.0.9, libxml2 >= 2.7.6") -endif() -# Add these for CentOS 7 -set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION - /lib - /lib/udev - /lib/udev/rules.d - /usr/sbin - /usr/lib/python2.7 - /usr/lib/python2.7/site-packages - /usr/lib/pkgconfig - /usr/lib64/pkgconfig -) + # Add these for CentOS 7 + set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION + /lib + /lib/udev + /lib/udev/rules.d + /usr/sbin + /usr/lib/python2.7 + /usr/lib/python2.7/site-packages + /usr/lib/pkgconfig + /usr/lib64/pkgconfig + ) +endif() set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) set(CPACK_PACKAGE_VERSION_MAJOR ${LIBIIO_VERSION_MAJOR}) diff -Nru libiio-0.21/CMakeLists.txt libiio-0.23/CMakeLists.txt --- libiio-0.21/CMakeLists.txt 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/CMakeLists.txt 2021-08-20 11:01:14.000000000 +0000 @@ -2,8 +2,12 @@ cmake_minimum_required(VERSION 2.8.7) project(libiio C) +if (MINGW) + set(WIN32 ON) +endif() + set(LIBIIO_VERSION_MAJOR 0) -set(LIBIIO_VERSION_MINOR 21) +set(LIBIIO_VERSION_MINOR 23) set(VERSION "${LIBIIO_VERSION_MAJOR}.${LIBIIO_VERSION_MINOR}") if (WIN32) string(TIMESTAMP BUILD_YEAR "%Y") @@ -33,7 +37,11 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS None Debug Release RelWithDebInfo MinSizeRel) endif() -set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries") +option(BUILD_SHARED_LIBS "Build shared libraries" ON) + +if (NOT BUILD_SHARED_LIBS) + add_definitions(-DLIBIIO_STATIC=1) +endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") option(OSX_PACKAGE "Create a OSX package" ON) @@ -79,6 +87,10 @@ if (HAS_WPEDANTIC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic") endif() + check_c_compiler_flag(-Wshadow HAS_WSHADOW) + if (HAS_WSHADOW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow") + endif() # cmake 2.8 doesn't support C_STANDARD defined in set_target_properties if (${CMAKE_VERSION} VERSION_LESS "3.2") check_c_compiler_flag(-std=c99 HAS_C99) @@ -86,6 +98,16 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") endif() endif() + + # Per http://www.mingw.org/wiki/Use_more_recent_defined_functions + if (MINGW) + # Build for Vista and above + # check mingw-w64-headers/include/w32api.h or windows sdkddkver.h + # https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt + # using a hex value is bad - but stops from loading the otherwise unnecessary headers + set(CMAKE_C_FLAGS "-D_WIN32_WINNT=0x600 ${CMAKE_C_FLAGS}") + set(CMAKE_C_FLAGS "-DWINVER=0x600 ${CMAKE_C_FLAGS}") + endif() elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -Wno-unused-parameter") else() @@ -98,9 +120,6 @@ if(APPLE) #full Single Unix Standard v3 (SUSv3) conformance (the Unix API) add_definitions(-D_DARWIN_C_SOURCE) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE=1") - add_definitions(-D_GNU_SOURCE=1) elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|DragonFly|OpenBSD|NetBSD") set(CMAKE_REQUIRED_DEFINITIONS "-D__BSD_VISIBLE") add_definitions(-D__BSD_VISIBLE=1) @@ -113,29 +132,25 @@ check_symbol_exists(strerror_r "string.h" HAS_STRERROR_R) check_symbol_exists(newlocale "locale.h" HAS_NEWLOCALE) -if (NOT WIN32) - find_library(PTHREAD_LIBRARIES pthread) - set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARIES}) - check_symbol_exists(pthread_setname_np "pthread.h" HAS_PTHREAD_SETNAME_NP) - set(CMAKE_REQUIRED_LIBRARIES) -endif() - option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON) if (ENABLE_IPV6) check_symbol_exists(in6addr_any "netinet/in.h" HAVE_IPV6) if (NOT HAVE_IPV6) - message(WARNING "IPv6 is not available in your system.") + message(SEND_ERROR "IPv6 is not available in your system.") endif() endif() -#Handle FreeBSD libusb and Linux libusb-1.0 libraries -find_library(LIBUSB_LIBRARIES NAMES usb-1.0 usb) -find_path(LIBUSB_INCLUDE_DIR libusb.h PATH_SUFFIXES libusb-1.0) -if (LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIR) - message(STATUS "Looking for libusb-1.0 : Found") - option(WITH_USB_BACKEND "Enable the libusb backend" ON) +option(WITH_USB_BACKEND "Enable the libusb backend" ON) +if (WITH_USB_BACKEND) + #Handle FreeBSD libusb and Linux libusb-1.0 libraries + find_library(LIBUSB_LIBRARIES NAMES usb-1.0 usb) + find_path(LIBUSB_INCLUDE_DIR libusb.h PATH_SUFFIXES libusb-1.0) + if (NOT LIBUSB_LIBRARIES OR NOT LIBUSB_INCLUDE_DIR) + message(SEND_ERROR "Unable to find libusb-1.0 dependency.\n" + "If you want to disable the USB backend, set WITH_USB_BACKEND=OFF.") + else() + message(STATUS "Looking for libusb-1.0 : Found") - if(WITH_USB_BACKEND) set(IIOD_CLIENT 1) set(NEED_LIBXML2 1) set(NEED_THREADS 1) @@ -146,13 +161,10 @@ set(TEMP1 ${CMAKE_REQUIRED_INCLUDES}) list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBUSB_LIBRARIES}) list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBUSB_INCLUDE_DIR}) - check_symbol_exists(libusb_get_version libusb.h - HAS_LIBUSB_GETVERSION) + check_symbol_exists(libusb_get_version libusb.h HAS_LIBUSB_GETVERSION) set(CMAKE_REQUIRED_LIBRARIES ${TEMP}) - set(CMAKE_REQUIRED_INCLUDES ${TEMP1}) + set(CMAKE_REQUIRED_INCLUDES ${TEMP1}) endif() -else() - message(STATUS "Looking for libusb-1.0 : Failed; building without usb") endif() # make sure all check_symbol_exists are before this point, otherwise they fail @@ -238,33 +250,46 @@ endif() endif() -find_library(LIBSERIALPORT_LIBRARIES serialport) -find_path(LIBSERIALPORT_INCLUDE_DIR libserialport.h) -if (LIBSERIALPORT_LIBRARIES AND LIBSERIALPORT_INCLUDE_DIR) - option(WITH_SERIAL_BACKEND "Enable the serial backend" ON) +option(WITH_SERIAL_BACKEND "Enable the serial backend" OFF) +if (WITH_SERIAL_BACKEND) + find_library(LIBSERIALPORT_LIBRARIES serialport) + find_path(LIBSERIALPORT_INCLUDE_DIR libserialport.h) + if (NOT LIBSERIALPORT_LIBRARIES OR NOT LIBSERIALPORT_INCLUDE_DIR) + message(SEND_ERROR "Unable to find libserialport dependency.\n") + else() + message(STATUS "Looking for libserialport : Found") - if (WITH_SERIAL_BACKEND) file(STRINGS ${LIBSERIALPORT_INCLUDE_DIR}/libserialport.h LIBSERIALPORT_VERSION_STR REGEX "SP_PACKAGE_VERSION_STRING") string(REGEX REPLACE "#define SP_PACKAGE_VERSION_STRING \"(.*)\"" "\\1" LIBSERIALPORT_VERSION ${LIBSERIALPORT_VERSION_STR}) if ("${LIBSERIALPORT_VERSION}" VERSION_LESS 0.1.1) - message(WARNING "The installed version of libserialport is too old. The minimum version supported is 0.1.1. Disabling Serial support.") - SET(WITH_SERIAL_BACKEND OFF) - else() - message(STATUS "Looking for libserialport : Found") - list(APPEND LIBIIO_CFILES serial.c) - list(APPEND LIBS_TO_LINK ${LIBSERIALPORT_LIBRARIES}) - - set(NEED_THREADS 1) - set(IIOD_CLIENT 1) - set(NEED_LIBXML2 1) - - include_directories(${LIBSERIALPORT_INCLUDE_DIR}) + message(SEND_ERROR "The installed version of libserialport is too old. The minimum version supported is 0.1.1.") endif() + + list(APPEND LIBIIO_CFILES serial.c) + list(APPEND LIBS_TO_LINK ${LIBSERIALPORT_LIBRARIES}) + + set(NEED_THREADS 1) + set(IIOD_CLIENT 1) + set(NEED_LIBXML2 1) + + include_directories(${LIBSERIALPORT_INCLUDE_DIR}) endif() -else() - message(STATUS "Looking for libserialport : Failed; building without serial") endif() +option(WITH_ZSTD "Support for ZSTD compressed metadata" OFF) +if (WITH_ZSTD) + find_library(LIBZSTD_LIBRARIES zstd) + find_path(LIBZSTD_INCLUDE_DIR zstd.h) + + if (NOT LIBZSTD_LIBRARIES OR NOT LIBZSTD_INCLUDE_DIR) + message(SEND_ERROR "Unable to find libzstd dependency.\n" + "If you want to disable ZSTD compression support, set WITH_ZSTD=OFF.") + endif() + + list(APPEND LIBS_TO_LINK ${LIBZSTD_LIBRARIES}) + include_directories(${LIBZSTD_INCLUDE_DIR}) +endif (WITH_ZSTD) + include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) if(WITH_NETWORK_BACKEND) @@ -274,51 +299,67 @@ endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - include(CheckCSourceCompiles) - check_c_source_compiles("#include \nint main(void) { return O_TMPFILE; }" HAS_O_TMPFILE) - - if (HAS_O_TMPFILE) - option(WITH_NETWORK_GET_BUFFER "Enable experimental zero-copy transfers" OFF) - endif(HAS_O_TMPFILE) + option(WITH_NETWORK_GET_BUFFER "Enable experimental zero-copy transfers" OFF) + if (WITH_NETWORK_GET_BUFFER) + include(CheckCSourceCompiles) + check_c_source_compiles("#define _GNU_SOURCE=1\n#include \nint main(void) { return O_TMPFILE; }" + HAS_O_TMPFILE) + + if (NOT HAS_O_TMPFILE) + message(SEND_ERROR "Zero-copy requires the O_TMPFILE flag, which is not available on the system.") + endif() + endif() - check_c_source_compiles("#include \nint main(void) { return eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); }" WITH_NETWORK_EVENTFD) - endif() + check_c_source_compiles("#include \nint main(void) { return eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); }" + WITH_NETWORK_EVENTFD) + if (NOT WITH_NETWORK_EVENTFD) + check_c_source_compiles("#define _GNU_SOURCE=1\n#include \n#include \nint main(void) { int fd[2]; return pipe2(fd, O_CLOEXEC | O_NONBLOCK); }" + HAS_PIPE2) + endif() - if(NOT WIN32) - include(CheckCSourceCompiles) - check_c_source_compiles("#include \n#include \nint main(void) { int fd[2]; return pipe2(fd, O_CLOEXEC | O_NONBLOCK); }" HAS_PIPE2) + if (WITH_NETWORK_GET_BUFFER OR HAS_PIPE2) + add_definitions(-D_GNU_SOURCE=1) + endif() endif() list(APPEND LIBIIO_CFILES network.c) + if (WIN32) + list(APPEND LIBIIO_CFILES network-windows.c) + else() + list(APPEND LIBIIO_CFILES network-unix.c) + endif() - find_library(AVAHI_CLIENT_LIBRARIES avahi-client) - find_library(AVAHI_COMMON_LIBRARIES avahi-common) - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + option(HAVE_DNS_SD "Enable DNS-SD (ZeroConf) support" ON) + if (NOT HAVE_DNS_SD) + message(STATUS "Building without DNS-SD (ZeroConf) support") + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") find_library(CORE_SERVICES CoreServices) message(STATUS "Building with CFNetServices, an Apple DNS SD implementation") - set(HAVE_DNS_SD ON) list(APPEND LIBIIO_CFILES dns_sd_bonjour.c dns_sd.c) list(APPEND LIBS_TO_LINK ${CORE_SERVICES} ) - elseif(AVAHI_CLIENT_LIBRARIES AND AVAHI_COMMON_LIBRARIES) - message(STATUS "Building with Avahi, a DNS SD implementation") - set(HAVE_DNS_SD ON) - set(HAVE_AVAHI ON) - - list(APPEND LIBIIO_CFILES dns_sd_avahi.c dns_sd.c) - set(AVAHI_LIBRARIES ${AVAHI_CLIENT_LIBRARIES} ${AVAHI_COMMON_LIBRARIES}) - list(APPEND LIBS_TO_LINK ${AVAHI_LIBRARIES}) elseif(WIN32) - set(HAVE_DNS_SD ON) list(APPEND LIBIIO_CFILES dns_sd_windows.c dns_sd.c) if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(dns_sd_windows.c PROPERTIES COMPILE_FLAGS "-Wno-unused-function") endif() message(STATUS "Building with mdns, A Public domain mDNS/DNS-SD library in C ") else() - message(STATUS "Building without DNS-SD (Zeroconf) support") + find_library(AVAHI_CLIENT_LIBRARIES avahi-client) + find_library(AVAHI_COMMON_LIBRARIES avahi-common) + if (NOT AVAHI_CLIENT_LIBRARIES OR NOT AVAHI_COMMON_LIBRARIES) + message(SEND_ERROR "Unable to find libavahi-common / libavahi-client dependencies.\n" + "If you want to disable DNS-SD (ZeroConf) support, set HAVE_DNS_SD=OFF.") + endif() + + message(STATUS "Building with Avahi, a DNS-SD (ZeroConf) implementation") + set(HAVE_AVAHI ON) + + list(APPEND LIBIIO_CFILES dns_sd_avahi.c dns_sd.c) + set(AVAHI_LIBRARIES ${AVAHI_CLIENT_LIBRARIES} ${AVAHI_COMMON_LIBRARIES}) + list(APPEND LIBS_TO_LINK ${AVAHI_LIBRARIES}) endif() set(NEED_THREADS 1) @@ -326,44 +367,50 @@ set(NEED_LIBXML2 1) else() message(STATUS "Building without network support") + set(HAVE_DNS_SD OFF) endif() -# Since libxml2-2.9.2, libxml2 provides its own LibXml2-config.cmake, with all -# variables correctly set. -# So, try first to find the CMake module provided by libxml2 package, then fallback -# on the CMake's FindLibXml2.cmake module (which can lack some definition, especially -# in static build case). -find_package(LibXml2 QUIET NO_MODULE) -if(DEFINED LIBXML2_VERSION_STRING) - set(LIBXML2_FOUND ON) - set(LIBXML2_INCLUDE_DIR ${LIBXML2_INCLUDE_DIRS}) -else() - include(FindLibXml2) -endif() - -if (LIBXML2_FOUND) - option(WITH_XML_BACKEND "Enable the XML backend" ON) - if (WITH_XML_BACKEND) - list(APPEND LIBIIO_CFILES xml.c) +option(WITH_XML_BACKEND "Enable the XML backend" ON) +if (WITH_XML_BACKEND) + # Since libxml2-2.9.2, libxml2 provides its own LibXml2-config.cmake, with all + # variables correctly set. + # So, try first to find the CMake module provided by libxml2 package, then fallback + # on the CMake's FindLibXml2.cmake module (which can lack some definition, especially + # in static build case). + find_package(LibXml2 QUIET NO_MODULE) + if(DEFINED LIBXML2_VERSION_STRING) + set(LIBXML2_FOUND ON) + set(LIBXML2_INCLUDE_DIR ${LIBXML2_INCLUDE_DIRS}) + else() + include(FindLibXml2) + endif() - include_directories(${LIBXML2_INCLUDE_DIR}) - list(APPEND LIBS_TO_LINK ${LIBXML2_LIBRARIES}) + if (NOT LIBXML2_FOUND) + message(SEND_ERROR "Unable to find libxml2 dependency.\n" + "If you want to disable the XML backend, set WITH_XML_BACKEND=OFF.") endif() -endif() -if (NEED_LIBXML2 AND NOT (LIBXML2_FOUND AND WITH_XML_BACKEND)) - message(SEND_ERROR "The selected backends require libxml2 and the XML backend to be enabled") + list(APPEND LIBIIO_CFILES xml.c) + + include_directories(${LIBXML2_INCLUDE_DIR}) + list(APPEND LIBS_TO_LINK ${LIBXML2_LIBRARIES}) +elseif(NEED_LIBXML2) + message(SEND_ERROR "Enabled backends require the XML backend to be enabled as well.\n" + "If you want to enable the XML backend, set WITH_XML_BACKEND=ON.") endif() +option(NO_THREADS "Disable multi-threading support" OFF) if (NEED_THREADS) - if (NOT WIN32) - if (PTHREAD_LIBRARIES) - list(APPEND LIBS_TO_LINK ${PTHREAD_LIBRARIES}) - else() - message(WARNING "pthread library not found; support for threads will be disabled") - set(NO_THREADS ON) + if (NOT NO_THREADS AND NOT WIN32 AND NOT ANDROID) + find_library(PTHREAD_LIBRARIES pthread) + + if (NOT PTHREAD_LIBRARIES) + message(SEND_ERROR "Unable to find pthread dependency.\n" + "If you want to disable multi-threading support, set NO_THREADS=ON.") endif() + + list(APPEND LIBS_TO_LINK ${PTHREAD_LIBRARIES}) endif() list(APPEND LIBIIO_CFILES lock.c) @@ -498,13 +545,15 @@ DOC "OSX Package builder (productbuild)") mark_as_advanced(PRODUCTBUILD_EXECUTABLE) + set(COPY_TOOLS_COMMAND) foreach(_tool ${IIO_TESTS_TARGETS}) - list(APPEND IIO_TESTS $) + list(APPEND COPY_TOOLS_COMMAND + COMMAND ${CMAKE_COMMAND} -E copy $ ${LIBIIO_FRAMEWORK_DIR}/Tools) endforeach() add_custom_command(OUTPUT ${LIBIIO_PKG} COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBIIO_FRAMEWORK_DIR}/Tools - COMMAND ${CMAKE_COMMAND} -E copy ${IIO_TESTS} ${LIBIIO_FRAMEWORK_DIR}/Tools + ${COPY_TOOLS_COMMAND} COMMAND ${PKGBUILD_EXECUTABLE} --component ${LIBIIO_FRAMEWORK_DIR} --identifier com.adi.iio --version ${VERSION} @@ -535,8 +584,8 @@ set(UPSTART_CONF_INSTALL_DIR /etc/init CACHE PATH "default install path for upstart conf files") if (NOT PTHREAD_LIBRARIES) - message(WARNING "IIOD requires threads support; disabling") - set(WITH_IIOD OFF CACHE BOOL "" FORCE) + message(SEND_ERROR "IIOD requires pthread support\n." + "If you want to disable IIOD, set WITH_IIOD=OFF.") else() add_subdirectory(iiod) endif() diff -Nru libiio-0.21/context.c libiio-0.23/context.c --- libiio-0.21/context.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/context.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// 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 - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-config.h" @@ -34,9 +24,10 @@ "" "" "" -"" +"" "" -"" +"" "" "" "" @@ -44,144 +35,208 @@ "" "]>"; -/* Returns a string containing the XML representation of this context */ -char * iio_context_create_xml(const struct iio_context *ctx) +static ssize_t sanitize_xml(char *ptr, ssize_t len, const char *str) { - ssize_t len; - size_t *devices_len = NULL; - char *str, *ptr, *eptr, **devices = NULL; - char ** ctx_attrs, **ctx_values; - unsigned int i; + ssize_t count = 0; + ssize_t ret; - len = sizeof(xml_header) - 1; - len += strnlen(ctx->name, MAX_CTX_NAME); - len += sizeof("") - 1; + for (; *str; str++) { + switch(*str) { + case '&': + ret = iio_snprintf(ptr, len, "%s", "&"); + break; + case '<': + ret = iio_snprintf(ptr, len, "%s", "<"); + break; + case '>': + ret = iio_snprintf(ptr, len, "%s", ">"); + break; + case '\'': + ret = iio_snprintf(ptr, len, "%s", "'"); + break; + case '"': + ret = iio_snprintf(ptr, len, "%s", """); + break; + default: + ret = iio_snprintf(ptr, len, "%c", *str); + break; + } - if (ctx->description) { - len += strnlen(ctx->description, MAX_CTX_DESC); - len += sizeof(" description=\"\"") - 1; - } + if (ret < 0) + return ret; - ctx_attrs = calloc(ctx->nb_attrs, sizeof(*ctx->attrs)); - if (!ctx_attrs) { - errno = ENOMEM; - return NULL; + iio_update_xml_indexes(ret, &ptr, &len, &count); } - ctx_values = calloc(ctx->nb_attrs, sizeof(*ctx->values)); - if (!ctx_values) { - errno = ENOMEM; - goto err_free_ctx_attrs; + + return count; +} + +ssize_t iio_xml_print_and_sanitized_param(char *ptr, ssize_t len, + const char *before, char *param, + const char *after) +{ + ssize_t ret, alen = 0; + + /* Print before */ + ret = iio_snprintf(ptr, len, "%s", before); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); + + /* Print param */ + ret = sanitize_xml(ptr, len, param); + if (ret < 0) + return ret; + iio_update_xml_indexes(ret, &ptr, &len, &alen); + + /* Print after */ + ret = iio_snprintf(ptr, len, "%s", after); + if (ret < 0) + return ret; + + return alen + ret; +} + +static ssize_t iio_snprintf_context_xml(char *ptr, ssize_t len, + const struct iio_context *ctx) +{ + ssize_t ret, alen = 0; + unsigned int i, major, minor; + char git_tag[64]; + + ret = iio_context_get_version(ctx, &major, &minor, git_tag); + if (ret < 0) + return ret; + + ret = iio_snprintf(ptr, len, + "%sname, major, minor, git_tag); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); + + if (ctx->description) { + ret = iio_xml_print_and_sanitized_param(ptr, len, + "description=\"", + ctx->description, + "\" >"); + } else { + ret = iio_snprintf(ptr, len, ">"); } + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); for (i = 0; i < ctx->nb_attrs; i++) { - ctx_attrs[i] = encode_xml_ndup(ctx->attrs[i]); - ctx_values[i] = encode_xml_ndup(ctx->values[i]); - if (!ctx_attrs[i] || !ctx_values[i]) - goto err_free_ctx_attrs_values; - - len += strnlen(ctx_attrs[i], MAX_ATTR_NAME); - len += strnlen(ctx_values[i], MAX_ATTR_VALUE); - len += sizeof("") - 1; + ret = iio_snprintf(ptr, len, + "attrs[i]); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); + + ret = iio_xml_print_and_sanitized_param(ptr, len, + "value=\"", + ctx->values[i], + "\" />"); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - if (ctx->nb_devices) { - devices_len = malloc(ctx->nb_devices * sizeof(*devices_len)); - if (!devices_len) { - errno = ENOMEM; - goto err_free_ctx_attrs_values; - } + for (i = 0; i < ctx->nb_devices; i++) { + ret = iio_snprintf_device_xml(ptr, len, ctx->devices[i]); + if (ret < 0) + return ret; - devices = calloc(ctx->nb_devices, sizeof(*devices)); - if (!devices) - goto err_free_devices_len; - - for (i = 0; i < ctx->nb_devices; i++) { - char *xml = iio_device_get_xml(ctx->devices[i], - &devices_len[i]); - if (!xml) - goto err_free_devices; - devices[i] = xml; - len += devices_len[i]; - } + iio_update_xml_indexes(ret, &ptr, &len, &alen); } + ret = iio_snprintf(ptr, len, ""); + if (ret < 0) + return ret; + + return alen + ret; +} + +/* Returns a string containing the XML representation of this context */ +static char * iio_context_create_xml(const struct iio_context *ctx) +{ + ssize_t len; + char *str; + + len = iio_snprintf_context_xml(NULL, 0, ctx); + if (len < 0) + return ERR_PTR((int) len); + len++; /* room for terminating NULL */ str = malloc(len); - if (!str) { - errno = ENOMEM; - goto err_free_devices; - } - eptr = str + len; - ptr = str; + if (!str) + return ERR_PTR(-ENOMEM); - if (len > 0) { - if (ctx->description) { - ptr += iio_snprintf(str, len, "%s", - xml_header, ctx->name, ctx->description); - } else { - ptr += iio_snprintf(str, len, "%s", - xml_header, ctx->name); - } - len = eptr - ptr; + len = iio_snprintf_context_xml(str, len, ctx); + if (len < 0) { + free(str); + return ERR_PTR((int) len); } - for (i = 0; i < ctx->nb_attrs && len > 0; i++) { - ptr += iio_snprintf(ptr, len, "", - ctx_attrs[i], ctx_values[i]); - free(ctx_attrs[i]); - free(ctx_values[i]); - len = eptr - ptr; - } + return str; +} - free(ctx_attrs); - free(ctx_values); +struct iio_context * iio_context_create_from_backend( + const struct iio_backend *backend, + const char *description) +{ + struct iio_context *ctx; + int ret; - for (i = 0; i < ctx->nb_devices; i++) { - if (len > (ssize_t) devices_len[i]) { - memcpy(ptr, devices[i], devices_len[i]); /* Flawfinder: ignore */ - ptr += devices_len[i]; - len -= devices_len[i]; - } - free(devices[i]); + if (!backend) { + errno = EINVAL; + return NULL; } - free(devices); - free(devices_len); + ctx = zalloc(sizeof(*ctx)); + if (!ctx) { + errno = ENOMEM; + return NULL; + } - if (len > 0) { - ptr += iio_strlcpy(ptr, "", len); - len -= sizeof("") - 1; + ret = -ENOMEM; + if (backend->sizeof_context_pdata) { + ctx->pdata = zalloc(backend->sizeof_context_pdata); + if (!ctx->pdata) + goto err_free_ctx; } - if (len != 1) { - IIO_ERROR("Internal libIIO error: iio_context_create_xml str length issue\n"); - free(str); - return NULL; + if (description) { + ctx->description = iio_strdup(description); + if (!ctx->description) + goto err_free_pdata; } - return str; + ctx->name = backend->name; + ctx->ops = backend->ops; -err_free_devices: - for (i = 0; i < ctx->nb_devices; i++) - free(devices[i]); - free(devices); -err_free_devices_len: - free(devices_len); -err_free_ctx_attrs_values: - for (i = 0; i < ctx->nb_attrs; i++) { - if (ctx_attrs[i]) - free(ctx_attrs[i]); - if (ctx_values[i]) - free(ctx_values[i]); - } + return ctx; - free(ctx_values); -err_free_ctx_attrs: - free(ctx_attrs); +err_free_pdata: + free(ctx->pdata); +err_free_ctx: + free(ctx); + errno = -ret; return NULL; } +struct iio_context_pdata * iio_context_get_pdata(const struct iio_context *ctx) +{ + return ctx->pdata; +} + const char * iio_context_get_xml(const struct iio_context *ctx) { return ctx->xml; @@ -210,18 +265,15 @@ free(ctx->attrs[i]); free(ctx->values[i]); } - if (ctx->nb_attrs) { - free(ctx->attrs); - free(ctx->values); - } + free(ctx->attrs); + free(ctx->values); for (i = 0; i < ctx->nb_devices; i++) free_device(ctx->devices[i]); - if (ctx->nb_devices) - free(ctx->devices); - if (ctx->xml) - free(ctx->xml); - if (ctx->description) - free(ctx->description); + free(ctx->devices); + free(ctx->xml); + free(ctx->description); + free(ctx->git_tag); + free(ctx->pdata); free(ctx); } @@ -246,7 +298,8 @@ for (i = 0; i < ctx->nb_devices; i++) { struct iio_device *dev = ctx->devices[i]; if (!strcmp(dev->id, name) || - (dev->name && !strcmp(dev->name, name))) + (dev->label && !strcmp(dev->label, name)) || + (dev->name && !strcmp(dev->name, name))) return dev; } return NULL; @@ -292,8 +345,8 @@ if (!ctx->xml) { ctx->xml = iio_context_create_xml(ctx); - if (!ctx->xml) - return -ENOMEM; + if (IS_ERR(ctx->xml)) + return PTR_ERR(ctx->xml); } return 0; @@ -302,6 +355,17 @@ int iio_context_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8]) { + if (ctx->git_tag) { + if (major) + *major = ctx->major; + if (minor) + *minor = ctx->minor; + if (git_tag) + iio_strlcpy(git_tag, ctx->git_tag, 8); + + return 0; + } + if (ctx->ops->get_version) return ctx->ops->get_version(ctx, major, minor, git_tag); @@ -329,30 +393,20 @@ struct iio_context * iio_create_context_from_uri(const char *uri) { -#ifdef WITH_LOCAL_BACKEND - if (strcmp(uri, "local:") == 0) /* No address part */ + if (WITH_LOCAL_BACKEND && strcmp(uri, "local:") == 0) /* No address part */ return iio_create_local_context(); -#endif -#ifdef WITH_XML_BACKEND - if (strncmp(uri, "xml:", sizeof("xml:") - 1) == 0) + if (WITH_XML_BACKEND && strncmp(uri, "xml:", sizeof("xml:") - 1) == 0) return iio_create_xml_context(uri + sizeof("xml:") - 1); -#endif -#ifdef WITH_NETWORK_BACKEND - if (strncmp(uri, "ip:", sizeof("ip:") - 1) == 0) + if (WITH_NETWORK_BACKEND && strncmp(uri, "ip:", sizeof("ip:") - 1) == 0) return iio_create_network_context(uri+3); -#endif -#ifdef WITH_USB_BACKEND - if (strncmp(uri, "usb:", sizeof("usb:") - 1) == 0) + if (WITH_USB_BACKEND && strncmp(uri, "usb:", sizeof("usb:") - 1) == 0) return usb_create_context_from_uri(uri); -#endif -#ifdef WITH_SERIAL_BACKEND - if (strncmp(uri, "serial:", sizeof("serial:") - 1) == 0) + if (WITH_SERIAL_BACKEND && strncmp(uri, "serial:", sizeof("serial:") - 1) == 0) return serial_create_context_from_uri(uri); -#endif errno = ENOSYS; return NULL; @@ -374,42 +428,38 @@ struct iio_context * iio_create_local_context(void) { -#ifdef WITH_LOCAL_BACKEND - return local_create_context(); -#else + if (WITH_LOCAL_BACKEND) + return local_create_context(); + errno = ENOSYS; return NULL; -#endif } struct iio_context * iio_create_network_context(const char *hostname) { -#ifdef WITH_NETWORK_BACKEND - return network_create_context(hostname); -#else + if (WITH_NETWORK_BACKEND) + return network_create_context(hostname); + errno = ENOSYS; return NULL; -#endif } struct iio_context * iio_create_xml_context_mem(const char *xml, size_t len) { -#ifdef WITH_XML_BACKEND - return xml_create_context_mem(xml, len); -#else + if (WITH_XML_BACKEND) + return xml_create_context_mem(xml, len); + errno = ENOSYS; return NULL; -#endif } struct iio_context * iio_create_xml_context(const char *xml_file) { -#ifdef WITH_XML_BACKEND - return xml_create_context(xml_file); -#else + if (WITH_XML_BACKEND) + return xml_create_context(xml_file); + errno = ENOSYS; return NULL; -#endif } unsigned int iio_context_get_attrs_count(const struct iio_context *ctx) @@ -443,6 +493,22 @@ return NULL; } +int iio_context_add_device(struct iio_context *ctx, struct iio_device *dev) +{ + struct iio_device **devices = realloc(ctx->devices, + (ctx->nb_devices + 1) * sizeof(struct iio_device *)); + + if (!devices) { + IIO_ERROR("Unable to allocate memory\n"); + return -ENOMEM; + } + + devices[ctx->nb_devices++] = dev; + ctx->devices = devices; + IIO_DEBUG("Added device \'%s\' to context \'%s\'\n", dev->id, ctx->name); + return 0; +} + int iio_context_add_attr(struct iio_context *ctx, const char *key, const char *value) { diff -Nru libiio-0.21/debian/changelog libiio-0.23/debian/changelog --- libiio-0.21/debian/changelog 2020-11-19 19:19:11.000000000 +0000 +++ libiio-0.23/debian/changelog 2021-11-28 00:41:07.000000000 +0000 @@ -1,8 +1,15 @@ -libiio (0.21-2build1) hirsute; urgency=medium +libiio (0.23-2) unstable; urgency=medium - * No-change rebuild to build with python3.9 as default. + * update to v0.23-26-gfbf5adb2 - -- Matthias Klose Thu, 19 Nov 2020 20:19:11 +0100 + -- A. Maitland Bottoms Sat, 27 Nov 2021 19:41:07 -0500 + +libiio (0.23-1) experimental; urgency=medium + + * New upstream release + * update to v0.23-19-g4e574547 + + -- A. Maitland Bottoms Tue, 09 Nov 2021 21:56:32 -0500 libiio (0.21-2) unstable; urgency=medium diff -Nru libiio-0.21/debian/control libiio-0.23/debian/control --- libiio-0.21/debian/control 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/control 2021-11-10 03:45:46.000000000 +0000 @@ -23,7 +23,7 @@ python3-setuptools, python3-sphinx, python3-sphinx-rtd-theme -Standards-Version: 4.5.0 +Standards-Version: 4.6.0 Rules-Requires-Root: no Homepage: https://github.com/analogdevicesinc/libiio Vcs-Browser: https://salsa.debian.org/debian/libiio @@ -93,7 +93,7 @@ Section: doc Architecture: all Multi-Arch: foreign -Depends: libjs-jquery, ${misc:Depends} +Depends: libjs-sphinxdoc, libjs-jquery, libjs-underscore, ${misc:Depends} Description: libiio documentation Libiio is a library that has been conceived to ease the development of applications interfacing Industrial Input/Output (IIO) devices through diff -Nru libiio-0.21/debian/copyright libiio-0.23/debian/copyright --- libiio-0.21/debian/copyright 2020-09-12 00:33:24.000000000 +0000 +++ libiio-0.23/debian/copyright 2021-11-10 02:55:27.000000000 +0000 @@ -3,10 +3,10 @@ Upstream-Contact: Robin Getz , Travis Collins , Paul Cercueil Source: https://github.com/analogdevicesinc/libiio/ - git archive --format=tar --prefix=libiio-0.21/ v0.21 | xz > ../../libiio_0.21.orig.tar.xz + git archive --format=tar --prefix=libiio-0.23/ v0.23 | xz > ../../libiio_0.23.orig.tar.xz Files: * -Copyright: 2015-2020, Analog Devices Inc. +Copyright: 2015-2021, Analog Devices Inc. License: LGPL-2.1+ 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 diff -Nru libiio-0.21/debian/libiio0-doc.doc-base libiio-0.23/debian/libiio0-doc.doc-base --- libiio-0.21/debian/libiio0-doc.doc-base 2020-09-12 01:35:33.000000000 +0000 +++ libiio-0.23/debian/libiio0-doc.doc-base 2021-11-10 03:21:35.000000000 +0000 @@ -4,5 +4,5 @@ Section: Programming Format: HTML -Index: /usr/share/doc/libiio0-doc/v0.21/libiio/index.html -Files: /usr/share/doc/libiio0-doc/v0.21/libiio/* +Index: /usr/share/doc/libiio0-doc/v0.23/libiio/index.html +Files: /usr/share/doc/libiio0-doc/v0.23/libiio/* diff -Nru libiio-0.21/debian/patches/0001-bindings-python-fix-ctypes-null-pointer-check.patch libiio-0.23/debian/patches/0001-bindings-python-fix-ctypes-null-pointer-check.patch --- libiio-0.21/debian/patches/0001-bindings-python-fix-ctypes-null-pointer-check.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0001-bindings-python-fix-ctypes-null-pointer-check.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,35 @@ +From 1e253132cc8de98df191a8da80d26b19f7437b40 Mon Sep 17 00:00:00 2001 +From: Matt Thomas <332011+mattypiper@users.noreply.github.com> +Date: Thu, 26 Aug 2021 13:20:48 -0400 +Subject: [PATCH 01/26] bindings/python: fix ctypes null pointer check + +Signed-off-by: Matt Thomas +--- + bindings/python/iio.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/bindings/python/iio.py b/bindings/python/iio.py +index 76a7e33b..5b03cf97 100644 +--- a/bindings/python/iio.py ++++ b/bindings/python/iio.py +@@ -1195,7 +1195,7 @@ class _DeviceOrTrigger(object): + The IIO Device + """ + chn = _d_find_channel(self._device, name_or_id.encode("ascii"), is_output) +- return None if chn is None else Channel(self, chn) ++ return None if bool(chn) is False else Channel(self, chn) + + def set_kernel_buffers_count(self, count): + """ +@@ -1411,7 +1411,7 @@ class Context(object): + The IIO Device + """ + dev = _find_device(self._context, name_or_id_or_label.encode("ascii")) +- return None if dev is None else Trigger(self, dev) if _d_is_trigger(dev) else Device(self, dev) ++ return None if bool(dev) is False else Trigger(self, dev) if _d_is_trigger(dev) else Device(self, dev) + + name = property( + lambda self: self._name, None, None, "Name of this IIO context.\n\ttype=str" +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0001-Use-https-for-download-links-in-README.md.patch libiio-0.23/debian/patches/0001-Use-https-for-download-links-in-README.md.patch --- libiio-0.21/debian/patches/0001-Use-https-for-download-links-in-README.md.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0001-Use-https-for-download-links-in-README.md.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -From 7af0f86efad2b3ecee76b951465a2a23f426cee2 Mon Sep 17 00:00:00 2001 -From: Martin Spiessl -Date: Thu, 4 Jun 2020 19:03:18 +0200 -Subject: [PATCH 01/53] Use https for download links in README.md - -The changes in this commit can be reproduced by the following command: -sed -i "s|\(http\)\(://swdownloads\)|\1s\2|g" README.md -This adds an "s" after http for every occurrence of http://swdownloads. - -Signed-off-by: Martin Spiessl ---- - README.md | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/README.md b/README.md -index 9f23653..1aaf523 100644 ---- a/README.md -+++ b/README.md -@@ -26,15 +26,15 @@ As with many open source packages, we use [GitHub](https://github.com/analogdevi - | Operating System | GitHub master status | Version | Primary Installer Package | Alternative Package, tarball or zip | - |:-----------------------:|:---------------------:|:-------:|:-------------------:|:--------------:| - | Windows | [![Windows Status](https://ci.appveyor.com/api/projects/status/github/analogdevicesinc/libiio?svg=true)](https://ci.appveyor.com/project/analogdevicesinc/libiio/branch/master) | Windows 10
Windows 8.1
Windows 8
Windows 7 | [![Latest Windows installer](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/win_box.png)](https://ci.appveyor.com/api/projects/analogdevicesinc/libiio/artifacts/libiio-setup.exe?branch=master) | [![Latest Windows zip](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/win_box.png)](https://ci.appveyor.com/api/projects/analogdevicesinc/libiio/artifacts/libiio.zip?branch=master) | --| OS X | [![OSX Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=osx&passingTex=foo)](https://travis-ci.org/analogdevicesinc/libiio) | OS X Mojave
(v 10.14) | [![OS-X package 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.pkg) | [![OS-X tarball 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.tar.gz) | --| | | OS X High Sierra
(v 10.13) | [![OS-X package 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.pkg) | [![OS-X tarball 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.tar.gz) | --| | | macOS Sierra
(v 10.12) | [![OS-X package 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.pkg) | [![OS-X tarball 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.tar.gz) | --| Linux | [![Linux Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=linux)](https://travis-ci.org/analogdevicesinc/libiio) | Ubuntu Bionic Beaver
(v 18.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.rpm) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.tar.gz) | --| | | Ubuntu Xenial Xerus
(v 16.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.tar.gz) | --| | | Raspbian Stretch
(v 9) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.tar.gz) | --| | | Raspbian Jessie
(v 8) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.tar.gz) | --| | | CentOS 7 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.tar.gz) | --| | | CentOS 6 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.tar.gz) | -+| OS X | [![OSX Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=osx&passingTex=foo)](https://travis-ci.org/analogdevicesinc/libiio) | OS X Mojave
(v 10.14) | [![OS-X package 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.pkg) | [![OS-X tarball 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.tar.gz) | -+| | | OS X High Sierra
(v 10.13) | [![OS-X package 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.pkg) | [![OS-X tarball 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.tar.gz) | -+| | | macOS Sierra
(v 10.12) | [![OS-X package 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.pkg) | [![OS-X tarball 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.tar.gz) | -+| Linux | [![Linux Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=linux)](https://travis-ci.org/analogdevicesinc/libiio) | Ubuntu Bionic Beaver
(v 18.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.rpm) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.tar.gz) | -+| | | Ubuntu Xenial Xerus
(v 16.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.tar.gz) | -+| | | Raspbian Stretch
(v 9) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.tar.gz) | -+| | | Raspbian Jessie
(v 8) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.tar.gz) | -+| | | CentOS 7 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.tar.gz) | -+| | | CentOS 6 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.tar.gz) | - - If you use it, and like it - please let us know. If you use it, and hate it - please let us know that too. The goal of the project is to try to make Linux IIO devices easier to use on a variety of platforms. If we aren't doing that - we will try to make it better. - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0002-cmake-Avoid-path-construction-in-pkg-config-file.patch libiio-0.23/debian/patches/0002-cmake-Avoid-path-construction-in-pkg-config-file.patch --- libiio-0.21/debian/patches/0002-cmake-Avoid-path-construction-in-pkg-config-file.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0002-cmake-Avoid-path-construction-in-pkg-config-file.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -From e400f02779a090f39205e59f3044890de3f0b2e5 Mon Sep 17 00:00:00 2001 -From: Jan Tojnar -Date: Mon, 6 Jul 2020 19:22:38 +0200 -Subject: [PATCH 02/53] cmake: Avoid path construction in pkg-config file - -Alternative fix for: https://github.com/analogdevicesinc/libiio/pull/563 - -It is not generally true that `CMAKE_INSTALL_` variables are relative paths: - -https://github.com/jtojnar/cmake-snips#concatenating-paths-when-building-pkg-config-files - -Absolute paths will cause things like this to appear: - - includedir=${prefix}//nix/store/87zhscw1p08nqm73ls2sd82zmr1a8rni-libiio-0.21-dev/include - -It would be best if the paths were relative to `${prefix}` pkg-config variable so that they could be overridden: - -https://www.bassi.io/articles/2018/03/15/pkg-config-and-paths/ - -but since that is not easy to do in CMake, we will just use absolute paths. - -libiio does not expect other project to install artefacts to its installation paths so non-overriddable paths should no do much harm. - -Signed-off-by: Jan Tojnar ---- - libiio.pc.cmakein | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libiio.pc.cmakein b/libiio.pc.cmakein -index 468da5b..fde107c 100644 ---- a/libiio.pc.cmakein -+++ b/libiio.pc.cmakein -@@ -1,7 +1,7 @@ - prefix=@CMAKE_INSTALL_PREFIX@ - exec_prefix=${prefix} --libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ --includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ -+libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ - - Name: libiio - Description: Library for interfacing IIO devices --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0002-C-public-fields-with-getters-setters-cannot-be-marke.patch libiio-0.23/debian/patches/0002-C-public-fields-with-getters-setters-cannot-be-marke.patch --- libiio-0.21/debian/patches/0002-C-public-fields-with-getters-setters-cannot-be-marke.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0002-C-public-fields-with-getters-setters-cannot-be-marke.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,31 @@ +From 85bf9cd32138539252ed01c355cf766612cf47c9 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Thu, 2 Sep 2021 11:04:21 +0100 +Subject: [PATCH 02/26] C#: public fields with getters/setters cannot be marked + readonly + +MSVC would fail with the following error: +error CS0106: The modifier 'readonly' is not valid for this item + +Reported-by: Raluca Chis +Signed-off-by: Paul Cercueil +--- + bindings/csharp/Device.cs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bindings/csharp/Device.cs b/bindings/csharp/Device.cs +index 96214243..6c8c8f4f 100644 +--- a/bindings/csharp/Device.cs ++++ b/bindings/csharp/Device.cs +@@ -208,7 +208,7 @@ namespace iio + public readonly string name; + + /// The label of this device. +- public readonly string label { get; private set; } ++ public string label { get; private set; } + + /// A list of all the attributes that this device has. + public readonly List attrs; +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0003-CI-reconfigure-Azure-Pipelines-artifacts.patch libiio-0.23/debian/patches/0003-CI-reconfigure-Azure-Pipelines-artifacts.patch --- libiio-0.21/debian/patches/0003-CI-reconfigure-Azure-Pipelines-artifacts.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0003-CI-reconfigure-Azure-Pipelines-artifacts.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,256 @@ +From 1c31e8ba7e245ceb5e65d41df5560671c31e69aa Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Thu, 2 Sep 2021 09:58:19 +0300 +Subject: [PATCH 03/26] CI:reconfigure Azure Pipelines artifacts + +- macOS: remove an extra line. +- macOS: change the name of .pkg and .tar.gz files to be different for + each macOS build. +- macOS: publish .tar.gz file as an Azure Pipeline artifact. +- linux: add ARTIFACTNAME to be availabla as an common env-var. +- linux: set CPACK_HELP to FLAGS in order to have different name for + artifacts in each linux build. +- windows: separe comands in build_win.ps1 for win32 and x64 architecture +- windows: generate .tar.gz file (using python 3.9). +- windows: add publish_deps.ps1 script which collects all .dll dependencies + to publish them as artifacts. +- windows: add some tasks to azure_pipelines.yml in order to publish + following files: iio.h header, .exe files, libiio-sharp.dll, + .tar.gz files, .dll dependencies. + +Signed-off-by: Raluca Chis +--- + CI/build_win.ps1 | 34 ++++++++++++++++++++++++++++++---- + CI/publish_deps.ps1 | 27 +++++++++++++++++++++++++++ + CI/travis/lib.sh | 2 +- + CI/travis/make_darwin | 11 +++++++++-- + CI/travis/make_linux | 5 +++-- + azure-pipelines.yml | 33 ++++++++++++++++++++++++++++++++- + 6 files changed, 102 insertions(+), 10 deletions(-) + create mode 100644 CI/publish_deps.ps1 + +diff --git a/CI/build_win.ps1 b/CI/build_win.ps1 +index 56f74527..5ec3cb04 100644 +--- a/CI/build_win.ps1 ++++ b/CI/build_win.ps1 +@@ -4,8 +4,34 @@ $ARCH=$Env:ARCH + + $src_dir=$pwd + +-mkdir build +-cd build ++if ($ARCH -eq "Win32") { ++ echo "Running cmake for $COMPILER on 32 bit..." ++ mkdir build-win32 ++ cp .\libiio.iss.cmakein .\build-win32 ++ cd build-win32 + +-cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. +-cmake --build . --config Release ++ cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. ++ cmake --build . --config Release ++ cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ ++ cd ../bindings/python ++ python.exe setup.py.cmakein sdist ++ Get-ChildItem dist\pylibiio-*.tar.gz | Rename-Item -NewName "libiio-py39-win32.tar.gz" ++ mv .\dist\*.gz . ++ rm .\dist\*.gz ++}else { ++ echo "Running cmake for $COMPILER on 64 bit..." ++ mkdir build-x64 ++ cp .\libiio.iss.cmakein .\build-x64 ++ cd build-x64 ++ ++ cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. ++ cmake --build . --config Release ++ cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ ++ cd ../bindings/python ++ python.exe setup.py.cmakein sdist ++ Get-ChildItem dist\pylibiio-*.tar.gz | Rename-Item -NewName "libiio-py39-amd64.tar.gz" ++ mv .\dist\*.gz . ++ rm .\dist\*.gz ++} +diff --git a/CI/publish_deps.ps1 b/CI/publish_deps.ps1 +new file mode 100644 +index 00000000..1520ee4a +--- /dev/null ++++ b/CI/publish_deps.ps1 +@@ -0,0 +1,27 @@ ++ ++$src_dir=$pwd ++ ++cd 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Redist\MSVC\14.29.30133' ++if ($ARCH -eq "Win32") { ++ echo "$PWD" ++ mv .\x86\Microsoft.VC142.CRT\msvcp140.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++}else { ++ echo "$PWD" ++ mv .\x64\Microsoft.VC142.CRT\msvcp140.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++} ++ ++cd $src_dir ++mkdir dependencies ++cd dependencies ++wget http://swdownloads.analog.com/cse/build/libiio-win-deps.zip -OutFile "libiio-win-deps.zip" ++7z x -y "libiio-win-deps.zip" ++ ++if ($ARCH -eq "Win32") { ++ mv .\libs\32\libxml2.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ mv .\libs\32\libserialport-0.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ mv .\libs\32\libusb-1.0.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++}else { ++ mv .\libs\64\libxml2.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ mv .\libs\64\libserialport-0.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++ mv .\libs\64\libusb-1.0.dll $env:BUILD_ARTIFACTSTAGINGDIRECTORY ++} +diff --git a/CI/travis/lib.sh b/CI/travis/lib.sh +index 15c2c058..bfea28e5 100644 +--- a/CI/travis/lib.sh ++++ b/CI/travis/lib.sh +@@ -26,7 +26,7 @@ INSIDE_DOCKER_BUILD_DIR=/docker_build_dir + # + # If these nothing should be passed, then clear or + #'unset INSIDE_DOCKER_TRAVIS_CI_ENV' after this script is included +-INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_TYPE OS_VERSION" ++INSIDE_DOCKER_TRAVIS_CI_ENV="TRAVIS TRAVIS_COMMIT TRAVIS_PULL_REQUEST OS_TYPE OS_VERSION ARTIFACTNAME" + + COMMON_SCRIPTS="inside_docker.sh" + +diff --git a/CI/travis/make_darwin b/CI/travis/make_darwin +index 52902598..c27fd505 100755 +--- a/CI/travis/make_darwin ++++ b/CI/travis/make_darwin +@@ -4,7 +4,6 @@ LIBIIO_BUILD_CONF="-DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=ON" + + if [ "x${COVERITY_SCAN_PROJECT_NAME}" != "x" ] ; then exit 0; fi + +- + build_osx() { + FLAGS=$1 + echo "### cmake ${FLAGS}" +@@ -17,16 +16,24 @@ build_osx() { + ls + } + ++change_artefact_name() { ++ old_name=`find . -name '*.pkg' | cut -b 3-26` ++ name=`echo ${old_name} | cut -b 1-20` ++ new_name="${name}-${ARTIFACTNAME}.pkg" ++ mv ./${old_name} ./${new_name} ++} ++ + mkdir -p build + + cd build + build_osx "-DOSX_PACKAGE=ON -DPYTHON_BINDINGS=ON -DWITH_EXAMPLES=ON ${LIBIIO_BUILD_CONF}" ++change_artefact_name + + cd .. + + mkdir -p build_tar + cd build_tar +-build_osx "-DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON ${LIBIIO_BUILD_CONF}" ++build_osx "-DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON -DCPACK_SYSTEM_NAME=${ARTIFACTNAME} ${LIBIIO_BUILD_CONF}" + echo "### make package" + make package + echo "### files are" +diff --git a/CI/travis/make_linux b/CI/travis/make_linux +index 019fc077..27e0234b 100755 +--- a/CI/travis/make_linux ++++ b/CI/travis/make_linux +@@ -5,6 +5,7 @@ if [ "x${COVERITY_SCAN_PROJECT_NAME}" != "x" ] ; then exit 0; fi + . CI/travis/lib.sh + + INSIDE_DOCKER_TRAVIS_CI_ENV="$INSIDE_DOCKER_TRAVIS_CI_ENV CHECK_AGAINST_KERNEL_HEADER CI_BUILD_SPHINX_DOCS" ++CPACK_HELP="-DCPACK_SYSTEM_NAME=${ARTIFACTNAME}" + + handle_default() { + echo "### making build dir" +@@ -42,7 +43,7 @@ handle_default() { + MAN_HELP="-DWITH_MAN=ON" + fi + +- FLAGS="-DENABLE_PACKAGING=ON -DDEB_DETECT_DEPENDENCIES=ON -DWITH_EXAMPLES=ON ${PYTHON_HELP} ${DOC_HELP} ${MAN_HELP}" ++ FLAGS="-DENABLE_PACKAGING=ON -DDEB_DETECT_DEPENDENCIES=ON -DWITH_EXAMPLES=ON ${PYTHON_HELP} ${DOC_HELP} ${MAN_HELP} ${CPACK_HELP}" + + # Ubuntu Xenial's libserialport and libzstd are too old + if [ "${OS_VERSION}" = xenial ] ; then +@@ -111,7 +112,7 @@ handle_centos() { + mkdir -p build + cd build + +- FLAGS="-DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=ON" ++ FLAGS="-DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=ON ${CPACK_HELP}" + + # CentOS 7's kernel headers are too old for USB support in IIOD + [ "${OS_VERSION}" = centos7 ] && FLAGS="${FLAGS} -DWITH_IIOD_USBD=OFF" +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index 77e0861d..fb248d4c 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -110,6 +110,11 @@ stages: + sourceFolder: '$(Agent.BuildDirectory)/s/build/' + contents: '$(Agent.BuildDirectory)/s/build/?(*.pkg)' + targetFolder: '$(Build.ArtifactStagingDirectory)' ++ - task: CopyFiles@2 ++ inputs: ++ sourceFolder: '$(Agent.BuildDirectory)/s/build_tar/' ++ contents: '$(Agent.BuildDirectory)/s/build_tar/?(*.gz)' ++ targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishPipelineArtifact@1 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + inputs: +@@ -135,6 +140,9 @@ stages: + - checkout: self + fetchDepth: 1 + clean: true ++ - task: UsePythonVersion@0 ++ inputs: ++ versionSpec: '3.9' + - task: PowerShell@2 + inputs: + targetType: 'filePath' +@@ -148,7 +156,7 @@ stages: + - task: CopyFiles@2 + displayName: 'Copy libraries' + inputs: +- sourceFolder: '$(Agent.BuildDirectory)/s/build/Release' ++ sourceFolder: '$(Agent.BuildDirectory)/s/build-$(ARCH)/Release' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: CopyFiles@2 + displayName: 'Copy iio.h header' +@@ -156,6 +164,29 @@ stages: + sourceFolder: '$(Agent.BuildDirectory)/s/' + contents: 'iio.h' + targetFolder: '$(Build.ArtifactStagingDirectory)' ++ - task: CopyFiles@2 ++ displayName: 'Copy .exe files' ++ inputs: ++ sourceFolder: '$(Agent.BuildDirectory)/s/build-$(ARCH)/tests/Release' ++ contents: '*.exe' ++ targetFolder: '$(Build.ArtifactStagingDirectory)' ++ - task: CopyFiles@2 ++ displayName: 'Copy .tar.gz files' ++ inputs: ++ sourceFolder: '$(Agent.BuildDirectory)/s/bindings/python' ++ contents: '*.gz' ++ targetFolder: '$(Build.ArtifactStagingDirectory)' ++ - task: CopyFiles@2 ++ displayName: 'Copy libiio-sharp.dll file' ++ inputs: ++ sourceFolder: '$(Agent.BuildDirectory)/s/build-$(ARCH)/bindings/csharp' ++ contents: 'libiio-sharp.dll' ++ targetFolder: '$(Build.ArtifactStagingDirectory)' ++ - task: PowerShell@2 ++ displayName: 'Copy dependencies' ++ inputs: ++ targetType: 'filePath' ++ filePath: .\CI\publish_deps.ps1 + - task: PublishPipelineArtifact@1 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + inputs: +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0003-tests-Support-context-timeout-in-common-manner.patch libiio-0.23/debian/patches/0003-tests-Support-context-timeout-in-common-manner.patch --- libiio-0.21/debian/patches/0003-tests-Support-context-timeout-in-common-manner.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0003-tests-Support-context-timeout-in-common-manner.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,334 +0,0 @@ -From 5e6addefffa04fb8c3a7536bde45eb72fed6a30d Mon Sep 17 00:00:00 2001 -From: Robin Getz -Date: Tue, 7 Jul 2020 11:59:19 -0400 -Subject: [PATCH 03/53] tests: Support context timeout in common manner - -and add it to the utils that did not support it before. - -Signed-off-by: Robin Getz ---- - tests/iio_adi_xflow_check.c | 1 + - tests/iio_attr.c | 1 + - tests/iio_common.c | 23 +++++++++++++++++++++++ - tests/iio_common.h | 2 +- - tests/iio_genxml.c | 1 + - tests/iio_info.c | 1 + - tests/iio_readdev.c | 23 ++--------------------- - tests/iio_reg.c | 1 + - tests/iio_stresstest.c | 8 ++++---- - tests/iio_writedev.c | 23 ++--------------------- - 10 files changed, 37 insertions(+), 47 deletions(-) - -diff --git a/tests/iio_adi_xflow_check.c b/tests/iio_adi_xflow_check.c -index 813f8b1..0b05cb9 100644 ---- a/tests/iio_adi_xflow_check.c -+++ b/tests/iio_adi_xflow_check.c -@@ -185,6 +185,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -diff --git a/tests/iio_attr.c b/tests/iio_attr.c -index 2aa3035..bf03960 100644 ---- a/tests/iio_attr.c -+++ b/tests/iio_attr.c -@@ -385,6 +385,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - context_scan = true; -diff --git a/tests/iio_common.c b/tests/iio_common.c -index 7b59aae..0b789c6 100644 ---- a/tests/iio_common.c -+++ b/tests/iio_common.c -@@ -193,6 +193,7 @@ static const struct option common_options[] = { - {"uri", required_argument, 0, 'u'}, - {"scan", optional_argument, 0, 'S'}, - {"auto", optional_argument, 0, 'a'}, -+ {"timeout", required_argument, 0, 'T'}, - {0, 0, 0, 0}, - }; - -@@ -247,6 +248,8 @@ static const char *common_options_descriptions[] = { - "Scan for available contexts and if a single context is" - "\n\t\t\tavailable use it. filters backend(s)" - "\n\t\t\t 'ip', 'usb' or 'ip:usb:'", -+ "Context timeout in milliseconds." -+ "\n\t\t\t0 = no timeout (wait forever)", - }; - - -@@ -261,6 +264,7 @@ struct iio_context * handle_common_opts(char * name, int argc, - bool do_scan = false, detect_context = false; - char buf[128]; - struct option *opts; -+ int timeout = -1; - - /* Setting opterr to zero disables error messages from getopt_long */ - opterr = 0; -@@ -339,6 +343,13 @@ struct iio_context * handle_common_opts(char * name, int argc, - arg = argv[optind++]; - } - break; -+ case 'T': -+ if (!optarg) { -+ fprintf(stderr, "Timeout requires an argument\n"); -+ return NULL; -+ } -+ timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); -+ break; - case '?': - break; - } -@@ -372,6 +383,18 @@ struct iio_context * handle_common_opts(char * name, int argc, - fprintf(stderr, "Unable to create Local IIO context : %s\n", buf); - } - -+ if (ctx && timeout >= 0) { -+ ssize_t ret = iio_context_set_timeout(ctx, timeout); -+ if (ret < 0) { -+ char err_str[1024]; -+ iio_strerror(-(int)ret, err_str, sizeof(err_str)); -+ fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", -+ err_str, ret); -+ iio_context_destroy(ctx); -+ return NULL; -+ } -+ } -+ - return ctx; - } - -diff --git a/tests/iio_common.h b/tests/iio_common.h -index a06e304..58a98e1 100644 ---- a/tests/iio_common.h -+++ b/tests/iio_common.h -@@ -51,7 +51,7 @@ unsigned long int sanitize_clamp(const char *name, const char *argv, - * If such a character is followed by a colon, the option requires an argument. - * Two colons mean an option takes an optional argument. - */ --#define COMMON_OPTIONS "hn:x:u:a::S::" -+#define COMMON_OPTIONS "hn:x:u:a::S::T:" - - struct iio_context * handle_common_opts(char * name, int argc, - char * const argv[], const char *optstring, -diff --git a/tests/iio_genxml.c b/tests/iio_genxml.c -index 2701110..48ee5b9 100644 ---- a/tests/iio_genxml.c -+++ b/tests/iio_genxml.c -@@ -63,6 +63,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -diff --git a/tests/iio_info.c b/tests/iio_info.c -index 02a2b5b..47ee252 100644 ---- a/tests/iio_info.c -+++ b/tests/iio_info.c -@@ -95,6 +95,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -diff --git a/tests/iio_readdev.c b/tests/iio_readdev.c -index 34d811a..94d052f 100644 ---- a/tests/iio_readdev.c -+++ b/tests/iio_readdev.c -@@ -38,18 +38,16 @@ static const struct option options[] = { - {"trigger", required_argument, 0, 't'}, - {"buffer-size", required_argument, 0, 'b'}, - {"samples", required_argument, 0, 's' }, -- {"timeout", required_argument, 0, 'T'}, - {"auto", no_argument, 0, 'a'}, - {0, 0, 0, 0}, - }; - - static const char *options_descriptions[] = { -- "[-t ] [-T ] [-b ]" -+ "[-t ] [-b ]" - "[-s ] [ ...]", - "Use the specified trigger.", - "Size of the capture buffer. Default is 256.", - "Number of samples to capture, 0 = infinite. Default is 0.", -- "Buffer timeout in milliseconds. 0 = no timeout", - "Scan for available contexts and if only one is available use it.", - }; - -@@ -198,7 +196,6 @@ int main(int argc, char **argv) - int c; - struct iio_device *dev; - ssize_t sample_size; -- int timeout = -1; - ssize_t ret; - struct option *opts; - -@@ -219,6 +216,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -@@ -247,13 +245,6 @@ int main(int argc, char **argv) - } - num_samples = sanitize_clamp("number of samples", optarg, 0, SIZE_MAX); - break; -- case 'T': -- if (!optarg) { -- fprintf(stderr, "Timeout requires an argument\n"); -- return EXIT_FAILURE; -- } -- timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); -- break; - case '?': - printf("Unknown argument '%c'\n", c); - return EXIT_FAILURE; -@@ -272,16 +263,6 @@ int main(int argc, char **argv) - - setup_sig_handler(); - -- if (timeout >= 0) { -- ret = iio_context_set_timeout(ctx, timeout); -- if (ret < 0) { -- char err_str[1024]; -- iio_strerror(-(int)ret, err_str, sizeof(err_str)); -- fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", -- err_str, ret); -- } -- } -- - dev = iio_context_find_device(ctx, argw[optind]); - if (!dev) { - fprintf(stderr, "Device %s not found\n", argw[optind]); -diff --git a/tests/iio_reg.c b/tests/iio_reg.c -index a082a56..04bb27e 100644 ---- a/tests/iio_reg.c -+++ b/tests/iio_reg.c -@@ -99,6 +99,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -diff --git a/tests/iio_stresstest.c b/tests/iio_stresstest.c -index eb046d9..4217dcc 100644 ---- a/tests/iio_stresstest.c -+++ b/tests/iio_stresstest.c -@@ -106,8 +106,8 @@ static const struct option options[] = { - {"uri", required_argument, 0, 'u'}, - {"buffer-size", required_argument, 0, 'b'}, - {"samples", required_argument, 0, 's' }, -- {"timeout", required_argument, 0, 't'}, -- {"Threads", required_argument, 0, 'T'}, -+ {"Timeout", required_argument, 0, 'T'}, -+ {"threads", required_argument, 0, 't'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0}, - }; -@@ -430,13 +430,13 @@ int main(int argc, char **argv) - info.buffer_size = sanitize_clamp("buffersize", info.argv[info.arg_index], - min_samples, 1024 * 1024 * 4); - break; -- case 't': -+ case 'T': - info.arg_index +=2; - /* ensure between least once a day and never (0) */ - info.timeout = 1000 * sanitize_clamp("timeout", info.argv[info.arg_index], - 0, 60 * 60 * 24); - break; -- case 'T': -+ case 't': - info.arg_index +=2; - /* Max number threads 1024, min 1 */ - info.num_threads = sanitize_clamp("threads", info.argv[info.arg_index], -diff --git a/tests/iio_writedev.c b/tests/iio_writedev.c -index a0db842..1e31033 100644 ---- a/tests/iio_writedev.c -+++ b/tests/iio_writedev.c -@@ -47,7 +47,6 @@ static const struct option options[] = { - {"trigger", required_argument, 0, 't'}, - {"buffer-size", required_argument, 0, 'b'}, - {"samples", required_argument, 0, 's' }, -- {"timeout", required_argument, 0, 'T'}, - {"auto", no_argument, 0, 'a'}, - {"cyclic", no_argument, 0, 'c'}, - {0, 0, 0, 0}, -@@ -55,12 +54,11 @@ static const struct option options[] = { - - static const char *options_descriptions[] = { - "[-t ] " -- "[-T ] [-b ] [-s ] " -+ "[-b ] [-s ] " - " [ ...]", - "Use the specified trigger.", - "Size of the transmit buffer. Default is 256.", - "Number of samples to write, 0 = infinite. Default is 0.", -- "Buffer timeout in milliseconds. 0 = no timeout", - "Scan for available contexts and if only one is available use it.", - "Use cyclic buffer mode.", - }; -@@ -209,7 +207,6 @@ int main(int argc, char **argv) - int c; - struct iio_device *dev; - ssize_t sample_size; -- int timeout = -1; - bool cyclic_buffer = false; - ssize_t ret; - struct option *opts; -@@ -230,6 +227,7 @@ int main(int argc, char **argv) - case 'n': - case 'x': - case 'u': -+ case 'T': - break; - case 'S': - case 'a': -@@ -258,13 +256,6 @@ int main(int argc, char **argv) - } - num_samples = sanitize_clamp("number of samples", optarg, 0, SIZE_MAX); - break; -- case 'T': -- if (!optarg) { -- fprintf(stderr, "Timeout requires argument\n"); -- return EXIT_FAILURE; -- } -- timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); -- break; - case 'c': - cyclic_buffer = true; - break; -@@ -286,16 +277,6 @@ int main(int argc, char **argv) - - setup_sig_handler(); - -- if (timeout >= 0) { -- ret = iio_context_set_timeout(ctx, timeout); -- if (ret < 0) { -- char err_str[1024]; -- iio_strerror(-(int)ret, err_str, sizeof(err_str)); -- fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", -- err_str, ret); -- } -- } -- - dev = iio_context_find_device(ctx, argw[optind]); - if (!dev) { - fprintf(stderr, "Device %s not found\n", argw[optind]); --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0004-CI-edit-Github-release.patch libiio-0.23/debian/patches/0004-CI-edit-Github-release.patch --- libiio-0.21/debian/patches/0004-CI-edit-Github-release.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0004-CI-edit-Github-release.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,143 @@ +From acd93b9f996c38262bc91718ccda5491dbb14528 Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Thu, 2 Sep 2021 13:50:08 +0300 +Subject: [PATCH 04/26] CI: edit Github release + +- change the name of the release +- add prepare_assets.sh script that will copy or archive the artifacts + for release, depending on each build. +- archive_artifacts.sh will be removed because that functions will be + included in prepare_assets.sh. + +Signed-off-by: Raluca Chis +--- + CI/travis/archive_artifacts.sh | 36 -------------------------- + CI/travis/prepare_assets.sh | 46 ++++++++++++++++++++++++++++++++++ + azure-pipelines.yml | 8 +++--- + 3 files changed, 49 insertions(+), 41 deletions(-) + delete mode 100755 CI/travis/archive_artifacts.sh + create mode 100644 CI/travis/prepare_assets.sh + +diff --git a/CI/travis/archive_artifacts.sh b/CI/travis/archive_artifacts.sh +deleted file mode 100755 +index 9c0645ce..00000000 +--- a/CI/travis/archive_artifacts.sh ++++ /dev/null +@@ -1,36 +0,0 @@ +-#!/bin/bash -e +- +-archive_linux() { +- local linux_dist='CentOS-7-x86_64 CentOS-8-x86_64 Ubuntu-16.04-x86_64 +- Ubuntu-18.04-x86_64 Ubuntu-20.04-x86_64 Debian-Buster-ARM Debian-Buster-ARM64' +- +- cd "${SOURCE_DIRECTORY}" +- for distribution in $linux_dist; do +- tar -zcvf Linux-"${distribution}".tar.gz Linux-"${distribution}" +- rm -r Linux-"${distribution}" +- done +-} +- +-archive_macOS() { +- local macOS_dist='10.14 10.15' +- +- cd "${SOURCE_DIRECTORY}" +- for distribution in $macOS_dist; do +- tar -zcvf macOS-"${distribution}".tar.gz macOS-"${distribution}" +- rm -r macOS-"${distribution}" +- done +-} +- +-archive_windows() { +- local windows_dist='Win32 x64' +- +- cd "${SOURCE_DIRECTORY}" +- for distribution in $windows_dist; do +- zip -r Windows-VS-16-2019-"${distribution}".zip Windows-VS-16-2019-"${distribution}" +- rm -r Windows-VS-16-2019-"${distribution}" +- done +-} +- +-archive_linux +-archive_macOS +-archive_windows +diff --git a/CI/travis/prepare_assets.sh b/CI/travis/prepare_assets.sh +new file mode 100644 +index 00000000..4fd6f8c4 +--- /dev/null ++++ b/CI/travis/prepare_assets.sh +@@ -0,0 +1,46 @@ ++#!/bin/bash -e ++ ++move_artifacts() { ++ local rpm_assets='CentOS-7-x86_64 CentOS-8-x86_64' ++ cd "${BUILD_ARTIFACTSTAGINGDIRECTORY}" ++ for i in $rpm_assets; do ++ cd "${i}" ++ find . -name '*.rpm' -exec mv {} ../ ";" ++ cd ../ ++ rm -r "${i}" ++ done ++ ++ local deb_assets='Ubuntu-16.04-x86_64 Ubuntu-18.04-x86_64 ++ Ubuntu-20.04-x86_64 Debian-Buster-ARM ++ Debian-Buster-ARM64' ++ cd "${BUILD_ARTIFACTSTAGINGDIRECTORY}" ++ for i in $deb_assets; do ++ cd "${i}" ++ find . -name '*.deb' -exec mv {} ../ ";" ++ cd ../ ++ rm -r "${i}" ++ done ++ ++ local pkg_assets='macOS-10.14 macOS-10.15' ++ cd "${BUILD_ARTIFACTSTAGINGDIRECTORY}" ++ for i in $pkg_assets; do ++ cd "${i}" ++ find . -name '*.pkg' -exec mv {} ../ ";" ++ find . -name '*.gz' -exec mv {} ../ ";" ++ cd ../ ++ rm -r "${i}" ++ done ++} ++ ++archive_windows() { ++ local windows_dist='Win32 x64' ++ ++ cd "${BUILD_ARTIFACTSTAGINGDIRECTORY}" ++ for distribution in $windows_dist; do ++ zip -r Windows-VS-16-2019-"${distribution}".zip Windows-VS-16-2019-"${distribution}" ++ rm -r Windows-VS-16-2019-"${distribution}" ++ done ++} ++ ++move_artifacts ++archive_windows +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index fb248d4c..447f3a4b 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -221,10 +221,8 @@ stages: + - task: DownloadPipelineArtifact@2 + inputs: + path: '$(Build.ArtifactStagingDirectory)' +- - bash: ./CI/travis/archive_artifacts.sh +- env: +- SOURCE_DIRECTORY: $(Build.ArtifactStagingDirectory) +- displayName: "Archive artifacts" ++ - bash: ./CI/travis/prepare_assets.sh ++ displayName: "Prepare assets for release" + - task: GithubRelease@0 + displayName: 'Attach artifacts to GitHub Release' + inputs: +@@ -233,7 +231,7 @@ stages: + action: create + target: $(Build.SourceVersion) + tag: $(Build.SourceBranchName) +- title: "$(Build.SourceBranchName): Version " ++ title: "Libiio release $(Build.SourceBranchName)" + assets: $(Build.ArtifactStagingDirectory)/* + addChangeLog: true + isDraft: true +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0004-dnssd-Use-lower-case-when-including-Windows-headers.patch libiio-0.23/debian/patches/0004-dnssd-Use-lower-case-when-including-Windows-headers.patch --- libiio-0.21/debian/patches/0004-dnssd-Use-lower-case-when-including-Windows-headers.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0004-dnssd-Use-lower-case-when-including-Windows-headers.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From 8818092dc54f328426abab376772538a7ab558da Mon Sep 17 00:00:00 2001 -From: Dan Nechita -Date: Fri, 10 Jul 2020 12:27:25 +0300 -Subject: [PATCH 04/53] dnssd: Use lower case when including Windows headers - -This would help the cross compile process where these headers are not -found because their filenames are lowercase. This happens if the host -where the cross compiling is done is case sensitive when it comes to -file paths. - -Signed-off-by: Dan Nechita ---- - mdns.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/mdns.h b/mdns.h -index 58a5bb5..7e164f7 100644 ---- a/mdns.h -+++ b/mdns.h -@@ -22,8 +22,8 @@ - - #include - #ifdef _WIN32 --#include --#include -+#include -+#include - #define strncasecmp _strnicmp - #else - #include --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0005-CI-generate-libiio-setup.exe.patch libiio-0.23/debian/patches/0005-CI-generate-libiio-setup.exe.patch --- libiio-0.21/debian/patches/0005-CI-generate-libiio-setup.exe.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0005-CI-generate-libiio-setup.exe.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,163 @@ +From c14a0f8b38e9f1ecee147324b0864b8bcf22e15b Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Fri, 3 Sep 2021 16:29:24 +0300 +Subject: [PATCH 05/26] CI: generate libiio-setup.exe + +- remove unavailable languages. +- change the paths to dependent files in libiio.iss.cmakein +- "pf32" and "cf" has been renamed to "commonpf32", respectively + "commoncf". +- add script generate_exe.ps1 in order to generate libiio-setup.exe. +- add a windows job to manage generate_exe.ps1 script. +- libiio-setup.exe will be generated only for releases and modifications + on master + +Signed-off-by: Raluca Chis +--- + CI/build_win.ps1 | 4 ++-- + CI/generate_exe.ps1 | 5 +++++ + azure-pipelines.yml | 18 ++++++++++++++++++ + libiio.iss.cmakein | 39 +++++++++++++++++---------------------- + 4 files changed, 42 insertions(+), 24 deletions(-) + create mode 100644 CI/generate_exe.ps1 + +diff --git a/CI/build_win.ps1 b/CI/build_win.ps1 +index 5ec3cb04..4b6110a8 100644 +--- a/CI/build_win.ps1 ++++ b/CI/build_win.ps1 +@@ -10,7 +10,7 @@ if ($ARCH -eq "Win32") { + cp .\libiio.iss.cmakein .\build-win32 + cd build-win32 + +- cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. ++ cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\32\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\32\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\32\\libserialport.dll.a" .. + cmake --build . --config Release + cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY + +@@ -25,7 +25,7 @@ if ($ARCH -eq "Win32") { + cp .\libiio.iss.cmakein .\build-x64 + cd build-x64 + +- cmake -G "$COMPILER" -A "$ARCH" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=OFF -DWITH_SERIAL_BACKEND=OFF -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="$src_dir\deps\lib\libxml2.dll.a" .. ++ cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\64\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\64\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\64\\libserialport.dll.a" .. + cmake --build . --config Release + cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY + +diff --git a/CI/generate_exe.ps1 b/CI/generate_exe.ps1 +new file mode 100644 +index 00000000..c68b2eba +--- /dev/null ++++ b/CI/generate_exe.ps1 +@@ -0,0 +1,5 @@ ++SET PATH=packages\Tools.InnoSetup.5.6.1\tools ++iscc $env:BUILD_ARTIFACTSTAGINGDIRECTORY\Windows-VS-16-2019-Win32\libiio.iss ++ ++Get-ChildItem $env:BUILD_ARTIFACTSTAGINGDIRECTORY -Force -Recurse | Remove-Item -Force -Recurse ++cp C:\libiio-setup.exe $env:BUILD_ARTIFACTSTAGINGDIRECTORY +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index 447f3a4b..a3fcbe98 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -196,6 +196,24 @@ stages: + - stage: PushArtifacts + dependsOn: Builds + jobs: ++ - job: GenerateSetupExe ++ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))) ++ pool: ++ vmImage: 'windows-2019' ++ steps: ++ - task: DownloadPipelineArtifact@2 ++ inputs: ++ path: '$(Build.ArtifactStagingDirectory)' ++ - task: PowerShell@2 ++ inputs: ++ targetType: 'filePath' ++ filePath: .\CI\generate_exe.ps1 ++ displayName: "Generate libiio-setup.exe" ++ - task: PublishPipelineArtifact@1 ++ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) ++ inputs: ++ targetPath: '$(Build.ArtifactStagingDirectory)' ++ artifactName: 'Libiio-Setup-Exe' + - job: PushToSWDownloads + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + pool: +diff --git a/libiio.iss.cmakein b/libiio.iss.cmakein +index 8ad44285..fc8de59a 100644 +--- a/libiio.iss.cmakein ++++ b/libiio.iss.cmakein +@@ -8,7 +8,7 @@ AppSupportURL="http://www.analog.com" + AppUpdatesURL="http://www.analog.com" + AppCopyright="Copyright 2015-@BUILD_YEAR@ ADI and other contributors" + CreateAppDir=no +-LicenseFile="C:\projects\libiio\COPYING.txt" ++LicenseFile="D:\a\1\s\COPYING.txt" + OutputBaseFilename=libiio-setup + OutputDir="C:\" + Compression=lzma +@@ -26,45 +26,40 @@ Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" + Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" + Name: "french"; MessagesFile: "compiler:Languages\French.isl" + Name: "german"; MessagesFile: "compiler:Languages\German.isl" +-Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl" + Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" +-Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl" + Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" + Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" + Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" + Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" + Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" + Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" +-Name: "scottishgaelic"; MessagesFile: "compiler:Languages\ScottishGaelic.isl" +-Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl" +-Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl" + Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" + Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" + Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" + Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" + + [Files] +-Source: "C:\projects\libiio\build-win32\Release\libiio.dll"; DestDir: "{sys}"; Flags: 32bit replacesameversion +-Source: "C:\projects\libiio\build-win64\Release\libiio.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: replacesameversion ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libiio.dll"; DestDir: "{sys}"; Flags: 32bit replacesameversion ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\libiio.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: replacesameversion + +-Source: "C:\projects\libiio\build-win32\tests\Release\*.exe"; DestDir: "{sys}"; Check: not Is64BitInstallMode; Flags: replacesameversion +-Source: "C:\projects\libiio\build-win64\tests\Release\*.exe"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: replacesameversion ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\*.exe"; DestDir: "{sys}"; Check: not Is64BitInstallMode; Flags: replacesameversion ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\*.exe"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: replacesameversion + +-Source: "C:\projects\libiio\build-win32\Release\libiio.lib"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\lib"; Check: not Is64BitInstallMode +-Source: "C:\projects\libiio\build-win64\Release\libiio.lib"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\lib\amd64"; Check: Is64BitInstallMode +-Source: "C:\projects\libiio\iio.h"; DestDir: "{pf32}\Microsoft Visual Studio 12.0\VC\include" ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libiio.lib"; DestDir: "{commonpf32}\Microsoft Visual Studio 12.0\VC\lib"; Check: not Is64BitInstallMode ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\libiio.lib"; DestDir: "{commonpf32}\Microsoft Visual Studio 12.0\VC\lib\amd64"; Check: Is64BitInstallMode ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\iio.h"; DestDir: "{commonpf32}\Microsoft Visual Studio 12.0\VC\include" + +-Source: "C:\libs\32\libxml2.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit +-Source: "C:\libs\64\libxml2.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libxml2.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\libxml2.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist + +-Source: "C:\libs\32\libusb-1.0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit +-Source: "C:\libs\64\libusb-1.0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libusb-1.0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\libusb-1.0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist + +-Source: "C:\libs\32\libserialport-0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit +-Source: "C:\libs\64\libserialport-0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libserialport-0.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit ++Source: "D:\a\1\a\Windows-VS-16-2019-x64\libserialport-0.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist + +-Source: "C:\projects\libiio\build-win32\bindings\csharp\libiio-sharp.dll"; DestDir: "{cf}\libiio"; Flags: replacesameversion ++Source: "D:\a\1\a\Windows-VS-16-2019-Win32\libiio-sharp.dll"; DestDir: "{commoncf}\libiio"; Flags: replacesameversion + +-Source: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x86\Microsoft.VC120.CRT\msvcr120.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit +-Source: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x64\Microsoft.VC120.CRT\msvcr120.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist ++Source: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Redist\MSVC\14.29.30133\x86\Microsoft.VC142.CRT\msvcp140.dll"; DestDir: "{sys}"; Flags: onlyifdoesntexist 32bit ++Source: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140.dll"; DestDir: "{sys}"; Check: Is64BitInstallMode; Flags: onlyifdoesntexist + +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0005-Update-python-package-name.patch libiio-0.23/debian/patches/0005-Update-python-package-name.patch --- libiio-0.21/debian/patches/0005-Update-python-package-name.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0005-Update-python-package-name.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -From 08aa2f0368fc7fdfbab90bc8f133d2594cd603bb Mon Sep 17 00:00:00 2001 -From: "Travis F. Collins" -Date: Mon, 20 Jul 2020 08:45:34 -0700 -Subject: [PATCH 05/53] Update python package name - -The name libiio is not available in pypi since Fedora blocked out future -package names that share the same name as their yum/apt names. -Therefore, we switch to using the name pylibiio for pypi. This change -updates the doc and packaging script. - -Signed-off-by: Travis F. Collins ---- - bindings/python/README.md | 4 ++-- - bindings/python/doc/index.rst | 2 +- - bindings/python/setup.py.cmakein | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/bindings/python/README.md b/bindings/python/README.md -index a656d91..43d7b00 100644 ---- a/bindings/python/README.md -+++ b/bindings/python/README.md -@@ -5,7 +5,7 @@ This package contains the python bindings for libiio, a library for interfacing - libiio is used to interface to the Linux Industrial Input/Output (IIO) Subsystem. The Linux IIO subsystem is intended to provide support for devices that in some sense are analog to digital or digital to analog converters (ADCs, DACs). This includes, but is not limited to ADCs, Accelerometers, Gyros, IMUs, Capacitance to Digital Converters (CDCs), Pressure Sensors, Color, Light and Proximity Sensors, Temperature Sensors, Magnetometers, DACs, DDS (Direct Digital Synthesis), PLLs (Phase Locked Loops), Variable/Programmable Gain Amplifiers (VGA, PGA), and RF transceivers. You can use libiio natively on an embedded Linux target (local mode), or use libiio to communicate remotely to that same target from a host Linux, Windows or MAC over USB or Ethernet or Serial. - - [![Build Status](https://travis-ci.org/analogdevicesinc/libiio.svg?branch=master)](https://travis-ci.org/analogdevicesinc/libiio) --[![PyPI version](https://badge.fury.io/py/libiio.svg)](https://badge.fury.io/py/libiio) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4bd027bfc5774029a30a9e1cedf5a434)](https://www.codacy.com/app/rgetz/libiio?utm_source=github.com&utm_medium=referral&utm_content=analogdevicesinc/libiio&utm_campaign=Badge_Grade) -+[![PyPI version](https://badge.fury.io/py/pylibiio.svg)](https://badge.fury.io/py/pylibiio) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/4bd027bfc5774029a30a9e1cedf5a434)](https://www.codacy.com/app/rgetz/libiio?utm_source=github.com&utm_medium=referral&utm_content=analogdevicesinc/libiio&utm_campaign=Badge_Grade) - ![open bugs](https://img.shields.io/github/issues/analogdevicesinc/libiio.svg) - - [[Docs](https://analogdevicesinc.github.io/libiio/v0.19/python/index.html)] -@@ -20,7 +20,7 @@ To use these bindings naturally you need the core library they depend upon, libi - ### Installing the bindings - To install these bindings there are a few methods. If you already have the library itself and just need the bindings, pip is the most convenient method: - ```shell --(sudo) pip install libiio -+(sudo) pip install pylibiio - ``` - If you do not want to use pip, then installation is dependent on your operating system. - #### Linux / macOS -diff --git a/bindings/python/doc/index.rst b/bindings/python/doc/index.rst -index 107f8e8..34a08bc 100644 ---- a/bindings/python/doc/index.rst -+++ b/bindings/python/doc/index.rst -@@ -10,7 +10,7 @@ The libiio python bindings can be installed from pip - - .. code-block:: bash - -- (sudo) pip install libiio -+ (sudo) pip install pylibiio - - or by grabbing the source directly - -diff --git a/bindings/python/setup.py.cmakein b/bindings/python/setup.py.cmakein -index cd14e2e..b13778e 100644 ---- a/bindings/python/setup.py.cmakein -+++ b/bindings/python/setup.py.cmakein -@@ -85,7 +85,7 @@ class InstallWrapper(install): - - config.update( - dict( -- name="libiio", -+ name="pylibiio", - version="${VERSION}", - maintainer="Analog Devices, Inc", - maintainer_email="travis.collins@analog.com", --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0006-CI-generate-and-deploy-documentation.patch libiio-0.23/debian/patches/0006-CI-generate-and-deploy-documentation.patch --- libiio-0.21/debian/patches/0006-CI-generate-and-deploy-documentation.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0006-CI-generate-and-deploy-documentation.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,252 @@ +From 019549f62675a6f4d83d558873a22421299f1243 Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Wed, 8 Sep 2021 11:26:45 +0300 +Subject: [PATCH 06/26] CI: generate and deploy documentation + +- add doxygen job in azure-pipelines.yml to generate and + deploy documentation to GitHub +- add handle_doxygen functions in before_install_linux and + make_linux +- modifications in generateDocumentationAndDeploy.sh.in: + - replace Travis CI variables with Azure Pipelines variables + - add condition to push documentation only for modifications on + master and release tags + +Signed-off-by: Raluca Chis +--- + CI/travis/before_install_linux | 4 + + .../generateDocumentationAndDeploy.sh.in | 94 +++++++++---------- + CI/travis/make_linux | 8 +- + azure-pipelines.yml | 12 ++- + 4 files changed, 65 insertions(+), 53 deletions(-) + +diff --git a/CI/travis/before_install_linux b/CI/travis/before_install_linux +index 200de537..f336c320 100755 +--- a/CI/travis/before_install_linux ++++ b/CI/travis/before_install_linux +@@ -102,6 +102,10 @@ handle_debian() { + handle_default + } + ++handle_doxygen() { ++ handle_default ++} ++ + setup_build_type_env_vars + + handle_${BUILD_TYPE} +diff --git a/CI/travis/generateDocumentationAndDeploy.sh.in b/CI/travis/generateDocumentationAndDeploy.sh.in +index dc416e39..37b0c2bf 100644 +--- a/CI/travis/generateDocumentationAndDeploy.sh.in ++++ b/CI/travis/generateDocumentationAndDeploy.sh.in +@@ -11,9 +11,6 @@ set -x + # - An gh-pages branch should already exist. See below for mor info on how to + # create a gh-pages branch. + # +-# Required global variables: +-# - GH_DOC_TOKEN : Secure token to the github repository. +-# + # This script will generate Doxygen documentation and push the documentation to + # the gh-pages branch of a repository specified by $TRAVIS_REPO_SLUG + # Before this script is used there should already be a gh-pages branch in the +@@ -25,14 +22,14 @@ set -x + + ##### Setup this script and get the current gh-pages branch. + echo 'Setting up the script...' +-GH_REPO_NAME=$(echo "$TRAVIS_REPO_SLUG" | awk -F/ '{print $2}') ++GH_REPO_NAME=$(echo "$BUILD_REPOSITORY_NAME" | awk -F/ '{print $2}') + + # Exit with nonzero exit code if anything fails + set -e + + # by the time this script is run, we should have already made the docs +-cd "$TRAVIS_BUILD_DIR/build" +-#docs should be in the $TRAVIS_BUILD_DIR/build/html directory ++cd "$BUILD_SOURCESDIRECTORY/build" ++#docs should be in the $BUILD_SOURCESDIRECTORY/build/html directory + if [ ! -d "html" ] || [ ! -f "./html/v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@/@PROJECT_NAME@/index.html" ]; then + echo '' >&2 + echo 'Warning: No documentation (html) files have been found!' >&2 +@@ -40,58 +37,59 @@ if [ ! -d "html" ] || [ ! -f "./html/v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MIN + exit 0 + fi + +-if [ -z "${TRAVIS_TAG}" ] ; then ++if [ -z "${BUILD_SOURCEBRANCH}" ] ; then + echo 'Warning: Not a tag' >&2 + echo 'Warning: Not going to push the documentation to GitHub!' >&2 + exit 0 + fi + +-# Get the current gh-pages branch +-git clone -b gh-pages https://git@github.com/$TRAVIS_REPO_SLUG +-cd "$GH_REPO_NAME" +- +-# Remove everything currently in the gh-pages branch. +-# GitHub is smart enough to know which files have changed and which files have +-# stayed the same and will only update the changed files. So the gh-pages branch +-# can be safely cleaned, and it is sure that everything pushed later is the new +-# documentation. +-rm -rf v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@/* ++if [ "${BUILD_SOURCEBRANCH}" = "refs/heads/master" ] || [ "${BUILD_SOURCEBRANCH}" = "refs/tags/v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@" ]; then ++ # Fetch gh-pages branch ++ git fetch origin +refs/heads/gh-pages:gh-pages ++ git checkout gh-pages + +-#copy the files over, this should add the new version +-cp -a ../html/* ./ ++ # Remove everything currently in the gh-pages branch. ++ # GitHub is smart enough to know which files have changed and which files have ++ # stayed the same and will only update the changed files. So the gh-pages branch ++ # can be safely cleaned, and it is sure that everything pushed later is the new ++ # documentation. ++ rm -rf v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@/* ++ cd ../ ++ cp -r ./build/html/v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@ ./ ++ cp -r ./build/html/v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@/* ./master ++ rm -rf build ++ rm -rf bindings + +-##### Configure git. +-# Set the push default to simple i.e. push only the current branch. +-git config --global push.default simple +-# Pretend to be an user called Travis CI. +-git config user.name "Autogenerated by Travis CI" +-git config user.email "robin.getz@analog.com" ++ ##### Configure git. ++ # Set the push default to simple i.e. push only the current branch. ++ git config --global push.default simple + +-# Need to create a .nojekyll file to allow filenames starting with an underscore +-# to be seen on the gh-pages site. Therefore creating an empty .nojekyll file. +-# Presumably this is only needed when the SHORT_NAMES option in Doxygen is set +-# to NO, which it is by default. So creating the file just in case. +-if [ ! -f ".nojekyll" ] ; then +- touch .nojekyll +-fi ++ git config user.name "Autogenerated by Azure Pipelines" ++ git config user.email "cse-ci-notifications@analog.com" + +-################################################################################ +-##### Upload the documentation to the gh-pages branch of the repository. ##### ++ # Need to create a .nojekyll file to allow filenames starting with an underscore ++ # to be seen on the gh-pages site. Therefore creating an empty .nojekyll file. ++ # Presumably this is only needed when the SHORT_NAMES option in Doxygen is set ++ # to NO, which it is by default. So creating the file just in case. ++ if [ ! -f ".nojekyll" ] ; then ++ touch .nojekyll ++ fi + +-echo 'Uploading documentation to the gh-pages branch...' +-# Add everything in this directory (the Doxygen code documentation) to the +-# gh-pages branch. +-# +-# GitHub is smart enough to know which files have changed and which files have +-# stayed the same and will only update the changed files. +-git add --all ++ ################################################################################ ++ ##### Upload the documentation to the gh-pages branch of the repository. ##### + +-# Commit the added files with a title and description containing the Travis CI +-# build number and the GitHub commit reference that issued this build. +-git commit -m "Deploy autogenerated docs for ${GH_REPO_NAME} v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@-g@LIBIIO_VERSION_GIT@" --sign ++ echo 'Uploading documentation to the gh-pages branch...' ++ # Add everything in this directory (the Doxygen code documentation) to the ++ # gh-pages branch. ++ # ++ # GitHub is smart enough to know which files have changed and which files have ++ # stayed the same and will only update the changed files. ++ git add --all + +-# Force push to the remote gh-pages branch. +-# The ouput is redirected to /dev/null to hide any sensitive credential data +-# that might otherwise be exposed. +-git push --force "https://${GH_DOC_TOKEN}@github.com/${TRAVIS_REPO_SLUG}" > /dev/null 2>&1 ++ # Commit the added files with a title and description containing the project ++ # name and the GitHub commit reference that issued this build. ++ git commit --allow-empty --amend -m "Deploy autogenerated docs for ${GH_REPO_NAME} v@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@-g@LIBIIO_VERSION_GIT@" --sign + ++ # Force push to the remote gh-pages branch. ++ git push --force origin gh-pages ++fi +diff --git a/CI/travis/make_linux b/CI/travis/make_linux +index 27e0234b..f5e89374 100755 +--- a/CI/travis/make_linux ++++ b/CI/travis/make_linux +@@ -94,8 +94,8 @@ handle_default() { + + echo "### make package" + make package +- if [ -n "${GH_DOC_TOKEN}" ] && \ +- [ -f "./generateDocumentationAndDeploy.sh" ] ; then ++ ++ if [ -f "./generateDocumentationAndDeploy.sh" ] ; then + sh generateDocumentationAndDeploy.sh + fi + cd .. +@@ -135,6 +135,10 @@ handle_generic_docker() { + run_docker_script inside_docker.sh + } + ++handle_doxygen() { ++ handle_default ++} ++ + setup_build_type_env_vars + + handle_${BUILD_TYPE} +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index a3fcbe98..138993af 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -40,14 +40,12 @@ stages: + OS_TYPE: 'ubuntu_docker' + OS_VERSION: bionic + artifactName: 'Linux-Ubuntu-18.04-x86_64' +- CI_BUILD_SPHINX_DOCS: 1 + ubuntu_20_04_x86_64: + imageName: 'ubuntu-latest' + OS_TYPE: 'ubuntu_docker' + OS_VERSION: focal + artifactName: 'Linux-Ubuntu-20.04-x86_64' + CHECK_AGAINST_KERNEL_HEADER: 1 +- CI_BUILD_SPHINX_DOCS: 1 + debian_buster_arm32v7: + imageName: 'ubuntu-latest' + OS_TYPE: 'arm32v7/debian_docker' +@@ -58,23 +56,31 @@ stages: + OS_TYPE: 'arm64v8/debian_docker' + OS_VERSION: 'buster' + artifactName: 'Linux-Debian-Buster-ARM64' ++ doxygen: ++ imageName: 'ubuntu-latest' ++ OS_TYPE: 'doxygen' ++ OS_VERSION: focal ++ artifactName: 'Libiio-documentation' ++ CI_BUILD_SPHINX_DOCS: 1 + pool: + vmImage: $(imageName) + steps: + - checkout: self + fetchDepth: 1 + clean: true ++ persistCredentials: true + - script: ./CI/travis/before_install_linux + displayName: "Install Dependencies" + - script: ./CI/travis/make_linux + displayName: "Build" + - task: CopyFiles@2 ++ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'), ne(variables['CI_BUILD_SPHINX_DOCS'], '1')) + inputs: + sourceFolder: '$(Agent.BuildDirectory)/s/build/' + contents: '$(Agent.BuildDirectory)/s/build/?(*.deb|*.rpm)' + targetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishPipelineArtifact@1 +- condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) ++ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'), ne(variables['CI_BUILD_SPHINX_DOCS'], '1')) + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: '$(artifactName)' +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0006-man-allow-man-pages-to-be-built-when-not-in-a-.-buil.patch libiio-0.23/debian/patches/0006-man-allow-man-pages-to-be-built-when-not-in-a-.-buil.patch --- libiio-0.21/debian/patches/0006-man-allow-man-pages-to-be-built-when-not-in-a-.-buil.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0006-man-allow-man-pages-to-be-built-when-not-in-a-.-buil.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -From ebe67a87d2d66ef60442613a479cfa4a574d0229 Mon Sep 17 00:00:00 2001 -From: Robin Getz -Date: Wed, 22 Jul 2020 16:16:42 -0400 -Subject: [PATCH 06/53] man: allow man pages to be built when not in a ./build - dir - -as pointed out in #555, we assumed that iio.h was always one directory -up, which is sort of bad form. - -Don't make that assumption, and process things with the CMAKE system. - -Signed-off-by: Robin Getz ---- - man/CMakeLists.txt | 5 ++++- - man/{make_man.sh => make_man.sh.in} | 11 ++++++----- - 2 files changed, 10 insertions(+), 6 deletions(-) - rename man/{make_man.sh => make_man.sh.in} (97%) - -diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt -index 5183685..c8924b5 100644 ---- a/man/CMakeLists.txt -+++ b/man/CMakeLists.txt -@@ -4,8 +4,11 @@ if (WITH_MAN) - execute_process( - COMMAND ${DATE_EXECUTABLE} "+%d %B %Y" - OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) -+ configure_file( -+ ${CMAKE_CURRENT_SOURCE_DIR}/make_man.sh.in -+ ${CMAKE_CURRENT_BINARY_DIR}/make_man.sh @ONLY) - execute_process( -- COMMAND ${BASH_EXECUTABLE} "-c" "${CMAKE_CURRENT_SOURCE_DIR}/make_man.sh > ${CMAKE_BINARY_DIR}/libiio.3.in" -+ COMMAND ${BASH_EXECUTABLE} "-c" "${CMAKE_CURRENT_BINARY_DIR}/make_man.sh > ${CMAKE_BINARY_DIR}/libiio.3.in" - ) - configure_file( - ${CMAKE_BINARY_DIR}/libiio.3.in -diff --git a/man/make_man.sh b/man/make_man.sh.in -similarity index 97% -rename from man/make_man.sh -rename to man/make_man.sh.in -index 57e3e5c..bdc5b2d 100755 ---- a/man/make_man.sh -+++ b/man/make_man.sh.in -@@ -1,9 +1,10 @@ - #!/bin/bash -e - --if [ -z "$TRAVIS_BUILD_DIR" ] ; then -- header="../iio.h" --else -- header="$TRAVIS_BUILD_DIR/iio.h" -+header="@CMAKE_SOURCE_DIR@/iio.h" -+ -+if [ ! -f "${header}" ] ; then -+ echo "Can not find iio.h at ${header}" -+ exit - fi - - cat < +Date: Mon, 13 Sep 2021 14:25:27 +0300 +Subject: [PATCH 07/26] CI: make file executable + +Signed-off-by: Raluca Chis +--- + CI/travis/prepare_assets.sh | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + mode change 100644 => 100755 CI/travis/prepare_assets.sh + +diff --git a/CI/travis/prepare_assets.sh b/CI/travis/prepare_assets.sh +old mode 100644 +new mode 100755 +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0007-cmake-set-_WIN32_WINNT-when-compiling-with-mingw.patch libiio-0.23/debian/patches/0007-cmake-set-_WIN32_WINNT-when-compiling-with-mingw.patch --- libiio-0.21/debian/patches/0007-cmake-set-_WIN32_WINNT-when-compiling-with-mingw.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0007-cmake-set-_WIN32_WINNT-when-compiling-with-mingw.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From d3be2ee68078c1f42c94b082c65653c9cc26db45 Mon Sep 17 00:00:00 2001 -From: Robin Getz -Date: Thu, 23 Jul 2020 11:19:43 -0400 -Subject: [PATCH 07/53] cmake: set _WIN32_WINNT when compiling with mingw - -This should fix #569 - -Signed-off-by: Robin Getz ---- - CMakeLists.txt | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index c044fe0..4f1ab21 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -86,6 +86,16 @@ elseif (CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") - endif() - endif() -+ -+ # Per http://www.mingw.org/wiki/Use_more_recent_defined_functions -+ if (MINGW) -+ # Build for Vista and above -+ # check mingw-w64-headers/include/w32api.h or windows sdkddkver.h -+ # https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt -+ # using a hex value is bad - but stops from loading the otherwise unnecessary headers -+ set(CMAKE_C_FLAGS "-D_WIN32_WINNT=0x600 ${CMAKE_C_FLAGS}") -+ set(CMAKE_C_FLAGS "-DWINVER=0x600 ${CMAKE_C_FLAGS}") -+ endif() - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -Wno-unused-parameter") - else() --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0008-local-Fix-detection-of-scan-element-channels.patch libiio-0.23/debian/patches/0008-local-Fix-detection-of-scan-element-channels.patch --- libiio-0.21/debian/patches/0008-local-Fix-detection-of-scan-element-channels.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0008-local-Fix-detection-of-scan-element-channels.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,38 @@ +From 00d9621d6cd3f42bc92e5a095a780e77bc0f34df Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Wed, 8 Sep 2021 09:35:03 +0100 +Subject: [PATCH 08/26] local: Fix detection of scan-element channels + +Previously, the detection of buffer-capable channels would fail when the +channel had attributes outside the scan_elements/ folder, as the channel +would be correctly marked as buffer-capable when the first attribute +was found, but then overriden as non-buffer-capable as soon as an +attribute outside the scan_elements/ folder was found. + +It went unnoticed until now, most likely because there is generally +either scan-elements attributes or non-scan-elements attributes, and +rarely both. + +Fixes #740. + +Signed-off-by: Paul Cercueil +--- + local.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/local.c b/local.c +index bbb62fea..e9095201 100644 +--- a/local.c ++++ b/local.c +@@ -1476,7 +1476,7 @@ static int add_channel(struct iio_device *dev, const char *name, + free(channel_id); + ret = add_attr_to_channel(chn, name, path, + dir_is_scan_elements); +- chn->is_scan_element = dir_is_scan_elements && !ret; ++ chn->is_scan_element |= dir_is_scan_elements && !ret; + return ret; + } + } +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0008-python-Do-not-verify-whether-libiio-is-installed-whe.patch libiio-0.23/debian/patches/0008-python-Do-not-verify-whether-libiio-is-installed-whe.patch --- libiio-0.21/debian/patches/0008-python-Do-not-verify-whether-libiio-is-installed-whe.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0008-python-Do-not-verify-whether-libiio-is-installed-whe.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -From 68ab31448e108cc13de1a45744fd487021c48f15 Mon Sep 17 00:00:00 2001 -From: Julien Malik -Date: Mon, 27 Jul 2020 14:34:44 +0200 -Subject: [PATCH 08/53] python: Do not verify whether libiio is installed when - cross-compiling - -This should fix #561 - -Signed-off-by: Julien Malik ---- - bindings/python/setup.py.cmakein | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/bindings/python/setup.py.cmakein b/bindings/python/setup.py.cmakein -index b13778e..dfbcc3b 100644 ---- a/bindings/python/setup.py.cmakein -+++ b/bindings/python/setup.py.cmakein -@@ -54,6 +54,13 @@ class InstallWrapper(install): - install.run(self) - - def _check_libiio_installed(self): -+ cross_compiling = ("${CMAKE_CROSSCOMPILING}" == "TRUE") -+ if cross_compiling: -+ # When cross-compiling, we generally cannot dlopen -+ # the libiio shared lib from the build platform. -+ # Simply skip this check in that case. -+ return -+ - from platform import system as _system - from ctypes import CDLL as _cdll - from ctypes.util import find_library --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0009-appveyor.yml-Update-the-MSYS-build-keyring-manually.patch libiio-0.23/debian/patches/0009-appveyor.yml-Update-the-MSYS-build-keyring-manually.patch --- libiio-0.21/debian/patches/0009-appveyor.yml-Update-the-MSYS-build-keyring-manually.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0009-appveyor.yml-Update-the-MSYS-build-keyring-manually.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From 56e5d6ad49b41ffa6ca00fcba7dda1e2989ea410 Mon Sep 17 00:00:00 2001 -From: Alexandra Trifan -Date: Wed, 29 Jul 2020 16:24:36 +0300 -Subject: [PATCH 09/53] appveyor.yml: Update the MSYS build keyring manually. - -We can revert this commit once appveyor updates the installer for MSYS. -https://www.msys2.org/news/#2020-06-29-new-packagers - -Signed-off-by: Alexandra Trifan ---- - appveyor.yml | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/appveyor.yml b/appveyor.yml -index 7111ea3..068be43 100644 ---- a/appveyor.yml -+++ b/appveyor.yml -@@ -38,8 +38,13 @@ build_script: - - C:\msys64\usr\bin\bash -lc "pwd" - - mkdir C:\projects\libiio\build-mingw-win32\"%configuration%"& cd C:\projects\libiio\build-mingw-win32\"%configuration%" - - C:\msys64\usr\bin\bash -lc "pwd" -- # TODO: Check when the latest pacman version is fixed and revert this commit. -- - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U http://repo.msys2.org/msys/x86_64/pacman-5.2.1-6-x86_64.pkg.tar.xz" -+ # TODO: Revert this after appveyor supports the latest installer. -+ - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U http://repo.msys2.org/msys/x86_64/pacman-5.2.2-1-x86_64.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -+ - C:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz{.sig,}" -+ - C:\msys64\usr\bin\bash -lc "pacman-key --populate" -+ - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syu" - - C:\msys64\usr\bin\bash -lc "pacman -Rs --noconfirm mingw-w64-i686-gcc-ada mingw-w64-i686-gcc-fortran mingw-w64-i686-gcc-libgfortran mingw-w64-i686-gcc-objc" - - C:\msys64\usr\bin\bash -lc "rm /mingw32/etc/gdbinit" --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0009-CI-push-windows-setup.exe-to-SWDownloads.patch libiio-0.23/debian/patches/0009-CI-push-windows-setup.exe-to-SWDownloads.patch --- libiio-0.21/debian/patches/0009-CI-push-windows-setup.exe-to-SWDownloads.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0009-CI-push-windows-setup.exe-to-SWDownloads.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,25 @@ +From 8c06bd4be1fe0fcc4910272dd70b5008b2a58793 Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Thu, 30 Sep 2021 16:50:37 +0300 +Subject: [PATCH 09/26] CI: push windows setup.exe to SWDownloads + +Signed-off-by: Raluca Chis +--- + azure-pipelines.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index 138993af..b0cbb1c5 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -221,6 +221,7 @@ stages: + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: 'Libiio-Setup-Exe' + - job: PushToSWDownloads ++ dependsOn: GenerateSetupExe + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + pool: + vmImage: 'ubuntu-latest' +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0010-iio_attr-accept-negative-numbers-as-data-to-write-to.patch libiio-0.23/debian/patches/0010-iio_attr-accept-negative-numbers-as-data-to-write-to.patch --- libiio-0.21/debian/patches/0010-iio_attr-accept-negative-numbers-as-data-to-write-to.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0010-iio_attr-accept-negative-numbers-as-data-to-write-to.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -From b5bc289c5029181ccd09aff990c9c526e2cc2847 Mon Sep 17 00:00:00 2001 -From: Robin Getz -Date: Tue, 28 Jul 2020 14:56:02 -0400 -Subject: [PATCH 10/53] iio_attr: accept negative numbers as data to write to - -getopt doesn't understand the difference between the '-' before an -option and the '-' before a negative number. It can not - they are both -the same, and in some applications option zero (-0) might be valid. - -in iio_attr this causes problems when we try to write negative numbers - -root@analog:~# iio_attr -o -c adrv9002-phy voltage0 hardwaregain -10 -iio_attr: invalid option -- '1' - -Since the only time we do this in in iio_attr, handle the last option -differently (if the last option is a negative number). - -This does mean we still don't pass -foo to an attribute to be written, -since iio_attr thinks that is an unknown "-f" option. - -./tests/iio_attr -v -a usb -o -c ad9361-phy voltage0 hardwaregain -foo -Using auto-detected IIO context at URI "usb:3.39.5" -./tests/iio_attr: invalid option -- 'f' - -but this does fix the reported bug #573 - -./tests/iio_attr -v -a usb -o -c ad9361-phy voltage0 hardwaregain -1 -Using auto-detected IIO context at URI "usb:3.39.5" -dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain', value '-10.000000 dB' -wrote 3 bytes to hardwaregain -dev 'ad9361-phy', channel 'voltage0' (output), attr 'hardwaregain', value '-1.000000 dB' - -Signed-off-by: Robin Getz ---- - tests/iio_attr.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/tests/iio_attr.c b/tests/iio_attr.c -index bf03960..bc3b1de 100644 ---- a/tests/iio_attr.c -+++ b/tests/iio_attr.c -@@ -353,7 +353,7 @@ int main(int argc, char **argv) - { - char **argw; - struct iio_context *ctx; -- int c; -+ int c, argd = argc; - int device_index = 0, channel_index = 0, attr_index = 0; - const char *gen_file = NULL; - bool search_device = false, ignore_case = false, -@@ -371,13 +371,24 @@ int main(int argc, char **argv) - - argw = dup_argv(MY_NAME, argc, argv); - -- ctx = handle_common_opts(MY_NAME, argc, argw, MY_OPTS, options, options_descriptions); -+ /* -+ * getopt_long() thinks negative numbers are options, -1 is option '1' -+ * The only time we should see a negative number is the last argument during a write, -+ * so if there is one, we skip that argument during getopt processing -+ * look for "-" followed by a number. -+ */ -+ if (strnlen(argv[argc - 1], 2) >= 2 && argv[argc - 1][0] == '-' && -+ (argv[argc - 1][1] >= '0' && argv[argc - 1][1] <= '9')) { -+ argd--; -+ } -+ -+ ctx = handle_common_opts(MY_NAME, argd, argw, MY_OPTS, options, options_descriptions); - opts = add_common_options(options); - if (!opts) { - fprintf(stderr, "Failed to add common options\n"); - return EXIT_FAILURE; - } -- while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ -+ while ((c = getopt_long(argd, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ - opts, NULL)) != -1) { - switch (c) { - /* All these are handled in the common */ --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0010-iiod-Add-is_usb-field-to-pdata-structure.patch libiio-0.23/debian/patches/0010-iiod-Add-is_usb-field-to-pdata-structure.patch --- libiio-0.21/debian/patches/0010-iiod-Add-is_usb-field-to-pdata-structure.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0010-iiod-Add-is_usb-field-to-pdata-structure.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,100 @@ +From 5595f1b32eb81310ed326f3126681a2590916159 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 24 Sep 2021 14:19:35 +0100 +Subject: [PATCH 10/26] iiod: Add 'is_usb' field to pdata structure + +This field will then be used in the readfd() and/or writefd() callbacks +as USB communication has to be handled slightly differently. + +Signed-off-by: Paul Cercueil +--- + iiod/iiod.c | 5 +++-- + iiod/ops.c | 6 ++++-- + iiod/ops.h | 3 ++- + iiod/usbd.c | 2 +- + 4 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/iiod/iiod.c b/iiod/iiod.c +index 178558b9..78131e69 100644 +--- a/iiod/iiod.c ++++ b/iiod/iiod.c +@@ -109,7 +109,7 @@ static void client_thd(struct thread_pool *pool, void *d) + struct client_data *cdata = d; + + interpreter(cdata->ctx, cdata->fd, cdata->fd, cdata->debug, +- true, false, pool, ++ true, false, false, pool, + cdata->xml_zstd, cdata->xml_zstd_len); + + IIO_INFO("Client exited\n"); +@@ -158,7 +158,8 @@ static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio, + } + + interpreter(ctx, STDIN_FILENO, STDOUT_FILENO, verbose, +- false, use_aio, main_thread_pool, xml_zstd, xml_zstd_len); ++ false, false, use_aio, main_thread_pool, ++ xml_zstd, xml_zstd_len); + return EXIT_SUCCESS; + } + +diff --git a/iiod/ops.c b/iiod/ops.c +index 5fc8c918..38e2fbbc 100644 +--- a/iiod/ops.c ++++ b/iiod/ops.c +@@ -1459,8 +1459,9 @@ ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + } + + void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, +- bool is_socket, bool use_aio, struct thread_pool *pool, +- const void *xml_zstd, size_t xml_zstd_len) ++ bool is_socket, bool is_usb, bool use_aio, ++ struct thread_pool *pool, const void *xml_zstd, ++ size_t xml_zstd_len) + { + yyscan_t scanner; + struct parser_pdata pdata; +@@ -1479,6 +1480,7 @@ void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, + + pdata.fd_in_is_socket = is_socket; + pdata.fd_out_is_socket = is_socket; ++ pdata.is_usb = is_usb; + + SLIST_INIT(&pdata.thdlist_head); + +diff --git a/iiod/ops.h b/iiod/ops.h +index 07bad939..0da5ca48 100644 +--- a/iiod/ops.h ++++ b/iiod/ops.h +@@ -66,6 +66,7 @@ struct parser_pdata { + struct iio_channel *chn; + bool channel_is_output; + bool fd_in_is_socket, fd_out_is_socket; ++ bool is_usb; + #if WITH_AIO + io_context_t aio_ctx; + int aio_eventfd; +@@ -88,7 +89,7 @@ static inline void *zalloc(size_t size) + } + + void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, +- bool is_socket, bool use_aio, struct thread_pool *pool, ++ bool is_socket, bool is_usb, bool use_aio, struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len); + + int start_usb_daemon(struct iio_context *ctx, const char *ffs, +diff --git a/iiod/usbd.c b/iiod/usbd.c +index 22ad7197..3385f5b5 100644 +--- a/iiod/usbd.c ++++ b/iiod/usbd.c +@@ -71,7 +71,7 @@ static void usbd_client_thread(struct thread_pool *pool, void *d) + struct usbd_client_pdata *pdata = d; + + interpreter(pdata->pdata->ctx, pdata->ep_in, pdata->ep_out, +- pdata->pdata->debug, false, ++ pdata->pdata->debug, false, true, + pdata->pdata->use_aio, pool, + pdata->pdata->xml_zstd, pdata->pdata->xml_zstd_len); + +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0011-iiod-Update-read_line-to-work-with-UART.patch libiio-0.23/debian/patches/0011-iiod-Update-read_line-to-work-with-UART.patch --- libiio-0.21/debian/patches/0011-iiod-Update-read_line-to-work-with-UART.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0011-iiod-Update-read_line-to-work-with-UART.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,85 @@ +From aad53e37e40a0c4ff48a8e7cf3cf2b4e0495ec21 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 24 Sep 2021 14:20:42 +0100 +Subject: [PATCH 11/26] iiod: Update read_line() to work with UART + +Previously, in the non-socket case, read_line() would read as much data +as possible in one read() call. As it was used almost exclusively for +USB, the amount of data returned always corresponded to the size of the bulk +data sent by the client, aka. a full line and nothing more. + +With UART though, if we try reading as much data as possible, we might +get just that, and end up reading much more data than we need, +disrupting the protocol. + +Fix this by reading character by character until the \n is found in the +non-socket, non-USB case. + +Signed-off-by: Paul Cercueil +--- + iiod/ops.c | 34 ++++++++++++++++++++++++++-------- + 1 file changed, 26 insertions(+), 8 deletions(-) + +diff --git a/iiod/ops.c b/iiod/ops.c +index 38e2fbbc..d1c1cdae 100644 +--- a/iiod/ops.c ++++ b/iiod/ops.c +@@ -1397,12 +1397,12 @@ err_print_value: + + ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + { ++ size_t bytes_read = 0; + ssize_t ret; ++ bool found; + + if (pdata->fd_in_is_socket) { + struct pollfd pfd[2]; +- bool found; +- size_t bytes_read = 0; + + pfd[0].fd = pdata->fd_in; + pfd[0].events = POLLIN | POLLRDHUP; +@@ -1445,16 +1445,34 @@ ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + + bytes_read += to_trunc; + } while (!found && len); ++ } else if (pdata->is_usb) { ++ ret = pdata->readfd(pdata, buf, len); + +- /* No \n found? Just garbage data */ +- if (!found) +- ret = -EIO; +- else +- ret = bytes_read; ++ found = buf[ret - 1] == '\n'; + } else { +- ret = pdata->readfd(pdata, buf, len); ++ while (len) { ++ ret = pdata->readfd(pdata, buf, 1); ++ if (ret < 0) ++ return ret; ++ ++ bytes_read++; ++ ++ if (*buf == '\n') ++ break; ++ ++ len--; ++ buf++; ++ } ++ ++ found = !!len; + } + ++ /* No \n found? Just garbage data */ ++ if (!found) ++ ret = -EIO; ++ else ++ ret = bytes_read; ++ + return ret; + } + +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0011-local-don-t-keep-internal-state-if-buffer-enabled.patch libiio-0.23/debian/patches/0011-local-don-t-keep-internal-state-if-buffer-enabled.patch --- libiio-0.21/debian/patches/0011-local-don-t-keep-internal-state-if-buffer-enabled.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0011-local-don-t-keep-internal-state-if-buffer-enabled.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -From 722d7ae066450b54059df89092b55155fc89a3b1 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Fri, 24 Jul 2020 10:41:16 +0300 -Subject: [PATCH 11/53] local: don't keep internal state if buffer enabled - -This also does a minor rework in re-defining the 'local_enable_buffer()' -function into a 'local_buffer_enabled_set(..., bool en)' function which can -enable/disable a local buffer by writing into the 'buffer/enable'. - -Keeping an internal state complicated things, as this state should be -handled by the kernel. -Even so, the original local_enable_buffer() would only get called once, -while the 'local_open()' function would also bypass this state potentially -causing inconsistency. - -Signed-off-by: Alexandru Ardelean ---- - local.c | 24 +++++++----------------- - 1 file changed, 7 insertions(+), 17 deletions(-) - -diff --git a/local.c b/local.c -index 1004b00..162eded 100644 ---- a/local.c -+++ b/local.c -@@ -97,7 +97,7 @@ struct iio_device_pdata { - struct block *blocks; - void **addrs; - int last_dequeued; -- bool is_high_speed, cyclic, cyclic_buffer_enqueued, buffer_enabled; -+ bool is_high_speed, cyclic, cyclic_buffer_enqueued; - - int cancel_fd; - }; -@@ -413,19 +413,10 @@ static ssize_t local_write(const struct iio_device *dev, - return ret; - } - --static ssize_t local_enable_buffer(const struct iio_device *dev) -+static ssize_t local_buffer_enabled_set(const struct iio_device *dev, bool en) - { -- struct iio_device_pdata *pdata = dev->pdata; -- ssize_t ret = 0; -- -- if (!pdata->buffer_enabled) { -- ret = local_write_dev_attr(dev, -- "buffer/enable", "1", 2, false); -- if (ret >= 0) -- pdata->buffer_enabled = true; -- } -- -- return ret; -+ return local_write_dev_attr(dev, "buffer/enable", en ? "1" : "0", -+ 2, false); - } - - static int local_set_kernel_buffers_count(const struct iio_device *dev, -@@ -921,7 +912,7 @@ static int local_open(const struct iio_device *dev, - if (pdata->fd != -1) - return -EBUSY; - -- ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false); -+ ret = local_buffer_enabled_set(dev, false); - if (ret < 0) - return ret; - -@@ -963,7 +954,6 @@ static int local_open(const struct iio_device *dev, - - pdata->cyclic = cyclic; - pdata->cyclic_buffer_enqueued = false; -- pdata->buffer_enabled = false; - pdata->samples_count = samples_count; - - ret = enable_high_speed(dev); -@@ -992,7 +982,7 @@ static int local_open(const struct iio_device *dev, - goto err_close; - } - -- ret = local_enable_buffer(dev); -+ ret = local_buffer_enabled_set(dev, true); - if (ret < 0) - goto err_close; - -@@ -1036,7 +1026,7 @@ static int local_close(const struct iio_device *dev) - pdata->fd = -1; - pdata->cancel_fd = -1; - -- ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false); -+ ret = local_buffer_enabled_set(dev, false); - - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *chn = dev->channels[i]; --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0012-iiod-thread-pool-Add-function-thread_pool_is_stopped.patch libiio-0.23/debian/patches/0012-iiod-thread-pool-Add-function-thread_pool_is_stopped.patch --- libiio-0.21/debian/patches/0012-iiod-thread-pool-Add-function-thread_pool_is_stopped.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0012-iiod-thread-pool-Add-function-thread_pool_is_stopped.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,80 @@ +From d97a476f45fb7ac00664779a1826da491e0ba882 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Thu, 15 Apr 2021 15:10:39 +0100 +Subject: [PATCH 12/26] iiod: thread-pool: Add function thread_pool_is_stopped + +This function can be used to know whether or not thread_pool_stop() was +called on a thread pool. + +Signed-off-by: Paul Cercueil +--- + iiod/thread-pool.c | 10 ++++++++++ + iiod/thread-pool.h | 3 +++ + 2 files changed, 13 insertions(+) + +diff --git a/iiod/thread-pool.c b/iiod/thread-pool.c +index d8fa6b83..2fd30825 100644 +--- a/iiod/thread-pool.c ++++ b/iiod/thread-pool.c +@@ -31,6 +31,7 @@ struct thread_pool { + pthread_cond_t thread_count_cond; + unsigned int thread_count; + int stop_fd; ++ bool stop; + }; + + struct thread_body_data { +@@ -130,6 +131,8 @@ struct thread_pool * thread_pool_new(void) + return NULL; + } + ++ pool->stop = false; ++ + pthread_mutex_init(&pool->thread_count_lock, NULL); + pthread_cond_init(&pool->thread_count_cond, NULL); + pool->thread_count = 0; +@@ -147,6 +150,8 @@ void thread_pool_stop(struct thread_pool *pool) + uint64_t e = 1; + int ret; + ++ pool->stop = true; ++ + do { + ret = write(pool->stop_fd, &e, sizeof(e)); + } while (ret == -1 && errno == EINTR); +@@ -170,6 +175,11 @@ void thread_pool_stop_and_wait(struct thread_pool *pool) + } while (ret != -1 || errno == EINTR); + } + ++bool thread_pool_is_stopped(const struct thread_pool *pool) ++{ ++ return pool->stop; ++} ++ + void thread_pool_destroy(struct thread_pool *pool) + { + pthread_mutex_destroy(&pool->thread_count_lock); +diff --git a/iiod/thread-pool.h b/iiod/thread-pool.h +index 3b83d569..b4e8bf0b 100644 +--- a/iiod/thread-pool.h ++++ b/iiod/thread-pool.h +@@ -9,6 +9,8 @@ + #ifndef __THREAD_POOL_H__ + #define __THREAD_POOL_H__ + ++#include ++ + struct thread_pool; + + struct thread_pool * thread_pool_new(void); +@@ -16,6 +18,7 @@ struct thread_pool * thread_pool_new(void); + int thread_pool_get_poll_fd(const struct thread_pool *pool); + void thread_pool_stop(struct thread_pool *pool); + void thread_pool_stop_and_wait(struct thread_pool *pool); ++bool thread_pool_is_stopped(const struct thread_pool *pool); + + void thread_pool_destroy(struct thread_pool *pool); + +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0012-local-harden-local_close-and-use-it-for-local_open-f.patch libiio-0.23/debian/patches/0012-local-harden-local_close-and-use-it-for-local_open-f.patch --- libiio-0.21/debian/patches/0012-local-harden-local_close-and-use-it-for-local_open-f.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0012-local-harden-local_close-and-use-it-for-local_open-f.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -From 128446b1b42727447693b016de22693a6cfeefd9 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Fri, 24 Jul 2020 10:47:06 +0300 -Subject: [PATCH 12/53] local: harden local_close() and use it for local_open() - failure - -There's a bug, when enabling a buffer (with local_buffer_enabled_set(), -i.e. writing to 'buffer/enable'), we can get -EINVAL, because the scan_mask -is invalidated by the kernel. -The issue seems to be that the local_open() exit-on-failure path is -un-balanced. Some things don't seem to be cleaned-up on exit-on-failure. - -This is seen with iiod trying to open a high-speed buffer device, where the -exit-on-failure path does not call munmap() on the buffers, nor does it -free the memory allocated for the buffer (in libiio). On the next -retry/open the buffer device is locked and -EBUSY is returned. -Essentially, this leaks resources (a file-descriptor and some memory for -the buffers). -Closing and re-opening iiod fixes the issue. - -Also, the local_close() function should not exit on the first fail in -finds. It should continue with disabling everything it can. The only error -that might make sense, is if the main FD is not initialized. - -This change simplifies the local_close() a bit: we return -EBADF if the -main FD is -1. Other than that, we continue disabling/cleaning everything -else (with the proper NULL/fd checks in place). - -This makes it re-usable for the local_open() exit-on-failure path. -This could be addressed [also] by balancing the initialization in the -reverse order of init. But it looks like something might be omitted later -(as they were up until now) in the exit-on-failure path. -So maybe a more future-proof method is to just re-use the local_open() -routine where possible. - -Signed-off-by: Alexandru Ardelean ---- - local.c | 39 +++++++++++++++++++-------------------- - 1 file changed, 19 insertions(+), 20 deletions(-) - -diff --git a/local.c b/local.c -index 162eded..389ed3e 100644 ---- a/local.c -+++ b/local.c -@@ -901,6 +901,8 @@ err_freemem: - return ret; - } - -+static int local_close(const struct iio_device *dev); -+ - static int local_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -@@ -929,8 +931,8 @@ static int local_open(const struct iio_device *dev, - iio_snprintf(buf, sizeof(buf), "/dev/%s", dev->id); - pdata->fd = open(buf, O_RDWR | O_CLOEXEC | O_NONBLOCK); - if (pdata->fd == -1) { -- ret = -errno; -- goto err_close_cancel_fd; -+ close(pdata->cancel_fd); -+ return -errno; - } - - /* Disable channels */ -@@ -988,11 +990,7 @@ static int local_open(const struct iio_device *dev, - - return 0; - err_close: -- close(pdata->fd); -- pdata->fd = -1; --err_close_cancel_fd: -- close(pdata->cancel_fd); -- pdata->cancel_fd = -1; -+ local_close(dev); - return ret; - } - -@@ -1000,16 +998,18 @@ static int local_close(const struct iio_device *dev) - { - struct iio_device_pdata *pdata = dev->pdata; - unsigned int i; -- int ret; - - if (pdata->fd == -1) - return -EBADF; - - if (pdata->is_high_speed) { - unsigned int i; -- for (i = 0; i < pdata->allocated_nb_blocks; i++) -- munmap(pdata->addrs[i], pdata->blocks[i].size); -- ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); -+ if (pdata->addrs) { -+ for (i = 0; i < pdata->allocated_nb_blocks; i++) -+ munmap(pdata->addrs[i], pdata->blocks[i].size); -+ } -+ if (pdata->fd > -1) -+ ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); - pdata->allocated_nb_blocks = 0; - free(pdata->addrs); - pdata->addrs = NULL; -@@ -1017,16 +1017,15 @@ static int local_close(const struct iio_device *dev) - pdata->blocks = NULL; - } - -- ret = close(pdata->fd); -- if (ret) -- return ret; -- -- close(pdata->cancel_fd); -- -+ close(pdata->fd); - pdata->fd = -1; -- pdata->cancel_fd = -1; - -- ret = local_buffer_enabled_set(dev, false); -+ if (pdata->cancel_fd > -1) { -+ close(pdata->cancel_fd); -+ pdata->cancel_fd = -1; -+ } -+ -+ local_buffer_enabled_set(dev, false); - - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *chn = dev->channels[i]; -@@ -1035,7 +1034,7 @@ static int local_close(const struct iio_device *dev) - channel_write_state(chn, false); - } - -- return (ret < 0) ? ret : 0; -+ return 0; - } - - static int local_get_fd(const struct iio_device *dev) --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0013-iiod-Support-running-on-UART.patch libiio-0.23/debian/patches/0013-iiod-Support-running-on-UART.patch --- libiio-0.21/debian/patches/0013-iiod-Support-running-on-UART.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0013-iiod-Support-running-on-UART.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,417 @@ +From 2d3cae005f364742b3a9e7234d15b2fd2cbac664 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Wed, 7 Apr 2021 14:27:39 +0100 +Subject: [PATCH 13/26] iiod: Support running on UART + +Add a -s option to serve IIO over UART. This option requires the UART +dev node and optionally the baud/parity/bits/stop bits/flow settings +to be specified as the parameter. + +For instance, this will run IIOD on the /dev/ttyS2 UART, at 57600 bps, +no parity, 8 bits per datum, 1 stop bit and RTS/CTS flow control: + +iiod -s /dev/ttyS2,57600,8n1r + +Fixes #560. + +Signed-off-by: Paul Cercueil +--- + iio-config.h.cmakein | 1 + + iiod/CMakeLists.txt | 5 + + iiod/iiod.c | 26 ++++- + iiod/ops.h | 3 + + iiod/serial.c | 270 +++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 304 insertions(+), 1 deletion(-) + create mode 100644 iiod/serial.c + +diff --git a/iio-config.h.cmakein b/iio-config.h.cmakein +index 781bfb6c..1854f47b 100644 +--- a/iio-config.h.cmakein ++++ b/iio-config.h.cmakein +@@ -16,6 +16,7 @@ + #cmakedefine WITH_NETWORK_GET_BUFFER + #cmakedefine01 WITH_NETWORK_EVENTFD + #cmakedefine01 WITH_IIOD_USBD ++#cmakedefine01 WITH_IIOD_SERIAL + #cmakedefine01 WITH_LOCAL_CONFIG + #cmakedefine01 WITH_AIO + #cmakedefine01 HAVE_DNS_SD +diff --git a/iiod/CMakeLists.txt b/iiod/CMakeLists.txt +index b91f0014..39b644c9 100644 +--- a/iiod/CMakeLists.txt ++++ b/iiod/CMakeLists.txt +@@ -55,6 +55,11 @@ if (WITH_AIO) + endif() + endif() + ++option(WITH_IIOD_SERIAL "Add serial (UART) support" ON) ++if (WITH_IIOD_SERIAL) ++ set(IIOD_CFILES ${IIOD_CFILES} serial.c) ++endif() ++ + add_executable(iiod ${IIOD_CFILES}) + set_target_properties(iiod PROPERTIES + C_STANDARD 99 +diff --git a/iiod/iiod.c b/iiod/iiod.c +index 78131e69..ebcecb56 100644 +--- a/iiod/iiod.c ++++ b/iiod/iiod.c +@@ -79,6 +79,7 @@ static const struct option options[] = { + {"aio", no_argument, 0, 'a'}, + {"ffs", required_argument, 0, 'F'}, + {"nb-pipes", required_argument, 0, 'n'}, ++ {"serial", required_argument, 0, 's'}, + {0, 0, 0, 0}, + }; + +@@ -91,6 +92,7 @@ static const char *options_descriptions[] = { + "Use asynchronous I/O.", + "Use the given FunctionFS mountpoint to serve over USB", + "Specify the number of USB pipes (ep couples) to use", ++ "Run " MY_NAME " on the specified UART.", + }; + + static void usage(void) +@@ -356,12 +358,13 @@ int main(int argc, char **argv) + struct iio_context *ctx; + int c, option_index = 0; + char *ffs_mountpoint = NULL; ++ char *uart_params = NULL; + char err_str[1024]; + void *xml_zstd; + size_t xml_zstd_len = 0; + int ret; + +- while ((c = getopt_long(argc, argv, "+hVdDiaF:n:", ++ while ((c = getopt_long(argc, argv, "+hVdDiaF:n:s:", + options, &option_index)) != -1) { + switch (c) { + case 'd': +@@ -402,6 +405,15 @@ int main(int argc, char **argv) + return EXIT_FAILURE; + } + break; ++ case 's': ++ if (!WITH_IIOD_SERIAL) { ++ IIO_ERROR("IIOD was not compiled with serial support.\n"); ++ return EXIT_FAILURE; ++ ++ } ++ ++ uart_params = optarg; ++ break; + case 'h': + usage(); + return EXIT_SUCCESS; +@@ -450,6 +462,18 @@ int main(int argc, char **argv) + } + } + ++ if (WITH_IIOD_SERIAL && uart_params) { ++ ret = start_serial_daemon(ctx, uart_params, ++ debug, main_thread_pool, ++ xml_zstd, xml_zstd_len); ++ if (ret) { ++ iio_strerror(-ret, err_str, sizeof(err_str)); ++ IIO_ERROR("Unable to start serial daemon: %s\n", err_str); ++ ret = EXIT_FAILURE; ++ goto out_destroy_thread_pool; ++ } ++ } ++ + if (interactive) + ret = main_interactive(ctx, debug, use_aio, xml_zstd, xml_zstd_len); + else +diff --git a/iiod/ops.h b/iiod/ops.h +index 0da5ca48..add7437b 100644 +--- a/iiod/ops.h ++++ b/iiod/ops.h +@@ -96,6 +96,9 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs, + bool debug, bool use_aio, unsigned int nb_pipes, + struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len); ++int start_serial_daemon(struct iio_context *ctx, const char *uart_params, ++ bool debug, struct thread_pool *pool, ++ const void *xml_zstd, size_t xml_zstd_len); + + int open_dev(struct parser_pdata *pdata, struct iio_device *dev, + size_t samples_count, const char *mask, bool cyclic); +diff --git a/iiod/serial.c b/iiod/serial.c +new file mode 100644 +index 00000000..544f053d +--- /dev/null ++++ b/iiod/serial.c +@@ -0,0 +1,270 @@ ++// SPDX-License-Identifier: LGPL-2.1-or-later ++/* ++ * libiio - Library for interfacing industrial I/O (IIO) devices ++ * ++ * Copyright (C) 2021 Analog Devices, Inc. ++ * Author: Paul Cercueil ++ */ ++ ++#include "../debug.h" ++#include "ops.h" ++#include "thread-pool.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct serial_pdata { ++ struct iio_context *ctx; ++ bool debug; ++ int fd; ++ const void *xml_zstd; ++ size_t xml_zstd_len; ++}; ++ ++static char *get_uart_params(const char *str, ++ unsigned int *bps, unsigned int *bits, ++ char *parity, unsigned int *stop, char *flow) ++{ ++ const char *ptr; ++ char *dev_name; ++ ++ /* Default values when unspecified */ ++ *bps = 57600; ++ *bits = 8; ++ *parity = 'n'; ++ *stop = 1; ++ *flow = '\0'; ++ ++ ptr = strchr(str, ','); ++ if (!ptr) { ++ dev_name = strdup(str); ++ } else { ++ dev_name = strndup(str, ptr - str); ++ sscanf(ptr, ",%u,%u%c%u%c", bps, bits, parity, stop, flow); ++ } ++ ++ return dev_name; ++} ++ ++static void serial_main(struct thread_pool *pool, void *d) ++{ ++ struct serial_pdata *pdata = d; ++ ++ do { ++ interpreter(pdata->ctx, pdata->fd, pdata->fd, pdata->debug, ++ false, false, false, pool, ++ pdata->xml_zstd, pdata->xml_zstd_len); ++ } while (!thread_pool_is_stopped(pool)); ++ ++ close(pdata->fd); ++ free(pdata); ++} ++ ++static int serial_configure(int fd, unsigned int uart_bps, ++ unsigned int uart_bits, ++ char uart_parity, ++ unsigned int uart_stop, ++ char uart_flow) ++{ ++ struct termios tty_attrs; ++ int err; ++ ++ err = tcgetattr(fd, &tty_attrs); ++ if (err == -1) { ++ IIO_ERROR("tcgetattr failed\n"); ++ return -errno; ++ } ++ ++ tty_attrs.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN); ++ tty_attrs.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); ++ ++ tty_attrs.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | ++ IGNCR | ICRNL | IMAXBEL | IXON | IXOFF); ++ ++ tty_attrs.c_cflag |= CLOCAL | CREAD | PARENB; ++ tty_attrs.c_cflag &= ~(CSIZE | CBAUD | CRTSCTS); ++#ifdef CMSPAR ++ tty_attrs.c_cflag &= ~CMSPAR; ++#endif ++ ++ tty_attrs.c_cc[VMIN] = 1; ++ tty_attrs.c_cc[VTIME] = 0; ++ ++#define CASE_BPS(bps, attr) case bps: (attr)->c_cflag |= B##bps; break ++ switch (uart_bps) { ++ CASE_BPS(50, &tty_attrs); ++ CASE_BPS(75, &tty_attrs); ++ CASE_BPS(110, &tty_attrs); ++ CASE_BPS(134, &tty_attrs); ++ CASE_BPS(150, &tty_attrs); ++ CASE_BPS(200, &tty_attrs); ++ CASE_BPS(300, &tty_attrs); ++ CASE_BPS(600, &tty_attrs); ++ CASE_BPS(1200, &tty_attrs); ++ CASE_BPS(1800, &tty_attrs); ++ CASE_BPS(2400, &tty_attrs); ++ CASE_BPS(4800, &tty_attrs); ++ CASE_BPS(9600, &tty_attrs); ++ CASE_BPS(19200, &tty_attrs); ++ CASE_BPS(38400, &tty_attrs); ++ CASE_BPS(57600, &tty_attrs); ++ CASE_BPS(115200, &tty_attrs); ++ CASE_BPS(230400, &tty_attrs); ++ CASE_BPS(460800, &tty_attrs); ++ CASE_BPS(500000, &tty_attrs); ++ CASE_BPS(576000, &tty_attrs); ++ CASE_BPS(921600, &tty_attrs); ++ CASE_BPS(1000000, &tty_attrs); ++ CASE_BPS(1152000, &tty_attrs); ++ CASE_BPS(1500000, &tty_attrs); ++ CASE_BPS(2000000, &tty_attrs); ++ CASE_BPS(2500000, &tty_attrs); ++ CASE_BPS(3000000, &tty_attrs); ++ CASE_BPS(3500000, &tty_attrs); ++ CASE_BPS(4000000, &tty_attrs); ++ default: ++ IIO_ERROR("Invalid baud rate\n"); ++ return -EINVAL; ++ } ++ ++ switch (uart_bits) { ++ case 5: ++ tty_attrs.c_cflag |= CS5; ++ break; ++ case 6: ++ tty_attrs.c_cflag |= CS6; ++ break; ++ case 7: ++ tty_attrs.c_cflag |= CS7; ++ break; ++ case 8: ++ tty_attrs.c_cflag |= CS8; ++ break; ++ default: ++ IIO_ERROR("Invalid serial configuration\n"); ++ return -EINVAL; ++ } ++ ++ switch (uart_parity) { ++ case 'n': ++ tty_attrs.c_cflag &= ~PARENB; ++ break; ++ case 'm': ++#ifndef CMSPAR ++ IIO_ERROR("\"mark\" parity not supported on this system.\n"); ++ return -EINVAL; ++#else ++ tty_attrs.c_cflag |= CMSPAR; ++#endif ++ /* falls through */ ++ case 'o': ++ tty_attrs.c_cflag |= PARODD; ++ break; ++ case 's': ++#ifndef CMSPAR ++ IIO_ERROR("\"space\" parity not supported on this system.\n"); ++ return -EINVAL; ++#else ++ tty_attrs.c_cflag |= CMSPAR; ++#endif ++ /* falls through */ ++ case 'e': ++ tty_attrs.c_cflag &= ~PARODD; ++ break; ++ default: ++ IIO_ERROR("Invalid serial configuration\n"); ++ return -EINVAL; ++ } ++ ++ switch (uart_stop) { ++ case 1: ++ tty_attrs.c_cflag &= ~CSTOPB; ++ break; ++ case 2: ++ tty_attrs.c_cflag |= CSTOPB; ++ break; ++ default: ++ IIO_ERROR("Invalid serial configuration\n"); ++ return -EINVAL; ++ } ++ ++ switch (uart_flow) { ++ case '\0': ++ break; ++ case 'x': ++ tty_attrs.c_iflag |= IXON | IXOFF; ++ break; ++ case 'r': ++ tty_attrs.c_cflag |= CRTSCTS; ++ break; ++ case 'd': ++ IIO_ERROR("DTR/SDR is unsupported\n"); ++ return -EINVAL; ++ default: ++ IIO_ERROR("Invalid serial configuration\n"); ++ return -EINVAL; ++ } ++ ++ err = tcsetattr(fd, TCSANOW, &tty_attrs); ++ if (err == -1) { ++ IIO_ERROR("Unable to apply serial settings\n"); ++ return -errno; ++ } ++ ++ return 0; ++} ++ ++int start_serial_daemon(struct iio_context *ctx, const char *uart_params, ++ bool debug, struct thread_pool *pool, ++ const void *xml_zstd, size_t xml_zstd_len) ++{ ++ struct serial_pdata *pdata; ++ char *dev, uart_parity, uart_flow; ++ unsigned int uart_bps, uart_bits, uart_stop; ++ int fd, err = -ENOMEM; ++ ++ dev = get_uart_params(uart_params, &uart_bps, &uart_bits, ++ &uart_parity, &uart_stop, &uart_flow); ++ if (!dev) ++ return -ENOMEM; ++ ++ pdata = zalloc(sizeof(*pdata)); ++ if (!pdata) ++ goto err_free_dev; ++ ++ fd = open(dev, O_RDWR | O_CLOEXEC); ++ if (fd == -1) { ++ err = -errno; ++ goto err_free_pdata; ++ } ++ ++ err = serial_configure(fd, uart_bps, uart_bits, ++ uart_parity, uart_stop, uart_flow); ++ if (err) ++ goto err_close_fd; ++ ++ pdata->ctx = ctx; ++ pdata->debug = debug; ++ pdata->fd = fd; ++ pdata->xml_zstd = xml_zstd; ++ pdata->xml_zstd_len = xml_zstd_len; ++ ++ IIO_DEBUG("Serving over UART on %s at %u bps, %u bits\n", ++ dev, uart_bps, uart_bits); ++ ++ return thread_pool_add_thread(pool, serial_main, pdata, "iiod_serial_thd"); ++ ++err_close_fd: ++ close(fd); ++err_free_pdata: ++ free(pdata); ++err_free_dev: ++ free(dev); ++ return err; ++} +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0013-local-handle-error-codes-in-local_close.patch libiio-0.23/debian/patches/0013-local-handle-error-codes-in-local_close.patch --- libiio-0.21/debian/patches/0013-local-handle-error-codes-in-local_close.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0013-local-handle-error-codes-in-local_close.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -From 4b0a7a26182d86c97bd6de70d1530987e2416774 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 30 Jul 2020 08:34:47 +0300 -Subject: [PATCH 13/53] local: handle error codes in local_close() - -With this change: -* all error returns in local_close() get printed -* the first error code is returned back to the caller - -Signed-off-by: Alexandru Ardelean ---- - local.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 50 insertions(+), 6 deletions(-) - -diff --git a/local.c b/local.c -index 389ed3e..08e5278 100644 ---- a/local.c -+++ b/local.c -@@ -998,10 +998,14 @@ static int local_close(const struct iio_device *dev) - { - struct iio_device_pdata *pdata = dev->pdata; - unsigned int i; -+ char err_str[32]; -+ int ret, ret1; - - if (pdata->fd == -1) - return -EBADF; - -+ ret = 0; -+ ret1 = 0; - if (pdata->is_high_speed) { - unsigned int i; - if (pdata->addrs) { -@@ -1009,7 +1013,12 @@ static int local_close(const struct iio_device *dev) - munmap(pdata->addrs[i], pdata->blocks[i].size); - } - if (pdata->fd > -1) -- ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); -+ ret = ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); -+ if (ret) { -+ ret = -errno; -+ iio_strerror(errno, err_str, sizeof(err_str)); -+ IIO_ERROR("Error during ioctl(): %s\n", err_str); -+ } - pdata->allocated_nb_blocks = 0; - free(pdata->addrs); - pdata->addrs = NULL; -@@ -1017,24 +1026,59 @@ static int local_close(const struct iio_device *dev) - pdata->blocks = NULL; - } - -- close(pdata->fd); -+ ret1 = close(pdata->fd); -+ if (ret1) { -+ ret1 = -errno; -+ iio_strerror(errno, err_str, sizeof(err_str)); -+ IIO_ERROR("Error during close() of main FD: %s\n", err_str); -+ if (ret == 0) -+ ret = ret1; -+ } -+ - pdata->fd = -1; - - if (pdata->cancel_fd > -1) { - close(pdata->cancel_fd); - pdata->cancel_fd = -1; -+ -+ if (ret1) { -+ ret1 = -errno; -+ iio_strerror(errno, err_str, sizeof(err_str)); -+ IIO_ERROR("Error during close() of cancel FD): %s\n", -+ err_str); -+ if (ret == 0) -+ ret = ret1; -+ } - } - -- local_buffer_enabled_set(dev, false); -+ ret1 = local_buffer_enabled_set(dev, false); -+ if (ret1) { -+ ret1 = -errno; -+ iio_strerror(errno, err_str, sizeof(err_str)); -+ IIO_ERROR("Error during buffer disable: %s\n", err_str); -+ if (ret == 0) -+ ret = ret1; -+ } - - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *chn = dev->channels[i]; - -- if (chn->pdata->enable_fn) -- channel_write_state(chn, false); -+ if (!chn->pdata->enable_fn) -+ continue; -+ -+ ret1 = channel_write_state(chn, false); -+ if (ret1 == 0) -+ continue; -+ -+ ret1 = -errno; -+ iio_strerror(errno, err_str, sizeof(err_str)); -+ IIO_ERROR("Error during channel[%u] disable: %s\n", -+ i, err_str); -+ if (ret == 0) -+ ret = ret1; - } - -- return 0; -+ return ret; - } - - static int local_get_fd(const struct iio_device *dev) --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0014-serial-Bump-max-baudrate-to-4-Mbps.patch libiio-0.23/debian/patches/0014-serial-Bump-max-baudrate-to-4-Mbps.patch --- libiio-0.21/debian/patches/0014-serial-Bump-max-baudrate-to-4-Mbps.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0014-serial-Bump-max-baudrate-to-4-Mbps.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,30 @@ +From 5c5461325e752a6aaeb61571423d34ec22fc00c5 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 24 Sep 2021 14:12:45 +0100 +Subject: [PATCH 14/26] serial: Bump max baudrate to 4 Mbps + +This is a completely artificial limit, to ensure that a valid value is +passed. The previous limit of 1 Mbps was too low since most UART +controllers can achieve at least 1.5 Mbps. + +Signed-off-by: Paul Cercueil +--- + serial.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/serial.c b/serial.c +index 451b03f0..99966c3c 100644 +--- a/serial.c ++++ b/serial.c +@@ -549,7 +549,7 @@ static int serial_parse_params(const char *params, + return -EINVAL; + + /* 110 baud to 1,000,000 baud */ +- if (params == end || *baud_rate < 110 || *baud_rate > 1000001) { ++ if (params == end || *baud_rate < 110 || *baud_rate > 4000000) { + IIO_ERROR("Invalid baud rate\n"); + return -EINVAL; + } +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0014-tests-iio_common-Fix-HEX-value-parsing-in-sanitize_c.patch libiio-0.23/debian/patches/0014-tests-iio_common-Fix-HEX-value-parsing-in-sanitize_c.patch --- libiio-0.21/debian/patches/0014-tests-iio_common-Fix-HEX-value-parsing-in-sanitize_c.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0014-tests-iio_common-Fix-HEX-value-parsing-in-sanitize_c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From f75ced2ab5690a3da72c2f83947a854a9f96871e Mon Sep 17 00:00:00 2001 -From: Michael Hennerich -Date: Fri, 31 Jul 2020 13:22:44 +0200 -Subject: [PATCH 14/53] tests/iio_common: Fix HEX value parsing in - sanitize_clamp() - -Right now iio_reg and possibly other tools are broken. -Registers and values are typically provided in hex values. -strtoul() with base 10 returns error when hex values are parsed. -So iio_reg will always clear register 0 which in most cases will -reset the device. - -Signed-off-by: Michael Hennerich ---- - tests/iio_common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/iio_common.c b/tests/iio_common.c -index 0b789c6..8d38f78 100644 ---- a/tests/iio_common.c -+++ b/tests/iio_common.c -@@ -137,7 +137,7 @@ unsigned long int sanitize_clamp(const char *name, const char *argv, - /* sanitized buffer by taking first 20 (or less) char */ - iio_snprintf(buf, sizeof(buf), "%s", argv); - errno = 0; -- val = strtoul(buf, &end, 10); -+ val = strtoul(buf, &end, 0); - if (buf == end || errno == ERANGE) - val = 0; - } --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0015-local-add-omitted-return-value-read-from-close-in-lo.patch libiio-0.23/debian/patches/0015-local-add-omitted-return-value-read-from-close-in-lo.patch --- libiio-0.21/debian/patches/0015-local-add-omitted-return-value-read-from-close-in-lo.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0015-local-add-omitted-return-value-read-from-close-in-lo.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -From a36fdf66a3afef7accb28090dd6e74b2d848cf78 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 5 Aug 2020 08:46:28 +0300 -Subject: [PATCH 15/53] local: add omitted return value read from close() in - local_close() - -Patch 4b0a7a26182d86 ("local: handle error codes in local_close()") omitted -one return value read for close(). -Coverity caught that. This patch reads the return value for -'close(pdata->cancel_fd);' - -Signed-off-by: Alexandru Ardelean ---- - local.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/local.c b/local.c -index 08e5278..a9a2f95 100644 ---- a/local.c -+++ b/local.c -@@ -1038,7 +1038,7 @@ static int local_close(const struct iio_device *dev) - pdata->fd = -1; - - if (pdata->cancel_fd > -1) { -- close(pdata->cancel_fd); -+ ret1 = close(pdata->cancel_fd); - pdata->cancel_fd = -1; - - if (ret1) { --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0015-serial-Implement-get-set-_trigger-callback.patch libiio-0.23/debian/patches/0015-serial-Implement-get-set-_trigger-callback.patch --- libiio-0.21/debian/patches/0015-serial-Implement-get-set-_trigger-callback.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0015-serial-Implement-get-set-_trigger-callback.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,54 @@ +From e5c41452f2acaf658072150f53f645ffc0ebfccc Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Thu, 30 Sep 2021 09:24:08 +0100 +Subject: [PATCH 15/26] serial: Implement {get,set}_trigger callback + +These two were missing, which meant it was impossible to configure a +device's trigger. + +Signed-off-by: Paul Cercueil +--- + serial.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/serial.c b/serial.c +index 99966c3c..6fe4a11e 100644 +--- a/serial.c ++++ b/serial.c +@@ -355,6 +355,24 @@ static int serial_set_timeout(struct iio_context *ctx, unsigned int timeout) + return 0; + } + ++static int serial_get_trigger(const struct iio_device *dev, ++ const struct iio_device **trigger) ++{ ++ const struct iio_context *ctx = iio_device_get_context(dev); ++ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); ++ ++ return iiod_client_get_trigger(pdata->iiod_client, NULL, dev, trigger); ++} ++ ++static int serial_set_trigger(const struct iio_device *dev, ++ const struct iio_device *trigger) ++{ ++ const struct iio_context *ctx = iio_device_get_context(dev); ++ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); ++ ++ return iiod_client_set_trigger(pdata->iiod_client, NULL, dev, trigger); ++} ++ + static const struct iio_backend_ops serial_ops = { + .get_version = serial_get_version, + .open = serial_open, +@@ -369,6 +387,8 @@ static const struct iio_backend_ops serial_ops = { + .shutdown = serial_shutdown, + .get_description = serial_get_description, + .set_timeout = serial_set_timeout, ++ .get_trigger = serial_get_trigger, ++ .set_trigger = serial_set_trigger, + }; + + static const struct iiod_client_ops serial_iiod_client_ops = { +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0016-C-Add-support-for-data-format.patch libiio-0.23/debian/patches/0016-C-Add-support-for-data-format.patch --- libiio-0.21/debian/patches/0016-C-Add-support-for-data-format.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0016-C-Add-support-for-data-format.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,80 @@ +From 27f8490f1978f13709eedd37c40e74d77e31ae51 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Tue, 5 Oct 2021 11:03:23 +0100 +Subject: [PATCH 16/26] C#: Add support for data format + +Provide a "format" field in the Channel object, which contains a +read-only DataFormat structure similar to iio_data_format. + +Signed-off-by: Paul Cercueil +--- + bindings/csharp/Channel.cs | 40 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/bindings/csharp/Channel.cs b/bindings/csharp/Channel.cs +index 017a0722..0ca9c909 100644 +--- a/bindings/csharp/Channel.cs ++++ b/bindings/csharp/Channel.cs +@@ -152,6 +152,36 @@ namespace iio + IIO_CHAN_TYPE_UNKNOWN = Int32.MaxValue + } + ++ public struct DataFormat ++ { ++ /// Total length of the sample, in bits ++ public uint length; ++ ++ /// Length of valuable data in the sample, in bits ++ public uint bits; ++ ++ /// Right-shift to apply when converting sample ++ public uint shift; ++ ++ /// True if the sample is signed ++ [MarshalAs(UnmanagedType.I1)] public bool is_signed; ++ ++ /// True if the sample if fully defined, sign-extended, etc. ++ [MarshalAs(UnmanagedType.I1)] public bool is_fully_defined; ++ ++ /// True if the sample is in big-endian format ++ [MarshalAs(UnmanagedType.I1)] public bool is_be; ++ ++ /// True if the sample should be scaled when converted ++ [MarshalAs(UnmanagedType.I1)] public bool with_scale; ++ ++ /// Scale to apply if with_scale is True ++ public double scale; ++ ++ /// Number of times length repeats ++ public uint repeat; ++ } ++ + internal IntPtr chn; + private uint sample_size; + +@@ -251,14 +281,20 @@ namespace iio + /// The type of this channel. + public ChannelType type { get; private set; } + ++ /// Represents the format of a data sample. ++ public DataFormat format { get; private set; } ++ + internal Channel(IntPtr chn) + { ++ IntPtr fmt_struct = iio_channel_get_data_format(chn); ++ uint nb_attrs = iio_channel_get_attrs_count(chn); ++ + this.chn = chn; + attrs = new List(); +- sample_size = (uint)Marshal.ReadInt32(iio_channel_get_data_format(this.chn)) / 8; + modifier = (ChannelModifier) iio_channel_get_modifier(chn); + type = (ChannelType) iio_channel_get_type(chn); +- uint nb_attrs = iio_channel_get_attrs_count(chn); ++ format = (DataFormat)Marshal.PtrToStructure(fmt_struct, typeof(DataFormat)); ++ sample_size = format.length / 8; + + for (uint i = 0; i < nb_attrs; i++) + { +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0016-Fixed-declaration-of-buf-hides-previous-local-declar.patch libiio-0.23/debian/patches/0016-Fixed-declaration-of-buf-hides-previous-local-declar.patch --- libiio-0.21/debian/patches/0016-Fixed-declaration-of-buf-hides-previous-local-declar.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0016-Fixed-declaration-of-buf-hides-previous-local-declar.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -From e2d3e74af423331e522b1c557a48cecccb52625b Mon Sep 17 00:00:00 2001 -From: f4exb -Date: Fri, 21 Aug 2020 10:32:01 +0200 -Subject: [PATCH 16/53] Fixed declaration of 'buf' hides previous local - declaration - -Signed-off-by: f4exb ---- - tests/iio_common.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/tests/iio_common.c b/tests/iio_common.c -index 8d38f78..e5ebc00 100644 ---- a/tests/iio_common.c -+++ b/tests/iio_common.c -@@ -375,12 +375,12 @@ struct iio_context * handle_common_opts(char * name, int argc, - ctx = iio_create_default_context(); - - if (!ctx && !do_scan && !detect_context) { -- char buf[1024]; -- iio_strerror(errno, buf, sizeof(buf)); -+ char err_str[1024]; -+ iio_strerror(errno, err_str, sizeof(err_str)); - if (arg) -- fprintf(stderr, "Unable to create IIO context %s: %s\n", arg, buf); -+ fprintf(stderr, "Unable to create IIO context %s: %s\n", arg, err_str); - else -- fprintf(stderr, "Unable to create Local IIO context : %s\n", buf); -+ fprintf(stderr, "Unable to create Local IIO context : %s\n", err_str); - } - - if (ctx && timeout >= 0) { --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0017-CI-disable-debug-on-the-artifact-deploy.patch libiio-0.23/debian/patches/0017-CI-disable-debug-on-the-artifact-deploy.patch --- libiio-0.21/debian/patches/0017-CI-disable-debug-on-the-artifact-deploy.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0017-CI-disable-debug-on-the-artifact-deploy.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,26 @@ +From 2f6c96fbaf6e7a6e98e3585e1dac65002a4db4fe Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Fri, 8 Oct 2021 11:27:28 +0300 +Subject: [PATCH 17/26] CI: disable debug on the artifact deploy + +Signed-off-by: Raluca Chis +--- + azure-pipelines.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index b0cbb1c5..2b5559ac 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -234,7 +234,7 @@ stages: + displayName: 'Download rsa key' + inputs: + secureFile: 'id_rsa' +- - bash: chmod 600 $(key.secureFilePath) ; scp -2 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o HostKeyAlgorithms=+ssh-dss -vv -i $(key.secureFilePath) -r /home/vsts/work/1/a/* $MAPPED_VAR ++ - bash: chmod 600 $(key.secureFilePath) ; scp -2 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o HostKeyAlgorithms=+ssh-dss -i $(key.secureFilePath) -r /home/vsts/work/1/a/* $MAPPED_VAR + env: + MAPPED_VAR: $(SERVER_ADDRESS) + displayName: "Push artifacts to SW Downloads" +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0017-doc-fix-typo-in-build-guide.patch libiio-0.23/debian/patches/0017-doc-fix-typo-in-build-guide.patch --- libiio-0.21/debian/patches/0017-doc-fix-typo-in-build-guide.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0017-doc-fix-typo-in-build-guide.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From ed85dddb32e2ac154015fbdfbe630448b1aad151 Mon Sep 17 00:00:00 2001 -From: Virgil Litan -Date: Thu, 27 Aug 2020 18:32:54 +0300 -Subject: [PATCH 17/53] doc: fix typo in build guide - -Signed-off-by: Virgil Litan ---- - README_BUILD.md | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/README_BUILD.md b/README_BUILD.md -index fcb7bbd..91f6e2f 100644 ---- a/README_BUILD.md -+++ b/README_BUILD.md -@@ -22,7 +22,7 @@ analog@precision:~$ sudo apt-get install doxygen graphviz - ``` - Install to build python backends - ```shell --analog@precision:~$ sudo apt-get python3 python3-pip python3-setuptools -+analog@precision:~$ sudo apt-get install python3 python3-pip python3-setuptools - ``` - Install to Read local context attributes from `/etc/libiio.ini` - ```shell --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0018-azure-pipelines-Update-libusb-and-libxml2-version-fo.patch libiio-0.23/debian/patches/0018-azure-pipelines-Update-libusb-and-libxml2-version-fo.patch --- libiio-0.21/debian/patches/0018-azure-pipelines-Update-libusb-and-libxml2-version-fo.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0018-azure-pipelines-Update-libusb-and-libxml2-version-fo.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,68 @@ +From 8402b80b1ba566a561f767f8dac860629c0290d6 Mon Sep 17 00:00:00 2001 +From: Alexandra Trifan +Date: Thu, 30 Sep 2021 16:17:55 +0300 +Subject: [PATCH 18/26] azure-pipelines: Update libusb and libxml2 version for + Windows builds. + +Old libusb and libxml2 were linking to a Visual Studio DLL from 2013 which +is no longer available on CI images. The new archive contains the latest +versions for both libusb and libxml2 and are now built using MSVC 2019. + +Signed-off-by: Alexandra Trifan +--- + CI/build_win.ps1 | 4 ++-- + CI/install_deps_win.ps1 | 2 +- + CI/publish_deps.ps1 | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/CI/build_win.ps1 b/CI/build_win.ps1 +index 4b6110a8..08048e22 100644 +--- a/CI/build_win.ps1 ++++ b/CI/build_win.ps1 +@@ -10,7 +10,7 @@ if ($ARCH -eq "Win32") { + cp .\libiio.iss.cmakein .\build-win32 + cd build-win32 + +- cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\32\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\32\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\32\\libserialport.dll.a" .. ++ cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\32\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\32\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\32\\libserialport.dll.a" -DLIBUSB_INCLUDE_DIR="C:\\include\\libusb-1.0" -DLIBXML2_INCLUDE_DIR="C:\\include\\libxml2" .. + cmake --build . --config Release + cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY + +@@ -25,7 +25,7 @@ if ($ARCH -eq "Win32") { + cp .\libiio.iss.cmakein .\build-x64 + cd build-x64 + +- cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\64\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\64\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\64\\libserialport.dll.a" .. ++ cmake -G "$COMPILER" -A "$ARCH" -DCMAKE_SYSTEM_PREFIX_PATH="C:" -DENABLE_IPV6=OFF -DWITH_USB_BACKEND=ON -DWITH_SERIAL_BACKEND=ON -DPYTHON_BINDINGS=ON -DCSHARP_BINDINGS:BOOL=ON -DLIBXML2_LIBRARIES="C:\\libs\\64\\libxml2.lib" -DLIBUSB_LIBRARIES="C:\\libs\\64\\libusb-1.0.lib" -DLIBSERIALPORT_LIBRARIES="C:\\libs\\64\\libserialport.dll.a" -DLIBUSB_INCLUDE_DIR="C:\\include\\libusb-1.0" -DLIBXML2_INCLUDE_DIR="C:\\include\\libxml2" .. + cmake --build . --config Release + cp .\libiio.iss $env:BUILD_ARTIFACTSTAGINGDIRECTORY + +diff --git a/CI/install_deps_win.ps1 b/CI/install_deps_win.ps1 +index af3f0513..53fd02b4 100644 +--- a/CI/install_deps_win.ps1 ++++ b/CI/install_deps_win.ps1 +@@ -20,7 +20,7 @@ rm libxml.7z + + echo "Downloading deps..." + cd C:\ +-wget http://swdownloads.analog.com/cse/build/libiio-win-deps.zip -OutFile "libiio-win-deps.zip" ++wget http://swdownloads.analog.com/cse/build/libiio-win-deps-libusb1.0.24.zip -OutFile "libiio-win-deps.zip" + 7z x -y "C:\libiio-win-deps.zip" + + # Note: InnoSetup is already installed on Azure images; so don't run this step +diff --git a/CI/publish_deps.ps1 b/CI/publish_deps.ps1 +index 1520ee4a..dc0cd46a 100644 +--- a/CI/publish_deps.ps1 ++++ b/CI/publish_deps.ps1 +@@ -13,7 +13,7 @@ if ($ARCH -eq "Win32") { + cd $src_dir + mkdir dependencies + cd dependencies +-wget http://swdownloads.analog.com/cse/build/libiio-win-deps.zip -OutFile "libiio-win-deps.zip" ++wget http://swdownloads.analog.com/cse/build/libiio-win-deps-libusb1.0.24.zip -OutFile "libiio-win-deps.zip" + 7z x -y "libiio-win-deps.zip" + + if ($ARCH -eq "Win32") { +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0018-utilities-Fix-getenv-function.patch libiio-0.23/debian/patches/0018-utilities-Fix-getenv-function.patch --- libiio-0.21/debian/patches/0018-utilities-Fix-getenv-function.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0018-utilities-Fix-getenv-function.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From 5ebe88fb217107e16efb76fff9bbafe6cc186863 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Nuno=20S=C3=A1?= -Date: Thu, 17 Sep 2020 08:51:37 +0200 -Subject: [PATCH 18/53] utilities: Fix getenv function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch fixes a wrong comparison leading to a false failure. We want to -return error if the env var size is bigger than max size and not the other -way around. - -Signed-off-by: Nuno Sá ---- - utilities.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/utilities.c b/utilities.c -index 604d8c1..e9db745 100644 ---- a/utilities.c -+++ b/utilities.c -@@ -301,7 +301,7 @@ char * iio_getenv (char * envvar) - len = strnlen(hostname, tmp); - - /* Should be smaller than max length */ -- if (len <= tmp) -+ if (len == tmp) - goto wrong_str; - - /* should be more than "usb:" or "ip:" */ --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0019-CMake-fix-build-with-cmake-2.8.7.patch libiio-0.23/debian/patches/0019-CMake-fix-build-with-cmake-2.8.7.patch --- libiio-0.21/debian/patches/0019-CMake-fix-build-with-cmake-2.8.7.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0019-CMake-fix-build-with-cmake-2.8.7.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From cc26843df1b877cb6029e525d0ddaf105614e4d1 Mon Sep 17 00:00:00 2001 -From: DanielGuramulta -Date: Thu, 1 Oct 2020 21:38:04 +0300 -Subject: [PATCH 19/53] CMake: fix build with cmake 2.8.7 - -Building libiio with cmake 2.8.7(minimum version required) would fail due to cmake(2.8.7) not being able to copy a list of files separated by ";" to a destination. A solution to this problem is to create a list of commands containing a copy command for each iio test target file. With this approach the minimum required cmake version is not touched. -Signed-off-by: DanielGuramulta ---- - CMakeLists.txt | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 4f1ab21..3d2a5d1 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -508,13 +508,15 @@ if(OSX_PACKAGE) - DOC "OSX Package builder (productbuild)") - mark_as_advanced(PRODUCTBUILD_EXECUTABLE) - -+ set(COPY_TOOLS_COMMAND) - foreach(_tool ${IIO_TESTS_TARGETS}) -- list(APPEND IIO_TESTS $) -+ list(APPEND COPY_TOOLS_COMMAND -+ COMMAND ${CMAKE_COMMAND} -E copy $ ${LIBIIO_FRAMEWORK_DIR}/Tools) - endforeach() - - add_custom_command(OUTPUT ${LIBIIO_PKG} - COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBIIO_FRAMEWORK_DIR}/Tools -- COMMAND ${CMAKE_COMMAND} -E copy ${IIO_TESTS} ${LIBIIO_FRAMEWORK_DIR}/Tools -+ ${COPY_TOOLS_COMMAND} - COMMAND ${PKGBUILD_EXECUTABLE} - --component ${LIBIIO_FRAMEWORK_DIR} - --identifier com.adi.iio --version ${VERSION} --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0019-iiod-fix-read_line-for-USB.patch libiio-0.23/debian/patches/0019-iiod-fix-read_line-for-USB.patch --- libiio-0.21/debian/patches/0019-iiod-fix-read_line-for-USB.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0019-iiod-fix-read_line-for-USB.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,63 @@ +From 4e574547cb935d131fc60c2acdaec9ddb500defc Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Thu, 21 Oct 2021 14:57:36 +0100 +Subject: [PATCH 19/26] iiod: fix read_line() for USB + +Commit aad53e3 ("iiod: Update read_line() to work with UART") made IIOD +able to read its input from UART, but broke USB support at the same +time. + +This commit changes the read_line() function so that it works as +expected with both UART and USB transports. + +The bug was reported on EZ: +https://ez.analog.com/linux-software-drivers/f/q-a/550894/modifying-libiio-recipe/436242 + +Signed-off-by: Paul Cercueil +--- + iiod/ops.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/iiod/ops.c b/iiod/ops.c +index d1c1cdae..4184872f 100644 +--- a/iiod/ops.c ++++ b/iiod/ops.c +@@ -1401,6 +1401,9 @@ ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + ssize_t ret; + bool found; + ++ if (pdata->is_usb) ++ return pdata->readfd(pdata, buf, len); ++ + if (pdata->fd_in_is_socket) { + struct pollfd pfd[2]; + +@@ -1445,10 +1448,6 @@ ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + + bytes_read += to_trunc; + } while (!found && len); +- } else if (pdata->is_usb) { +- ret = pdata->readfd(pdata, buf, len); +- +- found = buf[ret - 1] == '\n'; + } else { + while (len) { + ret = pdata->readfd(pdata, buf, 1); +@@ -1467,13 +1466,7 @@ ssize_t read_line(struct parser_pdata *pdata, char *buf, size_t len) + found = !!len; + } + +- /* No \n found? Just garbage data */ +- if (!found) +- ret = -EIO; +- else +- ret = bytes_read; +- +- return ret; ++ return found ? (ssize_t) bytes_read : -EIO; + } + + void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0020-CMake-re-work-messages-to-have-a-summary-at-the-bott.patch libiio-0.23/debian/patches/0020-CMake-re-work-messages-to-have-a-summary-at-the-bott.patch --- libiio-0.21/debian/patches/0020-CMake-re-work-messages-to-have-a-summary-at-the-bott.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0020-CMake-re-work-messages-to-have-a-summary-at-the-bott.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,202 @@ +From 0e1a9384f544d79e5e50ebef43f85d4cd64dc75e Mon Sep 17 00:00:00 2001 +From: Robin Getz +Date: Sat, 23 Oct 2021 16:55:17 -0400 +Subject: [PATCH 20/26] CMake: re-work messages, to have a summary at the + bottom of the cmake + +This re-works some of the cmake to make it quieter, and less status in +random places, to put a summary at the bottom of the file, to make it +easier for people to find (and for us to debug). + +Now we get outputs like: + +-- Features Enabled : xml network dns-sd avahi ipv6 local usb utils iiod iiod-serial iiod-aio iiod-usb man-utils +-- Features Disabled: C#-bindings Python-bindings zstd serial examples iiod-systemd iiod-sysvinit iiod-upstart doc man + +Signed-off-by: Robin Getz +--- + CMakeLists.txt | 42 +++++++++++++++++++++++++--------- + bindings/CMakeLists.txt | 6 +++++ + bindings/python/CMakeLists.txt | 3 --- + iiod/CMakeLists.txt | 12 ++++++++-- + man/CMakeLists.txt | 7 +++++- + 5 files changed, 53 insertions(+), 17 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 91db382a..7437136c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -149,8 +149,6 @@ if (WITH_USB_BACKEND) + message(SEND_ERROR "Unable to find libusb-1.0 dependency.\n" + "If you want to disable the USB backend, set WITH_USB_BACKEND=OFF.") + else() +- message(STATUS "Looking for libusb-1.0 : Found") +- + set(IIOD_CLIENT 1) + set(NEED_LIBXML2 1) + set(NEED_THREADS 1) +@@ -293,7 +291,6 @@ endif (WITH_ZSTD) + include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + + if(WITH_NETWORK_BACKEND) +- message(STATUS "Building with Network back end support") + if (WIN32) + list(APPEND LIBS_TO_LINK wsock32 iphlpapi ws2_32) + endif() +@@ -334,18 +331,14 @@ if(WITH_NETWORK_BACKEND) + message(STATUS "Building without DNS-SD (ZeroConf) support") + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + find_library(CORE_SERVICES CoreServices) +- +- message(STATUS "Building with CFNetServices, an Apple DNS SD implementation") +- + list(APPEND LIBIIO_CFILES dns_sd_bonjour.c dns_sd.c) + list(APPEND LIBS_TO_LINK ${CORE_SERVICES} ) +- ++ set(HAVE_BONJOUR ON) + elseif(WIN32) + list(APPEND LIBIIO_CFILES dns_sd_windows.c dns_sd.c) + if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set_source_files_properties(dns_sd_windows.c PROPERTIES COMPILE_FLAGS "-Wno-unused-function") + endif() +- message(STATUS "Building with mdns, A Public domain mDNS/DNS-SD library in C ") + else() + find_library(AVAHI_CLIENT_LIBRARIES avahi-client) + find_library(AVAHI_COMMON_LIBRARIES avahi-common) +@@ -354,9 +347,7 @@ if(WITH_NETWORK_BACKEND) + "If you want to disable DNS-SD (ZeroConf) support, set HAVE_DNS_SD=OFF.") + endif() + +- message(STATUS "Building with Avahi, a DNS-SD (ZeroConf) implementation") + set(HAVE_AVAHI ON) +- + list(APPEND LIBIIO_CFILES dns_sd_avahi.c dns_sd.c) + set(AVAHI_LIBRARIES ${AVAHI_CLIENT_LIBRARIES} ${AVAHI_COMMON_LIBRARIES}) + list(APPEND LIBS_TO_LINK ${AVAHI_LIBRARIES}) +@@ -366,7 +357,6 @@ if(WITH_NETWORK_BACKEND) + set(IIOD_CLIENT 1) + set(NEED_LIBXML2 1) + else() +- message(STATUS "Building without network support") + set(HAVE_DNS_SD OFF) + endif() + +@@ -618,3 +608,33 @@ if (WITH_USB_BACKEND AND CMAKE_SYSTEM_NAME MATCHES "^Linux") + endif() + + configure_file(iio-config.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/iio-config.h @ONLY) ++ ++list(APPEND IIO_FEATURES_${WITH_XML_BACKEND} xml) ++list(APPEND IIO_FEATURES_${WITH_ZSTD} zstd) ++list(APPEND IIO_FEATURES_${WITH_NETWORK_BACKEND} network) ++list(APPEND IIO_FEATURES_${HAVE_DNS_SD} dns-sd) ++list(APPEND IIO_FEATURES_${HAVE_AVAHI} avahi) ++list(APPEND IIO_FEATURES_${HAVE_BONJOUR} bonjour) ++list(APPEND IIO_FEATURES_${ENABLE_IPV6} ipv6) ++list(APPEND IIO_FEATURES_${WITH_SERIAL_BACKEND} serial) ++list(APPEND IIO_FEATURES_${WITH_LOCAL_BACKEND} local) ++list(APPEND IIO_FEATURES_${WITH_USB_BACKEND} usb) ++list(APPEND IIO_FEATURES_${WITH_TESTS} utils) ++list(APPEND IIO_FEATURES_${WITH_EXAMPLES} examples) ++list(APPEND IIO_FEATURES_${WITH_IIOD} iiod) ++#add iiod settings ++list(APPEND IIO_FEATURES_ON ${IIOD_FEATURES_ON}) ++list(APPEND IIO_FEATURES_OFF ${IIOD_FEATURES_OFF}) ++list(APPEND IIO_FEATURES_${WITH_DOC} doc) ++#add man page settings ++list(APPEND IIO_FEATURES_ON ${IIOM_FEATURES_ON}) ++list(APPEND IIO_FEATURES_OFF ${IIOM_FEATURES_OFF}) ++#add binding settings ++list(APPEND IIO_FEATURES_ON ${IIOB_FEATURES_ON}) ++list(APPEND IIO_FEATURES_OFF ${IIOB_FEATURES_OFF}) ++ ++string(REPLACE ";" " " IIO_FEATURES_ON "${IIO_FEATURES_ON}") ++string(REPLACE ";" " " IIO_FEATURES_OFF "${IIO_FEATURES_OFF}") ++ ++message(STATUS "Features enabled : ${IIO_FEATURES_ON}") ++message(STATUS "Features disabled: ${IIO_FEATURES_OFF}") +diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt +index 4c2063ac..12523ea6 100644 +--- a/bindings/CMakeLists.txt ++++ b/bindings/CMakeLists.txt +@@ -5,3 +5,9 @@ endif() + if (PYTHON_BINDINGS) + add_subdirectory(python) + endif() ++ ++list(APPEND IIOB_FEATURES_${PYTHON_BINDINGS} python-bindings) ++list(APPEND IIOB_FEATURES_${CSHARP_BINDINGS} "c#-bindings") ++ ++set(IIOB_FEATURES_ON "${IIOB_FEATURES_ON}" PARENT_SCOPE) ++set(IIOB_FEATURES_OFF "${IIOB_FEATURES_OFF}" PARENT_SCOPE) +diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt +index 6acac2ed..ec212a58 100644 +--- a/bindings/python/CMakeLists.txt ++++ b/bindings/python/CMakeLists.txt +@@ -9,7 +9,6 @@ if(${CMAKE_VERSION} VERSION_LESS "3.12.0") + # which is available from CMake 3.12. + set(Python_Interpreter_FOUND ${PYTHONINTERP_FOUND}) + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) +- message(STATUS "old") + else() + if(PYTHON_EXECUTABLE) + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) +@@ -22,12 +21,10 @@ else() + endif() + message(STATUS "bin=${Python_EXECUTABLE} lib=${Python_LIBRARY} inc=${Python_INCLUDE_DIR}") + find_package (Python COMPONENTS Interpreter) +- message(STATUS "new") + message(STATUS "Python_EXECUTABLE ${Python_EXECUTABLE}") + endif() + + if (Python_Interpreter_FOUND) +- message(STATUS "Found Python: Building bindings") + set(SETUP_PY_IN ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmakein) + set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py) + +diff --git a/iiod/CMakeLists.txt b/iiod/CMakeLists.txt +index 39b644c9..b144493f 100644 +--- a/iiod/CMakeLists.txt ++++ b/iiod/CMakeLists.txt +@@ -37,8 +37,6 @@ if (WITH_AIO) + "If you want to disable async. I/O support, set WITH_AIO=OFF.") + endif () + +- message(STATUS "Looking for libaio: Found") +- + option(WITH_IIOD_USBD "Add support for USB through FunctionFS within IIOD" ON) + if (WITH_IIOD_USBD) + include(CheckTypeSize) +@@ -104,3 +102,13 @@ if (WITH_UPSTART) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/init/iiod.conf.cmakein ${PROJECT_BINARY_DIR}/init/iiod.conf) + install(FILES ${PROJECT_BINARY_DIR}/init/iiod.conf DESTINATION ${UPSTART_CONF_INSTALL_DIR}) + endif() ++ ++list(APPEND IIOD_FEATURES_${WITH_IIOD_SERIAL} iiod-serial) ++list(APPEND IIOD_FEATURES_${WITH_AIO} iiod-aio) ++list(APPEND IIOD_FEATURES_${WITH_IIOD_USBD} iiod-usb) ++list(APPEND IIOD_FEATURES_${WITH_SYSTEMD} iiod-systemd) ++list(APPEND IIOD_FEATURES_${WITH_SYSVINIT} iiod-sysvinit) ++list(APPEND IIOD_FEATURES_${WITH_UPSTART} iiod-upstart) ++ ++set(IIOD_FEATURES_ON "${IIOD_FEATURES_ON}" PARENT_SCOPE) ++set(IIOD_FEATURES_OFF "${IIOD_FEATURES_OFF}" PARENT_SCOPE) +diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt +index 2555eced..0d9d6a10 100644 +--- a/man/CMakeLists.txt ++++ b/man/CMakeLists.txt +@@ -59,5 +59,10 @@ if (WITH_MAN) + install(DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_MANDIR} + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 + COMPONENT doc FILES_MATCHING PATTERN "*.1*") +- + endif() ++ ++list(APPEND IIOM_FEATURES_${WITH_MAN} man) ++list(APPEND IIOM_FEATURES_${WITH_TESTS} man-utils) ++ ++set(IIOM_FEATURES_ON "${IIOM_FEATURES_ON}" PARENT_SCOPE) ++set(IIOM_FEATURES_OFF "${IIOM_FEATURES_OFF}" PARENT_SCOPE) +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0020-local.c-when-target-buffer-is-too-small-fail.patch libiio-0.23/debian/patches/0020-local.c-when-target-buffer-is-too-small-fail.patch --- libiio-0.21/debian/patches/0020-local.c-when-target-buffer-is-too-small-fail.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0020-local.c-when-target-buffer-is-too-small-fail.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -From 67273fc6ce436d92b68b8905d38a0f5b8c72c9d5 Mon Sep 17 00:00:00 2001 -From: Robin Getz -Date: Wed, 7 Oct 2020 09:35:23 -0400 -Subject: [PATCH 20/53] local.c: when target buffer is too small, fail - -Fix #357 - -If a target buffer is too small, right now, we try to put a partial fill -in the buffer, and return sucess (which is wrong). - -Now we will return EFBIG, and leave the target buffer empty. This will -make the local backends the same as the otherbackends. - -Signed-off-by: Robin Getz ---- - local.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/local.c b/local.c -index a9a2f95..3d8d3ea 100644 ---- a/local.c -+++ b/local.c -@@ -706,10 +706,16 @@ static ssize_t local_read_dev_attr(const struct iio_device *dev, - return -errno; - - ret = fread(dst, 1, len, f); -+ -+ /* if we didn't read the entire file, fail */ -+ if (!feof(f)) -+ ret = -EFBIG; -+ - if (ret > 0) - dst[ret - 1] = '\0'; - else - dst[0] = '\0'; -+ - fflush(f); - if (ferror(f)) - ret = -errno; --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0021-local-Don-t-check-size-of-dequeued-buffer-vs.-bytes_.patch libiio-0.23/debian/patches/0021-local-Don-t-check-size-of-dequeued-buffer-vs.-bytes_.patch --- libiio-0.21/debian/patches/0021-local-Don-t-check-size-of-dequeued-buffer-vs.-bytes_.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0021-local-Don-t-check-size-of-dequeued-buffer-vs.-bytes_.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,35 @@ +From cbe8ba56228e89f3f5e226789c9362623aa40ef1 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 12 Nov 2021 13:33:33 +0000 +Subject: [PATCH 21/26] local: Don't check size of dequeued buffer vs. + bytes_used + +We already make sure in the high-level API (buffer.c) that bytes_used +will always be smaller or equal than the buffer size. + +Therefore, the case where bytes_used is bigger than a newly dequeued +block will never happen. + +Signed-off-by: Paul Cercueil +--- + local.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/local.c b/local.c +index e9095201..0b7f3558 100644 +--- a/local.c ++++ b/local.c +@@ -493,10 +493,6 @@ static ssize_t local_get_buffer(const struct iio_device *dev, + return ret; + } + +- /* Requested buffer size is too big! */ +- if (pdata->last_dequeued < 0 && bytes_used > block.size) +- return -EFBIG; +- + pdata->last_dequeued = block.id; + *addr_ptr = pdata->addrs[block.id]; + return (ssize_t) block.bytes_used; +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0021-xml-use-iio_context_destroy-on-error-path-of-iio_cre.patch libiio-0.23/debian/patches/0021-xml-use-iio_context_destroy-on-error-path-of-iio_cre.patch --- libiio-0.21/debian/patches/0021-xml-use-iio_context_destroy-on-error-path-of-iio_cre.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0021-xml-use-iio_context_destroy-on-error-path-of-iio_cre.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -From c7f455519485dcde5e9ac12220ceb604143c63e3 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 8 Oct 2020 15:03:37 +0300 -Subject: [PATCH 21/53] xml: use iio_context_destroy() on error path of - iio_create_xml_context_helper() - -The error path of the iio_create_xml_context_helper() has all the traits of -a iio_context_destroy() function. iio_context_destroy() does plenty of -null-checks when destroying data on a context object. - -This change, uses the iio_context_destroy() function on the error path of -iio_create_xml_context_helper(). - -The intent is to hide the 'iio_context' type inside the context.c file for -better modularity. - -Signed-off-by: Alexandru Ardelean ---- - xml.c | 26 +++++++------------------- - 1 file changed, 7 insertions(+), 19 deletions(-) - -diff --git a/xml.c b/xml.c -index bcc22a3..965db79 100644 ---- a/xml.c -+++ b/xml.c -@@ -373,7 +373,6 @@ static int parse_context_attr(struct iio_context *ctx, xmlNode *n) - - static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - { -- unsigned int i; - xmlNode *root, *n; - xmlAttr *attr; - int err = -ENOMEM; -@@ -388,7 +387,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - if (strcmp((char *) root->name, "context")) { - IIO_ERROR("Unrecognized XML file\n"); - err = -EINVAL; -- goto err_free_ctx; -+ goto err_context_destroy; - } - - for (attr = root->properties; attr; attr = attr->next) { -@@ -406,7 +405,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - if (!strcmp((char *) n->name, "context-attribute")) { - err = parse_context_attr(ctx, n); - if (err) -- goto err_free_devices; -+ goto err_context_destroy; - else - continue; - } else if (strcmp((char *) n->name, "device")) { -@@ -419,7 +418,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - dev = create_device(ctx, n); - if (!dev) { - IIO_ERROR("Unable to create device\n"); -- goto err_free_devices; -+ goto err_context_destroy; - } - - devs = realloc(ctx->devices, (1 + ctx->nb_devices) * -@@ -427,7 +426,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - if (!devs) { - IIO_ERROR("Unable to allocate memory\n"); - free(dev); -- goto err_free_devices; -+ goto err_context_destroy; - } - - devs[ctx->nb_devices++] = dev; -@@ -436,23 +435,12 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - - err = iio_context_init(ctx); - if (err) -- goto err_free_devices; -+ goto err_context_destroy; - - return ctx; - --err_free_devices: -- for (i = 0; i < ctx->nb_devices; i++) -- free_device(ctx->devices[i]); -- if (ctx->nb_devices) -- free(ctx->devices); -- for (i = 0; i < ctx->nb_attrs; i++) { -- free(ctx->attrs[i]); -- free(ctx->values[i]); -- } -- free(ctx->attrs); -- free(ctx->values); --err_free_ctx: -- free(ctx); -+err_context_destroy: -+ iio_context_destroy(ctx); - err_set_errno: - errno = -err; - return NULL; --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0022-iio-private.h-Remove-useless-field-is_output.patch libiio-0.23/debian/patches/0022-iio-private.h-Remove-useless-field-is_output.patch --- libiio-0.21/debian/patches/0022-iio-private.h-Remove-useless-field-is_output.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0022-iio-private.h-Remove-useless-field-is_output.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,28 @@ +From c2fbae7cbef855f4ffb5ef4b4941ac2c0a333f93 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 12 Nov 2021 13:30:28 +0000 +Subject: [PATCH 22/26] iio-private.h: Remove useless field is_output + +This field is never used anywhere. + +Signed-off-by: Paul Cercueil +--- + iio-private.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iio-private.h b/iio-private.h +index 21ced654..bc5af0bc 100644 +--- a/iio-private.h ++++ b/iio-private.h +@@ -200,7 +200,7 @@ struct iio_buffer { + uint32_t *mask; + unsigned int dev_sample_size; + unsigned int sample_size; +- bool is_output, dev_is_high_speed; ++ bool dev_is_high_speed; + }; + + struct iio_context_info { +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0022-local-use-API-accessors-for-accessing-devices-from-a.patch libiio-0.23/debian/patches/0022-local-use-API-accessors-for-accessing-devices-from-a.patch --- libiio-0.21/debian/patches/0022-local-use-API-accessors-for-accessing-devices-from-a.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0022-local-use-API-accessors-for-accessing-devices-from-a.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -From 10d9775b7d4b4feb477c1a18e082bfecf5790d6b Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 7 Oct 2020 16:37:05 +0300 -Subject: [PATCH 22/53] local: use API accessors for accessing devices from an - IIO context - -The aim is to make all libiio backends plugins, so they need to decouple a -bit from accessing internal IIO context objects, and channels. - -For all the backends in libiio, this change replaces the access of IIO -devices count and objects with IIO API accessors to get the number of -devices and a reference for each device when iterating. - -Signed-off-by: Alexandru Ardelean ---- - dns_sd.c | 10 ++++++---- - local.c | 12 ++++++------ - network.c | 8 ++++---- - usb.c | 13 +++++++------ - 4 files changed, 23 insertions(+), 20 deletions(-) - -diff --git a/dns_sd.c b/dns_sd.c -index a25d2fe..7a27061 100644 ---- a/dns_sd.c -+++ b/dns_sd.c -@@ -99,15 +99,17 @@ static int dnssd_fill_context_info(struct iio_context_info *info, - iio_snprintf(description, sizeof(description), "%s %s", addr_str, hw_model); - } else if (serial) { - iio_snprintf(description, sizeof(description), "%s %s", addr_str, serial); -- } else if (ctx->nb_devices == 0) { -+ } else if (iio_context_get_devices_count(ctx) == 0) { - iio_snprintf(description, sizeof(description), "%s", ctx->description); - } else { - iio_snprintf(description, sizeof(description), "%s (", addr_str); - p = description + strlen(description); -- for (i = 0; i < ctx->nb_devices - 1; i++) { -- if (ctx->devices[i]->name) { -+ for (i = 0; i < iio_context_get_devices_count(ctx) - 1; i++) { -+ const struct iio_device *dev = iio_context_get_device(ctx, i); -+ const char *name = iio_device_get_name(dev); -+ if (name) { - iio_snprintf(p, sizeof(description) - strlen(description) -1, -- "%s,", ctx->devices[i]->name); -+ "%s,", name); - p += strlen(p); - } - } -diff --git a/local.c b/local.c -index 3d8d3ea..24589ad 100644 ---- a/local.c -+++ b/local.c -@@ -156,8 +156,8 @@ static void local_shutdown(struct iio_context *ctx) - /* Free the backend data stored in every device structure */ - unsigned int i; - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - - iio_device_close(dev); - local_free_pdata(dev); -@@ -1125,9 +1125,9 @@ static int local_get_trigger(const struct iio_device *dev, - return 0; - } - -- nb = dev->ctx->nb_devices; -+ nb = iio_context_get_devices_count(dev->ctx); - for (i = 0; i < (size_t) nb; i++) { -- const struct iio_device *cur = dev->ctx->devices[i]; -+ const struct iio_device *cur = iio_context_get_device(dev->ctx, i); - if (cur->name && !strcmp(cur->name, buf)) { - *trigger = cur; - return 0; -@@ -1986,8 +1986,8 @@ static void init_scan_elements(struct iio_context *ctx) - { - unsigned int i, j; - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - - for (j = 0; j < dev->nb_channels; j++) - init_data_scale(dev->channels[j]); -diff --git a/network.c b/network.c -index fd4acee..6bd6193 100644 ---- a/network.c -+++ b/network.c -@@ -1085,8 +1085,8 @@ static void network_shutdown(struct iio_context *ctx) - close(pdata->io_ctx.fd); - iio_mutex_unlock(pdata->lock); - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - struct iio_device_pdata *dpdata = dev->pdata; - - if (dpdata) { -@@ -1462,8 +1462,8 @@ struct iio_context * network_create_context(const char *host) - if (ret < 0) - goto err_free_description; - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - - dev->pdata = zalloc(sizeof(*dev->pdata)); - if (!dev->pdata) { -diff --git a/usb.c b/usb.c -index bc4af06..7a236f5 100644 ---- a/usb.c -+++ b/usb.c -@@ -449,12 +449,13 @@ static int usb_set_trigger(const struct iio_device *dev, - - static void usb_shutdown(struct iio_context *ctx) - { -+ unsigned int nb_devices = iio_context_get_devices_count(ctx); - unsigned int i; - - usb_io_context_exit(&ctx->pdata->io_ctx); - -- for (i = 0; i < ctx->nb_devices; i++) -- usb_close(ctx->devices[i]); -+ for (i = 0; i < nb_devices; i++) -+ usb_close(iio_context_get_device(ctx, i)); - - iio_mutex_destroy(ctx->pdata->lock); - iio_mutex_destroy(ctx->pdata->ep_lock); -@@ -465,8 +466,8 @@ static void usb_shutdown(struct iio_context *ctx) - if (ctx->pdata->io_endpoints) - free(ctx->pdata->io_endpoints); - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < nb_devices; i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - - usb_io_context_exit(&dev->pdata->io_ctx); - free(dev->pdata); -@@ -1015,8 +1016,8 @@ struct iio_context * usb_create_context(unsigned int bus, - ctx->ops = &usb_ops; - ctx->pdata = pdata; - -- for (i = 0; i < ctx->nb_devices; i++) { -- struct iio_device *dev = ctx->devices[i]; -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) { -+ struct iio_device *dev = iio_context_get_device(ctx, i); - - dev->pdata = zalloc(sizeof(*dev->pdata)); - if (!dev->pdata) { --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0023-CMake-Move-include-CheckCSourceCompiles-before-its-m.patch libiio-0.23/debian/patches/0023-CMake-Move-include-CheckCSourceCompiles-before-its-m.patch --- libiio-0.21/debian/patches/0023-CMake-Move-include-CheckCSourceCompiles-before-its-m.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0023-CMake-Move-include-CheckCSourceCompiles-before-its-m.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,36 @@ +From 758ba58c81273d9075a539216f8a322935c2e434 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 12 Nov 2021 16:49:21 +0000 +Subject: [PATCH 23/26] CMake: Move include(CheckCSourceCompiles) before its + macros are used + +Move include(CheckCSourceCompiles) before any of the +check_c_source_compiles() macros is called. + +This fixes a CMake error when compiling with WITH_NETWORK_GET_BUFFER +disabled. + +Signed-off-by: Paul Cercueil +--- + CMakeLists.txt | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 7437136c..05b4feff 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -296,9 +296,10 @@ if(WITH_NETWORK_BACKEND) + endif() + + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") ++ include(CheckCSourceCompiles) ++ + option(WITH_NETWORK_GET_BUFFER "Enable experimental zero-copy transfers" OFF) + if (WITH_NETWORK_GET_BUFFER) +- include(CheckCSourceCompiles) + check_c_source_compiles("#define _GNU_SOURCE=1\n#include \nint main(void) { return O_TMPFILE; }" + HAS_O_TMPFILE) + +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0023-iio-local-xml-add-and-use-iio_context_add_device-hel.patch libiio-0.23/debian/patches/0023-iio-local-xml-add-and-use-iio_context_add_device-hel.patch --- libiio-0.21/debian/patches/0023-iio-local-xml-add-and-use-iio_context_add_device-hel.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0023-iio-local-xml-add-and-use-iio_context_add_device-hel.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -From e986fcd8fe3db6023f1757a3b621c74957038aa8 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 7 Oct 2020 16:56:42 +0300 -Subject: [PATCH 23/53] iio,local,xml: add and use iio_context_add_device() - helper - -This is common code present in the local & xml backends. It should be -moved in the context.c file to hide the access to the 'ctx->nb_devices' && -'ctx->devices' objects. - -Signed-off-by: Alexandru Ardelean ---- - context.c | 16 ++++++++++++++++ - iio-private.h | 2 ++ - local.c | 16 +--------------- - xml.c | 11 +++-------- - 4 files changed, 22 insertions(+), 23 deletions(-) - -diff --git a/context.c b/context.c -index a36eaf6..ab4a4b1 100644 ---- a/context.c -+++ b/context.c -@@ -443,6 +443,22 @@ const char * iio_context_get_attr_value( - return NULL; - } - -+int iio_context_add_device(struct iio_context *ctx, struct iio_device *dev) -+{ -+ struct iio_device **devices = realloc(ctx->devices, -+ (ctx->nb_devices + 1) * sizeof(struct iio_device *)); -+ -+ if (!devices) { -+ IIO_ERROR("Unable to allocate memory\n"); -+ return -ENOMEM; -+ } -+ -+ devices[ctx->nb_devices++] = dev; -+ ctx->devices = devices; -+ IIO_DEBUG("Added device \'%s\' to context \'%s\'\n", dev->id, ctx->name); -+ return 0; -+} -+ - int iio_context_add_attr(struct iio_context *ctx, - const char *key, const char *value) - { -diff --git a/iio-private.h b/iio-private.h -index c16580a..f0cfb26 100644 ---- a/iio-private.h -+++ b/iio-private.h -@@ -315,6 +315,8 @@ char *iio_strdup(const char *str); - size_t iio_strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize); - char * iio_getenv (char * envvar); - -+int iio_context_add_device(struct iio_context *ctx, struct iio_device *dev); -+ - int iio_context_add_attr(struct iio_context *ctx, - const char *key, const char *value); - -diff --git a/local.c b/local.c -index 24589ad..ab49607 100644 ---- a/local.c -+++ b/local.c -@@ -1427,20 +1427,6 @@ static int add_channel_to_device(struct iio_device *dev, - return 0; - } - --static int add_device_to_context(struct iio_context *ctx, -- struct iio_device *dev) --{ -- struct iio_device **devices = realloc(ctx->devices, -- (ctx->nb_devices + 1) * sizeof(struct iio_device *)); -- if (!devices) -- return -ENOMEM; -- -- devices[ctx->nb_devices++] = dev; -- ctx->devices = devices; -- IIO_DEBUG("Added device \'%s\' to context \'%s\'\n", dev->id, ctx->name); -- return 0; --} -- - static struct iio_channel *create_channel(struct iio_device *dev, - char *id, const char *attr, const char *path, - bool is_scan_element) -@@ -1869,7 +1855,7 @@ static int create_device(void *d, const char *path) - - dev->mask = mask; - -- ret = add_device_to_context(ctx, dev); -+ ret = iio_context_add_device(ctx, dev); - if (!ret) - return 0; - -diff --git a/xml.c b/xml.c -index 965db79..73ff988 100644 ---- a/xml.c -+++ b/xml.c -@@ -400,7 +400,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - } - - for (n = root->children; n; n = n->next) { -- struct iio_device **devs, *dev; -+ struct iio_device *dev; - - if (!strcmp((char *) n->name, "context-attribute")) { - err = parse_context_attr(ctx, n); -@@ -421,16 +421,11 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - goto err_context_destroy; - } - -- devs = realloc(ctx->devices, (1 + ctx->nb_devices) * -- sizeof(struct iio_device *)); -- if (!devs) { -- IIO_ERROR("Unable to allocate memory\n"); -+ err = iio_context_add_device(ctx, dev); -+ if (err) { - free(dev); - goto err_context_destroy; - } -- -- devs[ctx->nb_devices++] = dev; -- ctx->devices = devs; - } - - err = iio_context_init(ctx); --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0024-iiod-access-IIO-devices-via-API-accessors.patch libiio-0.23/debian/patches/0024-iiod-access-IIO-devices-via-API-accessors.patch --- libiio-0.21/debian/patches/0024-iiod-access-IIO-devices-via-API-accessors.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0024-iiod-access-IIO-devices-via-API-accessors.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 21e018cd001a084b9ed122063772edbfbfc061f8 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 8 Oct 2020 15:09:17 +0300 -Subject: [PATCH 24/53] iiod: access IIO devices via API accessors - -The intent is to hide the context object inside 'context.c' for better -modularity of the library. - -Signed-off-by: Alexandru Ardelean ---- - iiod/ops.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/iiod/ops.c b/iiod/ops.c -index 586bb16..5085221 100644 ---- a/iiod/ops.c -+++ b/iiod/ops.c -@@ -1422,8 +1422,8 @@ void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, - yylex_destroy(scanner); - - /* Close all opened devices */ -- for (i = 0; i < ctx->nb_devices; i++) -- close_dev_helper(&pdata, ctx->devices[i]); -+ for (i = 0; i < iio_context_get_devices_count(ctx); i++) -+ close_dev_helper(&pdata, iio_context_get_device(ctx, i)); - - #if WITH_AIO - if (use_aio) { --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0024-usb-Fix-printf-format-in-debug-string.patch libiio-0.23/debian/patches/0024-usb-Fix-printf-format-in-debug-string.patch --- libiio-0.21/debian/patches/0024-usb-Fix-printf-format-in-debug-string.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0024-usb-Fix-printf-format-in-debug-string.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,29 @@ +From 471d2b84368a3dcd62efd12a365ad8aeaccb69a4 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Fri, 12 Nov 2021 16:50:50 +0000 +Subject: [PATCH 24/26] usb: Fix printf format in debug string + +The parameter is a uint16_t, therefore the format specifier should be +%hu and not %hhu. + +Signed-off-by: Paul Cercueil +--- + usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/usb.c b/usb.c +index b2042e9c..97a4496b 100644 +--- a/usb.c ++++ b/usb.c +@@ -928,7 +928,7 @@ static struct iio_context * usb_create_context(unsigned int bus, + + pdata->nb_ep_couples = iface->bNumEndpoints / 2; + +- IIO_DEBUG("Found %hhu usable i/o endpoint couples\n", pdata->nb_ep_couples); ++ IIO_DEBUG("Found %hu usable i/o endpoint couples\n", pdata->nb_ep_couples); + + pdata->io_endpoints = calloc(pdata->nb_ep_couples, + sizeof(*pdata->io_endpoints)); +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0025-Archive-windows-artifacts.patch libiio-0.23/debian/patches/0025-Archive-windows-artifacts.patch --- libiio-0.21/debian/patches/0025-Archive-windows-artifacts.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0025-Archive-windows-artifacts.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,33 @@ +From ecbaa3a14d1492bb92b1cce950c70cbc07d2c03f Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Fri, 12 Nov 2021 11:45:04 +0200 +Subject: [PATCH 25/26] Archive windows artifacts + +Signed-off-by: Raluca Chis +--- + azure-pipelines.yml | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index 2b5559ac..a294acfb 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -228,7 +228,14 @@ stages: + steps: + - task: DownloadPipelineArtifact@2 + inputs: +- path: /home/vsts/work/1/a ++ path: '$(Build.ArtifactStagingDirectory)' ++ - script: | ++ cd $(Build.ArtifactStagingDirectory) ++ zip -r ./Windows-VS-16-2019-Win32.zip ./Windows-VS-16-2019-Win32 ++ rm -r ./Windows-VS-16-2019-Win32 ++ zip -r ./Windows-VS-16-2019-x64.zip ./Windows-VS-16-2019-x64 ++ rm -r ./Windows-VS-16-2019-x64 ++ displayName: "Archive windows artifacts" + - task: DownloadSecureFile@1 + name: key + displayName: 'Download rsa key' +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0025-Make-the-build-reproducible-Closes-591.patch libiio-0.23/debian/patches/0025-Make-the-build-reproducible-Closes-591.patch --- libiio-0.21/debian/patches/0025-Make-the-build-reproducible-Closes-591.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0025-Make-the-build-reproducible-Closes-591.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -From 53ad0a5ec99b8cbcbcb3decac08f4c42a1eeedf1 Mon Sep 17 00:00:00 2001 -From: Chris Lamb -Date: Sat, 10 Oct 2020 11:46:24 +0100 -Subject: [PATCH 25/53] Make the build reproducible (Closes: #591) - -Whilst working on the Reproducible Builds effort [0] we noticed that -libiio could not be built reproducibly. - -This is because it uses the current build time in the generated -manpages. Patch attached that uses SOURCE_DATE_EPOCH [1]. - - [0] https://reproducible-builds.org/ - [1] https://reproducible-builds.org/docs/source-date-epoch/ - -Signed-off-by: Chris Lamb ---- - man/CMakeLists.txt | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt -index c8924b5..2555ece 100644 ---- a/man/CMakeLists.txt -+++ b/man/CMakeLists.txt -@@ -1,9 +1,15 @@ - if (WITH_MAN) - find_program(BASH_EXECUTABLE bash) - find_program(DATE_EXECUTABLE date) -- execute_process( -- COMMAND ${DATE_EXECUTABLE} "+%d %B %Y" -- OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) -+ if (DEFINED ENV{SOURCE_DATE_EPOCH}) -+ execute_process( -+ COMMAND ${DATE_EXECUTABLE} "-u" "-d" "@$ENV{SOURCE_DATE_EPOCH}" "+%d %B %Y" -+ OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) -+ else () -+ execute_process( -+ COMMAND ${DATE_EXECUTABLE} "+%d %B %Y" -+ OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) -+ endif () - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/make_man.sh.in - ${CMAKE_CURRENT_BINARY_DIR}/make_man.sh @ONLY) --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0026-CI-update-macOS-version.patch libiio-0.23/debian/patches/0026-CI-update-macOS-version.patch --- libiio-0.21/debian/patches/0026-CI-update-macOS-version.patch 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/0026-CI-update-macOS-version.patch 2021-11-28 00:39:09.000000000 +0000 @@ -0,0 +1,40 @@ +From fbf5adb2d21c88c018f3642bacf994773cc94e1c Mon Sep 17 00:00:00 2001 +From: Raluca Chis +Date: Wed, 17 Nov 2021 15:22:18 +0200 +Subject: [PATCH 26/26] CI: update macOS version + +Signed-off-by: Raluca Chis +--- + azure-pipelines.yml | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +diff --git a/azure-pipelines.yml b/azure-pipelines.yml +index a294acfb..2d004e2b 100644 +--- a/azure-pipelines.yml ++++ b/azure-pipelines.yml +@@ -88,19 +88,12 @@ stages: + - job: macOSBuilds + strategy: + matrix: +- macOS_10_14: +- imageName: 'macOS-10.14' +- artifactName: 'macOS-10.14' + macOS_10_15: + imageName: 'macOS-10.15' + artifactName: 'macOS-10.15' +-# FIXME: uncomment after this is resolved: +-# https://github.com/actions/virtual-environments/issues/2072 +-# Mac OS X 11.0 is definitely a big thing (with their switch to ARM, +-# so we should be quick to have it) +-# macOS_11_0: +-# imageName: 'macOS-11.0' +-# artifactName: 'macOS-11.0' ++ macOS_11: ++ imageName: 'macOS-11' ++ artifactName: 'macOS-11' + pool: + vmImage: $(imageName) + steps: +-- +2.30.2 + diff -Nru libiio-0.21/debian/patches/0026-iiod-client-move-context-lock-inside-the-iiod_client.patch libiio-0.23/debian/patches/0026-iiod-client-move-context-lock-inside-the-iiod_client.patch --- libiio-0.21/debian/patches/0026-iiod-client-move-context-lock-inside-the-iiod_client.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0026-iiod-client-move-context-lock-inside-the-iiod_client.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,357 +0,0 @@ -From a56f583ded5f1965c1f97505a0f262fa7cb38478 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Fri, 9 Oct 2020 16:07:58 +0300 -Subject: [PATCH 26/53] iiod-client: move context lock inside the iiod_client - object - -All the iiod-client (type) backends create a context lock and pass it to -the iio_client object via iiod_client_new(). - -This looks wonky, since the iio_client routines do a lot of things with -that lock. - -The serial backend uses it quite extensively. The USB doesn't (explicitly -lock it at all), and the network backend only uses it during -network_close() (which may be un-required). - -For the cases where this lock is still used, a iiod_client_mutex_{un}lock() -function pair is created to access the lock. We may find that we can hide -the lock entirely, but until then this change shouldn't change any current -behavior. - -Signed-off-by: Alexandru Ardelean ---- - iiod-client.c | 24 ++++++++++++++++++++++-- - iiod-client.h | 5 ++++- - network.c | 28 +++++++++------------------- - serial.c | 31 ++++++++++--------------------- - usb.c | 18 ++---------------- - 5 files changed, 47 insertions(+), 59 deletions(-) - -diff --git a/iiod-client.c b/iiod-client.c -index 35583b6..b6a9af8 100644 ---- a/iiod-client.c -+++ b/iiod-client.c -@@ -32,6 +32,16 @@ struct iiod_client { - struct iio_mutex *lock; - }; - -+void iiod_client_mutex_lock(struct iiod_client *client) -+{ -+ iio_mutex_lock(client->lock); -+} -+ -+void iiod_client_mutex_unlock(struct iiod_client *client) -+{ -+ iio_mutex_unlock(client->lock); -+} -+ - static ssize_t iiod_client_read_integer(struct iiod_client *client, - void *desc, int *val) - { -@@ -138,7 +148,7 @@ static ssize_t iiod_client_read_all(struct iiod_client *client, - } - - struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, -- struct iio_mutex *lock, const struct iiod_client_ops *ops) -+ const struct iiod_client_ops *ops) - { - struct iiod_client *client; - -@@ -148,14 +158,24 @@ struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, - return NULL; - } - -- client->lock = lock; -+ client->lock = iio_mutex_create(); -+ if (!client->lock) { -+ errno = ENOMEM; -+ goto err_free_client; -+ } -+ - client->pdata = pdata; - client->ops = ops; - return client; -+ -+err_free_client: -+ free(client); -+ return NULL; - } - - void iiod_client_destroy(struct iiod_client *client) - { -+ iio_mutex_destroy(client->lock); - free(client); - } - -diff --git a/iiod-client.h b/iiod-client.h -index dcf2482..14e230f 100644 ---- a/iiod-client.h -+++ b/iiod-client.h -@@ -34,8 +34,11 @@ struct iiod_client_ops { - void *desc, char *dst, size_t len); - }; - -+void iiod_client_mutex_lock(struct iiod_client *client); -+void iiod_client_mutex_unlock(struct iiod_client *client); -+ - struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, -- struct iio_mutex *lock, const struct iiod_client_ops *ops); -+ const struct iiod_client_ops *ops); - void iiod_client_destroy(struct iiod_client *client); - - int iiod_client_get_version(struct iiod_client *client, void *desc, -diff --git a/network.c b/network.c -index 6bd6193..87f9e28 100644 ---- a/network.c -+++ b/network.c -@@ -47,7 +47,6 @@ struct iio_network_io_context { - struct iio_context_pdata { - struct iio_network_io_context io_ctx; - struct addrinfo *addrinfo; -- struct iio_mutex *lock; - struct iiod_client *iiod_client; - bool msg_trunc_supported; - }; -@@ -1080,10 +1079,10 @@ static void network_shutdown(struct iio_context *ctx) - struct iio_context_pdata *pdata = ctx->pdata; - unsigned int i; - -- iio_mutex_lock(pdata->lock); -+ iiod_client_mutex_lock(pdata->iiod_client); - write_command(&pdata->io_ctx, "\r\nEXIT\r\n"); - close(pdata->io_ctx.fd); -- iio_mutex_unlock(pdata->lock); -+ iiod_client_mutex_unlock(pdata->iiod_client); - - for (i = 0; i < iio_context_get_devices_count(ctx); i++) { - struct iio_device *dev = iio_context_get_device(ctx, i); -@@ -1097,7 +1096,6 @@ static void network_shutdown(struct iio_context *ctx) - } - - iiod_client_destroy(pdata->iiod_client); -- iio_mutex_destroy(pdata->lock); - freeaddrinfo(pdata->addrinfo); - free(pdata); - } -@@ -1293,6 +1291,7 @@ struct iio_context * network_create_context(const char *host) - { - struct addrinfo hints, *res; - struct iio_context *ctx; -+ struct iiod_client *iiod_client; - struct iio_context_pdata *pdata; - size_t i, len, uri_len; - int fd, ret; -@@ -1361,28 +1360,21 @@ struct iio_context * network_create_context(const char *host) - goto err_close_socket; - } - -+ iiod_client = iiod_client_new(pdata, &network_iiod_client_ops); -+ if (!iiod_client) -+ goto err_free_pdata; -+ -+ pdata->iiod_client = iiod_client; - pdata->io_ctx.fd = fd; - pdata->addrinfo = res; - pdata->io_ctx.timeout_ms = DEFAULT_TIMEOUT_MS; - -- pdata->lock = iio_mutex_create(); -- if (!pdata->lock) { -- errno = ENOMEM; -- goto err_free_pdata; -- } -- -- pdata->iiod_client = iiod_client_new(pdata, pdata->lock, -- &network_iiod_client_ops); -- - pdata->msg_trunc_supported = msg_trunc_supported(&pdata->io_ctx); - if (pdata->msg_trunc_supported) - IIO_DEBUG("MSG_TRUNC is supported\n"); - else - IIO_DEBUG("MSG_TRUNC is NOT supported\n"); - -- if (!pdata->iiod_client) -- goto err_destroy_mutex; -- - IIO_DEBUG("Creating context...\n"); - ctx = iiod_client_create_context(pdata->iiod_client, &pdata->io_ctx); - if (!ctx) -@@ -1517,9 +1509,7 @@ err_network_shutdown: - return NULL; - - err_destroy_iiod_client: -- iiod_client_destroy(pdata->iiod_client); --err_destroy_mutex: -- iio_mutex_destroy(pdata->lock); -+ iiod_client_destroy(iiod_client); - err_free_pdata: - free(pdata); - err_close_socket: -diff --git a/serial.c b/serial.c -index 0a23c95..6c2559c 100644 ---- a/serial.c -+++ b/serial.c -@@ -32,7 +32,6 @@ - - struct iio_context_pdata { - struct sp_port *port; -- struct iio_mutex *lock; - struct iiod_client *iiod_client; - - unsigned int timeout_ms; -@@ -124,7 +123,7 @@ static int serial_open(const struct iio_device *dev, - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBUSY; - -- iio_mutex_lock(ctx_pdata->lock); -+ iiod_client_mutex_lock(ctx_pdata->iiod_client); - if (pdata->opened) - goto out_unlock; - -@@ -134,7 +133,7 @@ static int serial_open(const struct iio_device *dev, - pdata->opened = !ret; - - out_unlock: -- iio_mutex_unlock(ctx_pdata->lock); -+ iiod_client_mutex_unlock(ctx_pdata->iiod_client); - return ret; - } - -@@ -145,7 +144,7 @@ static int serial_close(const struct iio_device *dev) - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBADF; - -- iio_mutex_lock(ctx_pdata->lock); -+ iiod_client_mutex_lock(ctx_pdata->iiod_client); - if (!pdata->opened) - goto out_unlock; - -@@ -153,7 +152,7 @@ static int serial_close(const struct iio_device *dev) - pdata->opened = false; - - out_unlock: -- iio_mutex_unlock(ctx_pdata->lock); -+ iiod_client_mutex_unlock(ctx_pdata->iiod_client); - return ret; - } - -@@ -164,10 +163,10 @@ static ssize_t serial_read(const struct iio_device *dev, void *dst, size_t len, - struct iio_context_pdata *pdata = ctx->pdata; - ssize_t ret; - -- iio_mutex_lock(pdata->lock); -+ iiod_client_mutex_lock(pdata->iiod_client); - ret = iiod_client_read_unlocked(pdata->iiod_client, NULL, - dev, dst, len, mask, words); -- iio_mutex_unlock(pdata->lock); -+ iiod_client_mutex_unlock(pdata->iiod_client); - - return ret; - } -@@ -179,9 +178,9 @@ static ssize_t serial_write(const struct iio_device *dev, - struct iio_context_pdata *pdata = ctx->pdata; - ssize_t ret; - -- iio_mutex_lock(pdata->lock); -+ iiod_client_mutex_lock(pdata->iiod_client); - ret = iiod_client_write_unlocked(pdata->iiod_client, NULL, dev, src, len); -- iio_mutex_unlock(pdata->lock); -+ iiod_client_mutex_unlock(pdata->iiod_client); - - return ret; - } -@@ -297,7 +296,6 @@ static void serial_shutdown(struct iio_context *ctx) - unsigned int i; - - iiod_client_destroy(ctx_pdata->iiod_client); -- iio_mutex_destroy(ctx_pdata->lock); - sp_close(ctx_pdata->port); - sp_free_port(ctx_pdata->port); - -@@ -425,16 +423,9 @@ static struct iio_context * serial_create_context(const char *port_name, - pdata->port = port; - pdata->timeout_ms = DEFAULT_TIMEOUT_MS; - -- pdata->lock = iio_mutex_create(); -- if (!pdata->lock) { -- errno = ENOMEM; -- goto err_free_pdata; -- } -- -- pdata->iiod_client = iiod_client_new(pdata, pdata->lock, -- &serial_iiod_client_ops); -+ pdata->iiod_client = iiod_client_new(pdata, &serial_iiod_client_ops); - if (!pdata->iiod_client) -- goto err_destroy_mutex; -+ goto err_free_pdata; - - ctx = iiod_client_create_context(pdata->iiod_client, NULL); - if (!ctx) -@@ -473,8 +464,6 @@ err_context_destroy: - - err_destroy_iiod_client: - iiod_client_destroy(pdata->iiod_client); --err_destroy_mutex: -- iio_mutex_destroy(pdata->lock); - err_free_pdata: - free(pdata); - err_free_description: -diff --git a/usb.c b/usb.c -index 7a236f5..f2b8442 100644 ---- a/usb.c -+++ b/usb.c -@@ -62,9 +62,6 @@ struct iio_context_pdata { - - struct iiod_client *iiod_client; - -- /* Lock for non-streaming operations */ -- struct iio_mutex *lock; -- - /* Lock for endpoint reservation */ - struct iio_mutex *ep_lock; - -@@ -457,7 +454,6 @@ static void usb_shutdown(struct iio_context *ctx) - for (i = 0; i < nb_devices; i++) - usb_close(iio_context_get_device(ctx, i)); - -- iio_mutex_destroy(ctx->pdata->lock); - iio_mutex_destroy(ctx->pdata->ep_lock); - - for (i = 0; i < ctx->pdata->nb_ep_couples; i++) -@@ -840,22 +836,14 @@ struct iio_context * usb_create_context(unsigned int bus, - goto err_set_errno; - } - -- pdata->lock = iio_mutex_create(); -- if (!pdata->lock) { -- IIO_ERROR("Unable to create mutex\n"); -- ret = -ENOMEM; -- goto err_free_pdata; -- } -- - pdata->ep_lock = iio_mutex_create(); - if (!pdata->ep_lock) { - IIO_ERROR("Unable to create mutex\n"); - ret = -ENOMEM; -- goto err_destroy_mutex; -+ goto err_free_pdata; - } - -- pdata->iiod_client = iiod_client_new(pdata, pdata->lock, -- &usb_iiod_client_ops); -+ pdata->iiod_client = iiod_client_new(pdata, &usb_iiod_client_ops); - if (!pdata->iiod_client) { - IIO_ERROR("Unable to create IIOD client\n"); - ret = -errno; -@@ -1062,8 +1050,6 @@ err_destroy_iiod_client: - iiod_client_destroy(pdata->iiod_client); - err_destroy_ep_mutex: - iio_mutex_destroy(pdata->ep_lock); --err_destroy_mutex: -- iio_mutex_destroy(pdata->lock); - err_free_pdata: - free(pdata); - err_set_errno: --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0027-appveyor.yml-parametrize-mingw-toolchains-version-an.patch libiio-0.23/debian/patches/0027-appveyor.yml-parametrize-mingw-toolchains-version-an.patch --- libiio-0.21/debian/patches/0027-appveyor.yml-parametrize-mingw-toolchains-version-an.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0027-appveyor.yml-parametrize-mingw-toolchains-version-an.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -From 4047da774b7a7e73f74d7ff223122133cc7271f5 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Tue, 13 Oct 2020 12:17:26 +0300 -Subject: [PATCH 27/53] appveyor.yml: parametrize mingw toolchains version and - bump version - -It makes things easier than changing in 4 places. -And bump to version 10.0.0-3. -At this version, there are no more tar.xz archives. Only tar.zst. - -Version 5.0.0-3 seems to start disappearing from the web. - -Signed-off-by: Alexandru Ardelean ---- - appveyor.yml | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/appveyor.yml b/appveyor.yml -index 068be43..154e83b 100644 ---- a/appveyor.yml -+++ b/appveyor.yml -@@ -29,6 +29,7 @@ build_script: - - set OPT_PATH=C:\msys64\mingw32\bin;C:\msys64\mingw64\bin; - - set PATH=%OPT_PATH%%PATH% - - set GENERATOR=Unix Makefiles -+ - set MINGW_TOOLCHAIN_VERSION=10.0.0-3 - - cd C:\projects\libiio - - set folder-path=C:\projects\libiio\build-mingw-win32\%configuration% - # MinGW 32 bit -@@ -50,7 +51,7 @@ build_script: - - C:\msys64\usr\bin\bash -lc "rm /mingw32/etc/gdbinit" - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy mingw-w64-i686-gcc mingw-w64-i686-libusb mingw-w64-i686-curl mingw-w64-i686-cmake mingw-w64-i686-libxml2 mingw-w64-i686-pkg-config mingw-w64-i686-libzip" - # Newer llvm breaks doxygen, use old version for now -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-llvm-5.0.0-3-any.pkg.tar.xz http://repo.msys2.org/mingw/i686/mingw-w64-i686-clang-5.0.0-3-any.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/i686/mingw-w64-i686-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" - # set the specific version of doxygen (06-Jun-2018), need to look at this later. - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-doxygen-1.8.14-2-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-graphviz-2.40.1-4-any.pkg.tar.xz" -@@ -72,7 +73,7 @@ build_script: - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy pacman" - - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Su" - # Newer llvm breaks doxygen, use old version for now -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-llvm-5.0.0-3-any.pkg.tar.xz http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-clang-5.0.0-3-any.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" - # set the specific version of doxygen, need to look at this later. - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-1.8.14-2-any.pkg.tar.xz" - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-2.40.1-4-any.pkg.tar.xz" --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0028-appveyor.yml-parametrize-bump-doxygen-graphviz-versi.patch libiio-0.23/debian/patches/0028-appveyor.yml-parametrize-bump-doxygen-graphviz-versi.patch --- libiio-0.21/debian/patches/0028-appveyor.yml-parametrize-bump-doxygen-graphviz-versi.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0028-appveyor.yml-parametrize-bump-doxygen-graphviz-versi.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -From bf452258e9b5e666e455ba7b51d580cad82f9805 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Tue, 13 Oct 2020 12:22:59 +0300 -Subject: [PATCH 28/53] appveyor.yml: parametrize + bump doxygen & graphviz - versions - -Versions are in 2 places. So add parameters for versions. -And change to tar.zst archives. -There are no more tar.xz archives. - -Signed-off-by: Alexandru Ardelean ---- - appveyor.yml | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/appveyor.yml b/appveyor.yml -index 154e83b..d8d1bff 100644 ---- a/appveyor.yml -+++ b/appveyor.yml -@@ -30,6 +30,8 @@ build_script: - - set PATH=%OPT_PATH%%PATH% - - set GENERATOR=Unix Makefiles - - set MINGW_TOOLCHAIN_VERSION=10.0.0-3 -+ - set DOXYGEN_VERSION=1.8.18-1 -+ - set GRAPHVIZ_VERSION=2.40.1-13 - - cd C:\projects\libiio - - set folder-path=C:\projects\libiio\build-mingw-win32\%configuration% - # MinGW 32 bit -@@ -53,8 +55,8 @@ build_script: - # Newer llvm breaks doxygen, use old version for now - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/i686/mingw-w64-i686-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" - # set the specific version of doxygen (06-Jun-2018), need to look at this later. -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-doxygen-1.8.14-2-any.pkg.tar.xz" -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-graphviz-2.40.1-4-any.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-doxygen-%DOXYGEN_VERSION%-any.pkg.tar.zst" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/i686/mingw-w64-i686-graphviz-%GRAPHVIZ_VERSION%-any.pkg.tar.zst" - # Download a 32-bit version of windres.exe - - appveyor DownloadFile http://swdownloads.analog.com/cse/build/windres.exe.gz -FileName C:\windres.exe.gz - - C:\msys64\usr\bin\bash -lc "cd /c ; gunzip windres.exe.gz" -@@ -75,8 +77,8 @@ build_script: - # Newer llvm breaks doxygen, use old version for now - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-llvm-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-clang-%MINGW_TOOLCHAIN_VERSION%-any.pkg.tar.zst" - # set the specific version of doxygen, need to look at this later. -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-1.8.14-2-any.pkg.tar.xz" -- - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-2.40.1-4-any.pkg.tar.xz" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-%DOXYGEN_VERSION%-any.pkg.tar.zst" -+ - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-%GRAPHVIZ_VERSION%-any.pkg.tar.zst" - - C:\msys64\usr\bin\bash -lc "cmake -G '%GENERATOR%' -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_INSTALL_PREFIX=/mingw64 -DCMAKE_C_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-g++.exe -DPKG_CONFIG_EXECUTABLE:FILEPATH=/mingw64/bin/pkg-config.exe -DENABLE_IPV6:BOOL=OFF -DLIBSERIALPORT_LIBRARIES=/c/libs/64/libserialport.dll.a -DLIBSERIALPORT_INCLUDE_DIR=/c/include /c/projects/libiio && make -j3" - - # Move the tests folder --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0029-network-change-type-of-i-to-unsigned-int.patch libiio-0.23/debian/patches/0029-network-change-type-of-i-to-unsigned-int.patch --- libiio-0.21/debian/patches/0029-network-change-type-of-i-to-unsigned-int.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0029-network-change-type-of-i-to-unsigned-int.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -From fea0a70f75a1a25beb5c7be17a1091157063985d Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Tue, 13 Oct 2020 14:04:05 +0300 -Subject: [PATCH 29/53] network: change type of 'i' to unsigned int - -This only happens on Appveyor with Visual C compiler. -``` -C:\projects\libiio\network.c(1458): error C2220: warning treated as error - no 'object' file generated [C:\projects\libiio\build-win64\iio.vcxproj] -C:\projects\libiio\network.c(1458): warning C4267: 'function' : conversion from 'size_t' to 'unsigned int', possible loss of data [C:\projects\libiio\build-win64\iio.vcxproj] -``` - -Warning is reasonable. So, change type of 'i'. - -Signed-off-by: Alexandru Ardelean ---- - network.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/network.c b/network.c -index 87f9e28..77d4034 100644 ---- a/network.c -+++ b/network.c -@@ -1293,7 +1293,8 @@ struct iio_context * network_create_context(const char *host) - struct iio_context *ctx; - struct iiod_client *iiod_client; - struct iio_context_pdata *pdata; -- size_t i, len, uri_len; -+ size_t len, uri_len; -+ unsigned int i; - int fd, ret; - char *description, *uri; - #ifdef _WIN32 --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0030-network-split-description-creation-into-it-s-own-fun.patch libiio-0.23/debian/patches/0030-network-split-description-creation-into-it-s-own-fun.patch --- libiio-0.21/debian/patches/0030-network-split-description-creation-into-it-s-own-fun.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0030-network-split-description-creation-into-it-s-own-fun.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +0,0 @@ -From 8020f093f44936f34f09c1f0f3529347d20a5e5f Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 12 Oct 2020 16:41:12 +0300 -Subject: [PATCH 30/53] network: split description creation into it's own - function - -The logic looks a bit spread across the network_create_context() function. -It looks like it would make sense to move it into it's own function. -This might give us the opportunity later to convert the -'iio_context->description' into a backend op. - -Signed-off-by: Alexandru Ardelean ---- - network.c | 119 ++++++++++++++++++++++++++++++------------------------ - 1 file changed, 67 insertions(+), 52 deletions(-) - -diff --git a/network.c b/network.c -index 77d4034..b64cc77 100644 ---- a/network.c -+++ b/network.c -@@ -587,6 +587,60 @@ int create_socket(const struct addrinfo *addrinfo, unsigned int timeout) - return fd; - } - -+static char * network_get_description(struct addrinfo *res, size_t *len) -+{ -+ char *description; -+ -+#ifdef HAVE_IPV6 -+ *len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; -+#else -+ *len = INET_ADDRSTRLEN + 1; -+#endif -+ -+ description = malloc(*len); -+ if (!description) { -+ errno = ENOMEM; -+ return NULL; -+ } -+ -+ description[0] = '\0'; -+ -+#ifdef HAVE_IPV6 -+ if (res->ai_family == AF_INET6) { -+ struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; -+ char *ptr; -+ inet_ntop(AF_INET6, &in->sin6_addr, -+ description, INET6_ADDRSTRLEN); -+ -+ if (IN6_IS_ADDR_LINKLOCAL(&in->sin6_addr)) { -+ ptr = if_indextoname(in->sin6_scope_id, description + -+ strlen(description) + 1); -+ if (!ptr) { -+ IIO_ERROR("Unable to lookup interface of IPv6 address\n"); -+ goto err_free_description; -+ } -+ -+ *(ptr - 1) = '%'; -+ } -+ } -+#endif -+ if (res->ai_family == AF_INET) { -+ struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; -+#if (!_WIN32 || _WIN32_WINNT >= 0x600) -+ inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN); -+#else -+ char *tmp = inet_ntoa(in->sin_addr); -+ iio_strlcpy(description, tmp, *len); -+#endif -+ } -+ -+ return description; -+ -+err_free_description: -+ free(description); -+ return NULL; -+} -+ - static int network_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -@@ -1361,9 +1415,13 @@ struct iio_context * network_create_context(const char *host) - goto err_close_socket; - } - -+ description = network_get_description(res, &len); -+ if (!description) -+ goto err_free_pdata; -+ - iiod_client = iiod_client_new(pdata, &network_iiod_client_ops); - if (!iiod_client) -- goto err_free_pdata; -+ goto err_free_description; - - pdata->iiod_client = iiod_client; - pdata->io_ctx.fd = fd; -@@ -1387,12 +1445,6 @@ struct iio_context * network_create_context(const char *host) - ctx->ops = &network_ops; - ctx->pdata = pdata; - --#ifdef HAVE_IPV6 -- len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; --#else -- len = INET_ADDRSTRLEN + 1; --#endif -- - uri_len = len; - if (host && host[0]) - uri_len = strnlen(host, MAXHOSTNAMELEN); -@@ -1404,47 +1456,9 @@ struct iio_context * network_create_context(const char *host) - goto err_network_shutdown; - } - -- description = malloc(len); -- if (!description) { -- ret = -ENOMEM; -- goto err_free_uri; -- } -- -- description[0] = '\0'; -- --#ifdef HAVE_IPV6 -- if (res->ai_family == AF_INET6) { -- struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; -- char *ptr; -- inet_ntop(AF_INET6, &in->sin6_addr, -- description, INET6_ADDRSTRLEN); -- -- if (IN6_IS_ADDR_LINKLOCAL(&in->sin6_addr)) { -- ptr = if_indextoname(in->sin6_scope_id, description + -- strlen(description) + 1); -- if (!ptr) { -- ret = -errno; -- IIO_ERROR("Unable to lookup interface of IPv6 address\n"); -- goto err_free_description; -- } -- -- *(ptr - 1) = '%'; -- } -- } --#endif -- if (res->ai_family == AF_INET) { -- struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; --#if (!_WIN32 || _WIN32_WINNT >= 0x600) -- inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN); --#else -- char *tmp = inet_ntoa(in->sin_addr); -- iio_strlcpy(description, tmp, len); --#endif -- } -- - ret = iio_context_add_attr(ctx, "ip,ip-addr", description); - if (ret < 0) -- goto err_free_description; -+ goto err_free_uri; - - if (host && host[0]) - iio_snprintf(uri, uri_len, "ip:%s", host); -@@ -1453,7 +1467,7 @@ struct iio_context * network_create_context(const char *host) - - ret = iio_context_add_attr(ctx, "uri", uri); - if (ret < 0) -- goto err_free_description; -+ goto err_free_uri; - - for (i = 0; i < iio_context_get_devices_count(ctx); i++) { - struct iio_device *dev = iio_context_get_device(ctx, i); -@@ -1461,7 +1475,7 @@ struct iio_context * network_create_context(const char *host) - dev->pdata = zalloc(sizeof(*dev->pdata)); - if (!dev->pdata) { - ret = -ENOMEM; -- goto err_free_description; -+ goto err_free_uri; - } - - dev->pdata->io_ctx.fd = -1; -@@ -1473,7 +1487,7 @@ struct iio_context * network_create_context(const char *host) - dev->pdata->lock = iio_mutex_create(); - if (!dev->pdata->lock) { - ret = -ENOMEM; -- goto err_free_description; -+ goto err_free_uri; - } - } - -@@ -1483,7 +1497,7 @@ struct iio_context * network_create_context(const char *host) - char *ptr, *new_description = realloc(description, new_size); - if (!new_description) { - ret = -ENOMEM; -- goto err_free_description; -+ goto err_free_uri; - } - - ptr = strrchr(new_description, '\0'); -@@ -1500,17 +1514,18 @@ struct iio_context * network_create_context(const char *host) - calculate_remote_timeout(DEFAULT_TIMEOUT_MS)); - return ctx; - --err_free_description: -- free(description); - err_free_uri: - free(uri); - err_network_shutdown: -+ free(description); - iio_context_destroy(ctx); - errno = -ret; - return NULL; - - err_destroy_iiod_client: - iiod_client_destroy(iiod_client); -+err_free_description: -+ free(description); - err_free_pdata: - free(pdata); - err_close_socket: --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0031-serial-split-description-creation-into-it-s-own-func.patch libiio-0.23/debian/patches/0031-serial-split-description-creation-into-it-s-own-func.patch --- libiio-0.21/debian/patches/0031-serial-split-description-creation-into-it-s-own-func.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0031-serial-split-description-creation-into-it-s-own-func.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -From ab3387a48513b6f012b1b3d2b96eaedcd7cdc56a Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 12 Oct 2020 17:21:37 +0300 -Subject: [PATCH 31/53] serial: split description creation into it's own - function - -The gain for splitting this routine into it's own function isn't that great -right now, but it does create an overview about changing the -'iio_context->description' field into a backend op. - -Signed-off-by: Alexandru Ardelean ---- - serial.c | 36 ++++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 12 deletions(-) - -diff --git a/serial.c b/serial.c -index 6c2559c..77a02c1 100644 ---- a/serial.c -+++ b/serial.c -@@ -115,6 +115,26 @@ static int serial_get_version(const struct iio_context *ctx, - major, minor, git_tag); - } - -+static char * serial_get_description(struct sp_port *port) -+{ -+ char *description, *name, *desc; -+ size_t desc_len; -+ -+ name = sp_get_port_name(port); -+ desc = sp_get_port_description(port); -+ -+ desc_len = sizeof(": \0") + strlen(name) + strlen(desc); -+ description = malloc(desc_len); -+ if (!description) { -+ errno = ENOMEM; -+ return NULL; -+ } -+ -+ iio_snprintf(description, desc_len, "%s: %s", name, desc); -+ -+ return description; -+} -+ - static int serial_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -@@ -368,8 +388,8 @@ static struct iio_context * serial_create_context(const char *port_name, - struct sp_port *port; - struct iio_context_pdata *pdata; - struct iio_context *ctx; -- char *name, *desc, *description; -- size_t desc_len, uri_len; -+ char *description; -+ size_t uri_len; - unsigned int i; - int ret; - char *uri; -@@ -402,17 +422,9 @@ static struct iio_context * serial_create_context(const char *port_name, - /* Empty the buffers */ - sp_flush(port, SP_BUF_BOTH); - -- name = sp_get_port_name(port); -- desc = sp_get_port_description(port); -- -- desc_len = sizeof(": \0") + strlen(name) + strlen(desc); -- description = malloc(desc_len); -- if (!description) { -- errno = ENOMEM; -+ description = serial_get_description(port); -+ if (!description) - goto err_close_port; -- } -- -- iio_snprintf(description, desc_len, "%s: %s", name, desc); - - pdata = zalloc(sizeof(*pdata)); - if (!pdata) { --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0032-network-move-free-description-under-ifdef-HAVE_IPV6.patch libiio-0.23/debian/patches/0032-network-move-free-description-under-ifdef-HAVE_IPV6.patch --- libiio-0.21/debian/patches/0032-network-move-free-description-under-ifdef-HAVE_IPV6.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0032-network-move-free-description-under-ifdef-HAVE_IPV6.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -From 192869ccccbc9d96dc2aa14f40b9cc1b6f175909 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Tue, 13 Oct 2020 17:09:13 +0300 -Subject: [PATCH 32/53] network: move free(description) under #ifdef HAVE_IPV6 - -This was not happening on Travis-CI because it's compiling on Linux, and -HAVE_IPV6 is defined. -Under Windows/Appveyor it seems it isn't, so the 'err_free_description' -label in network_get_description() is unused. - -This also seems to have happened, because Appveyor builds were failing. - -Signed-off-by: Alexandru Ardelean ---- - network.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/network.c b/network.c -index b64cc77..309b033 100644 ---- a/network.c -+++ b/network.c -@@ -617,7 +617,8 @@ static char * network_get_description(struct addrinfo *res, size_t *len) - strlen(description) + 1); - if (!ptr) { - IIO_ERROR("Unable to lookup interface of IPv6 address\n"); -- goto err_free_description; -+ free(description); -+ return NULL; - } - - *(ptr - 1) = '%'; -@@ -635,10 +636,6 @@ static char * network_get_description(struct addrinfo *res, size_t *len) - } - - return description; -- --err_free_description: -- free(description); -- return NULL; - } - - static int network_open(const struct iio_device *dev, --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0033-iio-split-iio_backend_ops-into-iio-backend.h.patch libiio-0.23/debian/patches/0033-iio-split-iio_backend_ops-into-iio-backend.h.patch --- libiio-0.21/debian/patches/0033-iio-split-iio_backend_ops-into-iio-backend.h.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0033-iio-split-iio_backend_ops-into-iio-backend.h.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ -From 0fcd01c27948948b788f7696241bdc3b95a42cba Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Fri, 2 Oct 2020 16:04:07 +0300 -Subject: [PATCH 33/53] iio: split iio_backend_ops into iio-backend.h - -The iio_backend_ops will be split away from libiio core. So, move the -iio_backend_ops into another header. -This header will be available in the IIO backends, and the rest of the -libiio core internals will be hidden from IIO backends. - -Right now, this split isn't doing too much [mostly moving some types -around]. And it's not yet ready to be used on it's own. -It's only being used in 'iio-private.h', in the same manner as before. - -Signed-off-by: Alexandru Ardelean ---- - iio-backend.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ - iio-private.h | 75 ++++++++++----------------------------------------- - 2 files changed, 89 insertions(+), 61 deletions(-) - create mode 100644 iio-backend.h - -diff --git a/iio-backend.h b/iio-backend.h -new file mode 100644 -index 0000000..a32a35a ---- /dev/null -+++ b/iio-backend.h -@@ -0,0 +1,75 @@ -+/* -+ * libiio - Library for interfacing industrial I/O (IIO) devices -+ * -+ * Copyright (C) 2020 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. -+ * -+ * */ -+ -+#ifndef __IIO_BACKEND_H__ -+#define __IIO_BACKEND_H__ -+ -+#include -+ -+struct iio_device; -+struct iio_context; -+ -+enum iio_attr_type { -+ IIO_ATTR_TYPE_DEVICE = 0, -+ IIO_ATTR_TYPE_DEBUG, -+ IIO_ATTR_TYPE_BUFFER, -+}; -+ -+struct iio_backend_ops { -+ struct iio_context * (*clone)(const struct iio_context *ctx); -+ ssize_t (*read)(const struct iio_device *dev, void *dst, size_t len, -+ uint32_t *mask, size_t words); -+ ssize_t (*write)(const struct iio_device *dev, -+ const void *src, size_t len); -+ int (*open)(const struct iio_device *dev, -+ size_t samples_count, bool cyclic); -+ int (*close)(const struct iio_device *dev); -+ int (*get_fd)(const struct iio_device *dev); -+ int (*set_blocking_mode)(const struct iio_device *dev, bool blocking); -+ -+ void (*cancel)(const struct iio_device *dev); -+ -+ int (*set_kernel_buffers_count)(const struct iio_device *dev, -+ unsigned int nb_blocks); -+ ssize_t (*get_buffer)(const struct iio_device *dev, -+ void **addr_ptr, size_t bytes_used, -+ uint32_t *mask, size_t words); -+ -+ ssize_t (*read_device_attr)(const struct iio_device *dev, -+ const char *attr, char *dst, size_t len, enum iio_attr_type); -+ ssize_t (*write_device_attr)(const struct iio_device *dev, -+ const char *attr, const char *src, -+ size_t len, enum iio_attr_type); -+ ssize_t (*read_channel_attr)(const struct iio_channel *chn, -+ const char *attr, char *dst, size_t len); -+ ssize_t (*write_channel_attr)(const struct iio_channel *chn, -+ const char *attr, const char *src, size_t len); -+ -+ int (*get_trigger)(const struct iio_device *dev, -+ const struct iio_device **trigger); -+ int (*set_trigger)(const struct iio_device *dev, -+ const struct iio_device *trigger); -+ -+ void (*shutdown)(struct iio_context *ctx); -+ -+ int (*get_version)(const struct iio_context *ctx, unsigned int *major, -+ unsigned int *minor, char git_tag[8]); -+ -+ int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); -+}; -+ -+#endif /* __IIO_BACKEND_H__ */ -diff --git a/iio-private.h b/iio-private.h -index f0cfb26..1a21ca9 100644 ---- a/iio-private.h -+++ b/iio-private.h -@@ -22,6 +22,20 @@ - /* Include public interface */ - #include "iio.h" - -+#ifdef _WIN32 -+# ifdef LIBIIO_EXPORTS -+# define __api __declspec(dllexport) -+# else -+# define __api __declspec(dllimport) -+# endif -+#elif __GNUC__ >= 4 -+# define __api __attribute__((visibility ("default"))) -+#else -+# define __api -+#endif -+ -+#include "iio-backend.h" -+ - #include "iio-config.h" - - #include -@@ -35,18 +49,6 @@ - #define iio_sscanf sscanf - #endif - --#ifdef _WIN32 --# ifdef LIBIIO_EXPORTS --# define __api __declspec(dllexport) --# else --# define __api __declspec(dllimport) --# endif --#elif __GNUC__ >= 4 --# define __api __attribute__((visibility ("default"))) --#else --# define __api --#endif -- - #define ARRAY_SIZE(x) (sizeof(x) ? sizeof(x) / sizeof((x)[0]) : 0) - #define BIT(x) (1 << (x)) - #define BIT_MASK(bit) BIT((bit) % 32) -@@ -111,55 +113,6 @@ static inline void *zalloc(size_t size) - return calloc(1, size); - } - --enum iio_attr_type { -- IIO_ATTR_TYPE_DEVICE = 0, -- IIO_ATTR_TYPE_DEBUG, -- IIO_ATTR_TYPE_BUFFER, --}; -- --struct iio_backend_ops { -- struct iio_context * (*clone)(const struct iio_context *ctx); -- ssize_t (*read)(const struct iio_device *dev, void *dst, size_t len, -- uint32_t *mask, size_t words); -- ssize_t (*write)(const struct iio_device *dev, -- const void *src, size_t len); -- int (*open)(const struct iio_device *dev, -- size_t samples_count, bool cyclic); -- int (*close)(const struct iio_device *dev); -- int (*get_fd)(const struct iio_device *dev); -- int (*set_blocking_mode)(const struct iio_device *dev, bool blocking); -- -- void (*cancel)(const struct iio_device *dev); -- -- int (*set_kernel_buffers_count)(const struct iio_device *dev, -- unsigned int nb_blocks); -- ssize_t (*get_buffer)(const struct iio_device *dev, -- void **addr_ptr, size_t bytes_used, -- uint32_t *mask, size_t words); -- -- ssize_t (*read_device_attr)(const struct iio_device *dev, -- const char *attr, char *dst, size_t len, enum iio_attr_type); -- ssize_t (*write_device_attr)(const struct iio_device *dev, -- const char *attr, const char *src, -- size_t len, enum iio_attr_type); -- ssize_t (*read_channel_attr)(const struct iio_channel *chn, -- const char *attr, char *dst, size_t len); -- ssize_t (*write_channel_attr)(const struct iio_channel *chn, -- const char *attr, const char *src, size_t len); -- -- int (*get_trigger)(const struct iio_device *dev, -- const struct iio_device **trigger); -- int (*set_trigger)(const struct iio_device *dev, -- const struct iio_device *trigger); -- -- void (*shutdown)(struct iio_context *ctx); -- -- int (*get_version)(const struct iio_context *ctx, unsigned int *major, -- unsigned int *minor, char git_tag[8]); -- -- int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); --}; -- - /* - * If these structures are updated, the qsort functions defined in sort.c - * may need to be updated. --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0034-iio-create-iio_context_create_from_backend-helper-an.patch libiio-0.23/debian/patches/0034-iio-create-iio_context_create_from_backend-helper-an.patch --- libiio-0.21/debian/patches/0034-iio-create-iio_context_create_from_backend-helper-an.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0034-iio-create-iio_context_create_from_backend-helper-an.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,251 +0,0 @@ -From 4a72ef03cf7a045a3b447c22a49a9ed7a2d73835 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 8 Oct 2020 17:42:41 +0300 -Subject: [PATCH 34/53] iio: create iio_context_create_from_backend() helper - and use it for local & xml - -The creation of a context can be tied to an iio_backend object that acts as -a template for some context parameters. -Using an iio_backend object for IIO context creation allows us to hide the -assignments of the name, iio_backend_ops, description, private data and -possibly other parameters in the future. - -For now, this ties it to the local & xml backends. The other backends seem -to be iiod client-type backends. Using the iio_backend object there -requires a bit more rework. - -At a later point in time, the iio_context_create_from_backend() helper -should also do more validation for the backend object. - -Signed-off-by: Alexandru Ardelean ---- - context.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - iio-backend.h | 24 ++++++++++++++++++++++++ - local.c | 40 ++++++++++++++++++++-------------------- - xml.c | 24 +++++++++++++++--------- - 4 files changed, 104 insertions(+), 29 deletions(-) - -diff --git a/context.c b/context.c -index ab4a4b1..7e121cc 100644 ---- a/context.c -+++ b/context.c -@@ -182,6 +182,51 @@ err_free_ctx_attrs: - return NULL; - } - -+struct iio_context * iio_context_create_from_backend( -+ const struct iio_backend *backend, -+ const char *description) -+{ -+ struct iio_context *ctx; -+ int ret; -+ -+ if (!backend) { -+ errno = EINVAL; -+ return NULL; -+ } -+ -+ ctx = zalloc(sizeof(*ctx)); -+ if (!ctx) { -+ errno = ENOMEM; -+ return NULL; -+ } -+ -+ ret = -ENOMEM; -+ if (backend->sizeof_context_pdata) { -+ ctx->pdata = zalloc(backend->sizeof_context_pdata); -+ if (!ctx->pdata) -+ goto err_free_ctx; -+ } -+ -+ if (description) { -+ ctx->description = iio_strdup(description); -+ if (!ctx->description) -+ goto err_free_pdata; -+ } -+ -+ ctx->name = backend->name; -+ ctx->ops = backend->ops; -+ -+ return ctx; -+ -+err_free_pdata: -+ if (ctx->pdata) -+ free(ctx->pdata); -+err_free_ctx: -+ free(ctx); -+ errno = -ret; -+ return NULL; -+} -+ - const char * iio_context_get_xml(const struct iio_context *ctx) - { - return ctx->xml; -diff --git a/iio-backend.h b/iio-backend.h -index a32a35a..4b11ab6 100644 ---- a/iio-backend.h -+++ b/iio-backend.h -@@ -23,6 +23,10 @@ - struct iio_device; - struct iio_context; - -+enum iio_backend_api_ver { -+ IIO_BACKEND_API_V1 = 1, -+}; -+ - enum iio_attr_type { - IIO_ATTR_TYPE_DEVICE = 0, - IIO_ATTR_TYPE_DEBUG, -@@ -72,4 +76,24 @@ struct iio_backend_ops { - int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); - }; - -+/** -+ * struct iio_backend - IIO backend object (API version 1) -+ * @api_version API version for interfacing with libiio core library -+ * @name Name of this backend -+ * @uri_prefix URI prefix for this backend -+ * @ops Reference to backend ops -+ * @sizeof_context_pdata Size of private data for the IIO contexts generated by this backend -+ */ -+struct iio_backend { -+ unsigned int api_version; -+ const char *name; -+ const char *uri_prefix; -+ const struct iio_backend_ops *ops; -+ unsigned int sizeof_context_pdata; -+}; -+ -+__api struct iio_context * iio_context_create_from_backend( -+ const struct iio_backend *backend, -+ const char *description); -+ - #endif /* __IIO_BACKEND_H__ */ -diff --git a/local.c b/local.c -index ab49607..6d4d84e 100644 ---- a/local.c -+++ b/local.c -@@ -1948,6 +1948,14 @@ static const struct iio_backend_ops local_ops = { - .cancel = local_cancel, - }; - -+static const struct iio_backend local_backend = { -+ .api_version = IIO_BACKEND_API_V1, -+ .name = "local", -+ .uri_prefix = "local:", -+ .ops = &local_ops, -+ .sizeof_context_pdata = sizeof(struct iio_context_pdata), -+}; -+ - static void init_data_scale(struct iio_channel *chn) - { - char *end, buf[1024]; -@@ -2038,37 +2046,29 @@ out_close_ini: - - struct iio_context * local_create_context(void) - { -+ struct iio_context *ctx; -+ char *description; - int ret = -ENOMEM; - unsigned int len; - struct utsname uts; -- struct iio_context *ctx = zalloc(sizeof(*ctx)); -- if (!ctx) -- goto err_set_errno; -- -- ctx->ops = &local_ops; -- ctx->name = "local"; -- -- ctx->pdata = zalloc(sizeof(*ctx->pdata)); -- if (!ctx->pdata) { -- free(ctx); -- goto err_set_errno; -- } -- -- local_set_timeout(ctx, DEFAULT_TIMEOUT_MS); - - uname(&uts); - len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release) - + strlen(uts.version) + strlen(uts.machine); -- ctx->description = malloc(len + 5); /* 4 spaces + EOF */ -- if (!ctx->description) { -- free(ctx->pdata); -- free(ctx); -+ description = malloc(len + 5); /* 4 spaces + EOF */ -+ if (!description) - goto err_set_errno; -- } - -- iio_snprintf(ctx->description, len + 5, "%s %s %s %s %s", uts.sysname, -+ iio_snprintf(description, len + 5, "%s %s %s %s %s", uts.sysname, - uts.nodename, uts.release, uts.version, uts.machine); - -+ ctx = iio_context_create_from_backend(&local_backend, description); -+ free(description); -+ if (!ctx) -+ goto err_set_errno; -+ -+ local_set_timeout(ctx, DEFAULT_TIMEOUT_MS); -+ - ret = foreach_in_dir(ctx, "/sys/bus/iio/devices", true, create_device); - if (ret < 0) - goto err_context_destroy; -diff --git a/xml.c b/xml.c -index 73ff988..434a482 100644 ---- a/xml.c -+++ b/xml.c -@@ -352,6 +352,13 @@ static const struct iio_backend_ops xml_ops = { - .clone = xml_clone, - }; - -+static const struct iio_backend xml_backend = { -+ .api_version = IIO_BACKEND_API_V1, -+ .name = "xml", -+ .uri_prefix = "xml:", -+ .ops = &xml_ops, -+}; -+ - static int parse_context_attr(struct iio_context *ctx, xmlNode *n) - { - xmlAttr *attr; -@@ -376,29 +383,28 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - xmlNode *root, *n; - xmlAttr *attr; - int err = -ENOMEM; -- struct iio_context *ctx = zalloc(sizeof(*ctx)); -- if (!ctx) -- goto err_set_errno; -- -- ctx->name = "xml"; -- ctx->ops = &xml_ops; -+ struct iio_context *ctx; -+ const char *description = NULL; - - root = xmlDocGetRootElement(doc); - if (strcmp((char *) root->name, "context")) { - IIO_ERROR("Unrecognized XML file\n"); - err = -EINVAL; -- goto err_context_destroy; -+ goto err_set_errno; - } - - for (attr = root->properties; attr; attr = attr->next) { - if (!strcmp((char *) attr->name, "description")) -- ctx->description = iio_strdup( -- (char *) attr->children->content); -+ description = (const char *)attr->children->content; - else if (strcmp((char *) attr->name, "name")) - IIO_WARNING("Unknown parameter \'%s\' in \n", - (char *) attr->children->content); - } - -+ ctx = iio_context_create_from_backend(&xml_backend, description); -+ if (!ctx) -+ goto err_set_errno; -+ - for (n = root->children; n; n = n->next) { - struct iio_device *dev; - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0035-iio-centralize-context-pdata-free-in-iio_context_des.patch libiio-0.23/debian/patches/0035-iio-centralize-context-pdata-free-in-iio_context_des.patch --- libiio-0.21/debian/patches/0035-iio-centralize-context-pdata-free-in-iio_context_des.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0035-iio-centralize-context-pdata-free-in-iio_context_des.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -From 08f46e5f1c7bdab122fdd4ac9abbbe8819d84846 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 12 Oct 2020 10:55:01 +0300 -Subject: [PATCH 35/53] iio: centralize context pdata free in - iio_context_destroy() - -iio_context_destroy() calls the 'shutdown' hook/op. This free's the context -private data at the end. - -This can be done also in iio_context_destroy(), since it's just a pointer -free. Also, since the context private data allocation is being moved in the -context.c file, it makes more sense to have it there. - -This minimizes open-coding, and some duplication. - -Signed-off-by: Alexandru Ardelean ---- - context.c | 2 ++ - local.c | 2 -- - network.c | 1 - - serial.c | 2 -- - usb.c | 1 - - 5 files changed, 2 insertions(+), 6 deletions(-) - -diff --git a/context.c b/context.c -index 7e121cc..afb9af3 100644 ---- a/context.c -+++ b/context.c -@@ -267,6 +267,8 @@ void iio_context_destroy(struct iio_context *ctx) - free(ctx->xml); - if (ctx->description) - free(ctx->description); -+ if (ctx->pdata) -+ free(ctx->pdata); - free(ctx); - } - -diff --git a/local.c b/local.c -index 6d4d84e..f4b3fd4 100644 ---- a/local.c -+++ b/local.c -@@ -162,8 +162,6 @@ static void local_shutdown(struct iio_context *ctx) - iio_device_close(dev); - local_free_pdata(dev); - } -- -- free(ctx->pdata); - } - - /** Shrinks the first nb characters of a string -diff --git a/network.c b/network.c -index 309b033..8278448 100644 ---- a/network.c -+++ b/network.c -@@ -1148,7 +1148,6 @@ static void network_shutdown(struct iio_context *ctx) - - iiod_client_destroy(pdata->iiod_client); - freeaddrinfo(pdata->addrinfo); -- free(pdata); - } - - static int network_get_version(const struct iio_context *ctx, -diff --git a/serial.c b/serial.c -index 77a02c1..b77ca09 100644 ---- a/serial.c -+++ b/serial.c -@@ -325,8 +325,6 @@ static void serial_shutdown(struct iio_context *ctx) - - free(pdata); - } -- -- free(ctx_pdata); - } - - static int serial_set_timeout(struct iio_context *ctx, unsigned int timeout) -diff --git a/usb.c b/usb.c -index f2b8442..ac002e5 100644 ---- a/usb.c -+++ b/usb.c -@@ -475,7 +475,6 @@ static void usb_shutdown(struct iio_context *ctx) - - libusb_close(ctx->pdata->hdl); - libusb_exit(ctx->pdata->ctx); -- free(ctx->pdata); - } - - static int iio_usb_match_interface(const struct libusb_config_descriptor *desc, --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0036-xml-split-iio_populate_xml_context_helper-from-creat.patch libiio-0.23/debian/patches/0036-xml-split-iio_populate_xml_context_helper-from-creat.patch --- libiio-0.21/debian/patches/0036-xml-split-iio_populate_xml_context_helper-from-creat.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0036-xml-split-iio_populate_xml_context_helper-from-creat.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -From 481437d93d0c05b94cd69bee5a5aa53701cfe9bd Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 12 Oct 2020 14:21:06 +0300 -Subject: [PATCH 36/53] xml: split iio_populate_xml_context_helper() from - create helper - -The iio_create_xml_context_helper() function is used in the manner that it -allocates an IIO context, then the network,serial & usb backends override -the name, description & pdata. - -This design is not ideal: -1. The description is overridden by each backend; this requires that each -backend free the previous description string, in order to not leak memory. -The logic in network.c seems a bit too complicated (for handling the -ctx->description, and serial.c forgets to free the description allocated by -this helper). -2. Similar, each backend needs to allocate it's own pdata. We can abstract -this away so that the 'sizeof_context_pdata' is used so that a memory block -is allocated and returned back to the backend. The alloc & free of the -memory block can be handled by iio_context_destroy() - -Signed-off-by: Alexandru Ardelean ---- - xml.c | 74 +++++++++++++++++++++++++++++++++-------------------------- - 1 file changed, 42 insertions(+), 32 deletions(-) - -diff --git a/xml.c b/xml.c -index 434a482..996e44b 100644 ---- a/xml.c -+++ b/xml.c -@@ -378,32 +378,10 @@ static int parse_context_attr(struct iio_context *ctx, xmlNode *n) - return iio_context_add_attr(ctx, name, value); - } - --static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) -+static int iio_populate_xml_context_helper(struct iio_context *ctx, xmlNode *root) - { -- xmlNode *root, *n; -- xmlAttr *attr; -+ xmlNode *n; - int err = -ENOMEM; -- struct iio_context *ctx; -- const char *description = NULL; -- -- root = xmlDocGetRootElement(doc); -- if (strcmp((char *) root->name, "context")) { -- IIO_ERROR("Unrecognized XML file\n"); -- err = -EINVAL; -- goto err_set_errno; -- } -- -- for (attr = root->properties; attr; attr = attr->next) { -- if (!strcmp((char *) attr->name, "description")) -- description = (const char *)attr->children->content; -- else if (strcmp((char *) attr->name, "name")) -- IIO_WARNING("Unknown parameter \'%s\' in \n", -- (char *) attr->children->content); -- } -- -- ctx = iio_context_create_from_backend(&xml_backend, description); -- if (!ctx) -- goto err_set_errno; - - for (n = root->children; n; n = n->next) { - struct iio_device *dev; -@@ -411,7 +389,7 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - if (!strcmp((char *) n->name, "context-attribute")) { - err = parse_context_attr(ctx, n); - if (err) -- goto err_context_destroy; -+ goto err_set_errno; - else - continue; - } else if (strcmp((char *) n->name, "device")) { -@@ -424,27 +402,59 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) - dev = create_device(ctx, n); - if (!dev) { - IIO_ERROR("Unable to create device\n"); -- goto err_context_destroy; -+ goto err_set_errno; - } - - err = iio_context_add_device(ctx, dev); - if (err) { - free(dev); -- goto err_context_destroy; -+ goto err_set_errno; - } - } - - err = iio_context_init(ctx); - if (err) -- goto err_context_destroy; -+ goto err_set_errno; - -- return ctx; -+ return 0; - --err_context_destroy: -- iio_context_destroy(ctx); - err_set_errno: - errno = -err; -- return NULL; -+ return err; -+} -+ -+static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) -+{ -+ const char *description = NULL; -+ struct iio_context *ctx; -+ xmlNode *root; -+ xmlAttr *attr; -+ -+ root = xmlDocGetRootElement(doc); -+ if (strcmp((char *) root->name, "context")) { -+ IIO_ERROR("Unrecognized XML file\n"); -+ errno = EINVAL; -+ return NULL; -+ } -+ -+ for (attr = root->properties; attr; attr = attr->next) { -+ if (!strcmp((char *) attr->name, "description")) -+ description = (const char *)attr->children->content; -+ else if (strcmp((char *) attr->name, "name")) -+ IIO_WARNING("Unknown parameter \'%s\' in \n", -+ (char *) attr->children->content); -+ } -+ -+ ctx = iio_context_create_from_backend(&xml_backend, description); -+ if (!ctx) -+ return NULL; -+ -+ if (iio_populate_xml_context_helper(ctx, root)) { -+ iio_context_destroy(ctx); -+ return NULL; -+ } -+ -+ return ctx; - } - - struct iio_context * xml_create_context(const char *xml_file) --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0037-iio-add-iio_context_get_pdata-accessor.patch libiio-0.23/debian/patches/0037-iio-add-iio_context_get_pdata-accessor.patch --- libiio-0.21/debian/patches/0037-iio-add-iio_context_get_pdata-accessor.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0037-iio-add-iio_context_get_pdata-accessor.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -From 5701d04727ee8eee28043672c3c58115c2ff5bfd Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 12 Oct 2020 11:07:21 +0300 -Subject: [PATCH 37/53] iio: add iio_context_get_pdata() accessor - -This adds a iio_context_get_pdata() accessor to retrieve the private -information of an IIO context object, to better hide it from IIO backends. - -Signed-off-by: Alexandru Ardelean ---- - context.c | 5 +++++ - iio-private.h | 2 ++ - 2 files changed, 7 insertions(+) - -diff --git a/context.c b/context.c -index afb9af3..48072f3 100644 ---- a/context.c -+++ b/context.c -@@ -227,6 +227,11 @@ err_free_ctx: - return NULL; - } - -+struct iio_context_pdata * iio_context_get_pdata(const struct iio_context *ctx) -+{ -+ return ctx->pdata; -+} -+ - const char * iio_context_get_xml(const struct iio_context *ctx) - { - return ctx->xml; -diff --git a/iio-private.h b/iio-private.h -index 1a21ca9..f3bdbff 100644 ---- a/iio-private.h -+++ b/iio-private.h -@@ -273,6 +273,8 @@ int iio_context_add_device(struct iio_context *ctx, struct iio_device *dev); - int iio_context_add_attr(struct iio_context *ctx, - const char *key, const char *value); - -+struct iio_context_pdata * iio_context_get_pdata(const struct iio_context *ctx); -+ - #undef __api - - #endif /* __IIO_PRIVATE_H__ */ --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0038-usb-make-use-of-the-iio_context_pdata-helper.patch libiio-0.23/debian/patches/0038-usb-make-use-of-the-iio_context_pdata-helper.patch --- libiio-0.21/debian/patches/0038-usb-make-use-of-the-iio_context_pdata-helper.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0038-usb-make-use-of-the-iio_context_pdata-helper.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -From c846dbcecfd0761c574da64500483a905b122f8f Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 16:41:42 +0300 -Subject: [PATCH 38/53] usb: make use of the iio_context_pdata() helper - -This tries to most of the access to the pdata pointer of the IIO context. - -Signed-off-by: Alexandru Ardelean ---- - usb.c | 62 ++++++++++++++++++++++++++++++++--------------------------- - 1 file changed, 34 insertions(+), 28 deletions(-) - -diff --git a/usb.c b/usb.c -index ac002e5..3b64f1b 100644 ---- a/usb.c -+++ b/usb.c -@@ -136,8 +136,10 @@ static void usb_io_context_exit(struct iio_usb_io_context *io_ctx) - static int usb_get_version(const struct iio_context *ctx, - unsigned int *major, unsigned int *minor, char git_tag[8]) - { -- return iiod_client_get_version(ctx->pdata->iiod_client, -- &ctx->pdata->io_ctx, major, minor, git_tag); -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ return iiod_client_get_version(pdata->iiod_client, -+ &pdata->io_ctx, major, minor, git_tag); - } - - static unsigned int usb_calculate_remote_timeout(unsigned int timeout) -@@ -220,7 +222,7 @@ static int usb_close_pipe(struct iio_context_pdata *pdata, uint16_t pipe_id) - - static int usb_reserve_ep_unlocked(const struct iio_device *dev) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - unsigned int i; - - for (i = 0; i < pdata->nb_ep_couples; i++) { -@@ -240,7 +242,7 @@ static int usb_reserve_ep_unlocked(const struct iio_device *dev) - - static void usb_free_ep_unlocked(const struct iio_device *dev) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - unsigned int i; - - for (i = 0; i < pdata->nb_ep_couples; i++) { -@@ -256,7 +258,7 @@ static void usb_free_ep_unlocked(const struct iio_device *dev) - static int usb_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -- struct iio_context_pdata *ctx_pdata = dev->ctx->pdata; -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBUSY; - -@@ -310,7 +312,7 @@ out_unlock: - - static int usb_close(const struct iio_device *dev) - { -- struct iio_context_pdata *ctx_pdata = dev->ctx->pdata; -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBADF; - -@@ -337,11 +339,12 @@ out_unlock: - static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words) - { -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - ssize_t ret; - - iio_mutex_lock(pdata->lock); -- ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client, -+ ret = iiod_client_read_unlocked(ctx_pdata->iiod_client, - &pdata->io_ctx, dev, dst, len, mask, words); - iio_mutex_unlock(pdata->lock); - -@@ -351,11 +354,12 @@ static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len, - static ssize_t usb_write(const struct iio_device *dev, - const void *src, size_t len) - { -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - ssize_t ret; - - iio_mutex_lock(pdata->lock); -- ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client, -+ ret = iiod_client_write_unlocked(ctx_pdata->iiod_client, - &pdata->io_ctx, dev, src, len); - iio_mutex_unlock(pdata->lock); - -@@ -365,7 +369,7 @@ static ssize_t usb_write(const struct iio_device *dev, - static ssize_t usb_read_dev_attr(const struct iio_device *dev, - const char *attr, char *dst, size_t len, enum iio_attr_type type) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_read_attr(pdata->iiod_client, - &pdata->io_ctx, dev, NULL, attr, -@@ -375,7 +379,7 @@ static ssize_t usb_read_dev_attr(const struct iio_device *dev, - static ssize_t usb_write_dev_attr(const struct iio_device *dev, - const char *attr, const char *src, size_t len, enum iio_attr_type type) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_write_attr(pdata->iiod_client, - &pdata->io_ctx, dev, NULL, attr, -@@ -385,7 +389,7 @@ static ssize_t usb_write_dev_attr(const struct iio_device *dev, - static ssize_t usb_read_chn_attr(const struct iio_channel *chn, - const char *attr, char *dst, size_t len) - { -- struct iio_context_pdata *pdata = chn->dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); - - return iiod_client_read_attr(pdata->iiod_client, - &pdata->io_ctx, chn->dev, chn, attr, -@@ -395,7 +399,7 @@ static ssize_t usb_read_chn_attr(const struct iio_channel *chn, - static ssize_t usb_write_chn_attr(const struct iio_channel *chn, - const char *attr, const char *src, size_t len) - { -- struct iio_context_pdata *pdata = chn->dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); - - return iiod_client_write_attr(pdata->iiod_client, - &pdata->io_ctx, chn->dev, chn, attr, -@@ -405,7 +409,7 @@ static ssize_t usb_write_chn_attr(const struct iio_channel *chn, - static int usb_set_kernel_buffers_count(const struct iio_device *dev, - unsigned int nb_blocks) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_set_kernel_buffers_count(pdata->iiod_client, - &pdata->io_ctx, dev, nb_blocks); -@@ -413,7 +417,7 @@ static int usb_set_kernel_buffers_count(const struct iio_device *dev, - - static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout) - { -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - unsigned int remote_timeout = usb_calculate_remote_timeout(timeout); - int ret; - -@@ -428,7 +432,7 @@ static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout) - static int usb_get_trigger(const struct iio_device *dev, - const struct iio_device **trigger) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_get_trigger(pdata->iiod_client, - &pdata->io_ctx, dev, trigger); -@@ -437,7 +441,7 @@ static int usb_get_trigger(const struct iio_device *dev, - static int usb_set_trigger(const struct iio_device *dev, - const struct iio_device *trigger) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_set_trigger(pdata->iiod_client, - &pdata->io_ctx, dev, trigger); -@@ -446,21 +450,22 @@ static int usb_set_trigger(const struct iio_device *dev, - - static void usb_shutdown(struct iio_context *ctx) - { -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - unsigned int nb_devices = iio_context_get_devices_count(ctx); - unsigned int i; - -- usb_io_context_exit(&ctx->pdata->io_ctx); -+ usb_io_context_exit(&pdata->io_ctx); - - for (i = 0; i < nb_devices; i++) - usb_close(iio_context_get_device(ctx, i)); - -- iio_mutex_destroy(ctx->pdata->ep_lock); -+ iio_mutex_destroy(pdata->ep_lock); - -- for (i = 0; i < ctx->pdata->nb_ep_couples; i++) -- if (ctx->pdata->io_endpoints[i].lock) -- iio_mutex_destroy(ctx->pdata->io_endpoints[i].lock); -- if (ctx->pdata->io_endpoints) -- free(ctx->pdata->io_endpoints); -+ for (i = 0; i < pdata->nb_ep_couples; i++) -+ if (pdata->io_endpoints[i].lock) -+ iio_mutex_destroy(pdata->io_endpoints[i].lock); -+ if (pdata->io_endpoints) -+ free(pdata->io_endpoints); - - for (i = 0; i < nb_devices; i++) { - struct iio_device *dev = iio_context_get_device(ctx, i); -@@ -469,12 +474,12 @@ static void usb_shutdown(struct iio_context *ctx) - free(dev->pdata); - } - -- iiod_client_destroy(ctx->pdata->iiod_client); -+ iiod_client_destroy(pdata->iiod_client); - -- usb_reset_pipes(ctx->pdata); /* Close everything */ -+ usb_reset_pipes(pdata); /* Close everything */ - -- libusb_close(ctx->pdata->hdl); -- libusb_exit(ctx->pdata->ctx); -+ libusb_close(pdata->hdl); -+ libusb_exit(pdata->ctx); - } - - static int iio_usb_match_interface(const struct libusb_config_descriptor *desc, -@@ -736,6 +741,7 @@ static int usb_verify_eps(const struct libusb_interface_descriptor *iface) - static int usb_populate_context_attrs(struct iio_context *ctx, - libusb_device *dev, libusb_device_handle *hdl) - { -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - struct libusb_device_descriptor dev_desc; - char buffer[64]; - unsigned int i; -@@ -758,7 +764,7 @@ static int usb_populate_context_attrs(struct iio_context *ctx, - - iio_snprintf(uri, sizeof(uri), "usb:%d.%d.%u", - libusb_get_bus_number(dev), libusb_get_device_address(dev), -- (uint8_t)ctx->pdata->intrfc); -+ (uint8_t)pdata->intrfc); - ret = iio_context_add_attr(ctx, "uri", uri); - if (ret < 0) - return ret; --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0039-network-make-use-of-the-iio_context_pdata-helper.patch libiio-0.23/debian/patches/0039-network-make-use-of-the-iio_context_pdata-helper.patch --- libiio-0.21/debian/patches/0039-network-make-use-of-the-iio_context_pdata-helper.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0039-network-make-use-of-the-iio_context_pdata-helper.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -From fddd578d2134cc577c50412f06184a4c7b4295a6 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 16:47:58 +0300 -Subject: [PATCH 39/53] network: make use of the iio_context_pdata() helper - -This tries to most of the access to the pdata pointer of the IIO context. - -Signed-off-by: Alexandru Ardelean ---- - network.c | 35 ++++++++++++++++++++--------------- - 1 file changed, 20 insertions(+), 15 deletions(-) - -diff --git a/network.c b/network.c -index 8278448..401e940 100644 ---- a/network.c -+++ b/network.c -@@ -641,7 +641,7 @@ static char * network_get_description(struct addrinfo *res, size_t *len) - static int network_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *ppdata = dev->pdata; - int ret = -EBUSY; - -@@ -696,6 +696,7 @@ out_mutex_unlock: - - static int network_close(const struct iio_device *dev) - { -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBADF; - -@@ -704,7 +705,7 @@ static int network_close(const struct iio_device *dev) - if (pdata->io_ctx.fd >= 0) { - if (!pdata->io_ctx.cancelled) { - ret = iiod_client_close_unlocked( -- dev->ctx->pdata->iiod_client, -+ ctx_pdata->iiod_client, - &pdata->io_ctx, dev); - - write_command(&pdata->io_ctx, "\r\nEXIT\r\n"); -@@ -735,11 +736,12 @@ static int network_close(const struct iio_device *dev) - static ssize_t network_read(const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words) - { -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - ssize_t ret; - - iio_mutex_lock(pdata->lock); -- ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client, -+ ret = iiod_client_read_unlocked(ctx_pdata->iiod_client, - &pdata->io_ctx, dev, dst, len, mask, words); - iio_mutex_unlock(pdata->lock); - -@@ -749,11 +751,12 @@ static ssize_t network_read(const struct iio_device *dev, void *dst, size_t len, - static ssize_t network_write(const struct iio_device *dev, - const void *src, size_t len) - { -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); - struct iio_device_pdata *pdata = dev->pdata; - ssize_t ret; - - iio_mutex_lock(pdata->lock); -- ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client, -+ ret = iiod_client_write_unlocked(ctx_pdata->iiod_client, - &pdata->io_ctx, dev, src, len); - iio_mutex_unlock(pdata->lock); - -@@ -1074,7 +1077,7 @@ err_unlock: - static ssize_t network_read_dev_attr(const struct iio_device *dev, - const char *attr, char *dst, size_t len, enum iio_attr_type type) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_read_attr(pdata->iiod_client, - &pdata->io_ctx, dev, NULL, attr, dst, len, type); -@@ -1083,7 +1086,7 @@ static ssize_t network_read_dev_attr(const struct iio_device *dev, - static ssize_t network_write_dev_attr(const struct iio_device *dev, - const char *attr, const char *src, size_t len, enum iio_attr_type type) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_write_attr(pdata->iiod_client, - &pdata->io_ctx, dev, NULL, attr, src, len, type); -@@ -1092,7 +1095,7 @@ static ssize_t network_write_dev_attr(const struct iio_device *dev, - static ssize_t network_read_chn_attr(const struct iio_channel *chn, - const char *attr, char *dst, size_t len) - { -- struct iio_context_pdata *pdata = chn->dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); - - return iiod_client_read_attr(pdata->iiod_client, - &pdata->io_ctx, chn->dev, chn, attr, dst, len, false); -@@ -1101,7 +1104,7 @@ static ssize_t network_read_chn_attr(const struct iio_channel *chn, - static ssize_t network_write_chn_attr(const struct iio_channel *chn, - const char *attr, const char *src, size_t len) - { -- struct iio_context_pdata *pdata = chn->dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); - - return iiod_client_write_attr(pdata->iiod_client, - &pdata->io_ctx, chn->dev, chn, attr, src, len, false); -@@ -1110,7 +1113,7 @@ static ssize_t network_write_chn_attr(const struct iio_channel *chn, - static int network_get_trigger(const struct iio_device *dev, - const struct iio_device **trigger) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_get_trigger(pdata->iiod_client, - &pdata->io_ctx, dev, trigger); -@@ -1119,7 +1122,7 @@ static int network_get_trigger(const struct iio_device *dev, - static int network_set_trigger(const struct iio_device *dev, - const struct iio_device *trigger) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_set_trigger(pdata->iiod_client, - &pdata->io_ctx, dev, trigger); -@@ -1127,7 +1130,7 @@ static int network_set_trigger(const struct iio_device *dev, - - static void network_shutdown(struct iio_context *ctx) - { -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - unsigned int i; - - iiod_client_mutex_lock(pdata->iiod_client); -@@ -1153,8 +1156,10 @@ static void network_shutdown(struct iio_context *ctx) - static int network_get_version(const struct iio_context *ctx, - unsigned int *major, unsigned int *minor, char git_tag[8]) - { -- return iiod_client_get_version(ctx->pdata->iiod_client, -- &ctx->pdata->io_ctx, major, minor, git_tag); -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ return iiod_client_get_version(pdata->iiod_client, -+ &pdata->io_ctx, major, minor, git_tag); - } - - static unsigned int calculate_remote_timeout(unsigned int timeout) -@@ -1166,7 +1171,7 @@ static unsigned int calculate_remote_timeout(unsigned int timeout) - - static int network_set_timeout(struct iio_context *ctx, unsigned int timeout) - { -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - int ret, fd = pdata->io_ctx.fd; - - ret = set_socket_timeout(fd, timeout); -@@ -1189,7 +1194,7 @@ static int network_set_timeout(struct iio_context *ctx, unsigned int timeout) - static int network_set_kernel_buffers_count(const struct iio_device *dev, - unsigned int nb_blocks) - { -- struct iio_context_pdata *pdata = dev->ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); - - return iiod_client_set_kernel_buffers_count(pdata->iiod_client, - &pdata->io_ctx, dev, nb_blocks); --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0040-serial-make-use-of-the-iio_context_pdata-helper.patch libiio-0.23/debian/patches/0040-serial-make-use-of-the-iio_context_pdata-helper.patch --- libiio-0.21/debian/patches/0040-serial-make-use-of-the-iio_context_pdata-helper.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0040-serial-make-use-of-the-iio_context_pdata-helper.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -From 38f1eadd65f0ff1073a6b029ae487c5335b102a8 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 16:51:28 +0300 -Subject: [PATCH 40/53] serial: make use of the iio_context_pdata() helper - -This tries to most of the access to the pdata pointer of the IIO context. - -Signed-off-by: Alexandru Ardelean ---- - serial.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/serial.c b/serial.c -index b77ca09..724ec90 100644 ---- a/serial.c -+++ b/serial.c -@@ -109,7 +109,7 @@ static inline int libserialport_to_errno(enum sp_return ret) - static int serial_get_version(const struct iio_context *ctx, - unsigned int *major, unsigned int *minor, char git_tag[8]) - { -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_get_version(pdata->iiod_client, NULL, - major, minor, git_tag); -@@ -139,7 +139,7 @@ static int serial_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *ctx_pdata = ctx->pdata; -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBUSY; - -@@ -160,7 +160,7 @@ out_unlock: - static int serial_close(const struct iio_device *dev) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *ctx_pdata = ctx->pdata; -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); - struct iio_device_pdata *pdata = dev->pdata; - int ret = -EBADF; - -@@ -180,7 +180,7 @@ static ssize_t serial_read(const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - ssize_t ret; - - iiod_client_mutex_lock(pdata->iiod_client); -@@ -195,7 +195,7 @@ static ssize_t serial_write(const struct iio_device *dev, - const void *src, size_t len) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - ssize_t ret; - - iiod_client_mutex_lock(pdata->iiod_client); -@@ -209,7 +209,7 @@ static ssize_t serial_read_dev_attr(const struct iio_device *dev, - const char *attr, char *dst, size_t len, enum iio_attr_type type) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_read_attr(pdata->iiod_client, NULL, - dev, NULL, attr, dst, len, type); -@@ -219,7 +219,7 @@ static ssize_t serial_write_dev_attr(const struct iio_device *dev, - const char *attr, const char *src, size_t len, enum iio_attr_type type) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_write_attr(pdata->iiod_client, NULL, - dev, NULL, attr, src, len, type); -@@ -230,7 +230,7 @@ static ssize_t serial_read_chn_attr(const struct iio_channel *chn, - { - const struct iio_device *dev = iio_channel_get_device(chn); - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_read_attr(pdata->iiod_client, NULL, - chn->dev, chn, attr, dst, len, false); -@@ -241,7 +241,7 @@ static ssize_t serial_write_chn_attr(const struct iio_channel *chn, - { - const struct iio_device *dev = iio_channel_get_device(chn); - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_write_attr(pdata->iiod_client, NULL, - dev, chn, attr, src, len, false); -@@ -251,7 +251,7 @@ static int serial_set_kernel_buffers_count(const struct iio_device *dev, - unsigned int nb_blocks) - { - const struct iio_context *ctx = iio_device_get_context(dev); -- struct iio_context_pdata *pdata = ctx->pdata; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); - - return iiod_client_set_kernel_buffers_count(pdata->iiod_client, NULL, - dev, nb_blocks); -@@ -312,7 +312,7 @@ static ssize_t serial_read_line(struct iio_context_pdata *pdata, - - static void serial_shutdown(struct iio_context *ctx) - { -- struct iio_context_pdata *ctx_pdata = ctx->pdata; -+ struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); - unsigned int i; - - iiod_client_destroy(ctx_pdata->iiod_client); -@@ -329,7 +329,9 @@ static void serial_shutdown(struct iio_context *ctx) - - static int serial_set_timeout(struct iio_context *ctx, unsigned int timeout) - { -- ctx->pdata->timeout_ms = timeout; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ pdata->timeout_ms = timeout; - return 0; - } - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0041-local-make-use-of-the-iio_context_pdata-helper.patch libiio-0.23/debian/patches/0041-local-make-use-of-the-iio_context_pdata-helper.patch --- libiio-0.21/debian/patches/0041-local-make-use-of-the-iio_context_pdata-helper.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0041-local-make-use-of-the-iio_context_pdata-helper.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -From 5648215ec317c28e0a7d79fbdd3e56264a95a96c Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 16:56:58 +0300 -Subject: [PATCH 41/53] local: make use of the iio_context_pdata() helper - -The local backend does a minimal use of it's backend. Mostly some timeout -handling. This change replaces the access of the context's pdata via -iio_context_pdata(). - -Signed-off-by: Alexandru Ardelean ---- - local.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/local.c b/local.c -index f4b3fd4..71baf04 100644 ---- a/local.c -+++ b/local.c -@@ -286,7 +286,8 @@ static int device_check_ready(const struct iio_device *dev, short events, - .events = POLLIN, - } - }; -- unsigned int rw_timeout_ms = dev->ctx->pdata->rw_timeout_ms; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); -+ unsigned int rw_timeout_ms = pdata->rw_timeout_ms; - int timeout_rel; - int ret; - -@@ -1900,7 +1901,9 @@ static int add_debug(void *d, const char *path) - - static int local_set_timeout(struct iio_context *ctx, unsigned int timeout) - { -- ctx->pdata->rw_timeout_ms = timeout; -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ pdata->rw_timeout_ms = timeout; - return 0; - } - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0042-iio-backend-add-get_description-backend-op.patch libiio-0.23/debian/patches/0042-iio-backend-add-get_description-backend-op.patch --- libiio-0.21/debian/patches/0042-iio-backend-add-get_description-backend-op.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0042-iio-backend-add-get_description-backend-op.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -From d61f62962fd0c5c05693cb8c06bfcf7f67f601fd Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 10:52:02 +0300 -Subject: [PATCH 42/53] iio: backend: add get_description() backend op - -This doesn't get rid of the 'ctx->description' object; that will still be -around and cache the description. - -The get_description() splits the creation logic of the description into a -backend op. That way, we can think of splitting the creation of an IIO -context into an 'alloc()' and 'init()' part where: -* an IIO context is allocated first in libiio core -* it's backend init() routine is called -* it's backend get_description() routine is called - -The idea of the 'get_description()' op is to return a pointer, that libiio -core will manage/free. Hence the return is 'char *' vs 'const char *'. - -Signed-off-by: Alexandru Ardelean ---- - iio-backend.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/iio-backend.h b/iio-backend.h -index 4b11ab6..217c702 100644 ---- a/iio-backend.h -+++ b/iio-backend.h -@@ -70,6 +70,8 @@ struct iio_backend_ops { - - void (*shutdown)(struct iio_context *ctx); - -+ char * (*get_description)(const struct iio_context *ctx); -+ - int (*get_version)(const struct iio_context *ctx, unsigned int *major, - unsigned int *minor, char git_tag[8]); - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0043-local-split-get_description-logic-into-function-and-.patch libiio-0.23/debian/patches/0043-local-split-get_description-logic-into-function-and-.patch --- libiio-0.21/debian/patches/0043-local-split-get_description-logic-into-function-and-.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0043-local-split-get_description-logic-into-function-and-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -From e236e465c5c86d70ffc09f7a61c8749ef3d8bdec Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 11:01:46 +0300 -Subject: [PATCH 43/53] local: split get_description() logic into function and - hook it to backend - -This change splits the creation of the description into it's own function -and hooks into the get_description backend op. - -Signed-off-by: Alexandru Ardelean ---- - local.c | 32 ++++++++++++++++++++++---------- - 1 file changed, 22 insertions(+), 10 deletions(-) - -diff --git a/local.c b/local.c -index 71baf04..f47f942 100644 ---- a/local.c -+++ b/local.c -@@ -1928,6 +1928,25 @@ static struct iio_context * local_clone( - return local_create_context(); - } - -+static char * local_get_description(const struct iio_context *ctx) -+{ -+ char *description; -+ unsigned int len; -+ struct utsname uts; -+ -+ uname(&uts); -+ len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release) -+ + strlen(uts.version) + strlen(uts.machine); -+ description = malloc(len + 5); /* 4 spaces + EOF */ -+ if (!description) -+ return NULL; -+ -+ iio_snprintf(description, len + 5, "%s %s %s %s %s", uts.sysname, -+ uts.nodename, uts.release, uts.version, uts.machine); -+ -+ return description; -+} -+ - static const struct iio_backend_ops local_ops = { - .clone = local_clone, - .open = local_open, -@@ -1945,6 +1964,7 @@ static const struct iio_backend_ops local_ops = { - .get_trigger = local_get_trigger, - .set_trigger = local_set_trigger, - .shutdown = local_shutdown, -+ .get_description = local_get_description, - .set_timeout = local_set_timeout, - .cancel = local_cancel, - }; -@@ -2050,18 +2070,9 @@ struct iio_context * local_create_context(void) - struct iio_context *ctx; - char *description; - int ret = -ENOMEM; -- unsigned int len; - struct utsname uts; - -- uname(&uts); -- len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release) -- + strlen(uts.version) + strlen(uts.machine); -- description = malloc(len + 5); /* 4 spaces + EOF */ -- if (!description) -- goto err_set_errno; -- -- iio_snprintf(description, len + 5, "%s %s %s %s %s", uts.sysname, -- uts.nodename, uts.release, uts.version, uts.machine); -+ description = local_get_description(NULL); - - ctx = iio_context_create_from_backend(&local_backend, description); - free(description); -@@ -2087,6 +2098,7 @@ struct iio_context * local_create_context(void) - goto err_context_destroy; - #endif - -+ uname(&uts); - ret = iio_context_add_attr(ctx, "local,kernel", uts.release); - if (ret < 0) - goto err_context_destroy; --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0044-network-hook-network_get_description-routine-to-back.patch libiio-0.23/debian/patches/0044-network-hook-network_get_description-routine-to-back.patch --- libiio-0.21/debian/patches/0044-network-hook-network_get_description-routine-to-back.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0044-network-hook-network_get_description-routine-to-back.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -From 134567b779c0726257eebee5dae5a284e5707625 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 14:38:15 +0300 -Subject: [PATCH 44/53] network: hook network_get_description() routine to - backend ops - -The network_get_description() function has been created with the idea of -hooking it into the backend ops. -This change does that, with a bit of polishing. -It's also needed inside network_create_context(). - -Signed-off-by: Alexandru Ardelean ---- - network.c | 25 +++++++++++++++++-------- - 1 file changed, 17 insertions(+), 8 deletions(-) - -diff --git a/network.c b/network.c -index 401e940..531baf4 100644 ---- a/network.c -+++ b/network.c -@@ -587,17 +587,18 @@ int create_socket(const struct addrinfo *addrinfo, unsigned int timeout) - return fd; - } - --static char * network_get_description(struct addrinfo *res, size_t *len) -+static char * __network_get_description(struct addrinfo *res) - { - char *description; -+ unsigned int len; - - #ifdef HAVE_IPV6 -- *len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; -+ len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; - #else -- *len = INET_ADDRSTRLEN + 1; -+ len = INET_ADDRSTRLEN + 1; - #endif - -- description = malloc(*len); -+ description = malloc(len); - if (!description) { - errno = ENOMEM; - return NULL; -@@ -631,13 +632,20 @@ static char * network_get_description(struct addrinfo *res, size_t *len) - inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN); - #else - char *tmp = inet_ntoa(in->sin_addr); -- iio_strlcpy(description, tmp, *len); -+ iio_strlcpy(description, tmp, len); - #endif - } - - return description; - } - -+static char *network_get_description(const struct iio_context *ctx) -+{ -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ return __network_get_description(pdata->addrinfo); -+} -+ - static int network_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -@@ -1223,6 +1231,7 @@ static const struct iio_backend_ops network_ops = { - .get_trigger = network_get_trigger, - .set_trigger = network_set_trigger, - .shutdown = network_shutdown, -+ .get_description = network_get_description, - .get_version = network_get_version, - .set_timeout = network_set_timeout, - .set_kernel_buffers_count = network_set_kernel_buffers_count, -@@ -1348,7 +1357,7 @@ struct iio_context * network_create_context(const char *host) - struct iio_context *ctx; - struct iiod_client *iiod_client; - struct iio_context_pdata *pdata; -- size_t len, uri_len; -+ size_t uri_len; - unsigned int i; - int fd, ret; - char *description, *uri; -@@ -1416,7 +1425,7 @@ struct iio_context * network_create_context(const char *host) - goto err_close_socket; - } - -- description = network_get_description(res, &len); -+ description = __network_get_description(res); - if (!description) - goto err_free_pdata; - -@@ -1446,7 +1455,7 @@ struct iio_context * network_create_context(const char *host) - ctx->ops = &network_ops; - ctx->pdata = pdata; - -- uri_len = len; -+ uri_len = strlen(description); - if (host && host[0]) - uri_len = strnlen(host, MAXHOSTNAMELEN); - uri_len += sizeof ("ip:"); --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0045-serial-hook-serial_get_description-routine-to-backen.patch libiio-0.23/debian/patches/0045-serial-hook-serial_get_description-routine-to-backen.patch --- libiio-0.21/debian/patches/0045-serial-hook-serial_get_description-routine-to-backen.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0045-serial-hook-serial_get_description-routine-to-backen.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -From a59a233203630f0555bdb375afd4660afc6e6d65 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Wed, 14 Oct 2020 15:15:27 +0300 -Subject: [PATCH 45/53] serial: hook serial_get_description() routine to - backend ops - -The serial_get_description() function has been created with the idea of -hooking it into the backend ops. -This change does that, with a bit of polishing. -It's also needed inside serial_create_context(). - -Signed-off-by: Alexandru Ardelean ---- - serial.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/serial.c b/serial.c -index 724ec90..686d99b 100644 ---- a/serial.c -+++ b/serial.c -@@ -115,7 +115,7 @@ static int serial_get_version(const struct iio_context *ctx, - major, minor, git_tag); - } - --static char * serial_get_description(struct sp_port *port) -+static char * __serial_get_description(struct sp_port *port) - { - char *description, *name, *desc; - size_t desc_len; -@@ -135,6 +135,13 @@ static char * serial_get_description(struct sp_port *port) - return description; - } - -+static char * serial_get_description(const struct iio_context *ctx) -+{ -+ struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); -+ -+ return __serial_get_description(pdata->port); -+} -+ - static int serial_open(const struct iio_device *dev, - size_t samples_count, bool cyclic) - { -@@ -347,6 +354,7 @@ static const struct iio_backend_ops serial_ops = { - .write_channel_attr = serial_write_chn_attr, - .set_kernel_buffers_count = serial_set_kernel_buffers_count, - .shutdown = serial_shutdown, -+ .get_description = serial_get_description, - .set_timeout = serial_set_timeout, - }; - -@@ -422,7 +430,7 @@ static struct iio_context * serial_create_context(const char *port_name, - /* Empty the buffers */ - sp_flush(port, SP_BUF_BOTH); - -- description = serial_get_description(port); -+ description = __serial_get_description(port); - if (!description) - goto err_close_port; - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0046-iio.h-add-IIO_MOD_O2-modifier-to-enum.patch libiio-0.23/debian/patches/0046-iio.h-add-IIO_MOD_O2-modifier-to-enum.patch --- libiio-0.21/debian/patches/0046-iio.h-add-IIO_MOD_O2-modifier-to-enum.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0046-iio.h-add-IIO_MOD_O2-modifier-to-enum.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -From 8979da9e09ee4c6b3286b1253f0df9a0af7a2275 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Fri, 16 Oct 2020 16:35:41 +0300 -Subject: [PATCH 46/53] iio.h: add IIO_MOD_O2 modifier to enum - -This started appearing in the builds: - https://travis-ci.org/github/analogdevicesinc/libiio/jobs/736083344#L1133 - -The upstream kernel header got an update. -This change syncs it to libiio. - -Updated in all bindings as well. - -Signed-off-by: Alexandru Ardelean ---- - bindings/csharp/Channel.cs | 3 ++- - bindings/python/iio.py | 1 + - channel.c | 1 + - iio.h | 1 + - 4 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/bindings/csharp/Channel.cs b/bindings/csharp/Channel.cs -index 993a188..1761337 100644 ---- a/bindings/csharp/Channel.cs -+++ b/bindings/csharp/Channel.cs -@@ -116,7 +116,8 @@ namespace iio - IIO_MOD_PM4, - IIO_MOD_PM10, - IIO_MOD_ETHANOL, -- IIO_MOD_H2 -+ IIO_MOD_H2, -+ IIO_MOD_O2 - } - - /// class: -diff --git a/bindings/python/iio.py b/bindings/python/iio.py -index 5306daa..29a1952 100644 ---- a/bindings/python/iio.py -+++ b/bindings/python/iio.py -@@ -173,6 +173,7 @@ class ChannelModifier(Enum): - IIO_MOD_PM10 = 41 - IIO_MOD_ETHANOL = 42 - IIO_MOD_H2 = 43 -+ IIO_MOD_O2 = 44 - - - class ChannelType(Enum): -diff --git a/channel.c b/channel.c -index d79074d..d458dd7 100644 ---- a/channel.c -+++ b/channel.c -@@ -100,6 +100,7 @@ static const char * const modifier_names[] = { - [IIO_MOD_CO2] = "co2", - [IIO_MOD_ETHANOL] = "ethanol", - [IIO_MOD_H2] = "h2", -+ [IIO_MOD_O2] = "h2", - [IIO_MOD_VOC] = "voc", - [IIO_MOD_PM1] = "pm1", - [IIO_MOD_PM2P5] = "pm2p5", -diff --git a/iio.h b/iio.h -index 641b4d5..317f64f 100644 ---- a/iio.h -+++ b/iio.h -@@ -190,6 +190,7 @@ enum iio_modifier { - IIO_MOD_PM10, - IIO_MOD_ETHANOL, - IIO_MOD_H2, -+ IIO_MOD_O2, - }; - - /* ---------------------------------------------------------------------------*/ --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0047-Fix-marshalling-in-C-bindings.patch libiio-0.23/debian/patches/0047-Fix-marshalling-in-C-bindings.patch --- libiio-0.21/debian/patches/0047-Fix-marshalling-in-C-bindings.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0047-Fix-marshalling-in-C-bindings.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -From 4c0f1d372565dcb979f90a48ec5725056cb9678a Mon Sep 17 00:00:00 2001 -From: Max Lehuraux -Date: Fri, 16 Oct 2020 09:13:53 -0400 -Subject: [PATCH 47/53] Fix marshalling in C# bindings - -During context creation, the context attributes' name and value were not marshalled correctly form native to managed memory, creating a crash when the GC collected gen2 heap memory. -Signed-off-by: Lehuraux, Max -Co-Authored-By: cristi-iacob <52404495+cristi-iacob@users.noreply.github.com> ---- - bindings/csharp/Context.cs | 21 +++++++++------------ - 1 file changed, 9 insertions(+), 12 deletions(-) - -diff --git a/bindings/csharp/Context.cs b/bindings/csharp/Context.cs -index a94a2b6..2587743 100644 ---- a/bindings/csharp/Context.cs -+++ b/bindings/csharp/Context.cs -@@ -99,7 +99,7 @@ namespace iio - private static extern uint iio_context_get_attrs_count(IntPtr ctx); - - [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] -- private static extern int iio_context_get_attr(IntPtr ctx, uint index, IntPtr name_ptr, IntPtr value_ptr); -+ private static extern int iio_context_get_attr(IntPtr ctx, uint index, out IntPtr name_ptr, out IntPtr value_ptr); - - [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr iio_context_find_device(IntPtr ctx, [In] string name); -@@ -199,19 +199,16 @@ namespace iio - backend_version = new Version(major, minor, builder.ToString()); - - attrs = new Dictionary(); -+ uint nbAttrs = iio_context_get_attrs_count(ctx); - -- for (uint i = 0; i < iio_context_get_attrs_count(ctx); i++) -+ for (uint i = 0; i < nbAttrs; i++) - { -- string attr_name = ""; -- GCHandle name_handle = GCHandle.Alloc(attr_name, GCHandleType.Pinned); -- IntPtr name_ptr = GCHandle.ToIntPtr(name_handle); -- string attr_value = ""; -- GCHandle value_handle = GCHandle.Alloc(attr_value, GCHandleType.Pinned); -- IntPtr value_ptr = GCHandle.ToIntPtr(value_handle); -- -- iio_context_get_attr(ctx, i, name_ptr, value_ptr); -- attr_name = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(name_ptr)); -- attr_value = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(value_ptr)); -+ IntPtr name_ptr; -+ IntPtr value_ptr; -+ -+ iio_context_get_attr(ctx, i, out name_ptr, out value_ptr); -+ string attr_name = Marshal.PtrToStringAnsi(name_ptr); -+ string attr_value = Marshal.PtrToStringAnsi(value_ptr); - - attrs[attr_name] = attr_value; - } --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0048-channel.c-fix-typo-for-string.patch libiio-0.23/debian/patches/0048-channel.c-fix-typo-for-string.patch --- libiio-0.21/debian/patches/0048-channel.c-fix-typo-for-string.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0048-channel.c-fix-typo-for-string.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From b3c755ad9e5eab9d2c5cb956a6dff9b4a947e78e Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 19 Oct 2020 09:09:21 +0300 -Subject: [PATCH 48/53] channel.c: fix typo for string - -Was introduced via copy+paste error. - -Fixes: 8979da9 ("iio.h: add IIO_MOD_O2 modifier to enum") -Signed-off-by: Alexandru Ardelean ---- - channel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/channel.c b/channel.c -index d458dd7..7d961cb 100644 ---- a/channel.c -+++ b/channel.c -@@ -100,7 +100,7 @@ static const char * const modifier_names[] = { - [IIO_MOD_CO2] = "co2", - [IIO_MOD_ETHANOL] = "ethanol", - [IIO_MOD_H2] = "h2", -- [IIO_MOD_O2] = "h2", -+ [IIO_MOD_O2] = "o2", - [IIO_MOD_VOC] = "voc", - [IIO_MOD_PM1] = "pm1", - [IIO_MOD_PM2P5] = "pm2p5", --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0049-ci-travis-remove-lsb-package-requirement.patch libiio-0.23/debian/patches/0049-ci-travis-remove-lsb-package-requirement.patch --- libiio-0.21/debian/patches/0049-ci-travis-remove-lsb-package-requirement.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0049-ci-travis-remove-lsb-package-requirement.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -From 5e935b5c156113cb8cd3ff26483b715c84a0f70c Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Sat, 17 Oct 2020 12:13:32 +0300 -Subject: [PATCH 49/53] ci,travis: remove lsb package requirement - -To get the lsb_release command working some packages need to be -pre-installed. -The docker images come pretty bare, so they need to be installed before. - -This can complicate things, because we need to make sure that all builds -down the pipeline install this package. - -The utilities that wrap lsb_release can be re-implemented with simple shell -commands and parsing of /etc/os-release. -This change does that. - -Signed-off-by: Alexandru Ardelean ---- - CI/travis/before_install_linux | 4 ++-- - CI/travis/lib.sh | 16 +++++++++++----- - 2 files changed, 13 insertions(+), 7 deletions(-) - -diff --git a/CI/travis/before_install_linux b/CI/travis/before_install_linux -index 387d99c..0cff06e 100755 ---- a/CI/travis/before_install_linux -+++ b/CI/travis/before_install_linux -@@ -42,7 +42,7 @@ handle_centos() { - # FIXME: see about adding `libserialport-dev` from EPEL ; maybe libusb-1.0.0-devel... - yum -y groupinstall 'Development Tools' - yum -y install cmake libxml2-devel libusb1-devel libaio-devel \ -- bzip2 gzip rpm rpm-build redhat-lsb-core -+ bzip2 gzip rpm rpm-build - - # needed for building python with pyenv - yum install -y gcc gcc-c++ make git patch openssl-devel zlib-devel readline-devel sqlite-devel bzip2-devel -@@ -95,7 +95,7 @@ handle_default() { - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y cmake graphviz \ - libaio-dev libavahi-client-dev \ - libavahi-common-dev libusb-1.0-0-dev libxml2-dev rpm tar \ -- bzip2 gzip flex bison git lsb-release libncurses5-dev libcdk5-dev -+ bzip2 gzip flex bison git libncurses5-dev libcdk5-dev - - # Most of these should be here, but are needed for building python by pyenv - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential \ -diff --git a/CI/travis/lib.sh b/CI/travis/lib.sh -index 4501773..c784319 100644 ---- a/CI/travis/lib.sh -+++ b/CI/travis/lib.sh -@@ -474,24 +474,30 @@ version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; - version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" = "$1"; } - - get_codename() { -- lsb_release -c -s -+ local VERSION_CODENAME -+ eval $(grep -w VERSION_CODENAME /etc/os-release) -+ echo "$VERSION_CODENAME" - } - - get_dist_id() { -- lsb_release -i -s -+ local ID -+ eval $(grep -w ID /etc/os-release) -+ echo "$ID" - } - - get_version() { -- lsb_release -r -s -+ local VERSION_ID -+ eval $(grep -w VERSION_ID /etc/os-release) -+ echo "$VERSION_ID" - } - - is_ubuntu_at_least_ver() { -- [ "$(get_dist_id)" = "Ubuntu" ] || return 1 -+ [ "$(get_dist_id)" = "ubuntu" ] || return 1 - version_ge "$(get_version)" "$1" - } - - is_centos_at_least_ver() { -- [ "$(get_dist_id)" = "CentOS" ] || return 1 -+ [ "$(get_dist_id)" = "centos" ] || return 1 - version_ge "$(get_version)" "$1" - } - --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0050-611-Eliminate-variable-shadowing-in-local.c.patch libiio-0.23/debian/patches/0050-611-Eliminate-variable-shadowing-in-local.c.patch --- libiio-0.21/debian/patches/0050-611-Eliminate-variable-shadowing-in-local.c.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0050-611-Eliminate-variable-shadowing-in-local.c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From 04d52b2c632f15212be0ca95a1c973eb9d456c4e Mon Sep 17 00:00:00 2001 -From: Marc Sporcich -Date: Mon, 19 Oct 2020 19:03:15 -0500 -Subject: [PATCH 50/53] #611:Eliminate variable shadowing in local.c - -Resolves build problems when compiling with -Werror=shadow. - -Signed-off-by: Marc Sporcich ---- - local.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/local.c b/local.c -index f47f942..f7533fa 100644 ---- a/local.c -+++ b/local.c -@@ -1012,7 +1012,6 @@ static int local_close(const struct iio_device *dev) - ret = 0; - ret1 = 0; - if (pdata->is_high_speed) { -- unsigned int i; - if (pdata->addrs) { - for (i = 0; i < pdata->allocated_nb_blocks; i++) - munmap(pdata->addrs[i], pdata->blocks[i].size); -@@ -1198,7 +1197,7 @@ static char * get_short_attr_name(struct iio_channel *chn, const char *attr) - ptr += len + 1; - - if (chn->name) { -- size_t len = strlen(chn->name); -+ len = strlen(chn->name); - if (strncmp(chn->name, ptr, len) == 0 && ptr[len] == '_') - ptr += len + 1; - } --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0051-.travis.yml-unify-EXTRA_SSH-env-var.patch libiio-0.23/debian/patches/0051-.travis.yml-unify-EXTRA_SSH-env-var.patch --- libiio-0.21/debian/patches/0051-.travis.yml-unify-EXTRA_SSH-env-var.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0051-.travis.yml-unify-EXTRA_SSH-env-var.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -From fc4961f681ced6ece8c2760602a3e6f6bdfc35e4 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Mon, 19 Oct 2020 09:23:47 +0300 -Subject: [PATCH 51/53] .travis.yml: unify EXTRA_SSH env var - -This has mostly cleanup value. Since it's duplicated everywhere, it may -make sense to just move the EXTRA_SSH to a global place, and not duplicate -it anymore. - -Signed-off-by: Alexandru Ardelean ---- - .travis.yml | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - -diff --git a/.travis.yml b/.travis.yml -index a8c0cdc..eaf6532 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -4,6 +4,7 @@ python: "3.6" - - env: - global: -+ - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - # SSHHOST - - secure: "NEXUEA+ccm/I21ujCPuKYIHFb8Gogunr3nYysCRpTBNT40PsU9VFIy5vbmMxPAkCaMwk8XZ0rMHE3uaNGbBAGfoDL9v0Ban5wG/jA1JkmOAWUpFrUsbQeejXNRA04QcZ/4VeL6TgFegV2T6V0tLB4M6/X316dIPhS9Tat1ZUC8s=" - # SSHUSER -@@ -23,13 +24,11 @@ matrix: - env: - - ARCH=arm - - OS_VERSION=jessie -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - compiler: "gcc" - dist: xenial - env: - - ARCH=arm - - OS_VERSION=stretch -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - compiler: "gcc" - os: linux - env: -@@ -52,43 +51,32 @@ matrix: - os: linux - dist: xenial - env: -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - # GH_DOC_TOKEN used to deploy docs - - secure: "OrwnYeUITY2R7pn11WHqsO7c6F9fRY7G5fOh98GGXnw7dAIoSvUhjUE70ehaBzLH0CyO83KgaiyACP8eqRx9BYUd1McrqTFDmYJNVR+Wk01SSjJxaXzU4RMsJPhXH9l5U7BEH5dVk/IFLLaCwYnc35mlADHE2KCGNanvtnRU0gU=" - - os: linux - env: - - OS_TYPE=centos_docker - - OS_VERSION=6 -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - os: linux - env: - - OS_TYPE=centos_docker - - OS_VERSION=7 -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - os: linux - dist: bionic -- env: -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - os: linux - env: - - OS_TYPE=centos_docker - - OS_VERSION=8 -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - os: linux - env: - - OS_TYPE=ubuntu_docker - - OS_VERSION=focal -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - compiler: "gcc" - os: osx - osx_image: xcode10.1 -- env: -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - compiler: "gcc" - os: osx - osx_image: xcode11 -- env: -- - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - - - stage: "Trigger Next In Pipeline" - env: --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0052-Appveyor-Use-mingw64-bin-windres-as-RC-compiler-for-.patch libiio-0.23/debian/patches/0052-Appveyor-Use-mingw64-bin-windres-as-RC-compiler-for-.patch --- libiio-0.21/debian/patches/0052-Appveyor-Use-mingw64-bin-windres-as-RC-compiler-for-.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0052-Appveyor-Use-mingw64-bin-windres-as-RC-compiler-for-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From e1f2454d1b290fd1de5b46a2945d5fe07456028b Mon Sep 17 00:00:00 2001 -From: Alexandra Trifan -Date: Thu, 22 Oct 2020 10:43:03 +0300 -Subject: [PATCH 52/53] Appveyor: Use mingw64/bin/windres as RC compiler for 64 - bit. - -Signed-off-by: Alexandra Trifan ---- - appveyor.yml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/appveyor.yml b/appveyor.yml -index d8d1bff..bd81442 100644 ---- a/appveyor.yml -+++ b/appveyor.yml -@@ -79,7 +79,7 @@ build_script: - # set the specific version of doxygen, need to look at this later. - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-doxygen-%DOXYGEN_VERSION%-any.pkg.tar.zst" - - C:\msys64\usr\bin\bash -lc "pacman -U --noconfirm http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-graphviz-%GRAPHVIZ_VERSION%-any.pkg.tar.zst" -- - C:\msys64\usr\bin\bash -lc "cmake -G '%GENERATOR%' -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_INSTALL_PREFIX=/mingw64 -DCMAKE_C_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-g++.exe -DPKG_CONFIG_EXECUTABLE:FILEPATH=/mingw64/bin/pkg-config.exe -DENABLE_IPV6:BOOL=OFF -DLIBSERIALPORT_LIBRARIES=/c/libs/64/libserialport.dll.a -DLIBSERIALPORT_INCLUDE_DIR=/c/include /c/projects/libiio && make -j3" -+ - C:\msys64\usr\bin\bash -lc "cmake -G '%GENERATOR%' -DCMAKE_RC_COMPILER=/c/msys64/mingw64/bin/windres.exe -DCMAKE_BUILD_TYPE=%configuration% -DCMAKE_INSTALL_PREFIX=/mingw64 -DCMAKE_C_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=/mingw64/bin/x86_64-w64-mingw32-g++.exe -DPKG_CONFIG_EXECUTABLE:FILEPATH=/mingw64/bin/pkg-config.exe -DENABLE_IPV6:BOOL=OFF -DLIBSERIALPORT_LIBRARIES=/c/libs/64/libserialport.dll.a -DLIBSERIALPORT_INCLUDE_DIR=/c/include /c/projects/libiio && make -j3" - - # Move the tests folder - - cd c:\projects\libiio --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/0053-.travis.yml-build-deploy-for-Xcode12.patch libiio-0.23/debian/patches/0053-.travis.yml-build-deploy-for-Xcode12.patch --- libiio-0.21/debian/patches/0053-.travis.yml-build-deploy-for-Xcode12.patch 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/0053-.travis.yml-build-deploy-for-Xcode12.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 99ef2015f4163e904cff28c3ff461a348cc9f488 Mon Sep 17 00:00:00 2001 -From: Alexandru Ardelean -Date: Thu, 22 Oct 2020 15:42:34 +0300 -Subject: [PATCH 53/53] .travis.yml: build & deploy for Xcode12 - -Xcode 12 has been out for a while now. -This change adds a build for it so that we can start putting it through the -pipeline. - -Signed-off-by: Alexandru Ardelean ---- - .travis.yml | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/.travis.yml b/.travis.yml -index eaf6532..243f3dd 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -77,6 +77,9 @@ matrix: - - compiler: "gcc" - os: osx - osx_image: xcode11 -+ - compiler: "gcc" -+ os: osx -+ osx_image: xcode12 - - - stage: "Trigger Next In Pipeline" - env: --- -2.20.1 - diff -Nru libiio-0.21/debian/patches/bump-cmake-minimum libiio-0.23/debian/patches/bump-cmake-minimum --- libiio-0.21/debian/patches/bump-cmake-minimum 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/debian/patches/bump-cmake-minimum 2021-11-10 04:09:03.000000000 +0000 @@ -0,0 +1,52 @@ +Description: modern CMake needs > 2.8.12 +Author: "A. Maitland Bottoms" + +--- a/examples/CMakeLists.txt ++++ b/examples/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + + project(ad9361-iiostream C) + project(ad9371-iiostream C) +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,5 +1,5 @@ + message(STATUS "cmake version: ${CMAKE_VERSION}") +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + project(libiio C) + + if (MINGW) +--- a/bindings/python/CMakeLists.txt ++++ b/bindings/python/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + project(libiio-py NONE) + + if(${CMAKE_VERSION} VERSION_LESS "3.12.0") +--- a/bindings/csharp/CMakeLists.txt ++++ b/bindings/csharp/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + project(libiio-sharp NONE) + + if (WIN32) +--- a/iiod/CMakeLists.txt ++++ b/iiod/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + project(iiod C) + + include(FindBISON) +--- a/tests/CMakeLists.txt ++++ b/tests/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 2.8.7) ++cmake_minimum_required(VERSION 3.10.2) + + project(iio_genxml C) + project(iio_info C) diff -Nru libiio-0.21/debian/patches/debian-soversion-udev-rules libiio-0.23/debian/patches/debian-soversion-udev-rules --- libiio-0.21/debian/patches/debian-soversion-udev-rules 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/debian-soversion-udev-rules 2021-11-28 00:41:07.000000000 +0000 @@ -4,7 +4,7 @@ --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -575,8 +575,8 @@ +@@ -603,8 +603,8 @@ if (INSTALL_UDEV_RULE) set(UDEV_RULES_INSTALL_DIR /lib/udev/rules.d CACHE PATH "default install path for udev rules") diff -Nru libiio-0.21/debian/patches/python-setup-libiio libiio-0.23/debian/patches/python-setup-libiio --- libiio-0.21/debian/patches/python-setup-libiio 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/python-setup-libiio 2021-11-10 02:58:20.000000000 +0000 @@ -3,7 +3,7 @@ --- a/bindings/python/setup.py.cmakein +++ b/bindings/python/setup.py.cmakein -@@ -49,7 +49,7 @@ +@@ -40,7 +40,7 @@ libiio library is actually installed""" def run(self): diff -Nru libiio-0.21/debian/patches/series libiio-0.23/debian/patches/series --- libiio-0.21/debian/patches/series 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/patches/series 2021-11-28 00:40:04.000000000 +0000 @@ -1,56 +1,30 @@ -0001-Use-https-for-download-links-in-README.md.patch -0002-cmake-Avoid-path-construction-in-pkg-config-file.patch -0003-tests-Support-context-timeout-in-common-manner.patch -0004-dnssd-Use-lower-case-when-including-Windows-headers.patch -0005-Update-python-package-name.patch -0006-man-allow-man-pages-to-be-built-when-not-in-a-.-buil.patch -0007-cmake-set-_WIN32_WINNT-when-compiling-with-mingw.patch -0008-python-Do-not-verify-whether-libiio-is-installed-whe.patch -0009-appveyor.yml-Update-the-MSYS-build-keyring-manually.patch -0010-iio_attr-accept-negative-numbers-as-data-to-write-to.patch -0011-local-don-t-keep-internal-state-if-buffer-enabled.patch -0012-local-harden-local_close-and-use-it-for-local_open-f.patch -0013-local-handle-error-codes-in-local_close.patch -0014-tests-iio_common-Fix-HEX-value-parsing-in-sanitize_c.patch -0015-local-add-omitted-return-value-read-from-close-in-lo.patch -0016-Fixed-declaration-of-buf-hides-previous-local-declar.patch -0017-doc-fix-typo-in-build-guide.patch -0018-utilities-Fix-getenv-function.patch -0019-CMake-fix-build-with-cmake-2.8.7.patch -0020-local.c-when-target-buffer-is-too-small-fail.patch -0021-xml-use-iio_context_destroy-on-error-path-of-iio_cre.patch -0022-local-use-API-accessors-for-accessing-devices-from-a.patch -0023-iio-local-xml-add-and-use-iio_context_add_device-hel.patch -0024-iiod-access-IIO-devices-via-API-accessors.patch -0025-Make-the-build-reproducible-Closes-591.patch -0026-iiod-client-move-context-lock-inside-the-iiod_client.patch -0027-appveyor.yml-parametrize-mingw-toolchains-version-an.patch -0028-appveyor.yml-parametrize-bump-doxygen-graphviz-versi.patch -0029-network-change-type-of-i-to-unsigned-int.patch -0030-network-split-description-creation-into-it-s-own-fun.patch -0031-serial-split-description-creation-into-it-s-own-func.patch -0032-network-move-free-description-under-ifdef-HAVE_IPV6.patch -0033-iio-split-iio_backend_ops-into-iio-backend.h.patch -0034-iio-create-iio_context_create_from_backend-helper-an.patch -0035-iio-centralize-context-pdata-free-in-iio_context_des.patch -0036-xml-split-iio_populate_xml_context_helper-from-creat.patch -0037-iio-add-iio_context_get_pdata-accessor.patch -0038-usb-make-use-of-the-iio_context_pdata-helper.patch -0039-network-make-use-of-the-iio_context_pdata-helper.patch -0040-serial-make-use-of-the-iio_context_pdata-helper.patch -0041-local-make-use-of-the-iio_context_pdata-helper.patch -0042-iio-backend-add-get_description-backend-op.patch -0043-local-split-get_description-logic-into-function-and-.patch -0044-network-hook-network_get_description-routine-to-back.patch -0045-serial-hook-serial_get_description-routine-to-backen.patch -0046-iio.h-add-IIO_MOD_O2-modifier-to-enum.patch -0047-Fix-marshalling-in-C-bindings.patch -0048-channel.c-fix-typo-for-string.patch -0049-ci-travis-remove-lsb-package-requirement.patch -0050-611-Eliminate-variable-shadowing-in-local.c.patch -0051-.travis.yml-unify-EXTRA_SSH-env-var.patch -0052-Appveyor-Use-mingw64-bin-windres-as-RC-compiler-for-.patch -0053-.travis.yml-build-deploy-for-Xcode12.patch +0001-bindings-python-fix-ctypes-null-pointer-check.patch +0002-C-public-fields-with-getters-setters-cannot-be-marke.patch +0003-CI-reconfigure-Azure-Pipelines-artifacts.patch +0004-CI-edit-Github-release.patch +0005-CI-generate-libiio-setup.exe.patch +0006-CI-generate-and-deploy-documentation.patch +0007-CI-make-file-executable.patch +0008-local-Fix-detection-of-scan-element-channels.patch +0009-CI-push-windows-setup.exe-to-SWDownloads.patch +0010-iiod-Add-is_usb-field-to-pdata-structure.patch +0011-iiod-Update-read_line-to-work-with-UART.patch +0012-iiod-thread-pool-Add-function-thread_pool_is_stopped.patch +0013-iiod-Support-running-on-UART.patch +0014-serial-Bump-max-baudrate-to-4-Mbps.patch +0015-serial-Implement-get-set-_trigger-callback.patch +0016-C-Add-support-for-data-format.patch +0017-CI-disable-debug-on-the-artifact-deploy.patch +0018-azure-pipelines-Update-libusb-and-libxml2-version-fo.patch +0019-iiod-fix-read_line-for-USB.patch +0020-CMake-re-work-messages-to-have-a-summary-at-the-bott.patch +0021-local-Don-t-check-size-of-dequeued-buffer-vs.-bytes_.patch +0022-iio-private.h-Remove-useless-field-is_output.patch +0023-CMake-Move-include-CheckCSourceCompiles-before-its-m.patch +0024-usb-Fix-printf-format-in-debug-string.patch +0025-Archive-windows-artifacts.patch +0026-CI-update-macOS-version.patch +bump-cmake-minimum reproducible-build.patch python-setup-libiio debian-soversion-udev-rules diff -Nru libiio-0.21/debian/rules libiio-0.23/debian/rules --- libiio-0.21/debian/rules 2020-10-31 23:26:57.000000000 +0000 +++ libiio-0.23/debian/rules 2021-11-10 03:44:45.000000000 +0000 @@ -13,4 +13,14 @@ override_dh_auto_install: dh_auto_install - - rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.21/python/.nojekyll + - rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/.nojekyll + rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/doctools.js + cd debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/ && ln -s /usr/share/javascript/sphinxdoc/1.0/doctools.js doctools.js + rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/language_data.js + cd debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/ && ln -s /usr/share/javascript/sphinxdoc/1.0/language_data.js language_data.js + rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/searchtools.js + cd debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/ && ln -s /usr/share/javascript/sphinxdoc/1.0/searchtools.js searchtools.js + rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/jquery.js + cd debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/ && ln -s /usr/share/javascript/jquery/jquery.js jquery.js + rm -f debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/underscore.js + cd debian/tmp/usr/share/doc/libiio0-doc/v0.23/python/_static/ && ln -s /usr/share/javascript/underscore/underscore.js underscore.js diff -Nru libiio-0.21/debug.h libiio-0.23/debug.h --- libiio-0.21/debug.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/debug.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +/* 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 - * - * 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. - * - * */ + */ #ifndef DEBUG_H #define DEBUG_H diff -Nru libiio-0.21/device.c libiio-0.23/device.c --- libiio-0.21/device.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/device.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// 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 - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-private.h" @@ -24,242 +14,115 @@ #include #include -static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type) +static ssize_t iio_snprintf_xml_attr(char *buf, ssize_t len, const char *attr, + enum iio_attr_type type) { - size_t len; - char *str; - - len = sizeof("") - 1; - len += strnlen(attr, MAX_ATTR_NAME); - - switch(type){ - case IIO_ATTR_TYPE_DEVICE: - break; - case IIO_ATTR_TYPE_DEBUG: - len += (sizeof("debug-") - 1); - break; - case IIO_ATTR_TYPE_BUFFER: - len += (sizeof("buffer-") - 1); - break; - default: - return NULL; - } - - *length = len; /* just the chars */ - len++; /* room for terminating NULL */ - str = malloc(len); - if (!str) - return NULL; - switch (type) { case IIO_ATTR_TYPE_DEVICE: - iio_snprintf(str, len, "", attr); - break; + return iio_snprintf(buf, len, "", attr); case IIO_ATTR_TYPE_DEBUG: - iio_snprintf(str, len, "", attr); - break; + return iio_snprintf(buf, len, "", attr); case IIO_ATTR_TYPE_BUFFER: - iio_snprintf(str, len, "", attr); - break; + return iio_snprintf(buf, len, "", attr); + default: + return -EINVAL; } - - return str; } -/* Returns a string containing the XML representation of this device */ -char * iio_device_get_xml(const struct iio_device *dev, size_t *length) +ssize_t iio_snprintf_device_xml(char *ptr, ssize_t len, + const struct iio_device *dev) { - ssize_t len; - char *ptr, *eptr, *str, **attrs, **channels, **buffer_attrs, **debug_attrs; - size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len; - unsigned int i, j, k; + ssize_t ret, alen = 0; + unsigned int i; - len = sizeof("") - 1; - len += strnlen(dev->id, MAX_DEV_ID); + ret = iio_snprintf(ptr, len, "id); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); if (dev->name) { - len += sizeof(" name=\"\"") - 1; - len += strnlen(dev->name, MAX_DEV_NAME); + ret = iio_snprintf(ptr, len, " name=\"%s\"", dev->name); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - attrs_len = malloc(dev->nb_attrs * sizeof(*attrs_len)); - if (!attrs_len) - return NULL; + if (dev->label) { + ret = iio_snprintf(ptr, len, " label=\"%s\"", dev->label); + if (ret < 0) + return ret; - attrs = malloc(dev->nb_attrs * sizeof(*attrs)); - if (!attrs) - goto err_free_attrs_len; - - for (i = 0; i < dev->nb_attrs; i++) { - char *xml = get_attr_xml(dev->attrs[i], &attrs_len[i], IIO_ATTR_TYPE_DEVICE); - if (!xml) - goto err_free_attrs; - attrs[i] = xml; - len += attrs_len[i]; - } - - channels_len = malloc(dev->nb_channels * sizeof(*channels_len)); - if (!channels_len) - goto err_free_attrs; - - channels = malloc(dev->nb_channels * sizeof(*channels)); - if (!channels) - goto err_free_channels_len; - - for (j = 0; j < dev->nb_channels; j++) { - char *xml = iio_channel_get_xml(dev->channels[j], - &channels_len[j]); - if (!xml) - goto err_free_channels; - channels[j] = xml; - len += channels_len[j]; - } - - buffer_attrs_len = malloc(dev->nb_buffer_attrs * - sizeof(*buffer_attrs_len)); - if (!buffer_attrs_len) - goto err_free_channels; - - buffer_attrs = malloc(dev->nb_buffer_attrs * sizeof(*buffer_attrs)); - if (!buffer_attrs) - goto err_free_buffer_attrs_len; - - for (k = 0; k < dev->nb_buffer_attrs; k++) { - char *xml = get_attr_xml(dev->buffer_attrs[k], - &buffer_attrs_len[k], IIO_ATTR_TYPE_BUFFER); - if (!xml) - goto err_free_buffer_attrs; - buffer_attrs[k] = xml; - len += buffer_attrs_len[k]; - } - - debug_attrs_len = malloc(dev->nb_debug_attrs * - sizeof(*debug_attrs_len)); - if (!debug_attrs_len) - goto err_free_buffer_attrs; - - debug_attrs = malloc(dev->nb_debug_attrs * sizeof(*debug_attrs)); - if (!debug_attrs) - goto err_free_debug_attrs_len; - - for (k = 0; k < dev->nb_debug_attrs; k++) { - char *xml = get_attr_xml(dev->debug_attrs[k], - &debug_attrs_len[k], IIO_ATTR_TYPE_DEBUG); - if (!xml) - goto err_free_debug_attrs; - debug_attrs[k] = xml; - len += debug_attrs_len[k]; - } - - len++; /* room for terminating NULL */ - str = malloc(len); - if (!str) - goto err_free_debug_attrs; - eptr = str + len; - ptr = str; - - if (len > 0) { - ptr += iio_snprintf(str, len, "id); - len = eptr - ptr; - } - - if (dev->name && len > 0) { - ptr += iio_snprintf(ptr, len, " name=\"%s\"", dev->name); - len = eptr - ptr; - } - - if (len > 0) { - ptr += iio_strlcpy(ptr, " >", len); - len -= 2; + iio_update_xml_indexes(ret, &ptr, &len, &alen); } + ret = iio_snprintf(ptr, len, " >"); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); + for (i = 0; i < dev->nb_channels; i++) { - if (len > (ssize_t) channels_len[i]) { - memcpy(ptr, channels[i], channels_len[i]); /* Flawfinder: ignore */ - ptr += channels_len[i]; - len -= channels_len[i]; - } - free(channels[i]); - } + ret = iio_snprintf_channel_xml(ptr, len, dev->channels[i]); + if (ret < 0) + return ret; - free(channels); - free(channels_len); + iio_update_xml_indexes(ret, &ptr, &len, &alen); + } - for (i = 0; i < dev->nb_attrs; i++) { - if (len > (ssize_t) attrs_len[i]) { - memcpy(ptr, attrs[i], attrs_len[i]); /* Flawfinder: ignore */ - ptr += attrs_len[i]; - len -= attrs_len[i]; - } - free(attrs[i]); + for (i = 0; i < dev->attrs.num; i++) { + ret = iio_snprintf_xml_attr(ptr, len, dev->attrs.names[i], + IIO_ATTR_TYPE_DEVICE); + if (ret < 0) + return ret; + + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - free(attrs); - free(attrs_len); + for (i = 0; i < dev->buffer_attrs.num; i++) { + ret = iio_snprintf_xml_attr(ptr, len, dev->buffer_attrs.names[i], + IIO_ATTR_TYPE_BUFFER); + if (ret < 0) + return ret; - for (i = 0; i < dev->nb_buffer_attrs; i++) { - if (len > (ssize_t) buffer_attrs_len[i]) { - memcpy(ptr, buffer_attrs[i], buffer_attrs_len[i]); /* Flawfinder: ignore */ - ptr += buffer_attrs_len[i]; - len -= buffer_attrs_len[i]; - } - free(buffer_attrs[i]); + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - free(buffer_attrs); - free(buffer_attrs_len); + for (i = 0; i < dev->debug_attrs.num; i++) { + ret = iio_snprintf_xml_attr(ptr, len, dev->debug_attrs.names[i], + IIO_ATTR_TYPE_DEBUG); + if (ret < 0) + return ret; - for (i = 0; i < dev->nb_debug_attrs; i++) { - if (len > (ssize_t) debug_attrs_len[i]) { - memcpy(ptr, debug_attrs[i], debug_attrs_len[i]); /* Flawfinder: ignore */ - ptr += debug_attrs_len[i]; - len -= debug_attrs_len[i]; - } - free(debug_attrs[i]); + iio_update_xml_indexes(ret, &ptr, &len, &alen); } - free(debug_attrs); - free(debug_attrs_len); + ret = iio_snprintf(ptr, len, ""); + if (ret < 0) + return ret; - if (len > 0) { - ptr += iio_strlcpy(ptr, "", len); - len -= sizeof("") - 1; - } + return alen + ret; +} - *length = ptr - str; +int add_iio_dev_attr(struct iio_dev_attrs *attrs, const char *attr, + const char *type, const char *dev_id) +{ + char **names, *name; - if (len != 1) { - IIO_ERROR("Internal libIIO error: iio_device_get_xml str length issue\n"); - free(str); - return NULL; - } + name = iio_strdup(attr); + if (!name) + return -ENOMEM; - return str; + names = realloc(attrs->names, (1 + attrs->num) * sizeof(char *)); + if (!names) { + free(name); + return -ENOMEM; + } -err_free_debug_attrs: - while (k--) - free(debug_attrs[k]); - free(debug_attrs); -err_free_debug_attrs_len: - free(debug_attrs_len); -err_free_buffer_attrs: - while (k--) - free(buffer_attrs[k]); - free(buffer_attrs); -err_free_buffer_attrs_len: - free(buffer_attrs_len); -err_free_channels: - while (j--) - free(channels[j]); - free(channels); -err_free_channels_len: - free(channels_len); -err_free_attrs: - while (i--) - free(attrs[i]); - free(attrs); -err_free_attrs_len: - free(attrs_len); - return NULL; + names[attrs->num++] = name; + attrs->names = names; + IIO_DEBUG("Added%s attr \'%s\' to device \'%s\'\n", type, attr, dev_id); + return 0; } const char * iio_device_get_id(const struct iio_device *dev) @@ -272,6 +135,11 @@ return dev->name; } +const char * iio_device_get_label(const struct iio_device *dev) +{ + return dev->label; +} + unsigned int iio_device_get_channels_count(const struct iio_device *dev) { return dev->nb_channels; @@ -302,68 +170,65 @@ return NULL; } -unsigned int iio_device_get_attrs_count(const struct iio_device *dev) -{ - return dev->nb_attrs; -} - -const char * iio_device_get_attr(const struct iio_device *dev, +static const char * iio_device_get_dev_attr(const struct iio_dev_attrs *attrs, unsigned int index) { - if (index >= dev->nb_attrs) + if (index >= attrs->num) return NULL; else - return dev->attrs[index]; + return attrs->names[index]; } -const char * iio_device_find_attr(const struct iio_device *dev, +const char * iio_device_find_dev_attr(const struct iio_dev_attrs *attrs, const char *name) { unsigned int i; - for (i = 0; i < dev->nb_attrs; i++) { - const char *attr = dev->attrs[i]; + for (i = 0; i < attrs->num; i++) { + const char *attr = attrs->names[i]; if (!strcmp(attr, name)) return attr; } return NULL; } +unsigned int iio_device_get_attrs_count(const struct iio_device *dev) +{ + return dev->attrs.num; +} + +const char * iio_device_get_attr(const struct iio_device *dev, + unsigned int index) +{ + return iio_device_get_dev_attr(&dev->attrs, index); +} + +const char * iio_device_find_attr(const struct iio_device *dev, + const char *name) +{ + return iio_device_find_dev_attr(&dev->attrs, name); +} + unsigned int iio_device_get_buffer_attrs_count(const struct iio_device *dev) { - return dev->nb_buffer_attrs; + return dev->buffer_attrs.num; } const char * iio_device_get_buffer_attr(const struct iio_device *dev, unsigned int index) { - if (index >= dev->nb_buffer_attrs) - return NULL; - else - return dev->buffer_attrs[index]; + return iio_device_get_dev_attr(&dev->buffer_attrs, index); } const char * iio_device_find_buffer_attr(const struct iio_device *dev, const char *name) { - unsigned int i; - for (i = 0; i < dev->nb_buffer_attrs; i++) { - const char *attr = dev->buffer_attrs[i]; - if (!strcmp(attr, name)) - return attr; - } - return NULL; + return iio_device_find_dev_attr(&dev->buffer_attrs, name); } const char * iio_device_find_debug_attr(const struct iio_device *dev, const char *name) { - unsigned int i; - for (i = 0; i < dev->nb_debug_attrs; i++) { - const char *attr = dev->debug_attrs[i]; - if (!strcmp(attr, name)) - return attr; - } - return NULL; + return iio_device_find_dev_attr(&dev->debug_attrs, name); } bool iio_device_is_tx(const struct iio_device *dev) @@ -545,31 +410,31 @@ return -ENOSYS; } +static void free_iio_dev_attrs(struct iio_dev_attrs *attrs) +{ + unsigned int i; + + for (i = 0; i < attrs->num; i++) + free(attrs->names[i]); + + free(attrs->names); +} + void free_device(struct iio_device *dev) { unsigned int i; - for (i = 0; i < dev->nb_attrs; i++) - free(dev->attrs[i]); - if (dev->nb_attrs) - free(dev->attrs); - for (i = 0; i < dev->nb_buffer_attrs; i++) - free(dev->buffer_attrs[i]); - if (dev->nb_buffer_attrs) - free(dev->buffer_attrs); - for (i = 0; i < dev->nb_debug_attrs; i++) - free(dev->debug_attrs[i]); - if (dev->nb_debug_attrs) - free(dev->debug_attrs); + + free_iio_dev_attrs(&dev->attrs); + free_iio_dev_attrs(&dev->buffer_attrs); + free_iio_dev_attrs(&dev->debug_attrs); + for (i = 0; i < dev->nb_channels; i++) free_channel(dev->channels[i]); - if (dev->nb_channels) - free(dev->channels); - if (dev->mask) - free(dev->mask); - if (dev->name) - free(dev->name); - if (dev->id) - free(dev->id); + free(dev->channels); + free(dev->mask); + free(dev->label); + free(dev->name); + free(dev->id); free(dev); } @@ -795,16 +660,13 @@ unsigned int iio_device_get_debug_attrs_count(const struct iio_device *dev) { - return dev->nb_debug_attrs; + return dev->debug_attrs.num; } const char * iio_device_get_debug_attr(const struct iio_device *dev, unsigned int index) { - if (index >= dev->nb_debug_attrs) - return NULL; - else - return dev->debug_attrs[index]; + return iio_device_get_dev_attr(&dev->debug_attrs, index); } int iio_device_debug_attr_read_longlong(const struct iio_device *dev, @@ -903,18 +765,18 @@ } } - for (i = 0; i < dev->nb_attrs; i++) { + for (i = 0; i < dev->attrs.num; i++) { /* Devices attributes are named after their filename */ - if (!strcmp(dev->attrs[i], filename)) { - *attr = dev->attrs[i]; + if (!strcmp(dev->attrs.names[i], filename)) { + *attr = dev->attrs.names[i]; *chn = NULL; return 0; } } - for (i = 0; i < dev->nb_debug_attrs; i++) { - if (!strcmp(dev->debug_attrs[i], filename)) { - *attr = dev->debug_attrs[i]; + for (i = 0; i < dev->debug_attrs.num; i++) { + if (!strcmp(dev->debug_attrs.names[i], filename)) { + *attr = dev->debug_attrs.names[i]; *chn = NULL; return 0; } diff -Nru libiio-0.21/dns_sd_avahi.c libiio-0.23/dns_sd_avahi.c --- libiio-0.21/dns_sd_avahi.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/dns_sd_avahi.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * @@ -5,59 +6,84 @@ * Author: Paul Cercueil * Robin Getz * - * 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. - * * Some of this is insipred from libavahi's example: * https://avahi.org/doxygen/html/client-browse-services_8c-example.html * which is also LGPL 2.1 or later. - * - * */ + */ +#include "debug.h" +#include "dns_sd.h" #include "iio-private.h" -#include "network.h" #include "iio-lock.h" +#include +#include #include - #include -#include "debug.h" + +#include +#include +#include +#include +#include +#include /* * Fundamentally, this builds up a linked list to manage * potential clients on the network */ -static int new_discovery_data(struct dns_sd_discovery_data **data) +static struct dns_sd_discovery_data *new_discovery_data(void) { struct dns_sd_discovery_data *d; - d = zalloc(sizeof(struct dns_sd_discovery_data)); + d = zalloc(sizeof(*d)); if (!d) - return -ENOMEM; + return NULL; - d->address = zalloc(sizeof(struct AvahiAddress)); + d->address = zalloc(sizeof(*d->address)); if (!d->address) { free(d); - return -ENOMEM; + return NULL; } - *data = d; - return 0; + return d; } -void dnssd_free_discovery_data(struct dns_sd_discovery_data *d) +static void avahi_process_resolved(struct dns_sd_discovery_data *ddata, + const AvahiAddress *addr, + const char *host_name, + const uint16_t port) { - free(d->hostname); - free(d->address); - free(d); + /* Avahi is multi-threaded, so lock the list */ + iio_mutex_lock(ddata->lock); + ddata->resolved++; + + /* Find empty data to store things*/ + while (ddata->next) + ddata = ddata->next; + + /* link a new placeholder to the list */ + avahi_address_snprint(ddata->addr_str, + sizeof(ddata->addr_str), addr); + memcpy(ddata->address, addr, sizeof(*ddata->address)); /* Flawfinder: ignore */ + ddata->port = port; + ddata->hostname = strdup(host_name); + ddata->resolved = true; + + /* link a new, empty placeholder to the list */ + ddata->next = new_discovery_data(); + if (ddata->next) { + /* duplicate poll & lock info, + * since we don't know which might be discarded */ + ddata->next->poll = ddata->poll; + ddata->next->lock = ddata->lock; + } else { + IIO_ERROR("Avahi Resolver : memory failure\n"); + } + iio_mutex_unlock(ddata->lock); + + IIO_DEBUG("\t\t%s:%u (%s)\n", host_name, port, ddata->addr_str); } /* @@ -67,14 +93,22 @@ */ static void __avahi_resolver_cb(AvahiServiceResolver *resolver, - __notused AvahiIfIndex iface, __notused AvahiProtocol proto, - AvahiResolverEvent event, const char *name, - const char *type, const char *domain, - const char *host_name, const AvahiAddress *address, - uint16_t port, AvahiStringList *txt, - __notused AvahiLookupResultFlags flags, void *d) + AvahiIfIndex iface, + AvahiProtocol proto, + AvahiResolverEvent event, + const char *name, + const char *type, + const char *domain, + const char *host_name, + const AvahiAddress *address, + uint16_t port, + AvahiStringList *txt, + AvahiLookupResultFlags flags, + void *d) { - struct dns_sd_discovery_data *ddata = (struct dns_sd_discovery_data *) d; + struct dns_sd_discovery_data *ddata = d; + AvahiClient *client; + int err; if (!resolver) { IIO_ERROR("Fatal Error in Avahi Resolver\n"); @@ -83,60 +117,71 @@ switch(event) { case AVAHI_RESOLVER_FAILURE: + client = avahi_service_resolver_get_client(resolver); + err = avahi_client_errno(client); + IIO_ERROR("Avahi Resolver: Failed resolve service '%s' " - "of type '%s' in domain '%s': %s\n", - name, type, domain, - avahi_strerror( - avahi_client_errno( - avahi_service_resolver_get_client( - resolver)))); + "of type '%s' in domain '%s': %s\n", + name, type, domain, + avahi_strerror(err)); break; case AVAHI_RESOLVER_FOUND: { - /* Avahi is multi-threaded, so lock the list */ - iio_mutex_lock(ddata->lock); - ddata->resolved++; - - /* Find empty data to store things*/ - while (ddata->next) - ddata = ddata->next; - - /* link a new placeholder to the list */ - avahi_address_snprint(ddata->addr_str, - sizeof(ddata->addr_str), address); - memcpy(ddata->address, address, sizeof(*address)); - ddata->port = port; - ddata->hostname = strdup(host_name); - ddata->resolved = true; - /* link a new, empty placeholder to the list */ - if (!new_discovery_data(&ddata->next)) { - /* duplicate poll & lock info, - * since we don't know which might be discarded */ - ddata->next->poll = ddata->poll; - ddata->next->lock = ddata->lock; - } else { - IIO_ERROR("Avahi Resolver : memory failure\n"); - } - iio_mutex_unlock(ddata->lock); - + avahi_process_resolved(ddata, address, host_name, port); IIO_DEBUG("Avahi Resolver : service '%s' of type '%s' in domain '%s':\n", - name, type, domain); - IIO_DEBUG("\t\t%s:%u (%s)\n", host_name, port, ddata->addr_str); - + name, type, domain); break; - } + } } avahi_service_resolver_free(resolver); } +static void avahi_host_resolver(AvahiHostNameResolver *resolver, + AvahiIfIndex iface, + AvahiProtocol proto, + AvahiResolverEvent event, + const char *host_name, + const AvahiAddress *address, + AvahiLookupResultFlags flags, + void *d) +{ + struct dns_sd_discovery_data *ddata = d; + AvahiClient *client; + int err; + + switch(event) { + case AVAHI_RESOLVER_FAILURE: + client = avahi_host_name_resolver_get_client(resolver); + err = avahi_client_errno(client); + + IIO_ERROR("Avahi Resolver: Failed to resolve host '%s' : %s\n", + host_name, avahi_strerror(err)); + break; + case AVAHI_RESOLVER_FOUND: + avahi_process_resolved(ddata, address, host_name, IIOD_PORT); + break; + } + + avahi_host_name_resolver_free(resolver); + avahi_simple_poll_quit(ddata->poll); +} + static void __avahi_browser_cb(AvahiServiceBrowser *browser, - AvahiIfIndex iface, AvahiProtocol proto, - AvahiBrowserEvent event, const char *name, - const char *type, const char *domain, - __notused AvahiLookupResultFlags flags, void *d) + AvahiIfIndex iface, + AvahiProtocol proto, + AvahiBrowserEvent event, + const char *name, + const char *type, + const char *domain, + AvahiLookupResultFlags flags, + void *d) { struct dns_sd_discovery_data *ddata = (struct dns_sd_discovery_data *) d; struct AvahiClient *client = avahi_service_browser_get_client(browser); - int i; + unsigned int i; + struct timespec ts; + + ts.tv_sec = 0; + ts.tv_nsec = 5e6; /* 5ms in ns */ if (!browser) { IIO_ERROR("Fatal Error in Avahi Browser\n"); @@ -145,18 +190,16 @@ switch (event) { case AVAHI_BROWSER_REMOVE: - IIO_DEBUG("Avahi Browser : REMOVE : " - "service '%s' of type '%s' in domain '%s'\n", - name, type, domain); + IIO_DEBUG("Avahi Browser : REMOVE : service '%s' of type '%s' in domain '%s'\n", + name, type, domain); break; case AVAHI_BROWSER_NEW: - IIO_DEBUG("Avahi Browser : NEW: " - "service '%s' of type '%s' in domain '%s'\n", - name, type, domain); + IIO_DEBUG("Avahi Browser : NEW: service '%s' of type '%s' in domain '%s'\n", + name, type, domain); if(!avahi_service_resolver_new(client, iface, - proto, name, type, domain, - AVAHI_PROTO_UNSPEC, 0, - __avahi_resolver_cb, d)) { + proto, name, type, domain, + AVAHI_PROTO_UNSPEC, 0, + __avahi_resolver_cb, d)) { IIO_ERROR("Failed to resolve service '%s\n", name); } else { iio_mutex_lock(ddata->lock); @@ -165,18 +208,13 @@ } break; case AVAHI_BROWSER_ALL_FOR_NOW: - /* Wait for a max of 1 second */ - i = 0; IIO_DEBUG("Avahi Browser : ALL_FOR_NOW Browser : %d, Resolved : %d\n", - ddata->found, ddata->resolved); + ddata->found, ddata->resolved); + /* 200 * 5ms = wait 1 second */ - while ((ddata->found != ddata->resolved) && i <= 200) { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 5e6; /* 5ms in ns*/ + for (i = 0; ddata->found != ddata->resolved && i <= 200; i++) nanosleep(&ts, NULL); - i++; - } + avahi_simple_poll_quit(ddata->poll); break; case AVAHI_BROWSER_FAILURE: @@ -202,7 +240,8 @@ AvahiServiceBrowser *browser; int ret = 0; - if (new_discovery_data(&d) < 0) + d = new_discovery_data(); + if (!d) return -ENOMEM; d->lock = iio_mutex_create(); @@ -213,25 +252,27 @@ d->poll = avahi_simple_poll_new(); if (!d->poll) { + iio_mutex_destroy(d->lock); dnssd_free_all_discovery_data(d); return -ENOMEM; } client = avahi_client_new(avahi_simple_poll_get(d->poll), - 0, NULL, NULL, &ret); + 0, NULL, NULL, &ret); if (!client) { IIO_ERROR("Unable to create Avahi DNS-SD client :%s\n", - avahi_strerror(ret)); + avahi_strerror(ret)); goto err_free_poll; } browser = avahi_service_browser_new(client, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, - "_iio._tcp", NULL, 0, __avahi_browser_cb, d); + AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + "_iio._tcp", NULL, 0, + __avahi_browser_cb, d); if (!browser) { ret = avahi_client_errno(client); IIO_ERROR("Unable to create Avahi DNS-SD browser: %s\n", - avahi_strerror(ret)); + avahi_strerror(ret)); goto err_free_client; } @@ -254,3 +295,94 @@ return ret; } + +static void avahi_resolve_host(struct dns_sd_discovery_data *d, + const char *hostname, + const AvahiProtocol proto) +{ + AvahiClient *client; + AvahiHostNameResolver *resolver; + int ret; + + d->poll = avahi_simple_poll_new(); + if (!d->poll) + return; + + client = avahi_client_new(avahi_simple_poll_get(d->poll), 0, NULL, NULL, &ret); + if (!client) { + IIO_ERROR("Unable to create Avahi DNS-SD client :%s\n", + avahi_strerror(ret)); + goto err_free_poll; + } + + resolver = avahi_host_name_resolver_new(client, AVAHI_IF_UNSPEC, proto, hostname, proto, 0, + avahi_host_resolver, d); + if (!resolver) { + ret = avahi_client_errno(client); + IIO_ERROR("Unable to create Avahi DNS-SD browser: %s\n", + avahi_strerror(ret)); + goto err_free_client; + } + + IIO_DEBUG("Trying to resolve host: %s, proto: %d\n", hostname, proto); + avahi_simple_poll_loop(d->poll); + +err_free_client: + avahi_client_free(client); +err_free_poll: + avahi_simple_poll_free(d->poll); +} + +int dnssd_resolve_host(const char *hostname, + char *ip_addr, + const int addr_len) +{ + struct dns_sd_discovery_data *d; + int ret = 0; + + if (!hostname || hostname[0] == '\0') + return -EINVAL; + + d = new_discovery_data(); + if (!d) + return -ENOMEM; + + d->lock = iio_mutex_create(); + if (!d->lock) { + ret = -ENOMEM; + goto err_free_data; + } + /* + * The reason not to use AVAHI_PROTO_UNSPEC is that avahi sometimes resolves the host + * to an ipv6 link local address which is not suitable to be used by connect. In fact, + * `port_knock_discovery_data()` would discard this entry. On the other hand, some users + * might really want to use ipv6 and have their environment correctly configured. Hence, + * we try to resolve both in ipv4 and ipv6... + */ + avahi_resolve_host(d, hostname, AVAHI_PROTO_INET); +#ifdef HAVE_IPV6 + avahi_resolve_host(d, hostname, AVAHI_PROTO_INET6); +#endif + + if (d->resolved) { + port_knock_discovery_data(&d); + remove_dup_discovery_data(&d); + } else { + ret = -ENXIO; + goto err_mutex_destroy; + } + + /* If next is null it means that d is empty */ + if (!d->next) { + ret = -ENXIO; + goto err_mutex_destroy; + } + + iio_strlcpy(ip_addr, d->addr_str, addr_len); + +err_mutex_destroy: + iio_mutex_destroy(d->lock); +err_free_data: + dnssd_free_all_discovery_data(d); + return ret; +} diff -Nru libiio-0.21/dns_sd_bonjour.c libiio-0.23/dns_sd_bonjour.c --- libiio-0.21/dns_sd_bonjour.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/dns_sd_bonjour.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,66 +1,52 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2020 Matej Kenda. * Author: Matej Kenda gmail.com> * Robin Getz - * - * 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. - * - * */ - -#include + */ +#include "debug.h" +#include "dns_sd.h" #include "iio-lock.h" #include "iio-private.h" -#include "network.h" -#include "debug.h" - -/* - Implementation for DNS SD discovery for macOS using CFNetServices. -*/ - -static int new_discovery_data(struct dns_sd_discovery_data **data) -{ - struct dns_sd_discovery_data *d; - - d = zalloc(sizeof(struct dns_sd_discovery_data)); - if (!d) - return -ENOMEM; - *data = d; - return 0; -} +#include +#include +#include -void dnssd_free_discovery_data(struct dns_sd_discovery_data *d) -{ - free(d->hostname); - free(d); -} +/* + * Implementation for DNS SD discovery for macOS using CFNetServices. + */ -static void __cfnet_browser_cb ( - CFNetServiceBrowserRef browser, - CFOptionFlags flags, - CFTypeRef domainOrService, - CFStreamError* error, - void* info) +static void __cfnet_browser_cb(CFNetServiceBrowserRef browser, + CFOptionFlags flags, + CFTypeRef domainOrService, + CFStreamError *error, + void *info) { - CFStreamError anError; + const CFNetServiceRef netService = (CFNetServiceRef)domainOrService; + struct dns_sd_discovery_data *dd = info; + char address_v4[DNS_SD_ADDRESS_STR_MAX+1] = ""; + char address_v6[DNS_SD_ADDRESS_STR_MAX+1] = ""; + char hostname[MAXHOSTNAMELEN]; + char name[MAXHOSTNAMELEN]; + bool have_v4 = false; + bool have_v6 = false; + struct sockaddr_in *sa; + CFStreamError anError; + CFStringRef targetHost; + CFStringRef svcName; + CFArrayRef addrArr; + CFDataRef data; + SInt32 port; if ((flags & kCFNetServiceFlagIsDomain) != 0) { IIO_ERROR("DNS SD: FATAL! Callback called for domain, not service.\n"); goto stop_browsing; } - - struct dns_sd_discovery_data *dd = (struct dns_sd_discovery_data *)info; + if (dd == NULL) { IIO_ERROR("DNS SD: Missing info structure. Stop browsing.\n"); goto stop_browsing; @@ -73,67 +59,65 @@ iio_mutex_lock(dd->lock); - const CFNetServiceRef netService = (CFNetServiceRef)domainOrService; if (netService == NULL) { IIO_DEBUG("DNS SD: Net service is null.\n"); goto verify_flags; } - + if (!CFNetServiceResolveWithTimeout(netService, 10.0, &anError)) { - IIO_DEBUG("DNS SD: Resolve error: %ld.%d\n", anError.domain, anError.error); + IIO_DEBUG("DNS SD: Resolve error: %ld.%d\n", + anError.domain, anError.error); goto exit; } - - CFStringRef targetHost = CFNetServiceGetTargetHost(netService); + + targetHost = CFNetServiceGetTargetHost(netService); if (targetHost == NULL) { IIO_DEBUG("DNS SD: No valid target host for service.\n"); goto exit; } - char hostname[MAXHOSTNAMELEN]; - if (!CFStringGetCString(targetHost, hostname, sizeof(hostname), kCFStringEncodingASCII)) { + if (!CFStringGetCString(targetHost, hostname, + sizeof(hostname), kCFStringEncodingASCII)) { IIO_ERROR("DNS SD: Could not translate hostname\n"); goto exit; } - CFStringRef svcName = CFNetServiceGetName(netService); - char name[MAXHOSTNAMELEN]; - if (!CFStringGetCString(svcName, name, sizeof(name), kCFStringEncodingASCII)) { + svcName = CFNetServiceGetName(netService); + if (!CFStringGetCString(svcName, name, + sizeof(name), kCFStringEncodingASCII)) { IIO_ERROR("DNS SD: Could not translate service name\n"); goto exit; } - SInt32 port = CFNetServiceGetPortNumber(netService); - - CFArrayRef addrArr = CFNetServiceGetAddressing(netService); + port = CFNetServiceGetPortNumber(netService); + addrArr = CFNetServiceGetAddressing(netService); if (addrArr == NULL) { - IIO_WARNING("DNS SD: No valid addresses for service %s.\n", name); + IIO_WARNING("DNS SD: No valid addresses for service %s.\n", + name); goto exit; } - - bool have_v4 = FALSE; - bool have_v6 = FALSE; - char address_v4[DNS_SD_ADDRESS_STR_MAX+1] = ""; - char address_v6[DNS_SD_ADDRESS_STR_MAX+1] = ""; + for (CFIndex i = 0; i < CFArrayGetCount(addrArr); i++) { - struct sockaddr_in *sa = (struct sockaddr_in *) - CFDataGetBytePtr(CFArrayGetValueAtIndex(addrArr, i)); + data = CFArrayGetValueAtIndex(addrArr, i); + sa = (struct sockaddr_in *) CFDataGetBytePtr(data); + switch(sa->sin_family) { - case AF_INET: - if (inet_ntop(sa->sin_family, &sa->sin_addr, - address_v4, sizeof(address_v4))) { - have_v4 = TRUE; - } - case AF_INET6: - if (inet_ntop(sa->sin_family, &sa->sin_addr, - address_v6, sizeof(address_v6))) { - have_v6 = TRUE; - } + case AF_INET: + if (inet_ntop(sa->sin_family, &sa->sin_addr, + address_v4, sizeof(address_v4))) { + have_v4 = true; + } + case AF_INET6: + if (inet_ntop(sa->sin_family, &sa->sin_addr, + address_v6, sizeof(address_v6))) { + have_v6 = true; + } } } if (!have_v4 && !have_v6) { - IIO_WARNING("DNS SD: Can't resolve valid address for service %s.\n", name); + IIO_WARNING("DNS SD: Can't resolve valid address for " + "service %s.\n", name); goto exit; } @@ -143,17 +127,18 @@ dd->port = port; dd->hostname = strdup(hostname); - if (have_v4) { + + if (have_v4) iio_strlcpy(dd->addr_str, address_v4, sizeof(dd->addr_str)); - } else if(have_v6) { + else if(have_v6) iio_strlcpy(dd->addr_str, address_v6, sizeof(dd->addr_str)); - } IIO_DEBUG("DNS SD: added %s (%s:%d)\n", hostname, dd->addr_str, port); if (have_v4 || have_v6) { - // A list entry was filled, prepare new item on the list. - if (!new_discovery_data(&dd->next)) { + /* A list entry was filled, prepare new item on the list. */ + dd->next = zalloc(sizeof(*dd->next)); + if (dd->next) { /* duplicate lock */ dd->next->lock = dd->lock; } else { @@ -175,16 +160,24 @@ CFNetServiceBrowserStopSearch(browser, &anError); } -int dnssd_find_hosts(struct dns_sd_discovery_data ** ddata) +int dnssd_find_hosts(struct dns_sd_discovery_data **ddata) { - int ret = 0; + CFNetServiceClientContext clientContext = { 0 }; + CFNetServiceBrowserRef serviceBrowser; struct dns_sd_discovery_data *d; + CFRunLoopRunResult runRes; + CFRunLoopRef runLoop; + CFStringRef type; + CFStringRef domain; + CFStreamError error; + Boolean result; + int ret = 0; IIO_DEBUG("DNS SD: Start service discovery.\n"); - if (new_discovery_data(&d) < 0) { + d = zalloc(sizeof(*d)); + if (!d) return -ENOMEM; - } d->lock = iio_mutex_create(); if (!d->lock) { @@ -192,9 +185,10 @@ return -ENOMEM; } - CFNetServiceClientContext clientContext = { 0, d, NULL, NULL, NULL }; - CFNetServiceBrowserRef serviceBrowser = CFNetServiceBrowserCreate( - kCFAllocatorDefault, __cfnet_browser_cb, &clientContext); + clientContext.info = d; + serviceBrowser = CFNetServiceBrowserCreate(kCFAllocatorDefault, + __cfnet_browser_cb, + &clientContext); if (serviceBrowser == NULL) { IIO_ERROR("DNS SD: Failed to create service browser.\n"); @@ -203,34 +197,43 @@ goto exit; } - CFRunLoopRef runLoop = CFRunLoopGetCurrent(); - CFNetServiceBrowserScheduleWithRunLoop(serviceBrowser, runLoop, kCFRunLoopDefaultMode); - - CFStringRef type = CFSTR("_iio._tcp."); - CFStringRef domain = CFSTR(""); - CFStreamError error; - Boolean result = CFNetServiceBrowserSearchForServices(serviceBrowser, domain, type, &error); + runLoop = CFRunLoopGetCurrent(); + CFNetServiceBrowserScheduleWithRunLoop(serviceBrowser, runLoop, + kCFRunLoopDefaultMode); + + type = CFSTR("_iio._tcp."); + domain = CFSTR(""); + result = CFNetServiceBrowserSearchForServices(serviceBrowser, + domain, type, &error); if (result == false) { - IIO_ERROR("DNS SD: CFNetServiceBrowserSearchForServices failed (domain = %ld, error = %d)\n", - (long)error.domain, error.error); + IIO_ERROR("DNS SD: CFNetServiceBrowserSearchForServices " + "failed (domain = %ld, error = %d)\n", + (long)error.domain, error.error); ret = -ENXIO; } else { - CFRunLoopRunResult runRes = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2, TRUE); + runRes = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 2, true); if (runRes != kCFRunLoopRunHandledSource && runRes != kCFRunLoopRunTimedOut) { - if (runRes == kCFRunLoopRunFinished) - IIO_ERROR("DSN SD: CFRunLoopRunInMode completed kCFRunLoopRunFinished (%d)\n", runRes); - else if (runRes == kCFRunLoopRunStopped) - IIO_ERROR("DSN SD: CFRunLoopRunInMode completed kCFRunLoopRunStopped (%d)\n", runRes); - else - IIO_ERROR("DSN SD: CFRunLoopRunInMode completed for unknown reason (%d)\n", runRes); + if (runRes == kCFRunLoopRunFinished) { + IIO_ERROR("DNS SD: CFRunLoopRunInMode completed " + "kCFRunLoopRunFinished (%d)\n", runRes); + } else if (runRes == kCFRunLoopRunStopped) { + IIO_ERROR("DNS SD: CFRunLoopRunInMode completed " + "kCFRunLoopRunStopped (%d)\n", runRes); + } else { + IIO_ERROR("DNS SD: CFRunLoopRunInMode completed " + "for unknown reason (%d)\n", runRes); + } } else { - if (runRes == kCFRunLoopRunHandledSource) - IIO_DEBUG("DSN SD: CFRunLoopRunInMode completed kCFRunLoopRunHandledSource (%d)\n", runRes); - else - IIO_DEBUG("DSN SD: CFRunLoopRunInMode completed kCFRunLoopRunTimedOut (%d)\n", runRes); + if (runRes == kCFRunLoopRunHandledSource) { + IIO_DEBUG("DNS SD: CFRunLoopRunInMode completed " + "kCFRunLoopRunHandledSource (%d)\n", runRes); + } else { + IIO_DEBUG("DNS SD: CFRunLoopRunInMode completed " + "kCFRunLoopRunTimedOut (%d)\n", runRes); + } } port_knock_discovery_data(&d); @@ -242,9 +245,15 @@ CFRelease(serviceBrowser); serviceBrowser = NULL; - IIO_DEBUG("DNS SD: Completed service discovery, return code : %d\n", ret); + IIO_DEBUG("DNS SD: Completed service discovery, " + "return code : %d\n", ret); exit: iio_mutex_destroy(d->lock); return ret; } + +int dnssd_resolve_host(const char *hostname, char *ip_addr, const int addr_len) +{ + return -ENOENT; +} diff -Nru libiio-0.21/dns_sd.c libiio-0.23/dns_sd.c --- libiio-0.21/dns_sd.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/dns_sd.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * @@ -5,27 +6,38 @@ * Author: Robin Getz * Matej Kenda * - * 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. - * * Some of this is insipred from libavahi's example: * https://avahi.org/doxygen/html/client-browse-services_8c-example.html * which is also LGPL 2.1 or later. - * - * */ + */ +#include "debug.h" +#include "dns_sd.h" #include "iio-lock.h" #include "iio-private.h" -#include "network.h" -#include "debug.h" +#include +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +#ifdef _WIN32 +#define close(s) closesocket(s) +#endif + +static void dnssd_free_discovery_data(struct dns_sd_discovery_data *d) +{ + free(d->hostname); + free(d->address); + free(d); +} /* Some functions for handling common linked list operations */ static void dnssd_remove_node(struct dns_sd_discovery_data **ddata, int n) @@ -65,10 +77,6 @@ * DNS Service Discovery is turned on */ -struct iio_scan_backend_context { - struct addrinfo *res; -}; - static int dnssd_fill_context_info(struct iio_context_info *info, char *hostname, char *addr_str, int port) { @@ -99,15 +107,17 @@ iio_snprintf(description, sizeof(description), "%s %s", addr_str, hw_model); } else if (serial) { iio_snprintf(description, sizeof(description), "%s %s", addr_str, serial); - } else if (ctx->nb_devices == 0) { + } else if (iio_context_get_devices_count(ctx) == 0) { iio_snprintf(description, sizeof(description), "%s", ctx->description); } else { iio_snprintf(description, sizeof(description), "%s (", addr_str); p = description + strlen(description); - for (i = 0; i < ctx->nb_devices - 1; i++) { - if (ctx->devices[i]->name) { + for (i = 0; i < iio_context_get_devices_count(ctx) - 1; i++) { + const struct iio_device *dev = iio_context_get_device(ctx, i); + const char *name = iio_device_get_name(dev); + if (name) { iio_snprintf(p, sizeof(description) - strlen(description) -1, - "%s,", ctx->devices[i]->name); + "%s,", name); p += strlen(p); } } @@ -130,24 +140,6 @@ return 0; } -struct iio_scan_backend_context * dnssd_context_scan_init(void) -{ - struct iio_scan_backend_context *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) { - errno = ENOMEM; - return NULL; - } - - return ctx; -} - -void dnssd_context_scan_free(struct iio_scan_backend_context *ctx) -{ - free(ctx); -} - /* * remove the ones in the list that you can't connect to * This is sort of silly, but we have seen non-iio devices advertised @@ -180,7 +172,7 @@ gai_strerror(ret)); } else { for (rp = res; rp != NULL; rp = rp->ai_next) { - fd = create_socket(rp, DEFAULT_TIMEOUT_MS); + fd = create_socket(rp); if (fd < 0) { IIO_DEBUG("Unable to open %s%s socket ('%s:%d' %s)\n", rp->ai_family == AF_INET ? "ipv4" : "", @@ -241,11 +233,10 @@ *ddata = d; } -int dnssd_context_scan(struct iio_scan_backend_context *ctx, - struct iio_scan_result *scan_result) +int dnssd_context_scan(struct iio_scan_result *scan_result) { - struct iio_context_info **info; struct dns_sd_discovery_data *ddata, *ndata; + struct iio_context_info *info; int ret = 0; ret = dnssd_find_hosts(&ddata); @@ -260,14 +251,14 @@ goto fail; for (ndata = ddata; ndata->next != NULL; ndata = ndata->next) { - info = iio_scan_result_add(scan_result, 1); + info = iio_scan_result_add(scan_result); if (!info) { IIO_ERROR("Out of memory when adding new scan result\n"); ret = -ENOMEM; break; } - ret = dnssd_fill_context_info(*info, + ret = dnssd_fill_context_info(info, ndata->hostname, ndata->addr_str,ndata->port); if (ret < 0) { IIO_DEBUG("Failed to add %s (%s) err: %d\n", ndata->hostname, ndata->addr_str, ret); diff -Nru libiio-0.21/dns_sd.h libiio-0.23/dns_sd.h --- libiio-0.21/dns_sd.h 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/dns_sd.h 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2014-2020 Analog Devices, Inc. + * Author: Paul Cercueil + * Robin Getz + */ + +#ifndef __IIO_DNS_SD_H +#define __IIO_DNS_SD_H + +#include +#include + +#ifdef _WIN32 +#include +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN (MAX_COMPUTERNAME_LENGTH+1) +#endif /* MAXHOSTNAMELEN */ +#else +#include +#endif + +#define DNS_SD_ADDRESS_STR_MAX (40) /* IPv6 Max = 4*8 + 7 + 1 for NUL */ + +/* MacOS doesn't include ENOMEDIUM (No medium found) like Linux does */ +#ifndef ENOMEDIUM +#define ENOMEDIUM ENOENT +#endif + +/* Used everywhere */ +#define IIOD_PORT 30431 + +struct addrinfo; +struct AvahiSimplePoll; +struct AvahiAddress; + +/* Common structure which all dns_sd_[*] files fill out + * Anything that is dynamically allocated (malloc) needs to be managed + */ +struct dns_sd_discovery_data { + struct iio_mutex *lock; + struct AvahiSimplePoll *poll; + struct AvahiAddress *address; + uint16_t found, resolved; + char addr_str[DNS_SD_ADDRESS_STR_MAX]; + char *hostname; + uint16_t port; + struct dns_sd_discovery_data *next; +}; + + +/* This functions is implemented in network.c, but used in dns_sd.c + */ +int create_socket(const struct addrinfo *addrinfo); + +/* These functions are common, and implemented in dns_sd_[*].c based on the + * implementations: avahi (linux), bonjour (mac), or ServiceDiscovery (Win10) + */ + +/* Resolves all IIO hosts on the available networks, and passes back a linked list */ +int dnssd_find_hosts(struct dns_sd_discovery_data ** ddata); + +/* Deallocates complete list of discovery data */ +void dnssd_free_all_discovery_data(struct dns_sd_discovery_data *d); + +/* These functions are common, and found in dns_sd.c, but are used in the + * dns_sd_[*].c implementations or network.c + */ + +/* Passed back the first (random) IIOD service resolved by DNS DS. */ +int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port); + +/* remove duplicates from the list */ +void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata); + +/* port knocks */ +void port_knock_discovery_data(struct dns_sd_discovery_data **ddata); + +/* Use dnssd to resolve a given hostname */ +int dnssd_resolve_host(const char *hostname, char *ip_addr, const int addr_len); + +#endif /* __IIO_DNS_SD_H */ diff -Nru libiio-0.21/dns_sd_windows.c libiio-0.23/dns_sd_windows.c --- libiio-0.21/dns_sd_windows.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/dns_sd_windows.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2020 Analog Devices, Inc. * Author: Adrian Suciu * - * 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. - * * Based on https://github.com/mjansson/mdns/blob/ce2e4f789f06429008925ff8f18c22036e60201e/mdns.c * which is Licensed under Public Domain */ @@ -23,53 +14,65 @@ #include #include +#include "debug.h" +#include "dns_sd.h" #include "iio-private.h" #include "mdns.h" -#include "network.h" -#include "debug.h" -static int new_discovery_data(struct dns_sd_discovery_data** data) -{ - struct dns_sd_discovery_data* d; +#ifdef HAVE_IPV6 +static const unsigned char localhost[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1 +}; +static const unsigned char localhost_mapped[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1 +}; - d = zalloc(sizeof(struct dns_sd_discovery_data)); - if (!d) - return -ENOMEM; +static bool is_localhost6(const struct sockaddr_in6 *saddr6) +{ + const uint8_t *addr = saddr6->sin6_addr.s6_addr; - *data = d; - return 0; + return !memcmp(addr, localhost, sizeof(localhost)) || + !memcmp(addr, localhost_mapped, sizeof(localhost_mapped)); } +#endif -void dnssd_free_discovery_data(struct dns_sd_discovery_data* d) +static bool is_localhost4(const struct sockaddr_in *saddr) { - free(d->hostname); - free(d); + return saddr->sin_addr.S_un.S_un_b.s_b1 == 127 && + saddr->sin_addr.S_un.S_un_b.s_b2 == 0 && + saddr->sin_addr.S_un.S_un_b.s_b3 == 0 && + saddr->sin_addr.S_un.S_un_b.s_b4 == 1; } -static int -open_client_sockets(int* sockets, int max_sockets) { - // When sending, each socket can only send to one network interface - // Thus we need to open one socket for each interface and address family - int num_sockets = 0; - - IP_ADAPTER_ADDRESSES* adapter_address = 0; +static int open_client_sockets(int *sockets, unsigned int max_sockets) +{ + IP_ADAPTER_UNICAST_ADDRESS *unicast; + IP_ADAPTER_ADDRESSES *adapter_address = 0; + PIP_ADAPTER_ADDRESSES adapter; ULONG address_size = 8000; - unsigned int ret; - unsigned int num_retries = 4; + unsigned int i, ret, num_retries = 4, num_sockets = 0; + struct sockaddr_in *saddr; + unsigned long param = 1; + int sock; + + /* When sending, each socket can only send to one network interface + * Thus we need to open one socket for each interface and address family */ + do { adapter_address = malloc(address_size); - if (adapter_address == NULL) { + if (!adapter_address) return -ENOMEM; - } - ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST, 0, - adapter_address, &address_size); - if (ret == ERROR_BUFFER_OVERFLOW) { - free(adapter_address); - adapter_address = 0; - } - else { + + ret = GetAdaptersAddresses(AF_UNSPEC, + GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST, 0, + adapter_address, &address_size); + if (ret != ERROR_BUFFER_OVERFLOW) break; - } + + free(adapter_address); + adapter_address = 0; } while (num_retries-- > 0); if (!adapter_address || (ret != NO_ERROR)) { @@ -78,44 +81,36 @@ return num_sockets; } - for (PIP_ADAPTER_ADDRESSES adapter = adapter_address; adapter; adapter = adapter->Next) { + for (adapter = adapter_address; adapter; adapter = adapter->Next) { if (adapter->TunnelType == TUNNEL_TYPE_TEREDO) continue; if (adapter->OperStatus != IfOperStatusUp) continue; - for (IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress; unicast; - unicast = unicast->Next) { + for (unicast = adapter->FirstUnicastAddress; + unicast; unicast = unicast->Next) { if (unicast->Address.lpSockaddr->sa_family == AF_INET) { - struct sockaddr_in* saddr = (struct sockaddr_in*)unicast->Address.lpSockaddr; - if ((saddr->sin_addr.S_un.S_un_b.s_b1 != 127) || - (saddr->sin_addr.S_un.S_un_b.s_b2 != 0) || - (saddr->sin_addr.S_un.S_un_b.s_b3 != 0) || - (saddr->sin_addr.S_un.S_un_b.s_b4 != 1)) { - if (num_sockets < max_sockets) { - int sock = mdns_socket_open_ipv4(saddr); - if (sock >= 0) { - sockets[num_sockets++] = sock; - } - } + saddr = (struct sockaddr_in *)unicast->Address.lpSockaddr; + + if (!is_localhost4(saddr) && + num_sockets < max_sockets) { + sock = mdns_socket_open_ipv4(saddr); + if (sock >= 0) + sockets[num_sockets++] = sock; } } #ifdef HAVE_IPV6 else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) { - struct sockaddr_in6* saddr = (struct sockaddr_in6*)unicast->Address.lpSockaddr; - static const unsigned char localhost[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1 }; - static const unsigned char localhost_mapped[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1 }; - if ((unicast->DadState == NldsPreferred) && - memcmp(saddr->sin6_addr.s6_addr, localhost, 16) && - memcmp(saddr->sin6_addr.s6_addr, localhost_mapped, 16)) { - if (num_sockets < max_sockets) { - int sock = mdns_socket_open_ipv6(saddr); - if (sock >= 0) { - sockets[num_sockets++] = sock; - } - } + struct sockaddr_in6 *saddr6; + + saddr6 = (struct sockaddr_in6 *)unicast->Address.lpSockaddr; + + if (unicast->DadState == NldsPreferred && + !is_localhost6(saddr6) && + num_sockets < max_sockets) { + sock = mdns_socket_open_ipv6(saddr6); + if (sock >= 0) + sockets[num_sockets++] = sock; } } #endif @@ -124,28 +119,27 @@ free(adapter_address); - for (int isock = 0; isock < num_sockets; ++isock) { - unsigned long param = 1; - ioctlsocket(sockets[isock], FIONBIO, ¶m); - } + for (i = 0; i < num_sockets; i++) + ioctlsocket(sockets[i], FIONBIO, ¶m); return num_sockets; } -static int -query_callback(int sock, const struct sockaddr* from, size_t addrlen, - mdns_entry_type_t entry, uint16_t transaction_id, - uint16_t rtype, uint16_t rclass, uint32_t ttl, - const void* data, size_t size, size_t offset, size_t length, - void* user_data) { - +static int query_callback(int sock, const struct sockaddr *from, size_t addrlen, + mdns_entry_type_t entry, uint16_t transaction_id, + uint16_t rtype, uint16_t rclass, uint32_t ttl, + const void *data, size_t size, size_t offset, + size_t length, + void *user_data) +{ + struct dns_sd_discovery_data *dd = user_data; char addrbuffer[64]; char servicebuffer[64]; char namebuffer[256]; + mdns_record_srv_t srv; - struct dns_sd_discovery_data* dd = (struct dns_sd_discovery_data*)user_data; - if (dd == NULL) { + if (!dd) { IIO_ERROR("DNS SD: Missing info structure. Stop browsing.\n"); goto quit; } @@ -153,113 +147,134 @@ if (rtype != MDNS_RECORDTYPE_SRV) goto quit; - getnameinfo((const struct sockaddr*)from, (socklen_t)addrlen, - addrbuffer, NI_MAXHOST, servicebuffer, NI_MAXSERV, - NI_NUMERICSERV | NI_NUMERICHOST); - - mdns_record_srv_t srv = mdns_record_parse_srv(data, size, offset, length, - namebuffer, sizeof(namebuffer)); - IIO_DEBUG("%s : SRV %.*s priority %d weight %d port %d\n", - addrbuffer, - MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); + getnameinfo(from, (socklen_t)addrlen, addrbuffer, NI_MAXHOST, + servicebuffer, NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST); + + srv = mdns_record_parse_srv(data, size, offset, length, + namebuffer, sizeof(namebuffer)); + IIO_DEBUG("%s : SRV %.*s priority %d weight %d port %d\n", addrbuffer, + MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); - // Go to the last element in the list - while (dd->next != NULL) + /* Go to the last element in the list */ + while (dd->next) dd = dd->next; if (srv.name.length > 1) { dd->hostname = malloc(srv.name.length); - if (dd->hostname == NULL) { + if (!dd->hostname) return -ENOMEM; - } + iio_strlcpy(dd->hostname, srv.name.str, srv.name.length); } + iio_strlcpy(dd->addr_str, addrbuffer, DNS_SD_ADDRESS_STR_MAX); dd->port = srv.port; - IIO_DEBUG("DNS SD: added %s (%s:%d)\n", dd->hostname, dd->addr_str, dd->port); - // A list entry was filled, prepare new item on the list. - if (new_discovery_data(&dd->next)) { + IIO_DEBUG("DNS SD: added %s (%s:%d)\n", + dd->hostname, dd->addr_str, dd->port); + + /* A list entry was filled, prepare new item on the list */ + dd->next = zalloc(sizeof(*dd->next)); + if (!dd->next) IIO_ERROR("DNS SD mDNS Resolver : memory failure\n"); - } quit: return 0; } -int dnssd_find_hosts(struct dns_sd_discovery_data** ddata) +int dnssd_find_hosts(struct dns_sd_discovery_data **ddata) { - WORD versionWanted = MAKEWORD(1, 1); WSADATA wsaData; + const char service[] = "_iio._tcp.local"; + size_t records, capacity = 2048; + unsigned int i, isock, num_sockets; + void *buffer; + int sockets[32]; + int transaction_id[32]; + int ret = -ENOMEM; + if (WSAStartup(versionWanted, &wsaData)) { printf("Failed to initialize WinSock\n"); - return -1; + return -WSAGetLastError(); } - struct dns_sd_discovery_data* d; - IIO_DEBUG("DNS SD: Start service discovery.\n"); - if (new_discovery_data(&d) < 0) { - return -ENOMEM; - } - *ddata = d; + *ddata = zalloc(sizeof(**ddata)); + if (!*ddata) + goto out_wsa_cleanup; - size_t capacity = 2048; - void* buffer = malloc(capacity); - if (buffer == NULL) { - return -ENOMEM; - } - const char service[] = "_iio._tcp.local"; + + buffer = malloc(capacity); + if (!buffer) + goto out_wsa_cleanup; IIO_DEBUG("Sending DNS-SD discovery\n"); - int sockets[32]; - int transaction_id[32]; - int num_sockets = open_client_sockets(sockets, sizeof(sockets) / sizeof(sockets[0])); - if (num_sockets <= 0) { + ret = open_client_sockets(sockets, ARRAY_SIZE(sockets)); + if (ret <= 0) { IIO_ERROR("Failed to open any client sockets\n"); - return -1; + goto out_free_buffer; } - IIO_DEBUG("Opened %d socket%s for mDNS query\n", num_sockets, num_sockets ? "s" : ""); + + num_sockets = (unsigned int)ret; + IIO_DEBUG("Opened %d socket%s for mDNS query\n", + num_sockets, (num_sockets > 1) ? "s" : ""); IIO_DEBUG("Sending mDNS query: %s\n", service); - for (int isock = 0; isock < num_sockets; ++isock) { - transaction_id[isock] = mdns_query_send(sockets[isock], MDNS_RECORDTYPE_PTR, service, sizeof(service)-1, buffer, - capacity); - if (transaction_id[isock] <= 0) - { + + for (isock = 0; isock < num_sockets; isock++) { + ret = mdns_query_send(sockets[isock], MDNS_RECORDTYPE_PTR, + service, sizeof(service)-1, buffer, + capacity); + if (ret <= 0) IIO_ERROR("Failed to send mDNS query: errno %d\n", errno); - } + + transaction_id[isock] = ret; } - // This is a simple implementation that loops for 10 seconds or as long as we get replies - // A real world implementation would probably use select, poll or similar syscall to wait - // until data is available on a socket and then read it + /* This is a simple implementation that loops for 10 seconds or as long as we get replies + * A real world implementation would probably use select, poll or similar syscall to wait + * until data is available on a socket and then read it */ IIO_DEBUG("Reading mDNS query replies\n"); - for (int i = 0; i < 10; ++i) { - size_t records; + + for (i = 0; i < 10; i++) { do { records = 0; - for (int isock = 0; isock < num_sockets; ++isock) { - if (transaction_id[isock] > 0) - records += - mdns_query_recv(sockets[isock], buffer, capacity, query_callback, d, transaction_id[isock]); + + for (isock = 0; isock < num_sockets; isock++) { + if (transaction_id[isock] <= 0) + continue; + + records += mdns_query_recv(sockets[isock], + buffer, capacity, + query_callback, *ddata, + transaction_id[isock]); } } while (records); + if (records) i = 0; + Sleep(100); } - free(buffer); - for (int isock = 0; isock < num_sockets; ++isock) + for (isock = 0; isock < num_sockets; ++isock) mdns_socket_close(sockets[isock]); - IIO_DEBUG("Closed socket%s\n", num_sockets ? "s" : ""); + IIO_DEBUG("Closed socket%s\n", (num_sockets > 1) ? "s" : ""); + + ret = 0; +out_free_buffer: + free(buffer); +out_wsa_cleanup: WSACleanup(); + return ret; +} - return 0; +int dnssd_resolve_host(const char *hostname, char *ip_addr, const int addr_len) +{ + return -ENOENT; } diff -Nru libiio-0.21/examples/ad9361-iiostream.c libiio-0.23/examples/ad9361-iiostream.c --- libiio-0.21/examples/ad9361-iiostream.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/ad9361-iiostream.c 2021-08-20 11:01:14.000000000 +0000 @@ -111,7 +111,7 @@ } /* returns ad9361 phy device */ -static struct iio_device* get_ad9361_phy(struct iio_context *ctx) +static struct iio_device* get_ad9361_phy(void) { struct iio_device *dev = iio_context_find_device(ctx, "ad9361-phy"); IIO_ENSURE(dev && "No ad9361-phy found"); @@ -119,7 +119,7 @@ } /* finds AD9361 streaming IIO devices */ -static bool get_ad9361_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) +static bool get_ad9361_stream_dev(enum iodev d, struct iio_device **dev) { switch (d) { case TX: *dev = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc"); return *dev != NULL; @@ -129,7 +129,7 @@ } /* finds AD9361 streaming IIO channels */ -static bool get_ad9361_stream_ch(__notused struct iio_context *ctx, enum iodev d, struct iio_device *dev, int chid, struct iio_channel **chn) +static bool get_ad9361_stream_ch(enum iodev d, struct iio_device *dev, int chid, struct iio_channel **chn) { *chn = iio_device_find_channel(dev, get_ch_name("voltage", chid), d == TX); if (!*chn) @@ -138,51 +138,51 @@ } /* finds AD9361 phy IIO configuration channel with id chid */ -static bool get_phy_chan(struct iio_context *ctx, enum iodev d, int chid, struct iio_channel **chn) +static bool get_phy_chan(enum iodev d, int chid, struct iio_channel **chn) { switch (d) { - case RX: *chn = iio_device_find_channel(get_ad9361_phy(ctx), get_ch_name("voltage", chid), false); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9361_phy(ctx), get_ch_name("voltage", chid), true); return *chn != NULL; + case RX: *chn = iio_device_find_channel(get_ad9361_phy(), get_ch_name("voltage", chid), false); return *chn != NULL; + case TX: *chn = iio_device_find_channel(get_ad9361_phy(), get_ch_name("voltage", chid), true); return *chn != NULL; default: IIO_ENSURE(0); return false; } } /* finds AD9361 local oscillator IIO configuration channels */ -static bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn) +static bool get_lo_chan(enum iodev d, struct iio_channel **chn) { switch (d) { // LO chan is always output, i.e. true - case RX: *chn = iio_device_find_channel(get_ad9361_phy(ctx), get_ch_name("altvoltage", 0), true); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9361_phy(ctx), get_ch_name("altvoltage", 1), true); return *chn != NULL; + case RX: *chn = iio_device_find_channel(get_ad9361_phy(), get_ch_name("altvoltage", 0), true); return *chn != NULL; + case TX: *chn = iio_device_find_channel(get_ad9361_phy(), get_ch_name("altvoltage", 1), true); return *chn != NULL; default: IIO_ENSURE(0); return false; } } /* applies streaming configuration through IIO */ -bool cfg_ad9361_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid) +bool cfg_ad9361_streaming_ch(struct stream_cfg *cfg, enum iodev type, int chid) { struct iio_channel *chn = NULL; // Configure phy and lo channels printf("* Acquiring AD9361 phy channel %d\n", chid); - if (!get_phy_chan(ctx, type, chid, &chn)) { return false; } + if (!get_phy_chan(type, chid, &chn)) { return false; } wr_ch_str(chn, "rf_port_select", cfg->rfport); wr_ch_lli(chn, "rf_bandwidth", cfg->bw_hz); wr_ch_lli(chn, "sampling_frequency", cfg->fs_hz); // Configure LO channel printf("* Acquiring AD9361 %s lo channel\n", type == TX ? "TX" : "RX"); - if (!get_lo_chan(ctx, type, &chn)) { return false; } + if (!get_lo_chan(type, &chn)) { return false; } wr_ch_lli(chn, "frequency", cfg->lo_hz); return true; } /* simple configuration and streaming */ -/* usage: +/* usage: * Default context, assuming local IIO devices, i.e., this script is run on ADALM-Pluto for example $./a.out * URI context, find out the uri by typing `iio_info -s` at the command line of the host PC - $./a.out usb:x.x.x + $./a.out usb:x.x.x */ int main (int argc, char **argv) { @@ -223,18 +223,18 @@ IIO_ENSURE(iio_context_get_devices_count(ctx) > 0 && "No devices"); printf("* Acquiring AD9361 streaming devices\n"); - IIO_ENSURE(get_ad9361_stream_dev(ctx, TX, &tx) && "No tx dev found"); - IIO_ENSURE(get_ad9361_stream_dev(ctx, RX, &rx) && "No rx dev found"); + IIO_ENSURE(get_ad9361_stream_dev(TX, &tx) && "No tx dev found"); + IIO_ENSURE(get_ad9361_stream_dev(RX, &rx) && "No rx dev found"); printf("* Configuring AD9361 for streaming\n"); - IIO_ENSURE(cfg_ad9361_streaming_ch(ctx, &rxcfg, RX, 0) && "RX port 0 not found"); - IIO_ENSURE(cfg_ad9361_streaming_ch(ctx, &txcfg, TX, 0) && "TX port 0 not found"); + IIO_ENSURE(cfg_ad9361_streaming_ch(&rxcfg, RX, 0) && "RX port 0 not found"); + IIO_ENSURE(cfg_ad9361_streaming_ch(&txcfg, TX, 0) && "TX port 0 not found"); printf("* Initializing AD9361 IIO streaming channels\n"); - IIO_ENSURE(get_ad9361_stream_ch(ctx, RX, rx, 0, &rx0_i) && "RX chan i not found"); - IIO_ENSURE(get_ad9361_stream_ch(ctx, RX, rx, 1, &rx0_q) && "RX chan q not found"); - IIO_ENSURE(get_ad9361_stream_ch(ctx, TX, tx, 0, &tx0_i) && "TX chan i not found"); - IIO_ENSURE(get_ad9361_stream_ch(ctx, TX, tx, 1, &tx0_q) && "TX chan q not found"); + IIO_ENSURE(get_ad9361_stream_ch(RX, rx, 0, &rx0_i) && "RX chan i not found"); + IIO_ENSURE(get_ad9361_stream_ch(RX, rx, 1, &rx0_q) && "RX chan q not found"); + IIO_ENSURE(get_ad9361_stream_ch(TX, tx, 0, &tx0_i) && "TX chan i not found"); + IIO_ENSURE(get_ad9361_stream_ch(TX, tx, 1, &tx0_q) && "TX chan q not found"); printf("* Enabling IIO streaming channels\n"); iio_channel_enable(rx0_i); @@ -300,4 +300,4 @@ shutdown(); return 0; -} +} diff -Nru libiio-0.21/examples/ad9371-iiostream.c libiio-0.23/examples/ad9371-iiostream.c --- libiio-0.21/examples/ad9371-iiostream.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/ad9371-iiostream.c 2021-08-20 11:01:14.000000000 +0000 @@ -129,7 +129,7 @@ } /* returns ad9371 phy device */ -static struct iio_device* get_ad9371_phy(struct iio_context *ctx) +static struct iio_device* get_ad9371_phy(void) { struct iio_device *dev = iio_context_find_device(ctx, "ad9371-phy"); IIO_ENSURE(dev && "No ad9371-phy found"); @@ -137,7 +137,7 @@ } /* finds AD9371 streaming IIO devices */ -static bool get_ad9371_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) +static bool get_ad9371_stream_dev(enum iodev d, struct iio_device **dev) { switch (d) { case TX: *dev = iio_context_find_device(ctx, "axi-ad9371-tx-hpc"); return *dev != NULL; @@ -147,7 +147,7 @@ } /* finds AD9371 streaming IIO channels */ -static bool get_ad9371_stream_ch(__notused struct iio_context *ctx, enum iodev d, struct iio_device *dev, int chid, char modify, struct iio_channel **chn) +static bool get_ad9371_stream_ch(enum iodev d, struct iio_device *dev, int chid, char modify, struct iio_channel **chn) { *chn = iio_device_find_channel(dev, modify ? get_ch_name_mod("voltage", chid, modify) : get_ch_name("voltage", chid), d == TX); if (!*chn) @@ -156,41 +156,41 @@ } /* finds AD9371 phy IIO configuration channel with id chid */ -static bool get_phy_chan(struct iio_context *ctx, enum iodev d, int chid, struct iio_channel **chn) +static bool get_phy_chan(enum iodev d, int chid, struct iio_channel **chn) { switch (d) { - case RX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("voltage", chid), false); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("voltage", chid), true); return *chn != NULL; + case RX: *chn = iio_device_find_channel(get_ad9371_phy(), get_ch_name("voltage", chid), false); return *chn != NULL; + case TX: *chn = iio_device_find_channel(get_ad9371_phy(), get_ch_name("voltage", chid), true); return *chn != NULL; default: IIO_ENSURE(0); return false; } } /* finds AD9371 local oscillator IIO configuration channels */ -static bool get_lo_chan(struct iio_context *ctx, enum iodev d, struct iio_channel **chn) +static bool get_lo_chan(enum iodev d, struct iio_channel **chn) { switch (d) { // LO chan is always output, i.e. true - case RX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("altvoltage", 0), true); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_ad9371_phy(ctx), get_ch_name("altvoltage", 1), true); return *chn != NULL; + case RX: *chn = iio_device_find_channel(get_ad9371_phy(), get_ch_name("altvoltage", 0), true); return *chn != NULL; + case TX: *chn = iio_device_find_channel(get_ad9371_phy(), get_ch_name("altvoltage", 1), true); return *chn != NULL; default: IIO_ENSURE(0); return false; } } /* applies streaming configuration through IIO */ -bool cfg_ad9371_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, enum iodev type, int chid) +bool cfg_ad9371_streaming_ch(struct stream_cfg *cfg, enum iodev type, int chid) { struct iio_channel *chn = NULL; // Configure phy and lo channels printf("* Acquiring AD9371 phy %s channel %d\n", type == TX ? "TX" : "RX", chid); - if (!get_phy_chan(ctx, type, chid, &chn)) { return false; } + if (!get_phy_chan(type, chid, &chn)) { return false; } rd_ch_lli(chn, "rf_bandwidth"); rd_ch_lli(chn, "sampling_frequency"); // Configure LO channel printf("* Acquiring AD9371 %s lo channel\n", type == TX ? "TX" : "RX"); - if (!get_lo_chan(ctx, type, &chn)) { return false; } + if (!get_lo_chan(type, &chn)) { return false; } wr_ch_lli(chn, type == TX ? "TX_LO_frequency" : "RX_LO_frequency" , cfg->lo_hz); return true; } @@ -224,18 +224,18 @@ IIO_ENSURE(iio_context_get_devices_count(ctx) > 0 && "No devices"); printf("* Acquiring AD9371 streaming devices\n"); - IIO_ENSURE(get_ad9371_stream_dev(ctx, TX, &tx) && "No tx dev found"); - IIO_ENSURE(get_ad9371_stream_dev(ctx, RX, &rx) && "No rx dev found"); + IIO_ENSURE(get_ad9371_stream_dev(TX, &tx) && "No tx dev found"); + IIO_ENSURE(get_ad9371_stream_dev(RX, &rx) && "No rx dev found"); printf("* Configuring AD9371 for streaming\n"); - IIO_ENSURE(cfg_ad9371_streaming_ch(ctx, &rxcfg, RX, 0) && "RX port 0 not found"); - IIO_ENSURE(cfg_ad9371_streaming_ch(ctx, &txcfg, TX, 0) && "TX port 0 not found"); + IIO_ENSURE(cfg_ad9371_streaming_ch(&rxcfg, RX, 0) && "RX port 0 not found"); + IIO_ENSURE(cfg_ad9371_streaming_ch(&txcfg, TX, 0) && "TX port 0 not found"); printf("* Initializing AD9371 IIO streaming channels\n"); - IIO_ENSURE(get_ad9371_stream_ch(ctx, RX, rx, 0, 'i', &rx0_i) && "RX chan i not found"); - IIO_ENSURE(get_ad9371_stream_ch(ctx, RX, rx, 0, 'q', &rx0_q) && "RX chan q not found"); - IIO_ENSURE(get_ad9371_stream_ch(ctx, TX, tx, 0, 0, &tx0_i) && "TX chan i not found"); - IIO_ENSURE(get_ad9371_stream_ch(ctx, TX, tx, 1, 0, &tx0_q) && "TX chan q not found"); + IIO_ENSURE(get_ad9371_stream_ch(RX, rx, 0, 'i', &rx0_i) && "RX chan i not found"); + IIO_ENSURE(get_ad9371_stream_ch(RX, rx, 0, 'q', &rx0_q) && "RX chan q not found"); + IIO_ENSURE(get_ad9371_stream_ch(TX, tx, 0, 0, &tx0_i) && "TX chan i not found"); + IIO_ENSURE(get_ad9371_stream_ch(TX, tx, 1, 0, &tx0_q) && "TX chan q not found"); printf("* Enabling IIO streaming channels\n"); iio_channel_enable(rx0_i); diff -Nru libiio-0.21/examples/adrv9002-iiostream.c libiio-0.23/examples/adrv9002-iiostream.c --- libiio-0.21/examples/adrv9002-iiostream.c 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/examples/adrv9002-iiostream.c 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2021 Analog Devices, Inc. + * Author: Nuno Sá + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARGS(fmt, ...) __VA_ARGS__ +#define FMT(fmt, ...) fmt +#define error(...) \ + printf("%s, %d: ERROR: " FMT(__VA_ARGS__, 0)"%s", __func__, __LINE__, ARGS(__VA_ARGS__, "")) + +#define info(...) \ + printf("%s, %d: INFO: " FMT(__VA_ARGS__, 0)"%s", __func__, __LINE__, ARGS(__VA_ARGS__, "")) + +/* helper macros */ +#define GHZ(x) ((long long)(x * 1000000000.0 + .5)) + +static bool stop = false; +static struct iio_context *ctx = NULL; +static struct iio_buffer *rxbuf = NULL; +static struct iio_buffer *txbuf = NULL; +static struct iio_channel *rx_chan[2] = { NULL, NULL }; +static struct iio_channel *tx_chan[2] = { NULL, NULL }; + +enum { + I_CHAN, + Q_CHAN +}; + +#ifdef _WIN32 +#include +#include +#include + +BOOL WINAPI sig_handler(DWORD dwCtrlType) +{ + /* Runs in its own thread */ + switch (dwCtrlType) { + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + stop = true; + return true; + default: + return false; + } +} + +static int register_signals(void) +{ + if (!SetConsoleCtrlHandler(sig_handler, TRUE)) + return -1; + + return 0; +} +#else +static void sig_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) { + info("Exit....\n"); + stop = true; + } +} + +static int register_signals(void) +{ + struct sigaction sa = {0}; + sigset_t mask = {0}; + + sa.sa_handler = sig_handler; + sigemptyset(&sa.sa_mask); + sigemptyset(&mask); + + if (sigaction(SIGTERM, &sa, NULL) < 0) { + error("sigaction: %s\n", strerror(errno)); + return -1; + } + + if (sigaction(SIGINT, &sa, NULL) < 0) { + error("sigaction: %s\n", strerror(errno)); + return -1; + } + + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + /* make sure these signals are unblocked */ + if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) { + error("sigprocmask: %s", strerror(errno)); + return -1; + } + + return 0; +} +#endif + +static int configure_tx_lo(void) +{ + struct iio_device *phy; + struct iio_channel *chan; + int ret; + long long val; + + phy = iio_context_find_device(ctx, "adrv9002-phy"); + if (!phy) { + error("Could not find adrv9002_phy\n"); + return -ENODEV; + } + + chan = iio_device_find_channel(phy, "voltage0", true); + if (!chan) { + error("Could not find TX voltage0 channel\n"); + return -ENODEV; + } + + /* printout some useful info */ + ret = iio_channel_attr_read_longlong(chan, "rf_bandwidth", &val); + if (ret) + return ret; + + info("adrv9002 bandwidth: %lld\n", val); + + ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", &val); + if (ret) + return ret; + + info("adrv9002 sampling_frequency: %lld\n", val); + + /* set the LO to 2.5GHz */ + val = GHZ(2.5); + chan = iio_device_find_channel(phy, "altvoltage2", true); + if (!chan) { + error("Could not find TX LO channel\n"); + return -ENODEV; + } + + return iio_channel_attr_write_longlong(chan, "TX1_LO_frequency", val); +} + +static void cleanup(void) +{ + int c; + + if (rxbuf) + iio_buffer_destroy(rxbuf); + + if (txbuf) + iio_buffer_destroy(txbuf); + + for (c = 0; c < 2; c++) { + if (rx_chan[c]) + iio_channel_disable(rx_chan[c]); + + if (tx_chan[c]) + iio_channel_disable(tx_chan[c]); + } + + iio_context_destroy(ctx); +} + +static int stream_channels_get_enable(const struct iio_device *dev, struct iio_channel **chan, + bool tx) +{ + int c; + const char * const channels[] = { + "voltage0_i", "voltage0_q", "voltage0", "voltage1" + }; + + for (c = 0; c < 2; c++) { + const char *str = channels[tx * 2 + c]; + + chan[c] = iio_device_find_channel(dev, str, tx); + if (!chan[c]) { + error("Could not find %s channel tx=%d\n", str, tx); + return -ENODEV; + } + + iio_channel_enable(chan[c]); + } + + return 0; +} + +static void stream(ssize_t rx_sample, ssize_t tx_sample) +{ + const struct iio_channel *rx_i_chan = rx_chan[I_CHAN]; + const struct iio_channel *tx_i_chan = tx_chan[I_CHAN]; + ssize_t nrx = 0; + ssize_t ntx = 0; + + while (!stop) { + ssize_t nbytes_rx, nbytes_tx; + int16_t *p_dat, *p_end; + ptrdiff_t p_inc; + + + nbytes_tx = iio_buffer_push(txbuf); + if (nbytes_tx < 0) { + error("Error pushing buf %zd\n", nbytes_tx); + return; + } + + nbytes_rx = iio_buffer_refill(rxbuf); + if (nbytes_rx < 0) { + error("Error refilling buf %zd\n", nbytes_rx); + return; + } + + /* READ: Get pointers to RX buf and read IQ from RX buf port 0 */ + p_inc = iio_buffer_step(rxbuf); + p_end = iio_buffer_end(rxbuf); + for (p_dat = iio_buffer_first(rxbuf, rx_i_chan); p_dat < p_end; + p_dat += p_inc / sizeof(*p_dat)) { + /* Example: swap I and Q */ + int16_t i = p_dat[0]; + int16_t q = p_dat[1]; + + p_dat[0] = q; + p_dat[1] = i; + } + + /* WRITE: Get pointers to TX buf and write IQ to TX buf port 0 */ + p_inc = iio_buffer_step(txbuf); + p_end = iio_buffer_end(txbuf); + for (p_dat = iio_buffer_first(txbuf, tx_i_chan); p_dat < p_end; + p_dat += p_inc / sizeof(*p_dat)) { + p_dat[0] = 0; /* Real (I) */ + p_dat[1] = 0; /* Imag (Q) */ + } + + nrx += nbytes_rx / rx_sample; + ntx += nbytes_tx / tx_sample; + info("\tRX %8.2f MSmp, TX %8.2f MSmp\n", nrx / 1e6, ntx / 1e6); + } +} + +int main(void) +{ + struct iio_device *tx; + struct iio_device *rx; + ssize_t tx_sample_sz, rx_sample_sz; + int ret; + + if (register_signals() < 0) + return EXIT_FAILURE; + + ctx = iio_create_default_context(); + if (!ctx) { + error("Could not create IIO context\n"); + return EXIT_FAILURE; + } + + ret = configure_tx_lo(); + if (ret) + goto clean; + + tx = iio_context_find_device(ctx, "axi-adrv9002-tx-lpc"); + if (!tx) { + ret = EXIT_FAILURE; + goto clean; + } + + rx = iio_context_find_device(ctx, "axi-adrv9002-rx-lpc"); + if (!rx) { + ret = EXIT_FAILURE; + goto clean; + } + + ret = stream_channels_get_enable(rx, rx_chan, false); + if (ret) + goto clean; + + ret = stream_channels_get_enable(tx, tx_chan, true); + if (ret) + goto clean; + + info("* Creating non-cyclic IIO buffers with 1 MiS\n"); + rxbuf = iio_device_create_buffer(rx, 1024 * 1024, false); + if (!rxbuf) { + error("Could not create RX buffer: %s\n", strerror(errno)); + ret = EXIT_FAILURE; + goto clean; + } + + txbuf = iio_device_create_buffer(tx, 1024 * 1024, false); + if (!txbuf) { + error("Could not create TX buffer: %s\n", strerror(errno)); + ret = EXIT_FAILURE; + goto clean; + } + + tx_sample_sz = iio_device_get_sample_size(tx); + rx_sample_sz = iio_device_get_sample_size(rx); + + stream(rx_sample_sz, tx_sample_sz); + +clean: + cleanup(); + return ret; +} diff -Nru libiio-0.21/examples/adrv9009-iiostream.c libiio-0.23/examples/adrv9009-iiostream.c --- libiio-0.21/examples/adrv9009-iiostream.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/adrv9009-iiostream.c 2021-08-20 11:01:14.000000000 +0000 @@ -129,7 +129,7 @@ } /* returns adrv9009 phy device */ -static struct iio_device* get_adrv9009_phy(struct iio_context *ctx) +static struct iio_device* get_adrv9009_phy(void) { struct iio_device *dev = iio_context_find_device(ctx, "adrv9009-phy"); IIO_ENSURE(dev && "No adrv9009-phy found"); @@ -137,7 +137,7 @@ } /* finds adrv9009 streaming IIO devices */ -static bool get_adrv9009_stream_dev(struct iio_context *ctx, enum iodev d, struct iio_device **dev) +static bool get_adrv9009_stream_dev(enum iodev d, struct iio_device **dev) { switch (d) { case TX: *dev = iio_context_find_device(ctx, "axi-adrv9009-tx-hpc"); return *dev != NULL; @@ -147,7 +147,7 @@ } /* finds adrv9009 streaming IIO channels */ -static bool get_adrv9009_stream_ch(__notused struct iio_context *ctx, enum iodev d, struct iio_device *dev, int chid, char modify, struct iio_channel **chn) +static bool get_adrv9009_stream_ch(enum iodev d, struct iio_device *dev, int chid, char modify, struct iio_channel **chn) { *chn = iio_device_find_channel(dev, modify ? get_ch_name_mod("voltage", chid, modify) : get_ch_name("voltage", chid), d == TX); if (!*chn) @@ -156,37 +156,37 @@ } /* finds adrv9009 phy IIO configuration channel with id chid */ -static bool get_phy_chan(struct iio_context *ctx, enum iodev d, int chid, struct iio_channel **chn) +static bool get_phy_chan(enum iodev d, int chid, struct iio_channel **chn) { switch (d) { - case RX: *chn = iio_device_find_channel(get_adrv9009_phy(ctx), get_ch_name("voltage", chid), false); return *chn != NULL; - case TX: *chn = iio_device_find_channel(get_adrv9009_phy(ctx), get_ch_name("voltage", chid), true); return *chn != NULL; + case RX: *chn = iio_device_find_channel(get_adrv9009_phy(), get_ch_name("voltage", chid), false); return *chn != NULL; + case TX: *chn = iio_device_find_channel(get_adrv9009_phy(), get_ch_name("voltage", chid), true); return *chn != NULL; default: IIO_ENSURE(0); return false; } } /* finds adrv9009 local oscillator IIO configuration channels */ -static bool get_lo_chan(struct iio_context *ctx, struct iio_channel **chn) +static bool get_lo_chan(struct iio_channel **chn) { // LO chan is always output, i.e. true - *chn = iio_device_find_channel(get_adrv9009_phy(ctx), get_ch_name("altvoltage", 0), true); return *chn != NULL; + *chn = iio_device_find_channel(get_adrv9009_phy(), get_ch_name("altvoltage", 0), true); return *chn != NULL; } /* applies streaming configuration through IIO */ -bool cfg_adrv9009_streaming_ch(struct iio_context *ctx, struct stream_cfg *cfg, int chid) +bool cfg_adrv9009_streaming_ch(struct stream_cfg *cfg, int chid) { struct iio_channel *chn = NULL; // Configure phy and lo channels printf("* Acquiring ADRV9009 phy channel %d\n", chid); - if (!get_phy_chan(ctx, true, chid, &chn)) { return false; } + if (!get_phy_chan(true, chid, &chn)) { return false; } rd_ch_lli(chn, "rf_bandwidth"); rd_ch_lli(chn, "sampling_frequency"); // Configure LO channel printf("* Acquiring ADRV9009 TRX lo channel\n"); - if (!get_lo_chan(ctx, &chn)) { return false; } + if (!get_lo_chan(&chn)) { return false; } wr_ch_lli(chn, "frequency", cfg->lo_hz); return true; } @@ -216,17 +216,17 @@ IIO_ENSURE(iio_context_get_devices_count(ctx) > 0 && "No devices"); printf("* Acquiring ADRV9009 streaming devices\n"); - IIO_ENSURE(get_adrv9009_stream_dev(ctx, TX, &tx) && "No tx dev found"); - IIO_ENSURE(get_adrv9009_stream_dev(ctx, RX, &rx) && "No rx dev found"); + IIO_ENSURE(get_adrv9009_stream_dev(TX, &tx) && "No tx dev found"); + IIO_ENSURE(get_adrv9009_stream_dev(RX, &rx) && "No rx dev found"); printf("* Configuring ADRV9009 for streaming\n"); - IIO_ENSURE(cfg_adrv9009_streaming_ch(ctx, &trxcfg, 0) && "TRX device not found"); + IIO_ENSURE(cfg_adrv9009_streaming_ch(&trxcfg, 0) && "TRX device not found"); printf("* Initializing ADRV9009 IIO streaming channels\n"); - IIO_ENSURE(get_adrv9009_stream_ch(ctx, RX, rx, 0, 'i', &rx0_i) && "RX chan i not found"); - IIO_ENSURE(get_adrv9009_stream_ch(ctx, RX, rx, 0, 'q', &rx0_q) && "RX chan q not found"); - IIO_ENSURE(get_adrv9009_stream_ch(ctx, TX, tx, 0, 0, &tx0_i) && "TX chan i not found"); - IIO_ENSURE(get_adrv9009_stream_ch(ctx, TX, tx, 1, 0, &tx0_q) && "TX chan q not found"); + IIO_ENSURE(get_adrv9009_stream_ch(RX, rx, 0, 'i', &rx0_i) && "RX chan i not found"); + IIO_ENSURE(get_adrv9009_stream_ch(RX, rx, 0, 'q', &rx0_q) && "RX chan q not found"); + IIO_ENSURE(get_adrv9009_stream_ch(TX, tx, 0, 0, &tx0_i) && "TX chan i not found"); + IIO_ENSURE(get_adrv9009_stream_ch(TX, tx, 1, 0, &tx0_q) && "TX chan q not found"); printf("* Enabling IIO streaming channels\n"); iio_channel_enable(rx0_i); diff -Nru libiio-0.21/examples/CMakeLists.txt libiio-0.23/examples/CMakeLists.txt --- libiio-0.21/examples/CMakeLists.txt 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/CMakeLists.txt 2021-08-20 11:01:14.000000000 +0000 @@ -4,6 +4,7 @@ project(ad9371-iiostream C) project(adrv9009-iiostream C) project(dummy-iiostream C) +project(adrv9002-iiostream C) if (APPLE) # Add relative rpath to iio library (which is in the same framework) @@ -37,20 +38,27 @@ add_executable( adrv9009-iiostream adrv9009-iiostream.c ${GETOPT_C_FILE} ${LIBIIO_RC} ) +add_executable( + adrv9002-iiostream adrv9002-iiostream.c ${GETOPT_C_FILE} ${LIBIIO_RC} +) add_executable(dummy-iiostream dummy-iiostream.c ${GETOPT_C_FILE} ${LIBIIO_RC}) target_link_libraries(ad9361-iiostream iio) target_link_libraries(ad9371-iiostream iio) target_link_libraries(adrv9009-iiostream iio) target_link_libraries(dummy-iiostream iio) +target_link_libraries(adrv9002-iiostream iio) set(IIO_EXAMPLES_TARGETS ad9361-iiostream ad9371-iiostream adrv9009-iiostream - dummy-iiostream + dummy-iiostream adrv9002-iiostream ) +find_library(PTHREAD_LIBRARIES pthread) find_library(CURSES_LIBRARY curses) find_library(CDK_LIBRARY cdk) +include(CheckSymbolExists) + if (PTHREAD_LIBRARIES AND CURSES_LIBRARY AND CDK_LIBRARY diff -Nru libiio-0.21/examples/dummy-iiostream.c libiio-0.23/examples/dummy-iiostream.c --- libiio-0.21/examples/dummy-iiostream.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/dummy-iiostream.c 2021-08-20 11:01:14.000000000 +0000 @@ -137,7 +137,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-ret, buf, sizeof(buf)); - fprintf(stderr, "%s (%d) while Disassociate trigger\n", buf, ret); + fprintf(stderr, "%s while Disassociate trigger\n", buf); } } @@ -355,7 +355,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-ret, buf, sizeof(buf)); - fprintf(stderr, "%s (%d) while processing buffer\n", buf, ret); + fprintf(stderr, "%s while processing buffer\n", buf); } printf("\n"); break; diff -Nru libiio-0.21/examples/iio-monitor.c libiio-0.23/examples/iio-monitor.c --- libiio-0.21/examples/iio-monitor.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/examples/iio-monitor.c 2021-08-20 11:01:14.000000000 +0000 @@ -77,7 +77,7 @@ { char buf[256]; iio_strerror(-ret, buf, sizeof(buf)); - fprintf(stderr, "Error during read: %s (%d)\n", buf, ret); + fprintf(stderr, "Error during read: %s\n", buf); } static double get_channel_value(struct iio_channel *chn) diff -Nru libiio-0.21/iio-backend.h libiio-0.23/iio-backend.h --- libiio-0.21/iio-backend.h 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/iio-backend.h 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2020 Analog Devices, Inc. + */ + +#ifndef __IIO_BACKEND_H__ +#define __IIO_BACKEND_H__ + +#include + +struct iio_device; +struct iio_context; + +enum iio_backend_api_ver { + IIO_BACKEND_API_V1 = 1, +}; + +enum iio_attr_type { + IIO_ATTR_TYPE_DEVICE = 0, + IIO_ATTR_TYPE_DEBUG, + IIO_ATTR_TYPE_BUFFER, +}; + +struct iio_backend_ops { + struct iio_context * (*clone)(const struct iio_context *ctx); + ssize_t (*read)(const struct iio_device *dev, void *dst, size_t len, + uint32_t *mask, size_t words); + ssize_t (*write)(const struct iio_device *dev, + const void *src, size_t len); + int (*open)(const struct iio_device *dev, + size_t samples_count, bool cyclic); + int (*close)(const struct iio_device *dev); + int (*get_fd)(const struct iio_device *dev); + int (*set_blocking_mode)(const struct iio_device *dev, bool blocking); + + void (*cancel)(const struct iio_device *dev); + + int (*set_kernel_buffers_count)(const struct iio_device *dev, + unsigned int nb_blocks); + ssize_t (*get_buffer)(const struct iio_device *dev, + void **addr_ptr, size_t bytes_used, + uint32_t *mask, size_t words); + + ssize_t (*read_device_attr)(const struct iio_device *dev, + const char *attr, char *dst, size_t len, enum iio_attr_type); + ssize_t (*write_device_attr)(const struct iio_device *dev, + const char *attr, const char *src, + size_t len, enum iio_attr_type); + ssize_t (*read_channel_attr)(const struct iio_channel *chn, + const char *attr, char *dst, size_t len); + ssize_t (*write_channel_attr)(const struct iio_channel *chn, + const char *attr, const char *src, size_t len); + + int (*get_trigger)(const struct iio_device *dev, + const struct iio_device **trigger); + int (*set_trigger)(const struct iio_device *dev, + const struct iio_device *trigger); + + void (*shutdown)(struct iio_context *ctx); + + char * (*get_description)(const struct iio_context *ctx); + + int (*get_version)(const struct iio_context *ctx, unsigned int *major, + unsigned int *minor, char git_tag[8]); + + int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); +}; + +/** + * struct iio_backend - IIO backend object (API version 1) + * @api_version API version for interfacing with libiio core library + * @name Name of this backend + * @uri_prefix URI prefix for this backend + * @ops Reference to backend ops + * @sizeof_context_pdata Size of private data for the IIO contexts generated by this backend + */ +struct iio_backend { + unsigned int api_version; + const char *name; + const char *uri_prefix; + const struct iio_backend_ops *ops; + unsigned int sizeof_context_pdata; +}; + +struct iio_context * iio_context_create_from_backend( + const struct iio_backend *backend, + const char *description); + +#endif /* __IIO_BACKEND_H__ */ diff -Nru libiio-0.21/iio-config.h.cmakein libiio-0.23/iio-config.h.cmakein --- libiio-0.21/iio-config.h.cmakein 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iio-config.h.cmakein 2021-08-20 11:01:14.000000000 +0000 @@ -7,16 +7,21 @@ #define LOG_LEVEL @LOG_LEVEL@_L -#cmakedefine WITH_LOCAL_BACKEND -#cmakedefine WITH_XML_BACKEND -#cmakedefine WITH_NETWORK_BACKEND -#cmakedefine WITH_USB_BACKEND -#cmakedefine WITH_SERIAL_BACKEND +#cmakedefine01 WITH_LOCAL_BACKEND +#cmakedefine01 WITH_XML_BACKEND +#cmakedefine01 WITH_NETWORK_BACKEND +#cmakedefine01 WITH_USB_BACKEND +#cmakedefine01 WITH_SERIAL_BACKEND #cmakedefine WITH_NETWORK_GET_BUFFER -#cmakedefine WITH_NETWORK_EVENTFD -#cmakedefine WITH_IIOD_USBD -#cmakedefine WITH_LOCAL_CONFIG +#cmakedefine01 WITH_NETWORK_EVENTFD +#cmakedefine01 WITH_IIOD_USBD +#cmakedefine01 WITH_LOCAL_CONFIG +#cmakedefine01 WITH_AIO +#cmakedefine01 HAVE_DNS_SD +#cmakedefine01 HAVE_AVAHI +#cmakedefine01 WITH_ZSTD + #cmakedefine HAS_PIPE2 #cmakedefine HAS_STRDUP #cmakedefine HAS_STRNDUP @@ -24,8 +29,6 @@ #cmakedefine HAS_NEWLOCALE #cmakedefine HAS_PTHREAD_SETNAME_NP #cmakedefine HAVE_IPV6 -#cmakedefine HAVE_DNS_SD -#cmakedefine HAVE_AVAHI #cmakedefine NO_THREADS #cmakedefine HAS_LIBUSB_GETVERSION diff -Nru libiio-0.21/iiod/CMakeLists.txt libiio-0.23/iiod/CMakeLists.txt --- libiio-0.21/iiod/CMakeLists.txt 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/CMakeLists.txt 2021-08-20 11:01:14.000000000 +0000 @@ -12,6 +12,13 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARIES}) +set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) +check_symbol_exists(pthread_setname_np "pthread.h" HAS_PTHREAD_SETNAME_NP) +set(CMAKE_REQUIRED_LIBRARIES) +set(CMAKE_REQUIRED_DEFINITIONS) + if (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCC) # flex sometimes generates code which generate sign comparison errors set_source_files_properties(${FLEX_lexer_OUTPUTS} PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") @@ -20,29 +27,33 @@ set(IIOD_CFILES iiod.c ops.c thread-pool.c ${BISON_parser_OUTPUTS} ${FLEX_lexer_OUTPUTS}) -find_library(LIBAIO_LIBRARIES aio) -find_path(LIBAIO_INCLUDE_DIR libaio.h) - -if (LIBAIO_LIBRARIES AND LIBAIO_INCLUDE_DIR) - option(ENABLE_AIO "Build IIOD with async. I/O support" ON) -endif () - -include(CheckTypeSize) -set(CMAKE_EXTRA_INCLUDE_FILES linux/usb/functionfs.h) -check_type_size("struct usb_functionfs_descs_head_v2" FUNCTIONFS_V2) -set(CMAKE_EXTRA_INCLUDE_FILES) +option(WITH_AIO "Build IIOD with async. I/O support" ON) +if (WITH_AIO) + find_library(LIBAIO_LIBRARIES aio) + find_path(LIBAIO_INCLUDE_DIR libaio.h) + + if (NOT LIBAIO_LIBRARIES OR NOT LIBAIO_INCLUDE_DIR) + message(SEND_ERROR "Unable to find libaio dependency.\n" + "If you want to disable async. I/O support, set WITH_AIO=OFF.") + endif () -if (HAVE_FUNCTIONFS_V2) - OPTION(WITH_IIOD_USBD "Add support for USB through FunctionFS within IIOD" ${ENABLE_AIO}) + message(STATUS "Looking for libaio: Found") + option(WITH_IIOD_USBD "Add support for USB through FunctionFS within IIOD" ON) if (WITH_IIOD_USBD) - if (NOT ENABLE_AIO) - message(SEND_ERROR "USB support in IIOD requires async. I/O support") - endif (NOT ENABLE_AIO) + include(CheckTypeSize) + set(CMAKE_EXTRA_INCLUDE_FILES linux/usb/functionfs.h) + check_type_size("struct usb_functionfs_descs_head_v2" FUNCTIONFS_V2) + set(CMAKE_EXTRA_INCLUDE_FILES) + + if (NOT HAVE_FUNCTIONFS_V2) + message(SEND_ERROR "Linux kernel headers are too old.\n" + "If you want to disable USB support, set WITH_IIOD_USBD=OFF.") + endif() set(IIOD_CFILES ${IIOD_CFILES} usbd.c) - endif (WITH_IIOD_USBD) -endif (HAVE_FUNCTIONFS_V2) + endif() +endif() add_executable(iiod ${IIOD_CFILES}) set_target_properties(iiod PROPERTIES @@ -52,14 +63,22 @@ ) target_link_libraries(iiod iio ${PTHREAD_LIBRARIES} ${AVAHI_LIBRARIES}) -if (ENABLE_AIO) - add_definitions(-DWITH_AIO=1) +if (WITH_AIO) include_directories(${LIBAIO_INCLUDE_DIR}) target_link_libraries(iiod ${LIBAIO_LIBRARIES}) endif () +if (WITH_ZSTD) + include_directories(${LIBZSTD_INCLUDE_DIR}) + target_link_libraries(iiod ${LIBZSTD_LIBRARIES}) +endif() + add_definitions(-D_GNU_SOURCE=1) +if (HAVE_AVAHI) + target_sources(iiod PRIVATE dns-sd.c) +endif() + if(NOT SKIP_INSTALL_ALL) install(TARGETS iiod RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) endif() diff -Nru libiio-0.21/iiod/dns-sd.c libiio-0.23/iiod/dns-sd.c --- libiio-0.21/iiod/dns-sd.c 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/iiod/dns-sd.c 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,327 @@ +// SPDX-license-identifier: LGPL-v2-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2021 Analog Devices, Inc. + * Author: Paul Cercueil + */ + +#include "dns-sd.h" +#include "ops.h" +#include "thread-pool.h" + +#include "../debug.h" +#include "../iio.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*** + * Parts of the avahi code are borrowed from the client-publish-service.c + * https://www.avahi.org/doxygen/html/client-publish-service_8c-example.html + * which is an example in the avahi library. Copyright Lennart Poettering + * released under the LGPL 2.1 or (at your option) any later version. + */ + +/* Global Data */ + +static struct avahi_data { + AvahiThreadedPoll *poll; + AvahiClient *client; + AvahiEntryGroup *group; + char * name; +} avahi; + +static void create_services(AvahiClient *c); +static AvahiClient * client_new(void); + +static void client_free() +{ + /* This also frees the entry group, if any. */ + if (avahi.client) { + avahi_client_free(avahi.client); + avahi.client = NULL; + avahi.group = NULL; + } +} + +static void shutdown_avahi() +{ + /* Stop the avahi client, if it's running. */ + if (avahi.poll) + avahi_threaded_poll_stop(avahi.poll); + + /* Clean up the avahi objects. The order is significant. */ + client_free(); + if (avahi.poll) { + avahi_threaded_poll_free(avahi.poll); + avahi.poll = NULL; + } + if (avahi.name) { + IIO_INFO("Avahi: Removing service '%s'\n", avahi.name); + avahi_free(avahi.name); + avahi.name = NULL; + } +} + +static void __avahi_group_cb(AvahiEntryGroup *group, + AvahiEntryGroupState state, void *d) +{ + /* Called whenever the entry group state changes */ + if (!group) { + IIO_ERROR("__avahi_group_cb with no valid group\n"); + return; + } + + avahi.group = group; + + switch (state) { + case AVAHI_ENTRY_GROUP_ESTABLISHED : + IIO_INFO("Avahi: Service '%s' successfully established.\n", + avahi.name); + break; + case AVAHI_ENTRY_GROUP_COLLISION : { + char *n; + /* A service name collision, pick a new name */ + n = avahi_alternative_service_name(avahi.name); + avahi_free(avahi.name); + avahi.name = n; + IIO_INFO("Avahi: Group Service name collision, renaming service to '%s'\n", + avahi.name); + create_services(avahi_entry_group_get_client(group)); + break; + } + case AVAHI_ENTRY_GROUP_FAILURE : + IIO_ERROR("Entry group failure: %s\n", + avahi_strerror(avahi_client_errno( + avahi_entry_group_get_client(group)))); + break; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + /* This is normal, + * since we commit things in the create_services() + */ + IIO_DEBUG("Avahi: Group uncommitted\n"); + break; + case AVAHI_ENTRY_GROUP_REGISTERING: + IIO_DEBUG("Avahi: Group registering\n"); + break; + } +} + +static void __avahi_client_cb(AvahiClient *client, + AvahiClientState state, void *d) +{ + if (!client) { + IIO_ERROR("__avahi_client_cb with no valid client\n"); + return; + } + + switch (state) { + case AVAHI_CLIENT_S_RUNNING: + /* Same as AVAHI_SERVER_RUNNING */ + IIO_DEBUG("Avahi: create services\n"); + /* The server has startup successfully, so create our services */ + create_services(client); + break; + case AVAHI_CLIENT_FAILURE: + if (avahi_client_errno(client) != AVAHI_ERR_DISCONNECTED) { + IIO_ERROR("Avahi: Client failure: %s\n", + avahi_strerror(avahi_client_errno(client))); + break; + } + IIO_INFO("Avahi: server disconnected\n"); + avahi_client_free(client); + avahi.group = NULL; + avahi.client = client_new(); + break; + case AVAHI_CLIENT_S_COLLISION: + /* Same as AVAHI_SERVER_COLLISION */ + /* When the server is back in AVAHI_SERVER_RUNNING state + * we will register them again with the new host name. */ + IIO_DEBUG("Avahi: Client collision\n"); + /* Let's drop our registered services.*/ + if (avahi.group) + avahi_entry_group_reset(avahi.group); + break; + case AVAHI_CLIENT_S_REGISTERING: + /* Same as AVAHI_SERVER_REGISTERING */ + IIO_DEBUG("Avahi: Client group reset\n"); + if (avahi.group) + avahi_entry_group_reset(avahi.group); + break; + case AVAHI_CLIENT_CONNECTING: + IIO_DEBUG("Avahi: Client Connecting\n"); + break; + } + + /* NOTE: group is freed by avahi_client_free */ +} + +static AvahiClient * client_new(void) +{ + int ret; + AvahiClient * client; + + client = avahi_client_new(avahi_threaded_poll_get(avahi.poll), + AVAHI_CLIENT_NO_FAIL, __avahi_client_cb, NULL, &ret); + + /* No Daemon is handled by the avahi_start thread */ + if (!client && ret != AVAHI_ERR_NO_DAEMON) { + IIO_ERROR("Avahi: failure creating client: %s (%d)\n", + avahi_strerror(ret), ret); + } + + return client; +} + + +static void create_services(AvahiClient *c) +{ + int ret; + + if (!c) { + IIO_ERROR("create_services called with no valid client\n"); + goto fail; + } + + if (!avahi.group) { + avahi.group = avahi_entry_group_new(c, __avahi_group_cb, NULL); + if (!avahi.group) { + IIO_ERROR("avahi_entry_group_new() failed: %s\n", + avahi_strerror(avahi_client_errno(c))); + goto fail; + } + } + + if (!avahi_entry_group_is_empty(avahi.group)) { + IIO_DEBUG("Avahi group not empty\n"); + return; + } + + ret = avahi_entry_group_add_service(avahi.group, + AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + 0, avahi.name, "_iio._tcp", NULL, NULL, IIOD_PORT, NULL); + if (ret < 0) { + if (ret == AVAHI_ERR_COLLISION) { + char *n; + n = avahi_alternative_service_name(avahi.name); + avahi_free(avahi.name); + avahi.name = n; + IIO_DEBUG("Service name collision, renaming service to '%s'\n", + avahi.name); + avahi_entry_group_reset(avahi.group); + create_services(c); + return; + } + IIO_ERROR("Failed to add _iio._tcp service: %s\n", avahi_strerror(ret)); + goto fail; + } + + ret = avahi_entry_group_commit(avahi.group); + if (ret < 0) { + IIO_ERROR("Failed to commit entry group: %s\n", avahi_strerror(ret)); + goto fail; + } + + IIO_INFO("Avahi: Registered '%s' to ZeroConf server %s\n", + avahi.name, avahi_client_get_version_string(c)); + + return; + +fail: + avahi_entry_group_reset(avahi.group); +} + +#define IIOD_ON "iiod on " + +static void start_avahi_thd(struct thread_pool *pool, void *d) +{ + + char label[AVAHI_LABEL_MAX]; + char host[AVAHI_LABEL_MAX - sizeof(IIOD_ON)]; + struct timespec ts; + int ret; + + ts.tv_nsec = 0; + ts.tv_sec = 1; + + while(true) { + ret = gethostname(host, sizeof(host)); + IIO_ERROR("host %s\n", host); + if (ret || !strcmp(host, "none")) + goto again; + + snprintf(label, sizeof(label), "%s%s", IIOD_ON, host); + + if (!avahi.name) + avahi.name = avahi_strdup(label); + if (!avahi.name) + break; + + if (!avahi.poll) + avahi.poll = avahi_threaded_poll_new(); + if (!avahi.poll) { + goto again; + } + + if (!avahi.client) + avahi.client = client_new(); + if (avahi.client) + break; +again: + IIO_INFO("Avahi didn't start, try again later\n"); + nanosleep(&ts, NULL); + ts.tv_sec++; + /* If it hasn't started in 10 times over 60 seconds, + * it is not going to, so stop + */ + if (ts.tv_sec >= 11) + break; + } + + if (avahi.client && avahi.poll) { + avahi_threaded_poll_start(avahi.poll); + IIO_INFO("Avahi: Started.\n"); + } else { + shutdown_avahi(); + IIO_INFO("Avahi: Failed to start.\n"); + } +} + +void start_avahi(struct thread_pool *pool) +{ + int ret; + char err_str[1024]; + + IIO_INFO("Attempting to start Avahi\n"); + + avahi.poll = NULL; + avahi.client = NULL; + avahi.group = NULL; + avahi.name = NULL; + + /* In case dbus, or avahi deamon are not started, we create a thread + * that tries a few times to attach, if it can't within the first + * minute, it gives up. + */ + ret = thread_pool_add_thread(pool, start_avahi_thd, NULL, "avahi_thd"); + if (ret) { + iio_strerror(ret, err_str, sizeof(err_str)); + IIO_ERROR("Failed to create new Avahi thread: %s\n", + err_str); + } +} + +void stop_avahi(void) +{ + shutdown_avahi(); + IIO_INFO("Avahi: Stopped\n"); +} diff -Nru libiio-0.21/iiod/dns-sd.h libiio-0.23/iiod/dns-sd.h --- libiio-0.21/iiod/dns-sd.h 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/iiod/dns-sd.h 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,17 @@ +/* SPDX-license-identifier: LGPL-v2-or-later */ +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2021 Analog Devices, Inc. + * Author: Paul Cercueil + */ + +#ifndef __IIOD_DNS_SD_H +#define __IIOD_DNS_SD_H + +struct thread_pool; + +void start_avahi(struct thread_pool *pool); +void stop_avahi(void); + +#endif /* __IIOD_DNS_SD_H */ diff -Nru libiio-0.21/iiod/iiod.c libiio-0.23/iiod/iiod.c --- libiio-0.21/iiod/iiod.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/iiod.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,24 +1,15 @@ +// 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 - * - * 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. - * - * */ + */ #include "../debug.h" #include "../iio.h" #include "../iio-config.h" +#include "dns-sd.h" #include "ops.h" #include "thread-pool.h" @@ -37,25 +28,18 @@ #include #include #include - -#ifdef HAVE_AVAHI -#include -#include -#include -#include -#include -#include -#include +#if WITH_ZSTD +#include #endif #define MY_NAME "iiod" -#define IIOD_PORT 30431 - struct client_data { int fd; bool debug; struct iio_context *ctx; + const void *xml_zstd; + size_t xml_zstd_len; }; bool server_demux; @@ -109,318 +93,6 @@ "Specify the number of USB pipes (ep couples) to use", }; -#ifdef HAVE_AVAHI - -/*** - * Parts of the avahi code are borrowed from the client-publish-service.c - * https://www.avahi.org/doxygen/html/client-publish-service_8c-example.html - * which is an example in the avahi library. Copyright Lennart Poettering - * released under the LGPL 2.1 or (at your option) any later version. - */ - -/* Global Data */ - -static struct avahi_data { - AvahiThreadedPoll *poll; - AvahiClient *client; - AvahiEntryGroup *group; - char * name; -} avahi; - -static void create_services(AvahiClient *c); -static AvahiClient * client_new(void); - -static void client_free() -{ - /* This also frees the entry group, if any. */ - if (avahi.client) { - avahi_client_free(avahi.client); - avahi.client = NULL; - avahi.group = NULL; - } -} - -static void shutdown_avahi() -{ - /* Stop the avahi client, if it's running. */ - if (avahi.poll) - avahi_threaded_poll_stop(avahi.poll); - - /* Clean up the avahi objects. The order is significant. */ - client_free(); - if (avahi.poll) { - avahi_threaded_poll_free(avahi.poll); - avahi.poll = NULL; - } - if (avahi.name) { - IIO_INFO("Avahi: Removing service '%s'\n", avahi.name); - avahi_free(avahi.name); - avahi.name = NULL; - } -} - -static void __avahi_group_cb(AvahiEntryGroup *group, - AvahiEntryGroupState state, void *d) -{ - /* Called whenever the entry group state changes */ - if (!group) { - IIO_ERROR("__avahi_group_cb with no valid group\n"); - return; - } - - avahi.group = group; - - switch (state) { - case AVAHI_ENTRY_GROUP_ESTABLISHED : - IIO_INFO("Avahi: Service '%s' successfully established.\n", - avahi.name); - break; - case AVAHI_ENTRY_GROUP_COLLISION : { - char *n; - /* A service name collision, pick a new name */ - n = avahi_alternative_service_name(avahi.name); - avahi_free(avahi.name); - avahi.name = n; - IIO_INFO("Avahi: Group Service name collision, renaming service to '%s'\n", - avahi.name); - create_services(avahi_entry_group_get_client(group)); - break; - } - case AVAHI_ENTRY_GROUP_FAILURE : - IIO_ERROR("Entry group failure: %s\n", - avahi_strerror(avahi_client_errno( - avahi_entry_group_get_client(group)))); - break; - case AVAHI_ENTRY_GROUP_UNCOMMITED: - /* This is normal, - * since we commit things in the create_services() - */ - IIO_DEBUG("Avahi: Group uncommitted\n"); - break; - case AVAHI_ENTRY_GROUP_REGISTERING: - IIO_DEBUG("Avahi: Group registering\n"); - break; - } -} - -static void __avahi_client_cb(AvahiClient *client, - AvahiClientState state, void *d) -{ - if (!client) { - IIO_ERROR("__avahi_client_cb with no valid client\n"); - return; - } - - switch (state) { - case AVAHI_CLIENT_S_RUNNING: - /* Same as AVAHI_SERVER_RUNNING */ - IIO_DEBUG("Avahi: create services\n"); - /* The server has startup successfully, so create our services */ - create_services(client); - break; - case AVAHI_CLIENT_FAILURE: - if (avahi_client_errno(client) != AVAHI_ERR_DISCONNECTED) { - IIO_ERROR("Avahi: Client failure: %s\n", - avahi_strerror(avahi_client_errno(client))); - break; - } - IIO_INFO("Avahi: server disconnected\n"); - avahi_client_free(client); - avahi.group = NULL; - avahi.client = client_new(); - break; - case AVAHI_CLIENT_S_COLLISION: - /* Same as AVAHI_SERVER_COLLISION */ - /* When the server is back in AVAHI_SERVER_RUNNING state - * we will register them again with the new host name. */ - IIO_DEBUG("Avahi: Client collision\n"); - /* Let's drop our registered services.*/ - if (avahi.group) - avahi_entry_group_reset(avahi.group); - break; - case AVAHI_CLIENT_S_REGISTERING: - /* Same as AVAHI_SERVER_REGISTERING */ - IIO_DEBUG("Avahi: Client group reset\n"); - if (avahi.group) - avahi_entry_group_reset(avahi.group); - break; - case AVAHI_CLIENT_CONNECTING: - IIO_DEBUG("Avahi: Client Connecting\n"); - break; - } - - /* NOTE: group is freed by avahi_client_free */ -} - -static AvahiClient * client_new(void) -{ - int ret; - AvahiClient * client; - - client = avahi_client_new(avahi_threaded_poll_get(avahi.poll), - AVAHI_CLIENT_NO_FAIL, __avahi_client_cb, NULL, &ret); - - /* No Daemon is handled by the avahi_start thread */ - if (!client && ret != AVAHI_ERR_NO_DAEMON) { - IIO_ERROR("Avahi: failure creating client: %s (%d)\n", - avahi_strerror(ret), ret); - } - - return client; -} - - -static void create_services(AvahiClient *c) -{ - int ret; - - if (!c) { - IIO_ERROR("create_services called with no valid client\n"); - goto fail; - } - - if (!avahi.group) { - avahi.group = avahi_entry_group_new(c, __avahi_group_cb, NULL); - if (!avahi.group) { - IIO_ERROR("avahi_entry_group_new() failed: %s\n", - avahi_strerror(avahi_client_errno(c))); - goto fail; - } - } - - if (!avahi_entry_group_is_empty(avahi.group)) { - IIO_DEBUG("Avahi group not empty\n"); - return; - } - - ret = avahi_entry_group_add_service(avahi.group, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, - 0, avahi.name, "_iio._tcp", NULL, NULL, IIOD_PORT, NULL); - if (ret < 0) { - if (ret == AVAHI_ERR_COLLISION) { - char *n; - n = avahi_alternative_service_name(avahi.name); - avahi_free(avahi.name); - avahi.name = n; - IIO_DEBUG("Service name collision, renaming service to '%s'\n", - avahi.name); - avahi_entry_group_reset(avahi.group); - create_services(c); - return; - } - IIO_ERROR("Failed to add _iio._tcp service: %s\n", avahi_strerror(ret)); - goto fail; - } - - ret = avahi_entry_group_commit(avahi.group); - if (ret < 0) { - IIO_ERROR("Failed to commit entry group: %s\n", avahi_strerror(ret)); - goto fail; - } - - IIO_INFO("Avahi: Registered '%s' to ZeroConf server %s\n", - avahi.name, avahi_client_get_version_string(c)); - - return; - -fail: - avahi_entry_group_reset(avahi.group); -} - -#define IIOD_ON "iiod on " - -static void start_avahi_thd(struct thread_pool *pool, void *d) -{ - - struct pollfd pfd[2]; - int ret = ENOMEM; - char label[AVAHI_LABEL_MAX]; - char host[AVAHI_LABEL_MAX - sizeof(IIOD_ON)]; - struct timespec ts; - ts.tv_nsec = 0; - ts.tv_sec = 1; - - pfd[1].fd = thread_pool_get_poll_fd(main_thread_pool); - pfd[1].events = POLLIN; - pfd[1].revents = 0; - - while(true) { - if (pfd[1].revents & POLLIN) /* STOP event */ - break; - - ret = gethostname(host, sizeof(host)); - IIO_ERROR("host %s\n", host); - if (ret || !strncmp(host, "none", sizeof("none") - 1)) - goto again; - - iio_snprintf(label, sizeof(label), "%s%s", IIOD_ON, host); - - if (!avahi.name) - avahi.name = avahi_strdup(label); - if (!avahi.name) - break; - - if (!avahi.poll) - avahi.poll = avahi_threaded_poll_new(); - if (!avahi.poll) { - goto again; - } - - if (!avahi.client) - avahi.client = client_new(); - if (avahi.client) - break; -again: - IIO_INFO("Avahi didn't start, try again later\n"); - nanosleep(&ts, NULL); - ts.tv_sec++; - /* If it hasn't started in 10 times over 60 seconds, - * it is not going to, so stop - */ - if (ts.tv_sec >= 11) - break; - } - - if (avahi.client && avahi.poll) { - avahi_threaded_poll_start(avahi.poll); - IIO_INFO("Avahi: Started.\n"); - } else { - shutdown_avahi(); - IIO_INFO("Avahi: Failed to start.\n"); - } -} - -static void start_avahi(void) -{ - int ret; - char err_str[1024]; - - IIO_INFO("Attempting to start Avahi\n"); - - avahi.poll = NULL; - avahi.client = NULL; - avahi.group = NULL; - avahi.name = NULL; - - /* In case dbus, or avahi deamon are not started, we create a thread - * that tries a few times to attach, if it can't within the first - * minute, it gives up. - */ - ret = thread_pool_add_thread(main_thread_pool, start_avahi_thd, NULL, "avahi_thd"); - if (ret) { - iio_strerror(ret, err_str, sizeof(err_str)); - IIO_ERROR("Failed to create new Avahi thread: %s\n", - err_str); - } -} -static void stop_avahi(void) -{ - shutdown_avahi(); - IIO_INFO("Avahi: Stopped\n"); -} -#endif /* HAVE_AVAHI */ - - static void usage(void) { unsigned int i; @@ -437,7 +109,8 @@ struct client_data *cdata = d; interpreter(cdata->ctx, cdata->fd, cdata->fd, cdata->debug, - true, false, pool); + true, false, pool, + cdata->xml_zstd, cdata->xml_zstd_len); IIO_INFO("Client exited\n"); close(cdata->fd); @@ -457,7 +130,8 @@ thread_pool_stop(main_thread_pool); } -static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio) +static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio, + const void *xml_zstd, size_t xml_zstd_len) { int flags; @@ -469,7 +143,7 @@ char err_str[1024]; iio_strerror(errno, err_str, sizeof(err_str)); IIO_ERROR("Could not get/set O_NONBLOCK on STDIN_FILENO" - " %s (%d)\n", err_str, -errno); + " %s\n", err_str); } flags = fcntl(STDOUT_FILENO, F_GETFL); @@ -479,16 +153,17 @@ char err_str[1024]; iio_strerror(errno, err_str, sizeof(err_str)); IIO_ERROR("Could not get/set O_NONBLOCK on STDOUT_FILENO" - " %s (%d)\n", err_str, -errno); + " %s\n", err_str); } } interpreter(ctx, STDIN_FILENO, STDOUT_FILENO, verbose, - false, use_aio, main_thread_pool); + false, use_aio, main_thread_pool, xml_zstd, xml_zstd_len); return EXIT_SUCCESS; } -static int main_server(struct iio_context *ctx, bool debug) +static int main_server(struct iio_context *ctx, bool debug, + const void *xml_zstd, size_t xml_zstd_len) { int ret, fd = -1, yes = 1, keepalive_time = 10, @@ -517,7 +192,7 @@ ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt SO_REUSEADDR : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt SO_REUSEADDR : %s\n", err_str); } #ifdef HAVE_IPV6 @@ -542,9 +217,8 @@ goto err_close_socket; } -#ifdef HAVE_AVAHI - start_avahi(); -#endif + if (HAVE_AVAHI) + start_avahi(main_thread_pool); pfd[0].fd = fd; pfd[0].events = POLLIN; @@ -588,35 +262,37 @@ ret = setsockopt(new, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt SO_KEEPALIVE : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt SO_KEEPALIVE : %s", err_str); } ret = setsockopt(new, IPPROTO_TCP, TCP_KEEPCNT, &keepalive_probes, sizeof(keepalive_probes)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt TCP_KEEPCNT : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt TCP_KEEPCNT : %s", err_str); } ret = setsockopt(new, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_time, sizeof(keepalive_time)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt TCP_KEEPIDLE : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt TCP_KEEPIDLE : %s", err_str); } ret = setsockopt(new, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl, sizeof(keepalive_intvl)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt TCP_KEEPINTVL : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt TCP_KEEPINTVL : %s", err_str); } ret = setsockopt(new, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)); if (ret < 0) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_WARNING("setsockopt TCP_NODELAY : %s (%d)", err_str, -errno); + IIO_WARNING("setsockopt TCP_NODELAY : %s", err_str); } cdata->fd = new; cdata->ctx = ctx; cdata->debug = debug; + cdata->xml_zstd = xml_zstd; + cdata->xml_zstd_len = xml_zstd_len; IIO_INFO("New client connected from %s\n", inet_ntoa(caddr.sin_addr)); @@ -632,9 +308,8 @@ } IIO_DEBUG("Cleaning up\n"); -#ifdef HAVE_AVAHI - stop_avahi(); -#endif + if (HAVE_AVAHI) + stop_avahi(); close(fd); return EXIT_SUCCESS; @@ -643,17 +318,46 @@ return EXIT_FAILURE; } +static void *get_xml_zstd_data(const struct iio_context *ctx, size_t *out_len) +{ +#if WITH_ZSTD + const char *xml = iio_context_get_xml(ctx); + size_t len, xml_len = strlen(xml); + void *buf; + size_t ret; + + len = ZSTD_compressBound(xml_len); + buf = malloc(len); + if (!buf) + return NULL; + + ret = ZSTD_compress(buf, len, xml, xml_len, 3); + if (ZSTD_isError(ret)) { + IIO_WARNING("Unable to compress XML string: %s\n", + ZSTD_getErrorName(xml_len)); + free(buf); + return NULL; + } + + *out_len = ret; + + return buf; +#else + return NULL; +#endif +} + int main(int argc, char **argv) { bool debug = false, interactive = false, use_aio = false; -#ifdef WITH_IIOD_USBD long nb_pipes = 3; char *end; -#endif struct iio_context *ctx; int c, option_index = 0; char *ffs_mountpoint = NULL; char err_str[1024]; + void *xml_zstd; + size_t xml_zstd_len = 0; int ret; while ((c = getopt_long(argc, argv, "+hVdDiaF:n:", @@ -669,23 +373,27 @@ interactive = true; break; case 'a': -#ifdef WITH_AIO + if (!WITH_AIO) { + IIO_ERROR("IIOD was not compiled with AIO support.\n"); + return EXIT_FAILURE; + } + use_aio = true; break; -#else - IIO_ERROR("IIOD was not compiled with AIO support.\n"); - return EXIT_FAILURE; -#endif case 'F': -#ifdef WITH_IIOD_USBD + if (!WITH_IIOD_USBD) { + IIO_ERROR("IIOD was not compiled with USB support.\n"); + return EXIT_FAILURE; + } + ffs_mountpoint = optarg; break; -#else - IIO_ERROR("IIOD was not compiled with USB support.\n"); - return EXIT_FAILURE; -#endif case 'n': -#ifdef WITH_IIOD_USBD + if (!WITH_IIOD_USBD) { + IIO_ERROR("IIOD was not compiled with USB support.\n"); + return EXIT_FAILURE; + } + errno = 0; nb_pipes = strtol(optarg, &end, 10); if (optarg == end || nb_pipes < 1 || errno == ERANGE) { @@ -693,10 +401,6 @@ return EXIT_FAILURE; } break; -#else - IIO_ERROR("IIOD was not compiled with USB support.\n"); - return EXIT_FAILURE; -#endif case 'h': usage(); return EXIT_SUCCESS; @@ -716,6 +420,8 @@ return EXIT_FAILURE; } + xml_zstd = get_xml_zstd_data(ctx, &xml_zstd_len); + main_thread_pool = thread_pool_new(); if (!main_thread_pool) { iio_strerror(errno, err_str, sizeof(err_str)); @@ -729,39 +435,36 @@ set_handler(SIGINT, sig_handler); set_handler(SIGTERM, sig_handler); - if (ffs_mountpoint) { -#ifdef WITH_IIOD_USBD + if (WITH_IIOD_USBD && ffs_mountpoint) { /* We pass use_aio == true directly, this is ensured to be true * by the CMake script. */ ret = start_usb_daemon(ctx, ffs_mountpoint, debug, true, (unsigned int) nb_pipes, - main_thread_pool); + main_thread_pool, xml_zstd, xml_zstd_len); if (ret) { iio_strerror(-ret, err_str, sizeof(err_str)); IIO_ERROR("Unable to start USB daemon: %s\n", err_str); ret = EXIT_FAILURE; goto out_destroy_thread_pool; } -#endif } if (interactive) - ret = main_interactive(ctx, debug, use_aio); + ret = main_interactive(ctx, debug, use_aio, xml_zstd, xml_zstd_len); else - ret = main_server(ctx, debug); + ret = main_server(ctx, debug, xml_zstd, xml_zstd_len); /* * In case we got here through an error in the main thread make sure all * the worker threads are signaled to shutdown. */ -#ifdef WITH_IIOD_USBD out_destroy_thread_pool: -#endif thread_pool_stop_and_wait(main_thread_pool); thread_pool_destroy(main_thread_pool); out_destroy_context: + free(xml_zstd); iio_context_destroy(ctx); return ret; diff -Nru libiio-0.21/iiod/lexer.l libiio-0.23/iiod/lexer.l --- libiio-0.21/iiod/lexer.l 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/lexer.l 2021-08-20 11:01:14.000000000 +0000 @@ -1,21 +1,11 @@ %{ +// 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 - * - * 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. - * - * */ + */ #include "parser.h" #include "ops.h" @@ -42,6 +32,10 @@ return PRINT; } +ZPRINT|zprint { + return ZPRINT; +} + EXIT|exit|QUIT|quit { return EXIT; } diff -Nru libiio-0.21/iiod/ops.c libiio-0.23/iiod/ops.c --- libiio-0.21/iiod/ops.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/ops.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,26 +1,15 @@ +// 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 - * - * 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. - * - * */ + */ #include "ops.h" #include "parser.h" #include "thread-pool.h" #include "../debug.h" -#include "../iio-private.h" #include #include @@ -105,6 +94,7 @@ struct iio_device *dev; struct iio_buffer *buf; unsigned int sample_size, nb_clients; + unsigned int samples_count; bool update_mask; bool cyclic; bool closed; @@ -131,6 +121,36 @@ * clients */ static pthread_mutex_t devlist_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int get_channel_number(const struct iio_channel *chn) +{ + const struct iio_device *dev = iio_channel_get_device(chn); + const struct iio_channel *other; + unsigned int i = 0; + + for (i = 0; i < iio_device_get_channels_count(dev); i++) { + other = iio_device_get_channel(dev, i); + if (other == chn) + break; + } + + return i; +} + +static inline const char *dev_label_or_name_or_id(const struct iio_device *dev) +{ + const char *name; + + name = iio_device_get_label(dev); + if (name) + return name; + + name = iio_device_get_name(dev); + if (name) + return name; + + return iio_device_get_id(dev); +} + #if WITH_AIO static ssize_t async_io(struct parser_pdata *pdata, void *buf, size_t len, bool do_read) @@ -353,7 +373,7 @@ output(pdata, "\n"); } else { char buf[128]; - iio_snprintf(buf, sizeof(buf), "%li\n", value); + snprintf(buf, sizeof(buf), "%li\n", value); output(pdata, buf); } } @@ -361,8 +381,10 @@ static ssize_t send_sample(const struct iio_channel *chn, void *src, size_t length, void *d) { + unsigned int number = get_channel_number(chn); struct sample_cb_info *info = d; - if (chn->index < 0 || !TEST_BIT(info->mask, chn->number)) + + if (iio_channel_get_index(chn) < 0 || !TEST_BIT(info->mask, number)) return 0; if (info->nb_bytes < length) return 0; @@ -388,8 +410,10 @@ static ssize_t receive_sample(const struct iio_channel *chn, void *dst, size_t length, void *d) { + unsigned int number = get_channel_number(chn); struct sample_cb_info *info = d; - if (chn->index < 0 || !TEST_BIT(info->mask, chn->number)) + + if (iio_channel_get_index(chn) < 0 || !TEST_BIT(info->mask, number)) return 0; if (info->cpt == info->nb_bytes) return 0; @@ -416,6 +440,7 @@ { struct parser_pdata *pdata = thd->pdata; bool demux = server_demux && dev->sample_size != thd->sample_size; + void *start; if (demux) len = (len / dev->sample_size) * thd->sample_size; @@ -428,20 +453,20 @@ unsigned int i; char buf[129], *ptr = buf; uint32_t *mask = demux ? thd->mask : dev->mask; - ssize_t ret, len; + ssize_t ret, length; - len = sizeof(buf); + length = sizeof(buf); /* Send the current mask */ for (i = dev->nb_words; i > 0 && ptr < buf + sizeof(buf); i--, ptr += 8) { - iio_snprintf(ptr, len, "%08x", mask[i - 1]); - len -= 8; + snprintf(ptr, length, "%08x", mask[i - 1]); + length -= 8; } *ptr = '\n'; - len--; + length--; - if (len < 0) { + if (length < 0) { IIO_ERROR("send_data: string length error\n"); return -ENOSPC; } @@ -455,7 +480,8 @@ if (!demux) { /* Short path */ - return write_all(pdata, dev->buf->buffer, len); + start = iio_buffer_start(dev->buf); + return write_all(pdata, start, len); } else { struct sample_cb_info info = { .pdata = pdata, @@ -481,11 +507,11 @@ if (dev->sample_size == thd->sample_size) { /* Short path: Receive directly in the buffer */ - size_t len = dev->buf->length; + size_t len = dev->sample_size * dev->samples_count; if (thd->nb < len) len = thd->nb; - return read_all(pdata, dev->buf->buffer, len); + return read_all(pdata, iio_buffer_start(dev->buf), len); } else { /* Long path: Mux the samples to the buffer */ @@ -537,7 +563,7 @@ ssize_t ret = 0; IIO_DEBUG("R/W thread started for device %s\n", - dev->name ? dev->name : dev->id); + dev_label_or_name_or_id(dev)); while (true) { bool has_readers = false, has_writers = false, @@ -566,14 +592,15 @@ if (entry->buf) iio_buffer_destroy(entry->buf); - for (i = 0; i < dev->nb_channels; i++) { - struct iio_channel *chn = dev->channels[i]; - long index = chn->index; + for (i = 0; i < iio_device_get_channels_count(dev); i++) { + struct iio_channel *chn = iio_device_get_channel(dev, i); + unsigned int number = get_channel_number(chn); + long index = iio_channel_get_index(chn); if (index < 0) continue; - if (TEST_BIT(entry->mask, chn->number)) + if (TEST_BIT(entry->mask, number)) iio_channel_enable(chn); else iio_channel_disable(chn); @@ -597,12 +624,13 @@ } IIO_DEBUG("IIO device %s reopened with new mask:\n", - dev->id); + dev_label_or_name_or_id(dev)); for (i = 0; i < nb_words; i++) IIO_DEBUG("Mask[%i] = 0x%08x\n", i, entry->mask[i]); entry->update_mask = false; entry->sample_size = iio_device_get_sample_size(dev); + entry->samples_count = samples_count; mask_updated = true; } @@ -685,8 +713,17 @@ pthread_mutex_lock(&entry->thdlist_lock); - /* Reset the size of the buffer to its maximum size */ - entry->buf->data_length = entry->buf->length; + /* Reset the size of the buffer to its maximum size. + * + * XXX(pcercuei): There is no way to perform this with + * the public libiio API. However, it probably does not + * matter; we only need to reset the size of the buffer + * if the buffer was used for receiving samples, and + * to date there is no IIO device that supports both + * receiving and sending samples. + * + * entry->buf->data_length = entry->buf->length; + */ /* Same comment as above */ for (thd = SLIST_FIRST(&entry->thdlist_head); @@ -754,7 +791,7 @@ pthread_mutex_unlock(&devlist_lock); IIO_DEBUG("Stopping R/W thread for device %s\n", - dev->name ? dev->name : dev->id); + dev_label_or_name_or_id(dev)); dev_entry_put(entry); } @@ -840,7 +877,7 @@ ptr = words + nb; while (*mask) { char buf[9]; - iio_snprintf(buf, sizeof(buf), "%.*s", 8, mask); + snprintf(buf, sizeof(buf), "%.*s", 8, mask); sscanf(buf, "%08x", --ptr); mask += 8; IIO_DEBUG("Mask[%lu]: 0x%08x\n", @@ -879,6 +916,48 @@ free_thd_entry(t); } +static ssize_t get_dev_sample_size_mask(const struct iio_device *dev, + const uint32_t *mask, size_t words) +{ + unsigned int i, len, number, + nb_channels = iio_device_get_channels_count(dev); + const struct iio_channel *prev = NULL; + const struct iio_channel *chn; + const struct iio_data_format *fmt; + long index; + ssize_t size = 0; + + if (words != (nb_channels + 31) / 32) + return -EINVAL; + + for (i = 0; i < nb_channels; i++) { + chn = iio_device_get_channel(dev, i); + number = get_channel_number(chn); + fmt = iio_channel_get_data_format(chn); + index = iio_channel_get_index(chn); + len = fmt->length / 8 * fmt->repeat; + + if (index < 0) + break; + if (!TEST_BIT(mask, number)) + continue; + + if (prev && index == iio_channel_get_index(prev)) { + prev = chn; + continue; + } + + if (size % len) + size += 2 * len - (size % len); + else + size += len; + + prev = chn; + } + + return size; +} + static int open_dev_helper(struct parser_pdata *pdata, struct iio_device *dev, size_t samples_count, const char *mask, bool cyclic) { @@ -893,7 +972,7 @@ if (!dev) return -ENODEV; - nb_channels = dev->nb_channels; + nb_channels = iio_device_get_channels_count(dev); if (len != ((nb_channels + 31) / 32) * 8) return -EINVAL; @@ -909,7 +988,7 @@ thd->mask = words; thd->nb = 0; thd->samples_count = samples_count; - thd->sample_size = iio_device_get_sample_size_mask(dev, words, len); + thd->sample_size = get_dev_sample_size_mask(dev, words, len); thd->pdata = pdata; thd->dev = dev; thd->eventfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); @@ -1260,12 +1339,13 @@ ret = iio_device_get_trigger(dev, &trigger); if (!ret && trigger) { + const char *name = iio_device_get_name(trigger); char buf[256]; - ret = strlen(trigger->name); + ret = strlen(name); print_value(pdata, ret); - iio_snprintf(buf, sizeof(buf), "%s\n", trigger->name); + snprintf(buf, sizeof(buf), "%s\n", name); ret = write_all(pdata, buf, ret + 1); } else { print_value(pdata, ret); @@ -1283,6 +1363,8 @@ int set_buffers_count(struct parser_pdata *pdata, struct iio_device *dev, long value) { + unsigned int i, nb = (unsigned int) value; + struct timespec wait; int ret = -EINVAL; if (!dev) { @@ -1290,9 +1372,24 @@ goto err_print_value; } - if (value >= 1) - ret = iio_device_set_kernel_buffers_count( - dev, (unsigned int) value); + if (nb >= 1) { + /* + * Avoid the same race condition described in open_dev_helper(). + * We must be sure that the buffer has not been enabled in order + * to set the number of kernel buffers. + */ + for (i = 0; i < 500; i++) { + ret = iio_device_set_kernel_buffers_count(dev, nb); + if (ret != -EBUSY) + break; + + wait.tv_sec = 0; + wait.tv_nsec = (100 * 1000); + do { + ret = nanosleep(&wait, &wait); + } while (ret == -1 && errno == EINTR); + } + } err_print_value: print_value(pdata, ret); return ret; @@ -1362,7 +1459,8 @@ } void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, - bool is_socket, bool use_aio, struct thread_pool *pool) + bool is_socket, bool use_aio, struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len) { yyscan_t scanner; struct parser_pdata pdata; @@ -1376,6 +1474,9 @@ pdata.verbose = verbose; pdata.pool = pool; + pdata.xml_zstd = xml_zstd; + pdata.xml_zstd_len = xml_zstd_len; + pdata.fd_in_is_socket = is_socket; pdata.fd_out_is_socket = is_socket; @@ -1422,8 +1523,8 @@ yylex_destroy(scanner); /* Close all opened devices */ - for (i = 0; i < ctx->nb_devices; i++) - close_dev_helper(&pdata, ctx->devices[i]); + for (i = 0; i < iio_context_get_devices_count(ctx); i++) + close_dev_helper(&pdata, iio_context_get_device(ctx, i)); #if WITH_AIO if (use_aio) { diff -Nru libiio-0.21/iiod/ops.h libiio-0.23/iiod/ops.h --- libiio-0.21/iiod/ops.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/ops.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,29 +1,20 @@ +/* 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 - * - * 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. - * - * */ + */ #ifndef __OPS_H__ #define __OPS_H__ -#include "../iio-private.h" +#include "../iio-config.h" #include "queue.h" #include #include +#include #include #include #include @@ -35,6 +26,8 @@ #include #endif +#define IIOD_PORT 30431 + #ifndef __bswap_constant_16 #define __bswap_constant_16(x) \ ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) @@ -46,9 +39,21 @@ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) #endif +#define BIT(x) (1 << (x)) +#define BIT_MASK(bit) BIT((bit) % 32) +#define BIT_WORD(bit) ((bit) / 32) +#define TEST_BIT(addr, bit) (!!(*(((uint32_t *) addr) + BIT_WORD(bit)) \ + & BIT_MASK(bit))) + struct thread_pool; extern struct thread_pool *main_thread_pool; +enum iio_attr_type { + IIO_ATTR_TYPE_DEVICE, + IIO_ATTR_TYPE_DEBUG, + IIO_ATTR_TYPE_BUFFER, +}; + struct parser_pdata { struct iio_context *ctx; bool stop, verbose; @@ -68,18 +73,28 @@ #endif struct thread_pool *pool; + const void *xml_zstd; + size_t xml_zstd_len; + ssize_t (*writefd)(struct parser_pdata *pdata, const void *buf, size_t len); ssize_t (*readfd)(struct parser_pdata *pdata, void *buf, size_t len); }; extern bool server_demux; /* Defined in iiod.c */ +static inline void *zalloc(size_t size) +{ + return calloc(1, size); +} + void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, - bool is_socket, bool use_aio, struct thread_pool *pool); + bool is_socket, bool use_aio, struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len); int start_usb_daemon(struct iio_context *ctx, const char *ffs, bool debug, bool use_aio, unsigned int nb_pipes, - struct thread_pool *pool); + struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len); int open_dev(struct parser_pdata *pdata, struct iio_device *dev, size_t samples_count, const char *mask, bool cyclic); diff -Nru libiio-0.21/iiod/parser.y libiio-0.23/iiod/parser.y --- libiio-0.21/iiod/parser.y 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/parser.y 2021-08-20 11:01:14.000000000 +0000 @@ -1,21 +1,11 @@ %{ +// 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 - * - * 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. - * - * */ + */ #include "ops.h" #include "parser.h" @@ -76,6 +66,7 @@ %token OPEN %token CLOSE %token PRINT +%token ZPRINT %token READ %token READBUF %token WRITEBUF @@ -118,6 +109,8 @@ "\t\tClose the current session\n" "\tPRINT\n" "\t\tDisplays a XML string corresponding to the current IIO context\n" + "\tZPRINT\n" + "\t\tGet a compressed XML string corresponding to the current IIO context\n" "\tVERSION\n" "\t\tGet the version of libiio in use\n" "\tTIMEOUT \n" @@ -162,6 +155,25 @@ output(pdata, "\n"); YYACCEPT; } + | ZPRINT END { + struct parser_pdata *pdata = yyget_extra(scanner); + if (pdata->xml_zstd) { + if (!pdata->verbose) { + char buf[128]; + sprintf(buf, "%lu\n", (unsigned long)pdata->xml_zstd_len); + output(pdata, buf); + } + if (write_all(pdata, pdata->xml_zstd, pdata->xml_zstd_len) <= 0) + pdata->stop = true; + output(pdata, "\n"); + YYACCEPT; + } else { + char buf[128]; + sprintf(buf, "%d\n", -EINVAL); + output(pdata, buf); + YYABORT; + } + } | TIMEOUT SPACE WORD END { char *word = $3; struct parser_pdata *pdata = yyget_extra(scanner); diff -Nru libiio-0.21/iiod/thread-pool.c libiio-0.23/iiod/thread-pool.c --- libiio-0.21/iiod/thread-pool.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/thread-pool.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2016 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. */ #include "thread-pool.h" diff -Nru libiio-0.21/iiod/thread-pool.h libiio-0.23/iiod/thread-pool.h --- libiio-0.21/iiod/thread-pool.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/thread-pool.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,18 +1,9 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2016 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. */ #ifndef __THREAD_POOL_H__ diff -Nru libiio-0.21/iiod/usbd.c libiio-0.23/iiod/usbd.c --- libiio-0.21/iiod/usbd.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod/usbd.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,22 +1,12 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2016 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. */ #include "../debug.h" -#include "../iio-private.h" #include "ops.h" #include "thread-pool.h" @@ -54,6 +44,9 @@ bool debug, use_aio; struct thread_pool **pool; unsigned int nb_pipes; + + const void *xml_zstd; + size_t xml_zstd_len; }; struct usbd_client_pdata { @@ -79,7 +72,8 @@ interpreter(pdata->pdata->ctx, pdata->ep_in, pdata->ep_out, pdata->pdata->debug, false, - pdata->pdata->use_aio, pool); + pdata->pdata->use_aio, pool, + pdata->pdata->xml_zstd, pdata->pdata->xml_zstd_len); close(pdata->ep_in); close(pdata->ep_out); @@ -106,14 +100,14 @@ * before opening the endpoints again. */ thread_pool_stop_and_wait(pdata->pool[pipe_id]); - iio_snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 1); + snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 1); cpdata->ep_out = open(buf, O_WRONLY); if (cpdata->ep_out < 0) { err = -errno; goto err_free_cpdata; } - iio_snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 2); + snprintf(buf, sizeof(buf), "%s/ep%u", pdata->ffs, pipe_id * 2 + 2); cpdata->ep_in = open(buf, O_RDONLY); if (cpdata->ep_in < 0) { err = -errno; @@ -336,7 +330,8 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs, bool debug, bool use_aio, unsigned int nb_pipes, - struct thread_pool *pool) + struct thread_pool *pool, + const void *xml_zstd, size_t xml_zstd_len) { struct usbd_pdata *pdata; unsigned int i; @@ -361,7 +356,7 @@ goto err_free_pdata_pool; } - iio_snprintf(buf, sizeof(buf), "%s/ep0", ffs); + snprintf(buf, sizeof(buf), "%s/ep0", ffs); pdata->ep0_fd = open(buf, O_RDWR); if (pdata->ep0_fd < 0) { @@ -384,6 +379,8 @@ pdata->ctx = ctx; pdata->debug = debug; pdata->use_aio = use_aio; + pdata->xml_zstd = xml_zstd; + pdata->xml_zstd_len = xml_zstd_len; ret = thread_pool_add_thread(pool, usbd_main, pdata, "usbd_main_thd"); if (!ret) diff -Nru libiio-0.21/iiod-client.c libiio-0.23/iiod-client.c --- libiio-0.21/iiod-client.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod-client.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,23 +1,14 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2020 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * */ #include "debug.h" #include "iiod-client.h" +#include "iio-config.h" #include "iio-lock.h" #include "iio-private.h" @@ -25,6 +16,9 @@ #include #include #include +#if WITH_ZSTD +#include +#endif struct iiod_client { struct iio_context_pdata *pdata; @@ -32,8 +26,19 @@ struct iio_mutex *lock; }; +void iiod_client_mutex_lock(struct iiod_client *client) +{ + iio_mutex_lock(client->lock); +} + +void iiod_client_mutex_unlock(struct iiod_client *client) +{ + iio_mutex_unlock(client->lock); +} + static ssize_t iiod_client_read_integer(struct iiod_client *client, - void *desc, int *val) + struct iiod_client_pdata *desc, + int *val) { unsigned int i; char buf[1024], *ptr = NULL, *end; @@ -70,7 +75,8 @@ } static int iiod_client_exec_command(struct iiod_client *client, - void *desc, const char *cmd) + struct iiod_client_pdata *desc, + const char *cmd) { int resp; ssize_t ret; @@ -84,7 +90,8 @@ } static ssize_t iiod_client_write_all(struct iiod_client *client, - void *desc, const void *src, size_t len) + struct iiod_client_pdata *desc, + const void *src, size_t len) { struct iio_context_pdata *pdata = client->pdata; const struct iiod_client_ops *ops = client->ops; @@ -111,7 +118,8 @@ } static ssize_t iiod_client_read_all(struct iiod_client *client, - void *desc, void *dst, size_t len) + struct iiod_client_pdata *desc, + void *dst, size_t len) { struct iio_context_pdata *pdata = client->pdata; const struct iiod_client_ops *ops = client->ops; @@ -138,7 +146,7 @@ } struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, - struct iio_mutex *lock, const struct iiod_client_ops *ops) + const struct iiod_client_ops *ops) { struct iiod_client *client; @@ -148,19 +156,31 @@ return NULL; } - client->lock = lock; + client->lock = iio_mutex_create(); + if (!client->lock) { + errno = ENOMEM; + goto err_free_client; + } + client->pdata = pdata; client->ops = ops; return client; + +err_free_client: + free(client); + return NULL; } void iiod_client_destroy(struct iiod_client *client) { + iio_mutex_destroy(client->lock); free(client); } -int iiod_client_get_version(struct iiod_client *client, void *desc, - unsigned int *major, unsigned int *minor, char *git_tag) +int iiod_client_get_version(struct iiod_client *client, + struct iiod_client_pdata *desc, + unsigned int *major, unsigned int *minor, + char *git_tag) { struct iio_context_pdata *pdata = client->pdata; const struct iiod_client_ops *ops = client->ops; @@ -209,8 +229,10 @@ return 0; } -int iiod_client_get_trigger(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_device **trigger) +int iiod_client_get_trigger(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_device **trigger) { const struct iio_context *ctx = iio_device_get_context(dev); unsigned int i, nb_devices = iio_context_get_devices_count(ctx); @@ -264,8 +286,10 @@ return ret; } -int iiod_client_set_trigger(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_device *trigger) +int iiod_client_set_trigger(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_device *trigger) { char buf[1024]; int ret; @@ -285,8 +309,10 @@ return ret; } -int iiod_client_set_kernel_buffers_count(struct iiod_client *client, void *desc, - const struct iio_device *dev, unsigned int nb_blocks) +int iiod_client_set_kernel_buffers_count(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + unsigned int nb_blocks) { int ret; char buf[1024]; @@ -301,7 +327,8 @@ } int iiod_client_set_timeout(struct iiod_client *client, - void *desc, unsigned int timeout) + struct iiod_client_pdata *desc, + unsigned int timeout) { int ret; char buf[1024]; @@ -314,8 +341,9 @@ return ret; } -static int iiod_client_discard(struct iiod_client *client, void *desc, - char *buf, size_t buf_len, size_t to_discard) +static int iiod_client_discard(struct iiod_client *client, + struct iiod_client_pdata *desc, + char *buf, size_t buf_len, size_t to_discard) { do { size_t read_len; @@ -336,9 +364,12 @@ return 0; } -ssize_t iiod_client_read_attr(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_channel *chn, - const char *attr, char *dest, size_t len, enum iio_attr_type type) +ssize_t iiod_client_read_attr(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_channel *chn, + const char *attr, char *dest, + size_t len, enum iio_attr_type type) { const char *id = iio_device_get_id(dev); char buf[1024]; @@ -417,9 +448,12 @@ return ret; } -ssize_t iiod_client_write_attr(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_channel *chn, - const char *attr, const char *src, size_t len, enum iio_attr_type type) +ssize_t iiod_client_write_attr(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_channel *chn, + const char *attr, const char *src, + size_t len, enum iio_attr_type type) { struct iio_context_pdata *pdata = client->pdata; const struct iiod_client_ops *ops = client->ops; @@ -494,18 +528,29 @@ return ret; } -struct iio_context * iiod_client_create_context( - struct iiod_client *client, void *desc) +static struct iio_context * +iiod_client_create_context_private(struct iiod_client *client, + struct iiod_client_pdata *desc, bool zstd) { + const char *cmd = zstd ? "ZPRINT\r\n" : "PRINT\r\n"; struct iio_context *ctx = NULL; size_t xml_len; char *xml; int ret; iio_mutex_lock(client->lock); - ret = iiod_client_exec_command(client, desc, "PRINT\r\n"); - if (ret < 0) + ret = iiod_client_exec_command(client, desc, cmd); + if (ret < 0) { + if (ret == -EINVAL && zstd) { + /* If the ZPRINT command does not exist, try again + * with the regular PRINT command. */ + iio_mutex_unlock(client->lock); + + return iiod_client_create_context_private(client, desc, false); + } + goto out_unlock; + } xml_len = (size_t) ret; xml = malloc(xml_len + 1); @@ -519,6 +564,41 @@ if (ret < 0) goto out_free_xml; +#if WITH_ZSTD + if (zstd) { + unsigned long long len; + char *xml_zstd; + + IIO_DEBUG("Received ZSTD-compressed XML string.\n"); + + len = ZSTD_getFrameContentSize(xml, xml_len); + if (len == ZSTD_CONTENTSIZE_UNKNOWN || + len == ZSTD_CONTENTSIZE_ERROR) { + ret = -EIO; + goto out_free_xml; + } + + xml_zstd = malloc(len); + if (!xml_zstd) { + ret = -ENOMEM; + goto out_free_xml; + } + + xml_len = ZSTD_decompress(xml_zstd, len, xml, xml_len); + if (ZSTD_isError(xml_len)) { + IIO_ERROR("Unable to decompress ZSTD data: %s\n", + ZSTD_getErrorName(xml_len)); + ret = -EIO; + free(xml_zstd); + goto out_free_xml; + } + + /* Free compressed data, make "xml" point to uncompressed data */ + free(xml); + xml = xml_zstd; + } +#endif + ctx = iio_create_xml_context_mem(xml, xml_len); if (!ctx) ret = -errno; @@ -532,8 +612,16 @@ return ctx; } -int iiod_client_open_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, size_t samples_count, bool cyclic) +struct iio_context * iiod_client_create_context(struct iiod_client *client, + struct iiod_client_pdata *desc) +{ + return iiod_client_create_context_private(client, desc, WITH_ZSTD); +} + +int iiod_client_open_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + size_t samples_count, bool cyclic) { char buf[1024], *ptr; size_t i; @@ -559,8 +647,9 @@ return iiod_client_exec_command(client, desc, buf); } -int iiod_client_close_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev) +int iiod_client_close_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev) { char buf[1024]; @@ -569,7 +658,8 @@ } static int iiod_client_read_mask(struct iiod_client *client, - void *desc, uint32_t *mask, size_t words) + struct iiod_client_pdata *desc, + uint32_t *mask, size_t words) { size_t i; ssize_t ret; @@ -603,9 +693,11 @@ return (int) ret; } -ssize_t iiod_client_read_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words) +ssize_t iiod_client_read_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + void *dst, size_t len, + uint32_t *mask, size_t words) { unsigned int nb_channels = iio_device_get_channels_count(dev); uintptr_t ptr = (uintptr_t) dst; @@ -659,8 +751,10 @@ return read; } -ssize_t iiod_client_write_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, const void *src, size_t len) +ssize_t iiod_client_write_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const void *src, size_t len) { ssize_t ret; char buf[1024]; diff -Nru libiio-0.21/iiod-client.h libiio-0.23/iiod-client.h --- libiio-0.21/iiod-client.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iiod-client.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,19 +1,9 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * */ #ifndef _IIOD_CLIENT_H @@ -23,49 +13,87 @@ struct iio_mutex; struct iiod_client; +struct iiod_client_pdata; struct iio_context_pdata; struct iiod_client_ops { ssize_t (*write)(struct iio_context_pdata *pdata, - void *desc, const char *src, size_t len); + struct iiod_client_pdata *desc, + const char *src, size_t len); ssize_t (*read)(struct iio_context_pdata *pdata, - void *desc, char *dst, size_t len); + struct iiod_client_pdata *desc, + char *dst, size_t len); ssize_t (*read_line)(struct iio_context_pdata *pdata, - void *desc, char *dst, size_t len); + struct iiod_client_pdata *desc, + char *dst, size_t len); }; +void iiod_client_mutex_lock(struct iiod_client *client); +void iiod_client_mutex_unlock(struct iiod_client *client); + struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, - struct iio_mutex *lock, const struct iiod_client_ops *ops); + const struct iiod_client_ops *ops); void iiod_client_destroy(struct iiod_client *client); -int iiod_client_get_version(struct iiod_client *client, void *desc, - unsigned int *major, unsigned int *minor, char *git_tag); -int iiod_client_get_trigger(struct iiod_client *client, void *desc, - const struct iio_device *dev, - const struct iio_device **trigger); -int iiod_client_set_trigger(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_device *trigger); +int iiod_client_get_version(struct iiod_client *client, + struct iiod_client_pdata *desc, + unsigned int *major, unsigned int *minor, + char *git_tag); + +int iiod_client_get_trigger(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_device **trigger); + +int iiod_client_set_trigger(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_device *trigger); + int iiod_client_set_kernel_buffers_count(struct iiod_client *client, - void *desc, const struct iio_device *dev, unsigned int nb_blocks); + struct iiod_client_pdata *desc, + const struct iio_device *dev, + unsigned int nb_blocks); + int iiod_client_set_timeout(struct iiod_client *client, - void *desc, unsigned int timeout); -ssize_t iiod_client_read_attr(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_channel *chn, - const char *attr, char *dest, size_t len, enum iio_attr_type type); -ssize_t iiod_client_write_attr(struct iiod_client *client, void *desc, - const struct iio_device *dev, const struct iio_channel *chn, - const char *attr, const char *src, size_t len, enum iio_attr_type type); -int iiod_client_open_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, size_t samples_count, - bool cyclic); -int iiod_client_close_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev); -ssize_t iiod_client_read_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words); -ssize_t iiod_client_write_unlocked(struct iiod_client *client, void *desc, - const struct iio_device *dev, const void *src, size_t len); -struct iio_context * iiod_client_create_context( - struct iiod_client *client, void *desc); + struct iiod_client_pdata *desc, + unsigned int timeout); + +ssize_t iiod_client_read_attr(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_channel *chn, + const char *attr, char *dest, size_t len, + enum iio_attr_type type); + +ssize_t iiod_client_write_attr(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const struct iio_channel *chn, + const char *attr, const char *src, + size_t len, enum iio_attr_type type); + +int iiod_client_open_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + size_t samples_count, bool cyclic); + +int iiod_client_close_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev); + +ssize_t iiod_client_read_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + void *dst, size_t len, + uint32_t *mask, size_t words); + +ssize_t iiod_client_write_unlocked(struct iiod_client *client, + struct iiod_client_pdata *desc, + const struct iio_device *dev, + const void *src, size_t len); + +struct iio_context * iiod_client_create_context(struct iiod_client *client, + struct iiod_client_pdata *desc); #endif /* _IIOD_CLIENT_H */ diff -Nru libiio-0.21/iio.h libiio-0.23/iio.h --- libiio-0.21/iio.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iio.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +/* 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 - * - * 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 iio.h * @brief Public interface */ @@ -72,7 +62,9 @@ #endif #ifdef _WIN32 -# ifdef LIBIIO_EXPORTS +# ifdef LIBIIO_STATIC +# define __api +# elif defined(LIBIIO_EXPORTS) # define __api __declspec(dllexport) # else # define __api __declspec(dllimport) @@ -190,6 +182,7 @@ IIO_MOD_PM10, IIO_MOD_ETHANOL, IIO_MOD_H2, + IIO_MOD_O2, }; /* ---------------------------------------------------------------------------*/ @@ -356,11 +349,9 @@ * @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 network context if the IIOD_REMOTE - * environment variable is set to the hostname where the IIOD server runs. If - * set to an empty string, the server will be discovered using ZeroConf. - * If the environment variable is not set, a local context will be created - * instead. */ + * 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); @@ -538,13 +529,13 @@ const struct iio_context *ctx, unsigned int index); -/** @brief Try to find a device structure by its name of ID +/** @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 name or the ID of - * the device to search for + * @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 name or ID does not correspond to any known device, NULL is - * returned */ + * @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); @@ -589,6 +580,14 @@ __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 */ diff -Nru libiio-0.21/iio-lock.h libiio-0.23/iio-lock.h --- libiio-0.21/iio-lock.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iio-lock.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,19 +1,9 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * */ #ifndef _IIO_LOCK_H diff -Nru libiio-0.21/iio-private.h libiio-0.23/iio-private.h --- libiio-0.21/iio-private.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/iio-private.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,50 +1,34 @@ +/* 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 - * - * 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. - * - * */ + */ #ifndef __IIO_PRIVATE_H__ #define __IIO_PRIVATE_H__ /* Include public interface */ #include "iio.h" - +#include "iio-backend.h" #include "iio-config.h" #include #ifdef _MSC_BUILD #define inline __inline -#define iio_snprintf sprintf_s #define iio_sscanf sscanf_s #else -#define iio_snprintf snprintf #define iio_sscanf sscanf #endif -#ifdef _WIN32 -# ifdef LIBIIO_EXPORTS -# define __api __declspec(dllexport) -# else -# define __api __declspec(dllimport) -# endif -#elif __GNUC__ >= 4 -# define __api __attribute__((visibility ("default"))) +#if defined(__MINGW32__) +# define __iio_printf __attribute__((__format__(gnu_printf, 3, 4))) +#elif defined(__GNUC__) +# define __iio_printf __attribute__((__format__(printf, 3, 4))) #else -# define __api +# define __iio_printf #endif #define ARRAY_SIZE(x) (sizeof(x) ? sizeof(x) / sizeof((x)[0]) : 0) @@ -81,23 +65,29 @@ #define MAX_CTX_NAME NAME_MAX /* nominally "xml" */ #define MAX_CTX_DESC NAME_MAX /* nominally "linux ..." */ #define MAX_ATTR_NAME NAME_MAX /* encoded in the sysfs filename */ -#define MAX_ATTR_VALUE PAGESIZE /* Linux page size, could be anything */ +#define MAX_ATTR_VALUE (8 * PAGESIZE) /* 8x Linux page size, could be anything */ + +#ifdef _MSC_BUILD +/* Windows only runs on little-endian systems */ +#define is_little_endian() true +#else +#define is_little_endian() (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#endif /* ntohl/htonl are a nightmare to use in cross-platform applications, * since they are defined in different headers on different platforms. * iio_be32toh/iio_htobe32 are just clones of ntohl/htonl. */ static inline uint32_t iio_be32toh(uint32_t word) { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + if (!is_little_endian()) + return word; + #ifdef __GNUC__ return __builtin_bswap32(word); #else return ((word & 0xff) << 24) | ((word & 0xff00) << 8) | ((word >> 8) & 0xff00) | ((word >> 24) & 0xff); #endif -#else - return word; -#endif } static inline uint32_t iio_htobe32(uint32_t word) @@ -111,54 +101,20 @@ return calloc(1, size); } -enum iio_attr_type { - IIO_ATTR_TYPE_DEVICE = 0, - IIO_ATTR_TYPE_DEBUG, - IIO_ATTR_TYPE_BUFFER, -}; - -struct iio_backend_ops { - struct iio_context * (*clone)(const struct iio_context *ctx); - ssize_t (*read)(const struct iio_device *dev, void *dst, size_t len, - uint32_t *mask, size_t words); - ssize_t (*write)(const struct iio_device *dev, - const void *src, size_t len); - int (*open)(const struct iio_device *dev, - size_t samples_count, bool cyclic); - int (*close)(const struct iio_device *dev); - int (*get_fd)(const struct iio_device *dev); - int (*set_blocking_mode)(const struct iio_device *dev, bool blocking); - - void (*cancel)(const struct iio_device *dev); - - int (*set_kernel_buffers_count)(const struct iio_device *dev, - unsigned int nb_blocks); - ssize_t (*get_buffer)(const struct iio_device *dev, - void **addr_ptr, size_t bytes_used, - uint32_t *mask, size_t words); - - ssize_t (*read_device_attr)(const struct iio_device *dev, - const char *attr, char *dst, size_t len, enum iio_attr_type); - ssize_t (*write_device_attr)(const struct iio_device *dev, - const char *attr, const char *src, - size_t len, enum iio_attr_type); - ssize_t (*read_channel_attr)(const struct iio_channel *chn, - const char *attr, char *dst, size_t len); - ssize_t (*write_channel_attr)(const struct iio_channel *chn, - const char *attr, const char *src, size_t len); - - int (*get_trigger)(const struct iio_device *dev, - const struct iio_device **trigger); - int (*set_trigger)(const struct iio_device *dev, - const struct iio_device *trigger); - - void (*shutdown)(struct iio_context *ctx); +static inline __check_ret bool IS_ERR(const void *ptr) +{ + return (uintptr_t)ptr >= (uintptr_t)-4095; +} - int (*get_version)(const struct iio_context *ctx, unsigned int *major, - unsigned int *minor, char git_tag[8]); +static inline __check_ret int PTR_ERR(const void *ptr) +{ + return (int)(intptr_t) ptr; +} - int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); -}; +static inline __check_ret void * ERR_PTR(int err) +{ + return (void *)(intptr_t) err; +} /* * If these structures are updated, the qsort functions defined in sort.c @@ -168,7 +124,6 @@ struct iio_context_pdata; struct iio_device_pdata; struct iio_channel_pdata; -struct iio_scan_backend_context; struct iio_channel_attr { char *name; @@ -181,6 +136,10 @@ const char *name; char *description; + unsigned int major; + unsigned int minor; + char *git_tag; + struct iio_device **devices; unsigned int nb_devices; @@ -210,21 +169,21 @@ unsigned int number; }; +struct iio_dev_attrs { + char **names; + unsigned int num; +}; + struct iio_device { const struct iio_context *ctx; struct iio_device_pdata *pdata; void *userdata; - char *name, *id; - - char **attrs; - unsigned int nb_attrs; - - char **buffer_attrs; - unsigned int nb_buffer_attrs; + char *name, *id, *label; - char **debug_attrs; - unsigned int nb_debug_attrs; + struct iio_dev_attrs attrs; + struct iio_dev_attrs buffer_attrs; + struct iio_dev_attrs debug_attrs; struct iio_channel **channels; unsigned int nb_channels; @@ -254,17 +213,17 @@ struct iio_context_info **info; }; -struct iio_context_info ** iio_scan_result_add( - struct iio_scan_result *scan_result, size_t num); +struct iio_context_info * +iio_scan_result_add(struct iio_scan_result *scan_result); void free_channel(struct iio_channel *chn); void free_device(struct iio_device *dev); -char *iio_channel_get_xml(const struct iio_channel *chn, size_t *len); -char *iio_device_get_xml(const struct iio_device *dev, size_t *len); +ssize_t iio_snprintf_channel_xml(char *str, ssize_t slen, + const struct iio_channel *chn); +ssize_t iio_snprintf_device_xml(char *str, ssize_t slen, + const struct iio_device *dev); -char *encode_xml_ndup(const char * input); -char *iio_context_create_xml(const struct iio_context *ctx); int iio_context_init(struct iio_context *ctx); bool iio_device_is_tx(const struct iio_device *dev); @@ -285,27 +244,16 @@ struct iio_context * network_create_context(const char *hostname); struct iio_context * xml_create_context_mem(const char *xml, size_t len); struct iio_context * xml_create_context(const char *xml_file); -struct iio_context * usb_create_context(unsigned int bus, uint16_t address, - uint16_t intrfc); struct iio_context * usb_create_context_from_uri(const char *uri); struct iio_context * serial_create_context_from_uri(const char *uri); int local_context_scan(struct iio_scan_result *scan_result); -struct iio_scan_backend_context * usb_context_scan_init(void); -void usb_context_scan_free(struct iio_scan_backend_context *ctx); +int usb_context_scan(struct iio_scan_result *scan_result); -int usb_context_scan(struct iio_scan_backend_context *ctx, - struct iio_scan_result *scan_result); +int dnssd_context_scan(struct iio_scan_result *scan_result); -struct iio_scan_backend_context * dnssd_context_scan_init(void); -void dnssd_context_scan_free(struct iio_scan_backend_context *ctx); - -int dnssd_context_scan(struct iio_scan_backend_context *ctx, - struct iio_scan_result *scan_result); - -/* This function is not part of the API, but is used by the IIO daemon */ -__api ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev, +ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev, const uint32_t *mask, size_t words); void iio_channel_init_finalize(struct iio_channel *chn); @@ -315,9 +263,30 @@ size_t iio_strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize); char * iio_getenv (char * envvar); +int iio_context_add_device(struct iio_context *ctx, struct iio_device *dev); + int iio_context_add_attr(struct iio_context *ctx, const char *key, const char *value); -#undef __api +struct iio_context_pdata * iio_context_get_pdata(const struct iio_context *ctx); + +int add_iio_dev_attr(struct iio_dev_attrs *attrs, const char *attr, + const char *type, const char *dev_id); + +ssize_t __iio_printf iio_snprintf(char *buf, size_t len, const char *fmt, ...); + +ssize_t iio_xml_print_and_sanitized_param(char *ptr, ssize_t len, + const char *before, char *param, + const char *after); + +static inline void iio_update_xml_indexes(ssize_t ret, char **ptr, ssize_t *len, + ssize_t *alen) +{ + if (*ptr) { + *ptr += ret; + *len -= ret; + } + *alen += ret; +} #endif /* __IIO_PRIVATE_H__ */ diff -Nru libiio-0.21/libiio.pc.cmakein libiio-0.23/libiio.pc.cmakein --- libiio-0.21/libiio.pc.cmakein 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/libiio.pc.cmakein 2021-08-20 11:01:14.000000000 +0000 @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: libiio Description: Library for interfacing IIO devices diff -Nru libiio-0.21/libiio.rules.cmakein libiio-0.23/libiio.rules.cmakein --- libiio-0.21/libiio.rules.cmakein 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/libiio.rules.cmakein 2021-08-20 11:01:14.000000000 +0000 @@ -1 +1 @@ -SUBSYSTEM=="usb", PROGRAM=="/bin/sh -c '@CMAKE_INSTALL_FULL_BINDIR@/iio_info -s | grep %s{idVendor}:%s{idProduct}'", RESULT!="", MODE="666" +SUBSYSTEM=="usb", PROGRAM=="/bin/sh -c '@CMAKE_INSTALL_FULL_BINDIR@/iio_info -S usb | grep %s{idVendor}:%s{idProduct}'", RESULT!="", MODE="666" diff -Nru libiio-0.21/local.c libiio-0.23/local.c --- libiio-0.21/local.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/local.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,27 +1,15 @@ +// 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 - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-private.h" #include "sort.h" -#ifdef WITH_LOCAL_CONFIG #include "libini/ini.h" -#endif #include @@ -97,7 +85,7 @@ struct block *blocks; void **addrs; int last_dequeued; - bool is_high_speed, cyclic, cyclic_buffer_enqueued, buffer_enabled; + bool is_high_speed, cyclic, cyclic_buffer_enqueued; int cancel_fd; }; @@ -126,6 +114,9 @@ ret = ioctl(fd, request, data); } while (ret == -1 && errno == EINTR); + if (ret == -1) + ret = -errno; + return ret; } @@ -156,14 +147,12 @@ /* Free the backend data stored in every device structure */ unsigned int i; - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < iio_context_get_devices_count(ctx); i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); iio_device_close(dev); local_free_pdata(dev); } - - free(ctx->pdata); } /** Shrinks the first nb characters of a string @@ -288,7 +277,8 @@ .events = POLLIN, } }; - unsigned int rw_timeout_ms = dev->ctx->pdata->rw_timeout_ms; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); + unsigned int rw_timeout_ms = pdata->rw_timeout_ms; int timeout_rel; int ret; @@ -413,19 +403,16 @@ return ret; } -static ssize_t local_enable_buffer(const struct iio_device *dev) +static int local_buffer_enabled_set(const struct iio_device *dev, bool en) { - struct iio_device_pdata *pdata = dev->pdata; - ssize_t ret = 0; + int ret; - if (!pdata->buffer_enabled) { - ret = local_write_dev_attr(dev, - "buffer/enable", "1", 2, false); - if (ret >= 0) - pdata->buffer_enabled = true; - } + ret = (int) local_write_dev_attr(dev, "buffer/enable", en ? "1" : "0", + 2, false); + if (ret < 0) + return ret; - return ret; + return 0; } static int local_set_kernel_buffers_count(const struct iio_device *dev, @@ -473,8 +460,7 @@ ret = (ssize_t) ioctl_nointr(f, BLOCK_ENQUEUE_IOCTL, last_block); if (ret) { - ret = (ssize_t) -errno; - iio_strerror(errno, err_str, sizeof(err_str)); + iio_strerror(-ret, err_str, sizeof(err_str)); IIO_ERROR("Unable to enqueue block: %s\n", err_str); return ret; } @@ -496,13 +482,12 @@ memset(&block, 0, sizeof(block)); ret = (ssize_t) ioctl_nointr(f, BLOCK_DEQUEUE_IOCTL, &block); - } while (pdata->blocking && ret == -1 && errno == EAGAIN); + } while (pdata->blocking && ret == -EAGAIN); if (ret) { - ret = (ssize_t) -errno; if ((!pdata->blocking && ret != -EAGAIN) || (pdata->blocking && ret != -ETIMEDOUT)) { - iio_strerror(errno, err_str, sizeof(err_str)); + iio_strerror(-ret, err_str, sizeof(err_str)); IIO_ERROR("Unable to dequeue block: %s\n", err_str); } return ret; @@ -526,16 +511,16 @@ switch (type) { case IIO_ATTR_TYPE_DEVICE: - nb = dev->nb_attrs; - attrs = dev->attrs; + nb = dev->attrs.num; + attrs = dev->attrs.names; break; case IIO_ATTR_TYPE_DEBUG: - nb = dev->nb_debug_attrs; - attrs = dev->debug_attrs; + nb = dev->debug_attrs.num; + attrs = dev->debug_attrs.names; break; case IIO_ATTR_TYPE_BUFFER: - nb = dev->nb_buffer_attrs; - attrs = dev->buffer_attrs; + nb = dev->buffer_attrs.num; + attrs = dev->buffer_attrs.names; break; default: return -EINVAL; @@ -617,16 +602,16 @@ switch (type) { case IIO_ATTR_TYPE_DEVICE: - nb = dev->nb_attrs; - attrs = dev->attrs; + nb = dev->attrs.num; + attrs = dev->attrs.names; break; case IIO_ATTR_TYPE_DEBUG: - nb = dev->nb_debug_attrs; - attrs = dev->debug_attrs; + nb = dev->debug_attrs.num; + attrs = dev->debug_attrs.names; break; case IIO_ATTR_TYPE_BUFFER: - nb = dev->nb_buffer_attrs; - attrs = dev->buffer_attrs; + nb = dev->buffer_attrs.num; + attrs = dev->buffer_attrs.names; break; default: return -EINVAL; @@ -715,10 +700,16 @@ return -errno; ret = fread(dst, 1, len, f); + + /* if we didn't read the entire file, fail */ + if (!feof(f)) + ret = -EFBIG; + if (ret > 0) dst[ret - 1] = '\0'; else dst[0] = '\0'; + fflush(f); if (ferror(f)) ret = -errno; @@ -856,10 +847,8 @@ req.count = nb_blocks; ret = ioctl_nointr(fd, BLOCK_ALLOC_IOCTL, &req); - if (ret < 0) { - ret = -errno; + if (ret < 0) goto err_freemem; - } if (req.count == 0) { ret = -ENOMEM; @@ -873,16 +862,12 @@ for (i = 0; i < pdata->allocated_nb_blocks; i++) { pdata->blocks[i].id = i; ret = ioctl_nointr(fd, BLOCK_QUERY_IOCTL, &pdata->blocks[i]); - if (ret) { - ret = -errno; + if (ret) goto err_munmap; - } ret = ioctl_nointr(fd, BLOCK_ENQUEUE_IOCTL, &pdata->blocks[i]); - if (ret) { - ret = -errno; + if (ret) goto err_munmap; - } pdata->addrs[i] = mmap(0, pdata->blocks[i].size, PROT_READ | PROT_WRITE, @@ -910,6 +895,8 @@ return ret; } +static int local_close(const struct iio_device *dev); + static int local_open(const struct iio_device *dev, size_t samples_count, bool cyclic) { @@ -921,7 +908,7 @@ if (pdata->fd != -1) return -EBUSY; - ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false); + ret = local_buffer_enabled_set(dev, false); if (ret < 0) return ret; @@ -938,8 +925,8 @@ iio_snprintf(buf, sizeof(buf), "/dev/%s", dev->id); pdata->fd = open(buf, O_RDWR | O_CLOEXEC | O_NONBLOCK); if (pdata->fd == -1) { - ret = -errno; - goto err_close_cancel_fd; + close(pdata->cancel_fd); + return -errno; } /* Disable channels */ @@ -963,7 +950,6 @@ pdata->cyclic = cyclic; pdata->cyclic_buffer_enqueued = false; - pdata->buffer_enabled = false; pdata->samples_count = samples_count; ret = enable_high_speed(dev); @@ -992,17 +978,13 @@ goto err_close; } - ret = local_enable_buffer(dev); + ret = local_buffer_enabled_set(dev, true); if (ret < 0) goto err_close; return 0; err_close: - close(pdata->fd); - pdata->fd = -1; -err_close_cancel_fd: - close(pdata->cancel_fd); - pdata->cancel_fd = -1; + local_close(dev); return ret; } @@ -1010,16 +992,25 @@ { struct iio_device_pdata *pdata = dev->pdata; unsigned int i; - int ret; + char err_str[32]; + int ret, ret1; if (pdata->fd == -1) return -EBADF; + ret = 0; + ret1 = 0; if (pdata->is_high_speed) { - unsigned int i; - for (i = 0; i < pdata->allocated_nb_blocks; i++) - munmap(pdata->addrs[i], pdata->blocks[i].size); - ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); + if (pdata->addrs) { + for (i = 0; i < pdata->allocated_nb_blocks; i++) + munmap(pdata->addrs[i], pdata->blocks[i].size); + } + if (pdata->fd > -1) + ret = ioctl_nointr(pdata->fd, BLOCK_FREE_IOCTL, 0); + if (ret) { + iio_strerror(-ret, err_str, sizeof(err_str)); + IIO_ERROR("Error during ioctl(): %s\n", err_str); + } pdata->allocated_nb_blocks = 0; free(pdata->addrs); pdata->addrs = NULL; @@ -1027,25 +1018,58 @@ pdata->blocks = NULL; } - ret = close(pdata->fd); - if (ret) - return ret; - - close(pdata->cancel_fd); + ret1 = close(pdata->fd); + if (ret1) { + ret1 = -errno; + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Error during close() of main FD: %s\n", err_str); + if (ret == 0) + ret = ret1; + } pdata->fd = -1; - pdata->cancel_fd = -1; - ret = local_write_dev_attr(dev, "buffer/enable", "0", 2, false); + if (pdata->cancel_fd > -1) { + ret1 = close(pdata->cancel_fd); + pdata->cancel_fd = -1; + + if (ret1) { + ret1 = -errno; + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Error during close() of cancel FD): %s\n", + err_str); + if (ret == 0) + ret = ret1; + } + } + + ret1 = local_buffer_enabled_set(dev, false); + if (ret1) { + iio_strerror(-ret1, err_str, sizeof(err_str)); + IIO_ERROR("Error during buffer disable: %s\n", err_str); + if (ret == 0) + ret = ret1; + } for (i = 0; i < dev->nb_channels; i++) { struct iio_channel *chn = dev->channels[i]; - if (chn->pdata->enable_fn) - channel_write_state(chn, false); + if (!chn->pdata->enable_fn) + continue; + + ret1 = channel_write_state(chn, false); + if (ret1 == 0) + continue; + + ret1 = -errno; + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Error during channel[%u] disable: %s\n", + i, err_str); + if (ret == 0) + ret = ret1; } - return (ret < 0) ? ret : 0; + return ret; } static int local_get_fd(const struct iio_device *dev) @@ -1086,9 +1110,9 @@ return 0; } - nb = dev->ctx->nb_devices; + nb = iio_context_get_devices_count(dev->ctx); for (i = 0; i < (size_t) nb; i++) { - const struct iio_device *cur = dev->ctx->devices[i]; + const struct iio_device *cur = iio_context_get_device(dev->ctx, i); if (cur->name && !strcmp(cur->name, buf)) { *trigger = cur; return 0; @@ -1160,7 +1184,7 @@ ptr += len + 1; if (chn->name) { - size_t len = strlen(chn->name); + len = strlen(chn->name); if (strncmp(chn->name, ptr, len) == 0 && ptr[len] == '_') ptr += len + 1; } @@ -1184,9 +1208,24 @@ return 0; } +static int read_device_label(struct iio_device *dev) +{ + char buf[1024]; + ssize_t ret = iio_device_attr_read(dev, "label", buf, sizeof(buf)); + if (ret < 0) + return ret; + else if (ret == 0) + return -EIO; + + dev->label = iio_strdup(buf); + if (!dev->label) + return -ENOMEM; + else + return 0; +} + static int add_attr_to_device(struct iio_device *dev, const char *attr) { - char **attrs, *name; unsigned int i; for (i = 0; i < ARRAY_SIZE(device_attrs_blacklist); i++) @@ -1195,21 +1234,10 @@ if (!strcmp(attr, "name")) return read_device_name(dev); + if (!strcmp(attr, "label")) + return read_device_label(dev); - name = iio_strdup(attr); - if (!name) - return -ENOMEM; - - attrs = realloc(dev->attrs, (1 + dev->nb_attrs) * sizeof(char *)); - if (!attrs) { - free(name); - return -ENOMEM; - } - - attrs[dev->nb_attrs++] = name; - dev->attrs = attrs; - IIO_DEBUG("Added attr \'%s\' to device \'%s\'\n", attr, dev->id); - return 0; + return add_iio_dev_attr(&dev->attrs, attr, " ", dev->id); } static int handle_protected_scan_element_attr(struct iio_channel *chn, @@ -1388,51 +1416,45 @@ return 0; } -static int add_device_to_context(struct iio_context *ctx, - struct iio_device *dev) -{ - struct iio_device **devices = realloc(ctx->devices, - (ctx->nb_devices + 1) * sizeof(struct iio_device *)); - if (!devices) - return -ENOMEM; - - devices[ctx->nb_devices++] = dev; - ctx->devices = devices; - IIO_DEBUG("Added device \'%s\' to context \'%s\'\n", dev->id, ctx->name); - return 0; -} - static struct iio_channel *create_channel(struct iio_device *dev, char *id, const char *attr, const char *path, bool is_scan_element) { - struct iio_channel *chn = zalloc(sizeof(*chn)); + struct iio_channel *chn; + int err = -ENOMEM; + + chn = zalloc(sizeof(*chn)); if (!chn) - return NULL; + return ERR_PTR(-ENOMEM); chn->pdata = zalloc(sizeof(*chn->pdata)); if (!chn->pdata) goto err_free_chn; - if (!strncmp(attr, "out_", 4)) + if (!strncmp(attr, "out_", 4)) { chn->is_output = true; - else if (strncmp(attr, "in_", 3)) + } else if (strncmp(attr, "in_", 3)) { + err = -EINVAL; goto err_free_chn_pdata; + } chn->dev = dev; chn->id = id; chn->is_scan_element = is_scan_element; chn->index = -ENOENT; - if (!add_attr_to_channel(chn, attr, path, is_scan_element)) - return chn; + err = add_attr_to_channel(chn, attr, path, is_scan_element); + if (err) + goto err_free_chn_pdata; + + return chn; err_free_chn_pdata: free(chn->pdata->enable_fn); free(chn->pdata); err_free_chn: free(chn); - return NULL; + return ERR_PTR(err); } static int add_channel(struct iio_device *dev, const char *name, @@ -1460,17 +1482,16 @@ } chn = create_channel(dev, channel_id, name, path, dir_is_scan_elements); - if (!chn) { + if (IS_ERR(chn)) { free(channel_id); - return -ENXIO; + return PTR_ERR(chn); } iio_channel_init_finalize(chn); ret = add_channel_to_device(dev, chn); if (ret) { - free(chn->pdata->enable_fn); - free(chn->pdata); + local_free_channel_pdata(chn); free_channel(chn); } return ret; @@ -1560,10 +1581,10 @@ static int detect_and_move_global_attrs(struct iio_device *dev) { unsigned int i; - char **ptr = dev->attrs; + char **ptr = dev->attrs.names; - for (i = 0; i < dev->nb_attrs; i++) { - const char *attr = dev->attrs[i]; + for (i = 0; i < dev->attrs.num; i++) { + const char *attr = dev->attrs.names[i]; bool match; int ret; @@ -1578,17 +1599,17 @@ } if (match) { - free(dev->attrs[i]); - dev->attrs[i] = NULL; + free(dev->attrs.names[i]); + dev->attrs.names[i] = NULL; } } /* Find channels without an index */ - for (i = 0; i < dev->nb_attrs; i++) { - const char *attr = dev->attrs[i]; + for (i = 0; i < dev->attrs.num; i++) { + const char *attr = dev->attrs.names[i]; int ret; - if (!dev->attrs[i]) + if (!dev->attrs.names[i]) continue; if (is_channel(attr, false)) { @@ -1596,20 +1617,20 @@ if (ret) return ret; - free(dev->attrs[i]); - dev->attrs[i] = NULL; + free(dev->attrs.names[i]); + dev->attrs.names[i] = NULL; } } - for (i = 0; i < dev->nb_attrs; i++) { - if (dev->attrs[i]) - *ptr++ = dev->attrs[i]; + for (i = 0; i < dev->attrs.num; i++) { + if (dev->attrs.names[i]) + *ptr++ = dev->attrs.names[i]; } - dev->nb_attrs = ptr - dev->attrs; - if (!dev->nb_attrs) { - free(dev->attrs); - dev->attrs = NULL; + dev->attrs.num = ptr - dev->attrs.names; + if (!dev->attrs.num) { + free(dev->attrs.names); + dev->attrs.names = NULL; } return 0; @@ -1619,27 +1640,13 @@ { struct iio_device *dev = (struct iio_device *) d; const char *name = strrchr(path, '/') + 1; - char **attrs, *attr; unsigned int i; for (i = 0; i < ARRAY_SIZE(buffer_attrs_reserved); i++) if (!strcmp(buffer_attrs_reserved[i], name)) return 0; - attr = iio_strdup(name); - if (!attr) - return -ENOMEM; - - attrs = realloc(dev->buffer_attrs, (1 + dev->nb_buffer_attrs) * sizeof(char *)); - if (!attrs) { - free(attr); - return -ENOMEM; - } - - attrs[dev->nb_buffer_attrs++] = attr; - dev->buffer_attrs = attrs; - IIO_DEBUG("Added buffer attr \'%s\' to device \'%s\'\n", attr, dev->id); - return 0; + return add_iio_dev_attr(&dev->buffer_attrs, name, " buffer", dev->id); } static int add_attr_or_channel_helper(struct iio_device *dev, @@ -1683,7 +1690,7 @@ while (true) { struct stat st; - char buf[1024]; + char buf[PATH_MAX]; errno = 0; entry = readdir(dir); @@ -1749,7 +1756,7 @@ if (ret < 0) return ret; - qsort(dev->buffer_attrs, dev->nb_buffer_attrs, sizeof(char *), + qsort(dev->buffer_attrs.names, dev->buffer_attrs.num, sizeof(char *), iio_buffer_attr_compare); } @@ -1799,7 +1806,10 @@ for (i = 0; i < dev->nb_channels; i++) { struct iio_channel *chn = dev->channels[i]; - set_channel_name(chn); + ret = set_channel_name(chn); + if (ret < 0) + goto err_free_scan_elements; + ret = handle_scan_elements(chn); free_protected_attrs(chn); if (ret < 0) @@ -1816,7 +1826,7 @@ qsort(chn->attrs, chn->nb_attrs, sizeof(struct iio_channel_attr), iio_channel_attr_compare); } - qsort(dev->attrs, dev->nb_attrs, sizeof(char *), + qsort(dev->attrs.names, dev->attrs.num, sizeof(char *), iio_device_attr_compare); dev->words = (dev->nb_channels + 31) / 32; @@ -1830,7 +1840,7 @@ dev->mask = mask; - ret = add_device_to_context(ctx, dev); + ret = iio_context_add_device(ctx, dev); if (!ret) return 0; @@ -1847,21 +1857,8 @@ { struct iio_device *dev = d; const char *attr = strrchr(path, '/') + 1; - char **attrs, *name = iio_strdup(attr); - if (!name) - return -ENOMEM; - attrs = realloc(dev->debug_attrs, - (1 + dev->nb_debug_attrs) * sizeof(char *)); - if (!attrs) { - free(name); - return -ENOMEM; - } - - attrs[dev->nb_debug_attrs++] = name; - dev->debug_attrs = attrs; - IIO_DEBUG("Added debug attr \'%s\' to device \'%s\'\n", name, dev->id); - return 0; + return add_iio_dev_attr(&dev->debug_attrs, attr, " debug", dev->id); } static int add_debug(void *d, const char *path) @@ -1877,7 +1874,9 @@ static int local_set_timeout(struct iio_context *ctx, unsigned int timeout) { - ctx->pdata->rw_timeout_ms = timeout; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + pdata->rw_timeout_ms = timeout; return 0; } @@ -1902,6 +1901,25 @@ return local_create_context(); } +static char * local_get_description(const struct iio_context *ctx) +{ + char *description; + unsigned int len; + struct utsname uts; + + uname(&uts); + len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release) + + strlen(uts.version) + strlen(uts.machine); + description = malloc(len + 5); /* 4 spaces + EOF */ + if (!description) + return NULL; + + iio_snprintf(description, len + 5, "%s %s %s %s %s", uts.sysname, + uts.nodename, uts.release, uts.version, uts.machine); + + return description; +} + static const struct iio_backend_ops local_ops = { .clone = local_clone, .open = local_open, @@ -1919,10 +1937,19 @@ .get_trigger = local_get_trigger, .set_trigger = local_set_trigger, .shutdown = local_shutdown, + .get_description = local_get_description, .set_timeout = local_set_timeout, .cancel = local_cancel, }; +static const struct iio_backend local_backend = { + .api_version = IIO_BACKEND_API_V1, + .name = "local", + .uri_prefix = "local:", + .ops = &local_ops, + .sizeof_context_pdata = sizeof(struct iio_context_pdata), +}; + static void init_data_scale(struct iio_channel *chn) { char *end, buf[1024]; @@ -1947,15 +1974,14 @@ { unsigned int i, j; - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < iio_context_get_devices_count(ctx); i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); for (j = 0; j < dev->nb_channels; j++) init_data_scale(dev->channels[j]); } } -#ifdef WITH_LOCAL_CONFIG static int populate_context_attrs(struct iio_context *ctx, const char *file) { struct INI *ini; @@ -2009,41 +2035,23 @@ ini_close(ini); return ret; } -#endif struct iio_context * local_create_context(void) { + struct iio_context *ctx; + char *description; int ret = -ENOMEM; - unsigned int len; struct utsname uts; - struct iio_context *ctx = zalloc(sizeof(*ctx)); - if (!ctx) - goto err_set_errno; - ctx->ops = &local_ops; - ctx->name = "local"; + description = local_get_description(NULL); - ctx->pdata = zalloc(sizeof(*ctx->pdata)); - if (!ctx->pdata) { - free(ctx); + ctx = iio_context_create_from_backend(&local_backend, description); + free(description); + if (!ctx) goto err_set_errno; - } local_set_timeout(ctx, DEFAULT_TIMEOUT_MS); - uname(&uts); - len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release) - + strlen(uts.version) + strlen(uts.machine); - ctx->description = malloc(len + 5); /* 4 spaces + EOF */ - if (!ctx->description) { - free(ctx->pdata); - free(ctx); - goto err_set_errno; - } - - iio_snprintf(ctx->description, len + 5, "%s %s %s %s %s", uts.sysname, - uts.nodename, uts.release, uts.version, uts.machine); - ret = foreach_in_dir(ctx, "/sys/bus/iio/devices", true, create_device); if (ret < 0) goto err_context_destroy; @@ -2055,12 +2063,13 @@ init_scan_elements(ctx); -#ifdef WITH_LOCAL_CONFIG - ret = populate_context_attrs(ctx, "/etc/libiio.ini"); - if (ret < 0) - goto err_context_destroy; -#endif + if (WITH_LOCAL_CONFIG) { + ret = populate_context_attrs(ctx, "/etc/libiio.ini"); + if (ret < 0) + goto err_context_destroy; + } + uname(&uts); ret = iio_context_add_attr(ctx, "local,kernel", uts.release); if (ret < 0) goto err_context_destroy; @@ -2132,7 +2141,7 @@ int local_context_scan(struct iio_scan_result *scan_result) { - struct iio_context_info **info; + struct iio_context_info *info; bool exists = false; char *desc, *uri, *machine, buf[2 * BUF_SIZE], names[BUF_SIZE]; int ret; @@ -2169,12 +2178,13 @@ if (!uri) goto err_free_desc; - info = iio_scan_result_add(scan_result, 1); + info = iio_scan_result_add(scan_result); if (!info) goto err_free_uri; - info[0]->description = desc; - info[0]->uri = uri; + info->description = desc; + info->uri = uri; + return 0; err_free_uri: diff -Nru libiio-0.21/lock.c libiio-0.23/lock.c --- libiio-0.21/lock.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/lock.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * */ #include "iio-config.h" diff -Nru libiio-0.21/man/CMakeLists.txt libiio-0.23/man/CMakeLists.txt --- libiio-0.21/man/CMakeLists.txt 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/man/CMakeLists.txt 2021-08-20 11:01:14.000000000 +0000 @@ -1,11 +1,20 @@ if (WITH_MAN) find_program(BASH_EXECUTABLE bash) find_program(DATE_EXECUTABLE date) + if (DEFINED ENV{SOURCE_DATE_EPOCH}) + execute_process( + COMMAND ${DATE_EXECUTABLE} "-u" "-d" "@$ENV{SOURCE_DATE_EPOCH}" "+%d %B %Y" + OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) + else () + execute_process( + COMMAND ${DATE_EXECUTABLE} "+%d %B %Y" + OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) + endif () + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/make_man.sh.in + ${CMAKE_CURRENT_BINARY_DIR}/make_man.sh @ONLY) execute_process( - COMMAND ${DATE_EXECUTABLE} "+%d %B %Y" - OUTPUT_VARIABLE CMAKE_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process( - COMMAND ${BASH_EXECUTABLE} "-c" "${CMAKE_CURRENT_SOURCE_DIR}/make_man.sh > ${CMAKE_BINARY_DIR}/libiio.3.in" + COMMAND ${BASH_EXECUTABLE} "-c" "${CMAKE_CURRENT_BINARY_DIR}/make_man.sh > ${CMAKE_BINARY_DIR}/libiio.3.in" ) configure_file( ${CMAKE_BINARY_DIR}/libiio.3.in diff -Nru libiio-0.21/man/make_man.sh libiio-0.23/man/make_man.sh --- libiio-0.21/man/make_man.sh 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/man/make_man.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ -#!/bin/bash -e - -if [ -z "$TRAVIS_BUILD_DIR" ] ; then - header="../iio.h" -else - header="$TRAVIS_BUILD_DIR/iio.h" -fi - -cat <. -.\" %%%LICENSE_END -.\" -.\" This file is autogenerated, and should not be editted -.\" -.if n .po 0 -.TH INTRO 3LIBIIO "@CMAKE_DATE@" "libiio-@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@" -.SH NAME -libiio-@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@ \- introduction to -.IR libiio , -a library for interacting with the Linux -.SM IIO -subsystem and devices -.SH SYNOPSIS -.B "#include " -.sp -cc file.c -.B -liio -.SH OPTIONS -The define -.B -IIO_CHECK_REG -will warn if return values are not checked. Most -.B -libiio -functions, if/when a failure occurs will return a negative error number. -this warning will ensure these error numbers are looked at. There is -nothing more frustraining than calling a function, debugging some hardware, -and then eventually realizing there was a typo in an attribute name. -This option will force libraries users to at least capture the return value. -.sp -cc file.c -.B -DIIO_CHECK_REG -liio - -.SH DESCRIPTION -.I libiio -is a library used to interface to the -.I "Linux Industrial Input/Output (IIO)" -Subsystem. The Linux -.I IIO -subsystem is intended to provide support for devices that in some sense -are analog to digital or digital to analog converters (ADCs, DACs). This -includes, but is not limited to ADCs, Accelerometers, Gyros, IMUs, -Capacitance to Digital Converters (CDCs), Pressure Sensors, Color, -Light and Proximity Sensors, Temperature Sensors, Magnetometers, DACs, -DDS (Direct Digital Synthesis), PLLs (Phase Locked Loops), -Variable/Programmable Gain Amplifiers (VGA, PGA), and RF transceivers. -You can use -.I libiio -natively on an embedded Linux target (local mode), or use libiio to -communicate remotely to that same target from a host Linux, Windows -or MAC over USB, Ethernet or Serial. -.SH "DATA TYPES" -The library makes use of C structures and typedefs to promote portability, -and is known to run on various GNU/Linux distributions, macOS, -Windows, and mbed (via tiny-iiod). The main C structures are: -.in +.5i -EOF - -tmp=$(grep @struct "${header}" | sed 's:^[[:space:]]*\*[[:space:]]*@::g' | awk '{print length($0)}' | sort -n | tail -1) -echo .TP $((tmp - 5)) - -grep @struct ../iio.h -A 1 | \ - sed -e 's:^[[:space:]]*\*[[:space:]]*@::g' \ - -e 's:struct[[:space:]]*:.TP\n.B :' \ - -e 's:brief[[:space:]]*::' \ - -e 's:[[:space:]]*\*\/[[:space:]]*::' \ - -e '/^--$/d' - -cat <. +.\" %%%LICENSE_END +.\" +.\" This file is autogenerated, and should not be editted +.\" +.if n .po 0 +.TH INTRO 3LIBIIO "@CMAKE_DATE@" "libiio-@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@" +.SH NAME +libiio-@LIBIIO_VERSION_MAJOR@.@LIBIIO_VERSION_MINOR@ \- introduction to +.IR libiio , +a library for interacting with the Linux +.SM IIO +subsystem and devices +.SH SYNOPSIS +.B "#include " +.sp +cc file.c +.B -liio +.SH OPTIONS +The define +.B +IIO_CHECK_REG +will warn if return values are not checked. Most +.B +libiio +functions, if/when a failure occurs will return a negative error number. +this warning will ensure these error numbers are looked at. There is +nothing more frustraining than calling a function, debugging some hardware, +and then eventually realizing there was a typo in an attribute name. +This option will force libraries users to at least capture the return value. +.sp +cc file.c +.B -DIIO_CHECK_REG -liio + +.SH DESCRIPTION +.I libiio +is a library used to interface to the +.I "Linux Industrial Input/Output (IIO)" +Subsystem. The Linux +.I IIO +subsystem is intended to provide support for devices that in some sense +are analog to digital or digital to analog converters (ADCs, DACs). This +includes, but is not limited to ADCs, Accelerometers, Gyros, IMUs, +Capacitance to Digital Converters (CDCs), Pressure Sensors, Color, +Light and Proximity Sensors, Temperature Sensors, Magnetometers, DACs, +DDS (Direct Digital Synthesis), PLLs (Phase Locked Loops), +Variable/Programmable Gain Amplifiers (VGA, PGA), and RF transceivers. +You can use +.I libiio +natively on an embedded Linux target (local mode), or use libiio to +communicate remotely to that same target from a host Linux, Windows +or MAC over USB, Ethernet or Serial. +.SH "DATA TYPES" +The library makes use of C structures and typedefs to promote portability, +and is known to run on various GNU/Linux distributions, macOS, +Windows, and mbed (via tiny-iiod). The main C structures are: +.in +.5i +EOF + +tmp=$(grep @struct "${header}" | sed 's:^[[:space:]]*\*[[:space:]]*@::g' | awk '{print length($0)}' | sort -n | tail -1) +echo .TP $((tmp - 5)) + +grep @struct ${header} -A 1 | \ + sed -e 's:^[[:space:]]*\*[[:space:]]*@::g' \ + -e 's:struct[[:space:]]*:.TP\n.B :' \ + -e 's:brief[[:space:]]*::' \ + -e 's:[[:space:]]*\*\/[[:space:]]*::' \ + -e '/^--$/d' + +cat < #ifdef _WIN32 -#include -#include +#include +#include #define strncasecmp _strnicmp #else #include diff -Nru libiio-0.21/network.c libiio-0.23/network.c --- libiio-0.21/network.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/network.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,59 +1,73 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2020 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ +#include "debug.h" +#include "dns_sd.h" #include "iio-config.h" #include "iio-private.h" -#include "network.h" #include "iio-lock.h" #include "iiod-client.h" -#include "debug.h" +#include "network.h" + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#else +/* + * Old OSes (CentOS 7, Ubuntu 16.04) require this for the + * IN6_IS_ADDR_LINKLOCAL() macro to work. + */ +#ifndef _GNU_SOURCE +#define __USE_MISC +#include +#undef __USE_MISC +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#endif #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) #define IIOD_PORT_STR STRINGIFY(IIOD_PORT) -struct iio_network_io_context { - int fd; - - /* Only buffer IO contexts can be cancelled. */ - bool cancellable; - bool cancelled; -#if defined(_WIN32) - WSAEVENT events[2]; -#elif defined(WITH_NETWORK_EVENTFD) - int cancel_fd[1]; /* eventfd */ +#ifdef _WIN32 +#define close(s) closesocket(s) +#define NETWORK_ERR_TIMEOUT WSAETIMEDOUT #else - int cancel_fd[2]; /* pipe */ +#define NETWORK_ERR_TIMEOUT ETIMEDOUT #endif - unsigned int timeout_ms; -}; + +#define DEFAULT_TIMEOUT_MS 5000 struct iio_context_pdata { - struct iio_network_io_context io_ctx; + struct iiod_client_pdata io_ctx; struct addrinfo *addrinfo; - struct iio_mutex *lock; struct iiod_client *iiod_client; bool msg_trunc_supported; }; struct iio_device_pdata { - struct iio_network_io_context io_ctx; + struct iiod_client_pdata io_ctx; #ifdef WITH_NETWORK_GET_BUFFER int memfd; void *mmap_addr; @@ -63,266 +77,7 @@ struct iio_mutex *lock; }; -#ifdef _WIN32 - -static int set_blocking_mode(int s, bool blocking) -{ - unsigned long nonblock; - int ret; - - nonblock = blocking ? 0 : 1; - - ret = ioctlsocket(s, FIONBIO, &nonblock); - if (ret == SOCKET_ERROR) { - ret = -WSAGetLastError(); - return ret; - } - - return 0; -} - -static int setup_cancel(struct iio_network_io_context *io_ctx) -{ - io_ctx->events[0] = WSACreateEvent(); - if (io_ctx->events[0] == WSA_INVALID_EVENT) - return -ENOMEM; /* Pretty much the only error that can happen */ - - io_ctx->events[1] = WSACreateEvent(); - if (io_ctx->events[1] == WSA_INVALID_EVENT) { - WSACloseEvent(io_ctx->events[0]); - return -ENOMEM; - } - - return 0; -} - -static void cleanup_cancel(struct iio_network_io_context *io_ctx) -{ - WSACloseEvent(io_ctx->events[0]); - WSACloseEvent(io_ctx->events[1]); -} - -static void do_cancel(struct iio_network_io_context *io_ctx) -{ - WSASetEvent(io_ctx->events[1]); -} - -static int wait_cancellable(struct iio_network_io_context *io_ctx, bool read) -{ - long wsa_events = FD_CLOSE; - DWORD ret; - - if (!io_ctx->cancellable) - return 0; - - if (read) - wsa_events |= FD_READ; - else - wsa_events |= FD_WRITE; - - WSAEventSelect(io_ctx->fd, NULL, 0); - WSAResetEvent(io_ctx->events[0]); - WSAEventSelect(io_ctx->fd, io_ctx->events[0], wsa_events); - - ret = WSAWaitForMultipleEvents(2, io_ctx->events, FALSE, - WSA_INFINITE, FALSE); - - if (ret == WSA_WAIT_EVENT_0 + 1) - return -EBADF; - - return 0; -} - -static int network_get_error(void) -{ - return -WSAGetLastError(); -} - -static bool network_should_retry(int err) -{ - return err == -WSAEWOULDBLOCK || err == -WSAETIMEDOUT; -} - -static bool network_is_interrupted(int err) -{ - return false; -} - -static bool network_connect_in_progress(int err) -{ - return err == -WSAEWOULDBLOCK; -} - -#define NETWORK_ERR_TIMEOUT WSAETIMEDOUT - -#else - -static int set_blocking_mode(int fd, bool blocking) -{ - int ret = fcntl(fd, F_GETFL, 0); - if (ret < 0) - return -errno; - - if (blocking) - ret &= ~O_NONBLOCK; - else - ret |= O_NONBLOCK; - - ret = fcntl(fd, F_SETFL, ret); - return ret < 0 ? -errno : 0; -} - -#include - -#if defined(WITH_NETWORK_EVENTFD) - -#include - -static int create_cancel_fd(struct iio_network_io_context *io_ctx) -{ - io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); - if (io_ctx->cancel_fd[0] < 0) - return -errno; - return 0; -} - -static void cleanup_cancel(struct iio_network_io_context *io_ctx) -{ - close(io_ctx->cancel_fd[0]); -} - -#define CANCEL_WR_FD 0 - -#else - -static int create_cancel_fd(struct iio_network_io_context *io_ctx) -{ - int ret; - -#ifdef HAS_PIPE2 - ret = pipe2(io_ctx->cancel_fd, O_CLOEXEC | O_NONBLOCK); - if (ret < 0 && errno != ENOSYS) /* If ENOSYS try pipe() */ - return -errno; -#endif - ret = pipe(io_ctx->cancel_fd); - if (ret < 0) - return -errno; - ret = set_blocking_mode(io_ctx->cancel_fd[0], false); - if (ret < 0) - goto err_close; - ret = set_blocking_mode(io_ctx->cancel_fd[1], false); - if (ret < 0) - goto err_close; - - return 0; -err_close: - close(io_ctx->cancel_fd[0]); - close(io_ctx->cancel_fd[1]); - return ret; -} - -static void cleanup_cancel(struct iio_network_io_context *io_ctx) -{ - close(io_ctx->cancel_fd[0]); - close(io_ctx->cancel_fd[1]); -} - -#define CANCEL_WR_FD 1 - -#endif - -static int setup_cancel(struct iio_network_io_context *io_ctx) -{ - int ret; - - ret = set_blocking_mode(io_ctx->fd, false); - if (ret) - return ret; - - return create_cancel_fd(io_ctx); -} - -static void do_cancel(struct iio_network_io_context *io_ctx) -{ - uint64_t event = 1; - int ret; - - ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); - if (ret == -1) { - /* If this happens something went very seriously wrong */ - char err_str[1024]; - iio_strerror(errno, err_str, sizeof(err_str)); - IIO_ERROR("Unable to signal cancellation event: %s\n", err_str); - } -} - -static int wait_cancellable(struct iio_network_io_context *io_ctx, bool read) -{ - struct pollfd pfd[2]; - int ret; - - if (!io_ctx->cancellable) - return 0; - - memset(pfd, 0, sizeof(pfd)); - - pfd[0].fd = io_ctx->fd; - if (read) - pfd[0].events = POLLIN; - else - pfd[0].events = POLLOUT; - pfd[1].fd = io_ctx->cancel_fd[0]; - pfd[1].events = POLLIN; - - do { - int timeout_ms; - - if (io_ctx->timeout_ms > 0) - timeout_ms = (int) io_ctx->timeout_ms; - else - timeout_ms = -1; - - do { - ret = poll(pfd, 2, timeout_ms); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) - return -errno; - if (!ret) - return -EPIPE; - - if (pfd[1].revents & POLLIN) - return -EBADF; - } while (!(pfd[0].revents & (pfd[0].events | POLLERR | POLLHUP))); - - return 0; -} - -static int network_get_error(void) -{ - return -errno; -} - -static bool network_should_retry(int err) -{ - return err == -EAGAIN; -} - -static bool network_is_interrupted(int err) -{ - return err == -EINTR; -} - -static bool network_connect_in_progress(int err) -{ - return err == -EINPROGRESS; -} - -#define NETWORK_ERR_TIMEOUT ETIMEDOUT - -#endif - -static ssize_t network_recv(struct iio_network_io_context *io_ctx, +static ssize_t network_recv(struct iiod_client_pdata *io_ctx, void *data, size_t len, int flags) { ssize_t ret; @@ -352,7 +107,7 @@ return ret; } -static ssize_t network_send(struct iio_network_io_context *io_ctx, +static ssize_t network_send(struct iiod_client_pdata *io_ctx, const void *data, size_t len, int flags) { ssize_t ret; @@ -383,7 +138,7 @@ return ret; } -static ssize_t write_all(struct iio_network_io_context *io_ctx, +static ssize_t write_all(struct iiod_client_pdata *io_ctx, const void *src, size_t len) { uintptr_t ptr = (uintptr_t) src; @@ -397,7 +152,7 @@ return (ssize_t)(ptr - (uintptr_t) src); } -static ssize_t write_command(struct iio_network_io_context *io_ctx, +static ssize_t write_command(struct iiod_client_pdata *io_ctx, const char *cmd) { ssize_t ret; @@ -421,68 +176,6 @@ ppdata->io_ctx.cancelled = true; } -#ifndef _WIN32 - -/* Use it if available */ -#ifndef SOCK_CLOEXEC -#define SOCK_CLOEXEC 0 -#endif - -static int do_create_socket(const struct addrinfo *addrinfo) -{ - int fd; - - fd = socket(addrinfo->ai_family, addrinfo->ai_socktype | SOCK_CLOEXEC, 0); - if (fd < 0) - return -errno; - - return fd; -} - -static int set_socket_timeout(int fd, unsigned int timeout) -{ - struct timeval tv; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 || - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, - &tv, sizeof(tv)) < 0) - return -errno; - else - return 0; -} -#else - -/* Use it if available */ -#ifndef WSA_FLAG_NO_HANDLE_INHERIT -#define WSA_FLAG_NO_HANDLE_INHERIT 0 -#endif - -static int do_create_socket(const struct addrinfo *addrinfo) -{ - SOCKET s; - - s = WSASocketW(addrinfo->ai_family, addrinfo->ai_socktype, 0, NULL, 0, - WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED); - if (s == INVALID_SOCKET) - return -WSAGetLastError(); - - return (int) s; -} - -static int set_socket_timeout(int fd, unsigned int timeout) -{ - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, - (const char *) &timeout, sizeof(timeout)) < 0 || - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, - (const char *) &timeout, sizeof(timeout)) < 0) - return -WSAGetLastError(); - else - return 0; -} -#endif /* !_WIN32 */ - /* The purpose of this function is to provide a version of connect() * that does not ignore timeouts... */ static int do_connect(int fd, const struct addrinfo *addrinfo, @@ -563,8 +256,9 @@ return 0; } -int create_socket(const struct addrinfo *addrinfo, unsigned int timeout) +int create_socket(const struct addrinfo *addrinfo) { + const unsigned int timeout = DEFAULT_TIMEOUT_MS; int ret, fd, yes = 1; fd = do_create_socket(addrinfo); @@ -588,10 +282,69 @@ return fd; } +static char * __network_get_description(struct addrinfo *res) +{ + char *description; + unsigned int len; + +#ifdef HAVE_IPV6 + len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; +#else + len = INET_ADDRSTRLEN + 1; +#endif + + description = malloc(len); + if (!description) { + errno = ENOMEM; + return NULL; + } + + description[0] = '\0'; + +#ifdef HAVE_IPV6 + if (res->ai_family == AF_INET6) { + struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; + char *ptr; + inet_ntop(AF_INET6, &in->sin6_addr, + description, INET6_ADDRSTRLEN); + + if (IN6_IS_ADDR_LINKLOCAL(&in->sin6_addr)) { + ptr = if_indextoname(in->sin6_scope_id, description + + strlen(description) + 1); + if (!ptr) { + IIO_ERROR("Unable to lookup interface of IPv6 address\n"); + free(description); + return NULL; + } + + *(ptr - 1) = '%'; + } + } +#endif + if (res->ai_family == AF_INET) { + struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; +#if (!_WIN32 || _WIN32_WINNT >= 0x600) + inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN); +#else + char *tmp = inet_ntoa(in->sin_addr); + iio_strlcpy(description, tmp, len); +#endif + } + + return description; +} + +static char *network_get_description(const struct iio_context *ctx) +{ + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return __network_get_description(pdata->addrinfo); +} + static int network_open(const struct iio_device *dev, size_t samples_count, bool cyclic) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *ppdata = dev->pdata; int ret = -EBUSY; @@ -599,7 +352,7 @@ if (ppdata->io_ctx.fd >= 0) goto out_mutex_unlock; - ret = create_socket(pdata->addrinfo, DEFAULT_TIMEOUT_MS); + ret = create_socket(pdata->addrinfo); if (ret < 0) { IIO_ERROR("Create socket: %d\n", ret); goto out_mutex_unlock; @@ -646,6 +399,7 @@ static int network_close(const struct iio_device *dev) { + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; int ret = -EBADF; @@ -654,7 +408,7 @@ if (pdata->io_ctx.fd >= 0) { if (!pdata->io_ctx.cancelled) { ret = iiod_client_close_unlocked( - dev->ctx->pdata->iiod_client, + ctx_pdata->iiod_client, &pdata->io_ctx, dev); write_command(&pdata->io_ctx, "\r\nEXIT\r\n"); @@ -685,11 +439,12 @@ static ssize_t network_read(const struct iio_device *dev, void *dst, size_t len, uint32_t *mask, size_t words) { + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; ssize_t ret; iio_mutex_lock(pdata->lock); - ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client, + ret = iiod_client_read_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx, dev, dst, len, mask, words); iio_mutex_unlock(pdata->lock); @@ -699,11 +454,12 @@ static ssize_t network_write(const struct iio_device *dev, const void *src, size_t len) { + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; ssize_t ret; iio_mutex_lock(pdata->lock); - ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client, + ret = iiod_client_write_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx, dev, src, len); iio_mutex_unlock(pdata->lock); @@ -712,7 +468,7 @@ #ifdef WITH_NETWORK_GET_BUFFER -static ssize_t read_all(struct iio_network_io_context *io_ctx, +static ssize_t read_all(struct iiod_client_pdata *io_ctx, void *dst, size_t len) { uintptr_t ptr = (uintptr_t) dst; @@ -728,7 +484,7 @@ return (ssize_t)(ptr - (uintptr_t) dst); } -static int read_integer(struct iio_network_io_context *io_ctx, long *val) +static int read_integer(struct iiod_client_pdata *io_ctx, long *val) { unsigned int i; char buf[1024], *ptr; @@ -757,7 +513,7 @@ return 0; } -static ssize_t network_read_mask(struct iio_network_io_context *io_ctx, +static ssize_t network_read_mask(struct iiod_client_pdata *io_ctx, uint32_t *mask, size_t words) { long read_len; @@ -797,7 +553,7 @@ return (ssize_t) read_len; } -static ssize_t read_error_code(struct iio_network_io_context *io_ctx) +static ssize_t read_error_code(struct iiod_client_pdata *io_ctx) { /* * The server returns two integer codes. @@ -905,7 +661,7 @@ err_close_pipe: close(pipefd[0]); close(pipefd[1]); - return ret < 0 ? ret : len; + return ret < 0 ? ret : (ssize_t)len; } static ssize_t network_get_buffer(const struct iio_device *dev, @@ -1024,7 +780,7 @@ static ssize_t network_read_dev_attr(const struct iio_device *dev, const char *attr, char *dst, size_t len, enum iio_attr_type type) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_read_attr(pdata->iiod_client, &pdata->io_ctx, dev, NULL, attr, dst, len, type); @@ -1033,7 +789,7 @@ static ssize_t network_write_dev_attr(const struct iio_device *dev, const char *attr, const char *src, size_t len, enum iio_attr_type type) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_write_attr(pdata->iiod_client, &pdata->io_ctx, dev, NULL, attr, src, len, type); @@ -1042,7 +798,7 @@ static ssize_t network_read_chn_attr(const struct iio_channel *chn, const char *attr, char *dst, size_t len) { - struct iio_context_pdata *pdata = chn->dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); return iiod_client_read_attr(pdata->iiod_client, &pdata->io_ctx, chn->dev, chn, attr, dst, len, false); @@ -1051,7 +807,7 @@ static ssize_t network_write_chn_attr(const struct iio_channel *chn, const char *attr, const char *src, size_t len) { - struct iio_context_pdata *pdata = chn->dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); return iiod_client_write_attr(pdata->iiod_client, &pdata->io_ctx, chn->dev, chn, attr, src, len, false); @@ -1060,7 +816,7 @@ static int network_get_trigger(const struct iio_device *dev, const struct iio_device **trigger) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_get_trigger(pdata->iiod_client, &pdata->io_ctx, dev, trigger); @@ -1069,7 +825,7 @@ static int network_set_trigger(const struct iio_device *dev, const struct iio_device *trigger) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_set_trigger(pdata->iiod_client, &pdata->io_ctx, dev, trigger); @@ -1077,16 +833,16 @@ static void network_shutdown(struct iio_context *ctx) { - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); unsigned int i; - iio_mutex_lock(pdata->lock); + iiod_client_mutex_lock(pdata->iiod_client); write_command(&pdata->io_ctx, "\r\nEXIT\r\n"); close(pdata->io_ctx.fd); - iio_mutex_unlock(pdata->lock); + iiod_client_mutex_unlock(pdata->iiod_client); - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < iio_context_get_devices_count(ctx); i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); struct iio_device_pdata *dpdata = dev->pdata; if (dpdata) { @@ -1097,16 +853,16 @@ } iiod_client_destroy(pdata->iiod_client); - iio_mutex_destroy(pdata->lock); freeaddrinfo(pdata->addrinfo); - free(pdata); } static int network_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8]) { - return iiod_client_get_version(ctx->pdata->iiod_client, - &ctx->pdata->io_ctx, major, minor, git_tag); + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return iiod_client_get_version(pdata->iiod_client, + &pdata->io_ctx, major, minor, git_tag); } static unsigned int calculate_remote_timeout(unsigned int timeout) @@ -1118,7 +874,7 @@ static int network_set_timeout(struct iio_context *ctx, unsigned int timeout) { - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); int ret, fd = pdata->io_ctx.fd; ret = set_socket_timeout(fd, timeout); @@ -1141,7 +897,7 @@ static int network_set_kernel_buffers_count(const struct iio_device *dev, unsigned int nb_blocks) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_set_kernel_buffers_count(pdata->iiod_client, &pdata->io_ctx, dev, nb_blocks); @@ -1170,6 +926,7 @@ .get_trigger = network_get_trigger, .set_trigger = network_set_trigger, .shutdown = network_shutdown, + .get_description = network_get_description, .get_version = network_get_version, .set_timeout = network_set_timeout, .set_kernel_buffers_count = network_set_kernel_buffers_count, @@ -1178,28 +935,31 @@ }; static ssize_t network_write_data(struct iio_context_pdata *pdata, - void *io_data, const char *src, size_t len) + struct iiod_client_pdata *io_data, + const char *src, size_t len) { - struct iio_network_io_context *io_ctx = io_data; + struct iiod_client_pdata *io_ctx = io_data; return network_send(io_ctx, src, len, 0); } static ssize_t network_read_data(struct iio_context_pdata *pdata, - void *io_data, char *dst, size_t len) + struct iiod_client_pdata *io_data, + char *dst, size_t len) { - struct iio_network_io_context *io_ctx = io_data; + struct iiod_client_pdata *io_ctx = io_data; return network_recv(io_ctx, dst, len, 0); } static ssize_t network_read_line(struct iio_context_pdata *pdata, - void *io_data, char *dst, size_t len) + struct iiod_client_pdata *io_data, + char *dst, size_t len) { bool found = false; size_t i; #ifdef __linux__ - struct iio_network_io_context *io_ctx = io_data; + struct iiod_client_pdata *io_ctx = io_data; ssize_t ret; size_t bytes_read = 0; @@ -1274,7 +1034,7 @@ * applications this is not something that can be detected at compile time. If * we want to support WSL we have to have a runtime workaround. */ -static bool msg_trunc_supported(struct iio_network_io_context *io_ctx) +static bool msg_trunc_supported(struct iiod_client_pdata *io_ctx) { int ret; @@ -1283,7 +1043,7 @@ return ret != -EFAULT && ret != -EINVAL; } #else -static bool msg_trunc_supported(struct iio_network_io_context *io_ctx) +static bool msg_trunc_supported(struct iiod_client_pdata *io_ctx) { return false; } @@ -1293,8 +1053,10 @@ { struct addrinfo hints, *res; struct iio_context *ctx; + struct iiod_client *iiod_client; struct iio_context_pdata *pdata; - size_t i, len, uri_len; + size_t uri_len; + unsigned int i; int fd, ret; char *description, *uri; #ifdef _WIN32 @@ -1312,8 +1074,7 @@ hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; -#ifdef HAVE_DNS_SD - if (!host || !host[0]) { + if (HAVE_DNS_SD && (!host || !host[0])) { char addr_str[DNS_SD_ADDRESS_STR_MAX]; char port_str[6]; uint16_t port = IIOD_PORT; @@ -1334,10 +1095,32 @@ iio_snprintf(port_str, sizeof(port_str), "%hu", port); ret = getaddrinfo(addr_str, port_str, &hints, &res); - } else -#endif - { + } else { ret = getaddrinfo(host, IIOD_PORT_STR, &hints, &res); + /* + * It might be an avahi hostname which means that getaddrinfo() will only work if + * nss-mdns is installed on the host and /etc/nsswitch.conf is correctly configured + * which might be not the case for some minimalist distros. In this case, + * as a last resort, let's try to resolve the host with avahi... + */ + if (HAVE_DNS_SD && ret) { + char addr_str[DNS_SD_ADDRESS_STR_MAX]; + + IIO_DEBUG("'getaddrinfo()' failed: %s. Trying dnssd as a last resort...\n", + gai_strerror(ret)); + + ret = dnssd_resolve_host(host, addr_str, sizeof(addr_str)); + if (ret) { + char buf[256]; + + iio_strerror(-ret, buf, sizeof(buf)); + IIO_DEBUG("Unable to find host: %s\n", buf); + errno = -ret; + return NULL; + } + + ret = getaddrinfo(addr_str, IIOD_PORT_STR, &hints, &res); + } } if (ret) { @@ -1349,7 +1132,7 @@ return NULL; } - fd = create_socket(res, DEFAULT_TIMEOUT_MS); + fd = create_socket(res); if (fd < 0) { errno = -fd; goto err_free_addrinfo; @@ -1361,28 +1144,25 @@ goto err_close_socket; } + description = __network_get_description(res); + if (!description) + goto err_free_pdata; + + iiod_client = iiod_client_new(pdata, &network_iiod_client_ops); + if (!iiod_client) + goto err_free_description; + + pdata->iiod_client = iiod_client; pdata->io_ctx.fd = fd; pdata->addrinfo = res; pdata->io_ctx.timeout_ms = DEFAULT_TIMEOUT_MS; - pdata->lock = iio_mutex_create(); - if (!pdata->lock) { - errno = ENOMEM; - goto err_free_pdata; - } - - pdata->iiod_client = iiod_client_new(pdata, pdata->lock, - &network_iiod_client_ops); - pdata->msg_trunc_supported = msg_trunc_supported(&pdata->io_ctx); if (pdata->msg_trunc_supported) IIO_DEBUG("MSG_TRUNC is supported\n"); else IIO_DEBUG("MSG_TRUNC is NOT supported\n"); - if (!pdata->iiod_client) - goto err_destroy_mutex; - IIO_DEBUG("Creating context...\n"); ctx = iiod_client_create_context(pdata->iiod_client, &pdata->io_ctx); if (!ctx) @@ -1394,13 +1174,7 @@ ctx->ops = &network_ops; ctx->pdata = pdata; -#ifdef HAVE_IPV6 - len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2; -#else - len = INET_ADDRSTRLEN + 1; -#endif - - uri_len = len; + uri_len = strlen(description); if (host && host[0]) uri_len = strnlen(host, MAXHOSTNAMELEN); uri_len += sizeof ("ip:"); @@ -1411,47 +1185,9 @@ goto err_network_shutdown; } - description = malloc(len); - if (!description) { - ret = -ENOMEM; - goto err_free_uri; - } - - description[0] = '\0'; - -#ifdef HAVE_IPV6 - if (res->ai_family == AF_INET6) { - struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; - char *ptr; - inet_ntop(AF_INET6, &in->sin6_addr, - description, INET6_ADDRSTRLEN); - - if (IN6_IS_ADDR_LINKLOCAL(&in->sin6_addr)) { - ptr = if_indextoname(in->sin6_scope_id, description + - strlen(description) + 1); - if (!ptr) { - ret = -errno; - IIO_ERROR("Unable to lookup interface of IPv6 address\n"); - goto err_free_description; - } - - *(ptr - 1) = '%'; - } - } -#endif - if (res->ai_family == AF_INET) { - struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; -#if (!_WIN32 || _WIN32_WINNT >= 0x600) - inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN); -#else - char *tmp = inet_ntoa(in->sin_addr); - iio_strlcpy(description, tmp, len); -#endif - } - ret = iio_context_add_attr(ctx, "ip,ip-addr", description); if (ret < 0) - goto err_free_description; + goto err_free_uri; if (host && host[0]) iio_snprintf(uri, uri_len, "ip:%s", host); @@ -1460,15 +1196,15 @@ ret = iio_context_add_attr(ctx, "uri", uri); if (ret < 0) - goto err_free_description; + goto err_free_uri; - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < iio_context_get_devices_count(ctx); i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); dev->pdata = zalloc(sizeof(*dev->pdata)); if (!dev->pdata) { ret = -ENOMEM; - goto err_free_description; + goto err_free_uri; } dev->pdata->io_ctx.fd = -1; @@ -1480,7 +1216,7 @@ dev->pdata->lock = iio_mutex_create(); if (!dev->pdata->lock) { ret = -ENOMEM; - goto err_free_description; + goto err_free_uri; } } @@ -1490,7 +1226,7 @@ char *ptr, *new_description = realloc(description, new_size); if (!new_description) { ret = -ENOMEM; - goto err_free_description; + goto err_free_uri; } ptr = strrchr(new_description, '\0'); @@ -1507,19 +1243,18 @@ calculate_remote_timeout(DEFAULT_TIMEOUT_MS)); return ctx; -err_free_description: - free(description); err_free_uri: free(uri); err_network_shutdown: + free(description); iio_context_destroy(ctx); errno = -ret; return NULL; err_destroy_iiod_client: - iiod_client_destroy(pdata->iiod_client); -err_destroy_mutex: - iio_mutex_destroy(pdata->lock); + iiod_client_destroy(iiod_client); +err_free_description: + free(description); err_free_pdata: free(pdata); err_close_socket: diff -Nru libiio-0.21/network.h libiio-0.23/network.h --- libiio-0.21/network.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/network.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,124 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2020 Analog Devices, Inc. * Author: Paul Cercueil * Robin Getz - * - * 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. - * - * */ - -#ifndef __IIO_NET_PRIVATE_H -#define __IIO_NET_PRIVATE_H - -#include "iio-config.h" -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#define close(s) closesocket(s) -/* winsock2.h defines ERROR, we don't want that */ -#undef ERROR -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN (MAX_COMPUTERNAME_LENGTH+1) -#endif /* MAXHOSTNAMELEN */ -#else /* !_WIN32 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* _WIN32 */ - -#ifdef HAVE_DNS_SD -#ifdef HAVE_AVAHI -#include -#include -#include -#include -#include -#include -#define DNS_SD_ADDRESS_STR_MAX AVAHI_ADDRESS_STR_MAX -#else /* !HAVE_AVAHI */ -#define DNS_SD_ADDRESS_STR_MAX (40) /* IPv6 Max = 4*8 + 7 + 1 for NUL */ -#endif /* HAVE_AVAHI */ - -/* MacOS doesn't include ENOMEDIUM (No medium found) like Linux does */ -#ifndef ENOMEDIUM -#define ENOMEDIUM ENOENT -#endif - -/* Common structure which all dns_sd_[*] files fill out - * Anything that is dynamically allocated (malloc) needs to be managed - */ -struct dns_sd_discovery_data { - struct iio_mutex *lock; -#ifdef HAVE_AVAHI - AvahiSimplePoll *poll; - AvahiAddress *address; - uint16_t found, resolved; -#endif /* HAVE_AVAHI */ - char addr_str[DNS_SD_ADDRESS_STR_MAX]; - char *hostname; - uint16_t port; - struct dns_sd_discovery_data *next; -}; - - -/* This functions is implemented in network.c, but used in dns_sd.c */ -int create_socket(const struct addrinfo *addrinfo, unsigned int timeout); - -/* These functions are common, and implemented in dns_sd_[*].c based on the - * implementations: avahi (linux), bonjour (mac), or ServiceDiscovery (Win10) - */ - -/* Resolves all IIO hosts on the available networks, and passes back a linked list */ -int dnssd_find_hosts(struct dns_sd_discovery_data ** ddata); -/* Frees memory of one entry on the list */ -void dnssd_free_discovery_data(struct dns_sd_discovery_data *d); +#ifndef __IIO_NETWORK_H +#define __IIO_NETWORK_H -/* Deallocates complete list of discovery data */ -void dnssd_free_all_discovery_data(struct dns_sd_discovery_data *d); - -/* These functions are common, and found in dns_sd.c, but are used in the - * dns_sd_[*].c implementations or network.c - */ - -/* Passed back the first (random) IIOD service resolved by DNS DS. */ -int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port); +#include -/* remove duplicates from the list */ -void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata); +struct addrinfo; -/* port knocks */ -void port_knock_discovery_data(struct dns_sd_discovery_data **ddata); +struct iiod_client_pdata { + int fd; -#endif /* HAVE_DNS_SD */ + /* Only buffer IO contexts can be cancelled. */ + bool cancellable; + bool cancelled; + void * events[2]; + int cancel_fd[2]; + unsigned int timeout_ms; +}; -/* Used everywhere */ -#define DEFAULT_TIMEOUT_MS 5000 -#define IIOD_PORT 30431 +int setup_cancel(struct iiod_client_pdata *io_ctx); +void cleanup_cancel(struct iiod_client_pdata *io_ctx); +void do_cancel(struct iiod_client_pdata *io_ctx); +int wait_cancellable(struct iiod_client_pdata *io_ctx, bool read); + +int do_create_socket(const struct addrinfo *addrinfo); + +int set_blocking_mode(int s, bool blocking); +int set_socket_timeout(int fd, unsigned int timeout); + +int network_get_error(void); +bool network_should_retry(int err); +bool network_is_interrupted(int err); +bool network_connect_in_progress(int err); -#endif /* __IIO_NET_PRIVATE_H */ +#endif /* __IIO_NETWORK_H */ diff -Nru libiio-0.21/network-unix.c libiio-0.23/network-unix.c --- libiio-0.21/network-unix.c 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/network-unix.c 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2021 Analog Devices, Inc. + * Author: Paul Cercueil + */ + +#include "debug.h" +#include "iio-config.h" +#include "iio-private.h" +#include "network.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int set_blocking_mode(int fd, bool blocking) +{ + int ret = fcntl(fd, F_GETFL, 0); + if (ret < 0) + return -errno; + + if (blocking) + ret &= ~O_NONBLOCK; + else + ret |= O_NONBLOCK; + + ret = fcntl(fd, F_SETFL, ret); + return ret < 0 ? -errno : 0; +} + +#if WITH_NETWORK_EVENTFD +#include + +static int create_cancel_fd(struct iiod_client_pdata *io_ctx) +{ + io_ctx->cancel_fd[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + if (io_ctx->cancel_fd[0] < 0) + return -errno; + return 0; +} + +#else /* WITH_NETWORK_EVENTFD */ + +static int create_cancel_fd(struct iiod_client_pdata *io_ctx) +{ + int ret; + +#ifdef HAS_PIPE2 + ret = pipe2(io_ctx->cancel_fd, O_CLOEXEC | O_NONBLOCK); + if (ret < 0 && errno != ENOSYS) /* If ENOSYS try pipe() */ + return -errno; +#endif + ret = pipe(io_ctx->cancel_fd); + if (ret < 0) + return -errno; + ret = set_blocking_mode(io_ctx->cancel_fd[0], false); + if (ret < 0) + goto err_close; + ret = set_blocking_mode(io_ctx->cancel_fd[1], false); + if (ret < 0) + goto err_close; + + return 0; +err_close: + close(io_ctx->cancel_fd[0]); + close(io_ctx->cancel_fd[1]); + return ret; +} +#endif /* WITH_NETWORK_EVENTFD */ + +void cleanup_cancel(struct iiod_client_pdata *io_ctx) +{ + close(io_ctx->cancel_fd[0]); + if (!WITH_NETWORK_EVENTFD) + close(io_ctx->cancel_fd[1]); +} + +int setup_cancel(struct iiod_client_pdata *io_ctx) +{ + int ret; + + ret = set_blocking_mode(io_ctx->fd, false); + if (ret) + return ret; + + return create_cancel_fd(io_ctx); +} + +#define CANCEL_WR_FD (!WITH_NETWORK_EVENTFD) + +void do_cancel(struct iiod_client_pdata *io_ctx) +{ + uint64_t event = 1; + int ret; + + ret = write(io_ctx->cancel_fd[CANCEL_WR_FD], &event, sizeof(event)); + if (ret == -1) { + /* If this happens something went very seriously wrong */ + char err_str[1024]; + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Unable to signal cancellation event: %s\n", err_str); + } +} + +int wait_cancellable(struct iiod_client_pdata *io_ctx, bool read) +{ + struct pollfd pfd[2]; + int ret; + + if (!io_ctx->cancellable) + return 0; + + memset(pfd, 0, sizeof(pfd)); + + pfd[0].fd = io_ctx->fd; + if (read) + pfd[0].events = POLLIN; + else + pfd[0].events = POLLOUT; + pfd[1].fd = io_ctx->cancel_fd[0]; + pfd[1].events = POLLIN; + + do { + int timeout_ms; + + if (io_ctx->timeout_ms > 0) + timeout_ms = (int) io_ctx->timeout_ms; + else + timeout_ms = -1; + + do { + ret = poll(pfd, 2, timeout_ms); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) + return -errno; + if (!ret) + return -EPIPE; + + if (pfd[1].revents & POLLIN) + return -EBADF; + } while (!(pfd[0].revents & (pfd[0].events | POLLERR | POLLHUP))); + + return 0; +} + +int network_get_error(void) +{ + return -errno; +} + +bool network_should_retry(int err) +{ + return err == -EAGAIN; +} + +bool network_is_interrupted(int err) +{ + return err == -EINTR; +} + +bool network_connect_in_progress(int err) +{ + return err == -EINPROGRESS; +} + + +/* Use it if available */ +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif + +int do_create_socket(const struct addrinfo *addrinfo) +{ + int fd; + + fd = socket(addrinfo->ai_family, addrinfo->ai_socktype | SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + return fd; +} + +int set_socket_timeout(int fd, unsigned int timeout) +{ + struct timeval tv; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0 || + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, + &tv, sizeof(tv)) < 0) + return -errno; + else + return 0; +} diff -Nru libiio-0.21/network-windows.c libiio-0.23/network-windows.c --- libiio-0.21/network-windows.c 1970-01-01 00:00:00.000000000 +0000 +++ libiio-0.23/network-windows.c 2021-08-20 11:01:14.000000000 +0000 @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2021 Analog Devices, Inc. + * Author: Paul Cercueil + */ + +#include "network.h" + +#include +#include +#define close(s) closesocket(s) +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN (MAX_COMPUTERNAME_LENGTH+1) +#endif /* MAXHOSTNAMELEN */ + +int set_blocking_mode(int s, bool blocking) +{ + unsigned long nonblock; + int ret; + + nonblock = blocking ? 0 : 1; + + ret = ioctlsocket(s, FIONBIO, &nonblock); + if (ret == SOCKET_ERROR) { + ret = -WSAGetLastError(); + return ret; + } + + return 0; +} + +int setup_cancel(struct iiod_client_pdata *io_ctx) +{ + io_ctx->events[0] = WSACreateEvent(); + if (io_ctx->events[0] == WSA_INVALID_EVENT) + return -ENOMEM; /* Pretty much the only error that can happen */ + + io_ctx->events[1] = WSACreateEvent(); + if (io_ctx->events[1] == WSA_INVALID_EVENT) { + WSACloseEvent(io_ctx->events[0]); + return -ENOMEM; + } + + return 0; +} + +void cleanup_cancel(struct iiod_client_pdata *io_ctx) +{ + WSACloseEvent(io_ctx->events[0]); + WSACloseEvent(io_ctx->events[1]); +} + +void do_cancel(struct iiod_client_pdata *io_ctx) +{ + WSASetEvent(io_ctx->events[1]); +} + +int wait_cancellable(struct iiod_client_pdata *io_ctx, bool read) +{ + long wsa_events = FD_CLOSE; + DWORD ret; + + if (!io_ctx->cancellable) + return 0; + + if (read) + wsa_events |= FD_READ; + else + wsa_events |= FD_WRITE; + + WSAEventSelect(io_ctx->fd, NULL, 0); + WSAResetEvent(io_ctx->events[0]); + WSAEventSelect(io_ctx->fd, io_ctx->events[0], wsa_events); + + ret = WSAWaitForMultipleEvents(2, io_ctx->events, FALSE, + WSA_INFINITE, FALSE); + + if (ret == WSA_WAIT_EVENT_0 + 1) + return -EBADF; + + return 0; +} + +int network_get_error(void) +{ + return -WSAGetLastError(); +} + +bool network_should_retry(int err) +{ + return err == -WSAEWOULDBLOCK || err == -WSAETIMEDOUT; +} + +bool network_is_interrupted(int err) +{ + return false; +} + +bool network_connect_in_progress(int err) +{ + return err == -WSAEWOULDBLOCK; +} + +/* Use it if available */ +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0 +#endif + +int do_create_socket(const struct addrinfo *addrinfo) +{ + SOCKET s; + + s = WSASocketW(addrinfo->ai_family, addrinfo->ai_socktype, 0, NULL, 0, + WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED); + if (s == INVALID_SOCKET) + return -WSAGetLastError(); + + return (int) s; +} + +int set_socket_timeout(int fd, unsigned int timeout) +{ + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, + (const char *) &timeout, sizeof(timeout)) < 0 || + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, + (const char *) &timeout, sizeof(timeout)) < 0) + return -WSAGetLastError(); + else + return 0; +} diff -Nru libiio-0.21/README_BUILD.md libiio-0.23/README_BUILD.md --- libiio-0.21/README_BUILD.md 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/README_BUILD.md 2021-08-20 11:01:14.000000000 +0000 @@ -22,7 +22,7 @@ ``` Install to build python backends ```shell -analog@precision:~$ sudo apt-get python3 python3-pip python3-setuptools +analog@precision:~$ sudo apt-get install python3 python3-pip python3-setuptools ``` Install to Read local context attributes from `/etc/libiio.ini` ```shell diff -Nru libiio-0.21/README.md libiio-0.23/README.md --- libiio-0.21/README.md 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/README.md 2021-08-20 11:01:14.000000000 +0000 @@ -26,15 +26,15 @@ | Operating System | GitHub master status | Version | Primary Installer Package | Alternative Package, tarball or zip | |:-----------------------:|:---------------------:|:-------:|:-------------------:|:--------------:| | Windows | [![Windows Status](https://ci.appveyor.com/api/projects/status/github/analogdevicesinc/libiio?svg=true)](https://ci.appveyor.com/project/analogdevicesinc/libiio/branch/master) | Windows 10
Windows 8.1
Windows 8
Windows 7 | [![Latest Windows installer](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/win_box.png)](https://ci.appveyor.com/api/projects/analogdevicesinc/libiio/artifacts/libiio-setup.exe?branch=master) | [![Latest Windows zip](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/win_box.png)](https://ci.appveyor.com/api/projects/analogdevicesinc/libiio/artifacts/libiio.zip?branch=master) | -| OS X | [![OSX Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=osx&passingTex=foo)](https://travis-ci.org/analogdevicesinc/libiio) | OS X Mojave
(v 10.14) | [![OS-X package 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.pkg) | [![OS-X tarball 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.tar.gz) | -| | | OS X High Sierra
(v 10.13) | [![OS-X package 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.pkg) | [![OS-X tarball 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.tar.gz) | -| | | macOS Sierra
(v 10.12) | [![OS-X package 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.pkg) | [![OS-X tarball 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.tar.gz) | -| Linux | [![Linux Status](https://api.travis-ci.org/analogdevicesinc/libiio.svg?branch=master&label=linux)](https://travis-ci.org/analogdevicesinc/libiio) | Ubuntu Bionic Beaver
(v 18.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.rpm) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.tar.gz) | -| | | Ubuntu Xenial Xerus
(v 16.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.tar.gz) | -| | | Raspbian Stretch
(v 9) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.tar.gz) | -| | | Raspbian Jessie
(v 8) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.tar.gz) | -| | | CentOS 7 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.tar.gz) | -| | | CentOS 6 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](http://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.tar.gz) | +| OS X | [![OSX Status](https://api.travis-ci.com/analogdevicesinc/libiio.svg?branch=master&label=osx&passingTex=foo)](https://travis-ci.com/analogdevicesinc/libiio) | OS X Mojave
(v 10.14) | [![OS-X package 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.pkg) | [![OS-X tarball 10.14](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.14.4.tar.gz) | +| | | OS X High Sierra
(v 10.13) | [![OS-X package 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.pkg) | [![OS-X tarball 10.13](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.13.6.tar.gz) | +| | | macOS Sierra
(v 10.12) | [![OS-X package 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.pkg) | [![OS-X tarball 10.12](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/osx_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-darwin-10.12.6.tar.gz) | +| Linux | [![Linux Status](https://api.travis-ci.com/analogdevicesinc/libiio.svg?branch=master&label=linux)](https://travis-ci.com/analogdevicesinc/libiio) | Ubuntu Bionic Beaver
(v 18.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.rpm) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-18.04-amd64.tar.gz) | +| | | Ubuntu Xenial Xerus
(v 16.04)1 | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-ubuntu-16.04-amd64.tar.gz) | +| | | Raspbian Stretch
(v 9) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-9-armhf.tar.gz) | +| | | Raspbian Jessie
(v 8) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.deb) | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.rpm) [![tar.gz file](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-raspbian-8-armhf.tar.gz) | +| | | CentOS 7 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-7-x86_64.tar.gz) | +| | | CentOS 6 | [![RPM File](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/rpm.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.rpm) | [![Debian](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/deb.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.deb) [![tar.gz](https://raw.githubusercontent.com/wiki/analogdevicesinc/libiio/img/linux_box.png)](https://swdownloads.analog.com/cse/travis_builds/master_latest_libiio-centos-6.10-x86_64.tar.gz) | If you use it, and like it - please let us know. If you use it, and hate it - please let us know that too. The goal of the project is to try to make Linux IIO devices easier to use on a variety of platforms. If we aren't doing that - we will try to make it better. diff -Nru libiio-0.21/scan.c libiio-0.23/scan.c --- libiio-0.21/scan.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/scan.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2016 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. */ #include "iio-config.h" @@ -23,12 +14,8 @@ #include struct iio_scan_context { -#ifdef WITH_USB_BACKEND - struct iio_scan_backend_context *usb_ctx; -#endif -#ifdef HAVE_DNS_SD - struct iio_scan_backend_context *dnssd_ctx; -#endif + bool scan_usb; + bool scan_network; bool scan_local; }; @@ -49,8 +36,7 @@ { struct iio_scan_result scan_result = { 0, NULL }; -#ifdef WITH_LOCAL_BACKEND - if (ctx->scan_local) { + if (WITH_LOCAL_BACKEND && ctx->scan_local) { int ret = local_context_scan(&scan_result); if (ret < 0) { if (scan_result.info) @@ -58,29 +44,24 @@ return ret; } } -#endif -#ifdef WITH_USB_BACKEND - if (ctx->usb_ctx) { - int ret = usb_context_scan(ctx->usb_ctx, &scan_result); + if (WITH_USB_BACKEND && ctx->scan_usb) { + int ret = usb_context_scan(&scan_result); if (ret < 0) { if (scan_result.info) iio_context_info_list_free(scan_result.info); return ret; } } -#endif -#ifdef HAVE_DNS_SD - if (ctx->dnssd_ctx) { - int ret = dnssd_context_scan(ctx->dnssd_ctx, &scan_result); + if (HAVE_DNS_SD && ctx->scan_network) { + int ret = dnssd_context_scan(&scan_result); if (ret < 0) { if (scan_result.info) iio_context_info_list_free(scan_result.info); return ret; } } -#endif *info = scan_result.info; @@ -97,43 +78,35 @@ for (it = list; *it; it++) { struct iio_context_info *info = *it; - if (info->description) - free(info->description); - if (info->uri) - free(info->uri); + free(info->description); + free(info->uri); free(info); } free(list); } -struct iio_context_info ** iio_scan_result_add( - struct iio_scan_result *scan_result, size_t num) +struct iio_context_info * +iio_scan_result_add(struct iio_scan_result *scan_result) { struct iio_context_info **info; - size_t old_size, new_size; - size_t i; - - old_size = scan_result->size; - new_size = old_size + num; + size_t size = scan_result->size; - info = realloc(scan_result->info, (new_size + 1) * sizeof(*info)); + info = realloc(scan_result->info, (size + 2) * sizeof(*info)); if (!info) return NULL; scan_result->info = info; - scan_result->size = new_size; + scan_result->size = size + 1; - for (i = old_size; i < new_size; i++) { - /* Make sure iio_context_info_list_free won't overflow */ - info[i + 1] = NULL; + /* Make sure iio_context_info_list_free won't overflow */ + info[size + 1] = NULL; - info[i] = zalloc(sizeof(**info)); - if (!info[i]) - return NULL; - } + info[size] = zalloc(sizeof(**info)); + if (!info[size]) + return NULL; - return &info[old_size]; + return info[size]; } struct iio_scan_context * iio_create_scan_context( @@ -156,28 +129,17 @@ if (!backend || strstr(backend, "local")) ctx->scan_local = true; -#ifdef WITH_USB_BACKEND if (!backend || strstr(backend, "usb")) - ctx->usb_ctx = usb_context_scan_init(); -#endif -#ifdef HAVE_DNS_SD + ctx->scan_usb = true; + if (!backend || strstr(backend, "ip")) - ctx->dnssd_ctx = dnssd_context_scan_init(); -#endif + ctx->scan_network = true; return ctx; } void iio_scan_context_destroy(struct iio_scan_context *ctx) { -#ifdef WITH_USB_BACKEND - if (ctx->usb_ctx) - usb_context_scan_free(ctx->usb_ctx); -#endif -#ifdef HAVE_DNS_SD - if (ctx->dnssd_ctx) - dnssd_context_scan_free(ctx->dnssd_ctx); -#endif free(ctx); } diff -Nru libiio-0.21/serial.c libiio-0.23/serial.c --- libiio-0.21/serial.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/serial.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014-2016 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-private.h" @@ -32,7 +22,6 @@ struct iio_context_pdata { struct sp_port *port; - struct iio_mutex *lock; struct iiod_client *iiod_client; unsigned int timeout_ms; @@ -110,21 +99,48 @@ static int serial_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8]) { - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_get_version(pdata->iiod_client, NULL, major, minor, git_tag); } +static char * __serial_get_description(struct sp_port *port) +{ + char *description, *name, *desc; + size_t desc_len; + + name = sp_get_port_name(port); + desc = sp_get_port_description(port); + + desc_len = sizeof(": \0") + strlen(name) + strlen(desc); + description = malloc(desc_len); + if (!description) { + errno = ENOMEM; + return NULL; + } + + iio_snprintf(description, desc_len, "%s: %s", name, desc); + + return description; +} + +static char * serial_get_description(const struct iio_context *ctx) +{ + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return __serial_get_description(pdata->port); +} + static int serial_open(const struct iio_device *dev, size_t samples_count, bool cyclic) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *ctx_pdata = ctx->pdata; + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); struct iio_device_pdata *pdata = dev->pdata; int ret = -EBUSY; - iio_mutex_lock(ctx_pdata->lock); + iiod_client_mutex_lock(ctx_pdata->iiod_client); if (pdata->opened) goto out_unlock; @@ -134,18 +150,18 @@ pdata->opened = !ret; out_unlock: - iio_mutex_unlock(ctx_pdata->lock); + iiod_client_mutex_unlock(ctx_pdata->iiod_client); return ret; } static int serial_close(const struct iio_device *dev) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *ctx_pdata = ctx->pdata; + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); struct iio_device_pdata *pdata = dev->pdata; int ret = -EBADF; - iio_mutex_lock(ctx_pdata->lock); + iiod_client_mutex_lock(ctx_pdata->iiod_client); if (!pdata->opened) goto out_unlock; @@ -153,7 +169,7 @@ pdata->opened = false; out_unlock: - iio_mutex_unlock(ctx_pdata->lock); + iiod_client_mutex_unlock(ctx_pdata->iiod_client); return ret; } @@ -161,13 +177,13 @@ uint32_t *mask, size_t words) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); ssize_t ret; - iio_mutex_lock(pdata->lock); + iiod_client_mutex_lock(pdata->iiod_client); ret = iiod_client_read_unlocked(pdata->iiod_client, NULL, dev, dst, len, mask, words); - iio_mutex_unlock(pdata->lock); + iiod_client_mutex_unlock(pdata->iiod_client); return ret; } @@ -176,12 +192,12 @@ const void *src, size_t len) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); ssize_t ret; - iio_mutex_lock(pdata->lock); + iiod_client_mutex_lock(pdata->iiod_client); ret = iiod_client_write_unlocked(pdata->iiod_client, NULL, dev, src, len); - iio_mutex_unlock(pdata->lock); + iiod_client_mutex_unlock(pdata->iiod_client); return ret; } @@ -190,7 +206,7 @@ const char *attr, char *dst, size_t len, enum iio_attr_type type) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_read_attr(pdata->iiod_client, NULL, dev, NULL, attr, dst, len, type); @@ -200,7 +216,7 @@ const char *attr, const char *src, size_t len, enum iio_attr_type type) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_write_attr(pdata->iiod_client, NULL, dev, NULL, attr, src, len, type); @@ -211,7 +227,7 @@ { const struct iio_device *dev = iio_channel_get_device(chn); const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_read_attr(pdata->iiod_client, NULL, chn->dev, chn, attr, dst, len, false); @@ -222,7 +238,7 @@ { const struct iio_device *dev = iio_channel_get_device(chn); const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_write_attr(pdata->iiod_client, NULL, dev, chn, attr, src, len, false); @@ -232,34 +248,52 @@ unsigned int nb_blocks) { const struct iio_context *ctx = iio_device_get_context(dev); - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); return iiod_client_set_kernel_buffers_count(pdata->iiod_client, NULL, dev, nb_blocks); } static ssize_t serial_write_data(struct iio_context_pdata *pdata, - void *io_data, const char *data, size_t len) + struct iiod_client_pdata *io_data, + const char *data, size_t len) { ssize_t ret = (ssize_t) libserialport_to_errno(sp_blocking_write( pdata->port, data, len, pdata->timeout_ms)); IIO_DEBUG("Write returned %li: %s\n", (long) ret, data); + + if (ret < 0) { + IIO_ERROR("sp_blocking_write returned %i\n", (int) ret); + return ret; + } else if ((size_t) ret < len) { + IIO_ERROR("sp_blocking_write has timedout\n"); + return -ETIMEDOUT; + } + return ret; } static ssize_t serial_read_data(struct iio_context_pdata *pdata, - void *io_data, char *buf, size_t len) + struct iiod_client_pdata *io_data, + char *buf, size_t len) { ssize_t ret = (ssize_t) libserialport_to_errno(sp_blocking_read_next( pdata->port, buf, len, pdata->timeout_ms)); IIO_DEBUG("Read returned %li: %.*s\n", (long) ret, (int) ret, buf); + + if (ret == 0) { + IIO_ERROR("sp_blocking_read_next has timedout\n"); + return -ETIMEDOUT; + } + return ret; } static ssize_t serial_read_line(struct iio_context_pdata *pdata, - void *io_data, char *buf, size_t len) + struct iiod_client_pdata *io_data, + char *buf, size_t len) { size_t i; bool found = false; @@ -271,6 +305,11 @@ ret = libserialport_to_errno(sp_blocking_read_next( pdata->port, &buf[i], 1, pdata->timeout_ms)); + if (ret == 0) { + IIO_ERROR("sp_blocking_read_next has timedout\n"); + return -ETIMEDOUT; + } + if (ret < 0) { IIO_ERROR("sp_blocking_read_next returned %i\n", ret); return (ssize_t) ret; @@ -293,11 +332,10 @@ static void serial_shutdown(struct iio_context *ctx) { - struct iio_context_pdata *ctx_pdata = ctx->pdata; + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(ctx); unsigned int i; iiod_client_destroy(ctx_pdata->iiod_client); - iio_mutex_destroy(ctx_pdata->lock); sp_close(ctx_pdata->port); sp_free_port(ctx_pdata->port); @@ -307,13 +345,13 @@ free(pdata); } - - free(ctx_pdata); } static int serial_set_timeout(struct iio_context *ctx, unsigned int timeout) { - ctx->pdata->timeout_ms = timeout; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + pdata->timeout_ms = timeout; return 0; } @@ -329,6 +367,7 @@ .write_channel_attr = serial_write_chn_attr, .set_kernel_buffers_count = serial_set_kernel_buffers_count, .shutdown = serial_shutdown, + .get_description = serial_get_description, .set_timeout = serial_set_timeout, }; @@ -370,8 +409,8 @@ struct sp_port *port; struct iio_context_pdata *pdata; struct iio_context *ctx; - char *name, *desc, *description; - size_t desc_len, uri_len; + char *description; + size_t uri_len; unsigned int i; int ret; char *uri; @@ -404,17 +443,9 @@ /* Empty the buffers */ sp_flush(port, SP_BUF_BOTH); - name = sp_get_port_name(port); - desc = sp_get_port_description(port); - - desc_len = sizeof(": \0") + strlen(name) + strlen(desc); - description = malloc(desc_len); - if (!description) { - errno = ENOMEM; + description = __serial_get_description(port); + if (!description) goto err_close_port; - } - - iio_snprintf(description, desc_len, "%s: %s", name, desc); pdata = zalloc(sizeof(*pdata)); if (!pdata) { @@ -425,16 +456,9 @@ pdata->port = port; pdata->timeout_ms = DEFAULT_TIMEOUT_MS; - pdata->lock = iio_mutex_create(); - if (!pdata->lock) { - errno = ENOMEM; - goto err_free_pdata; - } - - pdata->iiod_client = iiod_client_new(pdata, pdata->lock, - &serial_iiod_client_ops); + pdata->iiod_client = iiod_client_new(pdata, &serial_iiod_client_ops); if (!pdata->iiod_client) - goto err_destroy_mutex; + goto err_free_pdata; ctx = iiod_client_create_context(pdata->iiod_client, NULL); if (!ctx) @@ -473,8 +497,6 @@ err_destroy_iiod_client: iiod_client_destroy(pdata->iiod_client); -err_destroy_mutex: - iio_mutex_destroy(pdata->lock); err_free_pdata: free(pdata); err_free_description: diff -Nru libiio-0.21/sort.c libiio-0.23/sort.c --- libiio-0.21/sort.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/sort.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2018 Analog Devices, Inc. * Author: Robin Getz - * - * 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. - * - * */ + */ #include "iio-private.h" #include diff -Nru libiio-0.21/sort.h libiio-0.23/sort.h --- libiio-0.21/sort.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/sort.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2018 Analog Devices, Inc. * Author: Robin Getz - * - * 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. - * - * */ + */ #ifndef __IIO_QSORT_H__ #define __IIO_QSORT_H__ diff -Nru libiio-0.21/tests/CMakeLists.txt libiio-0.23/tests/CMakeLists.txt --- libiio-0.21/tests/CMakeLists.txt 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/CMakeLists.txt 2021-08-20 11:01:14.000000000 +0000 @@ -46,7 +46,7 @@ set(IIO_TESTS_TARGETS iio_genxml iio_info iio_attr iio_readdev iio_reg iio_writedev) -if(PTHREAD_LIBRARIES) +if(PTHREAD_LIBRARIES OR ANDROID) project(iio_adi_xflow_check C) project(iio_stresstest C) add_executable(iio_adi_xflow_check iio_adi_xflow_check.c) diff -Nru libiio-0.21/tests/gen_code.c libiio-0.23/tests/gen_code.c --- libiio-0.21/tests/gen_code.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/gen_code.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,21 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014, 2019 Analog Devices, Inc. * Author: Paul Cercueil * Robin Getz - * - * 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. - * - * */ + */ #include #include diff -Nru libiio-0.21/tests/gen_code.h libiio-0.23/tests/gen_code.h --- libiio-0.21/tests/gen_code.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/gen_code.h 2021-08-20 11:01:14.000000000 +0000 @@ -1,21 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2014, 2019 Analog Devices, Inc. * Author: Paul Cercueil * Robin Getz - * - * 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. - * - * */ + */ #ifndef GEN_CODE_H #define GEN_CODE_H diff -Nru libiio-0.21/tests/iio_adi_xflow_check.c libiio-0.23/tests/iio_adi_xflow_check.c --- libiio-0.21/tests/iio_adi_xflow_check.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_adi_xflow_check.c 2021-08-20 11:01:14.000000000 +0000 @@ -185,6 +185,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': diff -Nru libiio-0.21/tests/iio_attr.c libiio-0.23/tests/iio_attr.c --- libiio-0.21/tests/iio_attr.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_attr.c 2021-08-20 11:01:14.000000000 +0000 @@ -99,21 +99,31 @@ return ret; } +static inline const char *get_label_or_name_or_id(const struct iio_device *dev) +{ + const char *label, *name; + + label = iio_device_get_label(dev); + if (label) + return label; + + name = iio_device_get_name(dev); + if (name) + return name; + + return iio_device_get_id(dev); +} + static int dump_device_attributes(const struct iio_device *dev, const char *attr, const char *wbuf, enum verbosity quiet) { ssize_t ret = 0; char *buf = xmalloc(BUF_SIZE, MY_NAME); - const char *name = iio_device_get_name(dev); if (!wbuf || quiet == ATTR_VERBOSE) { if (quiet == ATTR_VERBOSE) { printf("%s ", iio_device_is_trigger(dev) ? "trig" : "dev"); - if(name) - printf("'%s'", name); - else - printf("'%s'", iio_device_get_id(dev)); - + printf("'%s'", get_label_or_name_or_id(dev)); printf(", attr '%s', value :", attr); } gen_function("device", "dev", attr, NULL); @@ -125,7 +135,7 @@ printf("'%s'\n", buf); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li)\n", buf, (long)ret); + printf("ERROR: %s\n", buf); } } if (wbuf) { @@ -137,8 +147,8 @@ dump_device_attributes(dev, attr, NULL, quiet); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li) while writing '%s' with '%s'\n", - buf, (long)ret, attr, wbuf); + printf("ERROR: %s while writing '%s' with '%s'\n", + buf, attr, wbuf); } } free(buf); @@ -151,7 +161,6 @@ { ssize_t ret = 0; char *buf = xmalloc(BUF_SIZE, MY_NAME); - const char *name = iio_device_get_name(dev); if (!wbuf || quiet == ATTR_VERBOSE ) { gen_function("device_buffer", "dev", attr, NULL); @@ -159,11 +168,7 @@ if (quiet == ATTR_VERBOSE) { printf("%s ", iio_device_is_trigger(dev) ? "trig" : "dev"); - if (name) - printf("'%s'", name); - else - printf("'%s'", iio_device_get_id(dev)); - + printf("'%s'", get_label_or_name_or_id(dev)); printf(", buffer attr '%s', value :", attr); } @@ -174,7 +179,7 @@ printf("'%s'\n", buf); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li)\n", buf, (long)ret); + printf("ERROR: %s\n", buf); } } @@ -187,8 +192,8 @@ dump_buffer_attributes(dev, attr, NULL, quiet); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li) while writing '%s' with '%s'\n", - buf, (long)ret, attr, wbuf); + printf("ERROR: %s while writing '%s' with '%s'\n", + buf, attr, wbuf); } } @@ -201,7 +206,6 @@ { ssize_t ret = 0; char *buf = xmalloc(BUF_SIZE, MY_NAME); - const char *name = iio_device_get_name(dev); if (!wbuf || quiet == ATTR_VERBOSE) { gen_function("device_debug", "dev", attr, NULL); @@ -209,11 +213,7 @@ if (quiet == ATTR_VERBOSE) { printf("%s ", iio_device_is_trigger(dev) ? "trig" : "dev"); - if (name) - printf("'%s'", name); - else - printf("'%s'", iio_device_get_id(dev)); - + printf("'%s'", get_label_or_name_or_id(dev)); printf(", debug attr '%s', value :", attr); } @@ -225,7 +225,7 @@ printf("'%s'\n", buf); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li)\n", buf, (long)ret); + printf("ERROR: %s\n", buf); } } @@ -238,8 +238,8 @@ dump_debug_attributes(dev, attr, NULL, quiet); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li) while writing '%s' with '%s'\n", - buf, (long)ret, attr, wbuf); + printf("ERROR: %s while writing '%s' with '%s'\n", + buf, attr, wbuf); } } @@ -253,7 +253,6 @@ ssize_t ret = 0; char *buf = xmalloc(BUF_SIZE, MY_NAME); const char *type_name; - const char *name = iio_device_get_name(dev); if (!wbuf || quiet == ATTR_VERBOSE) { if (iio_channel_is_output(ch)) @@ -265,11 +264,7 @@ ret = iio_channel_attr_read(ch, attr, buf, BUF_SIZE); if (quiet == ATTR_VERBOSE) { printf("%s ", iio_device_is_trigger(dev) ? "trig" : "dev"); - if (name) - printf("'%s'", name); - else - printf("'%s'", iio_device_get_id(dev)); - + printf("'%s'", get_label_or_name_or_id(dev)); printf(", channel '%s' (%s), ", iio_channel_get_id(ch), type_name); @@ -287,7 +282,7 @@ printf("value '%s'\n", buf); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("ERROR: %s (%li)\n", buf, (long)ret); + printf("ERROR: %s\n", buf); } } if (wbuf) { @@ -299,8 +294,8 @@ dump_channel_attributes(dev, ch, attr, NULL, quiet); } else { iio_strerror(-(int)ret, buf, BUF_SIZE); - printf("error %s (%li) while writing '%s' with '%s'\n", - buf, (long)ret, attr, wbuf); + printf("error %s while writing '%s' with '%s'\n", + buf, attr, wbuf); } } free(buf); @@ -353,7 +348,7 @@ { char **argw; struct iio_context *ctx; - int c; + int c, argd = argc; int device_index = 0, channel_index = 0, attr_index = 0; const char *gen_file = NULL; bool search_device = false, ignore_case = false, @@ -371,13 +366,24 @@ argw = dup_argv(MY_NAME, argc, argv); - ctx = handle_common_opts(MY_NAME, argc, argw, MY_OPTS, options, options_descriptions); + /* + * getopt_long() thinks negative numbers are options, -1 is option '1' + * The only time we should see a negative number is the last argument during a write, + * so if there is one, we skip that argument during getopt processing + * look for "-" followed by a number. + */ + if (strnlen(argv[argc - 1], 2) >= 2 && argv[argc - 1][0] == '-' && + (argv[argc - 1][1] >= '0' && argv[argc - 1][1] <= '9')) { + argd--; + } + + ctx = handle_common_opts(MY_NAME, argd, argw, MY_OPTS, options, options_descriptions); opts = add_common_options(options); if (!opts) { fprintf(stderr, "Failed to add common options\n"); return EXIT_FAILURE; } - while ((c = getopt_long(argc, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ + while ((c = getopt_long(argd, argw, "+" COMMON_OPTIONS MY_OPTS, /* Flawfinder: ignore */ opts, NULL)) != -1) { switch (c) { /* All these are handled in the common */ @@ -385,6 +391,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': context_scan = true; @@ -618,8 +625,8 @@ } else { char *buf = xmalloc(BUF_SIZE, MY_NAME); iio_strerror(errno, buf, BUF_SIZE); - fprintf(stderr, "Unable to get context attributes: %s (%zd)\n", - buf, ret); + fprintf(stderr, "Unable to get context attributes: %s\n", + buf); free(buf); } } @@ -633,12 +640,16 @@ for (i = 0; i < nb_devices; i++) { const struct iio_device *dev = iio_context_get_device(ctx, i); + const char *dev_id = iio_device_get_id(dev); + const char *label = iio_device_get_label(dev); const char *name = iio_device_get_name(dev); + const char *label_or_name = label ? label : name; + const char *label_or_name_or_id = label_or_name ? label_or_name : dev_id; const char *ch_name; - const char *dev_id = iio_device_get_id(dev); unsigned int nb_attrs, nb_channels, j; if (device_index && !str_match(dev_id, argw[device_index], ignore_case) + && !str_match(label, argw[device_index], ignore_case) && !str_match(name, argw[device_index], ignore_case)) { continue; } @@ -647,8 +658,8 @@ if ((search_device && !device_index) || (search_channel && !device_index) || (search_buffer && !device_index) || (search_debug && !device_index)) { printf("\t%s", dev_id); - if (name) - printf(", %s", name); + if (label_or_name) + printf(", %s", label_or_name); printf(": "); } @@ -724,10 +735,7 @@ if ((!scan_only && !channel_index) || ( scan_only && iio_channel_is_scan_element(ch))) { printf("%s ", iio_device_is_trigger(dev) ? "trig" : "dev"); - if (name) - printf("'%s', ", name); - else - printf("'%s', ", dev_id); + printf("'%s', ", label_or_name_or_id); printf("channel '%s'", iio_channel_get_id(ch)); @@ -806,7 +814,7 @@ printf("found %u device attributes\n", nb_attrs); if (search_device && device_index && !attr_index && !nb_attrs) { printf("%s: Found %s device, but it has %u device attributes\n", - MY_NAME, name ? name : dev_id, nb_attrs); + MY_NAME, label_or_name_or_id, nb_attrs); if (!attr_found) found_err = true; } @@ -838,7 +846,7 @@ printf("found %u buffer attributes\n", nb_attrs); if (search_buffer && device_index && !attr_index && !nb_attrs) { printf("%s: Found %s device, but it has %u buffer attributes\n", - MY_NAME, name ? name : dev_id, nb_attrs); + MY_NAME, label_or_name_or_id, nb_attrs); if (!attr_found) found_err = true; } diff -Nru libiio-0.21/tests/iio_common.c libiio-0.23/tests/iio_common.c --- libiio-0.21/tests/iio_common.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_common.c 2021-08-20 11:01:14.000000000 +0000 @@ -95,11 +95,11 @@ } if (ret == 0) { - printf("No IIO context found.\n"); + fprintf(stderr, "No IIO context found.\n"); goto err_free_info_list; } if (rtn && ret == 1) { - printf("Using auto-detected IIO context at URI \"%s\"\n", + fprintf(stderr, "Using auto-detected IIO context at URI \"%s\"\n", iio_context_info_get_uri(info[0])); ctx = iio_create_context_from_uri(iio_context_info_get_uri(info[0])); } else { @@ -137,7 +137,7 @@ /* sanitized buffer by taking first 20 (or less) char */ iio_snprintf(buf, sizeof(buf), "%s", argv); errno = 0; - val = strtoul(buf, &end, 10); + val = strtoul(buf, &end, 0); if (buf == end || errno == ERANGE) val = 0; } @@ -193,6 +193,7 @@ {"uri", required_argument, 0, 'u'}, {"scan", optional_argument, 0, 'S'}, {"auto", optional_argument, 0, 'a'}, + {"timeout", required_argument, 0, 'T'}, {0, 0, 0, 0}, }; @@ -247,6 +248,8 @@ "Scan for available contexts and if a single context is" "\n\t\t\tavailable use it. filters backend(s)" "\n\t\t\t 'ip', 'usb' or 'ip:usb:'", + "Context timeout in milliseconds." + "\n\t\t\t0 = no timeout (wait forever)", }; @@ -261,6 +264,7 @@ bool do_scan = false, detect_context = false; char buf[128]; struct option *opts; + int timeout = -1; /* Setting opterr to zero disables error messages from getopt_long */ opterr = 0; @@ -339,6 +343,13 @@ arg = argv[optind++]; } break; + case 'T': + if (!optarg) { + fprintf(stderr, "Timeout requires an argument\n"); + return NULL; + } + timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); + break; case '?': break; } @@ -364,12 +375,24 @@ ctx = iio_create_default_context(); if (!ctx && !do_scan && !detect_context) { - char buf[1024]; - iio_strerror(errno, buf, sizeof(buf)); + char err_str[1024]; + iio_strerror(errno, err_str, sizeof(err_str)); if (arg) - fprintf(stderr, "Unable to create IIO context %s: %s\n", arg, buf); + fprintf(stderr, "Unable to create IIO context %s: %s\n", arg, err_str); else - fprintf(stderr, "Unable to create Local IIO context : %s\n", buf); + fprintf(stderr, "Unable to create Local IIO context : %s\n", err_str); + } + + if (ctx && timeout >= 0) { + ssize_t ret = iio_context_set_timeout(ctx, timeout); + if (ret < 0) { + char err_str[1024]; + iio_strerror(-(int)ret, err_str, sizeof(err_str)); + fprintf(stderr, "IIO contexts set timeout failed : %s\n", + err_str); + iio_context_destroy(ctx); + return NULL; + } } return ctx; diff -Nru libiio-0.21/tests/iio_common.h libiio-0.23/tests/iio_common.h --- libiio-0.21/tests/iio_common.h 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_common.h 2021-08-20 11:01:14.000000000 +0000 @@ -51,7 +51,7 @@ * If such a character is followed by a colon, the option requires an argument. * Two colons mean an option takes an optional argument. */ -#define COMMON_OPTIONS "hn:x:u:a::S::" +#define COMMON_OPTIONS "hn:x:u:a::S::T:" struct iio_context * handle_common_opts(char * name, int argc, char * const argv[], const char *optstring, diff -Nru libiio-0.21/tests/iio_genxml.c libiio-0.23/tests/iio_genxml.c --- libiio-0.21/tests/iio_genxml.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_genxml.c 2021-08-20 11:01:14.000000000 +0000 @@ -63,6 +63,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': diff -Nru libiio-0.21/tests/iio_info.c libiio-0.23/tests/iio_info.c --- libiio-0.21/tests/iio_info.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_info.c 2021-08-20 11:01:14.000000000 +0000 @@ -95,6 +95,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': @@ -131,7 +132,7 @@ else { char err_str[1024]; iio_strerror(-ret, err_str, sizeof(err_str)); - fprintf(stderr, "Unable to get backend version: %s (%i)\n", err_str, ret); + fprintf(stderr, "Unable to get backend version: %s\n", err_str); } printf("Backend description string: %s\n", @@ -150,8 +151,8 @@ else { char err_str[1024]; iio_strerror(-ret, err_str, sizeof(err_str)); - fprintf(stderr, "\tUnable to read IIO context attributes: %s (%i)\n", - err_str, ret); + fprintf(stderr, "\tUnable to read IIO context attributes: %s\n", + err_str); } } @@ -162,9 +163,12 @@ for (i = 0; i < nb_devices; i++) { const struct iio_device *dev = iio_context_get_device(ctx, i); const char *name = iio_device_get_name(dev); + const char *label = iio_device_get_label(dev); printf("\t%s:", iio_device_get_id(dev)); if (name) printf(" %s", name); + if (label) + printf(" (label: %s)", label); if (dev_is_buffer_capable(dev)) printf(" (buffer capable)"); printf("\n"); @@ -232,7 +236,7 @@ printf("value: %s\n", buf); } else { iio_strerror(-ret, buf, BUF_SIZE); - printf("ERROR: %s (%i)\n", buf, ret); + printf("ERROR: %s\n", buf); } } } @@ -253,7 +257,7 @@ printf("value: %s\n", buf); } else { iio_strerror(-ret, buf, BUF_SIZE); - printf("ERROR: %s (%i)\n", buf, ret); + printf("ERROR: %s\n", buf); } } } @@ -274,7 +278,7 @@ printf("value: %s\n", buf); } else { iio_strerror(-ret, buf, BUF_SIZE); - printf("ERROR: %s (%i)\n", buf, ret); + printf("ERROR: %s\n", buf); } } } @@ -294,7 +298,7 @@ printf("value: %s\n", buf); } else { iio_strerror(-ret, buf, BUF_SIZE); - printf("ERROR: %s (%i)\n", buf, ret); + printf("ERROR: %s\n", buf); } } } @@ -314,7 +318,7 @@ printf("\t\tNo trigger on this device\n"); } else if (ret < 0) { iio_strerror(-ret, buf, BUF_SIZE); - printf("ERROR: checking for trigger : %s (%i)\n", buf, ret); + printf("ERROR: checking for trigger : %s\n", buf); } } diff -Nru libiio-0.21/tests/iio_readdev.c libiio-0.23/tests/iio_readdev.c --- libiio-0.21/tests/iio_readdev.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_readdev.c 2021-08-20 11:01:14.000000000 +0000 @@ -38,18 +38,16 @@ {"trigger", required_argument, 0, 't'}, {"buffer-size", required_argument, 0, 'b'}, {"samples", required_argument, 0, 's' }, - {"timeout", required_argument, 0, 'T'}, {"auto", no_argument, 0, 'a'}, {0, 0, 0, 0}, }; static const char *options_descriptions[] = { - "[-t ] [-T ] [-b ]" + "[-t ] [-b ]" "[-s ] [ ...]", "Use the specified trigger.", "Size of the capture buffer. Default is 256.", "Number of samples to capture, 0 = infinite. Default is 0.", - "Buffer timeout in milliseconds. 0 = no timeout", "Scan for available contexts and if only one is available use it.", }; @@ -198,7 +196,6 @@ int c; struct iio_device *dev; ssize_t sample_size; - int timeout = -1; ssize_t ret; struct option *opts; @@ -219,6 +216,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': @@ -238,7 +236,7 @@ fprintf(stderr, "Buffersize requires an argument\n"); return EXIT_FAILURE; } - buffer_size = sanitize_clamp("buffer size", optarg, 64, 4 * 1024 * 1024); + buffer_size = sanitize_clamp("buffer size", optarg, 1, SIZE_MAX); break; case 's': if (!optarg) { @@ -247,13 +245,6 @@ } num_samples = sanitize_clamp("number of samples", optarg, 0, SIZE_MAX); break; - case 'T': - if (!optarg) { - fprintf(stderr, "Timeout requires an argument\n"); - return EXIT_FAILURE; - } - timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); - break; case '?': printf("Unknown argument '%c'\n", c); return EXIT_FAILURE; @@ -272,16 +263,6 @@ setup_sig_handler(); - if (timeout >= 0) { - ret = iio_context_set_timeout(ctx, timeout); - if (ret < 0) { - char err_str[1024]; - iio_strerror(-(int)ret, err_str, sizeof(err_str)); - fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", - err_str, ret); - } - } - dev = iio_context_find_device(ctx, argw[optind]); if (!dev) { fprintf(stderr, "Device %s not found\n", argw[optind]); @@ -315,8 +296,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "sample rate not set : %s (%zd)\n", - buf, ret); + fprintf(stderr, "sample rate not set : %s\n", buf); } } @@ -324,8 +304,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "set triffer failed : %s (%zd)\n", - buf, ret); + fprintf(stderr, "set triffer failed : %s\n", buf); } } @@ -432,8 +411,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "buffer processing failed : %s (%zi)\n", - buf, ret); + fprintf(stderr, "buffer processing failed : %s\n", buf); } } } diff -Nru libiio-0.21/tests/iio_reg.c libiio-0.23/tests/iio_reg.c --- libiio-0.21/tests/iio_reg.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_reg.c 2021-08-20 11:01:14.000000000 +0000 @@ -99,6 +99,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': diff -Nru libiio-0.21/tests/iio_stresstest.c libiio-0.23/tests/iio_stresstest.c --- libiio-0.21/tests/iio_stresstest.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_stresstest.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// 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 - * - * 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 _DEFAULT_SOURCE @@ -34,6 +24,10 @@ #include #endif +#ifdef _WIN32 +#include +#endif + #include "iio_common.h" #define MY_NAME "iio_stresstest" @@ -106,8 +100,8 @@ {"uri", required_argument, 0, 'u'}, {"buffer-size", required_argument, 0, 'b'}, {"samples", required_argument, 0, 's' }, - {"timeout", required_argument, 0, 't'}, - {"Threads", required_argument, 0, 'T'}, + {"Timeout", required_argument, 0, 'T'}, + {"threads", required_argument, 0, 't'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}, }; @@ -219,7 +213,7 @@ if (ret < 0) { char err_str[1024]; iio_strerror(-ret, err_str, sizeof(err_str)); \ - fprintf(stderr, "%i : IIO ERROR : %s : %s (%zd)\n", id, what, err_str, ret); \ + fprintf(stderr, "%i : IIO ERROR : %s : %s\n", id, what, err_str); \ } } @@ -430,13 +424,13 @@ info.buffer_size = sanitize_clamp("buffersize", info.argv[info.arg_index], min_samples, 1024 * 1024 * 4); break; - case 't': + case 'T': info.arg_index +=2; /* ensure between least once a day and never (0) */ info.timeout = 1000 * sanitize_clamp("timeout", info.argv[info.arg_index], 0, 60 * 60 * 24); break; - case 'T': + case 't': info.arg_index +=2; /* Max number threads 1024, min 1 */ info.num_threads = sanitize_clamp("threads", info.argv[info.arg_index], diff -Nru libiio-0.21/tests/iio_writedev.c libiio-0.23/tests/iio_writedev.c --- libiio-0.21/tests/iio_writedev.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/tests/iio_writedev.c 2021-08-20 11:01:14.000000000 +0000 @@ -47,7 +47,6 @@ {"trigger", required_argument, 0, 't'}, {"buffer-size", required_argument, 0, 'b'}, {"samples", required_argument, 0, 's' }, - {"timeout", required_argument, 0, 'T'}, {"auto", no_argument, 0, 'a'}, {"cyclic", no_argument, 0, 'c'}, {0, 0, 0, 0}, @@ -55,12 +54,11 @@ static const char *options_descriptions[] = { "[-t ] " - "[-T ] [-b ] [-s ] " + "[-b ] [-s ] " " [ ...]", "Use the specified trigger.", "Size of the transmit buffer. Default is 256.", "Number of samples to write, 0 = infinite. Default is 0.", - "Buffer timeout in milliseconds. 0 = no timeout", "Scan for available contexts and if only one is available use it.", "Use cyclic buffer mode.", }; @@ -209,7 +207,6 @@ int c; struct iio_device *dev; ssize_t sample_size; - int timeout = -1; bool cyclic_buffer = false; ssize_t ret; struct option *opts; @@ -230,6 +227,7 @@ case 'n': case 'x': case 'u': + case 'T': break; case 'S': case 'a': @@ -249,7 +247,7 @@ fprintf(stderr, "Buffer Size requires argument\n"); return EXIT_FAILURE; } - buffer_size = sanitize_clamp("buffer size", optarg, 64, 4 * 1024 * 1024); + buffer_size = sanitize_clamp("buffer size", optarg, 1, SIZE_MAX); break; case 's': if (!optarg) { @@ -258,13 +256,6 @@ } num_samples = sanitize_clamp("number of samples", optarg, 0, SIZE_MAX); break; - case 'T': - if (!optarg) { - fprintf(stderr, "Timeout requires argument\n"); - return EXIT_FAILURE; - } - timeout = sanitize_clamp("timeout", optarg, 0, INT_MAX); - break; case 'c': cyclic_buffer = true; break; @@ -286,16 +277,6 @@ setup_sig_handler(); - if (timeout >= 0) { - ret = iio_context_set_timeout(ctx, timeout); - if (ret < 0) { - char err_str[1024]; - iio_strerror(-(int)ret, err_str, sizeof(err_str)); - fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", - err_str, ret); - } - } - dev = iio_context_find_device(ctx, argw[optind]); if (!dev) { fprintf(stderr, "Device %s not found\n", argw[optind]); @@ -329,8 +310,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "sample rate not set : %s (%zd)\n", - buf, ret); + fprintf(stderr, "sample rate not set : %s\n", buf); } } @@ -338,8 +318,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "set triffer failed : %s (%zd)\n", - buf, ret); + fprintf(stderr, "set trigger failed : %s\n", buf); } } @@ -433,8 +412,7 @@ if (ret < 0) { char buf[256]; iio_strerror(-(int)ret, buf, sizeof(buf)); - fprintf(stderr, "buffer processing failed : %s (%zd)\n", - buf, ret); + fprintf(stderr, "buffer processing failed : %s\n", buf); } } diff -Nru libiio-0.21/.travis.yml libiio-0.23/.travis.yml --- libiio-0.21/.travis.yml 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/.travis.yml 2021-08-20 11:01:14.000000000 +0000 @@ -4,6 +4,7 @@ env: global: + - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss # SSHHOST - secure: "NEXUEA+ccm/I21ujCPuKYIHFb8Gogunr3nYysCRpTBNT40PsU9VFIy5vbmMxPAkCaMwk8XZ0rMHE3uaNGbBAGfoDL9v0Ban5wG/jA1JkmOAWUpFrUsbQeejXNRA04QcZ/4VeL6TgFegV2T6V0tLB4M6/X316dIPhS9Tat1ZUC8s=" # SSHUSER @@ -23,13 +24,11 @@ env: - ARCH=arm - OS_VERSION=jessie - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - compiler: "gcc" dist: xenial env: - ARCH=arm - OS_VERSION=stretch - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - compiler: "gcc" os: linux env: @@ -52,43 +51,35 @@ os: linux dist: xenial env: - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss # GH_DOC_TOKEN used to deploy docs - secure: "OrwnYeUITY2R7pn11WHqsO7c6F9fRY7G5fOh98GGXnw7dAIoSvUhjUE70ehaBzLH0CyO83KgaiyACP8eqRx9BYUd1McrqTFDmYJNVR+Wk01SSjJxaXzU4RMsJPhXH9l5U7BEH5dVk/IFLLaCwYnc35mlADHE2KCGNanvtnRU0gU=" - os: linux env: - OS_TYPE=centos_docker - OS_VERSION=6 - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - os: linux env: - OS_TYPE=centos_docker - OS_VERSION=7 - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - os: linux dist: bionic - env: - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - os: linux env: - OS_TYPE=centos_docker - OS_VERSION=8 - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - os: linux env: - OS_TYPE=ubuntu_docker - OS_VERSION=focal - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - compiler: "gcc" os: osx osx_image: xcode10.1 - env: - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss - compiler: "gcc" os: osx osx_image: xcode11 - env: - - EXTRA_SSH=-oHostKeyAlgorithms=+ssh-dss + - compiler: "gcc" + os: osx + osx_image: xcode12 - stage: "Trigger Next In Pipeline" env: diff -Nru libiio-0.21/usb.c libiio-0.23/usb.c --- libiio-0.21/usb.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/usb.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * libiio - Library for interfacing industrial I/O (IIO) devices * * Copyright (C) 2015 - 2020 Analog Devices, Inc. * Author: Paul Cercueil - * - * 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. - * - * */ + */ #include "iio-lock.h" #include "iio-private.h" @@ -26,10 +16,6 @@ #include #include -#ifdef ERROR -#undef ERROR -#endif - #include "debug.h" #define DEFAULT_TIMEOUT_MS 5000 @@ -47,7 +33,7 @@ struct iio_mutex *lock; }; -struct iio_usb_io_context { +struct iiod_client_pdata { struct iio_usb_ep_couple *ep; struct iio_mutex *lock; @@ -62,9 +48,6 @@ struct iiod_client *iiod_client; - /* Lock for non-streaming operations */ - struct iio_mutex *lock; - /* Lock for endpoint reservation */ struct iio_mutex *ep_lock; @@ -73,14 +56,14 @@ unsigned int timeout_ms; - struct iio_usb_io_context io_ctx; + struct iiod_client_pdata io_ctx; }; struct iio_device_pdata { struct iio_mutex *lock; bool opened; - struct iio_usb_io_context io_ctx; + struct iiod_client_pdata io_ctx; }; static const unsigned int libusb_to_errno_codes[] = { @@ -119,7 +102,7 @@ } } -static int usb_io_context_init(struct iio_usb_io_context *io_ctx) +static int usb_io_context_init(struct iiod_client_pdata *io_ctx) { io_ctx->lock = iio_mutex_create(); if (!io_ctx->lock) @@ -128,7 +111,7 @@ return 0; } -static void usb_io_context_exit(struct iio_usb_io_context *io_ctx) +static void usb_io_context_exit(struct iiod_client_pdata *io_ctx) { if (io_ctx->lock) { iio_mutex_destroy(io_ctx->lock); @@ -139,8 +122,10 @@ static int usb_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8]) { - return iiod_client_get_version(ctx->pdata->iiod_client, - &ctx->pdata->io_ctx, major, minor, git_tag); + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return iiod_client_get_version(pdata->iiod_client, + &pdata->io_ctx, major, minor, git_tag); } static unsigned int usb_calculate_remote_timeout(unsigned int timeout) @@ -223,7 +208,7 @@ static int usb_reserve_ep_unlocked(const struct iio_device *dev) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); unsigned int i; for (i = 0; i < pdata->nb_ep_couples; i++) { @@ -243,7 +228,7 @@ static void usb_free_ep_unlocked(const struct iio_device *dev) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); unsigned int i; for (i = 0; i < pdata->nb_ep_couples; i++) { @@ -259,7 +244,7 @@ static int usb_open(const struct iio_device *dev, size_t samples_count, bool cyclic) { - struct iio_context_pdata *ctx_pdata = dev->ctx->pdata; + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; int ret = -EBUSY; @@ -313,7 +298,7 @@ static int usb_close(const struct iio_device *dev) { - struct iio_context_pdata *ctx_pdata = dev->ctx->pdata; + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; int ret = -EBADF; @@ -340,11 +325,12 @@ static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len, uint32_t *mask, size_t words) { + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; ssize_t ret; iio_mutex_lock(pdata->lock); - ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client, + ret = iiod_client_read_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx, dev, dst, len, mask, words); iio_mutex_unlock(pdata->lock); @@ -354,11 +340,12 @@ static ssize_t usb_write(const struct iio_device *dev, const void *src, size_t len) { + struct iio_context_pdata *ctx_pdata = iio_context_get_pdata(dev->ctx); struct iio_device_pdata *pdata = dev->pdata; ssize_t ret; iio_mutex_lock(pdata->lock); - ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client, + ret = iiod_client_write_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx, dev, src, len); iio_mutex_unlock(pdata->lock); @@ -368,7 +355,7 @@ static ssize_t usb_read_dev_attr(const struct iio_device *dev, const char *attr, char *dst, size_t len, enum iio_attr_type type) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_read_attr(pdata->iiod_client, &pdata->io_ctx, dev, NULL, attr, @@ -378,7 +365,7 @@ static ssize_t usb_write_dev_attr(const struct iio_device *dev, const char *attr, const char *src, size_t len, enum iio_attr_type type) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_write_attr(pdata->iiod_client, &pdata->io_ctx, dev, NULL, attr, @@ -388,7 +375,7 @@ static ssize_t usb_read_chn_attr(const struct iio_channel *chn, const char *attr, char *dst, size_t len) { - struct iio_context_pdata *pdata = chn->dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); return iiod_client_read_attr(pdata->iiod_client, &pdata->io_ctx, chn->dev, chn, attr, @@ -398,7 +385,7 @@ static ssize_t usb_write_chn_attr(const struct iio_channel *chn, const char *attr, const char *src, size_t len) { - struct iio_context_pdata *pdata = chn->dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(chn->dev->ctx); return iiod_client_write_attr(pdata->iiod_client, &pdata->io_ctx, chn->dev, chn, attr, @@ -408,7 +395,7 @@ static int usb_set_kernel_buffers_count(const struct iio_device *dev, unsigned int nb_blocks) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_set_kernel_buffers_count(pdata->iiod_client, &pdata->io_ctx, dev, nb_blocks); @@ -416,7 +403,7 @@ static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout) { - struct iio_context_pdata *pdata = ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); unsigned int remote_timeout = usb_calculate_remote_timeout(timeout); int ret; @@ -431,7 +418,7 @@ static int usb_get_trigger(const struct iio_device *dev, const struct iio_device **trigger) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_get_trigger(pdata->iiod_client, &pdata->io_ctx, dev, trigger); @@ -440,7 +427,7 @@ static int usb_set_trigger(const struct iio_device *dev, const struct iio_device *trigger) { - struct iio_context_pdata *pdata = dev->ctx->pdata; + struct iio_context_pdata *pdata = iio_context_get_pdata(dev->ctx); return iiod_client_set_trigger(pdata->iiod_client, &pdata->io_ctx, dev, trigger); @@ -449,36 +436,35 @@ static void usb_shutdown(struct iio_context *ctx) { + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + unsigned int nb_devices = iio_context_get_devices_count(ctx); unsigned int i; - usb_io_context_exit(&ctx->pdata->io_ctx); + usb_io_context_exit(&pdata->io_ctx); - for (i = 0; i < ctx->nb_devices; i++) - usb_close(ctx->devices[i]); + for (i = 0; i < nb_devices; i++) + usb_close(iio_context_get_device(ctx, i)); - iio_mutex_destroy(ctx->pdata->lock); - iio_mutex_destroy(ctx->pdata->ep_lock); + iio_mutex_destroy(pdata->ep_lock); - for (i = 0; i < ctx->pdata->nb_ep_couples; i++) - if (ctx->pdata->io_endpoints[i].lock) - iio_mutex_destroy(ctx->pdata->io_endpoints[i].lock); - if (ctx->pdata->io_endpoints) - free(ctx->pdata->io_endpoints); + for (i = 0; i < pdata->nb_ep_couples; i++) + if (pdata->io_endpoints[i].lock) + iio_mutex_destroy(pdata->io_endpoints[i].lock); + free(pdata->io_endpoints); - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < nb_devices; i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); usb_io_context_exit(&dev->pdata->io_ctx); free(dev->pdata); } - iiod_client_destroy(ctx->pdata->iiod_client); + iiod_client_destroy(pdata->iiod_client); - usb_reset_pipes(ctx->pdata); /* Close everything */ + usb_reset_pipes(pdata); /* Close everything */ - libusb_close(ctx->pdata->hdl); - libusb_exit(ctx->pdata->ctx); - free(ctx->pdata); + libusb_close(pdata->hdl); + libusb_exit(pdata->ctx); } static int iio_usb_match_interface(const struct libusb_config_descriptor *desc, @@ -578,7 +564,7 @@ } static int usb_sync_transfer(struct iio_context_pdata *pdata, - struct iio_usb_io_context *io_ctx, unsigned int ep_type, + struct iiod_client_pdata *io_ctx, unsigned int ep_type, char *data, size_t len, int *transferred) { unsigned char ep; @@ -683,7 +669,8 @@ } static ssize_t write_data_sync(struct iio_context_pdata *pdata, - void *ep, const char *data, size_t len) + struct iiod_client_pdata *ep, + const char *data, size_t len) { int transferred, ret; @@ -696,7 +683,8 @@ } static ssize_t read_data_sync(struct iio_context_pdata *pdata, - void *ep, char *buf, size_t len) + struct iiod_client_pdata *ep, + char *buf, size_t len) { int transferred, ret; @@ -740,6 +728,7 @@ static int usb_populate_context_attrs(struct iio_context *ctx, libusb_device *dev, libusb_device_handle *hdl) { + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); struct libusb_device_descriptor dev_desc; char buffer[64]; unsigned int i; @@ -762,7 +751,7 @@ iio_snprintf(uri, sizeof(uri), "usb:%d.%d.%u", libusb_get_bus_number(dev), libusb_get_device_address(dev), - (uint8_t)ctx->pdata->intrfc); + (uint8_t)pdata->intrfc); ret = iio_context_add_attr(ctx, "uri", uri); if (ret < 0) return ret; @@ -817,8 +806,8 @@ return 0; } -struct iio_context * usb_create_context(unsigned int bus, - uint16_t address, uint16_t intrfc) +static struct iio_context * usb_create_context(unsigned int bus, + uint16_t address, uint16_t intrfc) { libusb_context *usb_ctx; libusb_device_handle *hdl = NULL; @@ -839,22 +828,14 @@ goto err_set_errno; } - pdata->lock = iio_mutex_create(); - if (!pdata->lock) { - IIO_ERROR("Unable to create mutex\n"); - ret = -ENOMEM; - goto err_free_pdata; - } - pdata->ep_lock = iio_mutex_create(); if (!pdata->ep_lock) { IIO_ERROR("Unable to create mutex\n"); ret = -ENOMEM; - goto err_destroy_mutex; + goto err_free_pdata; } - pdata->iiod_client = iiod_client_new(pdata, pdata->lock, - &usb_iiod_client_ops); + pdata->iiod_client = iiod_client_new(pdata, &usb_iiod_client_ops); if (!pdata->iiod_client) { IIO_ERROR("Unable to create IIOD client\n"); ret = -errno; @@ -872,7 +853,7 @@ if (ret < 0) { ret = -(int) libusb_to_errno(ret); IIO_ERROR("Unable to get usb device list: %i\n", ret); - goto err_destroy_iiod_client; + goto err_libusb_exit; } usb_dev = NULL; @@ -924,8 +905,8 @@ if (ret) { ret = -(int) libusb_to_errno(ret); iio_strerror(-ret, err_str, sizeof(err_str)); - IIO_ERROR("Unable to claim interface %u:%u:%u: %s (%i)\n", - bus, address, intrfc, err_str, ret); + IIO_ERROR("Unable to claim interface %u:%u:%u: %s\n", + bus, address, intrfc, err_str); goto err_libusb_close; } @@ -933,8 +914,7 @@ if (ret) { ret = -(int) libusb_to_errno(ret); iio_strerror(-ret, err_str, sizeof(err_str)); - IIO_ERROR("Unable to get config descriptor: %s (%i)\n", - err_str, ret); + IIO_ERROR("Unable to get config descriptor: %s\n", err_str); goto err_libusb_close; } @@ -1015,8 +995,8 @@ ctx->ops = &usb_ops; ctx->pdata = pdata; - for (i = 0; i < ctx->nb_devices; i++) { - struct iio_device *dev = ctx->devices[i]; + for (i = 0; i < iio_context_get_devices_count(ctx); i++) { + struct iio_device *dev = iio_context_get_device(ctx, i); dev->pdata = zalloc(sizeof(*dev->pdata)); if (!dev->pdata) { @@ -1049,8 +1029,7 @@ for (i = 0; i < pdata->nb_ep_couples; i++) if (pdata->io_endpoints[i].lock) iio_mutex_destroy(pdata->io_endpoints[i].lock); - if (pdata->io_endpoints) - free(pdata->io_endpoints); + free(pdata->io_endpoints); err_free_config_descriptor: libusb_free_config_descriptor(conf_desc); err_libusb_close: @@ -1061,8 +1040,6 @@ iiod_client_destroy(pdata->iiod_client); err_destroy_ep_mutex: iio_mutex_destroy(pdata->ep_lock); -err_destroy_mutex: - iio_mutex_destroy(pdata->lock); err_free_pdata: free(pdata); err_set_errno: @@ -1223,49 +1200,24 @@ return 0; } -struct iio_scan_backend_context { - libusb_context *ctx; -}; - -struct iio_scan_backend_context * usb_context_scan_init(void) +int usb_context_scan(struct iio_scan_result *scan_result) { - struct iio_scan_backend_context *ctx; - int ret; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) { - errno = ENOMEM; - return NULL; - } - - ret = libusb_init(&ctx->ctx); - if (ret) { - free(ctx); - errno = (int) libusb_to_errno(ret); - return NULL; - } - - return ctx; -} - -void usb_context_scan_free(struct iio_scan_backend_context *ctx) -{ - libusb_exit(ctx->ctx); - free(ctx); -} - -int usb_context_scan(struct iio_scan_backend_context *ctx, - struct iio_scan_result *scan_result) -{ - struct iio_context_info **info; + struct iio_context_info *info; libusb_device **device_list; + libusb_context *ctx; unsigned int i; int ret; - ret = (int) libusb_get_device_list(ctx->ctx, &device_list); + ret = libusb_init(&ctx); if (ret < 0) return -(int) libusb_to_errno(ret); + ret = (int) libusb_get_device_list(ctx, &device_list); + if (ret < 0) { + ret = -(int) libusb_to_errno(ret); + goto cleanup_libusb_exit; + } + for (i = 0; device_list[i]; i++) { struct libusb_device_handle *hdl; struct libusb_device *dev = device_list[i]; @@ -1276,12 +1228,12 @@ continue; if (!iio_usb_match_device(dev, hdl, &intrfc)) { - info = iio_scan_result_add(scan_result, 1); + info = iio_scan_result_add(scan_result); if (!info) ret = -ENOMEM; else - ret = usb_fill_context_info(*info, dev, hdl, - intrfc); + ret = usb_fill_context_info(info, dev, hdl, + intrfc); } libusb_close(hdl); @@ -1293,5 +1245,7 @@ cleanup_free_device_list: libusb_free_device_list(device_list, true); +cleanup_libusb_exit: + libusb_exit(ctx); return ret; } diff -Nru libiio-0.21/utilities.c libiio-0.23/utilities.c --- libiio-0.21/utilities.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/utilities.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,30 +1,21 @@ +// 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 - * - * 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. - * - * */ + */ /* Force the XSI version of strerror_r */ #undef _GNU_SOURCE +#include "dns_sd.h" #include "iio-config.h" #include "iio-private.h" -#include "network.h" #include #include +#include #include #include #include @@ -216,6 +207,10 @@ #endif if (ret != 0) iio_snprintf(buf, len, "Unknown error %i", err); + else { + size_t i = strnlen(buf, len); + iio_snprintf(buf + i, len - i, " (%i)", err); + } } char *iio_strdup(const char *str) @@ -301,7 +296,7 @@ len = strnlen(hostname, tmp); /* Should be smaller than max length */ - if (len <= tmp) + if (len == tmp) goto wrong_str; /* should be more than "usb:" or "ip:" */ @@ -321,3 +316,17 @@ #endif return NULL; } + +ssize_t __iio_printf iio_snprintf(char *buf, size_t len, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vsnprintf(buf, len, fmt, ap); + if (len && ret >= (ssize_t)len) + ret = -ERANGE; + va_end(ap); + + return (ssize_t)ret; +} diff -Nru libiio-0.21/xml.c libiio-0.23/xml.c --- libiio-0.21/xml.c 2020-06-17 09:39:16.000000000 +0000 +++ libiio-0.23/xml.c 2021-08-20 11:01:14.000000000 +0000 @@ -1,20 +1,10 @@ +// 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 - * - * 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. - * - * */ + */ #include "debug.h" #include "iio-private.h" @@ -23,35 +13,31 @@ #include #include -/* 'input' must be in UTF-8 encoded, null terminated */ -char * encode_xml_ndup(const char * input) -{ - char * out; - - out = (char *)xmlEncodeEntitiesReentrant(NULL, (const xmlChar *)input); - - return out; -} - static int add_attr_to_channel(struct iio_channel *chn, xmlNode *n) { xmlAttr *attr; char *name = NULL, *filename = NULL; struct iio_channel_attr *attrs; + int err = -ENOMEM; for (attr = n->properties; attr; attr = attr->next) { if (!strcmp((char *) attr->name, "name")) { name = iio_strdup((char *) attr->children->content); + if (!name) + goto err_free; } else if (!strcmp((char *) attr->name, "filename")) { filename = iio_strdup((char *) attr->children->content); + if (!filename) + goto err_free; } else { - IIO_WARNING("Unknown field \'%s\' in channel %s\n", - attr->name, chn->id); + IIO_DEBUG("Unknown field \'%s\' in channel %s\n", + attr->name, chn->id); } } if (!name) { IIO_ERROR("Incomplete attribute in channel %s\n", chn->id); + err = -EINVAL; goto err_free; } @@ -72,78 +58,46 @@ return 0; err_free: - if (name) - free(name); - if (filename) - free(filename); - return -1; + free(name); + free(filename); + return err; } static int add_attr_to_device(struct iio_device *dev, xmlNode *n, enum iio_attr_type type) { xmlAttr *attr; - char **attrs, *name = NULL; + char *name = NULL; for (attr = n->properties; attr; attr = attr->next) { if (!strcmp((char *) attr->name, "name")) { - name = iio_strdup((char *) attr->children->content); + name = (char *) attr->children->content; } else { - IIO_WARNING("Unknown field \'%s\' in device %s\n", - attr->name, dev->id); + IIO_DEBUG("Unknown field \'%s\' in device %s\n", + attr->name, dev->id); } } if (!name) { IIO_ERROR("Incomplete attribute in device %s\n", dev->id); - goto err_free; + return -EINVAL; } switch(type) { case IIO_ATTR_TYPE_DEBUG: - attrs = realloc(dev->debug_attrs, - (1 + dev->nb_debug_attrs) * sizeof(char *)); - break; + return add_iio_dev_attr(&dev->debug_attrs, name, " debug", dev->id); case IIO_ATTR_TYPE_DEVICE: - attrs = realloc(dev->attrs, - (1 + dev->nb_attrs) * sizeof(char *)); - break; + return add_iio_dev_attr(&dev->attrs, name, " ", dev->id); case IIO_ATTR_TYPE_BUFFER: - attrs = realloc(dev->buffer_attrs, - (1 + dev->nb_buffer_attrs) * sizeof(char *)); - break; + return add_iio_dev_attr(&dev->buffer_attrs, name, " buffer", dev->id); default: - attrs = NULL; - break; + return -EINVAL; } - if (!attrs) - goto err_free; - - switch(type) { - case IIO_ATTR_TYPE_DEBUG: - attrs[dev->nb_debug_attrs++] = name; - dev->debug_attrs = attrs; - break; - case IIO_ATTR_TYPE_DEVICE: - attrs[dev->nb_attrs++] = name; - dev->attrs = attrs; - break; - case IIO_ATTR_TYPE_BUFFER: - attrs[dev->nb_buffer_attrs++] = name; - dev->buffer_attrs = attrs; - break; - } - - return 0; - -err_free: - if (name) - free(name); - return -1; } -static void setup_scan_element(struct iio_channel *chn, xmlNode *n) +static int setup_scan_element(struct iio_channel *chn, xmlNode *n) { xmlAttr *attr; + int err; for (attr = n->properties; attr; attr = attr->next) { const char *name = (const char *) attr->name, @@ -155,12 +109,12 @@ errno = 0; value = strtoll(content, &end, 0); if (end == content || value < 0 || errno == ERANGE) - return; + return -EINVAL; chn->index = (long) value; } else if (!strcmp(name, "format")) { char e, s; if (strchr(content, 'X')) { - iio_sscanf(content, "%ce:%c%u/%uX%u>>%u", + err = iio_sscanf(content, "%ce:%c%u/%uX%u>>%u", #ifdef _MSC_BUILD &e, (unsigned int)sizeof(e), &s, (unsigned int)sizeof(s), @@ -171,9 +125,11 @@ &chn->format.length, &chn->format.repeat, &chn->format.shift); + if (err != 6) + return -EINVAL; } else { chn->format.repeat = 1; - iio_sscanf(content, "%ce:%c%u/%u>>%u", + err = iio_sscanf(content, "%ce:%c%u/%u>>%u", #ifdef _MSC_BUILD &e, (unsigned int)sizeof(e), &s, (unsigned int)sizeof(s), @@ -183,6 +139,8 @@ &chn->format.bits, &chn->format.length, &chn->format.shift); + if (err != 5) + return -EINVAL; } chn->format.is_be = e == 'b'; chn->format.is_signed = (s == 's' || s == 'S'); @@ -196,24 +154,29 @@ value = strtof(content, &end); if (end == content || errno == ERANGE) { chn->format.with_scale = false; - return; + return -EINVAL; } chn->format.with_scale = true; chn->format.scale = value; } else { - IIO_WARNING("Unknown attribute \'%s\' in \n", - name); + IIO_DEBUG("Unknown attribute \'%s\' in \n", + name); } } + + return 0; } static struct iio_channel * create_channel(struct iio_device *dev, xmlNode *n) { xmlAttr *attr; - struct iio_channel *chn = zalloc(sizeof(*chn)); + struct iio_channel *chn; + int err = -ENOMEM; + + chn = zalloc(sizeof(*chn)); if (!chn) - return NULL; + return ERR_PTR(-ENOMEM); chn->dev = dev; @@ -225,34 +188,42 @@ *content = (const char *) attr->children->content; if (!strcmp(name, "name")) { chn->name = iio_strdup(content); + if (!chn->name) + goto err_free_channel; } else if (!strcmp(name, "id")) { chn->id = iio_strdup(content); + if (!chn->id) + goto err_free_channel; } else if (!strcmp(name, "type")) { if (!strcmp(content, "output")) chn->is_output = true; else if (strcmp(content, "input")) - IIO_WARNING("Unknown channel type %s\n", content); + IIO_DEBUG("Unknown channel type %s\n", content); } else { - IIO_WARNING("Unknown attribute \'%s\' in \n", - name); + IIO_DEBUG("Unknown attribute \'%s\' in \n", + name); } } if (!chn->id) { IIO_ERROR("Incomplete \n"); + err = -EINVAL; goto err_free_channel; } for (n = n->children; n; n = n->next) { if (!strcmp((char *) n->name, "attribute")) { - if (add_attr_to_channel(chn, n) < 0) + err = add_attr_to_channel(chn, n); + if (err < 0) goto err_free_channel; } else if (!strcmp((char *) n->name, "scan-element")) { chn->is_scan_element = true; - setup_scan_element(chn, n); + err = setup_scan_element(chn, n); + if (err < 0) + goto err_free_channel; } else if (strcmp((char *) n->name, "text")) { - IIO_WARNING("Unknown children \'%s\' in \n", - n->name); + IIO_DEBUG("Unknown children \'%s\' in \n", + n->name); continue; } } @@ -263,15 +234,18 @@ err_free_channel: free_channel(chn); - return NULL; + return ERR_PTR(err); } static struct iio_device * create_device(struct iio_context *ctx, xmlNode *n) { xmlAttr *attr; - struct iio_device *dev = zalloc(sizeof(*dev)); + struct iio_device *dev; + int err = -ENOMEM; + + dev = zalloc(sizeof(*dev)); if (!dev) - return NULL; + return ERR_PTR(-ENOMEM); dev->ctx = ctx; @@ -279,16 +253,25 @@ if (!strcmp((char *) attr->name, "name")) { dev->name = iio_strdup( (char *) attr->children->content); + if (!dev->name) + goto err_free_device; + } else if (!strcmp((char *) attr->name, "label")) { + dev->label = iio_strdup((char *) attr->children->content); + if (!dev->label) + goto err_free_device; } else if (!strcmp((char *) attr->name, "id")) { dev->id = iio_strdup((char *) attr->children->content); + if (!dev->id) + goto err_free_device; } else { - IIO_WARNING("Unknown attribute \'%s\' in \n", - attr->name); + IIO_DEBUG("Unknown attribute \'%s\' in \n", + attr->name); } } if (!dev->id) { IIO_ERROR("Unable to read device ID\n"); + err = -EINVAL; goto err_free_device; } @@ -296,14 +279,16 @@ if (!strcmp((char *) n->name, "channel")) { struct iio_channel **chns, *chn = create_channel(dev, n); - if (!chn) { - IIO_ERROR("Unable to create channel\n"); + if (IS_ERR(chn)) { + err = PTR_ERR(chn); + IIO_ERROR("Unable to create channel: %d\n", err); goto err_free_device; } chns = realloc(dev->channels, (1 + dev->nb_channels) * sizeof(struct iio_channel *)); if (!chns) { + err = -ENOMEM; IIO_ERROR("Unable to allocate memory\n"); free(chn); goto err_free_device; @@ -312,17 +297,20 @@ chns[dev->nb_channels++] = chn; dev->channels = chns; } else if (!strcmp((char *) n->name, "attribute")) { - if (add_attr_to_device(dev, n, IIO_ATTR_TYPE_DEVICE) < 0) + err = add_attr_to_device(dev, n, IIO_ATTR_TYPE_DEVICE); + if (err < 0) goto err_free_device; } else if (!strcmp((char *) n->name, "debug-attribute")) { - if (add_attr_to_device(dev, n, IIO_ATTR_TYPE_DEBUG) < 0) + err = add_attr_to_device(dev, n, IIO_ATTR_TYPE_DEBUG); + if (err < 0) goto err_free_device; } else if (!strcmp((char *) n->name, "buffer-attribute")) { - if (add_attr_to_device(dev, n, IIO_ATTR_TYPE_BUFFER) < 0) + err = add_attr_to_device(dev, n, IIO_ATTR_TYPE_BUFFER); + if (err < 0) goto err_free_device; } else if (strcmp((char *) n->name, "text")) { - IIO_WARNING("Unknown children \'%s\' in \n", - n->name); + IIO_DEBUG("Unknown children \'%s\' in \n", + n->name); continue; } } @@ -331,7 +319,7 @@ if (dev->words) { dev->mask = calloc(dev->words, sizeof(*dev->mask)); if (!dev->mask) { - errno = ENOMEM; + err = -ENOMEM; goto err_free_device; } } @@ -340,7 +328,8 @@ err_free_device: free_device(dev); - return NULL; + + return ERR_PTR(err); } static struct iio_context * xml_clone(const struct iio_context *ctx) @@ -352,6 +341,13 @@ .clone = xml_clone, }; +static const struct iio_backend xml_backend = { + .api_version = IIO_BACKEND_API_V1, + .name = "xml", + .uri_prefix = "xml:", + .ops = &xml_ops, +}; + static int parse_context_attr(struct iio_context *ctx, xmlNode *n) { xmlAttr *attr; @@ -371,91 +367,106 @@ return iio_context_add_attr(ctx, name, value); } -static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) +static int iio_populate_xml_context_helper(struct iio_context *ctx, xmlNode *root) { - unsigned int i; - xmlNode *root, *n; - xmlAttr *attr; - int err = -ENOMEM; - struct iio_context *ctx = zalloc(sizeof(*ctx)); - if (!ctx) - goto err_set_errno; - - ctx->name = "xml"; - ctx->ops = &xml_ops; - - root = xmlDocGetRootElement(doc); - if (strcmp((char *) root->name, "context")) { - IIO_ERROR("Unrecognized XML file\n"); - err = -EINVAL; - goto err_free_ctx; - } - - for (attr = root->properties; attr; attr = attr->next) { - if (!strcmp((char *) attr->name, "description")) - ctx->description = iio_strdup( - (char *) attr->children->content); - else if (strcmp((char *) attr->name, "name")) - IIO_WARNING("Unknown parameter \'%s\' in \n", - (char *) attr->children->content); - } + xmlNode *n; + int err; for (n = root->children; n; n = n->next) { - struct iio_device **devs, *dev; + struct iio_device *dev; if (!strcmp((char *) n->name, "context-attribute")) { err = parse_context_attr(ctx, n); if (err) - goto err_free_devices; - else - continue; + return err; + + continue; } else if (strcmp((char *) n->name, "device")) { if (strcmp((char *) n->name, "text")) - IIO_WARNING("Unknown children \'%s\' in " - "\n", n->name); + IIO_DEBUG("Unknown children \'%s\' in " + "\n", n->name); continue; } dev = create_device(ctx, n); - if (!dev) { - IIO_ERROR("Unable to create device\n"); - goto err_free_devices; + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + IIO_ERROR("Unable to create device: %d\n", err); + return err; } - devs = realloc(ctx->devices, (1 + ctx->nb_devices) * - sizeof(struct iio_device *)); - if (!devs) { - IIO_ERROR("Unable to allocate memory\n"); + err = iio_context_add_device(ctx, dev); + if (err) { free(dev); - goto err_free_devices; + return err; + } + } + + return iio_context_init(ctx); +} + +static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc) +{ + const char *description = NULL, *git_tag = NULL, *content; + struct iio_context *ctx; + long major = 0, minor = 0; + xmlNode *root; + xmlAttr *attr; + char *end; + int err; + + root = xmlDocGetRootElement(doc); + if (strcmp((char *) root->name, "context")) { + IIO_ERROR("Unrecognized XML file\n"); + errno = EINVAL; + return NULL; + } + + for (attr = root->properties; attr; attr = attr->next) { + content = (const char *) attr->children->content; + + if (!strcmp((char *) attr->name, "description")) { + description = content; + } else if (!strcmp((char *) attr->name, "version-major")) { + major = strtol(content, &end, 10); + if (*end != '\0') + IIO_WARNING("invalid format for major version\n"); + } else if (!strcmp((char *) attr->name, "version-minor")) { + minor = strtol(content, &end, 10); + if (*end != '\0') + IIO_WARNING("invalid format for minor version\n"); + } else if (!strcmp((char *) attr->name, "version-git")) { + git_tag = content; + } else if (strcmp((char *) attr->name, "name")) { + IIO_DEBUG("Unknown parameter \'%s\' in \n", + content); } + } - devs[ctx->nb_devices++] = dev; - ctx->devices = devs; + ctx = iio_context_create_from_backend(&xml_backend, description); + if (!ctx) + return NULL; + + if (git_tag) { + ctx->major = major; + ctx->minor = minor; + + ctx->git_tag = iio_strdup(git_tag); + if (!ctx->git_tag) { + iio_context_destroy(ctx); + errno = ENOMEM; + return NULL; + } } - err = iio_context_init(ctx); - if (err) - goto err_free_devices; + err = iio_populate_xml_context_helper(ctx, root); + if (err) { + iio_context_destroy(ctx); + errno = -err; + return NULL; + } return ctx; - -err_free_devices: - for (i = 0; i < ctx->nb_devices; i++) - free_device(ctx->devices[i]); - if (ctx->nb_devices) - free(ctx->devices); - for (i = 0; i < ctx->nb_attrs; i++) { - free(ctx->attrs[i]); - free(ctx->values[i]); - } - free(ctx->attrs); - free(ctx->values); -err_free_ctx: - free(ctx); -err_set_errno: - errno = -err; - return NULL; } struct iio_context * xml_create_context(const char *xml_file) @@ -495,3 +506,47 @@ xmlFreeDoc(doc); return ctx; } + + +static void cleanup_libxml2_stuff(void) +{ + /* + * This function will be called only when the libiio library is + * unloaded (e.g. when the program exits). + * + * Cleanup libxml2 so that memory analyzer tools like Valgrind won't + * detect a memory leak. + */ + xmlCleanupParser(); + xmlMemoryDump(); +} + +#if defined(_MSC_BUILD) +#pragma section(".CRT$XCU", read) +#define __CONSTRUCTOR(f, p) \ + static void f(void); \ + __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ + __pragma(comment(linker,"/include:" p #f "_")) \ + static void f(void) +#ifdef _WIN64 +#define _CONSTRUCTOR(f) __CONSTRUCTOR(f, "") +#else +#define _CONSTRUCTOR(f) __CONSTRUCTOR(f, "_") +#endif +#elif defined(__GNUC__) +#define _CONSTRUCTOR(f) static void __attribute__((constructor)) f(void) +#else +#define _CONSTRUCTOR(f) static void f(void) +#endif + +_CONSTRUCTOR(initialize) +{ + /* + * When the library loads, register our destructor. + * Do it here and not in the context creation function, + * as it could otherwise end up registering the destructor + * many times. + */ + atexit(cleanup_libxml2_stuff); +} +#undef _CONSTRUCTOR