summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2011-05-19 12:00:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2011-05-19 12:00:00 +0200
commit9444a60b913b8c5ff6946d58087fbe6cee8ce887 (patch)
tree7d7b2c1f443f9bdaa2ee05d76633b82546b7dcd4
parent384267346c5824f02bac7265e45f8937c9a7b48b (diff)
downloadmbgsdk-win-MeinbergAPIC#Wrapper.tar.gz
mbgsdk-win-MeinbergAPIC#Wrapper.zip
Add an example C# wrapper for mbgdevioMeinbergAPIC#Wrapper
The code was provided by a customer
-rw-r--r--c#/demo/mbgdevio/Constants.cs85
-rw-r--r--c#/demo/mbgdevio/Interop.cs239
-rw-r--r--c#/demo/mbgdevio/MeinbergAPI.csproj69
-rw-r--r--c#/demo/mbgdevio/MeinbergDevice.cs291
-rw-r--r--c#/demo/mbgdevio/MeinbergDeviceManager.cs90
-rw-r--r--c#/demo/mbgdevio/Properties/AssemblyInfo.cs36
-rw-r--r--c#/demo/mbgdevio/Structures.cs170
7 files changed, 980 insertions, 0 deletions
diff --git a/c#/demo/mbgdevio/Constants.cs b/c#/demo/mbgdevio/Constants.cs
new file mode 100644
index 0000000..d781352
--- /dev/null
+++ b/c#/demo/mbgdevio/Constants.cs
@@ -0,0 +1,85 @@
+using System;
+
+namespace MeinbergAPI
+{
+ public partial class Interop
+ {
+
+ // Please note:
+ // IRIG receiver cards may set the PCPS_INVT bit also if the card//s ref time offset
+ // to UTC has not yet been configured, or if the on-board date does not match the
+ // day-of-year number of the incoming IRIG signal. The reason for this is to avoid
+ // accepting wrong times from the IRIG signal due to the ambiguity of the time and
+ // day-of-year from the IRIG signal.
+
+ /// <summary>
+ /// This value is returned by the API functions on success
+ /// </summary>
+ public const short PCPS_SUCCESS = 0;
+
+ #region Bit masks used with both the status fields of the PCPS_TIME structure and the PCPS_HR_TIME structure
+
+ /// <summary>
+ /// GPS receiver has not verified its position
+ /// </summary>
+ public const short PCPS_FREER = 0x1;
+
+ /// <summary>
+ /// Daylight saving enabled
+ /// </summary>
+ public const short PCPS_DL_ENB = 0x2;
+
+ /// <summary>
+ /// Clock has synced at least once after power up
+ /// </summary>
+ public const short PCPS_SYNCD = 0x4;
+
+ /// <summary>
+ /// A change in daylight saving is announced
+ /// </summary>
+ public const short PCPS_DL_ANN = 0x8;
+
+ /// <summary>
+ /// The returned time is UTC
+ /// </summary>
+ public const short PCPS_UTC = 0x10;
+
+ /// <summary>
+ /// Leap second is announced
+ /// </summary>
+ public const short PCPS_LS_ANN = 0x20;
+
+ /// <summary>
+ /// The current time was set via PC interface
+ /// </summary>
+ public const short PCPS_IFTM = 0x40;
+
+ /// <summary>
+ /// Invalid time because battery was disconnected.
+ /// </summary>
+ public const short PCPS_INVT = 0x80;
+
+ #endregion
+
+ #region Bit masks used with the status fields of the PCPS_HR_TIME structure only
+
+ /// <summary>
+ /// current second is leap second
+ /// </summary>
+ public const short PCPS_LS_ENB = 0x100;
+
+ /// <summary>
+ /// Antenna failure
+ /// </summary>
+ public const short PCPS_ANT_FAIL = 0x200;
+
+ #endregion
+
+ #region These bits are used only if the PCPS_HR_TIME structure PCPS_HR_TIME contains a user capture event
+
+ public const short PCPS_UCAP_OVERRUN = 0x2000; // events interval too short
+ public const short PCPS_UCAP_BUFFER_FULL = 0x4000; // events read too slow
+
+ #endregion
+ }
+}
diff --git a/c#/demo/mbgdevio/Interop.cs b/c#/demo/mbgdevio/Interop.cs
new file mode 100644
index 0000000..1d5b2a4
--- /dev/null
+++ b/c#/demo/mbgdevio/Interop.cs
@@ -0,0 +1,239 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace MeinbergAPI
+{
+ /// <summary>
+ /// Not all API calls included below are supported by any Meinberg
+ /// plug-in card. Calls to functions which are not supported by a device
+ /// don't do any harm, they just return an error code to the application.
+ /// However, every API call to an unsupported function results in a log entry
+ /// in the Windows application event log, so an application should first check
+ /// whether such an API call is supported by the specific device. API calls
+ /// which are not supported by each device are commented accordingly.
+ /// </summary>
+ public partial class Interop
+ {
+ #region General functions supported by all Meinberg devices
+
+ /// <summary>
+ /// Returns the number of radio clock devices detected
+ /// If this function returns 0, then no devices has been detected.
+ /// </summary>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_find_devices", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_find_devices();
+
+ /// <summary>
+ /// Opens the device with given index and retrieve a handle to the device
+ /// E.g. if n devices have been found, valid indices are 0..n-1
+ /// </summary>
+ /// <param name="i">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <returns>The opened device's handle.</returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_open_device", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_open_device(int i);
+
+ /// <summary>
+ /// Closes the device and release the device handle.
+ /// The device handle value will be set to 0.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <returns>Will always return 0.</returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_close_device", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_close_device(ref int h);
+
+ /// <summary>
+ /// Reads date, time, and status from the device referenced by handle h.
+ /// This function is supported by all Meinberg plug-in boards and returns
+ /// date and time in human readable format (calendar date and time).
+ /// However, the resolution of time is limited to 10 milliseconds.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="t">The device's current time.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_time", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_time(int h, ref PCPS_TIME t);
+
+ #endregion
+
+ /// <summary>
+ /// The functions below read high resolution time plus status from the device
+ /// referenced by handle h.
+ /// These functions are NOT supported by all Meinberg plug-in boards, and the
+ /// effective resolution of the HR time depends on the characteristics of the
+ /// specific device.
+ /// </summary>
+ #region Functions for high-resolution time
+
+ /// <summary>
+ /// Checks whether the device referenced by handle h supports HR time.
+ /// If it does then the value returned for f is not 0.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="f">0 if not supported. If any other value, then supported.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_dev_has_hr_time", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_dev_has_hr_time(int h, ref int f);
+
+ /// <summary>
+ /// Reads a HR time stamp from the board. The returned time stamp may be biased
+ /// by a latency due to the IOCTL call performed by the function.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="t">The HR timestamp to set.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_hr_time", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_hr_time(int h, ref PCPS_HR_TIME t);
+
+ /// <summary>
+ /// Reads a HR time stamp from the board plus a performance counter value
+ /// associated to that time stamp. The performance counter value can be used
+ /// by the application to compensate the latency mentioned above.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="p">The performance counter to set.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_hr_time_cycles", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_hr_time_cycles(int h, ref PCPS_HR_TIME_CYCLES p);
+
+ /// <summary>
+ /// Reads a HR time stamp from the board and compensates for the specified latency. Return the compensated
+ /// time stamp, and optionally also return the latency value in 100 nanosecond units.
+ /// If the application does not need the latency value then a null pointer may be passed
+ /// for parameter l.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="t">The compensated timestamp to set.</param>
+ /// <param name="l">The latency. Can be nulled if not required.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_hr_time_comp", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_hr_time_comp(int h, ref PCPS_HR_TIME t, ref int l);
+
+ #endregion
+
+ /// <summary>
+ /// The functions below can be used with the capture buffer available on some cards.
+ /// These functions are NOT supported by all Meinberg plug-in boards, and the
+ /// effective accuracy of the time capture events depends on the characteristics
+ /// of the specific device.
+ /// </summary>
+ #region Functions for the event buffer
+
+ /// <summary>
+ /// Check whether the device referenced by handle h provides support for
+ /// user capture events.
+ /// If it does then the value returned for f is not 0.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="f">0 if not supported. If any other value, then supported.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_dev_has_ucap", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_dev_has_ucap(int h, ref int f);
+
+ /// <summary>
+ /// Clear the on-board user capture FIFO buffer
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_clr_ucap_buff", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_clr_ucap_buff(int h);
+
+ /// <summary>
+ /// Retrieve the maximum number of events that can be stored in the on-board
+ /// FIFO buffer, and the number of events currently saved in the buffer.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="p">The maximum number of entries.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_ucap_entries", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_ucap_entries(int h, ref PCPS_UCAP_ENTRIES p);
+
+ /// <summary>
+ /// Retrieve an entry from the on-board user capture FIFO buffer. The returned entry
+ /// is removed from the buffer. If no event is available in the buffer, i.e. the buffer
+ /// is empty, then both the seconds and fractions of the returned time stamp are 0.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="t">The returned entry.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_ucap_event", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_ucap_event(int h, ref PCPS_HR_TIME t);
+
+ #endregion
+
+ /// <summary>
+ /// The functions below can be used to read the receiver position from GPS add-in
+ /// cards. This is NOT supported by non-GPS add-in cards, so there's another
+ /// function which checks whether a specific device is a GPS receiver.
+ /// </summary>
+ #region Functions for position
+ /// <summary>
+ /// Check whether the device referenced by handle h is a GPS receiver.
+ /// If it is then the value returned for f is not 0.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="f">0 if not supported. If any other value, then supported.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_dev_is_gps", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_dev_is_gps(int h, ref int f);
+
+ /// <summary>
+ /// Read the current receiver position.
+ /// </summary>
+ /// <param name="h">The device handle as returned by <see cref="mbg_find_devices"/>.</param>
+ /// <param name="p">The receiver's current position.</param>
+ /// <returns></returns>
+ [DllImport("mbgdevio.dll", EntryPoint = "mbg_get_gps_pos", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_gps_pos(int h, ref MBG_RCVR_POS p);
+ #endregion
+
+ #region Service Functions
+
+ /// <summary>
+ /// Returns the version number of the DLL
+ /// <returns>The version number.</returns>
+ /// </summary>
+ [DllImport("mbgsvcio.dll", EntryPoint = "mbg_get_gps_pos", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbgsvcio_get_version();
+
+ /// <summary>
+ /// Checks that the DLL interface specification version is compatible with the
+ /// DLL version. Pass the MBGSVCIO_VERSION code from <see cref="mbgsvcio_get_version"/> as parameter.
+ /// <returns>PCPS_SUCCESS on success.</returns>
+ /// </summary>
+ [DllImport("mbgsvcio.dll", EntryPoint = "mbgsvcio_check_version", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbgsvcio_check_version();
+
+ /// <summary>
+ /// Checks if the Meinberg time adjustment service is active.
+ /// <returns>a positive value if the service is active
+ /// 0 if the service is not active</returns>
+ [DllImport("mbgsvcio.dll", EntryPoint = "mbg_time_adjustment_active", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_time_adjustment_active();
+
+ /// <summary>
+ /// Checks if the ref time source (e.g. radio clock) used by the Meinberg
+ /// time adjustment service is accessible. This should be always the case
+ /// with PCI plug-in boards, but this can also fail with an external clock
+ /// if for example the serial connection is broken or the device is powered
+ /// off.
+ /// <returns>a positive value if the ref time source is accessible
+ /// 0 if the ref time source is not accessible
+ /// a negative number if the status could not be determined.</returns>
+ /// </summary>
+ [DllImport("mbgsvcio.dll", EntryPoint = "mbg_ref_time_accessible", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_ref_time_accessible();
+
+ /// <summary>
+ /// Queries the status of the ref time source (e.g. radio clock) used by the
+ /// Meinberg time adjustment service.
+ /// <returns>a positive value if the ref time source is accessible
+ /// 0 if the ref time source is not accessible
+ /// a negative number if the status could not be determined.</returns>
+ /// </summary>
+ [DllImport("mbgsvcio.dll", EntryPoint = "mbg_get_ref_time_status", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
+ internal static extern int mbg_get_ref_time_status();
+
+ #endregion
+ }
+}
diff --git a/c#/demo/mbgdevio/MeinbergAPI.csproj b/c#/demo/mbgdevio/MeinbergAPI.csproj
new file mode 100644
index 0000000..bd7a2b4
--- /dev/null
+++ b/c#/demo/mbgdevio/MeinbergAPI.csproj
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{86FE288D-4091-4CB7-8431-DF82B78BD79B}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MeinbergAPI</RootNamespace>
+ <AssemblyName>MeinbergAPI</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Constants.cs" />
+ <Compile Include="MeinbergDevice.cs" />
+ <Compile Include="Interop.cs" />
+ <Compile Include="MeinbergDeviceManager.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Structures.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="mbgdevio.dll" />
+ <Content Include="mbgsvcio.dll" />
+ <Content Include="mbgsvctl.dll" />
+ <Content Include="mbgutil.dll" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/c#/demo/mbgdevio/MeinbergDevice.cs b/c#/demo/mbgdevio/MeinbergDevice.cs
new file mode 100644
index 0000000..49a03d5
--- /dev/null
+++ b/c#/demo/mbgdevio/MeinbergDevice.cs
@@ -0,0 +1,291 @@
+using System;
+
+namespace MeinbergAPI
+{
+ public class MeinbergDevice
+ {
+ #region Private Properties
+
+ private int _DeviceHandle;
+ private bool _SupportsHRTime;
+ private bool _SupportsUserCaptureEvents;
+ private bool _IsGpsReceiver;
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// The device's handle.
+ /// </summary>
+ public int DeviceHandle
+ {
+ get { return _DeviceHandle; }
+ set { _DeviceHandle = value; }
+ }
+
+ /// <summary>
+ /// Specifies whether the device supports HR time.
+ /// </summary>
+ public bool SupportsHRTime
+ {
+ get { return _SupportsHRTime; }
+ set { _SupportsHRTime = value; }
+ }
+
+ /// <summary>
+ /// Specified whether the device supports User Capture Events.
+ /// </summary>
+ public bool SupportsUserCaptureEvents
+ {
+ get { return _SupportsUserCaptureEvents; }
+ set
+ {
+ _SupportsUserCaptureEvents = value;
+ }
+ }
+
+ /// <summary>
+ /// Specifies whether the device is a GPS receiver.
+ /// </summary>
+ public bool IsGpsReceiver
+ {
+ get { return _IsGpsReceiver; }
+ set
+ {
+ _IsGpsReceiver = value;
+ }
+ }
+
+ public bool CapabilitiesChecked = false;
+
+ #endregion
+
+ #region Constructors & Destructors
+
+ /// <summary>
+ /// Initializes an instance of the MeinbergDevice class.
+ /// </summary>
+ /// <param name="deviceHandle">The device's handle.</param>
+ public MeinbergDevice(int deviceHandle)
+ {
+ _DeviceHandle = deviceHandle;
+ }
+
+ /// <summary>
+ /// Initializes an instance of the MeinbergDevice class.
+ /// </summary>
+ /// <param name="deviceHandle">The device's handle.</param>
+ /// <param name="initializeCapabilities">Specify whether to initialize the class with the device's capabilities.</param>
+ public MeinbergDevice(int deviceHandle, bool initializeCapabilities)
+ {
+ _DeviceHandle = deviceHandle;
+ if (initializeCapabilities) CheckCapabilities();
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public void CheckCapabilities()
+ {
+ int supportsHRTime = -1;
+ Interop.mbg_dev_has_hr_time(DeviceHandle, ref supportsHRTime);
+ SupportsHRTime = supportsHRTime != 0;
+
+ int supportsUCETime = -1;
+ Interop.mbg_dev_has_ucap(DeviceHandle, ref supportsUCETime);
+ SupportsUserCaptureEvents = supportsUCETime != 0;
+
+ int supportsGps = -1;
+ Interop.mbg_dev_is_gps(DeviceHandle, ref supportsGps);
+ IsGpsReceiver = supportsGps != 0;
+
+ CapabilitiesChecked = true;
+
+ }
+
+ public bool Open()
+ {
+ return Interop.mbg_open_device(this._DeviceHandle) == this._DeviceHandle;
+ }
+
+ public bool Close()
+ {
+ return Interop.mbg_close_device(ref this._DeviceHandle) == 0;
+ }
+
+ /// <summary>
+ /// Gets the time from the device.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns></returns>
+ public Interop.PCPS_TIME GetTime(out bool successful)
+ {
+ var time = new Interop.PCPS_TIME();
+ successful = Interop.mbg_get_time(this._DeviceHandle, ref time) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return time;
+ else
+ return new Interop.PCPS_TIME();
+ }
+
+ /// <summary>
+ /// Gets high-resolution time from the device.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns>Returns the time.</returns>
+ public Interop.PCPS_HR_TIME GetHRTime(out bool successful)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support high-resolution time.");
+
+ var time = new Interop.PCPS_HR_TIME();
+ successful = Interop.mbg_get_hr_time(this._DeviceHandle, ref time) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return time;
+ else
+ return new Interop.PCPS_HR_TIME();
+ }
+
+ /// <summary>
+ /// Reads a HR time stamp from the board plus a performance counter value
+ /// associated to that time stamp.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns>Returns the high-resolution time.</returns>
+ public Interop.PCPS_HR_TIME_CYCLES GetHRTimeCycles(out bool successful)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support high-resolution time.");
+
+ var time = new Interop.PCPS_HR_TIME_CYCLES();
+ successful = Interop.mbg_get_hr_time_cycles(this._DeviceHandle, ref time) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return time;
+ else
+ return new Interop.PCPS_HR_TIME_CYCLES();
+ }
+
+ /// <summary>
+ /// Reads a HR time stamp from the board and compensates for the specified latency.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <param name="latency">The latency to compensate for (Nullable)</param>
+ /// <returns>Returns the compensated time stamp, and optionally also return the latency
+ /// value in 100 nanosecond units.</returns>
+ public Interop.PCPS_HR_TIME GetHRTimeCycles(out bool successful, out int latency)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support high-resolution time.");
+
+ var time = new Interop.PCPS_HR_TIME();
+ int l = -1;
+
+ successful = Interop.mbg_get_hr_time_comp(this._DeviceHandle, ref time, ref l) == Interop.PCPS_SUCCESS;
+ if (successful)
+ {
+ latency = l;
+ return time;
+ }
+ else
+ {
+ latency = -1;
+ return new Interop.PCPS_HR_TIME();
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns>Returns whether the operation was successful.</returns>
+ public bool ClearOnboardBuffers()
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support user events.");
+
+ return Interop.mbg_clr_ucap_buff(this._DeviceHandle) == Interop.PCPS_SUCCESS;
+ }
+
+ /// <summary>
+ /// Retrieve the maximum number of events that can be stored in the on-board FIFO buffer,
+ /// and the number of events currently saved in the buffer.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns>Returns the entries in the buffer. </returns>
+ public Interop.PCPS_UCAP_ENTRIES GetEvents(out bool successful)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support user events.");
+
+ var allEvents = new Interop.PCPS_UCAP_ENTRIES();
+ successful = Interop.mbg_get_ucap_entries(this._DeviceHandle, ref allEvents) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return allEvents;
+ else
+ return new Interop.PCPS_UCAP_ENTRIES();
+ }
+
+ /// <summary>
+ /// Retrieve an entry from the on-board user capture FIFO buffer. The returned entry
+ /// is removed from the buffer.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns>Returns the entry requested. If no event is available in the buffer, i.e. the buffer
+ /// is empty, then both the seconds and fractions of the returned time stamp are 0.</returns>
+ public Interop.PCPS_HR_TIME GetEvent(out bool successful)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support user events.");
+
+ var singleEvent = new Interop.PCPS_HR_TIME();
+ successful = Interop.mbg_get_ucap_event(this._DeviceHandle, ref singleEvent) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return singleEvent;
+ else
+ return new Interop.PCPS_HR_TIME();
+ }
+
+ /// <summary>
+ /// Gets the device's current GPS position.
+ /// </summary>
+ /// <param name="successful">Specifies whether the operation was successful.</param>
+ /// <returns>Returns the GPS position.</returns>
+ public Interop.MBG_RCVR_POS GetDeviceGPSPosition(out bool successful)
+ {
+ if (CapabilitiesChecked)
+ throw new Exception("Before accessing extended functions, you first have to check the device's capabilities by calling CheckCapabilities.");
+
+ if (!SupportsHRTime)
+ throw new NotSupportedException("This device does not support GPS functionality.");
+
+ var gpsPosition = new Interop.MBG_RCVR_POS();
+ successful = Interop.mbg_get_gps_pos(this._DeviceHandle, ref gpsPosition) == Interop.PCPS_SUCCESS;
+ if (successful)
+ return gpsPosition;
+ else
+ return new Interop.MBG_RCVR_POS();
+ }
+
+ #endregion
+
+ }
+}
diff --git a/c#/demo/mbgdevio/MeinbergDeviceManager.cs b/c#/demo/mbgdevio/MeinbergDeviceManager.cs
new file mode 100644
index 0000000..da1e570
--- /dev/null
+++ b/c#/demo/mbgdevio/MeinbergDeviceManager.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace MeinbergAPI
+{
+ public class MeinbergDeviceManager
+ {
+ #region Private Properties
+
+ private List<MeinbergDevice> _Devices;
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// The devices currently attached to the system.
+ /// </summary>
+ public List<MeinbergDevice> Devices
+ {
+ get { return _Devices; }
+ }
+
+ #endregion
+
+ #region Constructors & Destructors
+
+ /// <summary>
+ /// Initializes an instance of the MeinbergDeviceManager.
+ /// Devices are loaded and capabilities for each device is checked during
+ /// instantiation.
+ /// </summary>
+ public MeinbergDeviceManager()
+ {
+ //TODO: check dll version
+ LoadDevices();
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void LoadDevices()
+ {
+ _Devices = new List<MeinbergDevice>();
+
+ int noOfDevices = Interop.mbg_find_devices();
+
+ for (int i = 0; i < noOfDevices - 1; i++)
+ {
+ Devices.Add(new MeinbergDevice(Interop.mbg_open_device(i), true));
+ Devices[i].Close();
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Gets all the Meinberg devices supporting GPS functionality.
+ /// </summary>
+ /// <returns>A list of Meinberg devices supporting GPS functionality.</returns>
+ public List<MeinbergDevice> GetDevicesSupportingGPS()
+ {
+ return (from device in _Devices where device.IsGpsReceiver select device).ToList();
+ }
+
+ /// <summary>
+ /// Gets all the Meinberg devices supporting high-resolution time.
+ /// </summary>
+ /// <returns>A list of Meinberg devices supporting high-resolution time.</returns>
+ public List<MeinbergDevice> GetDevicesSupportingHRTime()
+ {
+ return (from device in _Devices where device.SupportsHRTime select device).ToList();
+ }
+
+ /// <summary>
+ /// Gets all the Meinberg devices supporting user events.
+ /// </summary>
+ /// <returns>A list of Meinberg devices supporting user events.</returns>
+ public List<MeinbergDevice> GetDevicesSupportingUserEvents()
+ {
+ return (from device in _Devices where device.SupportsUserCaptureEvents select device).ToList();
+ }
+
+ #endregion
+ }
+}
diff --git a/c#/demo/mbgdevio/Properties/AssemblyInfo.cs b/c#/demo/mbgdevio/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ce048c9
--- /dev/null
+++ b/c#/demo/mbgdevio/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MeinbergAPI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Inivit Systems Pty. Ltd.")]
+[assembly: AssemblyProduct("MeinbergAPI")]
+[assembly: AssemblyCopyright("Copyright © Inivit Systems Pty. Ltd. 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1c4cfb7c-0ae6-4033-b512-1bbde7522833")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/c#/demo/mbgdevio/Structures.cs b/c#/demo/mbgdevio/Structures.cs
new file mode 100644
index 0000000..a8afb21
--- /dev/null
+++ b/c#/demo/mbgdevio/Structures.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace MeinbergAPI
+{
+ public partial class Interop
+ {
+ #region Time Structures
+
+ /// <summary>
+ /// The DLL version required by this interface specification
+ /// </summary>
+ public const short MBGDEVIO_VERSION = 0x212;
+
+ /// <summary>
+ /// This structure is passed to the function mbg_get_time to read date, time, and status
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PCPS_TIME
+ {
+ // 0..99
+ public byte sec100;
+ // 0..59, 60 if leap second
+ public byte sec;
+ // 0..59
+ public byte min;
+ // 0..23
+ public byte hour;
+ // 1..31
+ public byte mday;
+ // 1..7, 1 = Monday
+ public byte wday;
+ // 1..12
+ public byte month;
+ // 0..99 (year modulo 100)
+ public byte year;
+ // flag bits, see below
+ public byte status;
+ // 0..255
+ public byte signal;
+ // [h] signed!! (UTC = t - offs_utc)
+ public byte offs_utc;
+ }
+
+ /// <summary>
+ /// This structure has been introduced to be able to handle high resolution time stamps.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PCPS_TIME_STAMP
+ {
+ // UInt32, seconds since 1970 (UTC)
+ public int sec;
+ // UInt32, fractions of second ( &HFFFFFFFF == 0.9999.. sec)
+ public int frac;
+ }
+
+ /// <summary>
+ /// This structure holds a HR time stamp, plus UTC offset and status info
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PCPS_HR_TIME
+ {
+ public PCPS_TIME_STAMP tstamp;
+ // [sec] signed!! (local time = tstamp + offs_utc)
+ public int utc_offs;
+ // flag bits, see below
+ public short status;
+ // 0..255
+ public byte signal;
+ }
+
+ /// <summary>
+ /// This structure holds a HR time plus an associated Windows
+ /// performance counter value which can be used to relate performance
+ /// counter values to the current time. Please note that an application
+ /// must also determine the Windows performance counter frequency in order
+ /// to convert differences of performance counter values to time intervals.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PCPS_HR_TIME_CYCLES
+ {
+ // UInt64, performance counter value
+ public long cycles;
+ // associated HR time
+ public PCPS_HR_TIME t;
+ }
+
+ /// <summary>
+ /// This structure contains the maximum number of entries of an on-board
+ /// user capture FIFO buffer plus the number of currently used entries.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PCPS_UCAP_ENTRIES
+ {
+ // the number of saved capture events
+ public int used;
+ // capture buffer size
+ public int max;
+ }
+
+ #endregion
+
+ #region Structures for Geographic Position
+
+ /// <summary>
+ /// This type is used to hold a geographic position in cartesian coordinates.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct MBG_POS_XYZ
+ {
+ // x coordinate, in meters
+ public double x;
+ // y coordinate, in meters
+ public double y;
+ // z coordinate, in maters
+ public double z;
+ }
+
+ /// <summary>
+ /// This type is used to pass a geographic position in raw geographic coordinates.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct MBG_POS_LLA
+ {
+ // latitude, in radians
+ public double lat;
+ // longitude, in radians
+ public double lon;
+ // altitude (height above ellipsoid), in meters
+ public double alt;
+ }
+
+ /// <summary>
+ /// This type is used in conjuction with <see cref="MBG_RCVR_POS" /> to aid in
+ /// storing the receiver position in a human readable format
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct MBG_DMS
+ {
+ // ASCII code of 'N', 'E', 'S' or 'W'
+ public short prefix;
+ // [0...90 (lat) or 0...180 (lon)]
+ public short deg;
+ // [0...59]
+ public short min;
+ // [0...59.999]
+ public double sec;
+ }
+
+ /// <summary>
+ /// This type is used to store a geographic coordinate in broken-down (human readable) format.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct MBG_RCVR_POS
+ {
+ // always WGS84 ECEF coordinates
+ public MBG_POS_XYZ xyz;
+ // depending on the ellipsoid used for reference
+ public MBG_POS_LLA lla;
+ // longitude in degrees, minutes, seconds
+ public MBG_DMS longitude;
+ // latitude in degrees, minutes, seconds
+ public MBG_DMS latitude;
+ // ellipsoid used for reference
+ public short ellipsoid;
+ }
+
+ #endregion
+ }
+}