1 /* 2 * libiio - Library for interfacing industrial I/O (IIO) devices 3 * 4 * Copyright (C) 2015 Analog Devices, Inc. 5 * Author: Paul Cercueil <paul.cercueil@analog.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * */ 18 19 using System; 20 using System.Collections.Generic; 21 using System.Linq; 22 using System.Runtime.InteropServices; 23 using System.Text; 24 using System.Threading.Tasks; 25 26 namespace iio 27 { 28 public class Version 29 { 30 public readonly uint major; 31 public readonly uint minor; 32 public readonly string git_tag; 33 Version(uint major, uint minor, string git_tag)34 internal Version(uint major, uint minor, string git_tag) 35 { 36 this.major = major; 37 this.minor = minor; 38 this.git_tag = git_tag; 39 } 40 } 41 42 /// <summary><see cref="iio.Context"/> class: 43 /// Contains the representation of an IIO context.</summary> 44 public class Context : IDisposable 45 { 46 private IntPtr ctx; 47 48 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_create_network_context( [In()][MarshalAs(UnmanagedType.LPStr)] string hostname )49 private static extern IntPtr iio_create_network_context( 50 [In()][MarshalAs(UnmanagedType.LPStr)] string hostname 51 ); 52 53 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_create_context_from_uri( [In()][MarshalAs(UnmanagedType.LPStr)] string uri )54 private static extern IntPtr iio_create_context_from_uri( 55 [In()][MarshalAs(UnmanagedType.LPStr)] string uri 56 ); 57 58 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_create_default_context()59 private static extern IntPtr iio_create_default_context(); 60 61 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_destroy(IntPtr ctx)62 private static extern void iio_context_destroy(IntPtr ctx); 63 64 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_name(IntPtr ctx)65 private static extern IntPtr iio_context_get_name(IntPtr ctx); 66 67 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_description(IntPtr ctx)68 private static extern IntPtr iio_context_get_description(IntPtr ctx); 69 70 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_xml(IntPtr ctx)71 private static extern IntPtr iio_context_get_xml(IntPtr ctx); 72 73 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_library_get_version(ref uint major, ref uint minor, [Out()] StringBuilder git_tag)74 private static extern void iio_library_get_version(ref uint major, ref uint minor, [Out()] StringBuilder git_tag); 75 76 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_version(IntPtr ctx, ref uint major, ref uint minor, [Out()] StringBuilder git_tag)77 private static extern int iio_context_get_version(IntPtr ctx, ref uint major, ref uint minor, [Out()] StringBuilder git_tag); 78 79 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_devices_count(IntPtr ctx)80 private static extern uint iio_context_get_devices_count(IntPtr ctx); 81 82 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_get_device(IntPtr ctx, uint index)83 private static extern IntPtr iio_context_get_device(IntPtr ctx, uint index); 84 85 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] 86 [return: MarshalAs(UnmanagedType.I1)] iio_device_is_trigger(IntPtr dev)87 private static extern bool iio_device_is_trigger(IntPtr dev); 88 89 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_set_timeout(IntPtr ctx, uint timeout_ms)90 private static extern int iio_context_set_timeout(IntPtr ctx, uint timeout_ms); 91 92 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_context_clone(IntPtr ctx)93 private static extern IntPtr iio_context_clone(IntPtr ctx); 94 95 /// <summary>A XML representation of the current context.</summary> 96 public readonly string xml; 97 98 /// <summary>The name of the current context.</summary> 99 public readonly string name; 100 101 /// <summary>Retrieve a human-readable information string about the current context.</summary> 102 public readonly string description; 103 public readonly Version library_version, backend_version; 104 105 /// <summary>A <c>List</c> of all the IIO devices present on the current context.</summary> 106 public readonly List<Device> devices; 107 108 /// <summary>Initializes a new instance of the <see cref="iio.Context"/> class, 109 /// using the provided URI. For compatibility with existing code, providing 110 /// an IP address or a hostname here will automatically create a network 111 /// context.</summary> 112 /// <param name="uri">URI to use for the IIO context creation</param> 113 /// <returns>an instance of the <see cref="iio.Context"/> class</returns> 114 /// <exception cref="System.Exception">The IIO context could not be created.</exception> Context(string uri)115 public Context(string uri) : this(getContextFromString(uri)) {} 116 117 /// <summary>Initializes a new instance of the <see cref="iio.Context"/> class, 118 /// using the local or the network backend of the IIO library.</summary> 119 /// <remarks>This function will create a network context if the IIOD_REMOTE 120 /// environment variable is set to the hostname where the IIOD server runs. 121 /// If set to an empty string, the server will be discovered using ZeroConf. 122 /// If the environment variable is not set, a local context will be created 123 /// instead.</remarks> 124 /// <exception cref="System.Exception">The IIO context could not be created.</exception> Context()125 public Context() : this(iio_create_default_context()) {} 126 getContextFromString(string str)127 private static IntPtr getContextFromString(string str) 128 { 129 IntPtr ptr = iio_create_context_from_uri(str); 130 if (ptr == IntPtr.Zero) 131 ptr = iio_create_network_context(str); 132 return ptr; 133 } 134 Context(IntPtr ctx)135 private Context(IntPtr ctx) 136 { 137 this.ctx = ctx; 138 139 if (ctx == IntPtr.Zero) 140 throw new Exception("Unable to create IIO context"); 141 142 uint nb_devices = iio_context_get_devices_count(ctx); 143 144 devices = new List<Device>(); 145 for (uint i = 0; i < nb_devices; i++) 146 { 147 IntPtr ptr = iio_context_get_device(ctx, i); 148 if (iio_device_is_trigger(ptr)) 149 devices.Add(new Trigger(this, ptr)); 150 else 151 devices.Add(new Device(this, ptr)); 152 } 153 154 xml = Marshal.PtrToStringAnsi(iio_context_get_xml(ctx)); 155 name = Marshal.PtrToStringAnsi(iio_context_get_name(ctx)); 156 description = Marshal.PtrToStringAnsi(iio_context_get_description(ctx)); 157 158 uint major = 0; 159 uint minor = 0; 160 StringBuilder builder = new StringBuilder(8); 161 iio_library_get_version(ref major, ref minor, builder); 162 library_version = new Version(major, minor, builder.ToString()); 163 164 major = 0; 165 minor = 0; 166 builder.Clear(); 167 int err = iio_context_get_version(ctx, ref major, ref minor, builder); 168 if (err < 0) 169 throw new Exception("Unable to read backend version"); 170 backend_version = new Version(major, minor, builder.ToString()); 171 } 172 ~Context()173 ~Context() 174 { 175 if (ctx != IntPtr.Zero) 176 Dispose(false); 177 } 178 179 /// <summary>Clone this instance.</summary> clone()180 public Context clone() 181 { 182 return new Context(iio_context_clone(this.ctx)); 183 } 184 185 /// <summary>Get the <see cref="iio.Device"/> object of the specified name.</summary> 186 /// <param name="name">Name or ID of the device to look for</param> 187 /// <exception cref="System.Exception">The IIO device with the specified 188 /// name or ID could not be found in the current context.</exception> get_device(string name)189 public Device get_device(string name) 190 { 191 foreach (Device each in devices) { 192 if (each.name.CompareTo(name) == 0 || 193 each.id.CompareTo(name) == 0) 194 return each; 195 } 196 197 throw new Exception("Device " + name + " not found"); 198 } 199 200 /// <summary>Set a timeout for I/O operations.</summary> 201 /// <param name="timeout">The timeout value, in milliseconds</param> 202 /// <exception cref="System.Exception">The timeout could not be applied.</exception> set_timeout(uint timeout)203 public void set_timeout(uint timeout) 204 { 205 int ret = iio_context_set_timeout(ctx, timeout); 206 if (ret < 0) 207 throw new Exception("Unable to set timeout"); 208 } 209 210 /// <summary>Releases all resource used by the <see cref="iio.Context"/> object.</summary> 211 /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="iio.Context"/>. The 212 /// <see cref="Dispose"/> method leaves the <see cref="iio.Context"/> in an unusable state. After calling 213 /// <see cref="Dispose"/>, you must release all references to the <see cref="iio.Context"/> so the garbage 214 /// collector can reclaim the memory that the <see cref="iio.Context"/> was occupying.</remarks> Dispose()215 public void Dispose() 216 { 217 Dispose(true); 218 } 219 Dispose(bool clean)220 private void Dispose(bool clean) 221 { 222 if (ctx != IntPtr.Zero) 223 { 224 if (clean) 225 GC.SuppressFinalize(this); 226 iio_context_destroy(ctx); 227 ctx = IntPtr.Zero; 228 } 229 } 230 } 231 } 232