/* This software is subject to the license described in the License.txt file included with this software distribution. You may not use this file except in compliance with this license. Copyright (c) Dynastream Innovations Inc. 2013 All rights reserved. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace ANT_Managed_Library { /// /// Control class for an individual ANT channel. Created and accessed through the ANTDevice class. /// public class ANT_Channel : IANT_Channel { #region variables readonly ANT_Device creatingDevice = null; IntPtr unmanagedANTFramerPointer = IntPtr.Zero; private byte channelNumber; private bool disposed = false; #endregion #region ChannelEventCallback Variables /// /// The channel callback event for forwarding the raw msg struct. Triggered every time a message is received from the ANT device. /// Examples include transmit and receive messages. If you are coding in C# use the other response event version. /// public event dRawChannelResponseHandler rawChannelResponse; /// /// This event is fired whenever there are events on the device level that may impact the channel. /// Events that currently occur (Event, value of notification info Object): /// Reset, null /// Shutdown, null /// public event dDeviceNotificationHandler DeviceNotification; /// /// The channel callback event. Triggered every time a message is received from the ANT device. /// Examples include transmit and receive messages. /// public event dChannelResponseHandler channelResponse; //The event to assign callback functions to in a managed application #endregion #region ANT_DLL Imports [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_GetChannelID(IntPtr FramerPtr, byte ucANTChannel_, ref UInt16 pusDeviceNumber_, ref byte pucDeviceType_, ref byte pucTransmitType_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_GetChannelStatus(IntPtr FramerPtr, byte ucANTChannel_, ref byte pucStatus_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_AssignChannel_RTO", CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_AssignChannel(IntPtr FramerPtr, byte ucANTChannel, byte ucChanType, byte ucNetNumber, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_AssignChannelExt_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_AssignChannelExt(IntPtr FramerPtr, byte ucANTChannel, byte ucChanType, byte ucNetNumber, byte ucExtFlags, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_UnAssignChannel_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_UnAssignChannel(IntPtr FramerPtr, byte ucANTChannel, UInt32 ulResponseTime); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetChannelId_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetChannelId(IntPtr FramerPtr, byte ucANTChannel, UInt16 usDeviceNumber, byte ucDeviceType, byte ucTransmissionType_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetSerialNumChannelId_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetSerialNumChannelId_RTO(IntPtr FramerPtr, byte ucANTChannel_, byte ucDeviceType_, byte ucTransmissionType_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetChannelPeriod_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetChannelPeriod(IntPtr FramerPtr, byte ucANTChannel_, UInt16 usMesgPeriod_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_RSSI_SetSearchThreshold_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_RSSI_SetSearchThreshold(IntPtr FramerPtr, byte ucANTChannel_, byte ucThreshold_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetChannelRFFreq_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetChannelRFFreq(IntPtr FramerPtr, byte ucANTChannel_, byte ucRFFreq_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetChannelTxPower_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetChannelTxPower(IntPtr FramerPtr, byte ucANTChannel_, byte ucTransmitPower_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetChannelSearchTimeout_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetChannelSearchTimeout(IntPtr FramerPtr, byte ucANTChannel_, byte ucSearchTimeout_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_OpenChannel_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_OpenChannel(IntPtr FramerPtr, byte ucANTChannel, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_CloseChannel_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_CloseChannel(IntPtr FramerPtr, byte ucANTChannel, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SendBroadcastData(IntPtr FramerPtr, byte ucANTChannel, byte[] pucData); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SendAcknowledgedData_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern byte ANT_SendAcknowledgedData(IntPtr FramerPtr, byte ucANTChannel, byte[] pucData, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SendBurstTransfer_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern byte ANT_SendBurstTransfer(IntPtr FramerPtr, byte ucANTChannel_, byte[] pucData_, UInt32 usNumBytes, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SendAdvancedBurstTransfer_RTO", CallingConvention = CallingConvention.Cdecl)] private static extern byte ANT_SendAdvancedBurstTransfer(IntPtr FramerPtr, byte ucANTChannel_, byte[] pucData_, UInt32 usNumBytes, byte numStdPcktsPerSerialMsg_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SendExtBroadcastData(IntPtr FramerPtr, byte ucANTChannel, UInt16 usDeviceNumber, byte ucDeviceType, byte ucTransmissionType_, byte[] pucData); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SendExtAcknowledgedData_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern byte ANT_SendExtAcknowledgedData(IntPtr FramerPtr, byte ucANTChannel, UInt16 usDeviceNumber, byte ucDeviceType, byte ucTransmissionType_, byte[] pucData, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SendExtBurstTransfer_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern byte ANT_SendExtBurstTransfer(IntPtr FramerPtr, byte ucANTChannel_, UInt16 usDeviceNumber, byte ucDeviceType, byte ucTransmissionType_, byte[] pucData_, UInt32 usNumBytes, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetLowPriorityChannelSearchTimeout_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetLowPriorityChannelSearchTimeout(IntPtr FramerPtr, byte ucANTChannel_, byte ucSearchTimeout_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_AddChannelID_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_AddChannelID(IntPtr FramerPtr, byte ucANTChannel_, UInt16 usDeviceNumber_, byte ucDeviceType_, byte ucTransmissionType_, byte ucListIndex_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_ConfigList_RTO", CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_ConfigList(IntPtr FramerPtr, byte ucANTChannel_, byte ucListSize_, byte ucExclude_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_EncryptedChannelEnable_RTO", CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_EncryptedChannelEnable(IntPtr FramerPtr, byte ucANTChannel, byte ucMode, byte ucVolatileKeyIndex, byte ucDecimationRate, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_AddCryptoID_RTO", CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_AddCryptoID(IntPtr FramerPtr, byte ucANTChannel, byte[] pucData, byte ucListIndex, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_ConfigCryptoList_RTO", CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_ConfigCryptoList(IntPtr FramerPtr, byte ucANTChannel, byte ucListSize, byte ucBlacklist, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_SetProximitySearch(IntPtr FramerPtr, byte ucANTChannel_, byte ucSearchThreshold_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)] private static extern int ANT_ConfigFrequencyAgility(IntPtr FramerPtr, byte ucANTChannel_, byte ucFreq1_, byte ucFreq2_, byte ucFreq3_, UInt32 ulResponseTime_); [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)] private static extern int ANT_ConfigSelectiveDataUpdate(IntPtr FramerPtr, byte ucANTChannel_, byte ucSduConfig_, UInt32 ulResponseTime_); #endregion #region Constructor //Internal, because a channel can not be created without a device instance. Channels must be created by the device class which assigns the appropriate channel number internal ANT_Channel(ANT_Device creatingDevice, byte ucChannelNumber) { this.creatingDevice = creatingDevice; this.unmanagedANTFramerPointer = creatingDevice.getFramerPtr(); channelNumber = ucChannelNumber; } #endregion #region non-ANTdll Functions /// /// Returns the ANTDevice that this channel belongs to /// public ANT_Device getParentDevice() { return creatingDevice; } /// /// Returns the underlying C++ ANT framer reference that this channel uses for messaging. Useful to pass to unmanaged C++ implementations. /// /// Pointer to the C++ ANT framer for messaging public IntPtr getUnmgdFramer() { return creatingDevice.getFramerPtr(); } /// /// Returns the channel number of this instance /// public byte getChannelNum() { return channelNumber; } internal void NotifyDeviceEvent(ANT_Device.DeviceNotificationCode notification, object notificationInfo) { if (DeviceNotification != null) DeviceNotification(notification, notificationInfo); } internal void MessageReceived(ANT_Device.ANTMessage newMessage, ushort messageSize) { if (channelResponse != null) channelResponse(new ANT_Response(this, channelNumber, DateTime.Now, newMessage.msgID, newMessage.ucharBuf.Take(messageSize).ToArray())); if (rawChannelResponse != null) rawChannelResponse(newMessage, messageSize); } /// /// Dispose this channel. /// public void Dispose() { //There are no unmanaged resources to clean up in this channel implementation //It would be nice to close the channel if it is open, but it is really hard to tell if the channel //is open or not without requesting channelStatus, and we don't want to issue extraneous commands and clutter the logs //We can however nullify our reference in the device list, so that if someone calls getChannel again they get a new non-disposed channel creatingDevice.channelDisposed(channelNumber); disposed = true; GC.SuppressFinalize(this); } /// /// Returns current channel status. /// Throws exception on timeout. /// /// Time to wait for device success response public ANT_ChannelStatus requestStatus(UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); byte statusByte = 0; if (ANT_GetChannelStatus(unmanagedANTFramerPointer, channelNumber, ref statusByte, responseWaitTime) == 1) { return new ANT_ChannelStatus((ANT_ReferenceLibrary.BasicChannelStatusCode)(statusByte & 0x03), (byte)((statusByte & 0x0C) >> 2), (ANT_ReferenceLibrary.ChannelType)(statusByte & 0xF0)); } else { throw new ANT_Exception("Timed out waiting for requested message"); } } /// /// Returns the channel ID /// Throws exception on timeout /// /// Time to wait for device success response /// public ANT_ChannelID requestID(UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); ushort deviceNumber = 0; byte deviceType = 0; byte transmitType = 0; if (ANT_GetChannelID(unmanagedANTFramerPointer, channelNumber, ref deviceNumber, ref deviceType, ref transmitType, responseWaitTime) == 1) { return new ANT_ChannelID(deviceNumber, deviceType, transmitType); } else { throw new ANT_Exception("Timed out waiting for requested message"); } } #endregion #region ANT Channel Functions /// Assign channel /// /// Assign an ANT channel along with its main parameters. /// Throws exception if the network number is invalid. /// /// Channel Type byte /// Network to assign to channel, must be less than device's max networks-1 /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool assignChannel(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (networkNumber > creatingDevice.getDeviceCapabilities().maxNetworks - 1) throw new ANT_Exception("Network number must be less than device's max networks - 1"); return (ANT_AssignChannel(unmanagedANTFramerPointer, channelNumber, (byte)channelTypeByte, networkNumber, responseWaitTime) == 1); } /// /// Assign an ANT channel. /// /// Channel Type byte /// Network to assign to channel public void assignChannel(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber) { assignChannel(channelTypeByte, networkNumber, 0); } /// Assign channel (extended) /// /// Assign an ANT channel, using extended channel assignment /// Throws exception if the network number is invalid. /// /// Channel Type byte /// Network to assign to channel, must be less than device's max netwoks - 1 /// Extended assignment byte /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool assignChannelExt(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, ANT_ReferenceLibrary.ChannelTypeExtended extAssignByte, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (networkNumber > creatingDevice.getDeviceCapabilities().maxNetworks - 1) throw new ANT_Exception("Network number must be less than device's max networks - 1"); return (ANT_AssignChannelExt(unmanagedANTFramerPointer, channelNumber, (byte)channelTypeByte, networkNumber, (byte)extAssignByte, responseWaitTime) == 1); } /// /// Assign an ANT channel, using extended channel assignment /// Throws exception if the network number is invalid. /// /// Channel Type byte /// Network to assign to channel, must be less than device's max netwoks - 1 /// Extended assignment byte public void assignChannelExt(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, ANT_ReferenceLibrary.ChannelTypeExtended extAssignByte) { assignChannelExt(channelTypeByte, networkNumber, extAssignByte, 0); } /// Unassign channel /// /// Unassign this channel. /// /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool unassignChannel(UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_UnAssignChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1); } /// /// Unassigns this channel. /// public void unassignChannel() { unassignChannel(0); } /// Set the Channel ID /// /// Set the Channel ID of this channel. /// Throws exception if device type is > 127. /// /// Device number to assign to channel. Set to 0 for receiver wild card matching /// Device pairing bit. /// Device type to assign to channel. Must be less than 128. Set to 0 for receiver wild card matching /// Transmission type to assign to channel. Set to 0 for receiver wild card matching /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setChannelID(UInt16 deviceNumber, bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (deviceTypeID > 127) throw new ANT_Exception("Device Type ID is larger than 127"); if (pairingEnabled) //Set the pairing flag deviceTypeID |= 0x80; return (ANT_SetChannelId(unmanagedANTFramerPointer, channelNumber, deviceNumber, deviceTypeID, transmissionTypeID, responseWaitTime) == 1); } /// /// Set the Channel ID of this channel. /// Throws exception if device type is > 127. /// /// Device number to assign to channel. Set to 0 for receiver wild card matching /// Device pairing bit /// Device type to assign to channel. Set to 0 for receiver wild card matching /// Transmission type to assign to channel. Set to 0 for receiver wild card matching public void setChannelID(UInt16 deviceNumber, bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID) { setChannelID(deviceNumber, pairingEnabled, deviceTypeID, transmissionTypeID, 0); } /// Sets the Channel ID, using serial number as device number /// /// Identical to setChannelID, except last two bytes of serial number are used for device number. /// Not available on all ANT devices. /// Throws exception if device type is > 127. /// /// True on success. Note: Always returns true with a response time of 0 public bool setChannelID_UsingSerial(bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID, UInt32 waitResponseTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (deviceTypeID > 127) throw new ANT_Exception("Device Type ID is larger than 127"); if (pairingEnabled) //Set the pairing flag deviceTypeID |= 0x80; return (ANT_SetSerialNumChannelId_RTO(unmanagedANTFramerPointer, channelNumber, deviceTypeID, transmissionTypeID, waitResponseTime) == 1); } /// /// Identical to setChannelID, except last two bytes of serial number are used for device number. /// public void setChannelID_UsingSerial(bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID) { setChannelID_UsingSerial(pairingEnabled, deviceTypeID, transmissionTypeID, 0); } /// Sets channel message period /// /// Set this channel's messaging period /// /// Desired period in seconds * 32768 /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setChannelPeriod(UInt16 messagePeriod_32768unitspersecond, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_SetChannelPeriod(unmanagedANTFramerPointer, channelNumber, messagePeriod_32768unitspersecond, responseWaitTime) == 1); } /// /// Set this channel's messaging period /// /// Desired period in seconds * 32768 public void setChannelPeriod(UInt16 messagePeriod_32768unitspersecond) { setChannelPeriod(messagePeriod_32768unitspersecond, 0); } /// Sets the RSSI threshold (ARCT) /// /// Set this channel's RSSI threshold (ARCT) /// /// Desired RSSI threshold value /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setSearchThresholdRSSI(byte thresholdRSSI, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_RSSI_SetSearchThreshold(unmanagedANTFramerPointer, channelNumber, thresholdRSSI, responseWaitTime) == 1); } /// /// Set this channel's RSSI threshold (ARCT) /// /// Desired RSSI threshold value public void setSearchThresholdRSSI(byte thresholdRSSI) { setSearchThresholdRSSI(thresholdRSSI, 0); } /// Sets channel RF Frequency /// /// Set this channel's RF frequency, with the given offset from 2400Mhz. /// Note: Changing this frequency may affect the ability to certify the product in certain areas of the world. /// /// Offset to add to 2400Mhz /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setChannelFreq(byte RFFreqOffset, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_SetChannelRFFreq(unmanagedANTFramerPointer, channelNumber, RFFreqOffset, responseWaitTime) == 1); } /// /// Set this channel's RF frequency, with the given offset from 2400Mhz. /// Note: Changing this frequency may affect the ability to certify the product in certain areas of the world. /// /// Offset to add to 2400Mhz public void setChannelFreq(byte RFFreqOffset) { setChannelFreq(RFFreqOffset, 0); } /// Sets the channel transmission power /// /// Set the transmission power of this channel /// Throws exception if device is not capable of per-channel transmit power. /// /// Transmission power to set to /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setChannelTransmitPower(ANT_ReferenceLibrary.TransmitPower transmitPower, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (!creatingDevice.getDeviceCapabilities().perChannelTransmitPower) throw new ANT_Exception("Device not capable of per-channel transmit power"); return (ANT_SetChannelTxPower(unmanagedANTFramerPointer, channelNumber, (byte)transmitPower, responseWaitTime) == 1); } /// /// Set the transmission power of this channel /// /// Transmission power to set to public void setChannelTransmitPower(ANT_ReferenceLibrary.TransmitPower transmitPower) { setChannelTransmitPower(transmitPower, 0); } /// Sets the channel search timeout /// /// Set the search timeout /// /// timeout in 2.5 second units (in newer devices 255=infinite) /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setChannelSearchTimeout(byte searchTimeout, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_SetChannelSearchTimeout(unmanagedANTFramerPointer, channelNumber, searchTimeout, responseWaitTime) == 1); } /// /// Set the search timeout /// /// timeout in 2.5 second units (in newer devices 255=infinite) public void setChannelSearchTimeout(byte searchTimeout) { setChannelSearchTimeout(searchTimeout, 0); } /// Opens the channel /// /// Opens this channel /// /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool openChannel(UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_OpenChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1); } /// /// Opens this channel /// public void openChannel() { openChannel(0); } /// Sends broadcast message /// /// Sends the given data on the broadcast transmission. /// Throws exception if data > 8-bytes in length /// /// data to send (length 8 or less) public bool sendBroadcastData(byte[] data) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); int padNum = 8 - data.Length; if (padNum < 0) throw new ANT_Exception("Send data must not be greater than 8 bytes"); data = data.Concat(new byte[padNum]).ToArray(); return ANT_SendBroadcastData(unmanagedANTFramerPointer, channelNumber, data) == 1; } /// Sends acknowledged message /// /// Sends the given data as an acknowledged transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled /// Throws exception if data > 8-bytes in length /// /// data to send (length 8 or less) /// Time in ms to wait for acknowledgement /// 0=fail, 1=pass, 2=timeout, 3=cancelled public ANT_ReferenceLibrary.MessagingReturnCode sendAcknowledgedData(byte[] data, UInt32 ackWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); int padNum = 8 - data.Length; if (padNum < 0) throw new ANT_Exception("Send data must not be greater than 8 bytes"); data = data.Concat(new byte[padNum]).ToArray(); return (ANT_ReferenceLibrary.MessagingReturnCode)ANT_SendAcknowledgedData(unmanagedANTFramerPointer, channelNumber, data, ackWaitTime); } /// /// Sends the given data as an acknowledged transmission. /// Throws exception if data > 8-bytes in length /// /// data to send (length 8 or less) public void sendAcknowledgedData(byte[] data) { sendAcknowledgedData(data, 0); } /// Sends burst transfer /// /// Sends the given data as a burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled /// /// data to send, can be any length /// Time in ms to wait for completion of transfer /// 0=fail, 1=pass, 2=timeout, 3=cancelled public ANT_ReferenceLibrary.MessagingReturnCode sendBurstTransfer(byte[] data, UInt32 completeWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); int padNum = 8 - (data.Length % 8); if(padNum != 8) data = data.Concat(new byte[padNum]).ToArray(); return (ANT_ReferenceLibrary.MessagingReturnCode)ANT_SendBurstTransfer(unmanagedANTFramerPointer, channelNumber, data, (uint)data.Length, completeWaitTime); } /// /// Sends the given data as a burst transmission. /// /// data to send, can be any length public void sendBurstTransfer(byte[] data) { sendBurstTransfer(data, 0); } /// Sends extended broadcast message /// /// Sends the given data as an extended broadcast transmission. /// Throws exception if data > 8-bytes in length /// /// Device number of channel ID to send to /// Device type of channel ID to send to /// Transmission type of channel ID to send to /// data to send (length 8 or less) public bool sendExtBroadcastData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); int padNum = 8 - data.Length; if (padNum < 0) throw new ANT_Exception("Send data must not be greater than 8 bytes"); data = data.Concat(new byte[padNum]).ToArray(); return ANT_SendExtBroadcastData(unmanagedANTFramerPointer, channelNumber, deviceNumber, deviceTypeID, transmissionTypeID, data) == 1; } /// Sends extended acknowledged message /// /// Sends the given data as an extended acknowledged transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled /// Throws exception if data > 8-bytes in length /// /// Device number of channel ID to send to /// Device type of channel ID to send to /// Transmission type of channel ID to send to /// data to send (length 8 or less) /// Time in ms to wait for acknowledgement /// 0=fail, 1=pass, 2=timeout, 3=cancelled public ANT_ReferenceLibrary.MessagingReturnCode sendExtAcknowledgedData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data, UInt32 ackWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); int padNum = 8 - data.Length; if (padNum < 0) throw new ANT_Exception("Send data must not be greater than 8 bytes"); data = data.Concat(new byte[padNum]).ToArray(); return (ANT_ReferenceLibrary.MessagingReturnCode)ANT_SendExtAcknowledgedData(unmanagedANTFramerPointer, channelNumber, deviceNumber, deviceTypeID, transmissionTypeID, data, ackWaitTime); } /// /// Sends the given data as an extended acknowledged transmission. /// Throws exception if data > 8-bytes in length /// /// Device number of channel ID to send to /// Device type of channel ID to send to /// Transmission type of channel ID to send to /// data to send (length 8 or less) public void sendExtAcknowledgedData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data) { sendExtAcknowledgedData(deviceNumber, deviceTypeID, transmissionTypeID, data, 0); } /// Sends extended burst data /// /// Sends the given data as an extended burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled /// /// Device number of channel ID to send to /// Device type of channel ID to send to /// Transmission type of channel ID to send to /// data to send, can be any length /// Time in ms to wait for completion of transfer /// 0=fail, 1=pass, 2=timeout, 3=cancelled public ANT_ReferenceLibrary.MessagingReturnCode sendExtBurstTransfer(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data, UInt32 completeWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); //The new unmanaged wrapper burst function handles the padding, but we just do it here anyway to keep in line with the other send functions int padNum = 8 - (data.Length % 8); if(padNum != 8) data = data.Concat(new byte[padNum]).ToArray(); return (ANT_ReferenceLibrary.MessagingReturnCode)ANT_SendExtBurstTransfer(unmanagedANTFramerPointer, channelNumber, deviceNumber, deviceTypeID, transmissionTypeID, data, (uint)data.Length, completeWaitTime); } /// /// Sends the given data as an extended burst transmission. /// /// Device number of channel ID to send to /// Device type of channel ID to send to /// Transmission type of channel ID to send to /// data to send, can be any length public void sendExtBurstTransfer(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data) { sendExtBurstTransfer(deviceNumber, deviceTypeID, transmissionTypeID, data, 0); } /// Closes the channel /// /// Close this channel /// /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool closeChannel(UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return (ANT_CloseChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1); } /// /// Close this channel /// public void closeChannel() { closeChannel(0); } /// Sets the channel low priority search timeout /// /// Sets the search timeout for the channel's low-priority search, where it will not interrupt other open channels. /// When this period expires the channel will drop to high-priority search. /// This feature is not available in all ANT devices. /// /// Timeout period in 2.5 second units /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setLowPrioritySearchTimeout(byte lowPriorityTimeout, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return ANT_SetLowPriorityChannelSearchTimeout(unmanagedANTFramerPointer, channelNumber, lowPriorityTimeout, responseWaitTime) == 1; } /// /// Sets the timeout period for the channel's low-priority search, where it will not interrupt other open channels. /// When this period expires the channel will drop to high-priority search. /// /// Timeout period in 2.5 second units public void setLowPrioritySearchTimeout(byte lowPriorityTimeout) { setLowPrioritySearchTimeout(lowPriorityTimeout, 0); } /// Adds a channel ID to the device inclusion/exclusion list /// /// Add the given channel ID to the channel's inclusion/exclusion list. /// The channelID is then included or excluded from the wild card search depending on how the list is configured. /// Throws exception if listIndex > 3. /// /// deviceNumber of the channelID to add /// deviceType of the channelID to add /// transmissionType of the channelID to add /// position in inclusion/exclusion list to add channelID at (Max size of list is 4) /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool includeExcludeList_addChannel(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte listIndex, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (listIndex > 3) throw new ANT_Exception("listIndex must be 0..3"); return ANT_AddChannelID(unmanagedANTFramerPointer, channelNumber, deviceNumber, deviceTypeID, transmissionTypeID, listIndex, responseWaitTime) == 1; } /// /// Add the given channel ID to the channel's inclusion/exclusion list. /// The channelID is then included or excluded from the wild card search depending on how the list is configured. /// Throws exception if listIndex > 3. /// /// deviceNumber of the channelID to add /// deviceType of the channelID to add /// transmissionType of the channelID to add /// position in inclusion/exclusion list to add channelID at (0..3) public void includeExcludeList_addChannel(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte listIndex) { includeExcludeList_addChannel(deviceNumber, deviceTypeID, transmissionTypeID, listIndex, 0); } /// Configures the device inclusion/exclusion list /// /// Configures the inclusion/exclusion list. If isExclusionList is true the channel IDs will be /// excluded from any wild card search on this channel. Otherwise the IDs are the only IDs accepted in the search. /// Throws exception if list size is greater than 4. /// /// The desired size of the list, max size is 4, 0=none /// True = exclusion list, False = inclusion list /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool includeExcludeList_Configure(byte listSize, bool isExclusionList, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (listSize > 4) throw new ANT_Exception("Inclusion Exclusion List has a maximum size of 4"); return ANT_ConfigList(unmanagedANTFramerPointer, channelNumber, listSize, Convert.ToByte(isExclusionList), responseWaitTime) == 1; } /// /// Configures the inclusion/exclusion list. If isExclusionList is true the channel IDs will be /// excluded from any wild card search on this channel. Otherwise the IDs are the only IDs accepted in the search. /// Throws exception if list size is greater than 4. /// /// The desired size of the list, max size is 4, 0=none /// True = exclusion list, False = inclusion list public void includeExcludeList_Configure(byte listSize, bool isExclusionList) { includeExcludeList_Configure(listSize, isExclusionList, 0); } public bool encryptedChannelEnable(ANT_ReferenceLibrary.EncryptedChannelMode encryptionMode, byte volatileKeyIndex, byte decimationRate, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return ANT_EncryptedChannelEnable(unmanagedANTFramerPointer, channelNumber, (byte)encryptionMode, volatileKeyIndex, decimationRate, responseWaitTime) == 1; } public void encryptedChannelEnable(ANT_ReferenceLibrary.EncryptedChannelMode encryptionMode, byte volatileKeyIndex, byte decimationRate) { encryptedChannelEnable(encryptionMode, volatileKeyIndex, decimationRate, 0); } public bool encryptionIDList_AddID(byte[] encryptionID, byte listIndex, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (listIndex > 3) throw new ANT_Exception("listIndex must be 0..3"); return ANT_AddCryptoID(unmanagedANTFramerPointer, channelNumber, encryptionID, listIndex, responseWaitTime) == 1; } public void encryptionIDList_AddID(byte[] encryptionID, byte listIndex) { encryptionIDList_AddID(encryptionID, listIndex, 0); } public bool encryptionIDList_Configure(byte listSize, bool isBlacklist, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (listSize > 4) throw new ANT_Exception("Blacklist Whitelist has a maximum size of 4"); return ANT_ConfigCryptoList(unmanagedANTFramerPointer, channelNumber, listSize, Convert.ToByte(isBlacklist), responseWaitTime) == 1; } public void encryptionIDList_Configure(byte listSize, bool isBlacklist) { encryptionIDList_Configure(listSize, isBlacklist, 0); } /// Configures proximity search /// /// Enables a one time proximity requirement for searching. Only ANT devices within the set proximity bin can be acquired. /// Search threshold values are not correlated to specific distances as this will be dependent on the system design. /// This feature is not available on all ANT devices. /// Throws exception if given bin value is > 10. /// /// Threshold bin. Value from 0-10 (0= disabled). A search threshold value of 1 (i.e. bin 1) will yield the smallest radius search and is generally recommended as there is less chance of connecting to the wrong device. /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool setProximitySearch(byte thresholdBin, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); if (thresholdBin > 10) throw new ANT_Exception("Threshold bin must be 0-10"); return ANT_SetProximitySearch(unmanagedANTFramerPointer, channelNumber, thresholdBin, responseWaitTime) == 1; } /// /// Enables a one time proximity requirement for searching. Only ANT devices within the set proximity bin can be acquired. /// Search threshold values are not correlated to specific distances as this will be dependent on the system design. /// Throws exception if given bin value is > 10. /// /// Threshold bin. Value from 0-10 (0= disabled). A search threshold value of 1 (i.e. bin 1) will yield the smallest radius search and is generally recommended as there is less chance of connecting to the wrong device. public void setProximitySearch(byte thresholdBin) { setProximitySearch(thresholdBin, 0);} /// Configures the three operating RF frequencies for ANT frequency agility mode /// /// This function configures the three operating RF frequencies for ANT frequency agility mode /// and should be used with the ADV_FrequencyAgility_0x04 extended channel assignment flag. /// Should not be used with shared, or Tx/Rx only channel types. /// This feature is not available on all ANT devices. /// /// Operating RF frequency 1 /// Operating RF frequency 2 /// Operating RF frequency 3 /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool configFrequencyAgility(byte freq1, byte freq2, byte freq3, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return ANT_ConfigFrequencyAgility(unmanagedANTFramerPointer, channelNumber, freq1, freq2, freq3, responseWaitTime) == 1; } /// /// This function configures the three operating RF frequencies for ANT frequency agility mode /// and should be used with ADV_FrequencyAgility_0x04 channel assignment flag. /// Should not be used with shared, or Tx/Rx only channel types. /// /// Operating RF frequency 1 /// Operating RF frequency 2 /// Operating RF frequency 3 public void configFrequencyAgility(byte freq1, byte freq2, byte freq3) { configFrequencyAgility(freq1, freq2, freq3, 0); } /// Configures Selective Data Updates /// /// Allows enabling Selective Data Update /// /// Specify desired previously defined SDU mask and which messages it should apply to /// Time to wait for device success response /// True on success. Note: Always returns true with a response time of 0 public bool configSdu(byte sduConfig, UInt32 responseWaitTime) { if (disposed) throw new ObjectDisposedException("This ANTChannel object has been disposed"); return ANT_ConfigSelectiveDataUpdate(unmanagedANTFramerPointer, channelNumber, sduConfig, responseWaitTime) == 1; } /// /// Allows enabling Selective Data Update /// /// Specify desired previously defined SDU mask and which messages it should apply to public void configSdu(byte sduConfig) { configSdu(sduConfig, 0); } #endregion } }