Browse Source

Unity Project

wwdmbvbb 3 years ago
parent
commit
72e03c1644
100 changed files with 26209 additions and 0 deletions
  1. 8 0
      Assets/AdvancedAnt.meta
  2. 9 0
      Assets/AdvancedAnt/DEMO PC&MAC.meta
  3. 357 0
      Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.cs
  4. 12 0
      Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.cs.meta
  5. 1407 0
      Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.unity
  6. 8 0
      Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.unity.meta
  7. 9 0
      Assets/AdvancedAnt/DEMO PC&MAC/CodeExample.meta
  8. 106 0
      Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/ContinousScanExample.cs
  9. 12 0
      Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/ContinousScanExample.cs.meta
  10. 112 0
      Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/UsbExample.cs
  11. 12 0
      Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/UsbExample.cs.meta
  12. 9 0
      Assets/AdvancedAnt/DEMO PREFABS.meta
  13. 51 0
      Assets/AdvancedAnt/DEMO PREFABS/Android_readme.txt
  14. 8 0
      Assets/AdvancedAnt/DEMO PREFABS/Android_readme.txt.meta
  15. 4183 0
      Assets/AdvancedAnt/DEMO PREFABS/AntmultipleScan.unity
  16. 8 0
      Assets/AdvancedAnt/DEMO PREFABS/AntmultipleScan.unity.meta
  17. 93 0
      Assets/AdvancedAnt/DEMO PREFABS/PrefabDemoDisplay.cs
  18. 12 0
      Assets/AdvancedAnt/DEMO PREFABS/PrefabDemoDisplay.cs.meta
  19. 7743 0
      Assets/AdvancedAnt/DEMO PREFABS/demowithPrefabs.unity
  20. 8 0
      Assets/AdvancedAnt/DEMO PREFABS/demowithPrefabs.unity.meta
  21. 61 0
      Assets/AdvancedAnt/PC_MAC_readme.txt
  22. 8 0
      Assets/AdvancedAnt/PC_MAC_readme.txt.meta
  23. 9 0
      Assets/AdvancedAnt/Plugins.meta
  24. 9 0
      Assets/AdvancedAnt/Plugins/Android.meta
  25. 36 0
      Assets/AdvancedAnt/Plugins/Android/AndroidManifest.xml
  26. 8 0
      Assets/AdvancedAnt/Plugins/Android/AndroidManifest.xml.meta
  27. BIN
      Assets/AdvancedAnt/Plugins/Android/AntUnity.jar
  28. 23 0
      Assets/AdvancedAnt/Plugins/Android/AntUnity.jar.meta
  29. BIN
      Assets/AdvancedAnt/Plugins/Android/android-support-v4.jar
  30. 23 0
      Assets/AdvancedAnt/Plugins/Android/android-support-v4.jar.meta
  31. BIN
      Assets/AdvancedAnt/Plugins/Android/antpluginlib_3-5-0.jar
  32. 23 0
      Assets/AdvancedAnt/Plugins/Android/antpluginlib_3-5-0.jar.meta
  33. BIN
      Assets/AdvancedAnt/Plugins/Android/fit_14.10.jar
  34. 23 0
      Assets/AdvancedAnt/Plugins/Android/fit_14.10.jar.meta
  35. 9 0
      Assets/AdvancedAnt/Plugins/Ant.meta
  36. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library.meta
  37. 953 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Channel.cs
  38. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Channel.cs.meta
  39. 54 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelID.cs
  40. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelID.cs.meta
  41. 49 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelStatus.cs
  42. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelStatus.cs.meta
  43. 158 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Common.cs
  44. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Common.cs.meta
  45. 1869 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Device.cs
  46. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Device.cs.meta
  47. 346 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceCapabilities.cs
  48. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceCapabilities.cs.meta
  49. 63 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceInfo.cs
  50. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceInfo.cs.meta
  51. 43 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Exception.cs
  52. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Exception.cs.meta
  53. 427 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ReferenceLibrary.cs
  54. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ReferenceLibrary.cs.meta
  55. 201 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Response.cs
  56. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Response.cs.meta
  57. 57 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_VersionInfo.cs
  58. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_VersionInfo.cs.meta
  59. 382 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/IANT_Channel.cs
  60. 12 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/IANT_Channel.cs.meta
  61. 59 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle.meta
  62. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents.meta
  63. 46 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Info.plist
  64. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Info.plist.meta
  65. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS.meta
  66. BIN
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS/ANT_WrappedLib
  67. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS/ANT_WrappedLib.meta
  68. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources.meta
  69. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB.meta
  70. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common.meta
  71. 31 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.c
  72. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.c.meta
  73. 36 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.h
  74. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.h.meta
  75. 215 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.c
  76. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.c.meta
  77. 73 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.h
  78. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.h.meta
  79. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc.meta
  80. 346 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antdefines.h
  81. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antdefines.h.meta
  82. 406 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antmessage.h
  83. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antmessage.h.meta
  84. 41 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/defines.h
  85. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/defines.h.meta
  86. 196 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/types.h
  87. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/types.h.meta
  88. 21 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/version.h
  89. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/version.h.meta
  90. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software.meta
  91. 9 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS.meta
  92. 3907 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.cpp
  93. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.cpp.meta
  94. 777 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.hpp
  95. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.hpp.meta
  96. 384 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_interface.hpp
  97. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_interface.hpp.meta
  98. 194 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.c
  99. 8 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.c.meta
  100. 131 0
      Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.h

+ 8 - 0
Assets/AdvancedAnt.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 90ccd1520d7c27d43877c53d1c5838db
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/DEMO PC&MAC.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 67e91c079e075234eb717990af39e737
+folderAsset: yes
+timeCreated: 1475498400
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 357 - 0
Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.cs

@@ -0,0 +1,357 @@
+using UnityEngine;
+using System.Collections;
+using UnityEngine.UI;
+using ANT_Managed_Library;
+using System.Collections.Generic;
+using System;
+
+
+
+public class AntDemo : MonoBehaviour
+{
+    //output ant responses and data to unity UI text
+    public Text dataDisplay;
+    List<string> logDisplay;
+
+    AntChannel hrChannel;
+    AntChannel speedChannel;
+    AntChannel backgroundScanChannel;
+
+    //variable use for speed display
+    int prevRev;
+    int prevMeasTime = 0;
+
+    //fake HRM beat
+    byte hbCount = 0;
+
+    void Start()
+    {
+        logDisplay = new List<string>();
+        dataDisplay.text = "";
+        //EncodeFitFile(); //the FIT library is included to encode and decode FIT files
+    }
+
+    void init_Device()
+    {
+        if (AntManager.Instance.device == null)
+        {
+            AntManager.Instance.Init();
+            AntManager.Instance.onDeviceResponse += OnDeviceResponse;
+            AntManager.Instance.onSerialError += OnSerialError; //if usb dongle is unplugged for example
+        }
+
+    }
+
+    public void Onclick_Init_HRSensor()
+    {
+        init_Device();
+
+        //call the ConfigureAnt method for a master channel with the correct ANT speed display settings 
+        //found in ANT_Device_Profile_Heart_Rate_Monitor.pdf on thisisant.com
+        //using channel 1
+        hrChannel = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Master_Transmit_0x10, 1, 255, 120, 0, 57, 8070, false); //hr sensor
+        hrChannel.onChannelResponse += OnChannelResponse;
+
+        InvokeRepeating("HRMTransmit", 1, 1 / 4f); // let's fake a HRM by updating a HR beat every 1/4 second
+    }
+    public void Onclick_Init_SpeedDisplay()
+    {
+        init_Device();
+
+        //call the ConfigureAnt method for a slave channel with the correct ANT speed display settings 
+        //found in ANT+_Device_Profile_-_Bicycle_Speed_and_Cadence_2.0.pdf on thisisant.com
+        //using channel 2
+        //note: collision is a normal behaviour searching for a master.
+
+        speedChannel = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 2, 0, 123, 0, 57, 8118, false); //bike speed Display
+        speedChannel.onChannelResponse += OnChannelResponse;
+        speedChannel.onReceiveData += ReceivedSpeedAntData;
+
+    }
+
+    public void Onclick_Start_BackgroundScan()
+    {
+        init_Device();
+        backgroundScanChannel = AntManager.Instance.OpenBackgroundScanChannel(0);
+        backgroundScanChannel.onReceiveData += ReceivedBackgroundScanData;
+        backgroundScanChannel.onChannelResponse += OnChannelResponse;
+
+    }
+
+
+    public void Onclick_Close()
+    {
+
+        if (hrChannel)
+        {
+            hrChannel.onChannelResponse -= OnChannelResponse;
+            hrChannel.Close();
+            CancelInvoke("HRMTransmit");
+            hrChannel = null;
+
+        }
+        if (speedChannel)
+        {
+            speedChannel.onReceiveData -= ReceivedSpeedAntData;
+            speedChannel.Close();
+            speedChannel = null;
+        }
+        if (backgroundScanChannel)
+        {
+            backgroundScanChannel.onReceiveData -= ReceivedBackgroundScanData;
+            backgroundScanChannel.onChannelResponse -= OnChannelResponse;
+            backgroundScanChannel.Close();
+            backgroundScanChannel = null;
+        }
+
+        StopCoroutine("Reconnect");
+    }
+
+
+    void OnDeviceResponse(ANT_Response response)
+    {
+        DisplayText("device:" + response.getMessageID().ToString());
+    }
+
+    void OnSerialError(SerialError serialError)
+    {
+        DisplayText("Error:" + serialError.error.ToString());
+
+        //attempt to auto reconnect if the USB was unplugged
+        if (serialError.error == ANT_Device.serialErrorCode.DeviceConnectionLost)
+        {
+            foreach (AntChannel channel in AntManager.Instance.channelList)
+                channel.PauseChannel();
+
+            StartCoroutine("Reconnect", serialError.sender.getSerialNumber());
+        }
+
+    }
+
+    IEnumerator Reconnect(uint serial)
+    {
+        Debug.Log("looking for usb device " + serial.ToString());
+        // polling to try and find the USB device
+        while (true)
+        {
+
+            if (ANT_Common.getNumDetectedUSBDevices() > 0)
+            {
+                ANT_Device device = new ANT_Device();
+                if (device.getSerialNumber() == serial)
+                {
+                    Debug.Log("usb found!");
+                    AntManager.Instance.Reconnect(device);
+                    foreach (AntChannel channel in AntManager.Instance.channelList)
+                        channel.ReOpen();
+
+                    yield break;
+                }
+                else
+                    device.Dispose();
+
+            }
+
+            yield return new WaitForSeconds(0.1f);
+        }
+
+    }
+
+    void OnChannelResponse(ANT_Response response)
+    {
+
+        if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02)
+            DisplayText("channel " + response.antChannel.ToString() + " " + "RX fail");
+        else if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08)
+            DisplayText("channel " + response.antChannel.ToString() + " " + "Go to search");
+        else if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03)
+            DisplayText("channel " + response.antChannel.ToString() + " " + "Tx: (" + response.antChannel.ToString() + ")" + BitConverter.ToString(hrChannel.txBuffer));
+        else
+            DisplayText("channel " + response.antChannel.ToString() + " " + response.getChannelEventCode());
+
+    }
+
+    void HRMTransmit()
+    {
+        hbCount++;
+        //super simple HRM
+        hrChannel.txBuffer[0] = 0;
+        hrChannel.txBuffer[1] = 0;
+        hrChannel.txBuffer[2] = 0;
+        hrChannel.txBuffer[3] = 0;
+        hrChannel.txBuffer[4] = 0;
+        hrChannel.txBuffer[5] = 0;
+        hrChannel.txBuffer[6] = hbCount;
+        hrChannel.txBuffer[7] = (byte)UnityEngine.Random.Range(90, 100);
+
+    }
+
+    void ReceivedSpeedAntData(Byte[] data)
+    {
+        //output the data to our log window
+        string dataString = "RX: ";
+        foreach (byte b in data)
+            dataString += b.ToString("X") + " ";
+        DisplayText(dataString);
+
+        //speed formula as described in the ant+ device profile doc
+        int currentRevCount = (data[6]) | data[7] << 8;
+
+        if (currentRevCount != prevRev && prevRev > 0)
+        {
+            int currentMeasTime = (data[4]) | data[5] << 8;
+            float speed = (2.070f * (currentRevCount - prevRev) * 1024) / (currentMeasTime - prevMeasTime);
+            speed *= 3.6f;
+            prevMeasTime = currentMeasTime;
+            DisplayText("speed: " + speed.ToString("F2") + "km/h");
+        }
+
+        prevRev = currentRevCount;
+
+
+    }
+
+    void ReceivedBackgroundScanData(Byte[] data)
+    {
+
+        byte deviceType = (data[12]); // extended info Device Type byte
+                                      //use the Extended Message Formats to identify nodes
+        Debug.Log("scan found ID : "+ ((data[10]) | data[11] << 8)+ "of TYPE: "+ deviceType);
+        switch (deviceType)
+        {
+            case AntplusDeviceType.Antfs:
+                {
+                    DisplayText("Scan Found Antfs");
+                    break;
+                }
+            case AntplusDeviceType.BikePower:
+                {
+                    DisplayText("Scan Found BikePower");
+                    break;
+                }
+            case AntplusDeviceType.EnvironmentSensorLegacy:
+                {
+                    DisplayText("Scan Found EnvironmentSensorLegacy");
+                    break;
+                }
+            case AntplusDeviceType.MultiSportSpeedDistance:
+                {
+                    DisplayText("Scan Found MultiSportSpeedDistance");
+                    break;
+                }
+            case AntplusDeviceType.Control:
+                {
+                    DisplayText("Scan Found Control");
+                    break;
+                }
+            case AntplusDeviceType.FitnessEquipment:
+                {
+                    DisplayText("Scan Found FitnessEquipment");
+                    break;
+                }
+            case AntplusDeviceType.BloodPressure:
+                {
+                    DisplayText("Scan Found BloodPressure");
+                    break;
+                }
+            case AntplusDeviceType.GeocacheNode:
+                {
+                    DisplayText("Scan Found GeocacheNode");
+                    break;
+                }
+            case AntplusDeviceType.LightElectricVehicle:
+                {
+                    DisplayText("Scan Found LightElectricVehicle");
+                    break;
+                }
+            case AntplusDeviceType.EnvSensor:
+                {
+                    DisplayText("Scan Found EnvSensor");
+                    break;
+                }
+            case AntplusDeviceType.Racquet:
+                {
+                    DisplayText("Scan Found Racquet");
+                    break;
+                }
+            case AntplusDeviceType.ControlHub:
+                {
+                    DisplayText("Scan Found ControlHub");
+                    break;
+                }
+            case AntplusDeviceType.MuscleOxygen:
+                {
+                    DisplayText("Scan Found MuscleOxygen");
+                    break;
+                }
+            case AntplusDeviceType.BikeLightMain:
+                {
+                    DisplayText("Scan Found BikeLightMain");
+                    break;
+                }
+            case AntplusDeviceType.BikeLightShared:
+                {
+                    DisplayText("Scan Found BikeLightShared");
+                    break;
+                }
+            case AntplusDeviceType.BikeRadar:
+                {
+                    DisplayText("Scan Found BikeRadar");
+                    break;
+                }
+            case AntplusDeviceType.WeightScale:
+                {
+                    DisplayText("Scan Found WeightScale");
+                    break;
+                }
+            case AntplusDeviceType.HeartRate:
+                {
+                    DisplayText("Scan Found HeartRate");
+                    break;
+                }
+            case AntplusDeviceType.BikeSpeedCadence:
+                {
+                    DisplayText("Scan Found BikeSpeedCadence");
+                    break;
+                }
+            case AntplusDeviceType.BikeCadence:
+                {
+                    DisplayText("Scan Found BikeCadence");
+                    break;
+                }
+            case AntplusDeviceType.BikeSpeed:
+                {
+                    DisplayText("Scan Found BikeSpeed");
+                    break;
+                }
+            case AntplusDeviceType.StrideSpeedDistance:
+                {
+                    DisplayText("Scan Found StrideSpeedDistance");
+                    break;
+                }
+            default:
+                {
+                    DisplayText("Scan Found Found Unknown device");
+                    break;
+                }
+        }
+
+    }
+
+   
+    //Display content of the string list to the UI text
+    void DisplayText(string s)
+    {
+        dataDisplay.text = "";
+        logDisplay.Add(s + "\n");
+        if (logDisplay.Count > 13)
+            logDisplay.RemoveAt(0);
+
+        foreach (string log in logDisplay)
+            dataDisplay.text += log;
+    }
+
+
+
+
+}

+ 12 - 0
Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 28435c037830f2149bc80bf2e0e5b575
+timeCreated: 1475498421
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1407 - 0
Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.unity

@@ -0,0 +1,1407 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 8
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 9
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_TextureWidth: 1024
+    m_TextureHeight: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 0
+    m_CompAOExponentDirect: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 1024
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 1
+    m_BakeBackend: 0
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVRFilteringMode: 0
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 0
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &105061259
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 105061260}
+  - component: {fileID: 105061263}
+  - component: {fileID: 105061262}
+  - component: {fileID: 105061261}
+  m_Layer: 5
+  m_Name: Close_btn
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &105061260
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 105061259}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 481151742}
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 167.5, y: -44}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &105061261
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 105061259}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 105061262}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1516994880}
+        m_MethodName: Onclick_Close
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &105061262
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 105061259}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+--- !u!222 &105061263
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 105061259}
+--- !u!1 &258793380
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 258793381}
+  - component: {fileID: 258793383}
+  - component: {fileID: 258793382}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &258793381
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 258793380}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 350, y: 189}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &258793382
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 258793380}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: YOU NEED TO ENTER THE NETWORK KEY IN ANTManager.CS (Register on www.thisisant.com)
+--- !u!222 &258793383
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 258793380}
+--- !u!1 &481151741
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 481151742}
+  - component: {fileID: 481151744}
+  - component: {fileID: 481151743}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &481151742
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 481151741}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 105061260}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &481151743
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 481151741}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: CLOSE CHANNEL
+--- !u!222 &481151744
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 481151741}
+--- !u!1 &773002967
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 773002968}
+  - component: {fileID: 773002970}
+  - component: {fileID: 773002969}
+  m_Layer: 5
+  m_Name: DataDisplay
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &773002968
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 773002967}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 433, y: 147}
+  m_SizeDelta: {x: 238.79999, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &773002969
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 773002967}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!222 &773002970
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 773002967}
+--- !u!1 &799039329
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 799039334}
+  - component: {fileID: 799039333}
+  - component: {fileID: 799039332}
+  - component: {fileID: 799039331}
+  - component: {fileID: 799039330}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &799039330
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 799039329}
+  m_Enabled: 1
+--- !u!124 &799039331
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 799039329}
+  m_Enabled: 1
+--- !u!92 &799039332
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 799039329}
+  m_Enabled: 1
+--- !u!20 &799039333
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 799039329}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 2
+  m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0.019607844}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 0
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &799039334
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 799039329}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1050058894
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1050058897}
+  - component: {fileID: 1050058896}
+  - component: {fileID: 1050058895}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1050058895
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1050058894}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalAxis: Horizontal
+  m_VerticalAxis: Vertical
+  m_SubmitButton: Submit
+  m_CancelButton: Cancel
+  m_InputActionsPerSecond: 10
+  m_RepeatDelay: 0.5
+  m_ForceModuleActive: 0
+--- !u!114 &1050058896
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1050058894}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 5
+--- !u!4 &1050058897
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1050058894}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1098694198
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1098694199}
+  - component: {fileID: 1098694201}
+  - component: {fileID: 1098694200}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1098694199
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1098694198}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1757075034}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1098694200
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1098694198}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: BACKGROUND SCAN
+--- !u!222 &1098694201
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1098694198}
+--- !u!1 &1170148852
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1170148853}
+  - component: {fileID: 1170148855}
+  - component: {fileID: 1170148854}
+  m_Layer: 5
+  m_Name: Panel
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1170148853
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170148852}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 544, y: 53}
+  m_SizeDelta: {x: 590, y: 230}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1170148854
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170148852}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 0.392}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+--- !u!222 &1170148855
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170148852}
+--- !u!1 &1201437814
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1201437815}
+  - component: {fileID: 1201437818}
+  - component: {fileID: 1201437817}
+  - component: {fileID: 1201437816}
+  m_Layer: 5
+  m_Name: Init_btn_Sensor
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1201437815
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1201437814}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1281636520}
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 168, y: 150}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1201437816
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1201437814}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1201437817}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1516994880}
+        m_MethodName: Onclick_Init_HRSensor
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1201437817
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1201437814}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+--- !u!222 &1201437818
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1201437814}
+--- !u!1 &1281636519
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1281636520}
+  - component: {fileID: 1281636522}
+  - component: {fileID: 1281636521}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1281636520
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1281636519}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1201437815}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1281636521
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1281636519}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: INIT HR SENSOR
+--- !u!222 &1281636522
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1281636519}
+--- !u!1 &1516994879
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1516994882}
+  - component: {fileID: 1516994880}
+  m_Layer: 0
+  m_Name: AntDemo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1516994880
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1516994879}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 28435c037830f2149bc80bf2e0e5b575, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  dataDisplay: {fileID: 773002969}
+--- !u!4 &1516994882
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1516994879}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 1.1177655, y: 2.9260833, z: 8.269531}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1757075033
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1757075034}
+  - component: {fileID: 1757075037}
+  - component: {fileID: 1757075036}
+  - component: {fileID: 1757075035}
+  m_Layer: 5
+  m_Name: scan_btn
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1757075034
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1757075033}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1098694199}
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 6
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 167.5, y: 49}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1757075035
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1757075033}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1757075036}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1516994880}
+        m_MethodName: Onclick_Start_BackgroundScan
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1757075036
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1757075033}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+--- !u!222 &1757075037
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1757075033}
+--- !u!1 &1834606020
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1834606024}
+  - component: {fileID: 1834606023}
+  - component: {fileID: 1834606022}
+  - component: {fileID: 1834606021}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1834606021
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1834606020}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &1834606022
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1834606020}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+--- !u!223 &1834606023
+Canvas:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1834606020}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 0
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 25
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &1834606024
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1834606020}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_Children:
+  - {fileID: 773002968}
+  - {fileID: 1201437815}
+  - {fileID: 105061260}
+  - {fileID: 1170148853}
+  - {fileID: 2122244421}
+  - {fileID: 258793381}
+  - {fileID: 1757075034}
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!1 &1993978938
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1993978939}
+  - component: {fileID: 1993978941}
+  - component: {fileID: 1993978940}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1993978939
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1993978938}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 2122244421}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1993978940
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1993978938}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: INIT SPEED DISPLAY
+--- !u!222 &1993978941
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1993978938}
+--- !u!1 &2122244420
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 2122244421}
+  - component: {fileID: 2122244424}
+  - component: {fileID: 2122244423}
+  - component: {fileID: 2122244422}
+  m_Layer: 5
+  m_Name: Init_btn_Display
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2122244421
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2122244420}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1993978939}
+  m_Father: {fileID: 1834606024}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 167.5, y: 101}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2122244422
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2122244420}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 2122244423}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1516994880}
+        m_MethodName: Onclick_Init_SpeedDisplay
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &2122244423
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2122244420}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+--- !u!222 &2122244424
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2122244420}

+ 8 - 0
Assets/AdvancedAnt/DEMO PC&MAC/AntDemo.unity.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 58e98a7728e644d4d88e80e6e6299365
+timeCreated: 1475498421
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/DEMO PC&MAC/CodeExample.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2b67a3a16f9d4d34f9a2bcc880b3a2d9
+folderAsset: yes
+timeCreated: 1478432733
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 106 - 0
Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/ContinousScanExample.cs

@@ -0,0 +1,106 @@
+using UnityEngine;
+using System.Collections;
+using UnityEngine.UI;
+using ANT_Managed_Library;
+using System.Collections.Generic;
+using System;
+
+/*
+ * ContinouScanExample
+ *
+ * With continuous scan you can connect up to ~75 sensors with a single usb dongle
+ * open a channel with a given radio frequency  AntManager.Instance.OpenContinuousScanChannel(57); 
+ * and then filter the incomming device type and ID in the Receive Data event
+ */
+
+
+//Speed sensor object, for every new device ID that match the speed sensor type, we create a new SpeedSensor
+public class SpeedSensor {
+    public int stopRevCounter_speed;
+    public int prev_measTime_speed;
+    public int prev_revCount_speed;
+    public int revCountZero;
+    public float wheelCircumference = 2.096f;
+    public float speed;
+    public int deviceID;
+
+    public float GetSpeed(Byte[] data) {
+        
+
+        //SPEED
+        int measTime_speed = (data[5]) | data[6] << 8;
+        int revCount_speed = (data[7]) | data[8] << 8;
+
+
+
+        if (prev_measTime_speed != 0 && measTime_speed != prev_measTime_speed && prev_measTime_speed < measTime_speed && prev_revCount_speed < revCount_speed) {
+            
+            speed = (wheelCircumference * (revCount_speed - prev_revCount_speed) * 1024) / (measTime_speed - prev_measTime_speed);
+            speed *= 3.6f; // km/h
+            stopRevCounter_speed = 0;
+
+        } else
+            stopRevCounter_speed++;
+
+        if (stopRevCounter_speed >= 5) {
+            stopRevCounter_speed = 5;
+            speed = 0;
+        }
+
+
+        prev_measTime_speed = measTime_speed;
+        prev_revCount_speed = revCount_speed;
+        return speed;
+    }
+}
+
+public class ContinousScanExample : MonoBehaviour {
+
+    List<SpeedSensor> speedSensorList;
+    // Use this for initialization
+    void Start () {
+
+        if (AntManager.Instance.device == null) {
+            AntManager.Instance.Init();
+          //  AntManager.Instance.onDeviceResponse += OnDeviceResponse;
+          //  AntManager.Instance.onSerialError += OnSerialError; //if usb dongle is unplugged for example
+        }
+
+        AntChannel scanChannel = AntManager.Instance.OpenContinuousScanChannel(57); 
+       // scanChannel.onChannelResponse += OnChannelResponse;
+        scanChannel.onReceiveData += ReceiveContinuouScanData;
+    }
+
+
+    void ReceiveContinuouScanData(Byte[] data) {
+
+        if (speedSensorList == null)
+            speedSensorList = new List<SpeedSensor>();
+        // first byte is the channel ID, 0
+        int pageNumber = data[1] >> 1;
+        //device number to filter devices
+        int deviceNumber = ((data[10]) | data[11] << 8);
+        int deviceType = (data[12]);
+           
+        SpeedSensor sensor = null;
+        foreach (SpeedSensor s in speedSensorList) {
+            if (s.deviceID == deviceNumber) {
+                //WARNING  Byte[] data contains the channel ID in the first byte, shift the payload bytes from the array accordingly
+                Debug.Log("speed for sensor #" + s.deviceID + ": " + s.GetSpeed(data));
+                break;
+            }
+        }
+        //if sensor object not created and is of correct type, create and store in list
+        if (sensor == null && deviceType == AntplusDeviceType.BikeSpeed) {
+            //found new sensor
+            sensor = new SpeedSensor();
+            sensor.deviceID = deviceNumber;
+            speedSensorList.Add(sensor);
+        }
+
+
+
+    }
+
+
+}

+ 12 - 0
Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/ContinousScanExample.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 927ffa8e85d03a544bbea7734332d9e8
+timeCreated: 1478417919
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 112 - 0
Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/UsbExample.cs

@@ -0,0 +1,112 @@
+using UnityEngine;
+using System.Collections;
+using UnityEngine.UI;
+using ANT_Managed_Library;
+using System.Collections.Generic;
+using System;
+using System.IO;
+
+/*
+ * UsbExample
+ *
+ * you can specify the USB number in init_Device(int USBnum);
+ * OpenChannel last argument is the device number, default to 0
+ */
+
+
+public class UsbExample : MonoBehaviour {
+
+    uint nDeviceConnected = 0;
+    void Start() {
+     
+        //INIT HR Display on usb device 0 and 1
+        init_Device(0);
+        AntChannel c = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 0, 0, 120, 0, 57, 8070, false, 0); 
+        c.onChannelResponse += OnChannelResponse;
+        c.onReceiveData += USB0;
+        c.hideRXFAIL = true;
+
+        init_Device(1);
+        AntChannel d = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 0, 0, 120, 0, 57, 8070, false, 1);
+        d.onChannelResponse += OnChannelResponse;
+        d.onReceiveData += USB1;
+        d.hideRXFAIL = true;
+    }
+
+    void USB0(Byte[] data) {
+        Debug.Log("USB 0 received data");
+    }
+    void USB1(Byte[] data) {
+        Debug.Log("USB 1 received data");
+    }
+
+    bool firstDeviceInitialized = false;
+    void init_Device(byte USBDeviceNum) {
+        if (AntManager.Instance.devices[USBDeviceNum] == null) {
+            AntManager.Instance.Init(USBDeviceNum);
+
+            if (firstDeviceInitialized == false) { // device events need to be added only once
+                firstDeviceInitialized = true;
+                AntManager.Instance.onDeviceResponse += OnDeviceResponse;
+                AntManager.Instance.onSerialError += OnSerialError; //if usb dongle is unplugged for example
+            }
+
+        }
+
+    }
+
+
+    void OnDeviceResponse(ANT_Response response) {
+        ANT_Device device = response.sender as ANT_Device;
+        Debug.Log("device (usb " + device.getOpenedUSBDeviceNum() + ") : " + response.getMessageID().ToString());
+    }
+
+    void OnSerialError(SerialError serialError) {
+        Debug.Log("Error:" + serialError.error.ToString());
+
+        //attempt to auto reconnect if the USB was unplugged
+        if (serialError.error == ANT_Device.serialErrorCode.DeviceConnectionLost) {
+            foreach (AntChannel channel in AntManager.Instance.channelList) {
+                if (channel.device == serialError.sender)
+                    channel.PauseChannel();
+            }
+            nDeviceConnected = ANT_Common.getNumDetectedUSBDevices();
+            StartCoroutine("Reconnect", serialError.sender.getSerialNumber());
+        }
+
+    }
+
+    IEnumerator Reconnect(uint serial) {
+        Debug.Log("looking for usb device " + serial.ToString());
+        // polling to try and find the USB device
+        while (true) {
+
+            if (ANT_Common.getNumDetectedUSBDevices() > nDeviceConnected) {
+
+
+
+                ANT_Device device = new ANT_Device();
+                if (device.getSerialNumber() == serial) {
+                    Debug.Log("usb found!");
+                    AntManager.Instance.Reconnect(device);
+                    foreach (AntChannel channel in AntManager.Instance.channelList)
+                        channel.ReOpen(device);
+
+                    yield break;
+                } else
+                    device.Dispose();
+
+            }
+
+            yield return new WaitForSeconds(0.1f);
+        }
+
+    }
+
+    void OnChannelResponse(ANT_Response response) {
+        
+
+    }
+    
+
+}

+ 12 - 0
Assets/AdvancedAnt/DEMO PC&MAC/CodeExample/UsbExample.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d8676a4c109f11d40905b976fe894701
+timeCreated: 1478419070
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/DEMO PREFABS.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e7756b7e99846b8478172601b2334ec6
+folderAsset: yes
+timeCreated: 1475498988
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 51 - 0
Assets/AdvancedAnt/DEMO PREFABS/Android_readme.txt

@@ -0,0 +1,51 @@
+IMPORTANT: 
+move the AndroidManifest.xml file from the Assets/AdvancedAnt/Plugins/Android folder to Assets/plugins/Android folder
+If you are using any other pluging like VR, make sure to merge the services and activities
+
+---
+
+*set the minimum API level to Android 5.0 (API LEVEL 21)*
+
+-----
+The Android device must have the ANT radio service installed (a popup will ask the user to download it from google play if not installed, when you launch your app)
+I have added all APK in a zip file at the root of the package
+
+To debug on windows you can use the Android_PC_AndroidEmulatorBridge found in the ANT android SDK on thisisant.com ( you will need to install Android_ANTEmulatorConfig_2-0-0.apk on the device)
+
+-----
+
+The android plugin can use the built-in device selection UI by setting the useAndroidUI boolean to true on the prefabs.
+
+If you use multiple prefabs with autoconnect, the java plugin will queue the requests and connect to the sensor one by one.
+
+If you need any specific event from a device not implemented yet by the plugin, send me an email and I will add it. 
+Here are the events the android plugin forwards to Unity for each sensor:
+
+All sensors :isDisconnected , StateChange , ConnectEvent?
+
+Cadence sensor: Receive_calculatedCadence
+
+Speed & Cadence sensor: Receive_calculatedCadence?, Receive_calculatedSpeed, Receive_CalculatedAccumulatedDistance
+
+Speed sensor: Receive_calculatedSpeed, Receive_CalculatedAccumulatedDistance
+
+Power Meter sensor: Receive_calculatedPower, Receive_calculatedCadence?
+
+Heart Rate sensor: Receive_computedHeartRate?
+
+Fitness Equipment: Receive_instantaneousHeartRate, Receive_elapsedTime, Receive_instantaneousSpeed, Receive_cumulativeDistance?, Receive_trainer_instantaneousPowe, Receive_trainer_instantaneousCadence
+SetTrainerResistance(resitance %)
+SetTrainerTargetPower(power)
+RequestTrainerCapabilities​
+SetTrainerUserConfiguration
+
+Minimum Android version: 5.0.1
+
+The AndroidManifest.xml file has to be in the Assets\plugins\Android
+
+---- 
+If you set the device ID in a prefab, the plugin will attempt to connect to this device without using the Android ANT+ UI
+You can also scan for device ID by filtering device type.
+the AndroidMultipleDeviceSearch Gameobject in the  AntmultipleScan scene is set to look for speedAndCadence sensor and will connect to the first ID it found with SpeedCadenceDisplay prefab.
+
+activity.Call("start_multiple_device_search",this.gameObject.name,speedCadence,hr,cadence,speed,power,fec);

+ 8 - 0
Assets/AdvancedAnt/DEMO PREFABS/Android_readme.txt.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 77eb2bf0a9f888545a57bd16d2d01d82
+timeCreated: 1475486185
+licenseType: Store
+TextScriptImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4183 - 0
Assets/AdvancedAnt/DEMO PREFABS/AntmultipleScan.unity

@@ -0,0 +1,4183 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 8
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 9
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_TextureWidth: 1024
+    m_TextureHeight: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 0
+    m_CompAOExponentDirect: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 1024
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 1
+    m_BakeBackend: 0
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVRFilteringMode: 0
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 0
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &146069396
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 146069397}
+  - component: {fileID: 146069398}
+  m_Layer: 0
+  m_Name: Demo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &146069397
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 146069396}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 585111786}
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &146069398
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 146069396}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b96146adbbf118c47a3d9ba6cc0d6b40, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  uiText: {fileID: 407602310}
+  BikeTrainerButtons: {fileID: 0}
+--- !u!1 &407602308
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 407602309}
+  - component: {fileID: 407602311}
+  - component: {fileID: 407602310}
+  m_Layer: 5
+  m_Name: demoText
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &407602309
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1091122761}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: -186.9, y: -72}
+  m_SizeDelta: {x: -411, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &407602310
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 32
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 0
+    m_MaxSize: 82
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 'Multiple type scan on android
+
+'
+--- !u!222 &407602311
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+--- !u!1 &585111783
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 585111786}
+  - component: {fileID: 585111785}
+  - component: {fileID: 585111784}
+  m_Layer: 0
+  m_Name: Particle System
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!199 &585111784
+ParticleSystemRenderer:
+  serializedVersion: 4
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 0
+  m_Materials:
+  - {fileID: 10301, guid: 0000000000000000f000000000000000, type: 0}
+  - {fileID: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_RenderMode: 0
+  m_SortMode: 0
+  m_MinParticleSize: 0
+  m_MaxParticleSize: 0.5
+  m_CameraVelocityScale: 0
+  m_VelocityScale: 0
+  m_LengthScale: 2
+  m_SortingFudge: 0
+  m_NormalDirection: 1
+  m_RenderAlignment: 0
+  m_Pivot: {x: 0, y: 0, z: 0}
+  m_UseCustomVertexStreams: 0
+  m_VertexStreams: 0001030405
+  m_Mesh: {fileID: 0}
+  m_Mesh1: {fileID: 0}
+  m_Mesh2: {fileID: 0}
+  m_Mesh3: {fileID: 0}
+  m_MaskInteraction: 0
+--- !u!198 &585111785
+ParticleSystem:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  serializedVersion: 5
+  lengthInSec: 5
+  simulationSpeed: 1
+  stopAction: 0
+  looping: 1
+  prewarm: 0
+  playOnAwake: 1
+  useUnscaledTime: 0
+  autoRandomSeed: 1
+  useRigidbodyForVelocity: 1
+  startDelay:
+    serializedVersion: 2
+    minMaxState: 0
+    scalar: 0
+    minScalar: 0
+    maxCurve:
+      serializedVersion: 2
+      m_Curve:
+      - serializedVersion: 2
+        time: 0
+        value: 1
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+      - serializedVersion: 2
+        time: 1
+        value: 1
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+    minCurve:
+      serializedVersion: 2
+      m_Curve:
+      - serializedVersion: 2
+        time: 0
+        value: 0
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+      - serializedVersion: 2
+        time: 1
+        value: 0
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+  moveWithTransform: 0
+  moveWithCustomTransform: {fileID: 0}
+  scalingMode: 1
+  randomSeed: 0
+  InitialModule:
+    serializedVersion: 3
+    enabled: 1
+    startLifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 5
+      minScalar: 5
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSpeed:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 5
+      minScalar: 5
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startColor:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    startSize:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSizeY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSizeZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotationX:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotationY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotation:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    randomizeRotationDirection: 0
+    maxNumParticles: 1000
+    size3D: 0
+    rotation3D: 0
+    gravityModifier:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  ShapeModule:
+    serializedVersion: 5
+    enabled: 1
+    type: 4
+    angle: 25
+    length: 5
+    boxThickness: {x: 0, y: 0, z: 0}
+    radiusThickness: 1
+    donutRadius: 0.2
+    m_Position: {x: 0, y: 0, z: 0}
+    m_Rotation: {x: 0, y: 0, z: 0}
+    m_Scale: {x: 1, y: 1, z: 1}
+    placementMode: 0
+    m_MeshMaterialIndex: 0
+    m_MeshNormalOffset: 0
+    m_Mesh: {fileID: 0}
+    m_MeshRenderer: {fileID: 0}
+    m_SkinnedMeshRenderer: {fileID: 0}
+    m_UseMeshMaterialIndex: 0
+    m_UseMeshColors: 1
+    alignToDirection: 0
+    randomDirectionAmount: 0
+    sphericalDirectionAmount: 0
+    randomPositionAmount: 0
+    radius:
+      value: 1
+      mode: 0
+      spread: 0
+      speed:
+        serializedVersion: 2
+        minMaxState: 0
+        scalar: 1
+        minScalar: 1
+        maxCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 2
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          - serializedVersion: 2
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+        minCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 2
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          - serializedVersion: 2
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+    arc:
+      value: 360
+      mode: 0
+      spread: 0
+      speed:
+        serializedVersion: 2
+        minMaxState: 0
+        scalar: 1
+        minScalar: 1
+        maxCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 2
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          - serializedVersion: 2
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+        minCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 2
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          - serializedVersion: 2
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+  EmissionModule:
+    enabled: 1
+    serializedVersion: 4
+    rateOverTime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 10
+      minScalar: 10
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    rateOverDistance:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_BurstCount: 0
+    m_Bursts: []
+  SizeModule:
+    enabled: 0
+    curve:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+  RotationModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0.7853982
+      minScalar: 0.7853982
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+  ColorModule:
+    enabled: 0
+    gradient:
+      serializedVersion: 2
+      minMaxState: 1
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+  UVModule:
+    enabled: 0
+    mode: 0
+    frameOverTime:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 0.9999
+      minScalar: 0.9999
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 1
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 1
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 1
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 1
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startFrame:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    tilesX: 1
+    tilesY: 1
+    animationType: 0
+    rowIndex: 0
+    cycles: 1
+    uvChannelMask: -1
+    flipU: 0
+    flipV: 0
+    randomRow: 1
+    sprites:
+    - sprite: {fileID: 0}
+  VelocityModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    speedModifier:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    inWorldSpace: 0
+  InheritVelocityModule:
+    enabled: 0
+    m_Mode: 0
+    m_Curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  ForceModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    inWorldSpace: 0
+    randomizePerFrame: 0
+  ExternalForcesModule:
+    enabled: 0
+    multiplier: 1
+  ClampVelocityModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    magnitude:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxis: 0
+    inWorldSpace: 0
+    multiplyDragByParticleSize: 1
+    multiplyDragByParticleVelocity: 1
+    dampen: 1
+    drag:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  NoiseModule:
+    enabled: 0
+    strength:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    strengthY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    strengthZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+    frequency: 0.5
+    damping: 1
+    octaves: 1
+    octaveMultiplier: 0.5
+    octaveScale: 2
+    quality: 2
+    scrollSpeed:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remap:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapY:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapZ:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapEnabled: 0
+    positionAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    rotationAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    sizeAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  SizeBySpeedModule:
+    enabled: 0
+    curve:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    range: {x: 0, y: 1}
+    separateAxes: 0
+  RotationBySpeedModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0.7853982
+      minScalar: 0.7853982
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+    range: {x: 0, y: 1}
+  ColorBySpeedModule:
+    enabled: 0
+    gradient:
+      serializedVersion: 2
+      minMaxState: 1
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    range: {x: 0, y: 1}
+  CollisionModule:
+    enabled: 0
+    serializedVersion: 3
+    type: 0
+    collisionMode: 0
+    colliderForce: 0
+    multiplyColliderForceByParticleSize: 0
+    multiplyColliderForceByParticleSpeed: 0
+    multiplyColliderForceByCollisionAngle: 1
+    plane0: {fileID: 0}
+    plane1: {fileID: 0}
+    plane2: {fileID: 0}
+    plane3: {fileID: 0}
+    plane4: {fileID: 0}
+    plane5: {fileID: 0}
+    m_Dampen:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_Bounce:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_EnergyLossOnCollision:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    minKillSpeed: 0
+    maxKillSpeed: 10000
+    radiusScale: 1
+    collidesWith:
+      serializedVersion: 2
+      m_Bits: 4294967295
+    maxCollisionShapes: 256
+    quality: 0
+    voxelSize: 0.5
+    collisionMessages: 0
+    collidesWithDynamic: 1
+    interiorCollisions: 1
+  TriggerModule:
+    enabled: 0
+    collisionShape0: {fileID: 0}
+    collisionShape1: {fileID: 0}
+    collisionShape2: {fileID: 0}
+    collisionShape3: {fileID: 0}
+    collisionShape4: {fileID: 0}
+    collisionShape5: {fileID: 0}
+    inside: 1
+    outside: 0
+    enter: 0
+    exit: 0
+    radiusScale: 1
+  SubModule:
+    serializedVersion: 2
+    enabled: 0
+    subEmitters:
+    - serializedVersion: 2
+      emitter: {fileID: 0}
+      type: 0
+      properties: 0
+  LightsModule:
+    enabled: 0
+    ratio: 0
+    light: {fileID: 0}
+    randomDistribution: 1
+    color: 1
+    range: 1
+    intensity: 1
+    rangeCurve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    intensityCurve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    maxLights: 20
+  TrailModule:
+    enabled: 0
+    mode: 0
+    ratio: 1
+    lifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    minVertexDistance: 0.2
+    textureMode: 0
+    ribbonCount: 1
+    worldSpace: 0
+    dieWithParticles: 1
+    sizeAffectsWidth: 1
+    sizeAffectsLifetime: 0
+    inheritParticleColor: 1
+    generateLightingData: 0
+    splitSubEmitterRibbons: 0
+    colorOverLifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    widthOverTrail:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    colorOverTrail:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+  CustomDataModule:
+    enabled: 0
+    mode0: 0
+    vectorComponentCount0: 4
+    color0:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    colorLabel0: Color
+    vector0_0:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_0: X
+    vector0_1:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_1: Y
+    vector0_2:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_2: Z
+    vector0_3:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_3: W
+    mode1: 0
+    vectorComponentCount1: 4
+    color1:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    colorLabel1: Color
+    vector1_0:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_0: X
+    vector1_1:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_1: Y
+    vector1_2:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_2: Z
+    vector1_3:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 2
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        - serializedVersion: 2
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_3: W
+--- !u!4 &585111786
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
+  m_LocalPosition: {x: 0.018887915, y: -2.0154846, z: 0.31905746}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 146069397}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &618633214
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 618633216}
+  - component: {fileID: 618633215}
+  m_Layer: 0
+  m_Name: AndroidMultipleDeviceSearch
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &618633215
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 618633214}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f09784c9d7dda9e4ba2602de24d73714, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  speedCadence: 1
+  cadence: 0
+  hr: 0
+  speed: 0
+  power: 0
+  fec: 0
+  podometer: 0
+  foundSpeedCadenceIDList: 
+  foundCadenceIDList: 
+  foundHrIDList: 
+  foundSpeedIDList: 
+  foundPowerIDList: 
+  foundFecIDList: 
+  debugText: {fileID: 1257719637}
+  spcadDisplay: {fileID: 1265953478}
+--- !u!4 &618633216
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 618633214}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 256.08218, y: 123.95456, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &671601685
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 671601688}
+  - component: {fileID: 671601687}
+  - component: {fileID: 671601686}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &671601686
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalAxis: Horizontal
+  m_VerticalAxis: Vertical
+  m_SubmitButton: Submit
+  m_CancelButton: Cancel
+  m_InputActionsPerSecond: 10
+  m_RepeatDelay: 0.5
+  m_ForceModuleActive: 0
+--- !u!114 &671601687
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 5
+--- !u!4 &671601688
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1084991488
+Prefab:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: m_RootOrder
+      value: 6
+      objectReference: {fileID: 0}
+    - target: {fileID: 11431856, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: autoStartScan
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 11431856, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: autoConnectToFirstSensorFound
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 11431856, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: useAndroidUI
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 11431856, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+      propertyPath: skipPreferredSearch
+      value: 0
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_ParentPrefab: {fileID: 100100000, guid: a3f535a0b46c67b4db23c71997200530, type: 2}
+  m_IsPrefabParent: 0
+--- !u!1 &1091122757
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1091122761}
+  - component: {fileID: 1091122760}
+  - component: {fileID: 1091122759}
+  - component: {fileID: 1091122758}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1091122758
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &1091122759
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 1
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+--- !u!223 &1091122760
+Canvas:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 0
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 25
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &1091122761
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_Children:
+  - {fileID: 407602309}
+  - {fileID: 1257719636}
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!1 &1257719635
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1257719636}
+  - component: {fileID: 1257719638}
+  - component: {fileID: 1257719637}
+  m_Layer: 5
+  m_Name: demoText (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1257719636
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1091122761}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: -186.9, y: -20}
+  m_SizeDelta: {x: -411, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1257719637
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 32
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 0
+    m_MaxSize: 82
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!222 &1257719638
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+--- !u!114 &1265953478 stripped
+MonoBehaviour:
+  m_PrefabParentObject: {fileID: 11431856, guid: a3f535a0b46c67b4db23c71997200530,
+    type: 2}
+  m_PrefabInternal: {fileID: 1084991488}
+  m_Script: {fileID: 11500000, guid: bfd3eeecc78c01f42b0d64b342772f67, type: 3}
+--- !u!1 &2035920753
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 2035920755}
+  - component: {fileID: 2035920754}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &2035920754
+Light:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2035920753}
+  m_Enabled: 1
+  serializedVersion: 8
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_Lightmapping: 4
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &2035920755
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2035920753}
+  m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &2102487668
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 2102487673}
+  - component: {fileID: 2102487672}
+  - component: {fileID: 2102487671}
+  - component: {fileID: 2102487670}
+  - component: {fileID: 2102487669}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &2102487669
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!124 &2102487670
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!92 &2102487671
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!20 &2102487672
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 2
+  m_BackGroundColor: {r: 0.5735294, g: 0.5735294, b: 0.5735294, a: 0.019607844}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 0
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &2102487673
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 8 - 0
Assets/AdvancedAnt/DEMO PREFABS/AntmultipleScan.unity.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 11b4afc9c641a1d4db42c41770798c9e
+timeCreated: 1491558933
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 93 - 0
Assets/AdvancedAnt/DEMO PREFABS/PrefabDemoDisplay.cs

@@ -0,0 +1,93 @@
+using UnityEngine;
+using System.Collections;
+using UnityEngine.UI;
+
+public class PrefabDemoDisplay : MonoBehaviour {
+
+    public Text uiText;
+    public GameObject BikeTrainerButtons;
+
+    // Use this for initialization
+    void Start() {
+      
+    }
+
+    // Update is called once per frame
+    void Update() {
+        uiText.text = "";
+
+        if (GameObject.Find("CadenceDisplay")) {
+            uiText.text = "Cadence sensor - is connected ? " + GameObject.Find("CadenceDisplay").GetComponent<CadenceDisplay>().connected + "\n";
+            uiText.text += "cadence: " + GameObject.Find("CadenceDisplay").GetComponent<CadenceDisplay>().cadence + "\n";
+            uiText.text += "----------------------------------------------\n";
+        }
+        if (GameObject.Find("SpeedCadenceDisplay")) {
+            uiText.text += "SpeedCadence sensor - is connected ? " + GameObject.Find("SpeedCadenceDisplay").GetComponent<SpeedCadenceDisplay>().connected + "\n";
+            uiText.text += "cadence = " + GameObject.Find("SpeedCadenceDisplay").GetComponent<SpeedCadenceDisplay>().cadence +"\n";
+            uiText.text += "speed = " + GameObject.Find("SpeedCadenceDisplay").GetComponent<SpeedCadenceDisplay>().speed + "\n";
+            uiText.text += "distance = " + GameObject.Find("SpeedCadenceDisplay").GetComponent<SpeedCadenceDisplay>().distance + "\n";
+            uiText.text += "----------------------------------------------\n";
+        }
+        if (GameObject.Find("HeartRateDisplay")) {
+            uiText.text += "Heart rate sensor - is connected ? " + GameObject.Find("HeartRateDisplay").GetComponent<HeartRateDisplay>().connected + "\n";
+            uiText.text += "HR = " + GameObject.Find("HeartRateDisplay").GetComponent<HeartRateDisplay>().heartRate + "\n";
+            uiText.text += "----------------------------------------------\n";
+        }
+        if (GameObject.Find("SpeedDisplay")) {
+            uiText.text += "Speed sensor - is connected ? " + GameObject.Find("SpeedDisplay").GetComponent<SpeedDisplay>().connected + "\n";
+            uiText.text += "speed = " + GameObject.Find("SpeedDisplay").GetComponent<SpeedDisplay>().speed + "\n";
+            uiText.text += "distance = " + GameObject.Find("SpeedDisplay").GetComponent<SpeedDisplay>().distance + "\n";
+            uiText.text += "----------------------------------------------\n";
+        }
+        if (GameObject.Find("PowerMeterDisplay")) {
+            uiText.text += "Power sensor - is connected ? " + GameObject.Find("PowerMeterDisplay").GetComponent<PowerMeterDisplay>().connected + "\n";
+            uiText.text += "power = " + GameObject.Find("PowerMeterDisplay").GetComponent<PowerMeterDisplay>().instantaneousPower + "\n";
+            uiText.text += "cadence = " + GameObject.Find("PowerMeterDisplay").GetComponent<PowerMeterDisplay>().instantaneousCadence + "\n";
+           
+            uiText.text += "----------------------------------------------\n";
+        }
+        if (GameObject.Find("FitnessEquipmentDisplay")) {
+            BikeTrainerButtons.SetActive(true);
+            uiText.text += "Fitness E: - is connected ? " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().connected + "\n";
+            uiText.text += "power = " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().instantaneousPower + "\n";
+            uiText.text += "speed= " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().speed + "\n";
+            uiText.text += "elapsedTime= " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().elapsedTime + "\n";
+            uiText.text += "heartRate= " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().heartRate + "\n";
+            uiText.text += "distanceTraveled= " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().distanceTraveled + "\n";
+            uiText.text += "cadence= " + GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().cadence + "\n";
+
+            uiText.text += "----------------------------------------------\n";
+        }
+
+    }
+
+    public void FitnessButton1() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerResistance(0);
+    }
+    public void FitnessButton2() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerResistance(50);
+    }
+    public void FitnessButton3() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerResistance(100);
+    }
+    public void FitnessButton4() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().RequestTrainerCapabilities();
+    }
+    public void FitnessButton5() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerUserConfiguration(10, 80); //set the user weight
+    }
+    public void FitnessButton6() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerTargetPower(200); // set the target power in watt
+    }
+    public void FitnessButton7() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().SetTrainerSlope(5); //set the trainer simulation slope in % (grade) between -200 & 200%
+    }
+    public void FitnessButton8() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().RequestCommandStatus();
+    }
+    public void FitnessButton9() {
+        GameObject.Find("FitnessEquipmentDisplay").GetComponent<FitnessEquipmentDisplay>().RequestUserConfig();
+    }
+
+}
+

+ 12 - 0
Assets/AdvancedAnt/DEMO PREFABS/PrefabDemoDisplay.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b96146adbbf118c47a3d9ba6cc0d6b40
+timeCreated: 1475308017
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7743 - 0
Assets/AdvancedAnt/DEMO PREFABS/demowithPrefabs.unity

@@ -0,0 +1,7743 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 0
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 1024
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 1
+    m_BakeBackend: 0
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 500
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 0
+    m_PVRDenoiserTypeDirect: 0
+    m_PVRDenoiserTypeIndirect: 0
+    m_PVRDenoiserTypeAO: 0
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 0
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+    m_ExportTrainingData: 0
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 0
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &86658462
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 86658463}
+  - component: {fileID: 86658465}
+  - component: {fileID: 86658464}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &86658463
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 86658462}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 9
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 293, y: 257}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &86658464
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 86658462}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: FE CONTROLS
+--- !u!222 &86658465
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 86658462}
+  m_CullTransparentMesh: 0
+--- !u!1 &146069396
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 146069397}
+  - component: {fileID: 146069398}
+  m_Layer: 0
+  m_Name: Demo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &146069397
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 146069396}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 585111786}
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &146069398
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 146069396}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b96146adbbf118c47a3d9ba6cc0d6b40, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  uiText: {fileID: 407602310}
+  BikeTrainerButtons: {fileID: 1536744243}
+--- !u!1 &213599758
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 213599759}
+  - component: {fileID: 213599761}
+  - component: {fileID: 213599760}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &213599759
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 213599758}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1560750837}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &213599760
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 213599758}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Set resistance 50%
+--- !u!222 &213599761
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 213599758}
+  m_CullTransparentMesh: 0
+--- !u!1001 &223751295
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 171496, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_IsActive
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+      propertyPath: m_RootOrder
+      value: 7
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: 209022afdf8ea844cab71dc93643ee02, type: 3}
+--- !u!1 &356804120
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 356804121}
+  - component: {fileID: 356804124}
+  - component: {fileID: 356804123}
+  - component: {fileID: 356804122}
+  m_Layer: 5
+  m_Name: Button (5)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &356804121
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 356804120}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1761775220}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259, y: 66}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &356804122
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 356804120}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 356804123}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton6
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &356804123
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 356804120}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &356804124
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 356804120}
+  m_CullTransparentMesh: 0
+--- !u!1 &407602308
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 407602309}
+  - component: {fileID: 407602311}
+  - component: {fileID: 407602310}
+  m_Layer: 5
+  m_Name: demoText
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &407602309
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1091122761}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: -186.9, y: -47.1}
+  m_SizeDelta: {x: -411, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &407602310
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 32
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 0
+    m_MaxSize: 82
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 'Enable the gameObjects you would like to use
+
+'
+--- !u!222 &407602311
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 407602308}
+  m_CullTransparentMesh: 0
+--- !u!1 &508151421
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 508151422}
+  - component: {fileID: 508151425}
+  - component: {fileID: 508151424}
+  - component: {fileID: 508151423}
+  m_Layer: 5
+  m_Name: Button (8)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &508151422
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 508151421}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1257649300}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 8
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259, y: -62.7}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &508151423
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 508151421}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 508151424}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton9
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &508151424
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 508151421}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &508151425
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 508151421}
+  m_CullTransparentMesh: 0
+--- !u!1001 &581975400
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 171496, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_IsActive
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+      propertyPath: m_RootOrder
+      value: 9
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: a282f737de9dc2d4c9dfdcac21ce4da2, type: 3}
+--- !u!1 &585111783
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 585111786}
+  - component: {fileID: 585111785}
+  - component: {fileID: 585111784}
+  m_Layer: 0
+  m_Name: Particle System
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!199 &585111784
+ParticleSystemRenderer:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 0
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10301, guid: 0000000000000000f000000000000000, type: 0}
+  - {fileID: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_RenderMode: 0
+  m_SortMode: 0
+  m_MinParticleSize: 0
+  m_MaxParticleSize: 0.5
+  m_CameraVelocityScale: 0
+  m_VelocityScale: 0
+  m_LengthScale: 2
+  m_SortingFudge: 0
+  m_NormalDirection: 1
+  m_ShadowBias: 0
+  m_RenderAlignment: 0
+  m_Pivot: {x: 0, y: 0, z: 0}
+  m_Flip: {x: 0, y: 0, z: 0}
+  m_UseCustomVertexStreams: 0
+  m_EnableGPUInstancing: 0
+  m_ApplyActiveColorSpace: 0
+  m_AllowRoll: 1
+  m_VertexStreams: 0001030405
+  m_Mesh: {fileID: 0}
+  m_Mesh1: {fileID: 0}
+  m_Mesh2: {fileID: 0}
+  m_Mesh3: {fileID: 0}
+  m_MaskInteraction: 0
+--- !u!198 &585111785
+ParticleSystem:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  serializedVersion: 6
+  lengthInSec: 5
+  simulationSpeed: 1
+  stopAction: 0
+  cullingMode: 1
+  ringBufferMode: 0
+  ringBufferLoopRange: {x: 0, y: 1}
+  looping: 1
+  prewarm: 0
+  playOnAwake: 1
+  useUnscaledTime: 0
+  autoRandomSeed: 1
+  useRigidbodyForVelocity: 1
+  startDelay:
+    serializedVersion: 2
+    minMaxState: 0
+    scalar: 0
+    minScalar: 0
+    maxCurve:
+      serializedVersion: 2
+      m_Curve:
+      - serializedVersion: 3
+        time: 0
+        value: 1
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0.33333334
+        outWeight: 0.33333334
+      - serializedVersion: 3
+        time: 1
+        value: 1
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0.33333334
+        outWeight: 0.33333334
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+    minCurve:
+      serializedVersion: 2
+      m_Curve:
+      - serializedVersion: 3
+        time: 0
+        value: 0
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0.33333334
+        outWeight: 0.33333334
+      - serializedVersion: 3
+        time: 1
+        value: 0
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0.33333334
+        outWeight: 0.33333334
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+  moveWithTransform: 0
+  moveWithCustomTransform: {fileID: 0}
+  scalingMode: 1
+  randomSeed: 0
+  InitialModule:
+    serializedVersion: 3
+    enabled: 1
+    startLifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 5
+      minScalar: 5
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSpeed:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 5
+      minScalar: 5
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startColor:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    startSize:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSizeY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startSizeZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotationX:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotationY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startRotation:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    randomizeRotationDirection: 0
+    maxNumParticles: 1000
+    size3D: 0
+    rotation3D: 0
+    gravityModifier:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  ShapeModule:
+    serializedVersion: 6
+    enabled: 1
+    type: 4
+    angle: 25
+    length: 5
+    boxThickness: {x: 0, y: 0, z: 0}
+    radiusThickness: 1
+    donutRadius: 0.2
+    m_Position: {x: 0, y: 0, z: 0}
+    m_Rotation: {x: 0, y: 0, z: 0}
+    m_Scale: {x: 1, y: 1, z: 1}
+    placementMode: 0
+    m_MeshMaterialIndex: 0
+    m_MeshNormalOffset: 0
+    m_MeshSpawn:
+      mode: 0
+      spread: 0
+      speed:
+        serializedVersion: 2
+        minMaxState: 0
+        scalar: 1
+        minScalar: 1
+        maxCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+        minCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+    m_Mesh: {fileID: 0}
+    m_MeshRenderer: {fileID: 0}
+    m_SkinnedMeshRenderer: {fileID: 0}
+    m_Sprite: {fileID: 0}
+    m_SpriteRenderer: {fileID: 0}
+    m_UseMeshMaterialIndex: 0
+    m_UseMeshColors: 1
+    alignToDirection: 0
+    m_Texture: {fileID: 0}
+    m_TextureClipChannel: 3
+    m_TextureClipThreshold: 0
+    m_TextureUVChannel: 0
+    m_TextureColorAffectsParticles: 1
+    m_TextureAlphaAffectsParticles: 1
+    m_TextureBilinearFiltering: 0
+    randomDirectionAmount: 0
+    sphericalDirectionAmount: 0
+    randomPositionAmount: 0
+    radius:
+      value: 1
+      mode: 0
+      spread: 0
+      speed:
+        serializedVersion: 2
+        minMaxState: 0
+        scalar: 1
+        minScalar: 1
+        maxCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+        minCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+    arc:
+      value: 360
+      mode: 0
+      spread: 0
+      speed:
+        serializedVersion: 2
+        minMaxState: 0
+        scalar: 1
+        minScalar: 1
+        maxCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+        minCurve:
+          serializedVersion: 2
+          m_Curve:
+          - serializedVersion: 3
+            time: 0
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          - serializedVersion: 3
+            time: 1
+            value: 1
+            inSlope: 0
+            outSlope: 0
+            tangentMode: 0
+            weightedMode: 0
+            inWeight: 0.33333334
+            outWeight: 0.33333334
+          m_PreInfinity: 2
+          m_PostInfinity: 2
+          m_RotationOrder: 4
+  EmissionModule:
+    enabled: 1
+    serializedVersion: 4
+    rateOverTime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 10
+      minScalar: 10
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    rateOverDistance:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_BurstCount: 0
+    m_Bursts: []
+  SizeModule:
+    enabled: 0
+    curve:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+  RotationModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0.7853982
+      minScalar: 0.7853982
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+  ColorModule:
+    enabled: 0
+    gradient:
+      serializedVersion: 2
+      minMaxState: 1
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+  UVModule:
+    serializedVersion: 2
+    enabled: 0
+    mode: 0
+    timeMode: 0
+    fps: 30
+    frameOverTime:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 0.9999
+      minScalar: 0.9999
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 1
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 1
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 1
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 1
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    startFrame:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    speedRange: {x: 0, y: 1}
+    tilesX: 1
+    tilesY: 1
+    animationType: 0
+    rowIndex: 0
+    cycles: 1
+    uvChannelMask: -1
+    rowMode: 1
+    sprites:
+    - sprite: {fileID: 0}
+    flipU: 0
+    flipV: 0
+  VelocityModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalX:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalOffsetX:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalOffsetY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    orbitalOffsetZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    radial:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    speedModifier:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    inWorldSpace: 0
+  InheritVelocityModule:
+    enabled: 0
+    m_Mode: 0
+    m_Curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  ForceModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    inWorldSpace: 0
+    randomizePerFrame: 0
+  ExternalForcesModule:
+    serializedVersion: 2
+    enabled: 0
+    multiplierCurve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    influenceFilter: 0
+    influenceMask:
+      serializedVersion: 2
+      m_Bits: 4294967295
+    influenceList: []
+  ClampVelocityModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    magnitude:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxis: 0
+    inWorldSpace: 0
+    multiplyDragByParticleSize: 1
+    multiplyDragByParticleVelocity: 1
+    dampen: 1
+    drag:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  NoiseModule:
+    enabled: 0
+    strength:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    strengthY:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    strengthZ:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+    frequency: 0.5
+    damping: 1
+    octaves: 1
+    octaveMultiplier: 0.5
+    octaveScale: 2
+    quality: 2
+    scrollSpeed:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remap:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapY:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapZ:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: -1
+          inSlope: 0
+          outSlope: 2
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 2
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    remapEnabled: 0
+    positionAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    rotationAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    sizeAmount:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+  SizeBySpeedModule:
+    enabled: 0
+    curve:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    z:
+      serializedVersion: 2
+      minMaxState: 1
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    range: {x: 0, y: 1}
+    separateAxes: 0
+  RotationBySpeedModule:
+    enabled: 0
+    x:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    y:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    curve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0.7853982
+      minScalar: 0.7853982
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    separateAxes: 0
+    range: {x: 0, y: 1}
+  ColorBySpeedModule:
+    enabled: 0
+    gradient:
+      serializedVersion: 2
+      minMaxState: 1
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    range: {x: 0, y: 1}
+  CollisionModule:
+    enabled: 0
+    serializedVersion: 3
+    type: 0
+    collisionMode: 0
+    colliderForce: 0
+    multiplyColliderForceByParticleSize: 0
+    multiplyColliderForceByParticleSpeed: 0
+    multiplyColliderForceByCollisionAngle: 1
+    plane0: {fileID: 0}
+    plane1: {fileID: 0}
+    plane2: {fileID: 0}
+    plane3: {fileID: 0}
+    plane4: {fileID: 0}
+    plane5: {fileID: 0}
+    m_Dampen:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_Bounce:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    m_EnergyLossOnCollision:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    minKillSpeed: 0
+    maxKillSpeed: 10000
+    radiusScale: 1
+    collidesWith:
+      serializedVersion: 2
+      m_Bits: 4294967295
+    maxCollisionShapes: 256
+    quality: 0
+    voxelSize: 0.5
+    collisionMessages: 0
+    collidesWithDynamic: 1
+    interiorCollisions: 1
+  TriggerModule:
+    enabled: 0
+    collisionShape0: {fileID: 0}
+    collisionShape1: {fileID: 0}
+    collisionShape2: {fileID: 0}
+    collisionShape3: {fileID: 0}
+    collisionShape4: {fileID: 0}
+    collisionShape5: {fileID: 0}
+    inside: 1
+    outside: 0
+    enter: 0
+    exit: 0
+    radiusScale: 1
+  SubModule:
+    serializedVersion: 2
+    enabled: 0
+    subEmitters:
+    - serializedVersion: 3
+      emitter: {fileID: 0}
+      type: 0
+      properties: 0
+      emitProbability: 1
+  LightsModule:
+    enabled: 0
+    ratio: 0
+    light: {fileID: 0}
+    randomDistribution: 1
+    color: 1
+    range: 1
+    intensity: 1
+    rangeCurve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    intensityCurve:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    maxLights: 20
+  TrailModule:
+    enabled: 0
+    mode: 0
+    ratio: 1
+    lifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    minVertexDistance: 0.2
+    textureMode: 0
+    ribbonCount: 1
+    shadowBias: 0.5
+    worldSpace: 0
+    dieWithParticles: 1
+    sizeAffectsWidth: 1
+    sizeAffectsLifetime: 0
+    inheritParticleColor: 1
+    generateLightingData: 0
+    splitSubEmitterRibbons: 0
+    attachRibbonsToTransform: 0
+    colorOverLifetime:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    widthOverTrail:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 1
+      minScalar: 1
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 1
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    colorOverTrail:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+  CustomDataModule:
+    enabled: 0
+    mode0: 0
+    vectorComponentCount0: 4
+    color0:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    colorLabel0: Color
+    vector0_0:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_0: X
+    vector0_1:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_1: Y
+    vector0_2:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_2: Z
+    vector0_3:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel0_3: W
+    mode1: 0
+    vectorComponentCount1: 4
+    color1:
+      serializedVersion: 2
+      minMaxState: 0
+      minColor: {r: 1, g: 1, b: 1, a: 1}
+      maxColor: {r: 1, g: 1, b: 1, a: 1}
+      maxGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+      minGradient:
+        serializedVersion: 2
+        key0: {r: 1, g: 1, b: 1, a: 1}
+        key1: {r: 1, g: 1, b: 1, a: 1}
+        key2: {r: 0, g: 0, b: 0, a: 0}
+        key3: {r: 0, g: 0, b: 0, a: 0}
+        key4: {r: 0, g: 0, b: 0, a: 0}
+        key5: {r: 0, g: 0, b: 0, a: 0}
+        key6: {r: 0, g: 0, b: 0, a: 0}
+        key7: {r: 0, g: 0, b: 0, a: 0}
+        ctime0: 0
+        ctime1: 65535
+        ctime2: 0
+        ctime3: 0
+        ctime4: 0
+        ctime5: 0
+        ctime6: 0
+        ctime7: 0
+        atime0: 0
+        atime1: 65535
+        atime2: 0
+        atime3: 0
+        atime4: 0
+        atime5: 0
+        atime6: 0
+        atime7: 0
+        m_Mode: 0
+        m_NumColorKeys: 2
+        m_NumAlphaKeys: 2
+    colorLabel1: Color
+    vector1_0:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_0: X
+    vector1_1:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_1: Y
+    vector1_2:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_2: Z
+    vector1_3:
+      serializedVersion: 2
+      minMaxState: 0
+      scalar: 0
+      minScalar: 0
+      maxCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+      minCurve:
+        serializedVersion: 2
+        m_Curve:
+        - serializedVersion: 3
+          time: 0
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        - serializedVersion: 3
+          time: 1
+          value: 0
+          inSlope: 0
+          outSlope: 0
+          tangentMode: 0
+          weightedMode: 0
+          inWeight: 0.33333334
+          outWeight: 0.33333334
+        m_PreInfinity: 2
+        m_PostInfinity: 2
+        m_RotationOrder: 4
+    vectorLabel1_3: W
+--- !u!4 &585111786
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 585111783}
+  m_LocalRotation: {x: -0.7071068, y: 0, z: 0, w: 0.7071068}
+  m_LocalPosition: {x: 0.018887915, y: -2.0154846, z: 0.31905746}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 146069397}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &600985749
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 600985750}
+  - component: {fileID: 600985753}
+  - component: {fileID: 600985752}
+  - component: {fileID: 600985751}
+  m_Layer: 5
+  m_Name: Button
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &600985750
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 600985749}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 2057833860}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 1, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 209, y: 274}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &600985751
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 600985749}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 600985752}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton1
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &600985752
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 600985749}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &600985753
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 600985749}
+  m_CullTransparentMesh: 0
+--- !u!1 &619521812
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 619521813}
+  - component: {fileID: 619521815}
+  - component: {fileID: 619521814}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &619521813
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 619521812}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 789534365}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &619521814
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 619521812}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: RequestCapabilies
+--- !u!222 &619521815
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 619521812}
+  m_CullTransparentMesh: 0
+--- !u!1 &671601685
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 671601688}
+  - component: {fileID: 671601687}
+  - component: {fileID: 671601686}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &671601686
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalAxis: Horizontal
+  m_VerticalAxis: Vertical
+  m_SubmitButton: Submit
+  m_CancelButton: Cancel
+  m_InputActionsPerSecond: 10
+  m_RepeatDelay: 0.5
+  m_ForceModuleActive: 0
+--- !u!114 &671601687
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 5
+--- !u!4 &671601688
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 671601685}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &774828450
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 774828451}
+  - component: {fileID: 774828454}
+  - component: {fileID: 774828453}
+  - component: {fileID: 774828452}
+  m_Layer: 5
+  m_Name: Button (2)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &774828451
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 774828450}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 2062265444}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 260, y: 196}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &774828452
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 774828450}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 774828453}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton3
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &774828453
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 774828450}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &774828454
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 774828450}
+  m_CullTransparentMesh: 0
+--- !u!1 &789534364
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 789534365}
+  - component: {fileID: 789534368}
+  - component: {fileID: 789534367}
+  - component: {fileID: 789534366}
+  m_Layer: 5
+  m_Name: Button (3)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &789534365
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 789534364}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 619521813}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259, y: 155}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &789534366
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 789534364}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 789534367}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton4
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &789534367
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 789534364}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &789534368
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 789534364}
+  m_CullTransparentMesh: 0
+--- !u!1 &1091122757
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1091122761}
+  - component: {fileID: 1091122760}
+  - component: {fileID: 1091122759}
+  - component: {fileID: 1091122758}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1091122758
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &1091122759
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 1
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+--- !u!223 &1091122760
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 0
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_AdditionalShaderChannelsFlag: 25
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &1091122761
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1091122757}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_Children:
+  - {fileID: 407602309}
+  - {fileID: 1536744244}
+  - {fileID: 1257719636}
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!1 &1099291645
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1099291646}
+  - component: {fileID: 1099291648}
+  - component: {fileID: 1099291647}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1099291646
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1099291645}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1485915438}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1099291647
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1099291645}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'set user config
+
+'
+--- !u!222 &1099291648
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1099291645}
+  m_CullTransparentMesh: 0
+--- !u!1001 &1236522443
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 194424, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 497196, guid: 8b33d739087398741af407a1f2592745, type: 3}
+      propertyPath: m_RootOrder
+      value: 6
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: 8b33d739087398741af407a1f2592745, type: 3}
+--- !u!1 &1257649299
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1257649300}
+  - component: {fileID: 1257649302}
+  - component: {fileID: 1257649301}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1257649300
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257649299}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 508151422}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1257649301
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257649299}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'request userConfig
+
+
+'
+--- !u!222 &1257649302
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257649299}
+  m_CullTransparentMesh: 0
+--- !u!1 &1257719635
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1257719636}
+  - component: {fileID: 1257719638}
+  - component: {fileID: 1257719637}
+  m_Layer: 5
+  m_Name: demoText (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1257719636
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1091122761}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: -186.9, y: -97}
+  m_SizeDelta: {x: -411, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1257719637
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 32
+    m_FontStyle: 0
+    m_BestFit: 1
+    m_MinSize: 0
+    m_MaxSize: 82
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 0
+    m_HorizontalOverflow: 1
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!222 &1257719638
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1257719635}
+  m_CullTransparentMesh: 0
+--- !u!1001 &1345430471
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 171496, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_IsActive
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 497154, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+      propertyPath: m_RootOrder
+      value: 8
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: ed770e63cef19c243aa53f1ff2367659, type: 3}
+--- !u!1 &1395066054
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1395066055}
+  - component: {fileID: 1395066057}
+  - component: {fileID: 1395066056}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1395066055
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1395066054}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1682861826}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1395066056
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1395066054}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'set slope
+
+'
+--- !u!222 &1395066057
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1395066054}
+  m_CullTransparentMesh: 0
+--- !u!1 &1485915437
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1485915438}
+  - component: {fileID: 1485915441}
+  - component: {fileID: 1485915440}
+  - component: {fileID: 1485915439}
+  m_Layer: 5
+  m_Name: Button (4)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1485915438
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1485915437}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1099291646}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259.8, y: 112.7}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1485915439
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1485915437}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1485915440}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton5
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1485915440
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1485915437}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &1485915441
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1485915437}
+  m_CullTransparentMesh: 0
+--- !u!1 &1536744243
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1536744244}
+  m_Layer: 5
+  m_Name: FitnessButtons
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &1536744244
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1536744243}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 600985750}
+  - {fileID: 1560750837}
+  - {fileID: 774828451}
+  - {fileID: 789534365}
+  - {fileID: 1485915438}
+  - {fileID: 356804121}
+  - {fileID: 1682861826}
+  - {fileID: 1566511614}
+  - {fileID: 508151422}
+  - {fileID: 86658463}
+  m_Father: {fileID: 1091122761}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 100, y: 100}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1560750836
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1560750837}
+  - component: {fileID: 1560750840}
+  - component: {fileID: 1560750839}
+  - component: {fileID: 1560750838}
+  m_Layer: 5
+  m_Name: Button (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1560750837
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1560750836}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 213599759}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 309, y: 236}
+  m_SizeDelta: {x: 160, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1560750838
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1560750836}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1560750839}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton2
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1560750839
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1560750836}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &1560750840
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1560750836}
+  m_CullTransparentMesh: 0
+--- !u!1 &1566511613
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1566511614}
+  - component: {fileID: 1566511617}
+  - component: {fileID: 1566511616}
+  - component: {fileID: 1566511615}
+  m_Layer: 5
+  m_Name: Button (7)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1566511614
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566511613}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1888222092}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 7
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259, y: -21.9}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1566511615
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566511613}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1566511616}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton8
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1566511616
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566511613}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &1566511617
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566511613}
+  m_CullTransparentMesh: 0
+--- !u!1 &1682861825
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1682861826}
+  - component: {fileID: 1682861829}
+  - component: {fileID: 1682861828}
+  - component: {fileID: 1682861827}
+  m_Layer: 5
+  m_Name: Button (6)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1682861826
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1682861825}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1395066055}
+  m_Father: {fileID: 1536744244}
+  m_RootOrder: 6
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 0}
+  m_AnchoredPosition: {x: 259, y: 23.8}
+  m_SizeDelta: {x: 60, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1682861827
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1682861825}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Highlighted
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1682861828}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 146069398}
+        m_MethodName: FitnessButton7
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1682861828
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1682861825}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+--- !u!222 &1682861829
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1682861825}
+  m_CullTransparentMesh: 0
+--- !u!1001 &1748731146
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 100080, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 494254, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+      propertyPath: m_RootOrder
+      value: 5
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: a3f535a0b46c67b4db23c71997200530, type: 3}
+--- !u!1 &1761775219
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1761775220}
+  - component: {fileID: 1761775222}
+  - component: {fileID: 1761775221}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1761775220
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1761775219}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 356804121}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1761775221
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1761775219}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'set targetpower
+
+'
+--- !u!222 &1761775222
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1761775219}
+  m_CullTransparentMesh: 0
+--- !u!1 &1888222091
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1888222092}
+  - component: {fileID: 1888222094}
+  - component: {fileID: 1888222093}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1888222092
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1888222091}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1566511614}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1888222093
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1888222091}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 'request command status
+
+'
+--- !u!222 &1888222094
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1888222091}
+  m_CullTransparentMesh: 0
+--- !u!1 &2035920753
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2035920755}
+  - component: {fileID: 2035920754}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &2035920754
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2035920753}
+  m_Enabled: 1
+  serializedVersion: 9
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &2035920755
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2035920753}
+  m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &2057833859
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2057833860}
+  - component: {fileID: 2057833862}
+  - component: {fileID: 2057833861}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2057833860
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2057833859}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 600985750}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2057833861
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2057833859}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Set resistance 0%
+--- !u!222 &2057833862
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2057833859}
+  m_CullTransparentMesh: 0
+--- !u!1 &2062265443
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2062265444}
+  - component: {fileID: 2062265446}
+  - component: {fileID: 2062265445}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2062265444
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2062265443}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 774828451}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2062265445
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2062265443}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Set resistance 100%
+--- !u!222 &2062265446
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2062265443}
+  m_CullTransparentMesh: 0
+--- !u!1001 &2066773518
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 117568, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_IsActive
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 407298, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+      propertyPath: m_RootOrder
+      value: 10
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: c7b523a939558ef459cd126cd5f73cb5, type: 3}
+--- !u!1 &2102487668
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2102487673}
+  - component: {fileID: 2102487672}
+  - component: {fileID: 2102487671}
+  - component: {fileID: 2102487670}
+  - component: {fileID: 2102487669}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &2102487669
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!124 &2102487670
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!92 &2102487671
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+--- !u!20 &2102487672
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 2
+  m_BackGroundColor: {r: 0.36764705, g: 0.36764705, b: 0.36764705, a: 0.019607844}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_FocalLength: 50
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 0
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &2102487673
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2102487668}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 8 - 0
Assets/AdvancedAnt/DEMO PREFABS/demowithPrefabs.unity.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c86722469b2c9074dacfd799cc064c0c
+timeCreated: 1475308305
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 61 - 0
Assets/AdvancedAnt/PC_MAC_readme.txt

@@ -0,0 +1,61 @@
+ADVANCED ANT+ FOR UNITY
+
+*** using the ANT library on windows and macOS
+
+To Get started you need to sign up on thisisant.com and become a ANT+ Adopter for devices documentation and network key
+
+To obtain the network key:
+Register https://www.thisisant.com/register/
+Once your basic user account is activated, login and go to your MyANT+ page  https://www.thisisant.com/my-ant to add ANT+ Adopter
+Next search "Network Keys" on thisisant.com, we want the first key on the txt
+
+The key must be set in AntManager.cs ==>replace  readonly byte[] NETWORK_KEY = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+For more info about ANT+ https://www.thisisant.com/developer/ant-plus/ant-plus-basics/
+
+USAGE
+
+1. Init the device, this is you usb2 or usb-m dongle
+AntManager.Instance.Init();
+
+2. Subscribe to device event
+AntManager.Instance.onDeviceResponse += OnDeviceResponse;  
+   
+3. Open a channel with device configuration
+AntManager.Instance.OpenChannel(...);
+
+4. Subscribe to response and data event
+myChannel.onReceiveData += ReceivedAntData;
+myChannel.onChannelResponse += OnChannelResponse;
+
+
+A detailed example is available in the antDemo.cs file
+
+Device settings are found on thisisant.com 
+example: ANT_Device_Profile_Heart_Rate_Monitor.pdf 
+
+
+
+FAQ
+
+- How do I configure a channel to connect to a HR SENSOR ?
+To read data from an HR sensor the correct configuration as found in ANT+_Device_Profile_-_Heart_Rate_Rev_2.00.pdf page 11 ont thisisant.com
+ AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 2, 0, 120, 0, 57, 8070, false); 
+ the instantaneous HR is on data[7].
+ 
+ -How to get data from a power Meter ?
+ Settings found in ANT+_Device_Profile_-_Bicycle_Power_-_Rev4.2.pdf page 19
+ powerDisplay = AntManager.Instance.OpenChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 2, 0, 11, 0, 57, 8182, false); 
+ then in the data event method, as described in page 31 for Instantaneous Power
+ int power= (data[6]) | data[7] << 8;
+ 
+ -How can I auto connect to multiple bike speed sensor ?
+ have a look at the MultiBikeSpeedDisplayExample.cs and demo scene. We create a Bike Display class and open a new channel everytime the background scan finds a sensor of the correct type.
+
+ -Why do I get RX Fail messages ?
+ Lots of rx fails means the channel period is wrong. Otherwise it is normal to have some amount of rx fails. You can now turn the log off with mychannel.hideRXFAIL = true
+
+ -What are extended info ?
+ you will find the info related to the background search extended data in this file:
+https://www.thisisant.com/resources/ant-message-protocol-and-usage/
+Page 35 of 134 

+ 8 - 0
Assets/AdvancedAnt/PC_MAC_readme.txt.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a9ac76fde3a22b248b42f4697690fe60
+timeCreated: 1458020786
+licenseType: Store
+TextScriptImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e9e3736edb6fa314e8507fc1bc904388
+folderAsset: yes
+timeCreated: 1456991390
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Android.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d06b96b45585c1a408155277325b7529
+folderAsset: yes
+timeCreated: 1475310455
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/AdvancedAnt/Plugins/Android/AndroidManifest.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" android:installLocation="preferExternal" android:versionName="1.0" android:versionCode="1">
+
+  <supports-screens
+       android:smallScreens="true"
+       android:normalScreens="true"
+       android:largeScreens="true"
+       android:xlargeScreens="true"
+       android:anyDensity="true"/>
+
+  <application
+     android:theme="@style/UnityThemeSelector"
+     android:icon="@drawable/app_icon"
+         android:label="@string/app_name"
+         android:debuggable="true">
+   
+
+    <activity android:name="com.ant.plugin.Ant_Connector" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" >
+      <meta-data android:name="android.app.lib_name" android:value="unity" />
+      <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
+    </activity>
+
+    <service android:enabled="true" android:name="com.ant.plugin.Service_BikeCadence"/>
+    <service android:enabled="true" android:name="com.ant.plugin.Service_HeartRate"/>
+    <service android:enabled="true" android:name="com.ant.plugin.Service_Speed"/>
+    <service android:enabled="true" android:name="com.ant.plugin.Service_Power"/>
+    <service android:enabled="true" android:name="com.ant.plugin.Service_Fitness"/>
+    <service android:enabled="true" android:name="com.ant.plugin.Service_MultiDeviceSearch"/>
+
+  </application>
+</manifest>

+ 8 - 0
Assets/AdvancedAnt/Plugins/Android/AndroidManifest.xml.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b7fa9f27616eeb54188a8819b25d108e
+timeCreated: 1475486774
+licenseType: Store
+TextScriptImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AdvancedAnt/Plugins/Android/AntUnity.jar


+ 23 - 0
Assets/AdvancedAnt/Plugins/Android/AntUnity.jar.meta

@@ -0,0 +1,23 @@
+fileFormatVersion: 2
+guid: f20b44c806c98d14db80cd9f1bd77ba1
+timeCreated: 1475250802
+licenseType: Store
+PluginImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  platformData:
+    Android:
+      enabled: 1
+      settings: {}
+    Any:
+      enabled: 0
+      settings: {}
+    Editor:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AdvancedAnt/Plugins/Android/android-support-v4.jar


+ 23 - 0
Assets/AdvancedAnt/Plugins/Android/android-support-v4.jar.meta

@@ -0,0 +1,23 @@
+fileFormatVersion: 2
+guid: 8c587042b3c6bf248a3868912c7d2dc8
+timeCreated: 1475650105
+licenseType: Store
+PluginImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  platformData:
+    Android:
+      enabled: 1
+      settings: {}
+    Any:
+      enabled: 0
+      settings: {}
+    Editor:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AdvancedAnt/Plugins/Android/antpluginlib_3-5-0.jar


+ 23 - 0
Assets/AdvancedAnt/Plugins/Android/antpluginlib_3-5-0.jar.meta

@@ -0,0 +1,23 @@
+fileFormatVersion: 2
+guid: 48f2fce6f308b754994e494505798409
+timeCreated: 1475650105
+licenseType: Store
+PluginImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  platformData:
+    Android:
+      enabled: 1
+      settings: {}
+    Any:
+      enabled: 0
+      settings: {}
+    Editor:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AdvancedAnt/Plugins/Android/fit_14.10.jar


+ 23 - 0
Assets/AdvancedAnt/Plugins/Android/fit_14.10.jar.meta

@@ -0,0 +1,23 @@
+fileFormatVersion: 2
+guid: 6fbf24a7b7c0ced498d8c9ac45782607
+timeCreated: 1475650105
+licenseType: Store
+PluginImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  platformData:
+    Android:
+      enabled: 1
+      settings: {}
+    Any:
+      enabled: 0
+      settings: {}
+    Editor:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 5e424af03b980464384a6d705203b539
+folderAsset: yes
+timeCreated: 1456124786
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 42fb4ba882fd158408a7b716d1e3729e
+folderAsset: yes
+timeCreated: 1456124825
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 953 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Channel.cs

@@ -0,0 +1,953 @@
+/*
+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
+{
+    /// <summary>
+    /// Control class for an individual ANT channel. Created and accessed through the ANTDevice class.
+    /// </summary>
+    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
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        public event dRawChannelResponseHandler rawChannelResponse;
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        public event dDeviceNotificationHandler DeviceNotification;
+
+        /// <summary>
+        /// The channel callback event. Triggered every time a message is received from the ANT device.
+        /// Examples include transmit and receive messages.
+        /// </summary>
+        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
+
+
+        /// <summary>
+        /// Returns the ANTDevice that this channel belongs to
+        /// </summary>
+        public ANT_Device getParentDevice()
+        {
+            return creatingDevice;
+        }
+
+
+        /// <summary>
+        /// Returns the underlying C++ ANT framer reference that this channel uses for messaging. Useful to pass to unmanaged C++ implementations.
+        /// </summary>
+        /// <returns>Pointer to the C++ ANT framer for messaging</returns>
+        public IntPtr getUnmgdFramer()
+        {
+            return creatingDevice.getFramerPtr();
+        }
+
+
+        /// <summary>
+        /// Returns the channel number of this instance
+        /// </summary>
+        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);
+        }
+
+
+        /// <summary>
+        /// Dispose this channel.
+        /// </summary>
+        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);
+        }
+
+
+        /// <summary>
+        /// Returns current channel status.
+        /// Throws exception on timeout.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        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");
+            }
+        }
+
+
+        /// <summary>
+        /// Returns the channel ID
+        /// Throws exception on timeout
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns></returns>
+        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
+
+        /// <overloads>Assign channel</overloads>
+        /// <summary>
+        /// Assign an ANT channel along with its main parameters.
+        /// Throws exception if the network number is invalid.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel, must be less than device's max networks-1</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Assign an ANT channel.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel</param>
+        public void assignChannel(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber) { assignChannel(channelTypeByte, networkNumber, 0); }
+        
+
+        /// <overloads>Assign channel (extended)</overloads>
+        /// <summary>
+        /// Assign an ANT channel, using extended channel assignment
+        /// Throws exception if the network number is invalid.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel, must be less than device's max netwoks - 1</param>
+        /// <param name="extAssignByte">Extended assignment byte</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Assign an ANT channel, using extended channel assignment
+        /// Throws exception if the network number is invalid.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel, must be less than device's max netwoks - 1</param>
+        /// <param name="extAssignByte">Extended assignment byte</param>
+        public void assignChannelExt(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, ANT_ReferenceLibrary.ChannelTypeExtended extAssignByte) { assignChannelExt(channelTypeByte, networkNumber, extAssignByte, 0); }
+
+
+        /// <overloads>Unassign channel</overloads>
+        /// <summary>
+        /// Unassign this channel.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool unassignChannel(UInt32 responseWaitTime)
+        {
+            if (disposed)
+                throw new ObjectDisposedException("This ANTChannel object has been disposed");
+
+            return (ANT_UnAssignChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Unassigns this channel.
+        /// </summary>
+        public void unassignChannel() { unassignChannel(0); }
+        
+
+        /// <overloads>Set the Channel ID</overloads>
+        /// <summary>
+        /// Set the Channel ID of this channel.
+        /// Throws exception if device type is > 127.
+        /// </summary>
+        /// <param name="deviceNumber">Device number to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="pairingEnabled">Device pairing bit.</param>
+        /// <param name="deviceTypeID">Device type to assign to channel. Must be less than 128. Set to 0 for receiver wild card matching</param>
+        /// <param name="transmissionTypeID">Transmission type to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Set the Channel ID of this channel.
+        /// Throws exception if device type is > 127.
+        /// </summary>
+        /// <param name="deviceNumber">Device number to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="pairingEnabled">Device pairing bit</param>
+        /// <param name="deviceTypeID">Device type to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="transmissionTypeID">Transmission type to assign to channel. Set to 0 for receiver wild card matching</param>
+        public void setChannelID(UInt16 deviceNumber, bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID) { setChannelID(deviceNumber, pairingEnabled, deviceTypeID, transmissionTypeID, 0); }
+        
+
+        /// <overloads>Sets the Channel ID, using serial number as device number</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Identical to setChannelID, except last two bytes of serial number are used for device number.
+        /// </summary>
+        public void setChannelID_UsingSerial(bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID) { setChannelID_UsingSerial(pairingEnabled, deviceTypeID, transmissionTypeID, 0); }
+        
+
+        /// <overloads>Sets channel message period</overloads>
+        /// <summary>
+        /// Set this channel's messaging period
+        /// </summary>
+        /// <param name="messagePeriod_32768unitspersecond">Desired period in seconds * 32768</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Set this channel's messaging period
+        /// </summary>
+        /// <param name="messagePeriod_32768unitspersecond">Desired period in seconds * 32768</param>
+        public void setChannelPeriod(UInt16 messagePeriod_32768unitspersecond) { setChannelPeriod(messagePeriod_32768unitspersecond, 0); }
+
+
+        /// <overloads>Sets the RSSI threshold (ARCT)</overloads>
+        /// <summary>
+        /// Set this channel's RSSI threshold (ARCT)
+        /// </summary>
+        /// <param name="thresholdRSSI">Desired RSSI threshold value</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Set this channel's RSSI threshold (ARCT)
+        /// </summary>
+        /// <param name="thresholdRSSI">Desired RSSI threshold value</param>
+        public void setSearchThresholdRSSI(byte thresholdRSSI) { setSearchThresholdRSSI(thresholdRSSI, 0); }
+
+
+        /// <overloads>Sets channel RF Frequency</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="RFFreqOffset">Offset to add to 2400Mhz</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="RFFreqOffset">Offset to add to 2400Mhz</param>
+        public void setChannelFreq(byte RFFreqOffset) { setChannelFreq(RFFreqOffset, 0); }
+        
+
+        /// <overloads>Sets the channel transmission power</overloads>
+        /// <summary>
+        /// Set the transmission power of this channel
+        /// Throws exception if device is not capable of per-channel transmit power.
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to set to</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Set the transmission power of this channel
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to set to</param>
+        public void setChannelTransmitPower(ANT_ReferenceLibrary.TransmitPower transmitPower) { setChannelTransmitPower(transmitPower, 0); }
+        
+
+        /// <overloads>Sets the channel search timeout</overloads>
+        /// <summary>
+        /// Set the search timeout
+        /// </summary>
+        /// <param name="searchTimeout">timeout in 2.5 second units (in newer devices 255=infinite)</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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);
+        }
+        /// <summary>
+        /// Set the search timeout
+        /// </summary>
+        /// <param name="searchTimeout">timeout in 2.5 second units (in newer devices 255=infinite)</param>
+        public void setChannelSearchTimeout(byte searchTimeout) { setChannelSearchTimeout(searchTimeout, 0); }
+        
+
+        /// <overloads>Opens the channel</overloads>
+        /// <summary>
+        /// Opens this channel
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool openChannel(UInt32 responseWaitTime)
+        {
+            if (disposed)
+                throw new ObjectDisposedException("This ANTChannel object has been disposed");
+
+            return (ANT_OpenChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Opens this channel
+        /// </summary>
+        public void openChannel() { openChannel(0); }
+        
+
+        /// <overloads>Sends broadcast message</overloads>
+        /// <summary>
+        /// Sends the given data on the broadcast transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="data">data to send (length 8 or less)</param>
+        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;
+        }
+
+
+        /// <overloads>Sends acknowledged message</overloads>
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <param name="data">data to send (length 8 or less)</param>
+        /// <param name="ackWaitTime">Time in ms to wait for acknowledgement</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        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);
+        }
+        /// <summary>
+        /// Sends the given data as an acknowledged transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="data">data to send (length 8 or less)</param>
+        public void sendAcknowledgedData(byte[] data) { sendAcknowledgedData(data, 0); }
+        
+
+        /// <overloads>Sends burst transfer</overloads>
+        /// <summary>
+        /// Sends the given data as a burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled
+        /// </summary>
+        /// <param name="data">data to send, can be any length</param>
+        /// <param name="completeWaitTime">Time in ms to wait for completion of transfer</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        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);
+        }
+        /// <summary>
+        /// Sends the given data as a burst transmission.
+        /// </summary>
+        /// <param name="data">data to send, can be any length</param>
+        public void sendBurstTransfer(byte[] data) { sendBurstTransfer(data, 0); }
+
+
+        
+
+        /// <overloads>Sends extended broadcast message</overloads>
+        /// <summary>
+        /// Sends the given data as an extended broadcast transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send (length 8 or less)</param>
+        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;
+        }
+        
+
+        /// <overloads>Sends extended acknowledged message</overloads>
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send (length 8 or less)</param>
+        /// <param name="ackWaitTime">Time in ms to wait for acknowledgement</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        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);
+        }
+        /// <summary>
+        /// Sends the given data as an extended acknowledged transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send (length 8 or less)</param>
+        public void sendExtAcknowledgedData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data) { sendExtAcknowledgedData(deviceNumber, deviceTypeID, transmissionTypeID, data, 0); }
+        
+
+        /// <overloads>Sends extended burst data</overloads>
+        /// <summary>
+        /// Sends the given data as an extended burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send, can be any length</param>
+        /// <param name="completeWaitTime">Time in ms to wait for completion of transfer</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        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);
+        }
+        /// <summary>
+        /// Sends the given data as an extended burst transmission.
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send, can be any length</param>
+        public void sendExtBurstTransfer(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data) { sendExtBurstTransfer(deviceNumber, deviceTypeID, transmissionTypeID, data, 0); }
+        
+
+        /// <overloads>Closes the channel</overloads>
+        /// <summary>
+        /// Close this channel
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool closeChannel(UInt32 responseWaitTime)
+        {
+            if (disposed)
+                throw new ObjectDisposedException("This ANTChannel object has been disposed");
+
+            return (ANT_CloseChannel(unmanagedANTFramerPointer, channelNumber, responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Close this channel
+        /// </summary>
+        public void closeChannel() { closeChannel(0); }
+        
+
+
+        /// <overloads>Sets the channel low priority search timeout</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="lowPriorityTimeout">Timeout period in 2.5 second units</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="lowPriorityTimeout">Timeout period in 2.5 second units</param>
+        public void setLowPrioritySearchTimeout(byte lowPriorityTimeout) { setLowPrioritySearchTimeout(lowPriorityTimeout, 0); }
+        
+
+
+        /// <overloads>Adds a channel ID to the device inclusion/exclusion list</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="deviceNumber">deviceNumber of the channelID to add</param>
+        /// <param name="deviceTypeID">deviceType of the channelID to add</param>
+        /// <param name="transmissionTypeID">transmissionType of the channelID to add</param>
+        /// <param name="listIndex">position in inclusion/exclusion list to add channelID at (Max size of list is 4)</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="deviceNumber">deviceNumber of the channelID to add</param>
+        /// <param name="deviceTypeID">deviceType of the channelID to add</param>
+        /// <param name="transmissionTypeID">transmissionType of the channelID to add</param>
+        /// <param name="listIndex">position in inclusion/exclusion list to add channelID at (0..3)</param>
+        public void includeExcludeList_addChannel(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte listIndex)
+        {
+            includeExcludeList_addChannel(deviceNumber, deviceTypeID, transmissionTypeID, listIndex, 0);
+        }
+        
+
+        /// <overloads>Configures the device inclusion/exclusion list</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="listSize">The desired size of the list, max size is 4, 0=none</param>
+        /// <param name="isExclusionList">True = exclusion list, False = inclusion list</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="listSize">The desired size of the list, max size is 4, 0=none</param>
+        /// <param name="isExclusionList">True = exclusion list, False = inclusion list</param>
+        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);
+        }
+
+        /// <overloads>Configures proximity search</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="thresholdBin">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. </param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="thresholdBin">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. </param>        
+        public void setProximitySearch(byte thresholdBin) { setProximitySearch(thresholdBin, 0);}
+        
+
+
+        /// <overloads>Configures the three operating RF frequencies for ANT frequency agility mode</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="freq1">Operating RF frequency 1</param>
+        /// <param name="freq2">Operating RF frequency 2</param>
+        /// <param name="freq3">Operating RF frequency 3</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>
+        /// 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. 
+        /// </summary>
+        /// <param name="freq1">Operating RF frequency 1</param>
+        /// <param name="freq2">Operating RF frequency 2</param>
+        /// <param name="freq3">Operating RF frequency 3</param>
+        public void configFrequencyAgility(byte freq1, byte freq2, byte freq3) { configFrequencyAgility(freq1, freq2, freq3, 0); }
+        
+        /// <overloads>Configures Selective Data Updates</overloads>
+        /// <summary>
+        /// Allows enabling Selective Data Update
+        /// </summary>
+        /// <param name="sduConfig">Specify desired previously defined SDU mask and which messages it should apply to</param>                
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        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;
+        }
+        /// <summary>        
+        /// Allows enabling Selective Data Update
+        /// </summary>
+        /// <param name="sduConfig">Specify desired previously defined SDU mask and which messages it should apply to</param>                        
+        public void configSdu(byte sduConfig) { configSdu(sduConfig, 0); }
+        
+ 
+
+
+
+
+        #endregion
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Channel.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f33ee316390af7c4c8d3a845166aa78f
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 54 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelID.cs

@@ -0,0 +1,54 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Structure containing the data composing a channel ID
+    /// </summary>
+    public struct ANT_ChannelID
+    {
+        /// <summary>
+        /// Device Number
+        /// </summary>
+        public UInt16 deviceNumber;
+        /// <summary>
+        /// Pairing Bit
+        /// </summary>
+        public bool pairingBit;
+        /// <summary>
+        /// Device Type ID
+        /// </summary>
+        public byte deviceTypeID;
+        /// <summary>
+        /// Transmission Type ID
+        /// </summary>
+        public byte transmissionTypeID;
+
+        /// <summary>
+        /// Initializes a new Channel ID Object
+        /// </summary>
+        /// <param name="deviceNumber">Device Number</param>
+        /// <param name="deviceType">Device Type ID</param>
+        /// <param name="transmissionType">Transmission Type ID</param>
+        public ANT_ChannelID(ushort deviceNumber, byte deviceType, byte transmissionType)
+        {
+            this.deviceNumber = deviceNumber;
+            this.deviceTypeID = deviceType;
+            this.transmissionTypeID = transmissionType;
+            this.pairingBit = false;
+        }
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelID.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f6be66be2bda17146b51979ae2532957
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 49 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelStatus.cs

@@ -0,0 +1,49 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Contains the information returned by a channel status request message
+    /// </summary>
+    public struct ANT_ChannelStatus
+    {
+        /// <summary>
+        /// Bits 0-1 of the status response
+        /// </summary>
+        public ANT_ReferenceLibrary.BasicChannelStatusCode BasicStatus;
+        /// <summary>
+        /// Bits 2-3 of the status response. Invalid on AP1.
+        /// </summary>
+        public byte networkNumber;
+        /// <summary>
+        /// Bits 4-7 of the status response. Not a valid channelType on AP1.
+        /// </summary>
+        public ANT_ReferenceLibrary.ChannelType ChannelType;
+
+        /// <summary>
+        /// Creates and fills the ChannelStatus
+        /// </summary>
+        /// <param name="BasicStatus"></param>
+        /// <param name="networkNumber"></param>
+        /// <param name="ChannelType"></param>
+        public ANT_ChannelStatus(ANT_ReferenceLibrary.BasicChannelStatusCode BasicStatus, byte networkNumber, ANT_ReferenceLibrary.ChannelType ChannelType)
+        {
+            this.BasicStatus = BasicStatus;
+            this.networkNumber = networkNumber;
+            this.ChannelType = ChannelType;
+        }
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ChannelStatus.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6fdaefb8adc74da47aecf36fa6947934
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 158 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Common.cs

@@ -0,0 +1,158 @@
+/*
+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 UnityEngine;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// This is a static class that manages all the functions and variables common to the whole scope of the library.
+    /// </summary>
+    public static class ANT_Common
+    {
+
+        /// <summary>
+        /// Enables or disables all devices from resetting on startup, shutdown, and on CWTestMode Failure.
+        /// Default = true.
+        /// </summary>
+        static public bool autoResetIsEnabled = true;
+
+        #region constants
+
+    #if EXT_FUNCTIONALITY
+#warning "The Extended build is for internal use only, and even then, only for specific projects, do not use without discussing with the ANT team"
+        internal const String ANT_UNMANAGED_WRAPPER = "ANT_WrappedLib_Ext.dll";
+    #else
+        internal const String ANT_UNMANAGED_WRAPPER = "ANT_WrappedLib";
+    #endif
+
+        internal const String ANT_SI_LIBRARY = "DSI_SiUSBXp_3_1";
+        internal const String ANT_SI_LIBRARY2 = "DSI_CP210xManufacturing_3_1";
+
+        #endregion
+
+
+        #region DLL imports
+       
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern UInt32 ANT_GetNumDevices();
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_EnableDebugLogging();
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern void ANT_DisableDebugLogging();
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_SetDebugLogDirectory(string pcDirectory);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_DebugThreadInit(string pucName);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_DebugThreadWrite(string pcMessage);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int ANT_DebugResetTime();
+
+        #endregion
+
+
+        /// <summary>
+        /// Returns the number of ANT USB devices currently detected by the system.
+        /// </summary>
+        public static UInt32 getNumDetectedUSBDevices()
+        {
+            return ANT_GetNumDevices();
+        }
+
+               
+        /// <overloads>Enables debug files</overloads>
+        /// <summary>
+        /// Initializes and enables debug logs for all devices
+        /// Note:  For application specific logs to work properly
+        /// (e.g. ANT-FS logs), this needs to be called BEFORE
+        /// creating an ANT Device.
+        /// </summary>
+        public static bool enableDebugLogs()
+        {
+            return ANT_EnableDebugLogging() == 1;
+        }
+        
+        /// <summary>
+        /// Initializes and enables debug logs for all devices,
+        /// and stores the log in the specified path.  
+        /// Note:  For application specific logs to work properly
+        /// (e.g. ANT-FS logs), this needs to be called BEFORE
+        /// creating an ANT Device.
+        /// </summary>
+        /// <param name="debugPath">Debug log directory</param>
+        public static void enableDebugLogs(string debugPath)
+        {
+            enableDebugLogs();
+            setDebugLogDirectory(debugPath);
+        }
+
+        /// <summary>
+        /// Disables and closes the debug logs
+        /// </summary>
+        public static void disableDebugLogs()
+        {
+            ANT_DisableDebugLogging();
+        }
+        
+        /// <summary>
+        /// Set the directory the log files are saved to. 
+        /// This string will prefix the file name so must end with a slash or will be part of the name. 
+        /// ie: directoryPath='c:\ANT\logs' will result in files being saved to the \ANT directory named logsdevice0.txt. 
+        /// Throws an exception if directory does not exist.
+        /// </summary>
+        /// <param name="directoryPath">
+        /// Path to directory to save log files in. Default is the running directory.
+        /// This string will prefix the file name so must end with a slash or will be part of the name. 
+        /// ie: directoryPath='c:\ANT\logs' will result in files being saved to the \ANT directory named logsdevice0.txt.
+        /// </param>
+        public static bool setDebugLogDirectory(string directoryPath)
+        {
+            if (!System.IO.Directory.Exists(directoryPath))
+                throw new ANT_Exception("Path does not exist");
+
+            return ANT_SetDebugLogDirectory(directoryPath) == 1;
+        }
+
+        //
+        //Note: Access to the following logging functions is required by the current ANT-FS implementation
+        //
+        /// <summary>
+        /// Creates a debug log for the currently executing thread
+        /// </summary>
+        /// <param name="name">Name of file (will result in ao_debug_name)</param>
+        /// <returns>True if successful</returns>
+        internal static bool initDebugLogThread(string name)
+        {
+            return ANT_DebugThreadInit(name) == 1;
+        }
+
+        /// <summary>
+        /// Adds an application specific message to the log for the current thread
+        /// </summary>
+        /// <param name="message">Message to write to the log</param>
+        /// <returns>True on success</returns>
+        internal static bool writeToDebugLog(string message)
+        {
+            return ANT_DebugThreadWrite(message) == 1;
+        }
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Common.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 33f8a9d534762944882f7a65d9f74b8d
+timeCreated: 1456133402
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1869 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Device.cs

@@ -0,0 +1,1869 @@
+/*
+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;
+//using System.Management;
+using Debug = UnityEngine.Debug;
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Control class for a given ANT device. An instance of this class is an open connection to the given ANT USB device.
+    /// Handles creating channels and device setup.
+    /// </summary>
+    public class ANT_Device : IDisposable
+    {
+        #region variables
+
+        ANT_ReferenceLibrary.FramerType frameType;
+        ANT_ReferenceLibrary.PortType portType;
+
+        IntPtr unmanagedANTSerialPtr = IntPtr.Zero;
+        IntPtr unmanagedANTFramerPtr = IntPtr.Zero;
+        IntPtr unmanagedCancelBool = IntPtr.Zero;   //The bool type def in the unmanaged code is an int, so 4 bytes
+        bool? cancelTxFlag //Handles accessing the unmanged bool as a normal nullable bool
+        {
+            get
+            {
+                if(unmanagedCancelBool == IntPtr.Zero)
+                    return null;
+                return Convert.ToBoolean(Marshal.ReadInt32(unmanagedCancelBool));
+            }
+            set //TODO: Should we send out a deviceNotification when this occurs?
+            {
+                if (unmanagedCancelBool != IntPtr.Zero)                    
+                    Marshal.WriteInt32(unmanagedCancelBool, Convert.ToInt32(value));
+            }
+        }
+
+        bool initializedUSB = false;
+        byte USBDeviceNum = 255;    //Device num of instance
+        uint USBBaudRate = 0;
+        
+        ANT_DeviceCapabilities capabilities = null;
+        bool pollingOn;
+
+        int numDeviceChannels;
+        ANT_Channel[] antChannels;
+
+
+        #endregion
+
+
+        #region DeviceCallback variables
+
+        //This struct is used by the unmanaged code to pass response messages
+        [StructLayout(LayoutKind.Sequential)]
+        struct ANTMessageItem
+        {
+            public byte dataSize;
+            public ANTMessage antMsgData;
+        }
+
+        /// <summary>
+        /// ANTMessage struct as defined in unmanaged code for marshalling ant messages with unmanaged code
+        /// </summary>
+        [StructLayout(LayoutKind.Sequential)]
+        public struct ANTMessage
+        {
+            /// <summary>
+            /// Message ID byte
+            /// </summary>
+            public byte msgID;
+
+            /// <summary>
+            /// Data buffer
+            /// </summary>
+            [MarshalAs(UnmanagedType.ByValArray, SizeConst = ANT_ReferenceLibrary.MAX_MESG_SIZE)] //We have to make sure the marshalling knows the unmanaged equivalent is a fixed array of the maximum ANT message size
+            public byte[] ucharBuf; //The size of this should match the SizeConst
+        }
+
+        /// <summary>
+        /// Codes for the device notification event
+        /// </summary>
+        public enum DeviceNotificationCode : byte
+        {
+            /// <summary>
+            /// The device is being reset
+            /// </summary>
+            Reset = 0x01,
+
+            /// <summary>
+            /// The device is being shutdown
+            /// </summary>
+            Shutdown = 0x02,
+        }
+
+        System.Threading.Thread responsePoller; //This thread is in charge of monitoring the device for new messages and forwards them to the appropriate handler function
+
+        /// <summary>
+        /// Delegate for device response event
+        /// </summary>
+        /// <param name="response">Message details received from device</param>
+        public delegate void dDeviceResponseHandler(ANT_Response response); //The delegate for the managed callback functions
+
+        /// <summary>
+        /// The channel callback event. Triggered every time a message is received from the ANT device.
+        /// Examples include requested responses and setup status messages.
+        /// </summary>
+        public event dDeviceResponseHandler deviceResponse;  //The event to assign callback functions to in a managed application
+
+        /// <summary>
+        /// Function to handle ANT_Device serial errors
+        /// </summary>
+        /// <param name="sender">The ANT_Device reporting the error</param>
+        /// <param name="error">The serial error that occured</param>
+        /// <param name="isCritical">If true, the communication with the device is lost and this device object should be disposed</param>
+        public delegate void dSerialErrorHandler(ANT_Device sender, serialErrorCode error, bool isCritical); //The delegate for the serialError callback function
+
+        /// <summary>
+        /// This event is triggered when there is a serial communication error with the ANT Device.
+        /// If the error is critical all communication with the device is dead and the
+        /// device reference is sent in this function to allow the application
+        /// to know which device is dead and to dispose of it.
+        /// </summary>
+        public event dSerialErrorHandler serialError;
+
+        /// <summary>
+        /// ANT Device Serial Error Codes
+        /// </summary>
+        public enum serialErrorCode
+        {
+            /// <summary>
+            /// A write command to the device failed, could be a usb communication issue or due to invalid paramters passed to the write function.
+            /// If it is a device communication failure, a serial read error will most likely occur shortly.
+            /// </summary>
+            SerialWriteError,
+
+            /// <summary>
+            /// A failure occured reading data from the device.
+            /// </summary>
+            SerialReadError,
+
+            /// <summary>
+            /// Communication with the device has been lost.
+            /// </summary>
+            DeviceConnectionLost,
+
+            /// <summary>
+            /// A message received by the device failed the crc check and was discarded.
+            /// </summary>
+            MessageLost_CrcError,
+
+            /// <summary>
+            /// The message queue for received messages has overflowed and one or more messages were lost.
+            /// </summary>
+            MessageLost_QueueOverflow,
+
+            /// <summary>
+            /// A message received was over the maximum message size, and the message was discarded.
+            /// This is usually due to a communication error or an error in the library or library compilation settings.
+            /// </summary>
+            MessageLost_TooLarge,
+
+            /// <summary>
+            /// A channel event was received for a channel which does not exist and the message was dropped (but will still appear in the logs)
+            /// </summary>
+            MessageLost_InvalidChannel,
+
+            /// <summary>
+            /// Unspecified error, most likely a new or changed error definition
+            /// </summary>
+            Unknown
+        }
+        
+        #endregion
+
+
+
+        #region ANT_DLL Imports
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Init(byte ucUSBDeviceNum, UInt32 usBaudrate, ref IntPtr returnSerialPtr, ref IntPtr returnFramerPtr, byte ucPortType, byte ucHCIFrameTpye);
+
+        //Note: Before uncommenting this read todo comment on constructor, we don't use this now because we want to know the device number we opened
+        //[DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        //private static extern int ANT_AutoInit(ref IntPtr returnSerialPtr, ref IntPtr returnFramerPtr);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern void ANT_Close(IntPtr SerialPtr, IntPtr FramerPtr);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_USBReset(IntPtr SerialPtr);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_ResetSystem(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern void ANT_SetCancelParameter(IntPtr FramerPtr, IntPtr pbCancel);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetNetworkKey_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_SetNetworkKey(IntPtr FramerPtr, byte ucNetNumber, byte[] pucKey, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_EnableLED_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_EnableLED(IntPtr FramerPtr, byte ucEnable, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_GetDeviceUSBPID(IntPtr FramerPtr, ref UInt16 usbPID);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_GetDeviceUSBVID(IntPtr FramerPtr, ref UInt16 usbVID);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigureSplitAdvancedBursts(IntPtr FramerPtr, int bEnabelSplitBursts);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_ConfigureAdvancedBurst_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigureAdvancedBurst(IntPtr FramerPtr, int enable, byte ucMaxPacketLength, UInt32 ulRequiredFields, UInt32 ulOptionalFields, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_ConfigureAdvancedBurst_ext_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigureAdvancedBurst_ext(IntPtr FramerPtr, int enable, byte ucMaxPacketLength, UInt32 ulRequiredFields, UInt32 ulOptionalFields, UInt16 usStallCount, byte ucRetryCount, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCryptoKey_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetCryptoKey(IntPtr FramerPtr, byte ucVolatileKeyIndex, byte[] pucKey, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCryptoID_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetCryptoID(IntPtr FramerPtr, byte[] pucData, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCryptoUserInfo_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetCryptoUserInfo(IntPtr FramerPtr, byte[] pucData, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCryptoRNGSeed_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetCryptoRNGSeed(IntPtr FramerPtr, byte[] pucData, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCryptoInfo_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetCryptoInfo(IntPtr FramerPtr, byte ucParameter, byte[] pucData, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_LoadCryptoKeyNVMOp_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_LoadCryptoKeyNVMOp(IntPtr FramerPtr, byte ucNVMKeyIndex, byte ucVolatileKeyIndex, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_StoreCryptoKeyNVMOp_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_StoreCryptoKeyNVMOp(IntPtr FramerPtr, byte ucNVMKeyIndex, byte[] pucKey, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_CryptoKeyNVMOp_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_CryptoKeyNVMOp(IntPtr FramerPtr, byte ucOperation, byte ucNVMKeyIndex, byte[] pucData, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern uint ANT_GetDeviceSerialNumber(IntPtr SerialPtr);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_GetDeviceUSBInfo(IntPtr FramerPtr, byte ucDeviceNum_, 
+            [MarshalAs(UnmanagedType.LPArray)] byte[] pucProductString_, 
+            [MarshalAs(UnmanagedType.LPArray)] byte[] pucSerialString_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetTransmitPower_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_SetTransmitPower(IntPtr FramerPtr, byte ucTransmitPower_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigEventFilter(IntPtr FramerPtr, UInt16 usFilter_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigEventBuffer(IntPtr FramerPtr, byte ucConfig_, UInt16 usSize_, UInt16 usTime_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigHighDutySearch(IntPtr FramerPtr, byte ucEnable_, byte ucSuppressionCycles_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_SetSelectiveDataUpdateMask(IntPtr FramerPtr, byte ucMaskNumber_, byte[] ucSduMask_, UInt32 ulResponseTime_);       
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_ConfigUserNVM(IntPtr FramerPtr, UInt16 usAddress_, byte[] pucData_, byte ucSize_, UInt32 ulResponseTime_);       
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_RequestMessage(IntPtr FramerPtr, byte ucANTChannel, byte ucMessageID, ref ANTMessageItem ANT_MESSAGE_ITEM_response, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_RequestUserNvmMessage(IntPtr FramerPtr, byte ucANTChannel, byte ucMessageID, ref ANTMessageItem ANT_MESSAGE_ITEM_response, UInt16 usAddress, byte ucSize, UInt32 ulResponseTime_); 
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern UInt16 ANT_WaitForMessage(IntPtr FramerPtr, UInt32 ulMilliseconds_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern UInt16 ANT_GetMessage(IntPtr FramerPtr, ref ANTMessage ANT_MESSAGE_response);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern byte ANT_GetChannelNumber(IntPtr FramerPtr, ref ANTMessage pstANTMessage);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_GetCapabilities(IntPtr FramerPtr, 
+           [MarshalAs(UnmanagedType.LPArray)] byte[] pucCapabilities_,
+           UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_InitCWTestMode_RTO", CallingConvention = CallingConvention.Cdecl)]
+        private static extern int ANT_InitCWTestMode(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_SetCWTestMode_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_SetCWTestMode(IntPtr FramerPtr, byte ucTransmitPower_, byte ucRFChannel_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_OpenRxScanMode_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_OpenRxScanMode(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_Write_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_Write(IntPtr FramerPtr, byte ucSize_, byte[] pucData_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_Clear_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_Clear(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_SetDefaultSector_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_SetDefaultSector(IntPtr FramerPtr, byte ucSectNumber_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_EndSector_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_EndSector(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_Dump_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_Dump(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_Script_Lock_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_Script_Lock(IntPtr FramerPtr, UInt32 ulResponseTimeout_);
+
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "ANT_RxExtMesgsEnable_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_RxExtMesgsEnable(IntPtr FramerPtr, byte ucEnable_, UInt32 ulResponseTimeout_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_CrystalEnable(IntPtr FramerPtr, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_WriteMessage(IntPtr FramerPtr, ANTMessage pstANTMessage, UInt16 usMessageSize);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern int ANT_SetLibConfig(IntPtr FramerPtr, byte ucLibConfigFlags_, UInt32 ulResponseTime_);
+
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "FIT_SetFEState_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int FIT_SetFEState(IntPtr FramerPtr, byte ucFEState_, UInt32 ulResponseTime_);
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, EntryPoint = "FIT_AdjustPairingSettings_RTO", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int FIT_AdjustPairingSettings(IntPtr FramerPtr, byte ucSearchLv_, byte ucPairLv_, byte ucTrackLv_, UInt32 ulResponseTime_);        
+        #endregion
+
+
+
+        #region Constructors and Destructor
+
+        /// <overloads>
+        /// Opens a connection to an ANT device attached by USB.
+        /// Throws exception if a connection can not be established.
+        /// </overloads>
+        /// <summary>
+        /// Attempts to open a connection to an ANT device attached by USB using the given deviceNum and baud rate
+        /// Throws exception if a connection can not be established.
+        /// </summary>
+        /// <param name="USBDeviceNum">The device number of the ANT USB device (the first connected device starts at 0 and so on)</param>
+        /// <param name="baudRate">The baud rate to connect at (AP2/AT3=57600, AP1=50000)</param>
+        public ANT_Device(byte USBDeviceNum, uint baudRate)
+            :this(ANT_ReferenceLibrary.PortType.USB, USBDeviceNum, baudRate, ANT_ReferenceLibrary.FramerType.basicANT)
+        {
+        }
+
+
+        /// <overloads>
+        /// Opens a connection to an ANT device attached by USB.
+        /// Throws exception if a connection can not be established.
+        /// </overloads>
+        /// <summary>
+        /// Attempts to open a connection to an ANT device attached by USB using the given deviceNum and baud rate
+        /// Throws exception if a connection can not be established.
+        /// </summary>
+        /// <param name="portType">The type of connection to use when talking to the device</param>
+        /// <param name="USBDeviceNum">If port type is USB, device number of the ANT USB device.
+        /// If port type is COM this is the COM port number</param>
+        /// <param name="baudRate">The baud rate to connect at (USB: AP2/AT3=57600, AP1=50000)</param>
+        /// <param name="frameType">The framing method to use for the connection to the chip.
+        /// Needed for multimode chips and currently only supported on COM connections.</param>
+        public ANT_Device(ANT_ReferenceLibrary.PortType portType, byte USBDeviceNum, uint baudRate, ANT_ReferenceLibrary.FramerType frameType)
+        {
+            try
+            {
+               startUp(USBDeviceNum, baudRate, frameType, portType, false);  // Let exceptions propagate
+            }
+            catch
+            {
+                // If constructor throws an exception, release acquired resources and suppress finalization
+                this.Dispose();
+                throw;
+            }
+        }
+
+
+        /// <summary>
+        /// Automatically connects to first availiable ANTDevice.
+        /// Throws exception if a connection can not be established.
+        /// Will not auto find COM-connected devices.
+        /// </summary>
+        public ANT_Device() //TODO: Need to change this to use the c++ library auto open, so it will check device strings, etc. NOT as now where it could open any SI device...the problem is that currently if the autoinit is used the device number is not accessible which we want to keep for ANTWare II
+        {
+            ulong numDevices = ANT_Common.getNumDetectedUSBDevices();
+            if (numDevices == 0)
+            {
+              throw new ANT_Exception("No ANT devices detected");
+            }
+            
+            bool fail = true;
+            for (byte i = 0; i < numDevices && fail; ++i)
+            {
+                try
+                {
+                    //Try 57600 baud first
+                    startUp(i, 57600, ANT_ReferenceLibrary.FramerType.basicANT, ANT_ReferenceLibrary.PortType.USB, true);  //If this fails it will throw an exception, and we'll try 50000
+                    fail = false;   //If no exception is thrown we are good to go
+                }
+                catch (Exception)
+                {
+                    //Try 50000 baudRate then
+                    try
+                    {
+                        startUp(i, 50000, ANT_ReferenceLibrary.FramerType.basicANT, ANT_ReferenceLibrary.PortType.USB, true);
+                        fail = false;   //If no exception is thrown we are good to go
+                    }
+                    catch (Exception)
+                    {
+                        fail = true;    //Both baud rates failed
+                    }
+                }
+            }
+
+            if (fail)
+            {
+                // If constructor throws an exception, release acquired resources and suppress finalization         
+                this.Dispose();
+                throw new ANT_Exception("Failed to connect to any ANT devices");
+            }
+        }
+
+
+        //This is all the initialization, pulled out to this method so it could be called by both constructors
+        private void startUp(byte USBDeviceNum, uint baudRate, ANT_ReferenceLibrary.FramerType frameType, ANT_ReferenceLibrary.PortType portType, bool calledByAutoInit)
+        {
+            // The SI libraries are not required for USB2, so attempt to connect first and only throw an 
+            // exception if this fails.
+            int ret = ANT_Init(USBDeviceNum, baudRate, ref unmanagedANTSerialPtr, ref unmanagedANTFramerPtr, (byte)portType, (byte)frameType);
+            if (ret != 0)
+            {
+                switch(ret)
+                {
+                    case -1:
+                        throw new ANT_Exception("Unexpected init library error. This is typically a problem with the c++ library");
+                    case -2:
+                        throw new ANT_Exception("Unrecognized type parameters");
+                    case -3:
+                        throw new ANT_Exception("Unable to initialize USB:" + USBDeviceNum + " at Baud:" + baudRate + ", probably device not present or already in use, or drivers not installed");
+                    default:
+                        throw new ANT_Exception("Unrecognized error code received from c++ library");
+                }
+            }
+
+            initializedUSB = true;  //Keep track of whether device is connected or not
+            this.USBDeviceNum = USBDeviceNum;   //Keep the parameters for reference
+            this.USBBaudRate = baudRate;
+            this.frameType = frameType;
+            this.portType = portType;
+
+#if (ANTFS_DEBUGGING)
+            //This logging is used in the ANT-FS libraries.  Will not create any files if logging not enabled
+            ANT_Common.initDebugLogThread("Device" + USBDeviceNum + "_Application");
+            ANT_Common.ANT_DebugResetTime();
+            ANT_Common.writeToDebugLog("ANT_NET.DLL " + ANT_VersionInfo.getManagedLibraryVersion() + " with ANT_WrappedLib.DLL " + ANT_VersionInfo.getUnmanagedLibraryVersion());
+#endif
+
+            try
+            {
+                responsePoller = new System.Threading.Thread(responsePollFunc);
+                responsePoller.Name = this.ToString() + " Receive Thread";
+                responsePoller.IsBackground = true; //Make this a background thread so it will terminate when a program closes
+                responsePoller.Start();
+
+                //Get capabilities so we know how many channels we have
+                //If this throws an exception it is probably connected at the wrong baud rate, so we send a descriptive exception
+                try
+                {
+                    getDeviceCapabilities(true, 200);
+                }
+                catch (ANT_Exception ex)
+                {
+                    throw new ANT_Exception(ex.Message.Remove(0, 22) + ", probably connecting at wrong baud rate");
+                }
+
+                if(ANT_Common.autoResetIsEnabled)
+                    ANT_ResetSystem(unmanagedANTFramerPtr, 200); //Send a reset so by the time the user gets this handle the device is viable
+
+                numDeviceChannels = capabilities.maxANTChannels;
+
+                // Set up the channel list to the right size
+                antChannels = new ANT_Channel[numDeviceChannels];
+
+                unmanagedCancelBool = Marshal.AllocHGlobal(4);
+                cancelTxFlag = false;
+                ANT_SetCancelParameter(unmanagedANTFramerPtr, unmanagedCancelBool);                
+            }
+            catch (Exception)    // clean up
+            {
+                shutdown();
+                throw;   //Forward the error to caller
+            }
+        }
+
+        /// <summary>
+        /// Destructor closes all opened resources
+        /// </summary>
+        ~ANT_Device()
+        {
+            shutdown();            
+        }
+
+        /// <summary>
+        /// Dispose method for explicit resource cleanup. Same as shutdownDeviceInstance() but doesn't nullify reference.
+        /// </summary>
+        public void Dispose()
+        {
+            shutdown();
+            GC.SuppressFinalize(this);
+        }
+
+
+        //This function cleans up all opened resources
+        //This is accessed externally by calling Dispose()
+        private void shutdown()
+        {
+            try
+            {
+                lock (this) //To prevent multiple threads calling shutdown concurrently...not sure why because none of our other code is really thread safe
+                {
+                    if (initializedUSB) //if reference is already disposed, there is no cleanup to do
+                    {
+                        //Notify and Close the channels first
+                        if (antChannels != null)
+                        {
+                            NotifyDeviceEvent(DeviceNotificationCode.Shutdown, null);
+                            foreach (ANT_Channel i in antChannels)
+                            {
+                                //We dispose any channel references because since the c++ framer is being destroyed dereferencing it later will blow it up,
+                                //By disposing the channel the user will know from the ObjectDisposed exceptions instead of an undeterministic c++ explosion
+                                if (i != null)
+                                    i.Dispose();    //Since this nullifies all the list references, it will stop all further feedback to the channels
+                            }
+                        }
+                        
+
+                        //Now shutdown all the device resources
+
+                        //Set cancel so if we are in a transfer it has a chance to shutdown gracefully
+                        cancelTxFlag = true;   
+
+                        //Exit the response polling thread
+                        pollingOn = false;
+                        if (!responsePoller.Join(1500)) //Wait for the poll thread to terminate
+                        {
+                            responsePoller.Abort(); //Abort poll thread if it doesn't join
+                            Debug.Log("Response poll thread did not join in timeout and was aborted. Was the application slow/stalling, or should we increase the join timeout?");
+                        }
+
+                        //We call reset directly, because we don't care about notifying the mgd channels because we just closed them
+                        //If capabilities is null, it means init failed and we don't have an open line of communication to send a reset
+                        if (capabilities != null && ANT_Common.autoResetIsEnabled)
+                            ANT_ResetSystem(unmanagedANTFramerPtr, 0);
+
+                        //This is the most important part: clean up the big unmanged objects
+                        ANT_Close(unmanagedANTSerialPtr, unmanagedANTFramerPtr);
+                        if (unmanagedCancelBool != IntPtr.Zero)
+                        {
+                            Marshal.FreeHGlobal(unmanagedCancelBool);
+                            unmanagedCancelBool = IntPtr.Zero;
+                        }
+
+                        //Mark as disposed 
+                        initializedUSB = false;
+                    }
+                }
+            }
+            catch (Exception ex) 
+            {
+                //Ignore all exceptions because this is only called on destruction or critical failure anyway
+                Debug.Log("Exception on shutdown: " + ex.Message); 
+            }  
+        }
+
+
+        /// <summary>
+        /// Shuts down all open resources, calls reset on the physical device, and nullifies the given ANTDevice and all its channels
+        /// </summary>
+        /// <param name="deviceToShutdown">ANTDevice to shutdown</param>
+        public static void shutdownDeviceInstance(ref ANT_Device deviceToShutdown)
+        {
+            if (deviceToShutdown != null)
+            {
+                deviceToShutdown.Dispose();
+                deviceToShutdown = null;                
+            }
+        }
+
+
+        //Allows a disposed channel to nullify its list reference, so the next call to getChannel() can get a new un-disposed reference
+        internal void channelDisposed(byte channelNumber)
+        {
+            antChannels[channelNumber] = null;
+        }
+
+
+        #endregion
+
+
+        #region non-ANTdll Functions
+
+        /// <summary>
+        /// Convert instance to a string including the USB device number the connection is on
+        /// </summary>
+        public override string ToString()
+        {
+ 	         return base.ToString()+ " on USBdeviceNum: " + USBDeviceNum.ToString();
+        }
+
+        /// <summary>
+        /// Returns the pointer to the underlying C++ ANT Framer used for messaging
+        /// </summary>
+        /// <returns>Pointer to C++ ANT Framer</returns>
+        internal IntPtr getFramerPtr()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return unmanagedANTFramerPtr;
+        }
+
+        /// <summary>
+        /// Returns the device number used when this instance was opened
+        /// Note: For some device types this number is not static and can change whenever new devices are enumerated in the system
+        /// </summary>
+        public int getOpenedUSBDeviceNum()
+        {
+            return USBDeviceNum;
+        }
+
+        /// <summary>
+        /// Returns the baud rate used when this instance was opened
+        /// </summary>
+        public uint getOpenedUSBBaudRate()
+        {
+            return USBBaudRate;
+        }
+
+        /// <summary>
+        /// Returns the Frame Type used to open the device
+        /// </summary>
+        public ANT_ReferenceLibrary.FramerType getOpenedFrameType()
+        {
+            return frameType;
+        }
+
+        /// <summary>
+        /// Returns the Port Type used to open the device
+        /// </summary>
+        public ANT_ReferenceLibrary.PortType getOpenedPortType()
+        {
+            return portType;
+        }
+        
+        /// <summary>
+        /// Returns the requested ANTChannel or throws an exception if channel doesn't exist.
+        /// </summary>
+        /// <param name="num">Channel number requested</param>
+        public ANT_Channel getChannel(int num)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if(num > antChannels.Length-1 || num < 0)
+                throw new ANT_Exception("Channel number invalid");
+
+            if(antChannels[num] == null)
+                antChannels[num] = new ANT_Channel(this, (byte)num);
+
+            return antChannels[num];
+        }
+
+
+        /// <summary>
+        /// Returns the number of ANTChannels owned by this device
+        /// </summary>
+        /// <returns>Number of ant channels on device</returns>
+        public int getNumChannels()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return antChannels.Length;
+        }
+
+        void NotifyDeviceEvent(DeviceNotificationCode notification, Object notificationInfo)
+        {
+            foreach (ANT_Channel i in antChannels)
+            {
+                if(i != null)
+                    i.NotifyDeviceEvent(notification, notificationInfo);
+            }
+        }
+
+
+        private void responsePollFunc()
+        {
+            ushort messageSize = 0;
+            byte channelNum;
+            bool isMsgForChannel;
+
+            pollingOn = true;   //Set to false on shutdown to terminate the thread
+#if (ANTFS_DEBUGGING)
+            ANT_Common.initDebugLogThread("Device" + USBDeviceNum + "_ANTReceive"); // We still need this for ANT-FS!  Will not be created if debug disabled
+#endif
+            while (initializedUSB && pollingOn)    //check continuously; this thread is terminated on destruction of the class
+            {
+                // We only wait in the unmanged code for 100 ms because we want this thread to be responsive on our side. 
+                // It does mean that we are running through a lot more cycles than we need to                
+                messageSize = ANT_WaitForMessage(unmanagedANTFramerPtr, 100);
+
+                if (messageSize == (ushort)0xFFFE)   //DSI_FRAMER_TIMEDOUT
+                    continue;   //Expected, just keep looping           
+                
+                ANTMessage newMessage = new ANTMessage();
+                messageSize = ANT_GetMessage(unmanagedANTFramerPtr, ref newMessage);
+
+                if (messageSize == (ushort)0xFFFF)  // DSI_FRAMER_ERROR - in current library could be from CRC error, Write error, Read error, or DeviceGone
+                {
+                    serialErrorCode error;
+                    bool isCritical = false;
+
+                    switch(newMessage.msgID)
+                    {
+                        case 0x02:  //DSI_FRAMER_ANT_ESERIAL
+                            switch(newMessage.ucharBuf[0])
+                            {
+                                case 0x04:  //ESERIAL -> DSI_FRAMER_ANT_CRC_ERROR
+                                    error = serialErrorCode.MessageLost_CrcError;
+                                    break;
+                                case 0x02:  //ESERIAL -> DSI_SERIAL_EWRITE
+                                    error = serialErrorCode.SerialWriteError;
+                                    break;
+                                case 0x03:  //ESERIAL -> DSI_SERIAL_EREAD
+                                    error = serialErrorCode.SerialReadError;
+                                    isCritical = true;
+                                    break;
+                                case 0x01:  //ESERIAL -> DSI_SERIAL_DEVICE_GONE
+                                    error = serialErrorCode.DeviceConnectionLost;
+                                    isCritical = true;
+                                    break;
+                                default:
+                                    error = serialErrorCode.Unknown;
+                                    Debug.Log("Unknown serial failure, why isn't this known?");
+                                    break;
+                            }
+                            break;
+                        case 0x01:  //DSI_FRAMER_ANT_EQUEUE_OVERFLOW
+                            error = serialErrorCode.MessageLost_QueueOverflow;
+                            break;
+                        case 0x03:  //DSI_FRAMER_ANT_EINVALID_SIZE
+                            error = serialErrorCode.MessageLost_TooLarge;
+                            break;
+                        default:
+                            error = serialErrorCode.Unknown;
+                            Debug.Log("Unknown serial failure, why isn't this known?");
+                            break;
+                    }
+
+                    if(isCritical)
+                    {
+                        //System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(x => shutdown())); //Clean up all resources on another thread to allow this one to close cleanly    
+                        pollingOn = false;  //Just stop polling, since we will never get new messages now. Allow the user to dispose of the device.
+                    }
+
+                    //If application has subscribed to the event we can inform them
+                    if (serialError != null)
+                        serialError(this, error, isCritical);
+                   
+
+                    if (isCritical)
+                        break;  //If the device is dead, exit the polling loop
+                    else
+                        continue;
+                }
+
+                isMsgForChannel = false;
+                channelNum = Byte.MaxValue;
+
+                switch (newMessage.msgID)   //Check if we send to channel or protocol response func
+                {
+                    // Send on Channel event
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
+                        if (newMessage.ucharBuf[1] == (byte)ANT_ReferenceLibrary.ANTMessageID.EVENT_0x01)
+                            isMsgForChannel = true;
+                        break;
+                    // or any of the transmission events
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BROADCAST_DATA_0xC1:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_ACKNOWLEDGED_DATA_0xC2:
+                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BURST_DATA_0xC3:
+                        isMsgForChannel = true;
+                        break;
+                }
+
+                ANT_Response newResponse;
+
+                //Now dispatch to appropriate event
+                //The messages are buffered in the ant library so we just dispatch with current thread 
+                //then no matter how long the event call takes we still won't miss messages
+                if (isMsgForChannel)
+                {
+                    channelNum = (byte)(newMessage.ucharBuf[0] & 0x1F); //Mask out what channel this is for. [We can eventually switch to use the c++ code to determine the channel, but we should do it all together with getMessage to avoid extra marshalling and copying and remove the processing in C# above]
+                    if (antChannels != null && channelNum < antChannels.Length)
+                    {
+                        if (antChannels[channelNum] != null)
+                            antChannels[channelNum].MessageReceived(newMessage, messageSize);
+                    }
+                    else
+                    {
+                        if (serialError != null)
+                            serialError(this, serialErrorCode.MessageLost_InvalidChannel, false);
+                    }                    
+                }
+                else
+                {
+                    newResponse = new ANT_Response(this, newMessage.ucharBuf[0], DateTime.Now, newMessage.msgID, newMessage.ucharBuf.Take(messageSize).ToArray());
+
+                    if (deviceResponse != null) //Ensure events are assigned before we call the event
+                        deviceResponse(newResponse);
+                }
+                
+            }
+        }
+
+
+        /// <summary>
+        /// Sets the cancel flag on all acknowledged and burst transfers in progress for the given amount of time.
+        /// When these transmissions see the flag they will abort their operation and return as cancelled.
+        /// </summary>
+        /// <param name="cancelWaitTime">Time to set cancel flag for</param>
+        public void cancelTransfers(int cancelWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            cancelTxFlag = true;
+            System.Threading.Thread.Sleep(cancelWaitTime);
+            cancelTxFlag = false;
+        }
+
+        /// <overloads>Returns the device capabilities</overloads>
+        /// <summary>
+        /// Returns the capabilities of this device.
+        /// Throws an exception if capabilities are not received.
+        /// </summary>
+        /// <param name="forceNewCopy">Force function to send request message to device</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>Last device capabilities received or a new copy if forceNewCopy is true</returns>
+        public ANT_DeviceCapabilities getDeviceCapabilities(bool forceNewCopy, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if (forceNewCopy || capabilities == null)
+            {
+                try
+                {
+                    ANT_DeviceCapabilities newCaps = null;
+                    ANT_Response response = requestMessageAndResponse(ANT_ReferenceLibrary.RequestMessageID.CAPABILITIES_0x54, responseWaitTime);
+                    if (response != null && response.responseID == (byte)ANT_ReferenceLibrary.RequestMessageID.CAPABILITIES_0x54)
+                    {
+                        byte[] padding = new byte[16 - response.messageContents.Length];
+                        newCaps = new ANT_DeviceCapabilities(response.messageContents.Concat(padding).ToArray());
+                    }
+                    capabilities = newCaps; //We replace the old capabilities because that is what forceNewCopy means
+                }
+                catch (Exception)
+                {
+                    //If we timeout receiving the message or the interpretation fails
+                    throw new ANT_Exception("Retrieving Device Capabilities Failed");
+                }
+            }
+            return capabilities;
+        }
+
+        /// <summary>
+        /// Returns the device capabilities of this device.
+        /// Throws an exception if capabilities are not received.
+        /// </summary>
+        public ANT_DeviceCapabilities getDeviceCapabilities() { return getDeviceCapabilities(false, 1500); }
+        /// <summary>
+        /// Returns the device capabilities of this device.
+        /// Throws an exception if capabilities are not received.
+        /// </summary>
+        public ANT_DeviceCapabilities getDeviceCapabilities(UInt32 responseWaitTime) { return getDeviceCapabilities(false, responseWaitTime); }
+       
+
+        #endregion
+
+
+
+        #region ANT Device Functions
+
+        /// <overloads>Resets the USB device</overloads>
+        /// <summary>
+        /// Resets this USB device at the driver level
+        /// </summary>
+        public void ResetUSB()
+        {
+            if (portType != ANT_ReferenceLibrary.PortType.USB)
+                throw new ANT_Exception("Can't call ResetUSB on non-USB devices");
+                
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            ANT_USBReset(unmanagedANTSerialPtr);
+        }
+
+
+
+        /// <overloads>Resets the device and all its channels</overloads>
+        /// <summary>
+        /// Reset this device and all associated channels
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool ResetSystem(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            // Notify channels
+            NotifyDeviceEvent(DeviceNotificationCode.Reset, null);
+
+            return (ANT_ResetSystem(unmanagedANTFramerPtr, responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Reset this device and all associated channels
+        /// </summary>
+        public void ResetSystem(){ ResetSystem(500);}
+
+
+
+        /// <overloads>Sets a network key</overloads>
+        /// <summary>
+        /// Set the network key for the given network
+        /// Throws exception if net number is invalid or network key is not 8-bytes in length
+        /// </summary>
+        /// <param name="netNumber">The network number to set the key for</param>
+        /// <param name="networkKey">The 8-byte network key</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool setNetworkKey(byte netNumber, byte[] networkKey, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if (capabilities != null)
+            {
+                if (netNumber >= capabilities.maxNetworks)
+                    throw new ANT_Exception("Network number must be less than the maximum capable networks of the device");
+            }
+
+            if (networkKey.Length != 8)
+                throw new ANT_Exception("Network key must be 8 bytes");
+            bool result = (ANT_SetNetworkKey(unmanagedANTFramerPtr, netNumber, networkKey, responseWaitTime) == 1);
+            return result;
+        }
+        /// <summary>
+        /// Set the network key for the given network
+        /// Throws exception if net number is invalid or network key is not 8-bytes in length
+        /// </summary>
+        /// <param name="netNumber">The network number to set the key for</param>
+        /// <param name="networkKey">The 8-byte network key</param>
+        public void setNetworkKey(byte netNumber, byte[] networkKey) { setNetworkKey(netNumber, networkKey, 0); }
+
+
+                
+        /// <overloads>Sets the transmit power for all channels</overloads>
+        /// <summary>
+        /// Set the transmit power for all channels of this device
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to set to</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool setTransmitPowerForAllChannels(ANT_ReferenceLibrary.TransmitPower transmitPower, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetTransmitPower(unmanagedANTFramerPtr, (byte)transmitPower, responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Set the transmit power for all channels of this device
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to set to</param>
+        public void setTransmitPowerForAllChannels(ANT_ReferenceLibrary.TransmitPower transmitPower) { setTransmitPowerForAllChannels(transmitPower, 0); }
+
+
+
+        /// <summary>
+        /// When enabled advanced burst messages will be split into standard burst packets when received.
+        /// This is disabled by default.
+        /// </summary>
+        /// <param name="splitBursts">Whether to split advanced burst messages.</param>
+        /// <returns>True on success.</returns>
+        public bool configureAdvancedBurstSplitting(bool splitBursts)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_ConfigureSplitAdvancedBursts(unmanagedANTFramerPtr, (splitBursts ? 1 : 0)) == 1);
+        }
+
+
+        /// <summary>
+        /// Configure advanced bursting for this device.
+        /// </summary>
+        /// <param name="enable">Whether to enable advanced bursting messages</param>
+        /// <param name="maxPacketLength">Maximum packet length allowed for bursting messages (valid values are 1-3)</param>
+        /// <param name="requiredFields">Features that the application requires the device to use</param>
+        /// <param name="optionalFields">Features that the device should use if it supports them</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureAdvancedBursting(bool enable, byte maxPacketLength, ANT_ReferenceLibrary.AdvancedBurstConfigFlags requiredFields,
+            ANT_ReferenceLibrary.AdvancedBurstConfigFlags optionalFields, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_ConfigureAdvancedBurst(unmanagedANTFramerPtr, (enable ? 1 : 0), maxPacketLength,
+                (UInt32)requiredFields, (UInt32)optionalFields, responseWaitTime) == 1);
+        }
+
+
+        /// <summary>
+        /// Configure advanced bursting for this device.
+        /// </summary>
+        /// <param name="enable">Whether to enable advanced bursting messages</param>
+        /// <param name="maxPacketLength">Maximum packet length allowed for bursting messages (valid values are 1-3)</param>
+        /// <param name="requiredFields">Features that the application requires the device to use</param>
+        /// <param name="optionalFields">Features that the device should use if it supports them</param>
+        public void configureAdvancedBursting(bool enable, byte maxPacketLength, ANT_ReferenceLibrary.AdvancedBurstConfigFlags requiredFields,
+            ANT_ReferenceLibrary.AdvancedBurstConfigFlags optionalFields)
+        {
+            configureAdvancedBursting(enable, maxPacketLength, requiredFields, optionalFields, (UInt32)0);
+        }
+
+
+        /// <summary>
+        /// Configure advanced bursting for this device including extended parameters.
+        /// </summary>
+        /// <param name="enable">Whether to enable advanced bursting messages</param>
+        /// <param name="maxPacketLength">Maximum packet length allowed for bursting messages (valid values are 1-3)</param>
+        /// <param name="requiredFields">Features that the application requires the device to use</param>
+        /// <param name="optionalFields">Features that the device should use if it supports them</param>
+        /// <param name="stallCount">Maximum number of burst periods (~3.1ms) to stall for while waiting for the next message</param>
+        /// <param name="retryCount">Number of times (multiplied by 5) to retry burst</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureAdvancedBursting_ext(bool enable, byte maxPacketLength, ANT_ReferenceLibrary.AdvancedBurstConfigFlags requiredFields,
+            ANT_ReferenceLibrary.AdvancedBurstConfigFlags optionalFields, UInt16 stallCount, byte retryCount, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_ConfigureAdvancedBurst_ext(unmanagedANTFramerPtr, (enable ? 1 : 0), maxPacketLength,
+                (UInt32)requiredFields, (UInt32)optionalFields, stallCount, retryCount, responseWaitTime) == 1);
+        }
+
+
+        /// <summary>
+        /// Configure advanced bursting for this device including extended parameters.
+        /// </summary>
+        /// <param name="enable">Whether to enable advanced bursting messages</param>
+        /// <param name="maxPacketLength">Maximum packet length allowed for bursting messages (valid values are 1-3)</param>
+        /// <param name="requiredFields">Features that the application requires the device to use</param>
+        /// <param name="optionalFields">Features that the device should use if it supports them</param>
+        /// <param name="stallCount">Maximum number of burst periods (~3.1ms) to stall for while waiting for the next message</param>
+        /// <param name="retryCount">Number of times (multiplied by 5) to retry burst</param>
+        public void configureAdvancedBursting_ext(bool enable, byte maxPacketLength, ANT_ReferenceLibrary.AdvancedBurstConfigFlags requiredFields,
+            ANT_ReferenceLibrary.AdvancedBurstConfigFlags optionalFields, UInt16 stallCount, byte retryCount)
+        {
+            configureAdvancedBursting_ext(enable, maxPacketLength, requiredFields, optionalFields, stallCount, retryCount, 0);
+        }
+
+        public bool setCryptoKey(byte volatileKeyIndex, byte[] encryptionKey, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetCryptoKey(unmanagedANTFramerPtr, volatileKeyIndex, encryptionKey, responseWaitTime) == 1);
+        }
+
+        public void setCryptoKey(byte volatileKeyIndex, byte[] encryptionKey)
+        {
+            setCryptoKey(volatileKeyIndex, encryptionKey, 0);
+        }
+
+        public bool setCryptoID(byte[] encryptionID, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetCryptoID(unmanagedANTFramerPtr, encryptionID, responseWaitTime) == 1);
+        }
+
+        public void setCryptoID(byte[] encryptionID)
+        {
+            setCryptoID(encryptionID, 0);
+        }
+
+        public bool setCryptoUserInfo(byte[] userInfoString, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetCryptoUserInfo(unmanagedANTFramerPtr, userInfoString, responseWaitTime) == 1);
+        }
+
+        public void setCryptoUserInfo(byte[] userInfoString)
+        {
+            setCryptoUserInfo(userInfoString, 0);
+        }
+
+        public bool setCryptoRNGSeed(byte[] cryptoRNGSeed, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetCryptoRNGSeed(unmanagedANTFramerPtr, cryptoRNGSeed, responseWaitTime) == 1);
+        }
+
+        public void setCryptoRNGSeed(byte[] cryptoRNGSeed)
+        {
+            setCryptoRNGSeed(cryptoRNGSeed, 0);
+        }
+
+        public bool setCryptoInfo(ANT_ReferenceLibrary.EncryptionInfo encryptionParameter, byte[] parameterData, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_SetCryptoInfo(unmanagedANTFramerPtr, (byte)encryptionParameter, parameterData, responseWaitTime) == 1);
+        }
+
+        public void setCryptoInfo(ANT_ReferenceLibrary.EncryptionInfo encryptionParameter, byte[] parameterData)
+        {
+            setCryptoInfo(encryptionParameter, parameterData, 0);
+        }
+
+        public bool loadCryptoKeyFromNVM(byte nonVolatileKeyIndex, byte volatileKeyIndex, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_LoadCryptoKeyNVMOp(unmanagedANTFramerPtr, nonVolatileKeyIndex, volatileKeyIndex, responseWaitTime) == 1);
+        }
+
+        public void loadCryptoKeyFromNVM(byte nonVolatileKeyIndex, byte volatileKeyIndex)
+        {
+            loadCryptoKeyFromNVM(nonVolatileKeyIndex, volatileKeyIndex, 0);
+        }
+
+        public bool storeCryptoKeyToNVM(byte nonVolatileKeyIndex, byte[] encryptionKey, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_StoreCryptoKeyNVMOp(unmanagedANTFramerPtr, nonVolatileKeyIndex, encryptionKey, responseWaitTime) == 1);
+        }
+
+        public void storeCryptoKeyToNVM(byte nonVolatileKeyIndex, byte[] encryptionKey)
+        {
+            storeCryptoKeyToNVM(nonVolatileKeyIndex, encryptionKey, 0);
+        }
+
+        public bool cryptoKeyNVMOp(ANT_ReferenceLibrary.EncryptionNVMOp memoryOperation, byte nonVolatileKeyIndex, byte[] operationData, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_CryptoKeyNVMOp(unmanagedANTFramerPtr, (byte)memoryOperation, nonVolatileKeyIndex, operationData, responseWaitTime) == 1);
+        }
+
+        public void cryptoKeyNVMOp(ANT_ReferenceLibrary.EncryptionNVMOp memoryOperation, byte nonVolatileKeyIndex, byte[] operationData)
+        {
+            cryptoKeyNVMOp(memoryOperation, nonVolatileKeyIndex, operationData, 0);
+        }
+
+        /// <overloads>Enables/Disables the device's LED</overloads>
+        /// <summary>
+        /// Enables/Disables the LED flashing when a transmission event occurs
+        /// </summary>
+        /// <param name="IsEnabled">Desired state</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool EnableLED(bool IsEnabled, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return (ANT_EnableLED(unmanagedANTFramerPtr, Convert.ToByte(IsEnabled), responseWaitTime) == 1);
+        }
+        /// <summary>
+        /// Enables/Disables the LED flashing when a transmission event occurs
+        /// </summary>
+        /// <param name="IsEnabled">Desired state</param>
+        public void EnableLED(bool IsEnabled) { EnableLED(IsEnabled, 0); }
+
+        /// <overloads>Configures Event Buffering</overloads>
+        /// <summary>
+        /// Allows buffering of ANT events.  Preset groups of events may be selected for buffering.  
+        /// Events may be buffered by size or time and buffering can be used in conjunction with filtering.    
+        /// </summary>
+        /// <param name="config">Selects which events are buffered</param>
+        /// <param name="size">Number of bytes that will be stored before a buffer flush occurs.  Set to 0 to disable.</param>
+        /// <param name="time">Maximum time (in 10ms units) before a buffer flush occurs.  Set to 0 to disable.  
+        /// Buffer size must also be set to a non zero value.</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureEventBuffer(ANT_ReferenceLibrary.EventBufferConfig config, UInt16 size, UInt16 time, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           return ANT_ConfigEventBuffer(unmanagedANTFramerPtr, (byte)config, size, time, responseWaitTime) == 1;
+        }
+        /// <summary>        
+        /// Allows buffering of ANT events.  Preset groups of events may be selected for buffering.  
+        /// Events may be buffered by size or time and buffering can be used in conjunction with filtering.    
+        /// </summary>
+        /// <param name="config">Selects which events are buffered</param>
+        /// <param name="size">Number of bytes that will be stored before a buffer flush occurs.  Set to 0 to disable.</param>
+        /// <param name="time">Maximum time (in 10ms units) before a buffer flush occurs.  Set to 0 to disable.  
+        /// Buffer size must also be set to a non zero value.</param>
+        public void configureEventBuffer(ANT_ReferenceLibrary.EventBufferConfig config, UInt16 size, UInt16 time) { configureEventBuffer(config, size, time, 0); }
+
+        /// <overloads>Configures Event Filtering</overloads>
+        /// <summary>
+        /// Allows filtering of specified ANT events.  Filtering can be used in conjunction with buffering. 
+        /// </summary>
+        /// <param name="eventFilter">Bitfield of events to filter.  Set Bit0 to filter event 0 etc.</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureEventFilter(UInt16 eventFilter, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           return ANT_ConfigEventFilter(unmanagedANTFramerPtr, eventFilter, responseWaitTime) == 1;
+        }
+        /// <summary>        
+        /// Allows filtering of specified ANT events.  Filtering can be used in conjunction with buffering. 
+        /// </summary>
+        /// <param name="eventFilter">Bitfield of events to filter.  Set Bit0 to filter event 0 etc.</param>        
+        public void configureEventFilter(UInt16 eventFilter) { configureEventFilter(eventFilter, 0); }
+
+        /// <overloads>Configures High Duty Search</overloads>
+        /// <summary>
+        /// Allows configuring High Duty Search if no channels have been opened yet
+        /// </summary>
+        /// <param name="enable">Enable or disable High Duty Search</param>        
+        /// <param name="suppressionCycles">Search period to suppress high duty search in units of 250ms.  0=Allow full time, 5=Suppress entirely</param>        
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureHighDutySearch(bool enable, byte suppressionCycles, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           return ANT_ConfigHighDutySearch(unmanagedANTFramerPtr, (enable ? (byte)1 : (byte)0), suppressionCycles, responseWaitTime) == 1;
+        }             
+        /// <summary>        
+        /// Allows configuring High Duty Search if no channels have been opened yet
+        /// </summary>
+        /// <param name="enable">Enable or disable High Duty Search</param>        
+        /// <param name="suppressionCycles">Search period to suppress high duty search in units of 250ms.  0=Allow full time, 5=Suppress entirely</param>        
+        public void configureHighDutySearch(bool enable, byte suppressionCycles) { configureHighDutySearch(enable, suppressionCycles, 0); }
+
+        /// <overloads>Allows defining a new Selective Data Update Mask</overloads>
+        /// <summary>
+        /// Allows defining a new Selective Data Update Mask
+        /// </summary>
+        /// <param name="maskNumber">Identifier for the SDU Mask</param>        
+        /// <param name="mask">Rx Data Message Mask, 0=Ignore, 1=Update on Change</param>        
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool setSduMask(byte maskNumber, byte[] mask, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           return ANT_SetSelectiveDataUpdateMask(unmanagedANTFramerPtr, maskNumber, mask, responseWaitTime) == 1;
+        }
+        /// <summary>        
+        /// Allows defining a new Selective Data Update Mask
+        /// </summary>
+        /// <param name="maskNumber">Identifier for the SDU Mask</param>        
+        /// <param name="mask">Rx Data Message Mask, 0=Ignore, 1=Update on Change</param>        
+        public void setSduMask(byte maskNumber, byte[] mask) { setSduMask(maskNumber, mask, 0); }
+
+       /// <overloads>Configures User NVM</overloads>
+        /// <summary>
+        /// Allows configuring User NVM if available.
+        /// </summary>
+        /// <param name="address"> Nvm starting address</param>        
+        /// <param name="data">Data block to write</param>        
+        /// <param name="size">Size of data block</param>        
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool configureUserNvm(UInt16 address, byte[] data, byte size, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           return ANT_ConfigUserNVM(unmanagedANTFramerPtr, address, data, size, responseWaitTime) == 1;
+        }
+        /// <summary>        
+        /// Allows configuring User Nvm if available.
+        /// </summary>
+        /// <param name="address"> Nvm starting address</param>        
+        /// <param name="data">Data block to write</param>        
+        /// <param name="size">Size of data block</param>        
+        public void configureUserNvm(UInt16 address, byte[] data, byte size) { configureUserNvm(address, data, size, 0); }
+
+        /// <overloads>Requests a message from the device and returns the response</overloads>
+        /// <summary>
+        /// Read User Nvm by sending Request Mesg capturing the response.        
+        /// Throws exception on timeout.
+        /// </summary>                
+        /// <param name="address">NVM Address to read from</param>
+        /// <param name="size">Number of bytes to read</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        public ANT_Response readUserNvm(UInt16 address, byte size, UInt32 responseWaitTime)
+        {
+           if (!initializedUSB)
+              throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+           ANTMessageItem response = new ANTMessageItem();
+           if (ANT_RequestUserNvmMessage(unmanagedANTFramerPtr, 0, (byte)ANT_ReferenceLibrary.RequestMessageID.USER_NVM_0x7C, ref response, address, size, responseWaitTime) == 0)
+              throw new ANT_Exception("Timed out waiting for requested message");
+           ANT_Response retVal = new ANT_Response(this, 0, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray());
+           return retVal;
+        }
+        /// <summary>
+        /// Read User Nvm by sending Request Mesg capturing the response.        
+        /// Throws exception on timeout.
+        /// </summary>        
+        /// <param name="address">NVM Address to read from</param>
+        /// <param name="size">Number of bytes to read</param>        
+        public ANT_Response readUserNvm(UInt16 address, byte size)
+        {
+           return readUserNvm(address, size, 500);
+        }
+
+        /// <summary>
+        /// Obtains the PID (Product ID) of the USB device.
+        /// Throws an exception if the PID is not received.
+        /// </summary>
+        /// <returns>PID of the USB device.</returns>
+        public UInt16 getDeviceUSBPID()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            UInt16 returnPID = 0;           
+
+            if(ANT_GetDeviceUSBPID(unmanagedANTFramerPtr, ref returnPID) != 1)
+                throw new ANT_Exception("Retrieving Device USB PID failed");
+            return (returnPID);
+        }
+
+
+        /// <summary>
+        /// Obtains the VID (Vendor ID) of the USB device
+        /// </summary>
+        /// <returns>VID of the USB device</returns>
+        public UInt16 getDeviceUSBVID()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            UInt16 returnVID = 0;
+
+            if (ANT_GetDeviceUSBVID(unmanagedANTFramerPtr, ref returnVID) != 1)
+                throw new ANT_Exception("Retrieving Device USB VID failed");
+            return (returnVID);
+        }
+
+
+        /// <summary>
+        /// Returns the USB device serial number.
+        /// This can be used to figure out the serial number if the option to use the USB device
+        /// serial number was selected.
+        /// </summary>
+        /// <returns>Client serial number</returns>
+        public uint getSerialNumber()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_GetDeviceSerialNumber(unmanagedANTSerialPtr);
+        }
+
+
+        /// <overloads>Obtains the device USB Information</overloads>
+        /// <summary>
+        /// Obtains the USB information for the device
+        /// Throws an exception if no information is received
+        /// </summary>
+        /// <param name="deviceNum">USB Device Number</param>
+        /// <returns>USB Device Information</returns>
+        public ANT_DeviceInfo getDeviceUSBInfo(byte deviceNum)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            byte[] returnProdDescription = new byte[256];   // size should match that defined on the Unmanaged Wrapper
+            byte[] returnSerialString = new byte[256];
+
+            if (ANT_GetDeviceUSBInfo(unmanagedANTFramerPtr, deviceNum, returnProdDescription, returnSerialString) != 1)
+                throw new ANT_Exception("Retrieving USB device information failed");
+
+            return (new ANT_DeviceInfo(returnProdDescription, returnSerialString));
+        }
+
+
+        /// <summary>
+        /// Obtains the USB information for the device
+        /// Throws an exception if no information is received
+        /// </summary>
+        /// <returns>USB Device Information</returns>
+        public ANT_DeviceInfo getDeviceUSBInfo()
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return getDeviceUSBInfo(USBDeviceNum);
+        }
+
+
+
+
+        /// <overloads>Requests a message from the device and returns the response</overloads>
+        /// <summary>
+        /// Request a message from device and returns the response. 
+        /// Throws exception on timeout.
+        /// </summary>
+        /// <param name="channelNum">Channel to send request on</param>
+        /// <param name="messageID">Request to send</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        public ANT_Response requestMessageAndResponse(byte channelNum, ANT_ReferenceLibrary.RequestMessageID messageID, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            ANTMessageItem response = new ANTMessageItem();
+            if (ANT_RequestMessage(unmanagedANTFramerPtr, channelNum, (byte)messageID, ref response, responseWaitTime) == 0)
+                throw new ANT_Exception("Timed out waiting for requested message");
+            ANT_Response retVal = new ANT_Response(this, channelNum, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray());
+            return retVal;
+        }
+        /// <summary>
+        /// Request a message from device on channel 0 and returns the response. 
+        /// Throws exception on timeout.
+        /// </summary>
+        /// <param name="messageID">Request to send</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        public ANT_Response requestMessageAndResponse(ANT_ReferenceLibrary.RequestMessageID messageID, UInt32 responseWaitTime)
+        {
+            return requestMessageAndResponse(0, messageID, responseWaitTime);
+        }
+
+        /// <overloads>Requests a message from the device</overloads>
+        /// <summary>
+        /// Request a message from device
+        /// </summary>
+        /// <param name="channelNum">Channel to send request on</param>
+        /// <param name="messageID">Request to send</param>
+        public void requestMessage(byte channelNum, ANT_ReferenceLibrary.RequestMessageID messageID)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+            ANTMessageItem dummystruct = new ANTMessageItem();
+            ANT_RequestMessage(unmanagedANTFramerPtr, channelNum, (byte)messageID, ref dummystruct, 0);
+
+        }
+        /// <summary>
+        /// Request a message from device
+        /// </summary>
+        /// <param name="messageID">Request to send</param>
+        public void requestMessage(ANT_ReferenceLibrary.RequestMessageID messageID)
+        {
+            requestMessage(0, messageID);
+        }
+
+
+
+        /// <overloads>Set device in continuous scanning mode</overloads>
+        /// <summary>
+        /// Starts operation in continuous scanning mode.
+        /// This allows the device to receive all messages matching the configured channel ID mask in an asynchronous manner.
+        /// This feature is not available on all ANT devices.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool openRxScanMode(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_OpenRxScanMode(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Starts operation in continuous scanning mode.
+        /// This allows the device to receive all messages matching the configured channel ID mask in an asynchronous manner.
+        /// </summary>
+        public void openRxScanMode() { openRxScanMode(0); }
+
+
+
+        /// <overloads>Initializes and starts CW test mode</overloads>
+        /// <summary>
+        /// Initialize and start CW test mode. This mode is to test your implementation for RF frequency requirements.
+        /// The device will transmit an unmodulated carrier wave at the RF frequency of 2400Mhz + RFFreqOffset at the specified power level.
+        /// This mode can then only be exited by a system reset.
+        /// Note: When this function call returns false, the system will be reset automatically.
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to test at</param>
+        /// <param name="RFFreqOffset">Offset to add to 2400Mhz</param>
+        /// <param name="responseWaitTime">Time to wait for response, used for both initialization and start command</param>
+        /// <returns>False if initialization or starting of CW test mode fails. On false, the system is automatically reset.</returns>
+        /// <remarks>
+        /// This function encapsulates both ANT_InitCWTestMode and ANT_SetCWTestMode from the old library.
+        /// It will automatically reset the system if either call fails. 
+        /// The given response time is used for both calls and the reset time is 500ms. 
+        /// So max wait time = responseTime*2 + 500ms 
+        /// </remarks>
+        public bool startCWTest(ANT_ReferenceLibrary.TransmitPower transmitPower, byte RFFreqOffset, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            bool retVal = true;
+            ResetSystem();  //CW Mode is only supposed to be set up after a reset
+            if (ANT_InitCWTestMode(unmanagedANTFramerPtr, responseWaitTime) != 1)
+                retVal = false;
+            if (ANT_SetCWTestMode(unmanagedANTFramerPtr, (byte)transmitPower, RFFreqOffset, responseWaitTime) != 1)
+                retVal = false;
+            if (retVal == false && ANT_Common.autoResetIsEnabled) //If we messed up we want to make sure the module doesn't get messed up in CW mode, so we reset
+                ResetSystem(500);
+            return retVal;
+        }
+
+
+
+        /// <overloads>Enables extended message reception</overloads>
+        /// <summary>
+        /// Enables extended message receiving. When enabled, messages received will contain extended data.
+        /// </summary>
+        /// <param name="IsEnabled">Desired State</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool enableRxExtendedMessages(bool IsEnabled, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_RxExtMesgsEnable(unmanagedANTFramerPtr, Convert.ToByte(IsEnabled), responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Enables extended message receiving. When enabled, messages received will contain extended data.
+        /// </summary>
+        /// <param name="IsEnabled">Desired State</param>
+        public void enableRxExtendedMessages(bool IsEnabled) { enableRxExtendedMessages(IsEnabled, 0); }
+
+
+
+        /// <overloads>Enables the use of external 32kHz crystal</overloads>
+        /// <summary>
+        /// If the use of an external 32kHz crystal input is desired, this message must be sent once, each time a startup message is received
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        /// <remarks> Enabling an external 32kHz crystal input as a low power clock source saves ~85uA while ANT is active when compared to using the internal clock source. </remarks>
+        public bool crystalEnable(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_CrystalEnable(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// If the use of an external 32kHz crystal input is desired, this message must be sent once, each time a startup message is received
+        /// </summary>
+        /// <remarks> Enabling an external 32kHz crystal input as a low power clock source saves ~85uA while ANT is active when compared to using the internal clock source. </remarks>
+        public void crystalEnable() { crystalEnable(0); }
+
+
+
+
+        /// <summary>
+        /// Writes a message to the device, this function allows sending manually formatted messages.
+        /// </summary>
+        /// <param name="msgID">msgID to write</param>
+        /// <param name="msgData">data buffer to write</param>
+        /// <returns>False if writing bytes to device fails</returns>
+        public bool writeRawMessageToDevice(byte msgID, byte[] msgData)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            //Create ANT_MESSAGE
+            ANTMessage aMsg = new ANTMessage();
+            aMsg.msgID = msgID;
+
+            //We create an array of max size, because the struct sizing expects a constant size array
+            int padNum = ANT_ReferenceLibrary.MAX_MESG_SIZE - msgData.Length;
+            if(padNum < 0)
+                throw new ANT_Exception("msgData max length is " + ANT_ReferenceLibrary.MAX_MESG_SIZE + " bytes");
+            aMsg.ucharBuf = msgData.Concat(new byte[padNum]).ToArray();
+            
+            return ANT_WriteMessage(unmanagedANTFramerPtr, aMsg, (UInt16)msgData.Length) == 1; 
+        }
+
+        /// <overloads>Configure the device ANT library, ie: to send extra msg info</overloads>
+        /// <summary>
+        /// Configure the device ANT library, ie: to send extra msg info
+        /// </summary>
+        /// <param name="libConfigFlags">Config flags</param>
+        /// <param name="responseWaitTime">Time to wait for response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool setLibConfig(ANT_ReferenceLibrary.LibConfigFlags libConfigFlags, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_SetLibConfig(unmanagedANTFramerPtr, (byte)libConfigFlags, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Configure the device ANT library, ie: to send extra msg info
+        /// </summary>
+        /// <param name="libConfigFlags">Config flags</param>
+        public void setLibConfig(ANT_ReferenceLibrary.LibConfigFlags libConfigFlags) { setLibConfig(libConfigFlags, 0); }
+
+
+
+
+        #region SensRcore NVM script commands
+        /// <overloads>Writes a SensRCore command to non-volatile memory</overloads>
+        /// <summary>
+        /// Writes a SensRcore command to non-volatile memory.
+        /// Throws exception if command string length > 255, although commands will be much smaller
+        /// </summary>
+        /// <param name="commandString">SensRcore command to write: [Cmd][CmdData0]...[CmdDataN], must be less than 256 bytes</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_Write(byte[] commandString, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if(!(commandString.Length < 256))   //We are casting to byte, so we need to be safe
+                throw new ANT_Exception("commandString max size is 255");
+            return ANT_Script_Write(unmanagedANTFramerPtr, (byte)commandString.Length, commandString, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Writes a SensRcore command to non-volatile memory.
+        /// Throws exception if command string length > 255.
+        /// </summary>
+        /// <param name="commandString">SensRcore command to write: [Cmd][CmdData0]...[CmdDataN], must be less than 256 bytes</param>
+        public void script_Write(byte[] commandString) { script_Write(commandString, 0); }
+
+
+
+
+        /// <overloads>Clears the NVM</overloads>
+        /// <summary>
+        /// Clears the non-volatile memory. NVM should be cleared before beginning write operations.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_Clear(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_Script_Clear(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Clears the non-volatile memory. NVM should be cleared before beginning write operations.
+        /// </summary>
+        public void script_Clear() { script_Clear(0); }
+
+
+
+        /// <overloads>Sets the default SensRCore sector</overloads>
+        /// <summary>
+        /// Set the default sector which will be executed after mandatory execution of sector 0.
+        /// This command has no effect if it is set to 0 or the Read Pins for Sector command appears in sector 0.
+        /// </summary>
+        /// <param name="sectorNum">sector number to set as default</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_setDefaultSector(byte sectorNum, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_Script_SetDefaultSector(unmanagedANTFramerPtr, sectorNum, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Set the default sector which will be executed after mandatory execution of sector 0.
+        /// This command has no effect if it is set to 0 or the Read Pins for Sector command appears in sector 0.
+        /// </summary>
+        /// <param name="sectorNum">sector number to set as default</param>
+        public void script_setDefaultSector(byte sectorNum) { script_setDefaultSector(sectorNum, 0); }
+
+
+
+
+        /// <overloads>Writes a sector break to NVM</overloads>
+        /// <summary>
+        /// Writes a sector break in the NVM image
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_endSector(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_Script_EndSector(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Writes a sector break in the NVM image
+        /// </summary>
+        public void script_endSector() { script_endSector(0); }
+
+
+
+
+        /// <overloads>Request a dump of the device's script memory</overloads>
+        /// <summary>
+        /// Requests the device to return the current NVM contents through the device callback function.
+        /// The end of the dump is signified by a 0x57 NVM_Cmd msg, which contains 0x04 EndDump code followed by 
+        /// a byte signifying how many instructions were read and returned.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_requestNVMDump(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_Script_Dump(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Requests the device to return the current NVM contents through the device callback function.
+        /// The end of the dump is signified by a 0x57 NVM_Cmd msg, which contains 0x04 EndDump code followed by 
+        /// a byte signifying how many instructions were read and returned.
+        /// </summary>
+        public void script_requestNVMDump() { script_requestNVMDump(0); }
+
+
+
+        /// <overloads>Locks the NVM contents</overloads>
+        /// <summary>
+        /// Locks the NVM so that it can not be read by the dump function. 
+        /// Can only be disabled by clearing the NVM.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        public bool script_lockNVM(UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            return ANT_Script_Lock(unmanagedANTFramerPtr, responseWaitTime) == 1;
+        }
+        /// <summary>
+        /// Locks the NVM so that it can not be read by the dump function. 
+        /// Can only be disabled by clearing the NVM.
+        /// </summary>
+        public void script_lockNVM() { script_lockNVM(0); }
+
+
+
+        ///<overloads>Sets the equipment state</overloads>
+        /// <summary>
+        /// Sets the equipment state.
+        /// This command is specifically for use with the FIT1e module.
+        /// </summary>
+        /// <param name="feState">Fitness equipment state</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success.  Note: Always returns true with a response time of 0</returns>
+        public bool fitSetFEState(byte feState, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if (!capabilities.FIT)  // Check this is a FIT1e module
+                return false;
+
+            return FIT_SetFEState(unmanagedANTFramerPtr, feState, responseWaitTime) == 1;
+        }
+
+        /// <summary>
+        /// Sets the equipment state.
+        /// This command is specifically for use with the FIT1e module.
+        /// </summary>
+        /// <param name="feState">Fitness equipment state</param>
+        public void fitSetFEState(byte feState) { fitSetFEState(feState, 0);}
+
+        /// <summary>
+        /// Adjusts the pairing distance settings.
+        /// This command is specifically for use with the FIT1e module.
+        /// </summary>
+        /// <param name="searchLv">Minimum signal strength for a signal to be considered for pairing.</param>
+        /// <param name="pairLv">Signal strength required for the FIT1e to pair with an ANT+ HR strap or watch</param>
+        /// <param name="trackLv">An ANT+ device will unpair if the signal strength drops below this setting while in
+        /// READY state or within the first 30 secons of the IN_USE state</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success.  Note: Always returns true with a response time of 0</returns>
+        public bool fitAdjustPairingSettings(byte searchLv, byte pairLv, byte trackLv, UInt32 responseWaitTime)
+        {
+            if (!initializedUSB)
+                throw new ObjectDisposedException("ANTDevice object has been disposed");
+
+            if (!capabilities.FIT)  // Check this is a FIT1e module
+                return false;
+
+            return FIT_AdjustPairingSettings(unmanagedANTFramerPtr, searchLv, pairLv, trackLv, responseWaitTime) == 1;
+        }
+
+        /// <summary>
+        /// Adjusts the pairing distance settings.
+        /// This command is specifically for use with the FIT1e module.
+        /// </summary>
+        /// <param name="searchLv">Minimum signal strength for a signal to be considered for pairing.</param>
+        /// <param name="pairLv">Signal strength required for the FIT1e to pair with an ANT+ HR strap or watch</param>
+        /// <param name="trackLv">An ANT+ device will unpair if the signal strength drops below this setting while in
+        /// READY state or within the first 30 secons of the IN_USE state</param>
+        public void fitAdjustPairingSettings(byte searchLv, byte pairLv, byte trackLv)
+        {
+            fitAdjustPairingSettings(searchLv, pairLv, trackLv, 0);
+        }
+        #endregion
+                
+        #endregion
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Device.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: abf02afb1063ed84f92fbf5a4a459f81
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 346 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceCapabilities.cs

@@ -0,0 +1,346 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Container for all the device capability information, returned from an ANTDevice
+    /// </summary>
+    public class ANT_DeviceCapabilities
+    {
+        /// <summary>
+        /// Number of channels available
+        /// </summary>
+        public readonly byte maxANTChannels;   //byte 0
+
+        /// <summary>
+        /// Number of simultaneous networks allowed
+        /// </summary>
+        public readonly byte maxNetworks;      //byte 1
+
+        //TODO: Document all the capabilities
+#pragma warning disable 1591
+        //Basic Capabilities - byte 2
+        public readonly bool NoReceiveChannels;
+        public readonly bool NoTransmitChannels;
+        public readonly bool NoReceiveMessages;
+        public readonly bool NoTransmitMessages;
+        public readonly bool NoAckMessages;
+        public readonly bool NoBurstMessages;
+
+        //Advanced Capabilities - byte 3
+        public readonly bool PrivateNetworks;
+        public readonly bool SerialNumber;
+        public readonly bool perChannelTransmitPower;
+        public readonly bool lowPrioritySearch;
+        public readonly bool ScriptSupport;
+        public readonly bool SearchList;
+
+        //Advanced Capabilities 2 - byte 4
+        public readonly bool OnboardLED;
+        public readonly bool ExtendedMessaging;
+        public readonly bool ScanModeSupport;
+        public readonly bool ExtendedChannelAssignment;
+        public readonly bool ProximitySearch;
+        public readonly bool FS;
+        public readonly bool FIT;
+
+        //Advanced Capabilities 3 - byte 6
+        public readonly bool AdvancedBurst;
+        public readonly bool EventBuffering;
+        public readonly bool EventFiltering;
+        public readonly bool HighDutySearch;
+        public readonly bool SelectiveDataUpdate;
+        public readonly bool SingleChannelEncryption;
+
+
+#pragma warning restore 1591
+
+        /// <summary>
+        /// Number of SensRcore data channels available
+        /// </summary>
+        public readonly byte maxDataChannels;  //byte 5
+
+        internal ANT_DeviceCapabilities(byte[] capabilitiesData)
+        {
+            if (capabilitiesData.Length != 16)
+                throw new ANT_Exception("This function only decodes capabilities data of exactly length 16");
+
+            maxANTChannels = capabilitiesData[0];
+            maxNetworks = capabilitiesData[1];            
+
+            //Now decode all the bit fields
+            //Basic Capabilities - 3rd byte
+            NoReceiveChannels = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_RX_CHANNELS) != 0);
+            NoTransmitChannels = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_TX_CHANNELS) != 0);
+            NoReceiveMessages = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_RX_MESSAGES) != 0);
+            NoTransmitMessages = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_TX_MESSAGES) != 0);
+            NoAckMessages = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_ACKD_MESSAGES) != 0);
+            NoBurstMessages = ((capabilitiesData[2] & (byte)BasicCapabilitiesMasks.NO_BURST_TRANSFER) != 0);
+
+            //Advanced Capabilities - 4th byte
+            PrivateNetworks = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.NETWORK_CAPABLE) != 0);
+            SerialNumber = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.SERIAL_NUMBER_CAPABLE) != 0);
+            perChannelTransmitPower = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.PER_CHANNEL_TX_POWER_CAPABLE) != 0);
+            lowPrioritySearch = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.LOW_PRIORITY_SEARCH_CAPABLE) != 0);
+            ScriptSupport = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.SCRIPT_CAPABLE) != 0);
+            SearchList = ((capabilitiesData[3] & (byte)AdvancedCapabilitiesMasks.SEARCH_LIST_CAPABLE) != 0);
+
+            //Advanced Capabilities 2 - 5th byte
+            OnboardLED = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.LED_CAPABLE) != 0);
+            ExtendedMessaging = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.EXT_MESSAGE_CAPABLE) != 0);
+            ScanModeSupport = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.SCAN_MODE_CAPABLE) != 0);            
+            ProximitySearch = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.PROX_SEARCH_CAPABLE) != 0);
+            ExtendedChannelAssignment = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.EXT_ASSIGN_CAPABLE) != 0);
+            FS = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.FS_ANTFS_ENABLED) != 0);
+            FIT = ((capabilitiesData[4] & (byte)AdvancedCapabilities2Masks.FIT1_CAPABLE) != 0);
+
+            //SensorCore Data Channels - 6th byte
+            maxDataChannels = capabilitiesData[5];
+
+            //Advanced Capabilities 3 - 7th byte
+            AdvancedBurst = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.ADVANCED_BURST_CAPABLE) != 0);
+            EventBuffering = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.EVENT_BUFFERING_CAPABLE) != 0);
+            EventFiltering = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.EVENT_FILTERING_CAPABLE) != 0);
+            HighDutySearch = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.HIGH_DUTY_SEARCH_CAPABLE) != 0);
+            SelectiveDataUpdate = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.SELECTIVE_DATA_UPDATE) != 0);
+            SingleChannelEncryption = ((capabilitiesData[6] & (byte)AdvancedCapabilities3Masks.ENCRYPTED_CHANNEL_CAPABLE) != 0);
+
+        }
+
+        /// <summary>
+        /// Prints a string containing a formatted, readable version of all the capabilities
+        /// </summary>
+        public String printCapabilities()
+        {
+            StringBuilder returnString = new StringBuilder();
+            returnString.AppendLine( "Max ANT Channels: " + maxANTChannels);
+            returnString.AppendLine( "Max Networks: " + maxNetworks);
+            returnString.AppendLine( "Max Data Channels: " + maxDataChannels);
+            returnString.AppendLine( "Capabilities:");
+            //Basic
+            if(NoReceiveChannels)
+                returnString.AppendLine("-No Receive Channels");
+            if (NoTransmitChannels)
+                returnString.AppendLine("-No Transmit Channels");
+            if (NoReceiveMessages)
+                returnString.AppendLine("-No Receive Messages");
+            if (NoTransmitMessages)
+                returnString.AppendLine("-No Transmit Messages");
+            if (NoAckMessages)
+                returnString.AppendLine("-No Acknowledged Messaging");
+            if (NoBurstMessages)
+                returnString.AppendLine("-No Burst Messaging");
+            //Advanced
+            if (PrivateNetworks)
+                returnString.AppendLine("-Private Networks");
+            if (SerialNumber)
+                returnString.AppendLine("-Serial Number");
+            if (perChannelTransmitPower)
+                returnString.AppendLine("-Per Channel Tx Power");
+            if (lowPrioritySearch)
+                returnString.AppendLine("-Low Priority Search");
+            if (ScriptSupport)
+                returnString.AppendLine("-Script Support");
+            if (SearchList)
+                returnString.AppendLine("-Search List");
+            //Advanced 2
+            if (OnboardLED)
+                returnString.AppendLine("-Onboard LED");
+            if (ExtendedMessaging)
+                returnString.AppendLine("-Extended Messaging");
+            if (ScanModeSupport)
+                returnString.AppendLine("-Scan Channel Support");
+            if (ExtendedChannelAssignment)
+                returnString.AppendLine("-Ext Channel Assignment");
+            if (ProximitySearch)
+                returnString.AppendLine("-Proximity Search");
+            if (FS)
+                returnString.AppendLine("-FS");
+            if (FIT)
+                returnString.AppendLine("-FIT");
+            //Advanced 3
+            if (AdvancedBurst)
+                returnString.AppendLine("-Advanced Burst");
+            if (EventBuffering)
+                returnString.AppendLine("-Event Buffering");
+            if (EventFiltering)
+                returnString.AppendLine("-Event Filtering");
+            if (HighDutySearch)
+                returnString.AppendLine("-High Duty Search");
+            if (SelectiveDataUpdate)
+                returnString.AppendLine("-Selective Data Update");
+            if (SingleChannelEncryption)
+                returnString.AppendLine("-Single Channel Encryption");
+
+            return returnString.ToString();
+        }
+
+        /// <summary>
+        /// Prints a compact string containing a formatted, readable version of just the standard capabilities
+        /// </summary>
+        public String printStandardCapabilities()
+        {
+           StringBuilder returnString = new StringBuilder();
+           returnString.AppendLine("Max ANT Channels: " + maxANTChannels);
+           returnString.AppendLine("Max Networks: " + maxNetworks);
+           returnString.AppendLine("Max Data Channels: " + maxDataChannels);           
+           //Basic
+           if (NoReceiveChannels)
+              returnString.AppendLine("-No Receive Channels");
+           if (NoTransmitChannels)
+              returnString.AppendLine("-No Transmit Channels");
+           if (NoReceiveMessages)
+              returnString.AppendLine("-No Receive Messages");
+           if (NoTransmitMessages)
+              returnString.AppendLine("-No Transmit Messages");
+           if (NoAckMessages)
+              returnString.AppendLine("-No Acknowledged Messaging");
+           if (NoBurstMessages)
+              returnString.AppendLine("-No Burst Messaging");
+           
+           return returnString.ToString();
+        }
+
+        /// <summary>
+        /// Prints a string containing a formatted, readable version of all the advanced capabilities
+        /// </summary>
+        public String printAdvCapabilities()
+        {
+           StringBuilder returnString = new StringBuilder();           
+           returnString.AppendLine("Adv Capabilities:");
+           //Basic
+           if (NoReceiveChannels)
+              returnString.AppendLine("-No Receive Channels");
+           if (NoTransmitChannels)
+              returnString.AppendLine("-No Transmit Channels");
+           if (NoReceiveMessages)
+              returnString.AppendLine("-No Receive Messages");
+           if (NoTransmitMessages)
+              returnString.AppendLine("-No Transmit Messages");
+           if (NoAckMessages)
+              returnString.AppendLine("-No Acknowledged Messaging");
+           if (NoBurstMessages)
+              returnString.AppendLine("-No Burst Messaging");
+           //Advanced
+           if (PrivateNetworks)
+              returnString.AppendLine("-Private Networks");
+           if (SerialNumber)
+              returnString.AppendLine("-Serial Number");
+           if (perChannelTransmitPower)
+              returnString.AppendLine("-Per Channel Tx Power");
+           if (lowPrioritySearch)
+              returnString.AppendLine("-Low Priority Search");
+           if (ScriptSupport)
+              returnString.AppendLine("-Script Support");
+           if (SearchList)
+              returnString.AppendLine("-Search List");
+           //Advanced 2
+           if (OnboardLED)
+              returnString.AppendLine("-Onboard LED");
+           if (ExtendedMessaging)
+              returnString.AppendLine("-Extended Messaging");
+           if (ScanModeSupport)
+              returnString.AppendLine("-Scan Channel Support");
+           if (ExtendedChannelAssignment)
+              returnString.AppendLine("-Ext Channel Assignment");
+           if (ProximitySearch)
+              returnString.AppendLine("-Proximity Search");
+           if (FS)
+              returnString.AppendLine("-FS");
+           if (FIT)
+              returnString.AppendLine("-FIT");
+           //Advanced 3
+           if (AdvancedBurst)
+              returnString.AppendLine("-Advanced Burst");
+           if (EventBuffering)
+              returnString.AppendLine("-Event Buffering");
+           if (EventFiltering)
+              returnString.AppendLine("-Event Filtering");
+           if (HighDutySearch)
+              returnString.AppendLine("-High Duty Search");
+           if (SelectiveDataUpdate)
+              returnString.AppendLine("-Selective Data Update");
+           if (SingleChannelEncryption)
+              returnString.AppendLine("-Single Channel Encryption");
+
+           return returnString.ToString();
+        }
+
+        /// <summary>
+        /// Returns a formatted, readable string of all the capabilities
+        /// </summary>
+        public override String ToString() { return printCapabilities(); }
+
+#pragma warning disable 1591
+        /// <summary>
+        /// Basic Capabilities Masks (3rd Byte)
+        /// </summary>
+        public enum BasicCapabilitiesMasks : byte
+        {
+            NO_RX_CHANNELS = 0x01,
+            NO_TX_CHANNELS = 0x02,
+            NO_RX_MESSAGES = 0x04,
+            NO_TX_MESSAGES = 0x08,
+            NO_ACKD_MESSAGES = 0x10,
+            NO_BURST_TRANSFER = 0x20
+        };
+
+        /// <summary>
+        /// Advanced Capabilities Masks 1 (4th Byte)
+        /// </summary>
+        public enum AdvancedCapabilitiesMasks : byte
+        {		
+            OVERUN_UNDERRUN = 0x01,     // Support for this functionality has been dropped
+            NETWORK_CAPABLE = 0x02,
+            AP1_VERSION_2 = 0x04,     // This Version of the AP1 does not support transmit and only had a limited release
+            SERIAL_NUMBER_CAPABLE = 0x08,
+            PER_CHANNEL_TX_POWER_CAPABLE = 0x10,
+            LOW_PRIORITY_SEARCH_CAPABLE = 0x20,
+            SCRIPT_CAPABLE = 0x40,
+            SEARCH_LIST_CAPABLE = 0x80
+        };
+
+        /// <summary>
+        /// Advanced Capabilities Masks 2 (5th Byte)
+        /// </summary>
+        public enum AdvancedCapabilities2Masks : byte
+        {
+            LED_CAPABLE = 0x01,
+            EXT_MESSAGE_CAPABLE = 0x02,
+            SCAN_MODE_CAPABLE = 0x04,
+            RESERVED = 0x08,
+            PROX_SEARCH_CAPABLE = 0x10,
+            EXT_ASSIGN_CAPABLE = 0x20,
+            FS_ANTFS_ENABLED = 0x40,
+            FIT1_CAPABLE = 0x80,
+        };
+
+        /// <summary>
+        /// Advanced Capabilities Masks 3 (7th Byte)
+        /// </summary>
+        public enum AdvancedCapabilities3Masks : byte
+        {
+            ADVANCED_BURST_CAPABLE = 0x01,
+            EVENT_BUFFERING_CAPABLE = 0x02,
+            EVENT_FILTERING_CAPABLE = 0x04,
+            HIGH_DUTY_SEARCH_CAPABLE = 0x08,
+            SELECTIVE_DATA_UPDATE = 0x40,
+            ENCRYPTED_CHANNEL_CAPABLE = 0x80,
+        };
+
+#pragma warning restore 1591
+    };
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceCapabilities.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 64de77c943822704293f59f450bd4654
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 63 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceInfo.cs

@@ -0,0 +1,63 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Container for all the USB Device information, returned from an ANTDevice
+    /// </summary>
+    public class ANT_DeviceInfo
+    {
+        /// <summary>
+        /// USB Device Product Description
+        /// </summary>
+        public byte[] productDescription;
+
+        /// <summary>
+        /// USB Device Serial String
+        /// </summary>
+        public byte[] serialString;
+
+        internal ANT_DeviceInfo(byte[] productDescription, byte[] serialString)
+        {
+            this.productDescription = productDescription;
+            this.serialString = serialString;
+        }
+
+        /// <summary>
+        /// Returns a formatted, readable string for the product description
+        /// </summary>
+        public String printProductDescription()
+        {
+           return printBytes(productDescription);
+        }
+
+        /// <summary>
+        /// Returns a formatted, readable string for the serial string
+        /// </summary>
+        public String printSerialString()
+        {
+            return printBytes(serialString);
+        }
+
+        private String printBytes(byte[] rawBytes)
+        {
+            // Decode as null terminated ASCII string
+            string formattedString = System.Text.Encoding.ASCII.GetString(rawBytes);
+            return (formattedString.Remove(formattedString.IndexOf('\0')));
+        }
+
+    };
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_DeviceInfo.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d34496655de08614e9b8c3335161196d
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 43 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Exception.cs

@@ -0,0 +1,43 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// An exception occuring in the ANT Managed Library
+    /// </summary>
+    [Serializable]
+    public class ANT_Exception: Exception
+    {    
+        /// <summary>
+        /// Prefixes given string with "ANTLibrary Exception: "
+        /// </summary>
+        /// <param name="exceptionDetail">String to prefix</param>
+        public ANT_Exception(String exceptionDetail) : base("ANTLibrary Exception: " + exceptionDetail) { }
+
+        /// <summary>
+        /// Prefixes given string with "ANTLibrary Exception: " and propates inner exception
+        /// </summary>
+        /// <param name="exceptionDetail">String to prefix</param>
+        /// <param name="innerException">Inner exception</param>
+        public ANT_Exception(String exceptionDetail, Exception innerException) : base("ANTLibrary Exception: " + exceptionDetail, innerException) { }
+
+        /// <summary>
+        /// Copy constructor
+        /// </summary>
+        /// <param name="aex">ANTException to copy</param>
+        public ANT_Exception(ANT_Exception aex) : base(aex.Message) { }   //C++ exceptions like to have a copy constructor
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Exception.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 7308a513d53e69c4b8569deaf06ed576
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 427 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ReferenceLibrary.cs

@@ -0,0 +1,427 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Contains all the ANT constants and enumerations for general use.
+    /// Note: Where desired, in functions where enumerations are required, a byte type can be 
+    /// cast to the enumeration to feed the function raw byte values.
+    /// IE: <c>ANTDeviceInstance.RequestMessage((RequestMessageID)0x4E));</c> would compile.
+    /// </summary>
+    public sealed class ANT_ReferenceLibrary
+    {
+        //removed class scope static modifier because it interferes with some serialization, so a private constructor is needed to enforce static use
+        private ANT_ReferenceLibrary()
+        {
+            throw new Exception("This is a static class, do not create instances");
+        }
+
+#pragma warning disable 1591
+
+        /// <summary>
+        /// Possible port connection types.
+        /// </summary>
+        public enum PortType : byte
+        {
+            USB = 0x00,
+            COM = 0x01
+        };
+
+        /// <summary>
+        /// Possible framing modes.
+        /// Use FramerType.basicANT unless you know you need to use another.
+        /// </summary>
+        public enum FramerType : byte
+        {
+            basicANT = 0x00,
+
+        };
+
+        /// <summary>
+        /// Channel Type flags. A valid channel type is one BASE parameter (Slave XOR Receive) 
+        /// combined by '|' (bitwise OR) with any desired ADV parameters
+        /// </summary>
+        [Flags]
+        public enum ChannelType : byte
+        {
+            BASE_Slave_Receive_0x00 = 0x00,
+            BASE_Master_Transmit_0x10 = 0x10,
+            ADV_Shared_0x20 = 0x20,
+            ADV_TxRx_Only_or_RxAlwaysWildCard_0x40 = 0x40,
+        };
+
+        [Flags]
+        public enum ChannelTypeExtended : byte
+        {
+            ADV_AlwaysSearch_0x01 = 0x01,
+            ADV_FrequencyAgility_0x04 = 0x04,
+            ADV_FastStart_0x10 = 0x10,
+            ADV_AsyncTx_0x20 = 0x20,
+        }
+
+        /// <summary>
+        /// The int status codes returned by the acknowledged and broadcast messaging functions.
+        /// </summary>
+        public enum MessagingReturnCode : int
+        {
+            Fail = 0,
+            Pass = 1,
+            Timeout = 2,
+            Cancelled = 3,
+            InvalidParams = 4,
+        }
+
+        /// <summary>
+        /// Basic Channel status message codes, the bottom two bits of the received status message
+        /// </summary>
+        public enum BasicChannelStatusCode : byte
+        {
+            UNASSIGNED_0x0 = 0x0,
+            ASSIGNED_0x1 = 0x1,
+            SEARCHING_0x2 = 0x2,
+            TRACKING_0x3 = 0x3,
+        }
+
+        /// <summary>
+        /// Transmit Power offsets
+        /// </summary>
+        public enum TransmitPower : byte
+        {
+            RADIO_TX_POWER_MINUS20DB_0x00 = 0x00,
+            RADIO_TX_POWER_MINUS10DB_0x01 = 0x01,
+            RADIO_TX_POWER_MINUS5DB_0x02 = 0x02,
+            RADIO_TX_POWER_0DB_0x03 = 0x03
+        };
+
+        /// <summary>
+        /// Startup message
+        /// </summary>
+        public enum StartupMessage : byte
+        {
+            RESET_POR_0x00 = 0x00,
+            RESET_RST_0x01 = 0x01,
+            RESET_WDT_0x02 = 0x02,
+            RESET_CMD_0x20 = 0x20,
+            RESET_SYNC_0x40 = 0x40,
+            RESET_SUSPEND_0x80 = 0x80
+        };
+
+
+        /// <summary>
+        /// Message ID to request message.
+        /// Note: Where desired, raw byte values can be cast to the enum type. IE: <c>(RequestMessageID)0x4E</c> will compile.
+        /// </summary>
+        public enum RequestMessageID : byte
+        {
+            VERSION_0x3E = 0x3E,
+            CHANNEL_ID_0x51 = 0x51,
+            CHANNEL_STATUS_0x52 = 0x52,
+            CAPABILITIES_0x54 = 0x54,
+            SERIAL_NUMBER_0x61 = 0x61,
+            USER_NVM_0x7C = 0x7C,
+        };
+
+
+        /// <summary>
+        /// Command Codes for SensRcore operations
+        /// </summary>
+        public enum SensRcoreScriptCommandCodes : byte
+        {
+            SCRIPT_CMD_FORMAT_0x00 = 0x00,
+            SCRIPT_CMD_DUMP_0x01 = 0x01,
+            SCRIPT_CMD_SET_DEFAULT_SECTOR_0x02 = 0x02,
+            SCRIPT_CMD_END_SECTOR_0x03 = 0x03,
+            SCRIPT_CMD_END_DUMP_0x04 = 0x04,
+            SCRIPT_CMD_LOCK_0x05 = 0x05,
+        };
+
+        /// <summary>
+        /// Flags for configuring device ANT library
+        /// </summary>
+        [Flags]
+        public enum LibConfigFlags
+        {
+            RADIO_CONFIG_ALWAYS_0x01 = 0x01,
+            MESG_OUT_INC_TIME_STAMP_0x20 = 0x20,
+            MESG_OUT_INC_RSSI_0x40 = 0x40,
+            MESG_OUT_INC_DEVICE_ID_0x80 = 0x80,
+        }
+
+        /// <summary>
+        /// Flags for configuring advanced bursting features.
+        /// </summary>
+        [Flags]
+        public enum AdvancedBurstConfigFlags : uint
+        {
+            FREQUENCY_HOP_ENABLE = 0x00000001,
+        };
+
+        public enum EncryptedChannelMode : byte
+        {
+            DISABLE = 0x00,
+            ENABLE = 0x01,
+            ENABLE_USER_INFO = 0x02,
+        };
+
+        public enum EncryptionInfo : byte
+        {
+            ENCRYPTION_ID = 0x00,
+            USER_INFO_STRING = 0x01,
+            RANDOM_NUMBER_SEED = 0x02,
+        };
+       
+        public enum EncryptionNVMOp : byte
+        {
+            LOAD_KEY_FROM_NVM = 0x00,
+            STORE_KEY_TO_NVM = 0x01,
+        }
+       
+        /// <summary>
+        /// Event groups for configuring Event Buffering
+        /// </summary>
+        [Flags]        
+        public enum EventBufferConfig : byte
+        {
+           BUFFER_LOW_PRIORITY_EVENTS = 0x00,
+           BUFFER_ALL_EVENTS = 0x01           
+        };
+
+        /// <summary>
+        /// MessageIDs for reference
+        /// </summary>
+        public enum ANTMessageID : byte
+        {
+            INVALID_0x00 = 0x00,
+            EVENT_0x01 = 0x01,
+
+            VERSION_0x3E = 0x3E,
+            RESPONSE_EVENT_0x40 = 0x40,
+
+            UNASSIGN_CHANNEL_0x41 = 0x41,
+            ASSIGN_CHANNEL_0x42 = 0x42,
+            CHANNEL_MESG_PERIOD_0x43 = 0x43,
+            CHANNEL_SEARCH_TIMEOUT_0x44 = 0x44,
+            CHANNEL_RADIO_FREQ_0x45 = 0x45,
+            NETWORK_KEY_0x46 = 0x46,
+            RADIO_TX_POWER_0x47 = 0x47,
+            RADIO_CW_MODE_0x48 = 0x48,
+
+            SYSTEM_RESET_0x4A = 0x4A,
+            OPEN_CHANNEL_0x4B = 0x4B,
+            CLOSE_CHANNEL_0x4C = 0x4C,
+            REQUEST_0x4D = 0x4D,
+
+            BROADCAST_DATA_0x4E = 0x4E,
+            ACKNOWLEDGED_DATA_0x4F = 0x4F,
+            BURST_DATA_0x50 = 0x50,
+
+            CHANNEL_ID_0x51 = 0x51,
+            CHANNEL_STATUS_0x52 = 0x52,
+            RADIO_CW_INIT_0x53 = 0x53,
+            CAPABILITIES_0x54 = 0x54,
+
+            STACKLIMIT_0x55 = 0x55,
+
+            SCRIPT_DATA_0x56 = 0x56,
+            SCRIPT_CMD_0x57 = 0x57,
+
+            ID_LIST_ADD_0x59 = 0x59,
+            ID_LIST_CONFIG_0x5A = 0x5A,
+            OPEN_RX_SCAN_0x5B = 0x5B,
+
+
+            EXT_BROADCAST_DATA_0x5D = 0x5D,
+            EXT_ACKNOWLEDGED_DATA_0x5E = 0x5E,
+            EXT_BURST_DATA_0x5F = 0x5F,
+
+            CHANNEL_RADIO_TX_POWER_0x60 = 0x60,
+            GET_SERIAL_NUM_0x61 = 0x61,
+            GET_TEMP_CAL_0x62 = 0x62,
+            SET_LP_SEARCH_TIMEOUT_0x63 = 0x63,
+            SERIAL_NUM_SET_CHANNEL_ID_0x65 = 0x65,
+            RX_EXT_MESGS_ENABLE_0x66 = 0x66,
+            ENABLE_LED_FLASH_0x68 = 0x68,
+            XTAL_ENABLE_0x6D = 0x6D,
+            STARTUP_MESG_0x6F = 0x6F,
+            AUTO_FREQ_CONFIG_0x70 = 0x70,
+            PROX_SEARCH_CONFIG_0x71 = 0x71,
+            
+            ADV_BURST_DATA_0x72 = 0x72,
+            EVENT_BUFFER_CONFIG_0x74 = 0x74,
+            HIGH_DUTY_SEARCH_CONFIG_0x77 = 0x77,
+            ADV_BURST_CONFIG_0x78 = 0x78,
+            EVENT_FILTER_CONFIG_0x79 = 0x79,
+
+
+            FIT1_SET_AGC_0x8F = 0x8F,
+
+            /// <summary>
+            /// *** CONFLICT: w/ Sensrcore, Fit1 will never have sensrcore enabled
+            /// </summary>
+            FIT1_SET_EQUIP_STATE_0x91 = 0x91,
+
+            // SensRcore Messages
+            SET_CHANNEL_INPUT_MASK_0x90 = 0x90,
+            SET_CHANNEL_DATA_TYPE_0x91 = 0x91,
+            READ_PINS_FOR_SECT_0x92 = 0x92,
+            TIMER_SELECT_0x93 = 0x93,
+            ATOD_SETTINGS_0x94 = 0x94,
+            SET_SHARED_ADDRESS_0x95 = 0x95,
+
+            RSSI_POWER_0xC0 = 0xC0,
+            RSSI_BROADCAST_DATA_0xC1 = 0xC1,
+            RSSI_ACKNOWLEDGED_DATA_0xC2 = 0xC2,
+            RSSI_BURST_DATA_0xC3 = 0xC3,
+            RSSI_SEARCH_THRESHOLD_0xC4 = 0xC4,
+
+            SLEEP_0xC5 = 0xC5,
+            SET_USB_INFO_0xC7 = 0xC7,
+
+        };
+
+        /// <summary>
+        /// EventIDs for reference
+        /// </summary>
+        public enum ANTEventID : byte
+        {
+            RESPONSE_NO_ERROR_0x00 = 0x00,
+            NO_EVENT_0x00 = 0x00,
+
+            EVENT_RX_SEARCH_TIMEOUT_0x01 = 0x01,
+            EVENT_RX_FAIL_0x02 = 0x02,
+            EVENT_TX_0x03 = 0x03,
+            EVENT_TRANSFER_RX_FAILED_0x04 = 0x04,
+            EVENT_TRANSFER_TX_COMPLETED_0x05 = 0x05,
+            EVENT_TRANSFER_TX_FAILED_0x06 = 0x06,
+            EVENT_CHANNEL_CLOSED_0x07 = 0x07,
+            EVENT_RX_FAIL_GO_TO_SEARCH_0x08 = 0x08,
+            EVENT_CHANNEL_COLLISION_0x09 = 0x09,
+            /// <summary>
+            /// a pending transmit transfer has begun
+            /// </summary>
+            EVENT_TRANSFER_TX_START_0x0A = 0x0A,
+
+            EVENT_CHANNEL_ACTIVE_0x0F = 0x0F,
+
+            EVENT_TRANSFER_TX_COMPLETED_RSSI_0x10 = 0x10,
+
+
+            /// <summary>
+            /// returned on attempt to perform an action from the wrong channel state
+            /// </summary>
+            CHANNEL_IN_WRONG_STATE_0x15 = 0x15,
+            /// <summary>
+            /// returned on attempt to communicate on a channel that is not open
+            /// </summary>
+            CHANNEL_NOT_OPENED_0x16 = 0x16,
+            /// <summary>
+            /// returned on attempt to open a channel without setting the channel ID
+            /// </summary>
+            CHANNEL_ID_NOT_SET_0x18 = 0x18,
+            /// <summary>
+            /// returned when attempting to start scanning mode
+            /// </summary>
+            CLOSE_ALL_CHANNELS_0x19 = 0x19,
+
+            /// <summary>
+            /// returned on attempt to communicate on a channel with a TX transfer in progress
+            /// </summary>
+            TRANSFER_IN_PROGRESS_0x1F = 0x1F,
+            /// <summary>
+            /// returned when sequence number is out of order on a Burst transfer
+            /// </summary>
+            TRANSFER_SEQUENCE_NUMBER_ERROR_0x20 = 0x20,
+            TRANSFER_IN_ERROR_0x21 = 0x21,
+            TRANSFER_BUSY_0x22 = 0x22,
+
+            /// <summary>
+            /// returned if a data message is provided that is too large
+            /// </summary>
+            MESSAGE_SIZE_EXCEEDS_LIMIT_0x27 = 0x27,
+            /// <summary>
+            /// returned when the message has an invalid parameter
+            /// </summary>
+            INVALID_MESSAGE_0x28 = 0x28,
+            /// <summary>
+            /// returned when an invalid network number is provided
+            /// </summary>
+            INVALID_NETWORK_NUMBER_0x29 = 0x29,
+            /// <summary>
+            /// returned when the provided list ID or size exceeds the limit
+            /// </summary>
+            INVALID_LIST_ID_0x30 = 0x30,
+            /// <summary>
+            /// returned when attempting to transmit on channel 0 when in scan mode
+            /// </summary>
+            INVALID_SCAN_TX_CHANNEL_0x31 = 0x31,
+            /// <summary>
+            /// returned when an invalid parameter is specified in a configuration message
+            /// </summary>
+            INVALID_PARAMETER_PROVIDED_0x33 = 0x33,
+
+            /// <summary>
+            /// ANT event que has overflowed and lost 1 or more events
+            /// </summary>
+            EVENT_QUE_OVERFLOW_0x35 = 0x35,
+
+
+            /// <summary>
+            /// error writing to script
+            /// </summary>
+            SCRIPT_FULL_ERROR_0x40 = 0x40,
+            /// <summary>
+            /// error writing to script
+            /// </summary>
+            SCRIPT_WRITE_ERROR_0x41 = 0x41,
+            /// <summary>
+            /// error accessing script page
+            /// </summary>
+            SCRIPT_INVALID_PAGE_ERROR_0x42 = 0x42,
+            /// <summary>
+            /// the scripts are locked and can't be dumped
+            /// </summary>
+            SCRIPT_LOCKED_ERROR_0x43 = 0x43, 
+
+
+            /// <summary>
+            /// Fit1 only event added for timeout of the pairing state after the Fit module becomes active
+            /// </summary>
+            FIT_ACTIVE_SEARCH_TIMEOUT_0x60 = 0x60,
+            /// <summary>
+            /// Fit1 only
+            /// </summary>
+            FIT_WATCH_PAIR_0x61 = 0x61,
+            /// <summary>
+            /// Fit1 only
+            /// </summary>
+            FIT_WATCH_UNPAIR_0x62 = 0x62,
+        };
+
+
+        /// <summary>
+        /// PIDs for reference
+        /// </summary>
+        public enum USB_PID : ushort
+        {
+            ANT_INTERFACE_BOARD = 0x4102,
+            ANT_ARCT = 0x4103
+        };
+
+        public const byte MAX_MESG_SIZE = 41; // Must match MARSHALL_MESG_MAX_SIZE_VALUE in unmanagedWrapper dll_exports.cpp
+#pragma warning restore 1591
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_ReferenceLibrary.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d00180992c6a97f42a7f225509800a68
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 201 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Response.cs

@@ -0,0 +1,201 @@
+/*
+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;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// Container for all the information passed from an ANT device callback function
+    /// </summary>
+    public class ANT_Response
+    {
+        /// <summary>
+        /// The object that created this response (ie: The corresponding ANTChannel or ANTDevice instance).
+        /// </summary>
+        public object sender;
+
+        /// <summary>
+        /// The channel parameter received in the message. Note: For some messages this is not applicable.
+        /// </summary>
+        public byte antChannel;
+
+        /// <summary>
+        /// The time the message was received.
+        /// </summary>
+        public DateTime timeReceived;
+
+        /// <summary>
+        /// The MessageID of the response
+        /// </summary>
+        public byte responseID;
+
+        /// <summary>
+        /// The raw contents of the response message
+        /// </summary>
+        public byte[] messageContents;        
+
+        internal ANT_Response(object sender, byte antChannel, DateTime timeReceived, byte IDcode, byte[] messageContents)
+        {
+            this.sender = sender;
+            this.antChannel = antChannel;
+            this.timeReceived = timeReceived;
+            this.responseID = IDcode;
+            this.messageContents = messageContents;
+        }
+
+
+        #region Accessors
+
+        /// <summary>
+        /// Returns messageContents[2] cast to an ANTEventID. Throws an exception if this is not a channel event.
+        /// </summary>
+        public ANT_ReferenceLibrary.ANTEventID getChannelEventCode()
+        {
+            if (responseID != (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
+                throw new ANT_Exception("Response is not a channel event");
+            return (ANT_ReferenceLibrary.ANTEventID)messageContents[2];
+        }
+
+
+        /// <summary>
+        /// Returns messageContents[1] cast to an ANTMessageID. Throws an exception if this is not a response event.
+        /// </summary>
+        public ANT_ReferenceLibrary.ANTMessageID getMessageID()
+        {
+            if (responseID != (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
+                throw new ANT_Exception("Response is not a response event");
+            return (ANT_ReferenceLibrary.ANTMessageID)messageContents[1];
+        }
+
+
+        /// <summary>
+        /// Returns the 8-byte data payload of an ANT message. Throws an exception if this is not a received message.
+        /// </summary>
+        /// <returns></returns>
+        public byte[] getDataPayload()
+        {
+            if (messageContents.Length == 9 
+                && (responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E 
+                     || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F 
+                     || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50 
+               ))
+                return messageContents.Skip(1).ToArray();   //Just skip the channel byte and return the payload
+            else
+                return splitExtMessage(extMsgParts.DataPayload);    // Extended message
+        }
+
+
+
+        /// <summary>
+        /// Returns the burst sequence number (upper three bits of channel number). Throws exception if this is not a burst event.
+        /// </summary>
+        public byte getBurstSequenceNumber()
+        {
+            if (responseID != (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50 
+                && responseID != (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F
+               )
+                throw new ANT_Exception("Response is not a burst event");
+            else
+                return (byte)((messageContents[0] & 0xE0) >> 5);
+        }
+
+
+
+        /// <summary>
+        /// Returns the channel ID portion of an extended message. Throws an exception if this is not an extended message.
+        /// </summary>
+        public ANT_ChannelID getDeviceIDfromExt()
+        {
+            ANT_ChannelID extID = new ANT_ChannelID();
+            byte[] rawID = splitExtMessage(extMsgParts.DeviceID);
+
+            extID.deviceNumber = (UInt16)(rawID[0] + (rawID[1] << 8));
+            extID.pairingBit = Convert.ToBoolean(rawID[2] & 0x80);
+            extID.deviceTypeID = (byte)(rawID[2] & 0x7F);
+            extID.transmissionTypeID = rawID[3];
+
+            return extID;
+        }
+
+        /// <summary>
+        /// Returns true if this is an extended message, false otherwise
+        /// </summary>
+        public bool isExtended()
+        {
+            if (messageContents.Length < 13
+                )
+                return false;
+            else
+                return true;
+        }
+
+
+        /// <summary>
+        /// Splits and returns the requested part of an extended message. Throws an exception if this is not an extended message.
+        /// </summary>
+        /// <param name="whichPart">The desired part of the message</param>
+        private byte[] splitExtMessage(extMsgParts whichPart)
+        {
+            if (!isExtended())
+                throw new ANT_Exception("Response is not an extended message");
+
+            byte[] dataPayload;
+            byte[] deviceID;
+
+            // Legacy extended message
+            // The "extended" part of this message is the 4-byte channel ID of the device that we recieved this message from. 
+            // This event is only available on the AT3
+            if (responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D
+                    || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E
+                    || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F)
+            {
+                deviceID = messageContents.Skip(1).Take(4).ToArray(); //Skip channel byte
+                dataPayload = messageContents.Skip(5).Take(8).ToArray();    //Skip channel byte and 4 bytes of id parameters
+            }
+            // "Flag" extended message. The 4-byte channel ID  is included if the flag byte includes 0x80
+            else if (responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E
+                    || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F
+                    || responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50)
+            {
+                dataPayload = messageContents.Skip(1).Take(8).ToArray();    //Skip channel byte
+                if ((messageContents[9] & 0x80) == 0)   // Check flag byte
+                    throw new ANT_Exception("Response does not contain a channel ID");
+                deviceID = messageContents.Skip(10).Take(4).ToArray();   //Skip channel byte, 8 bytes of data, and flag byte
+            }
+            else
+                throw new ANT_Exception("Response is not an extended message");
+
+            switch (whichPart)
+            {
+                case extMsgParts.DataPayload:
+                    return dataPayload;
+                case extMsgParts.DeviceID:
+                    return deviceID;
+                default:
+                    throw new ANT_Exception("Invalid extMsgPart");
+            }
+        }
+
+
+        //This enum makes the code more readable when calling splitExtMessage()
+        private enum extMsgParts
+        {
+            DataPayload,
+            DeviceID
+        }
+
+
+        #endregion
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_Response.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ff535d02745b5af44aa1f09225d02d50
+timeCreated: 1456124826
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 57 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_VersionInfo.cs

@@ -0,0 +1,57 @@
+/*
+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.Reflection;
+using System.Runtime.InteropServices;
+
+namespace ANT_Managed_Library
+{
+    /// <summary>
+    /// The information for this version of the ANT Managed Library
+    /// </summary>
+    public static class ANT_VersionInfo
+    {
+        private static string applicationCode = "AMO";
+        private static string versionSuffix = "";
+
+        /// <summary>
+        /// This string shows the date the library received its current version number
+        /// </summary>
+        public static string versionNumberLastChangedOn = "May 28 2013";
+
+        /// <summary>
+        /// Returns the version information as a string
+        /// </summary>
+        /// <returns>Managed Library Version String</returns>
+        public static string getManagedLibraryVersion()
+        {
+            return applicationCode + Assembly.GetExecutingAssembly().GetName().Version.ToString(4) + versionSuffix;
+        }
+
+
+        [DllImport(ANT_Common.ANT_UNMANAGED_WRAPPER, CallingConvention=CallingConvention.Cdecl)]
+        private static extern IntPtr getUnmanagedVersion();
+
+        /// <summary>
+        /// Gets the version string of the underlying unmanaged wrapper library, ANT_WrappedLib.dll
+        /// </summary>
+        /// <returns>Unmanaged Wrapper Version String</returns>
+        public static string getUnmanagedLibraryVersion()
+        {
+            IntPtr pVerStr = getUnmanagedVersion();
+            return Marshal.PtrToStringAnsi(pVerStr);
+        }
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/ANT_VersionInfo.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c718ed8569cc5fa418d78a6bdc291839
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 382 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/IANT_Channel.cs

@@ -0,0 +1,382 @@
+/*
+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.Runtime.InteropServices;
+
+namespace ANT_Managed_Library
+{
+    #region Delegates for channel events
+
+    /// <summary>
+    /// Delegate for the DeviceNotification event
+    /// </summary>
+    /// <param name="notification">The notification code for the current event</param>
+    /// <param name="notificationInfo">An object that optionally holds more information about the current event</param>
+    public delegate void dDeviceNotificationHandler(ANT_Device.DeviceNotificationCode notification, Object notificationInfo);
+
+    /// <summary>
+    /// Delegate for Channel Response Event for forwarding the raw msg struct. If you are coding in C# use the other response event version.
+    /// </summary>
+    /// <param name="message">Message bytes received from device</param>
+    /// <param name="messageSize">Length of data in message structure</param>
+    public delegate void dRawChannelResponseHandler(ANT_Device.ANTMessage message, ushort messageSize);
+
+    /// <summary>
+    /// Delegate for Channel Response Event
+    /// </summary>
+    /// <param name="response">Message details received from device</param>
+    public delegate void dChannelResponseHandler(ANT_Response response);
+
+    #endregion
+
+
+    //TODO we need to refactor this interface to change the return type for those functions that are un-'safe' to a return value instead of a bool so it is usable for the device sharing service implementation
+    /// <summary>
+    /// Interface for an ANT channel. Allows classes to use different channel implementations behind the interface.
+    /// </summary>
+   // [Obsolete("Note: NOT OBSOLETE! This warning is just to inform you that IANT_Channel interface is under development and is subject to change")]
+    public interface IANT_Channel: IDisposable
+    {
+        /// <summary>
+        /// Returns the underlying C++ ANT framer reference that this channel uses for messaging. Useful to pass to unmanaged C++ implementations.
+        /// </summary>
+        /// <returns>Pointer to the C++ ANT framer for messaging</returns>
+        IntPtr getUnmgdFramer();
+
+        /// <summary>
+        /// Returns the channel number of this chanel
+        /// </summary>
+        /// <returns>The channel number that is sent with messages on the ANT messaging layer</returns>
+        byte getChannelNum();
+
+
+
+        #region ChannelEventCallback Variables
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        event dDeviceNotificationHandler DeviceNotification;
+
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        event dRawChannelResponseHandler rawChannelResponse;
+
+
+        /// <summary>
+        /// The channel callback event. Triggered every time a message is received from the ANT device.
+        /// Examples include transmit and receive messages.
+        /// </summary>
+        event dChannelResponseHandler channelResponse;
+
+        #endregion
+
+
+        #region ANT Channel Functions
+
+        /// <summary>
+        /// Returns current channel status.
+        /// Throws exception on timeout.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        ANT_ChannelStatus requestStatus(UInt32 responseWaitTime);
+
+
+        /// <summary>
+        /// Returns the channel ID
+        /// Throws exception on timeout
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns></returns>
+        ANT_ChannelID requestID(UInt32 responseWaitTime);
+
+
+        /// <overloads>Assign channel</overloads>
+        /// <summary>
+        /// Assign an ANT channel along with its main parameters.
+        /// Throws exception if the network number is invalid.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel, must be less than device's max networks-1</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool assignChannel(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, UInt32 responseWaitTime);
+
+
+        /// <overloads>Assign channel (extended)</overloads>
+        /// <summary>
+        /// Assign an ANT channel, using extended channel assignment
+        /// Throws exception if the network number is invalid.
+        /// </summary>
+        /// <param name="channelTypeByte">Channel Type byte</param>
+        /// <param name="networkNumber">Network to assign to channel, must be less than device's max netwoks - 1</param>
+        /// <param name="extAssignByte">Extended assignment byte</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool assignChannelExt(ANT_ReferenceLibrary.ChannelType channelTypeByte, byte networkNumber, ANT_ReferenceLibrary.ChannelTypeExtended extAssignByte, UInt32 responseWaitTime);
+
+
+        /// <overloads>Unassign channel</overloads>
+        /// <summary>
+        /// Unassign this channel.
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool unassignChannel(UInt32 responseWaitTime);
+
+
+        /// <overloads>Set the Channel ID</overloads>
+        /// <summary>
+        /// Set the Channel ID of this channel.
+        /// Throws exception if device type is > 127.
+        /// </summary>
+        /// <param name="deviceNumber">Device number to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="pairingEnabled">Device pairing bit.</param>
+        /// <param name="deviceTypeID">Device type to assign to channel. Must be less than 128. Set to 0 for receiver wild card matching</param>
+        /// <param name="transmissionTypeID">Transmission type to assign to channel. Set to 0 for receiver wild card matching</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelID(UInt16 deviceNumber, bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID, UInt32 responseWaitTime);
+
+
+        /// <overloads>Sets the Channel ID, using serial number as device number</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelID_UsingSerial(bool pairingEnabled, byte deviceTypeID, byte transmissionTypeID, UInt32 waitResponseTime);
+
+
+        /// <overloads>Sets channel message period</overloads>
+        /// <summary>
+        /// Set this channel's messaging period
+        /// </summary>
+        /// <param name="messagePeriod_32768unitspersecond">Desired period in seconds * 32768</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelPeriod(UInt16 messagePeriod_32768unitspersecond, UInt32 responseWaitTime);
+
+
+        /// <overloads>Sets the RSSI threshold (ARCT)</overloads>
+        /// <summary>
+        /// Set this channel's RSSI threshold (ARCT)
+        /// </summary>
+        /// <param name="thresholdRSSI">Desired RSSI threshold value</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setSearchThresholdRSSI(byte thresholdRSSI, UInt32 responseWaitTime);
+    
+
+        /// <overloads>Sets channel RF Frequency</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="RFFreqOffset">Offset to add to 2400Mhz</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelFreq(byte RFFreqOffset, UInt32 responseWaitTime);
+
+
+        /// <overloads>Sets the channel transmission power</overloads>
+        /// <summary>
+        /// Set the transmission power of this channel
+        /// Throws exception if device is not capable of per-channel transmit power.
+        /// </summary>
+        /// <param name="transmitPower">Transmission power to set to</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelTransmitPower(ANT_ReferenceLibrary.TransmitPower transmitPower, UInt32 responseWaitTime);
+
+
+        /// <overloads>Sets the channel search timeout</overloads>
+        /// <summary>
+        /// Set the search timeout
+        /// </summary>
+        /// <param name="searchTimeout">timeout in 2.5 second units (in newer devices 255=infinite)</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setChannelSearchTimeout(byte searchTimeout, UInt32 responseWaitTime);
+
+
+        /// <overloads>Opens the channel</overloads>
+        /// <summary>
+        /// Opens this channel
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool openChannel(UInt32 responseWaitTime);
+
+
+        /// <overloads>Sends broadcast message</overloads>
+        /// <summary>
+        /// Sends the given data on the broadcast transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="data">data to send (length 8 or less)</param>
+        bool sendBroadcastData(byte[] data);
+
+
+        /// <overloads>Sends acknowledged message</overloads>
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <param name="data">data to send (length 8 or less)</param>
+        /// <param name="ackWaitTime">Time in ms to wait for acknowledgement</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        ANT_ReferenceLibrary.MessagingReturnCode sendAcknowledgedData(byte[] data, UInt32 ackWaitTime);
+
+
+        /// <overloads>Sends burst transfer</overloads>
+        /// <summary>
+        /// Sends the given data as a burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled
+        /// </summary>
+        /// <param name="data">data to send, can be any length</param>
+        /// <param name="completeWaitTime">Time in ms to wait for completion of transfer</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        ANT_ReferenceLibrary.MessagingReturnCode sendBurstTransfer(byte[] data, UInt32 completeWaitTime);
+
+
+
+
+        /// <overloads>Sends extended broadcast message</overloads>
+        /// <summary>
+        /// Sends the given data as an extended broadcast transmission.
+        /// Throws exception if data > 8-bytes in length
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send (length 8 or less)</param>
+            bool sendExtBroadcastData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data);
+
+
+
+        /// <overloads>Sends extended acknowledged message</overloads>
+        /// <summary>
+        /// 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
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send (length 8 or less)</param>
+        /// <param name="ackWaitTime">Time in ms to wait for acknowledgement</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        ANT_ReferenceLibrary.MessagingReturnCode sendExtAcknowledgedData(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data, UInt32 ackWaitTime);
+
+
+        /// <overloads>Sends extended burst data</overloads>
+        /// <summary>
+        /// Sends the given data as an extended burst transmission. Returns: 0=fail, 1=pass, 2=timeout, 3=cancelled
+        /// </summary>
+        /// <param name="deviceNumber">Device number of channel ID to send to</param>
+        /// <param name="deviceTypeID">Device type of channel ID to send to</param>
+        /// <param name="transmissionTypeID">Transmission type of channel ID to send to</param>
+        /// <param name="data">data to send, can be any length</param>
+        /// <param name="completeWaitTime">Time in ms to wait for completion of transfer</param>
+        /// <returns>0=fail, 1=pass, 2=timeout, 3=cancelled</returns>
+        ANT_ReferenceLibrary.MessagingReturnCode sendExtBurstTransfer(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte[] data, UInt32 completeWaitTime);
+
+
+        /// <overloads>Closes the channel</overloads>
+        /// <summary>
+        /// Close this channel
+        /// </summary>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool closeChannel(UInt32 responseWaitTime);
+
+
+        /// <overloads>Sets the channel low priority search timeout</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="lowPriorityTimeout">Timeout period in 2.5 second units</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setLowPrioritySearchTimeout(byte lowPriorityTimeout, UInt32 responseWaitTime);
+
+
+        /// <overloads>Adds a channel ID to the device inclusion/exclusion list</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="deviceNumber">deviceNumber of the channelID to add</param>
+        /// <param name="deviceTypeID">deviceType of the channelID to add</param>
+        /// <param name="transmissionTypeID">transmissionType of the channelID to add</param>
+        /// <param name="listIndex">position in inclusion/exclusion list to add channelID at (Max size of list is 4)</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool includeExcludeList_addChannel(UInt16 deviceNumber, byte deviceTypeID, byte transmissionTypeID, byte listIndex, UInt32 responseWaitTime);
+
+
+
+        /// <overloads>Configures the device inclusion/exclusion list</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="listSize">The desired size of the list, max size is 4, 0=none</param>
+        /// <param name="isExclusionList">True = exclusion list, False = inclusion list</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool includeExcludeList_Configure(byte listSize, bool isExclusionList, UInt32 responseWaitTime);
+
+
+        /// <overloads>Configures proximity search</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="thresholdBin">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. </param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool setProximitySearch(byte thresholdBin, UInt32 responseWaitTime);
+
+
+        /// <overloads>Configures the three operating RF frequencies for ANT frequency agility mode</overloads>
+        /// <summary>
+        /// 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.
+        /// </summary>
+        /// <param name="freq1">Operating RF frequency 1</param>
+        /// <param name="freq2">Operating RF frequency 2</param>
+        /// <param name="freq3">Operating RF frequency 3</param>
+        /// <param name="responseWaitTime">Time to wait for device success response</param>
+        /// <returns>True on success. Note: Always returns true with a response time of 0</returns>
+        bool configFrequencyAgility(byte freq1, byte freq2, byte freq3, UInt32 responseWaitTime);
+
+
+
+
+
+        #endregion
+    }
+}

+ 12 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_Managed_Library/IANT_Channel.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 1864af5831dcd82449aa13292dac0cf2
+timeCreated: 1456124825
+licenseType: Store
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 59 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle.meta

@@ -0,0 +1,59 @@
+fileFormatVersion: 2
+guid: 13c237187ad143143a7272b635546774
+folderAsset: yes
+timeCreated: 1456465486
+licenseType: Store
+PluginImporter:
+  serializedVersion: 1
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  platformData:
+    Android:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+    Any:
+      enabled: 0
+      settings: {}
+    Editor:
+      enabled: 1
+      settings:
+        CPU: AnyCPU
+        DefaultValueInitialized: true
+        OS: OSX
+    Linux:
+      enabled: 0
+      settings:
+        CPU: x86
+    Linux64:
+      enabled: 0
+      settings:
+        CPU: x86_64
+    LinuxUniversal:
+      enabled: 0
+      settings:
+        CPU: None
+    OSXIntel:
+      enabled: 1
+      settings:
+        CPU: AnyCPU
+    OSXIntel64:
+      enabled: 1
+      settings:
+        CPU: AnyCPU
+    OSXUniversal:
+      enabled: 1
+      settings:
+        CPU: AnyCPU
+    Win:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+    Win64:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2eea5c75d15684348b1b3bc9c9106bd7
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 46 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Info.plist

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildMachineOSBuild</key>
+	<string>15F34</string>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>ANT_WrappedLib</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.Antbundle.AntBundle</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>ANT_WrappedLib</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleSupportedPlatforms</key>
+	<array>
+		<string>MacOSX</string>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>DTCompiler</key>
+	<string>com.apple.compilers.llvm.clang.1_0</string>
+	<key>DTPlatformBuild</key>
+	<string>7D1014</string>
+	<key>DTPlatformVersion</key>
+	<string>GM</string>
+	<key>DTSDKBuild</key>
+	<string>15E60</string>
+	<key>DTSDKName</key>
+	<string>macosx10.11</string>
+	<key>DTXcode</key>
+	<string>0731</string>
+	<key>DTXcodeBuild</key>
+	<string>7D1014</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright © 2016 M. All rights reserved.</string>
+</dict>
+</plist>

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Info.plist.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 97e03f9b1a7c043559f278c11dbbed64
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3d96226ff75714ead882e91b9244d6ce
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS/ANT_WrappedLib


+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/MacOS/ANT_WrappedLib.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 11673a87c2080024aafbbe7598848212
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 55682fea49d8749bdb131f7a81be1ba1
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 8d48f29b3db924d5fbbf98dd5f71abe7
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 492d3be4bb4284bcb8d2cf995c74968d
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 31 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.c

@@ -0,0 +1,31 @@
+/*
+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.
+*/
+
+
+#include "types.h"
+#include "checksum.h"
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Functions
+//////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+UCHAR CheckSum_Calc8(const volatile void *pvDataPtr_, USHORT usSize_)
+{
+   const UCHAR *pucDataPtr = (UCHAR *)pvDataPtr_;
+   UCHAR ucCheckSum = 0;
+   int i;
+   
+   // Calculate the CheckSum value (XOR of all bytes in the buffer).
+   for (i = 0; i < usSize_; i++)
+      ucCheckSum ^= pucDataPtr[i];
+   
+   return ucCheckSum;
+}

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.c.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 431bdbdd301344be3b1752bb22852911
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.h

@@ -0,0 +1,36 @@
+/*
+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.
+*/
+
+#if !defined(CHECKSUM_H)
+#define CHECKSUM_H
+
+#include "types.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+//////////////////////////////////////////////////////////////////////////////////
+
+#define CHECKSUM_VERSION   "AQB0.009"
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+//////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__cplusplus)
+   extern "C" {
+#endif
+
+UCHAR CheckSum_Calc8(const volatile void *pvDataPtr_, USHORT usSize_);
+
+#if defined(__cplusplus)
+   }
+#endif
+
+#endif // !defined(CHECKSUM_H)

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/checksum.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ea1bb250feecd4d468e7077d93900f04
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 215 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.c

@@ -0,0 +1,215 @@
+/*
+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.
+*/
+
+#include "types.h"
+#include "crc.h"
+#include "config.h"
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Private Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+#define CRC32_POLYNOMIAL 0xEDB88320
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Functions
+//////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+UCHAR CRC_Calc8(const void *pvDataPtr_, ULONG ulSize_)
+{
+   return CRC_UpdateCRC8(0, pvDataPtr_, ulSize_);
+}
+
+///////////////////////////////////////////////////////////////////////
+UCHAR CRC_UpdateCRC8(UCHAR ucCRC_, const void *pvDataPtr_, ULONG ulSize_)
+{
+   UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
+   
+   while (ulSize_)
+   {
+      ucCRC_ = CRC_Get8(ucCRC_, *pucDataPtr);
+      pucDataPtr++;
+      ulSize_--;
+   }
+
+   return ucCRC_;
+}
+
+///////////////////////////////////////////////////////////////////////
+UCHAR CRC_Get8(UCHAR ucCRC_, UCHAR ucByte_)
+{
+#if defined(AVR)
+   __flash
+#endif
+   static const UCHAR ucTable[256] =
+   {
+      0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,
+      0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
+      0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,
+      0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
+      0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,
+      0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
+      0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,
+      0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
+      0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,
+      0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
+      0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,
+      0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
+      0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,
+      0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
+      0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,
+      0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
+      0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,
+      0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
+      0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,
+      0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
+      0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,
+      0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
+      0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,
+      0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
+      0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,
+      0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
+      0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,
+      0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
+      0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,
+      0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
+      0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,
+      0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
+   };
+
+   return ucTable[ucCRC_ ^ ucByte_];
+}
+
+///////////////////////////////////////////////////////////////////////
+USHORT CRC_Calc16(const void *pvDataPtr_, ULONG ulSize_)
+{
+   return CRC_UpdateCRC16(0, pvDataPtr_, ulSize_);
+}
+
+///////////////////////////////////////////////////////////////////////
+USHORT CRC_UpdateCRC16(USHORT usCRC_, const volatile void *pvDataPtr_, ULONG ulSize_)
+{
+   UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
+   
+   while (ulSize_)
+   {
+      usCRC_ = CRC_Get16(usCRC_, *pucDataPtr);
+      pucDataPtr++;
+      ulSize_--;
+   }
+
+   return usCRC_;
+}
+
+///////////////////////////////////////////////////////////////////////
+//  Optimized 8051 compatible
+///////////////////////////////////////////////////////////////////////
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma location="DSI_BOOT_CODE"
+#endif
+USHORT CRC_UpdateCRC16Short(USHORT usCRC_, UCHAR MEM_TYPE *pucDataPtr_, USHORT usSize_)
+{
+   while (usSize_)
+   {
+      usCRC_ = CRC_Get16(usCRC_, *pucDataPtr_);
+      pucDataPtr_++;
+      usSize_--;
+   }
+
+   return usCRC_;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma location="DSI_BOOT_CODE"
+#endif
+USHORT CRC_Get16(USHORT usCRC_, UCHAR ucByte_) 
+{
+#if defined(AVR)
+   __flash
+#endif
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma memory = constseg(DSI_BOOT_DATA16_C)
+#endif
+      static const USHORT ausCRC16Table[16] = 
+      {
+         0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
+         0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 
+      };
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma memory = default
+#endif
+
+   USHORT usTemp;
+
+   // compute checksum of lower four bits of byte 
+   usTemp = ausCRC16Table[usCRC_ & 0xF];
+   usCRC_  = (usCRC_ >> 4) & 0x0FFF;
+   usCRC_  = usCRC_ ^ usTemp ^ ausCRC16Table[ucByte_ & 0x0F];
+
+   // now compute checksum of upper four bits of byte 
+   usTemp = ausCRC16Table[usCRC_ & 0xF];
+   usCRC_  = (usCRC_ >> 4) & 0x0FFF;
+   usCRC_  = usCRC_ ^ usTemp ^ ausCRC16Table[(ucByte_ >> 4) & 0x0F];
+
+   return usCRC_;
+}
+
+///////////////////////////////////////////////////////////////////////
+ULONG CRC_Calc32(const void *pvDataPtr_, ULONG ulSize_)
+{
+   return CRC_UpdateCRC32(0, pvDataPtr_, ulSize_);
+}
+
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma location="DSI_BOOT_CODE"
+#endif
+///////////////////////////////////////////////////////////////////////
+ULONG CRC_UpdateCRC32(ULONG ulCRC_, const void *pvDataPtr_, ULONG ulSize_)
+{
+   ULONG ulTemp1;
+   ULONG ulTemp2;
+   
+   UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
+   
+   while (ulSize_-- != 0)
+   {
+      ulTemp1 = (ulCRC_ >> 8) & 0x00FFFFFFL;
+      ulTemp2 = CRC_Get32(((UCHAR) ulCRC_ ^ *pucDataPtr++) & 0xff);
+      ulCRC_ = ulTemp1 ^ ulTemp2;
+   }
+   
+   return ulCRC_;
+}
+
+#if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
+   #pragma location="DSI_BOOT_CODE"
+#endif
+///////////////////////////////////////////////////////////////////////
+ULONG CRC_Get32(UCHAR ucByte)
+{
+   UCHAR ucIndex;
+   ULONG ulCRC;
+   
+   ulCRC = (ULONG) ucByte;
+
+   for (ucIndex = 8; ucIndex > 0; ucIndex--)
+   {
+      if (ulCRC & 1)
+         ulCRC = (ulCRC >> 1) ^ CRC32_POLYNOMIAL;
+      else
+         ulCRC >>= 1;
+   }
+   
+   return ulCRC;
+}

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.c.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a64724e09c87049dbba948497853e95c
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 73 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.h

@@ -0,0 +1,73 @@
+/*
+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.
+*/
+
+#if !defined(CRC_H)
+#define CRC_H
+
+#include "types.h"
+
+#if defined(__cplusplus)
+   extern "C" {
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+//////////////////////////////////////////////////////////////////////////////////
+
+// The functions below follow the patter described here, where X is the
+// type and x is the bit-width:
+
+//X CRC_Calcx(const void *pvDataPtr_, ULONG ulSize_);
+///////////////////////////////////////////////////////////////////////
+// Calculate the CRC of a block of data
+// Parameters:
+//    *pvDataPtr_:               Pointer to block of data.
+//    ulSize_:                   Length of the block of data.
+// Returns the CRC.
+///////////////////////////////////////////////////////////////////////
+
+//X CRC_UpdateCRCx(X uxCRC_, const void *pvDataPtr_, ULONG ulSize_);
+///////////////////////////////////////////////////////////////////////
+// Calculate the CRC of a block of data given an initial CRC seed.
+// Useful for continuing a CRC calculation from a previous one.
+// Parameters:
+//    uxCRC_:                    CRC seed.
+//    *pvDataPtr_:               Pointer to block of data.
+//    ulSize_:                   Length of the block of data.
+// Returns the CRC.
+///////////////////////////////////////////////////////////////////////
+
+//X CRC_Getx(X uxCRC_, UCHAR ucByte_);
+///////////////////////////////////////////////////////////////////////
+// Get the CRC for a single byte.
+// Parameters:
+//    uxCRC_:                    CRC seed.
+//    ucByte_:                   Byte on which to calculate the CRC.
+// Returns the CRC.
+///////////////////////////////////////////////////////////////////////
+
+UCHAR CRC_Calc8(const void *pvDataPtr_, ULONG ulSize_);
+UCHAR CRC_UpdateCRC8(UCHAR ucCRC_, const void *pvDataPtr_, ULONG ulSize_);
+UCHAR CRC_Get8(UCHAR ucCRC_, UCHAR ucByte_);
+
+USHORT CRC_Calc16(const void *pvDataPtr_, ULONG ulSize_);
+USHORT CRC_UpdateCRC16(USHORT usCRC_, const volatile void *pvDataPtr_, ULONG ulSize_);
+USHORT CRC_UpdateCRC16Short(USHORT usCRC_, UCHAR MEM_TYPE *pucDataPtr_, USHORT usSize_);
+USHORT CRC_Get16(USHORT usCRC_, UCHAR ucByte_);
+
+ULONG CRC_Calc32(const void *pvDataPtr_, ULONG ulSize_);
+ULONG CRC_UpdateCRC32(ULONG ulCRC_, const void *pvDataPtr_, ULONG ulSize_);
+ULONG CRC_Get32(UCHAR ucByte);
+
+#if defined(__cplusplus)
+   }
+#endif
+
+#endif // !defined(CRC_H)
+

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/common/crc.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 05233e0c10b84461a9e8816e024d6834
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 496e10fda633f4dbe8d599368cae33c0
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 346 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antdefines.h

@@ -0,0 +1,346 @@
+/*
+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.
+*/
+
+#ifndef ANTDEFINES_H
+#define ANTDEFINES_H
+
+#include "types.h"
+
+
+//////////////////////////////////////////////
+// ANT Message Payload Size
+//////////////////////////////////////////////
+#define ANT_STANDARD_DATA_PAYLOAD_SIZE             ((UCHAR)8)
+
+//////////////////////////////////////////////
+// ANT LIBRARY Extended Data Message Fields
+// NOTE: You must check the extended message
+// bitfield first to find out which fields
+// are present before accessing them!
+//////////////////////////////////////////////
+#define ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE          ((UCHAR)4)
+   #define ANT_EXT_STRING_SIZE                     ((UCHAR)27)             // increase buffer size to support longer messages (32 extra bytes after ANT standard payload)
+
+//////////////////////////////////////////////
+// ANT Extended Data Message Bifield Definitions
+//////////////////////////////////////////////
+#define ANT_EXT_MESG_BITFIELD_DEVICE_ID            ((UCHAR)0x80)           // first field after bitfield
+
+// 4 bits free reserved set to 0
+#define ANT_EXT_MESG_BIFIELD_EXTENSION             ((UCHAR)0x01)
+
+// extended message input bitfield defines
+#define ANT_EXT_MESG_BITFIELD_OVERWRITE_SHARED_ADR ((UCHAR)0x10)
+#define ANT_EXT_MESG_BITFIELD_TRANSMISSION_TYPE    ((UCHAR)0x08)  
+
+
+//////////////////////////////////////////////
+// ANT Library Config
+//////////////////////////////////////////////
+#define ANT_LIB_CONFIG_MASK_ALL                    ((UCHAR)0xFF)
+#define ANT_LIB_CONFIG_RADIO_CONFIG_ALWAYS         ((UCHAR)0x01)
+#define ANT_LIB_CONFIG_MESG_OUT_INC_TIME_STAMP     ((UCHAR)0x20)
+#define ANT_LIB_CONFIG_MESG_OUT_INC_RSSI           ((UCHAR)0x40)
+#define ANT_LIB_CONFIG_MESG_OUT_INC_DEVICE_ID      ((UCHAR)0x80)
+
+//////////////////////////////////////////////
+// ID Definitions
+//////////////////////////////////////////////
+#define ANT_ID_SIZE                                ((UCHAR)4)
+#define ANT_ID_TRANS_TYPE_OFFSET                   ((UCHAR)3)
+#define ANT_ID_DEVICE_TYPE_OFFSET                  ((UCHAR)2)
+#define ANT_ID_DEVICE_NUMBER_HIGH_OFFSET           ((UCHAR)1)
+#define ANT_ID_DEVICE_NUMBER_LOW_OFFSET            ((UCHAR)0)
+#define ANT_ID_DEVICE_TYPE_PAIRING_FLAG            ((UCHAR)0x80)
+
+#define ANT_TRANS_TYPE_SHARED_ADDR_MASK            ((UCHAR)0x03)
+#define ANT_TRANS_TYPE_1_BYTE_SHARED_ADDRESS       ((UCHAR)0x02)
+#define ANT_TRANS_TYPE_2_BYTE_SHARED_ADDRESS       ((UCHAR)0x03)
+
+
+//////////////////////////////////////////////
+// Assign Channel Parameters
+//////////////////////////////////////////////
+#define PARAMETER_RX_NOT_TX                        ((UCHAR)0x00)
+#define PARAMETER_TX_NOT_RX                        ((UCHAR)0x10)
+#define PARAMETER_SHARED_CHANNEL                   ((UCHAR)0x20)
+#define PARAMETER_NO_TX_GUARD_BAND                 ((UCHAR)0x40)
+#define PARAMETER_ALWAYS_RX_WILD_CARD_SEARCH_ID    ((UCHAR)0x40)                 //Pre-AP2
+#define PARAMETER_RX_ONLY                          ((UCHAR)0x40)
+
+//////////////////////////////////////////////
+// Ext. Assign Channel Parameters
+//////////////////////////////////////////////
+#define EXT_PARAM_ALWAYS_SEARCH                    ((UCHAR)0x01)
+#define EXT_PARAM_FREQUENCY_AGILITY                ((UCHAR)0x04)
+
+//////////////////////////////////////////////
+// Radio TX Power Definitions
+//////////////////////////////////////////////
+#define RADIO_TX_POWER_LVL_MASK                    ((UCHAR)0x03)
+
+#define RADIO_TX_POWER_LVL_0                       ((UCHAR)0x00)                //(formerly: RADIO_TX_POWER_MINUS20DB) lowest
+#define RADIO_TX_POWER_LVL_1                       ((UCHAR)0x01)                //(formerly: RADIO_TX_POWER_MINUS10DB)
+#define RADIO_TX_POWER_LVL_2                       ((UCHAR)0x02)                //(formerly: RADIO_TX_POWER_MINUS5DB)
+#define RADIO_TX_POWER_LVL_3                       ((UCHAR)0x03)                //(formerly: RADIO_TX_POWER_0DB) highest
+
+//////////////////////////////////////////////
+// Channel Status
+//////////////////////////////////////////////
+#define STATUS_CHANNEL_STATE_MASK                  ((UCHAR)0x03)
+#define STATUS_UNASSIGNED_CHANNEL                  ((UCHAR)0x00)
+#define STATUS_ASSIGNED_CHANNEL                    ((UCHAR)0x01)
+#define STATUS_SEARCHING_CHANNEL                   ((UCHAR)0x02)
+#define STATUS_TRACKING_CHANNEL                    ((UCHAR)0x03)
+
+//////////////////////////////////////////////
+// Standard capabilities defines
+//////////////////////////////////////////////
+#define CAPABILITIES_NO_RX_CHANNELS                ((UCHAR)0x01)
+#define CAPABILITIES_NO_TX_CHANNELS                ((UCHAR)0x02)
+#define CAPABILITIES_NO_RX_MESSAGES                ((UCHAR)0x04)
+#define CAPABILITIES_NO_TX_MESSAGES                ((UCHAR)0x08)
+#define CAPABILITIES_NO_ACKD_MESSAGES              ((UCHAR)0x10)
+#define CAPABILITIES_NO_BURST_TRANSFER             ((UCHAR)0x20)
+
+//////////////////////////////////////////////
+// Advanced capabilities defines
+//////////////////////////////////////////////
+#define CAPABILITIES_OVERUN_UNDERRUN               ((UCHAR)0x01)     // Support for this functionality has been dropped
+#define CAPABILITIES_NETWORK_ENABLED               ((UCHAR)0x02)
+#define CAPABILITIES_AP1_VERSION_2                 ((UCHAR)0x04)     // This Version of the AP1 does not support transmit and only had a limited release
+#define CAPABILITIES_SERIAL_NUMBER_ENABLED         ((UCHAR)0x08)
+#define CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED  ((UCHAR)0x10)
+#define CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED   ((UCHAR)0x20)
+#define CAPABILITIES_SCRIPT_ENABLED                ((UCHAR)0x40)
+#define CAPABILITIES_SEARCH_LIST_ENABLED           ((UCHAR)0x80)
+
+//////////////////////////////////////////////
+// Advanced capabilities 2 defines
+//////////////////////////////////////////////
+#define CAPABILITIES_LED_ENABLED                   ((UCHAR)0x01)
+#define CAPABILITIES_EXT_MESSAGE_ENABLED           ((UCHAR)0x02)
+#define CAPABILITIES_SCAN_MODE_ENABLED             ((UCHAR)0x04)
+#define CAPABILITIES_RESERVED                      ((UCHAR)0x08)
+#define CAPABILITIES_PROX_SEARCH_ENABLED           ((UCHAR)0x10)
+#define CAPABILITIES_EXT_ASSIGN_ENABLED            ((UCHAR)0x20)
+#define CAPABILITIES_FS_ANTFS_ENABLED              ((UCHAR)0x40)
+#define CAPABILITIES_FIT1_ENABLED                  ((UCHAR)0x80)
+
+//////////////////////////////////////////////
+// Advanced capabilities 3 defines
+//////////////////////////////////////////////
+#define CAPABILITIES_SENSRCORE_ENABLED             ((UCHAR)0x01)
+#define CAPABILITIES_RESERVED_1                    ((UCHAR)0x02)
+#define CAPABILITIES_RESERVED_2                    ((UCHAR)0x04)
+#define CAPABILITIES_RESERVED_3                    ((UCHAR)0x08)
+
+//////////////////////////////////////////////
+// Burst Message Sequence
+//////////////////////////////////////////////
+#define CHANNEL_NUMBER_MASK                        ((UCHAR)0x1F)
+#define SEQUENCE_NUMBER_MASK                       ((UCHAR)0xE0)
+#define SEQUENCE_NUMBER_ROLLOVER                   ((UCHAR)0x60)
+#define SEQUENCE_FIRST_MESSAGE                     ((UCHAR)0x00)
+#define SEQUENCE_LAST_MESSAGE                      ((UCHAR)0x80)
+#define SEQUENCE_NUMBER_INC                        ((UCHAR)0x20)
+
+
+//////////////////////////////////////////////
+// Extended Message ID Mask
+//////////////////////////////////////////////
+#define MSG_EXT_ID_MASK                            ((UCHAR)0xE0)
+
+//////////////////////////////////////////////
+// Control Message Flags
+//////////////////////////////////////////////
+#define BROADCAST_CONTROL_BYTE                     ((UCHAR)0x00)
+#define ACKNOWLEDGED_CONTROL_BYTE                  ((UCHAR)0xA0)
+
+//////////////////////////////////////////////
+// Response / Event Codes
+//////////////////////////////////////////////
+#define RESPONSE_NO_ERROR                          ((UCHAR)0x00)
+#define NO_EVENT                                   ((UCHAR)0x00)
+
+#define EVENT_RX_SEARCH_TIMEOUT                    ((UCHAR)0x01)
+#define EVENT_RX_FAIL                              ((UCHAR)0x02)
+#define EVENT_TX                                   ((UCHAR)0x03)
+#define EVENT_TRANSFER_RX_FAILED                   ((UCHAR)0x04)
+#define EVENT_TRANSFER_TX_COMPLETED                ((UCHAR)0x05)
+#define EVENT_TRANSFER_TX_FAILED                   ((UCHAR)0x06)
+#define EVENT_CHANNEL_CLOSED                       ((UCHAR)0x07)
+#define EVENT_RX_FAIL_GO_TO_SEARCH                 ((UCHAR)0x08)
+#define EVENT_CHANNEL_COLLISION                    ((UCHAR)0x09)
+#define EVENT_TRANSFER_TX_START                    ((UCHAR)0x0A)           // a pending transmit transfer has begun
+
+#define EVENT_CHANNEL_ACTIVE                       ((UCHAR)0x0F)
+
+#define EVENT_TRANSFER_TX_NEXT_MESSAGE             ((UCHAR)0x11)           // only enabled in FIT1
+
+#define CHANNEL_IN_WRONG_STATE                     ((UCHAR)0x15)           // returned on attempt to perform an action from the wrong channel state
+#define CHANNEL_NOT_OPENED                         ((UCHAR)0x16)           // returned on attempt to communicate on a channel that is not open
+#define CHANNEL_ID_NOT_SET                         ((UCHAR)0x18)           // returned on attempt to open a channel without setting the channel ID
+#define CLOSE_ALL_CHANNELS                         ((UCHAR)0x19)           // returned when attempting to start scanning mode, when channels are still open
+
+#define TRANSFER_IN_PROGRESS                       ((UCHAR)0x1F)           // returned on attempt to communicate on a channel with a TX transfer in progress
+#define TRANSFER_SEQUENCE_NUMBER_ERROR             ((UCHAR)0x20)           // returned when sequence number is out of order on a Burst transfer
+#define TRANSFER_IN_ERROR                          ((UCHAR)0x21)
+#define TRANSFER_BUSY                              ((UCHAR)0x22)
+
+#define INVALID_MESSAGE_CRC                        ((UCHAR)0x26)           // returned if there is a framing error on an incomming message
+#define MESSAGE_SIZE_EXCEEDS_LIMIT                 ((UCHAR)0x27)           // returned if a data message is provided that is too large
+#define INVALID_MESSAGE                            ((UCHAR)0x28)           // returned when the message has an invalid parameter
+#define INVALID_NETWORK_NUMBER                     ((UCHAR)0x29)           // returned when an invalid network number is provided
+#define INVALID_LIST_ID                            ((UCHAR)0x30)           // returned when the provided list ID or size exceeds the limit
+#define INVALID_SCAN_TX_CHANNEL                    ((UCHAR)0x31)           // returned when attempting to transmit on channel 0 when in scan mode
+#define INVALID_PARAMETER_PROVIDED                 ((UCHAR)0x33)           // returned when an invalid parameter is specified in a configuration message
+
+#define EVENT_SERIAL_QUE_OVERFLOW                  ((UCHAR)0x34)
+#define EVENT_QUE_OVERFLOW                         ((UCHAR)0x35)           // ANT event que has overflowed and lost 1 or more events
+
+#define EVENT_CLK_ERROR                            ((UCHAR)0x36)           // debug event for XOSC16M on LE1
+#define EVENT_STATE_OVERRUN                        ((UCHAR)0x37)
+
+
+#define SCRIPT_FULL_ERROR                          ((UCHAR)0x40)           // error writing to script, memory is full
+#define SCRIPT_WRITE_ERROR                         ((UCHAR)0x41)           // error writing to script, bytes not written correctly
+#define SCRIPT_INVALID_PAGE_ERROR                  ((UCHAR)0x42)           // error accessing script page
+#define SCRIPT_LOCKED_ERROR                        ((UCHAR)0x43)           // the scripts are locked and can't be dumped
+
+#define NO_RESPONSE_MESSAGE                        ((UCHAR)0x50)           // returned to the Command_SerialMessageProcess function, so no reply message is generated
+#define RETURN_TO_MFG                              ((UCHAR)0x51)           // default return to any mesg when the module determines that the mfg procedure has not been fully completed
+
+#define FIT_ACTIVE_SEARCH_TIMEOUT                  ((UCHAR)0x60)           // Fit1 only event added for timeout of the pairing state after the Fit module becomes active
+#define FIT_WATCH_PAIR                             ((UCHAR)0x61)           // Fit1 only
+#define FIT_WATCH_UNPAIR                           ((UCHAR)0x62)           // Fit1 only
+
+#define USB_STRING_WRITE_FAIL                      ((UCHAR)0x70)
+
+// Internal only events below this point
+#define INTERNAL_ONLY_EVENTS                       ((UCHAR)0x80)
+#define EVENT_RX                                   ((UCHAR)0x80)           // INTERNAL: Event for a receive message
+#define EVENT_NEW_CHANNEL                          ((UCHAR)0x81)           // INTERNAL: EVENT for a new active channel
+#define EVENT_PASS_THRU                            ((UCHAR)0x82)           // INTERNAL: Event to allow an upper stack events to pass through lower stacks
+
+#define EVENT_BLOCKED                              ((UCHAR)0xFF)           // INTERNAL: Event to replace any event we do not wish to go out, will also zero the size of the Tx message
+
+///////////////////////////////////////////////////////
+// Script Command Codes
+///////////////////////////////////////////////////////
+#define SCRIPT_CMD_FORMAT                          ((UCHAR)0x00)
+#define SCRIPT_CMD_DUMP                            ((UCHAR)0x01)
+#define SCRIPT_CMD_SET_DEFAULT_SECTOR              ((UCHAR)0x02)
+#define SCRIPT_CMD_END_SECTOR                      ((UCHAR)0x03)
+#define SCRIPT_CMD_END_DUMP                        ((UCHAR)0x04)
+#define SCRIPT_CMD_LOCK                            ((UCHAR)0x05)
+
+///////////////////////////////////////////////////////
+// USB Descriptor Strings
+///////////////////////////////////////////////////////
+#define USB_DESCRIPTOR_VID_PID							((UCHAR) 0x00)
+#define USB_DESCRIPTOR_MANUFACTURER_STRING			((UCHAR) 0x01)
+#define USB_DESCRIPTOR_DEVICE_STRING					((UCHAR) 0x02)
+#define USB_DESCRIPTOR_SERIAL_STRING					((UCHAR) 0x03)
+
+///////////////////////////////////////////////////////
+// Reset Mesg Codes
+///////////////////////////////////////////////////////
+#define RESET_FLAGS_MASK                           ((UCHAR)0xE0)
+#define RESET_SUSPEND                              ((UCHAR)0x80)              // this must follow bitfield def
+#define RESET_SYNC                                 ((UCHAR)0x40)              // this must follow bitfield def
+#define RESET_CMD                                  ((UCHAR)0x20)              // this must follow bitfield def
+#define RESET_WDT                                  ((UCHAR)0x02)
+#define RESET_RST                                  ((UCHAR)0x01)
+#define RESET_POR                                  ((UCHAR)0x00)
+
+//////////////////////////////////////////////
+// PC Application Event Codes
+/////////////////////////////////////// ///////
+//NOTE: These events are not generated by the embedded ANT module
+
+#define EVENT_RX_BROADCAST                         ((UCHAR)0x9A)           // returned when module receives broadcast data
+#define EVENT_RX_ACKNOWLEDGED                      ((UCHAR)0x9B)           // returned when module receives acknowledged data
+#define EVENT_RX_BURST_PACKET                      ((UCHAR)0x9C)           // returned when module receives burst data
+
+#define EVENT_RX_EXT_BROADCAST                     ((UCHAR)0x9D)           // returned when module receives broadcast data
+#define EVENT_RX_EXT_ACKNOWLEDGED                  ((UCHAR)0x9E)           // returned when module receives acknowledged data
+#define EVENT_RX_EXT_BURST_PACKET                  ((UCHAR)0x9F)           // returned when module receives burst data
+
+#define EVENT_RX_RSSI_BROADCAST                    ((UCHAR)0xA0)           // returned when module receives broadcast data
+#define EVENT_RX_RSSI_ACKNOWLEDGED                 ((UCHAR)0xA1)           // returned when module receives acknowledged data
+#define EVENT_RX_RSSI_BURST_PACKET                 ((UCHAR)0xA2)           // returned when module receives burst data
+
+#define EVENT_RX_FLAG_BROADCAST                    ((UCHAR)0xA3)          // returned when module receives broadcast data with flag attached
+#define EVENT_RX_FLAG_ACKNOWLEDGED                 ((UCHAR)0xA4)          // returned when module receives acknowledged data with flag attached
+#define EVENT_RX_FLAG_BURST_PACKET                 ((UCHAR)0xA5)          // returned when module receives burst data with flag attached           
+
+//////////////////////////////////////////////
+// Integrated ANT-FS Client Response/Event Codes
+//////////////////////////////////////////////
+#define MESG_FS_ANTFS_EVENT_PAIR_REQUEST           ((UCHAR)0x01)
+#define MESG_FS_ANTFS_EVENT_DOWNLOAD_START         ((UCHAR)0x02)
+#define MESG_FS_ANTFS_EVENT_UPLOAD_START           ((UCHAR)0x03)
+#define MESG_FS_ANTFS_EVENT_DOWNLOAD_COMPLETE      ((UCHAR)0x04)
+#define MESG_FS_ANTFS_EVENT_UPLOAD_COMPLETE        ((UCHAR)0x05)
+#define MESG_FS_ANTFS_EVENT_ERASE_COMPLETE         ((UCHAR)0x06)
+#define MESG_FS_ANTFS_EVENT_LINK_STATE             ((UCHAR)0x07)
+#define MESG_FS_ANTFS_EVENT_AUTH_STATE             ((UCHAR)0x08)
+#define MESG_FS_ANTFS_EVENT_TRANSPORT_STATE        ((UCHAR)0x09)
+#define MESG_FS_ANTFS_EVENT_CMD_RECEIVED           ((UCHAR)0x0A)
+#define MESG_FS_ANTFS_EVENT_CMD_PROCESSED          ((UCHAR)0x0B)
+
+#define FS_NO_ERROR_RESPONSE									((UCHAR) 0x00)
+#define FS_MEMORY_UNFORMATTED_ERROR_RESPONSE				((UCHAR) 0x01)
+#define FS_MEMORY_NO_FREE_SECTORS_ERROR_RESPONSE		((UCHAR) 0x02)
+#define FS_MEMORY_READ_ERROR_RESPONSE						((UCHAR) 0x03)
+#define FS_MEMORY_WRITE_ERROR_RESPONSE						((UCHAR) 0x04)
+#define FS_MEMORY_ERASE_ERROR_RESPONSE						((UCHAR) 0x05)
+#define FS_TOO_MANY_FILES_OPEN_RESPONSE					((UCHAR) 0x06)
+#define FS_FILE_INDEX_INVALID_ERROR_RESPONSE				((UCHAR) 0x07)
+#define FS_FILE_INDEX_EXISTS_ERROR_RESPONSE				((UCHAR) 0x08)
+#define FS_AUTO_INDEX_FAILED_TRY_AGAIN_ERROR_RESPONSE	((UCHAR) 0x09)
+#define FS_FILE_ALREADY_OPEN_ERROR_RESPONSE				((UCHAR) 0x0A)
+#define FS_FILE_NOT_OPEN_ERROR_RESPONSE					((UCHAR) 0x0B)
+#define FS_DIR_CORRUPTED_ERROR_RESPONSE					((UCHAR) 0x0C)
+#define FS_INVALID_OFFSET_ERROR_RESPONSE					((UCHAR) 0x0D)
+#define FS_BAD_PERMISSIONS_ERROR_RESPONSE					((UCHAR) 0x0E)
+#define FS_EOF_REACHED_ERROR_RESPONSE						((UCHAR) 0x0F)
+#define FS_INVALID_FILE_HANDLE_ERROR_RESPONSE			((UCHAR) 0x10)
+
+#define FS_CRYPTO_OPEN_PERMISSION_ERROR_RESPONSE	((UCHAR) 0x32)
+#define FS_CRYPTO_HANDLE_ALREADY_IN_USE_RESPONSE	((UCHAR) 0x33)
+#define FS_CRYPTO_USER_KEY_NOT_SPECIFIED_RESPONSE	((UCHAR) 0x34)
+#define FS_CRYPTO_USER_KEY_ADD_ERROR_RESPONSE		((UCHAR) 0x35)
+#define FS_CRYPTO_USER_KEY_FETCH_ERROR_RESPONSE		((UCHAR) 0x36)
+#define FS_CRYPTO_IVNONE_READ_ERROR_RESPONSE			((UCHAR) 0x37)
+#define FS_CRYPTO_BLOCK_OFFSET_ERROR_RESPONSE		((UCHAR) 0x38)
+#define FS_CRYPTO_BLOCK_SIZE_ERROR_RESPONSE			((UCHAR) 0x39)
+#define FS_CRYPTO_CFG_TYPE_NOT_SUPPORTED_RESPONSE	((UCHAR) 0x40)
+
+#define FS_FIT_FILE_HEADER_ERROR_RESPONSE					((UCHAR) 0x64)
+#define FS_FIT_FILE_SIZE_INTEGRITY_ERROR_RESPONSE		((UCHAR) 0x65)
+#define FS_FIT_FILE_CRC_ERROR_RESPONSE						((UCHAR) 0x66)
+#define FS_FIT_FILE_CHECK_PERMISSION_ERROR_RESPONSE	((UCHAR) 0x67)
+#define FS_FIT_FILE_CHECK_FILE_TYPE_ERROR_RESPONSE		((UCHAR) 0x68)
+#define FS_FIT_FILE_OP_ABORT_ERROR_RESPONSE				((UCHAR) 0x69)
+
+//////////////////////////////////////////////
+// ANT EVENT return structure
+//////////////////////////////////////////////
+typedef struct
+{
+   UCHAR ucChannel;
+   UCHAR ucEvent;     
+
+} ANT_EVENT;
+
+#endif // !ANTDEFINES_H
+
+

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antdefines.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3039b652f2ae446eea46d7b02976d1ad
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 406 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antmessage.h

@@ -0,0 +1,406 @@
+/*
+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.
+*/
+
+#ifndef ANTMESSAGE_H
+#define ANTMESSAGE_H
+
+#include "types.h"
+#include "antdefines.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// Message Format
+// Messages are in the format:
+//
+// AX XX YY -------- CK
+//
+// where: AX    is the 1 byte sync byte either transmit or recieve
+//        XX    is the 1 byte size of the message (0-249) NOTE: THIS WILL BE LIMITED BY THE EMBEDDED RECEIVE BUFFER SIZE
+//        YY    is the 1 byte ID of the message (1-255, 0 is invalid)
+//        ----- is the data of the message (0-249 bytes of data)
+//        CK    is the 1 byte Checksum of the message
+/////////////////////////////////////////////////////////////////////////////
+#define MESG_TX_SYNC                         ((UCHAR)0xA4)
+#define MESG_RX_SYNC                         ((UCHAR)0xA5)
+#define MESG_SYNC_SIZE                       ((UCHAR)1)
+#define MESG_SIZE_SIZE                       ((UCHAR)1)
+#define MESG_ID_SIZE                         ((UCHAR)1)
+#define MESG_CHANNEL_NUM_SIZE                ((UCHAR)1)
+#define MESG_EXT_MESG_BF_SIZE                ((UCHAR)1)  // NOTE: this could increase in the future
+#define MESG_CHECKSUM_SIZE                   ((UCHAR)1)
+#define MESG_DATA_SIZE                       ((UCHAR)9)
+
+// The largest serial message is an ANT data message with all of the extended fields
+#define MESG_ANT_MAX_PAYLOAD_SIZE            ANT_STANDARD_DATA_PAYLOAD_SIZE
+
+#define MESG_MAX_EXT_DATA_SIZE               (ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE + ANT_EXT_STRING_SIZE) // ANT device ID (4 bytes) +  Padding for ANT EXT string size(27 bytes)
+
+#define MESG_MAX_DATA_SIZE                   (MESG_ANT_MAX_PAYLOAD_SIZE + MESG_EXT_MESG_BF_SIZE + MESG_MAX_EXT_DATA_SIZE) // ANT data payload (8 bytes) + extended bitfield (1 byte) + extended data (31 bytes) = 40 bytes
+#define MESG_MAX_SIZE_VALUE                  (MESG_MAX_DATA_SIZE + MESG_CHANNEL_NUM_SIZE)  // this is the maximum value that the serial message size value is allowed to be (40 + 1 = 41 bytes)
+#define MESG_BUFFER_SIZE                     (MESG_SIZE_SIZE + MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE + MESG_CHECKSUM_SIZE)
+#define MESG_FRAMED_SIZE                     (MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE)
+#define MESG_HEADER_SIZE                     (MESG_SYNC_SIZE + MESG_SIZE_SIZE + MESG_ID_SIZE)
+#define MESG_FRAME_SIZE                      (MESG_HEADER_SIZE + MESG_CHECKSUM_SIZE)
+#define MESG_MAX_SIZE                        (MESG_MAX_DATA_SIZE + MESG_FRAME_SIZE)
+
+#define MESG_SIZE_OFFSET                     (MESG_SYNC_SIZE)
+#define MESG_ID_OFFSET                       (MESG_SYNC_SIZE + MESG_SIZE_SIZE)
+#define MESG_DATA_OFFSET                     (MESG_HEADER_SIZE)
+#define MESG_RECOMMENDED_BUFFER_SIZE         ((UCHAR) 64)                         // This is the recommended size for serial message buffers if there are no RAM restrictions on the system
+
+//////////////////////////////////////////////
+// Message ID's
+//////////////////////////////////////////////
+#define MESG_INVALID_ID                      ((UCHAR)0x00)
+#define MESG_EVENT_ID                        ((UCHAR)0x01)
+
+#define MESG_VERSION_ID                      ((UCHAR)0x3E)
+#define MESG_RESPONSE_EVENT_ID               ((UCHAR)0x40)
+
+#define MESG_UNASSIGN_CHANNEL_ID             ((UCHAR)0x41)
+#define MESG_ASSIGN_CHANNEL_ID               ((UCHAR)0x42)
+#define MESG_CHANNEL_MESG_PERIOD_ID          ((UCHAR)0x43)
+#define MESG_CHANNEL_SEARCH_TIMEOUT_ID       ((UCHAR)0x44)
+#define MESG_CHANNEL_RADIO_FREQ_ID           ((UCHAR)0x45)
+#define MESG_NETWORK_KEY_ID                  ((UCHAR)0x46)
+#define MESG_RADIO_TX_POWER_ID               ((UCHAR)0x47)
+#define MESG_RADIO_CW_MODE_ID                ((UCHAR)0x48)
+#define MESG_SYSTEM_RESET_ID                 ((UCHAR)0x4A)
+#define MESG_OPEN_CHANNEL_ID                 ((UCHAR)0x4B)
+#define MESG_CLOSE_CHANNEL_ID                ((UCHAR)0x4C)
+#define MESG_REQUEST_ID                      ((UCHAR)0x4D)
+
+#define MESG_BROADCAST_DATA_ID               ((UCHAR)0x4E)
+#define MESG_ACKNOWLEDGED_DATA_ID            ((UCHAR)0x4F)
+#define MESG_BURST_DATA_ID                   ((UCHAR)0x50)
+
+#define MESG_CHANNEL_ID_ID                   ((UCHAR)0x51)
+#define MESG_CHANNEL_STATUS_ID               ((UCHAR)0x52)
+#define MESG_RADIO_CW_INIT_ID                ((UCHAR)0x53)
+#define MESG_CAPABILITIES_ID                 ((UCHAR)0x54)
+
+#define MESG_STACKLIMIT_ID                   ((UCHAR)0x55)
+
+#define MESG_SCRIPT_DATA_ID                  ((UCHAR)0x56)
+#define MESG_SCRIPT_CMD_ID                   ((UCHAR)0x57)
+
+#define MESG_ID_LIST_ADD_ID                  ((UCHAR)0x59)
+#define MESG_ID_LIST_CONFIG_ID               ((UCHAR)0x5A)
+#define MESG_OPEN_RX_SCAN_ID                 ((UCHAR)0x5B)
+
+#define MESG_EXT_CHANNEL_RADIO_FREQ_ID       ((UCHAR)0x5C)  // OBSOLETE: (for 905 radio)
+#define MESG_EXT_BROADCAST_DATA_ID           ((UCHAR)0x5D)
+#define MESG_EXT_ACKNOWLEDGED_DATA_ID        ((UCHAR)0x5E)
+#define MESG_EXT_BURST_DATA_ID               ((UCHAR)0x5F)
+
+#define MESG_CHANNEL_RADIO_TX_POWER_ID       ((UCHAR)0x60)
+#define MESG_GET_SERIAL_NUM_ID               ((UCHAR)0x61)
+#define MESG_GET_TEMP_CAL_ID                 ((UCHAR)0x62)
+#define MESG_SET_LP_SEARCH_TIMEOUT_ID        ((UCHAR)0x63)
+#define MESG_SET_TX_SEARCH_ON_NEXT_ID        ((UCHAR)0x64)
+#define MESG_SERIAL_NUM_SET_CHANNEL_ID_ID    ((UCHAR)0x65)
+#define MESG_RX_EXT_MESGS_ENABLE_ID          ((UCHAR)0x66)  
+#define MESG_RADIO_CONFIG_ALWAYS_ID          ((UCHAR)0x67)
+#define MESG_ENABLE_LED_FLASH_ID             ((UCHAR)0x68)
+#define MESG_XTAL_ENABLE_ID                  ((UCHAR)0x6D)
+#define MESG_ANTLIB_CONFIG_ID                ((UCHAR)0x6E)
+#define MESG_STARTUP_MESG_ID                 ((UCHAR)0x6F)
+#define MESG_AUTO_FREQ_CONFIG_ID             ((UCHAR)0x70)
+#define MESG_PROX_SEARCH_CONFIG_ID           ((UCHAR)0x71)
+
+#define MESG_SET_SEARCH_CH_PRIORITY_ID       ((UCHAR)0x75)
+
+
+#define MESG_CUBE_CMD_ID                     ((UCHAR)0x80)
+
+#define MESG_GET_PIN_DIODE_CONTROL_ID        ((UCHAR)0x8D)
+#define MESG_PIN_DIODE_CONTROL_ID            ((UCHAR)0x8E)
+#define MESG_FIT1_SET_AGC_ID                 ((UCHAR)0x8F)
+
+#define MESG_FIT1_SET_EQUIP_STATE_ID         ((UCHAR)0x91)  // *** CONFLICT: w/ Sensrcore, Fit1 will never have sensrcore enabled
+
+// Sensrcore Messages
+#define MESG_SET_CHANNEL_INPUT_MASK_ID       ((UCHAR)0x90)
+#define MESG_SET_CHANNEL_DATA_TYPE_ID        ((UCHAR)0x91)
+#define MESG_READ_PINS_FOR_SECT_ID           ((UCHAR)0x92)
+#define MESG_TIMER_SELECT_ID                 ((UCHAR)0x93)
+#define MESG_ATOD_SETTINGS_ID                ((UCHAR)0x94)
+#define MESG_SET_SHARED_ADDRESS_ID           ((UCHAR)0x95)
+#define MESG_ATOD_EXTERNAL_ENABLE_ID         ((UCHAR)0x96)
+#define MESG_ATOD_PIN_SETUP_ID               ((UCHAR)0x97)
+#define MESG_SETUP_ALARM_ID                  ((UCHAR)0x98)
+#define MESG_ALARM_VARIABLE_MODIFY_TEST_ID   ((UCHAR)0x99)
+#define MESG_PARTIAL_RESET_ID                ((UCHAR)0x9A)
+#define MESG_OVERWRITE_TEMP_CAL_ID           ((UCHAR)0x9B)
+#define MESG_SERIAL_PASSTHRU_SETTINGS_ID     ((UCHAR)0x9C)
+
+#define MESG_BIST_ID                         ((UCHAR)0xAA)
+#define MESG_UNLOCK_INTERFACE_ID             ((UCHAR)0xAD)
+#define MESG_SERIAL_ERROR_ID                 ((UCHAR)0xAE)
+#define MESG_SET_ID_STRING_ID                ((UCHAR)0xAF)
+
+#define MESG_PORT_GET_IO_STATE_ID            ((UCHAR)0xB4)
+#define MESG_PORT_SET_IO_STATE_ID            ((UCHAR)0xB5)
+
+#define MESG_RSSI_ID                         ((UCHAR)0xC0)
+#define MESG_RSSI_BROADCAST_DATA_ID          ((UCHAR)0xC1)
+#define MESG_RSSI_ACKNOWLEDGED_DATA_ID       ((UCHAR)0xC2)
+#define MESG_RSSI_BURST_DATA_ID              ((UCHAR)0xC3)
+#define MESG_RSSI_SEARCH_THRESHOLD_ID        ((UCHAR)0xC4)
+#define MESG_SLEEP_ID                        ((UCHAR)0xC5)
+#define MESG_GET_GRMN_ESN_ID                 ((UCHAR)0xC6)
+#define MESG_SET_USB_INFO_ID                 ((UCHAR)0xC7)
+
+#define MESG_HCI_COMMAND_COMPLETE            ((UCHAR)0xC8)
+
+// 0xE0 - 0xEF reserved for extended ID
+#define MESG_EXT_ID_0                        ((UCHAR)0xE0)  
+#define MESG_EXT_ID_1                        ((UCHAR)0xE1)
+#define MESG_EXT_ID_2                        ((UCHAR)0xE2)
+
+// 0xE0 extended IDs
+#define MESG_EXT_RESPONSE_ID                 ((USHORT)0xE000)
+
+// 0xE1 extended IDs
+#define MESG_EXT_REQUEST_ID                  ((USHORT)0xE100)
+
+// 0xE2 extended IDs
+#define MESG_FS_INIT_MEMORY_ID               ((USHORT)0xE200)
+#define MESG_FS_FORMAT_MEMORY_ID             ((USHORT)0xE201)
+#define MESG_FS_GET_USED_SPACE_ID            ((USHORT)0xE202)
+#define MESG_FS_GET_FREE_SPACE_ID            ((USHORT)0xE203)
+#define MESG_FS_FIND_FILE_INDEX_ID           ((USHORT)0xE204)
+#define MESG_FS_DIRECTORY_READ_ABSOLUTE_ID   ((USHORT)0xE205)
+#define MESG_FS_DIRECTORY_READ_ENTRY_ID      ((USHORT)0xE206)
+#define MESG_FS_DIRECTORY_SAVE_ID            ((USHORT)0xE207)
+#define MESG_FS_DIRECTORY_GET_SIZE_ID        ((USHORT)0xE208)
+#define MESG_FS_DIRECTORY_REBUILD_ID         ((USHORT)0xE209)
+#define MESG_FS_FILE_CREATE_ID               ((USHORT)0xE20A)
+#define MESG_FS_FILE_OPEN_ID                 ((USHORT)0xE20B)
+#define MESG_FS_FILE_DELETE_ID               ((USHORT)0xE20C)
+#define MESG_FS_FILE_CLOSE_ID                ((USHORT)0xE20D)
+#define MESG_FS_FILE_READ_ABSOLUTE_ID        ((USHORT)0xE20E)
+#define MESG_FS_FILE_READ_RELATIVE_ID        ((USHORT)0xE20F)
+#define MESG_FS_FILE_WRITE_ABSOLUTE_ID       ((USHORT)0xE210)
+#define MESG_FS_FILE_WRITE_RELATIVE_ID       ((USHORT)0xE211)
+#define MESG_FS_FILE_SET_SPECIFIC_FLAGS_ID   ((USHORT)0xE212)
+#define MESG_FS_FILE_GET_SIZE_ID             ((USHORT)0xE213)
+#define MESG_FS_FILE_GET_SPECIFIC_FILE_FLAGS_ID ((USHORT)0xE214)
+#define MESG_FS_FILE_GET_SIZE_IN_MEM_ID      ((USHORT)0xE215)
+#define MESG_FS_DIRECTORY_READ_LOCK_ID       ((USHORT)0xE216)
+
+#define MESG_FS_FILE_SET_GENERAL_FLAGS_ID    ((USHORT)0xE21E)
+#define MESG_FS_DIRECTORY_WRITE_ABSOLUTE_ID  ((USHORT)0xE21F)
+// reserved
+#define MESG_MEMDEV_EEPROM_INIT_ID           ((USHORT)0xE220)
+#define MESG_MEMDEV_FLASH_INIT_ID            ((USHORT)0xE221)
+//reserved
+#define MESG_FS_ANTFS_EVENT_ID               ((USHORT)0xE230)
+#define MESG_FS_ANTFS_OPEN_ID                ((USHORT)0xE231)
+#define MESG_FS_ANTFS_CLOSE_ID               ((USHORT)0xE232)
+#define MESG_FS_ANTFS_CONFIG_BEACON_ID       ((USHORT)0xE233)
+#define MESG_FS_ANTFS_SET_AUTH_STRING_ID     ((USHORT)0xE234)
+#define MESG_FS_ANTFS_SET_BEACON_STATE_ID    ((USHORT)0xE235)
+#define MESG_FS_ANTFS_PAIR_RESPONSE_ID       ((USHORT)0xE236)
+#define MESG_FS_ANTFS_SET_LINK_FREQ_ID       ((USHORT)0xE237)
+#define MESG_FS_ANTFS_SET_BEACON_TIMEOUT_ID  ((USHORT)0xE238)
+#define MESG_FS_ANTFS_SET_PAIRING_TIMEOUT_ID ((USHORT)0xE239)
+#define MESG_FS_ANTFS_REMOTE_FILE_CREATE_EN_ID ((USHORT)0xE23A)
+#define MESG_FS_ANTFS_GET_CMD_PIPE_ID        ((USHORT)0xE23B)
+#define MESG_FS_ANTFS_SET_CMD_PIPE_ID        ((USHORT)0xE23C)
+#define MESG_FS_SYSTEM_TIME_ID               ((USHORT)0xE23D)
+#define MESG_FS_ANTFS_SET_ANTFS_STATE_ID     ((USHORT)0xE23E)
+// reserved
+#define MESG_FS_CRYPTO_ADD_USER_KEY_INDEX_ID ((USHORT)0xE245)
+#define MESG_FS_CRYPTO_SET_USER_KEY_INDEX_ID ((USHORT)0xE246)
+#define MESG_FS_CRYPTO_SET_USER_KEY_VAL_ID   ((USHORT)0xE247)
+// reserved
+#define MESG_FS_FIT_FILE_INTEGRITY_CHECK_ID  ((USHORT)0xE250)
+
+
+//////////////////////////////////////////////
+// Message Sizes
+//////////////////////////////////////////////
+#define MESG_INVALID_SIZE                    ((UCHAR)0)
+
+#define MESG_VERSION_SIZE                    ((UCHAR)13)
+#define MESG_RESPONSE_EVENT_SIZE             ((UCHAR)3)
+#define MESG_CHANNEL_STATUS_SIZE             ((UCHAR)2)
+
+#define MESG_UNASSIGN_CHANNEL_SIZE           ((UCHAR)1)
+#define MESG_ASSIGN_CHANNEL_SIZE             ((UCHAR)3)
+#define MESG_CHANNEL_ID_SIZE                 ((UCHAR)5)
+#define MESG_CHANNEL_MESG_PERIOD_SIZE        ((UCHAR)3)
+#define MESG_CHANNEL_SEARCH_TIMEOUT_SIZE     ((UCHAR)2)
+#define MESG_CHANNEL_RADIO_FREQ_SIZE         ((UCHAR)2)
+#define MESG_CHANNEL_RADIO_TX_POWER_SIZE     ((UCHAR)2)
+#define MESG_NETWORK_KEY_SIZE                ((UCHAR)9)
+#define MESG_RADIO_TX_POWER_SIZE             ((UCHAR)2)
+#define MESG_RADIO_CW_MODE_SIZE              ((UCHAR)3)
+#define MESG_RADIO_CW_INIT_SIZE              ((UCHAR)1)
+#define MESG_SYSTEM_RESET_SIZE               ((UCHAR)1)
+#define MESG_OPEN_CHANNEL_SIZE               ((UCHAR)1)
+#define MESG_CLOSE_CHANNEL_SIZE              ((UCHAR)1)
+#define MESG_REQUEST_SIZE                    ((UCHAR)2)
+
+#define MESG_CAPABILITIES_SIZE               ((UCHAR)6)
+#define MESG_STACKLIMIT_SIZE                 ((UCHAR)2)
+
+#define MESG_SCRIPT_DATA_SIZE                ((UCHAR)10)
+#define MESG_SCRIPT_CMD_SIZE                 ((UCHAR)3)
+
+#define MESG_ID_LIST_ADD_SIZE                ((UCHAR)6)
+#define MESG_ID_LIST_CONFIG_SIZE             ((UCHAR)3)
+#define MESG_OPEN_RX_SCAN_SIZE               ((UCHAR)1)
+#define MESG_EXT_CHANNEL_RADIO_FREQ_SIZE     ((UCHAR)3)
+
+#define MESG_RADIO_CONFIG_ALWAYS_SIZE        ((UCHAR)2)
+#define MESG_RX_EXT_MESGS_ENABLE_SIZE        ((UCHAR)2)
+#define MESG_SET_TX_SEARCH_ON_NEXT_SIZE      ((UCHAR)2)
+#define MESG_SET_LP_SEARCH_TIMEOUT_SIZE      ((UCHAR)2)
+
+#define MESG_SERIAL_NUM_SET_CHANNEL_ID_SIZE  ((UCHAR)3)
+#define MESG_ENABLE_LED_FLASH_SIZE           ((UCHAR)2)
+#define MESG_GET_SERIAL_NUM_SIZE             ((UCHAR)4)
+#define MESG_GET_TEMP_CAL_SIZE               ((UCHAR)4)
+#define MESG_ANTLIB_CONFIG_SIZE              ((UCHAR)2)
+#define MESG_XTAL_ENABLE_SIZE                ((UCHAR)1)
+#define MESG_STARTUP_MESG_SIZE               ((UCHAR)1)
+#define MESG_AUTO_FREQ_CONFIG_SIZE           ((UCHAR)4)
+#define MESG_PROX_SEARCH_CONFIG_SIZE         ((UCHAR)2)
+
+#define MESG_GET_PIN_DIODE_CONTROL_SIZE      ((UCHAR)1)
+#define MESG_PIN_DIODE_CONTROL_ID_SIZE       ((UCHAR)2)
+#define MESG_FIT1_SET_EQUIP_STATE_SIZE       ((UCHAR)2)
+#define MESG_FIT1_SET_AGC_SIZE               ((UCHAR)4)
+
+#define MESG_BIST_SIZE                       ((UCHAR)6)
+#define MESG_UNLOCK_INTERFACE_SIZE           ((UCHAR)1)
+#define MESG_SET_SHARED_ADDRESS_SIZE         ((UCHAR)3)
+
+#define MESG_GET_GRMN_ESN_SIZE               ((UCHAR)5)
+
+#define MESG_PORT_SET_IO_STATE_SIZE          ((UCHAR)5)
+
+
+#define MESG_SLEEP_SIZE                      ((UCHAR)1)
+
+
+#define MESG_EXT_DATA_SIZE                   ((UCHAR)13)
+
+#define MESG_RSSI_SIZE                       ((UCHAR)5)
+#define MESG_RSSI_DATA_SIZE                  ((UCHAR)17)
+#define MESG_RSSI_RESPONSE_SIZE              ((UCHAR)7)
+#define MESG_RSSI_SEARCH_THRESHOLD_SIZE      ((UCHAR)2)
+
+#define MESG_MEMDEV_EEPROM_INIT_SIZE					((UCHAR) 0x04)
+#define MESG_FS_INIT_MEMORY_SIZE							((UCHAR) 0x01)
+#define MESG_FS_FORMAT_MEMORY_SIZE						((UCHAR) 0x05)
+#define MESG_FS_DIRECTORY_SAVE_SIZE						((UCHAR) 0x01)
+#define MESG_FS_DIRECTORY_REBUILD_SIZE					((UCHAR) 0x01)
+#define MESG_FS_FILE_DELETE_SIZE							((UCHAR) 0x02)
+#define MESG_FS_FILE_CLOSE_SIZE							((UCHAR) 0x02)
+#define MESG_FS_FILE_SET_SPECIFIC_FLAGS_SIZE			((UCHAR) 0x03)
+#define MESG_FS_DIRECTORY_READ_LOCK_SIZE				((UCHAR) 0x02)
+#define MESG_FS_SYSTEM_TIME_SIZE							((UCHAR) 0x05)
+#define MESG_FS_CRYPTO_ADD_USER_KEY_INDEX_SIZE		((UCHAR) 0x34)
+#define MESG_FS_CRYPTO_SET_USER_KEY_INDEX_SIZE  	((UCHAR) 0x05)
+#define MESG_FS_CRYPTO_SET_USER_KEY_VAL_SIZE			((UCHAR) 0x33)
+#define MESG_FS_FIT_FILE_INTEGRITY_CHECK_SIZE		((UCHAR) 0x02)
+#define MESG_FS_ANTFS_OPEN_SIZE							((UCHAR) 0x01)
+#define MESG_FS_ANTFS_CLOSE_SIZE							((UCHAR) 0x01)
+#define MESG_FS_ANTFS_CONFIG_BEACON_SIZE				((UCHAR) 0x09)
+#define MESG_FS_ANTFS_SET_AUTH_STRING_SIZE         ((UCHAR) 0x02) 
+#define MESG_FS_ANTFS_SET_BEACON_STATE_SIZE			((UCHAR) 0x02)
+#define MESG_FS_ANTFS_PAIR_RESPONSE_SIZE				((UCHAR) 0x02)
+#define MESG_FS_ANTFS_SET_LINK_FREQ_SIZE				((UCHAR) 0x03)
+#define MESG_FS_ANTFS_SET_BEACON_TIMEOUT_SIZE		((UCHAR) 0x02)
+#define MESG_FS_ANTFS_SET_PAIRING_TIMEOUT_SIZE		((UCHAR) 0x02)
+#define MESG_FS_ANTFS_REMOTE_FILE_CREATE_EN_SIZE	((UCHAR) 0x02)
+#define MESG_FS_GET_USED_SPACE_SIZE						((UCHAR) 0x03)
+#define MESG_FS_GET_FREE_SPACE_SIZE						((UCHAR) 0x03)
+#define MESG_FS_FIND_FILE_INDEX_SIZE					((UCHAR) 0x07)
+#define MESG_FS_DIRECTORY_READ_ABSOLUTE_SIZE       ((UCHAR) 0x08)
+#define MESG_FS_DIRECTORY_READ_ENTRY_SIZE				((UCHAR) 0x05)
+#define MESG_FS_DIRECT0RY_GET_SIZE_SIZE				((UCHAR) 0x03)
+#define MESG_FS_FILE_CREATE_SIZE							((UCHAR) 0x0B)
+#define MESG_FS_FILE_OPEN_SIZE							((UCHAR) 0x06)
+#define MESG_FS_FILE_READ_ABSOLUTE_SIZE				((UCHAR) 0x09)
+#define MESG_FS_FILE_READ_RELATIVE_SIZE				((UCHAR) 0x05)
+#define MESG_FS_FILE_WRITE_ABSOLUTE_SIZE           ((UCHAR) 0x09)
+#define MESG_FS_FILE_WRITE_RELATIVE_SIZE           ((UCHAR) 0x05)
+#define MESG_FS_FILE_GET_SIZE_SIZE						((UCHAR) 0x04)
+#define MESG_FS_FILE_GET_SIZE_IN_MEM_SIZE				((UCHAR) 0x04)
+#define MESG_FS_FILE_GET_SPECIFIC_FILE_FLAGS_SIZE	((UCHAR) 0x04)
+#define MESG_FS_SYSTEM_TIME_REQUEST_SIZE				((UCHAR) 0x03)
+#define MESG_FS_ANTFS_GET_CMD_PIPE_SIZE				((UCHAR) 0x05)
+#define MESG_FS_ANTFS_SET_CMD_PIPE_SIZE				((UCHAR) 0x05)
+#define MESG_FS_REQUEST_RESPONSE_SIZE				   ((UCHAR) 0x03)
+
+
+//////////////////////////////////////////////
+// ANT serial message structure
+//////////////////////////////////////////////
+#if defined (DSI_TYPES_OTHER_OS) || defined(__BORLANDC__)  // Nameless unions/struct are not supported by all compilers, remove this if you wish to use the following structures
+
+typedef union
+{
+   UCHAR ucExtMesgBF;
+   struct
+   {
+      BOOL bExtFieldCont : 1;
+      BOOL               : 1;
+      BOOL               : 1;
+      BOOL               : 1;
+      BOOL               : 1;
+      BOOL bANTTimeStamp : 1;
+      BOOL bReserved1    : 1;
+      BOOL bANTDeviceID  : 1;
+   };
+
+} EXT_MESG_BF;                                                          // extended message bitfield
+
+typedef union
+{
+   ULONG ulForceAlign;                                                  // force the struct to be 4-byte aligned, required for some casting in command.c
+   UCHAR aucMessage[MESG_BUFFER_SIZE];                                  // the complete message buffer pointer
+   struct
+   {
+      UCHAR ucSize;                                                     // the message size
+      union
+      {
+         UCHAR aucFramedData[MESG_FRAMED_SIZE];                         // pointer for serial framer
+         struct
+         {
+            UCHAR ucMesgID;                                             // the message ID
+            union
+            {
+               UCHAR aucMesgData[MESG_MAX_SIZE_VALUE];                   // the message data
+               struct
+               {
+                  union
+                  {
+                     UCHAR       ucChannel;                              // ANT channel number
+                     UCHAR       ucSubID;                                // subID portion of ext ID message  
+                  };
+                  UCHAR       aucPayload[ANT_STANDARD_DATA_PAYLOAD_SIZE];// ANT message payload
+                  EXT_MESG_BF sExtMesgBF;                               // extended message bitfield (NOTE: this will not be here for longer data messages)
+                  UCHAR       aucExtData[MESG_MAX_EXT_DATA_SIZE];       // extended message data
+               };
+            };
+         };
+      };
+      UCHAR ucCheckSum;                                                 // the message checksum
+   };
+   
+   
+} ANT_MESSAGE;
+
+#endif
+
+#endif // !ANTMESSAGE_H

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/antmessage.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0413238f40845469785ec2ce3391539b
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 41 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/defines.h

@@ -0,0 +1,41 @@
+/*
+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.
+*/
+
+#ifndef DSI_DEFINES_H
+#define DSI_DEFINES_H
+
+#include "types.h"
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+#define KELVIN                         273.15F
+#define G                              9.80665F             // m/s2
+#define PI                             3.14159265359F
+#define RADTODEG(x)                    ((x) * 360.0F / (2.0F * PI))
+#define DEGTORAD(x)                    ((x) * (2.0F * PI) / 360.0F)
+#define CTOK(x)                        ((x) + KELVIN)
+#define KTOC(x)                        ((x) - KELVIN)
+#define MIN(x, y)                      (((x) < (y)) ? (x) : (y))
+#define MAX(x, y)                      (((x) > (y)) ? (x) : (y))
+#define SQR(x)                         ((x) * (x))
+#define UINTDIV(x, y)                  (((x) + (y) / 2) / (y)) // Unsigned integer division, x / y rounded to the nearest integer
+
+#define ROUND_BIAS(x)                  ((x) < 0 ? -0.5F : 0.5F)
+#define ROUND_FLOAT(x)                 ((x) + ROUND_BIAS(x))
+
+// The following macro computes offset (in bytes) of a member in a
+// structure.  This compiles to a constant if a constant member is
+// supplied as arg.
+#define STRUCT_OFFSET(MEMBER, STRUCT_TYPE)   ( ((UCHAR *) &(((STRUCT_TYPE *) NULL)->MEMBER)) - ((UCHAR *) (NULL)) )
+
+#endif // defined(DSI_DEFINES_H)
+

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/defines.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d9a15590cab524595a0a1940e3a750d7
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 196 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/types.h

@@ -0,0 +1,196 @@
+/*
+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.
+*/
+
+#ifndef DSI_TYPES_H
+#define DSI_TYPES_H
+
+#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(__TOS_WIN__) || defined(__WINDOWS__)  //Windows Platform
+   #define DSI_TYPES_WINDOWS
+
+   #if defined(_WIN32_WINNT)
+      #if (_WIN32_WINNT < 0x501)
+         #undef _WIN32_WINNT
+         #define _WIN32_WINNT          0x0501
+      #endif
+   #else
+      #define _WIN32_WINNT             0X0501
+   #endif
+
+   #include <windows.h>
+
+#elif defined(macintosh) || defined (Macintosh) || defined(__APPLE__) || defined(__MACH__)
+   // Apple platform (first two defines are for Mac OS 9; last two are for Mac OS X)
+   #define DSI_TYPES_MACINTOSH
+#elif defined(linux) || defined (__linux)                   // Linux platform
+   #define DSI_TYPES_LINUX
+#else
+   #define DSI_TYPES_OTHER_OS
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+#if !defined(TRUE)
+   #define TRUE                        ((BOOL) 1)
+#endif
+#if !defined(FALSE)
+   #define FALSE                       ((BOOL) 0)
+#endif
+
+#if !defined(NULL)                                          // <windef.h> compatibility.
+   #define NULL                        ((void *) 0)
+#endif
+
+#define NUL                            '\0'
+
+#define MAX_SCHAR                      ((SCHAR) 0x7F)
+#define MIN_SCHAR                      ((SCHAR) 0x80)
+#define MAX_UCHAR                      ((UCHAR) 0xFF)
+#define MIN_UCHAR                      ((UCHAR) 0)
+
+#define MAX_SSHORT                     ((SSHORT) 0x7FFF)
+#define MIN_SSHORT                     ((SSHORT) 0x8000)
+#define MAX_USHORT                     ((USHORT) 0xFFFF)
+#define MIN_USHORT                     ((USHORT) 0)
+
+#define MAX_SLONG                      ((SLONG) 0x7FFFFFFF)
+#define MIN_SLONG                      ((SLONG) 0x80000000)
+#define MAX_ULONG                      ((ULONG) 0xFFFFFFFF)
+#define MIN_ULONG                      ((ULONG) 0)
+
+#if defined (__ICC8051__)
+   #define C_TYPE                      __code
+   #define MEM_TYPE                    __xdata
+   #define MEM_TYPE_S                  static __xdata
+   #define MEM_TYPE_P                  __xdata *
+   #define BIT_TYPE                    __bdata
+   #define DIR_TYPE                    __data
+#else
+   #define C_TYPE
+   #define MEM_TYPE
+   #define MEM_TYPE_S
+   #define MEM_TYPE_P
+   #define BIT_TYPE
+   #define DIR_TYPE
+#endif
+
+#if defined(__IAR_SYSTEMS_ICC__)
+   #define BITFIELD_START              struct {
+   #define BITFIELD_END                }
+   #define BITS_1                      : 1
+   #define BITS_2                      : 2
+   #define BITS_3                      : 3
+   #define BITS_4                      : 4
+   #define BITS_5                      : 5
+   #define BITS_6                      : 6
+   #define BITS_7                      : 7
+#else
+   #define BITFIELD_START
+   #define BITFIELD_END  
+   #define BITS_1        
+   #define BITS_2        
+   #define BITS_3        
+   #define BITS_4        
+   #define BITS_5        
+   #define BITS_6        
+   #define BITS_7        
+#endif
+
+#if !defined(DSI_TYPES_WINDOWS)
+   #if !defined(BASETYPES) && !defined(_WinToMac_h_)
+      typedef unsigned char            BOOL;
+      typedef char                     BYTE;                // 1-byte int. Sign is processor/compiler-dependent.
+   #endif
+#endif
+
+typedef unsigned char                  BOOL_SAFE;           // BOOL that doesn't get redefined to signed int in windows to result in TRUE=-1 when used in bit fields.
+
+typedef signed char                    SCHAR;               // Signed 1-byte int.
+typedef unsigned char                  UCHAR;               // Unsigned 1-byte int.
+
+typedef signed short                   SSHORT;              // Signed 2-byte int.
+typedef unsigned short                 USHORT;              // Unsigned 2-byte int.
+
+typedef signed long                    SLONG;               // Signed 4-byte int.
+#if defined (DSI_TYPES_MACINTOSH)
+#include <MacTypes.h>
+typedef UInt32 ULONG;
+#else
+typedef unsigned long                  ULONG;               // Unsigned 4-byte int.
+#endif
+#if !defined(_WinToMac_h_)
+   typedef long                        LONG;
+   // 4-byte int.  Sign is processor/compiler-dependent.  Commonly assumed
+   // to be signed, however this is not guaranteed.  Suggested use for
+   // this type is for efficient data passing and bit manipulation.
+   // Assuming any sign for math may be problematic, especially on code
+   // intended to be cross-platform.
+#endif
+
+#if !defined(__BORLANDC__)
+typedef signed long long               SLLONG;              // Signed 8-byte int.
+typedef unsigned long long             ULLONG;              // Unsigned 8-byte int.
+#endif
+
+typedef float                          FLOAT;               // 2-byte floating point.
+typedef double                         DOUBLE;              // 4-byte floating point.
+
+///////////////////////////////////////////////////////////////////////
+// !!NOTE:  The structures below assume little endian architecture!!
+///////////////////////////////////////////////////////////////////////
+typedef union
+{
+   USHORT usData;
+   struct
+   {
+      UCHAR ucLow;
+      UCHAR ucHigh;
+   } stBytes;
+} USHORT_UNION;
+
+#define USHORT_HIGH(X)  (((USHORT_UNION *)(X))->stBytes.ucHigh)
+#define USHORT_LOW(X)   (((USHORT_UNION *)(X))->stBytes.ucLow)
+
+typedef union 
+{    
+   signed short ssData;
+   struct
+   {
+      UCHAR ucLow;
+      UCHAR ucHigh;
+   } stBytes;
+} SSHORT_UNION;
+
+#define SSHORT_HIGH(X)  (((SSHORT_UNION *)(X))->stBytes.ucHigh)
+#define SSHORT_LOW(X)   (((SSHORT_UNION *)(X))->stBytes.ucLow)
+
+typedef union
+{
+   UCHAR aucData[4];
+   ULONG ulData;
+   struct
+   {
+      // The least significant byte of the ULONG in this structure is
+      // referenced by ucByte0.
+      UCHAR ucByte0;
+      UCHAR ucByte1;
+      UCHAR ucByte2;
+      UCHAR ucByte3;
+   } stBytes;
+} ULONG_UNION;
+
+#define ULONG_LOW_0(X)  (((ULONG_UNION *)(X))->stBytes.ucByte0)
+#define ULONG_MID_1(X)  (((ULONG_UNION *)(X))->stBytes.ucByte1)
+#define ULONG_MID_2(X)  (((ULONG_UNION *)(X))->stBytes.ucByte2)
+#define ULONG_HIGH_3(X) (((ULONG_UNION *)(X))->stBytes.ucByte3)
+
+
+#endif // defined(DSI_TYPES_H)

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/types.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e3eb452cb644b4253929f8fcfeadd003
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 21 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/version.h

@@ -0,0 +1,21 @@
+/*
+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.
+*/
+
+#if !defined(__VERSION_H__)
+#define __VERSION_H__
+
+// Version Information
+#define SW_VER_PPP                     "ALU"
+#define SW_VER_NUM                     "2.9"
+#define SW_VER_DEV                     "03" 
+#define SW_VER_SUFFIX				      ""
+#define SW_VER                         SW_VER_PPP SW_VER_NUM SW_VER_DEV SW_VER_SUFFIX
+#define SW_DESCR					         ""
+
+#endif // !defined(CONFIG_H)

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/inc/version.h.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5ab517b2b1af94611b9928fa55b8e67f
+timeCreated: 1468561032
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e9c4321bbef404274aaa70bacd63560f
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b279649c547e04e51a4adedda6ab1e60
+folderAsset: yes
+timeCreated: 1456479465
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3907 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.cpp

@@ -0,0 +1,3907 @@
+/*
+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.
+*/
+ 
+
+#include "types.h"
+#include "dsi_framer_ant.hpp"
+#include "dsi_serial_generic.hpp"
+#include "dsi_thread.h"
+#include "dsi_timer.hpp"
+#include "dsi_convert.h"
+#include "crc.h"
+
+#include "antfs_client_channel.hpp"
+#include "antfsmessage.h"
+#include "config.h"
+
+#include "dsi_debug.hpp"
+#if defined(DEBUG_FILE)
+   #include "macros.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Private Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+static const UCHAR caucNetworkKey[] = NETWORK_KEY;
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Functions
+//////////////////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::ANTFSClientChannel()
+{  
+   bInitFailed = FALSE;
+   bTimerRunning = FALSE;
+
+   bKillThread = FALSE;
+   bANTFSThreadRunning = FALSE;
+
+   pclANT = (DSIFramerANT*) NULL;
+   pbCancel = &bCancel;
+   *pbCancel = FALSE;         
+
+   // Default channel configuration
+   ucChannelNumber = ANTFS_CHANNEL;
+   ucNetworkNumber = ANTFS_NETWORK;   
+   usRadioChannelID = ANTFS_CLIENT_NUMBER;
+   ucTheDeviceType = ANTFS_DEVICE_TYPE;          
+   ucTheTransmissionType = ANTFS_TRANSMISSION_TYPE;    
+   usTheMessagePeriod = ANTFS_MESSAGE_PERIOD;  
+   usBeaconChannelPeriod = ANTFS_MESSAGE_PERIOD;
+   memcpy(aucTheNetworkkey,caucNetworkKey,8); 
+
+   ucLinkTxPower = RADIO_TX_POWER_LVL_3;
+   ucSessionTxPower = RADIO_TX_POWER_LVL_3;
+   bCustomTxPower = FALSE;
+
+   // Default beacon configuration
+   SetDefaultBeacon();
+   memset(aucFriendlyName, 0, sizeof(aucFriendlyName));
+   memset(aucPassKey, 0, sizeof(aucPassKey));
+   ucPassKeySize = 0;
+   ucFriendlyNameSize = 0;
+   memset(&stHostDisconnectParams, 0, sizeof(stHostDisconnectParams));
+
+   eANTFSState = ANTFS_CLIENT_STATE_OFF;
+   ResetClientState();   
+
+   // Debugging is initialized by DSIANTDevice (or ANTDevice in Managed Lib)
+
+   // Timer
+   pclTimer = (DSITimer*)NULL;
+   
+   // Threading
+   hANTFSThread = (DSI_THREAD_ID)NULL;    // Handle for the ANTFS thread
+
+   if (DSIThread_MutexInit(&stMutexCriticalSection) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+
+   if (DSIThread_MutexInit(&stMutexResponseQueue) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+
+   if (DSIThread_CondInit(&stCondANTFSThreadExit) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+
+   if (DSIThread_CondInit(&stCondRequest) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+
+   if (DSIThread_CondInit(&stCondRxEvent) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+
+   if (DSIThread_CondInit(&stCondWaitForResponse) != DSI_THREAD_ENONE)
+   {
+      bInitFailed = TRUE;
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::~ANTFSClientChannel()
+{
+   this->Close();
+
+   if (bInitFailed == FALSE)
+   {
+      DSIThread_MutexDestroy(&stMutexCriticalSection);
+      DSIThread_MutexDestroy(&stMutexResponseQueue);
+      DSIThread_CondDestroy(&stCondANTFSThreadExit);
+      DSIThread_CondDestroy(&stCondRequest);
+      DSIThread_CondDestroy(&stCondRxEvent);
+      DSIThread_CondDestroy(&stCondWaitForResponse);
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::Init(DSIFramerANT* pclANT_, UCHAR ucChannel_)
+{
+   if (bInitFailed == TRUE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::Init():  bInitFailed == TRUE");
+      #endif
+      return FALSE;
+   }   
+
+   ucChannelNumber = ucChannel_;
+   pclANT = pclANT_; 
+
+   if(pclANT)
+   {
+      if(pclANT->GetCancelParameter() == (BOOL*) NULL)   // If cancel parameter has not been configured in framer, use internal
+         pclANT->SetCancelParameter(pbCancel);
+      else  // Use cancel parameter configured in framer
+         pbCancel = pclANT->GetCancelParameter();
+   }
+
+   return ReInitDevice();
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::Close(void)
+{
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Closing ANTFS...");
+   #endif
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   // Stop the threads.
+   bKillThread = TRUE;
+   *pbCancel = TRUE;
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  SetEvent(stCondWaitForResponse).");
+   #endif
+
+   DSIThread_MutexLock(&stMutexResponseQueue);
+      DSIThread_CondSignal(&stCondWaitForResponse);
+      clResponseQueue.Clear();
+   DSIThread_MutexUnlock(&stMutexResponseQueue);
+
+   if (hANTFSThread)
+   {
+      if (bANTFSThreadRunning == TRUE)
+     {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  SetEvent(stCondRequest).");
+         #endif
+         DSIThread_CondSignal(&stCondRequest);
+
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  SetEvent(stCondRxEvent).");
+         #endif
+         DSIThread_CondSignal(&stCondRxEvent);
+
+
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Killing thread.");
+         #endif
+
+         if (DSIThread_CondTimedWait(&stCondANTFSThreadExit, &stMutexCriticalSection, 9000) != DSI_THREAD_ENONE)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Thread not dead.");
+               DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Forcing thread termination...");
+            #endif
+            DSIThread_DestroyThread(hANTFSThread);
+         }
+         else
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Thread terminated successfully.");
+            #endif
+         }
+      }
+
+      DSIThread_ReleaseThreadID(hANTFSThread);
+      hANTFSThread = (DSI_THREAD_ID)NULL;
+   }
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   if (bTimerRunning)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Deleting Command Timer...");
+      #endif
+
+      delete pclTimer;
+      pclTimer = (DSITimer*)NULL;
+      DSIThread_MutexDestroy(&stMutexPairingTimeout);
+
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Deleted Timer.");
+      #endif
+
+      bTimerRunning = FALSE;
+   }
+
+   eANTFSState = ANTFS_CLIENT_STATE_OFF;
+   pclANT = (DSIFramerANT*) NULL;
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::Close():  Closed.");
+   #endif
+
+   if (pucTransferBufferDynamic)
+   {
+      delete[] pucTransferBufferDynamic;
+      pucTransferBufferDynamic = (UCHAR*)NULL;
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::Cancel(void)
+{
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::Cancel(): Cancel current operation...");
+   #endif
+   
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   *pbCancel = TRUE;
+
+   DSIThread_CondSignal(&stCondRxEvent);
+   DSIThread_CondSignal(&stCondRequest);
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::ProcessDeviceNotification(ANT_DEVICE_NOTIFICATION eCode_, void* pvParameter_)
+{   
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(eCode_ != ANT_DEVICE_NOTIFICATION_RESET &&
+      eCode_ != ANT_DEVICE_NOTIFICATION_SHUTDOWN)
+   {    
+      #if defined(DEBUG_FILE)
+         UCHAR aucString[256];
+         SNPRINTF((char *) aucString, 256, "ANTFSClientChannel::ProcessDeviceNotification():  Unknown code %0", eCode_);
+         DSIDebug::ThreadWrite((char *) aucString);
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);      
+      return;
+   }
+
+   if(eANTFSState <= ANTFS_CLIENT_STATE_IDLE)
+   {
+      // We do not need to do anything, since ANT-FS is already in idle state
+      DSIThread_MutexUnlock(&stMutexCriticalSection);      
+      return;
+   }
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::ProcessDeviceNotification():  Resetting state...");
+   #endif
+   *pbCancel = TRUE;
+   eANTFSRequest = ANTFS_REQUEST_INIT;   
+   DSIThread_CondSignal(&stCondRxEvent);
+   DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::ConfigureClientParameters(ANTFS_CLIENT_PARAMS* pstInitParams_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(eANTFSState >= ANTFS_CLIENT_STATE_BEACONING)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::ConfigureClientParameters():  Incorrect state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+
+   if(pstInitParams_->ucAuthType == AUTH_COMMAND_PAIR && pstInitParams_->bPairingEnabled)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::ConfigureClientParameters():  Pairing was selected, but it is not supported.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+
+   stInitParams = *pstInitParams_;
+   ucActiveBeaconStatus1 = 0;
+   ucActiveBeaconStatus1 |= ((stInitParams.ucLinkPeriod & BEACON_PERIOD_MASK) << BEACON_PERIOD_SHIFT);
+   ucActiveBeaconStatus1 |= stInitParams.bPairingEnabled * PAIRING_AVAILABLE_FLAG_MASK;
+   ucActiveBeaconStatus1 |= stInitParams.bUploadEnabled * UPLOAD_ENABLED_FLAG_MASK;
+   ucActiveBeaconStatus1 |= stInitParams.bDataAvailable * DATA_AVAILABLE_FLAG_MASK;
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return ANTFS_RETURN_PASS;   
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN  ANTFSClientChannel::SetPairingEnabled(BOOL bEnable_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(eANTFSState == ANTFS_CLIENT_STATE_AUTHENTICATING || eANTFSState == ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE ||
+      (eANTFSState == ANTFS_CLIENT_STATE_CONNECTED && ucLinkCommandInProgress != ANTFS_CMD_NONE))
+   {
+      // Should not change the pairing capabilities while processing an authentication request
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SetPairingEnabled():  Busy processing an authentication request.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   stInitParams.bPairingEnabled = bEnable_;
+   if(bEnable_)
+      ucActiveBeaconStatus1 |= PAIRING_AVAILABLE_FLAG_MASK;
+   else
+      ucActiveBeaconStatus1 &= ~PAIRING_AVAILABLE_FLAG_MASK;
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS; 
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SetUploadEnabled(BOOL bEnable_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(eANTFSState == ANTFS_CLIENT_STATE_UPLOADING || eANTFSState == ANTFS_CLIENT_STATE_UPLOADING_WAIT_FOR_RESPONSE ||
+      (eANTFSState == ANTFS_CLIENT_STATE_TRANSPORT && ucLinkCommandInProgress != ANTFS_CMD_NONE))
+   {
+      // Should not change the upload capabilities while processing an upload
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SetUploadEnabled():  Busy processing a transport request.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   stInitParams.bUploadEnabled = bEnable_;
+   if(bEnable_)
+      ucActiveBeaconStatus1 |= UPLOAD_ENABLED_FLAG_MASK;
+   else
+      ucActiveBeaconStatus1 &= ~UPLOAD_ENABLED_FLAG_MASK;
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS; 
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SetDataAvailable(BOOL bDataAvailable_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(eANTFSState == ANTFS_CLIENT_STATE_DOWNLOADING || eANTFSState == ANTFS_CLIENT_STATE_DOWNLOADING_WAIT_FOR_DATA ||
+      (eANTFSState == ANTFS_CLIENT_STATE_TRANSPORT && ucLinkCommandInProgress != ANTFS_CMD_NONE))
+   {
+      // Should not change the data available bit while processing a download
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SetDataAvailable():  Busy processing a transport request.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   stInitParams.bDataAvailable = bDataAvailable_;
+   if(bDataAvailable_)
+      ucActiveBeaconStatus1 |= DATA_AVAILABLE_FLAG_MASK;
+   else
+      ucActiveBeaconStatus1 &= ~DATA_AVAILABLE_FLAG_MASK;
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetBeaconTimeout(UCHAR ucTimeout_)
+{
+   stInitParams.ucBeaconTimeout = ucTimeout_;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetPairingTimeout(UCHAR ucTimeout_)
+{
+   stInitParams.ucPairingTimeout = ucTimeout_;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SetFriendlyName(UCHAR* pucFriendlyName_, UCHAR ucFriendlyNameSize_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if(eANTFSState == ANTFS_CLIENT_STATE_AUTHENTICATING)
+   {
+      // Should not change the friendly name while sending an authentication response
+      #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::SetFriendlyName():  Busy authenticating.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   memset(aucFriendlyName, 0, sizeof(aucFriendlyName));
+
+   if(pucFriendlyName_)
+   {
+      ucFriendlyNameSize = ucFriendlyNameSize_;   
+      memcpy(aucFriendlyName, pucFriendlyName_, ucFriendlyNameSize);      
+   }
+   else
+   {
+      ucFriendlyNameSize = 0;
+   }
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SetPassKey(UCHAR* pucPassKey_, UCHAR ucPassKeySize_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if(eANTFSState == ANTFS_CLIENT_STATE_CONNECTED && ucLinkCommandInProgress != ANTFS_CMD_NONE)
+   {
+      // Should not change the passkey while we are processing a request and comparing the keys
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SetPassKey():  Busy processing an authentication request.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   memset(aucPassKey, 0, sizeof(aucPassKey));
+
+   if(pucPassKey_)
+   {
+      ucPassKeySize = ucPassKeySize_;   
+      memcpy(aucPassKey, pucPassKey_, ucPassKeySize);      
+   }
+   else
+   {
+      ucPassKeySize = 0;
+   }
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetChannelID(UCHAR ucDeviceType_, UCHAR ucTransmissionType_)
+{
+   ucTheDeviceType = ucDeviceType_;
+   ucTheTransmissionType = ucTransmissionType_;  
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetChannelPeriod(USHORT usChannelPeriod_)
+{
+   usBeaconChannelPeriod = usChannelPeriod_;
+   // TODO: Should we also change the content of the beacon?
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetNetworkKey(UCHAR ucNetwork_, UCHAR ucNetworkkey[])
+{
+   ucNetworkNumber = ucNetwork_;
+   memcpy(aucTheNetworkkey,ucNetworkkey,8);
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetTxPower(UCHAR ucPairingLv_, UCHAR ucConnectedLv_)
+{
+   ucLinkTxPower = ucPairingLv_;
+   ucSessionTxPower = ucConnectedLv_;
+   bCustomTxPower = TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::OpenBeacon()
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::OpenBeacon():  Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState != ANTFS_CLIENT_STATE_IDLE)
+   {
+      #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSCient::OpenBeacon():  Not in correct state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+
+   #if defined(DEBUG_FILE)
+   DSIDebug::ThreadWrite("ANTFSClientChannel::OpenBeacon():  Beacon starting...");
+   #endif
+   
+   memset(&stHostDisconnectParams, 0, sizeof(stHostDisconnectParams)); // Clear old disconnect parameters
+   ConfigureClientParameters(&stInitParams);
+   SetANTChannelPeriod(stInitParams.ucLinkPeriod);
+   ucActiveBeaconFrequency = stInitParams.ucBeaconFrequency;
+   if(stInitParams.ulSerialNumber & 0x0000FFFF)
+   {
+      usRadioChannelID = (USHORT) (stInitParams.ulSerialNumber & 0x0000FFFF);   // make sure ANT device number is not zero
+   }
+
+   eANTFSRequest = ANTFS_REQUEST_OPEN_BEACON;
+   DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::OpenBeacon():  Open beacon request pending...");
+   #endif
+
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::CloseBeacon(BOOL bReturnToBroadcast_)
+{
+   ANTFS_RETURN eReturn = ANTFS_RETURN_PASS;
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::CloseBeacon():  Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState < ANTFS_CLIENT_STATE_OPENING)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::CloseBeacon():  Beacon is already closed.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+
+   #if defined(DEBUG_FILE)
+   DSIDebug::ThreadWrite("ANTFSClientChannel::CloseBeacon():  Beacon closing...");
+   #endif
+
+   bReturnToBroadcast = bReturnToBroadcast_;
+   eANTFSRequest = ANTFS_REQUEST_CLOSE_BEACON;
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::CloseBeacon():  Close beacon request pending...");
+   #endif
+
+   DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return eReturn;
+}
+
+///////////////////////////////////////////////////////////////////////
+#define MESG_CHANNEL_OFFSET                  0
+#define MESG_EVENT_ID_OFFSET                 1
+#define MESG_EVENT_CODE_OFFSET               2
+
+void ANTFSClientChannel::ProcessMessage(ANT_MESSAGE* pstMessage_, USHORT usMesgSize_)
+{
+   UCHAR ucANTChannel;
+   BOOL bProcessed = FALSE;
+
+   if(!GetEnabled())
+      return; // Only process ANT messages if ANT-FS is on
+
+   if (usMesgSize_ < DSI_FRAMER_TIMEDOUT)  //if the return isn't DSI_FRAMER_TIMEDOUT or DSI_FRAMER_ERROR
+   {
+      ucANTChannel = pstMessage_->aucData[MESG_CHANNEL_OFFSET] & CHANNEL_NUMBER_MASK;
+      if(!FilterANTMessages(pstMessage_, ucANTChannel))
+         return;      
+
+      switch (pstMessage_->ucMessageID)
+      {
+         case MESG_RESPONSE_EVENT_ID:
+           if (pstMessage_->aucData[MESG_EVENT_ID_OFFSET] != MESG_EVENT_ID) // this is a response
+           {
+              memcpy(aucResponseBuf, pstMessage_->aucData, MESG_RESPONSE_EVENT_SIZE);
+              bProcessed = ANTProtocolEventProcess(ucANTChannel, MESG_RESPONSE_EVENT_ID);               
+           }
+           else // this is an event
+           {
+              memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+              bProcessed = ANTChannelEventProcess(ucANTChannel, pstMessage_->aucData[MESG_EVENT_CODE_OFFSET]); // pass through any events not handled here
+           }
+           break;
+
+         case MESG_BROADCAST_DATA_ID:
+           //Call channel event function with Broadcast message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_BROADCAST);
+           break;
+
+         case MESG_ACKNOWLEDGED_DATA_ID:
+           //Call channel event function with Acknowledged message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_ACKNOWLEDGED);
+           break;
+
+         case MESG_BURST_DATA_ID:
+           //Call channel event function with Burst message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_BURST_PACKET);
+           break;
+
+         case MESG_EXT_BROADCAST_DATA_ID:
+           //Call channel event function with Broadcast message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_BROADCAST);
+           break;
+
+         case MESG_EXT_ACKNOWLEDGED_DATA_ID:
+           //Call channel event function with Acknowledged message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_ACKNOWLEDGED);
+           break;
+
+         case MESG_EXT_BURST_DATA_ID:
+           //Call channel event function with Burst message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_BURST_PACKET);
+           break;
+
+         case MESG_RSSI_BROADCAST_DATA_ID:
+           //Call channel event function with Broadcast message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_BROADCAST);
+           break;
+
+         case MESG_RSSI_ACKNOWLEDGED_DATA_ID:
+           //Call channel event function with Acknowledged message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_ACKNOWLEDGED);
+           break;
+
+         case MESG_RSSI_BURST_DATA_ID:
+           //Call channel event function with Burst message code
+           memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_BURST_PACKET);
+           break;
+
+         default:
+           memcpy(aucResponseBuf, pstMessage_->aucData, usMesgSize_);
+           bProcessed = ANTProtocolEventProcess(ucANTChannel, pstMessage_->ucMessageID );
+           break;
+       }
+    }
+
+   return;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetEnabled()
+{
+   if(eANTFSState < ANTFS_CLIENT_STATE_OPENING)
+   {
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_CLIENT_STATE ANTFSClientChannel::GetStatus(void)
+{
+   return eANTFSState;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetHostName(UCHAR *aucHostFriendlyName_, UCHAR *pucBufferSize_)
+{
+   if(!stHostFriendlyName.bNameSet)
+   {
+      *pucBufferSize_ = 0;
+      return FALSE;
+   }
+
+   memset(aucHostFriendlyName_, 0, *pucBufferSize_);
+
+   if (stHostFriendlyName.ucSize < *pucBufferSize_)
+   {
+      *pucBufferSize_ = stHostFriendlyName.ucSize;
+   }
+
+   memcpy(aucHostFriendlyName_, stHostFriendlyName.acFriendlyName, *pucBufferSize_);
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetRequestParameters(ANTFS_REQUEST_PARAMS* pstRequestParams_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if(ucLinkCommandInProgress == ANTFS_CMD_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::GetRequestParameters():  No request in progress.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return FALSE;
+   }
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   // Make a copy of the request parameters
+   memcpy(pstRequestParams_, &stHostRequestParams, sizeof(stHostRequestParams));
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetRequestedFileIndex(USHORT* pusIndex_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if(ucLinkCommandInProgress == ANTFS_CMD_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::GetRequestedFileIndex():  No request in progress.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return FALSE;
+   }
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   *pusIndex_ = stHostRequestParams.usFileIndex;
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetDownloadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if (eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::GetDownloadStatus(): Incorrect state.");
+      #endif
+      *pulTotalLength_ = 10;  // Avoid division by zero when calculating progress
+      *pulByteProgress_ = 0;
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return FALSE;
+   }    
+
+   if (ulTransferFileSize == 0)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::GetDownloadStatus():  Download not in progress.");
+      #endif
+
+      *pulTotalLength_ = 10;  // Avoid division by zero when calculating progress
+      *pulByteProgress_ = 0;
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return FALSE;
+   }
+
+   *pulTotalLength_ = ulTransferBurstIndex + ulTransferBytesRemaining;
+   *pulByteProgress_ = ulTransferBurstIndex;    // initialize with the current location within the data block
+
+   if (ulDownloadProgress >= 24)
+   {
+      *pulByteProgress_ = *pulByteProgress_ + ulDownloadProgress - 24; // do not count the 24 bytes of the header
+   }
+   if (ulDownloadProgress >= ulTransferBytesRemaining + 24)
+   {
+      *pulByteProgress_ = *pulByteProgress_ - 8; // do not count the 8 byte footer
+   }
+
+   #if defined(DEBUG_FILE)
+      UCHAR aucString[256];
+      SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::GetDownloadStatus(): %lu/%lu", *pulByteProgress_, *pulTotalLength_);
+      DSIDebug::ThreadWrite((char*) aucString);
+   #endif
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetUploadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_)
+{
+   // TODO: Implement GetUploadStatus
+   return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetTransferData(ULONG *pulDataSize_ , void *pvData_)
+{
+   // TODO: Implement GetTransferData
+   return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::GetDisconnectParameters(ANTFS_DISCONNECT_PARAMS* pstDisconnectParams_)
+{
+   // Make a copy of the requested parameters
+   memcpy(pstDisconnectParams_, &stHostDisconnectParams, sizeof(stHostDisconnectParams));
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SendPairingResponse(BOOL bAccept_)
+{
+   DSIThread_MutexLock(&stMutexPairingTimeout);
+   if(bTimeoutEvent)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendPairingResponse():  Pairing request timed out.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexPairingTimeout);
+      return ANTFS_RETURN_FAIL;
+   }      
+   ucPairingTimeout = MAX_UCHAR;   // Disable timeout
+   DSIThread_MutexUnlock(&stMutexPairingTimeout);
+
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if(stInitParams.bPairingEnabled != TRUE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendPairingResponse():  Pairing not supported.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendPairingResponse():  Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState != ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendPairingResponse():  Not in correct state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }      
+   
+   bAcceptRequest = bAccept_;
+   
+   ucLinkCommandInProgress = ANTFS_AUTHENTICATE_ID;
+   eANTFSState = ANTFS_CLIENT_STATE_AUTHENTICATING;
+   eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+   DSIThread_CondSignal(&stCondRequest);
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SendDownloadResponse(UCHAR ucResponse_, ANTFS_DOWNLOAD_PARAMS* pstDownloadInfo_, ULONG ulDataLength_, void *pvData_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendDownloadResponse():   Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState != ANTFS_CLIENT_STATE_DOWNLOADING_WAIT_FOR_DATA)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendDownloadResponse():  Not in correct state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }         
+
+   if(pstDownloadInfo_ && usTransferDataFileIndex != pstDownloadInfo_->usFileIndex)
+   {
+      #if defined(DEBUG_FILE)
+         UCHAR aucString[256];
+         SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::SendDownloadResponse(): This is not the file requested, expected %hu and got %hu", 
+            usTransferDataFileIndex, pstDownloadInfo_->usFileIndex);
+         DSIDebug::ThreadWrite((char*) aucString);
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+   
+   ucRequestResponse = ucResponse_;
+   if(ucRequestResponse != DOWNLOAD_RESPONSE_OK)
+   {
+      // Download is being rejected, there are no other parameters to check
+      ulTransferBytesRemaining = 0;
+      ulTransferBurstIndex = 0;
+      ulTransferFileSize = 0;
+      eANTFSRequest = ANTFS_REQUEST_DOWNLOAD_RESPONSE;
+      DSIThread_CondSignal(&stCondRequest);
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_PASS;   
+   }
+   
+   ulTransferFileSize = ulDataLength_;      // File size of the requested download      
+   pucDownloadData = (UCHAR*)pvData_;   // Data block to download   
+   usTransferCrc = 0;   // Initialize to zero, as application only receives the initial request
+   ulDownloadProgress = 0; // No data burst yet
+
+   ulTransferBurstIndex = stHostRequestParams.ulOffset;   // Initialize current position in burst to offset requested by host
+   if(ulTransferBurstIndex > ulTransferFileSize)
+   {
+      ulTransferBurstIndex = ulTransferFileSize;      
+   }
+
+   ulTransferBytesRemaining = stHostRequestParams.ulBlockSize;   // Initialize number of remaining bytes to host specified maximum block size
+   if((stHostRequestParams.ulBlockSize == 0) || (ulTransferFileSize < stHostRequestParams.ulBlockSize)) // If the host is not limiting download size or the file size does not exceed the host's download size limit
+   {
+      ulTransferBytesRemaining = ulTransferFileSize;   //  Number of bytes remaining to be downloaded in this block is the file size
+   }
+
+   if((ulTransferFileSize - ulTransferBurstIndex) < ulTransferBytesRemaining)
+   {
+      ulTransferBytesRemaining = ulTransferFileSize - ulTransferBurstIndex;  // Calculate number of remaining bytes in this block based on the offset
+   }
+
+   ulTransferBlockSize = pstDownloadInfo_->ulMaxBlockSize;
+   if((pstDownloadInfo_->ulMaxBlockSize != 0) && (ulTransferBytesRemaining > pstDownloadInfo_->ulMaxBlockSize))   // If the application is limiting the block size
+   {   
+      ulTransferBytesRemaining = pstDownloadInfo_->ulMaxBlockSize;   // Number of remaining bytes in this block is the application defined block size     
+   }
+
+   eANTFSRequest = ANTFS_REQUEST_DOWNLOAD_RESPONSE;
+   DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS;   
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SendUploadResponse(UCHAR ucResponse_, ANTFS_UPLOAD_PARAMS* pstUploadInfo_, ULONG ulDataLength_, void *pvData_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendUploadResponse():   Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState != ANTFS_CLIENT_STATE_UPLOADING_WAIT_FOR_RESPONSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendUploadResponse():  Not in correct state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }    
+
+   if(pstUploadInfo_ && usTransferDataFileIndex != pstUploadInfo_->usFileIndex)
+   {
+      #if defined(DEBUG_FILE)
+         UCHAR aucString[256];
+         SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::SendUploadResponse(): This is not the file requested, expected %hu and got %hu", 
+            usTransferDataFileIndex, pstUploadInfo_->usFileIndex);
+         DSIDebug::ThreadWrite((char*) aucString);
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }
+   
+   ucRequestResponse = ucResponse_;
+   if(ucRequestResponse != UPLOAD_RESPONSE_OK)
+   {
+      // Upload is being rejected, there are no other parameters to check
+      ulTransferBlockOffset = 0;
+      ulTransferMaxIndex = 0;
+      ulTransferBlockSize = 0;
+      usTransferCrc = 0;
+      eANTFSRequest = ANTFS_REQUEST_UPLOAD_RESPONSE;
+      DSIThread_CondSignal(&stCondRequest);
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_PASS;   
+   }
+
+   if(stHostRequestParams.ulMaxSize > pstUploadInfo_->ulMaxSize)
+      ucRequestResponse = UPLOAD_RESPONSE_INSUFFICIENT_SPACE;
+
+   if((stHostRequestParams.ulOffset > stHostRequestParams.ulMaxSize) && (stHostRequestParams.ulOffset != MAX_ULONG))
+      ucRequestResponse = UPLOAD_RESPONSE_REQUEST_INVALID;   
+
+   ulTransferMaxIndex = pstUploadInfo_->ulMaxSize;      
+
+   if(pstUploadInfo_->ulMaxBlockSize)
+      ulTransferBlockSize = pstUploadInfo_->ulMaxBlockSize;
+   else
+      ulTransferBlockSize = ulTransferMaxIndex;
+
+   ulTransferBurstIndex = 0;
+   ulTransferBlockOffset = 0;
+   usTransferCrc = 0;
+   
+   ulTransferBytesRemaining = ulTransferMaxIndex;
+   if(stHostRequestParams.ulOffset != MAX_ULONG)
+   {
+      ulTransferBytesRemaining = stHostRequestParams.ulMaxSize - stHostRequestParams.ulOffset;
+      ulTransferBlockOffset = stHostRequestParams.ulOffset;
+      usTransferCrc = 0;   // TODO: Validate that data was provided and calculate CRC.
+   }
+
+   eANTFSRequest = ANTFS_REQUEST_UPLOAD_RESPONSE;
+   DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   return ANTFS_RETURN_PASS;  
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFS_RETURN ANTFSClientChannel::SendEraseResponse(UCHAR ucResponse_)
+{
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   if (eANTFSRequest != ANTFS_REQUEST_NONE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendEraseResponse():  Request Busy.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_BUSY;
+   }
+
+   if (eANTFSState != ANTFS_CLIENT_STATE_ERASING)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SendEraseResponse():  Not in correct state.");
+      #endif
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+      return ANTFS_RETURN_FAIL;
+   }      
+   
+   ucRequestResponse = ucResponse_;
+   
+   ucLinkCommandInProgress = ANTFS_ERASE_ID;
+   eANTFSState = ANTFS_CLIENT_STATE_ERASING;
+   eANTFSRequest = ANTFS_REQUEST_ERASE_RESPONSE;
+   DSIThread_CondSignal(&stCondRequest);
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return ANTFS_RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+//Returns a response if there is one ready, otherwise waits the specified time for one to occur
+ANTFS_CLIENT_RESPONSE ANTFSClientChannel::WaitForResponse(ULONG ulMilliseconds_)
+{
+   ANTFS_CLIENT_RESPONSE stResponse = ANTFS_CLIENT_RESPONSE_NONE;
+
+   if (bKillThread == TRUE)
+      return ANTFS_CLIENT_RESPONSE_NONE;
+
+   //Wait for response
+   DSIThread_MutexLock(&stMutexResponseQueue);
+      if(clResponseQueue.isEmpty())
+      {
+         UCHAR ucResult = DSIThread_CondTimedWait(&stCondWaitForResponse, &stMutexResponseQueue, ulMilliseconds_);
+         switch(ucResult)
+         {
+            case DSI_THREAD_ENONE:
+               stResponse = clResponseQueue.GetResponse();
+               break;
+
+            case DSI_THREAD_ETIMEDOUT:
+               stResponse = ANTFS_CLIENT_RESPONSE_NONE;
+               break;
+
+            case DSI_THREAD_EOTHER:
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::WaitForResponse():  CondTimedWait() Failed!");
+               #endif
+               stResponse = ANTFS_CLIENT_RESPONSE_NONE;
+               break;
+
+            default:
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::WaitForResponse():  Error  Unknown...");
+               #endif
+               stResponse = ANTFS_CLIENT_RESPONSE_NONE;
+               break;
+         }
+      }
+      else
+      {
+         stResponse = clResponseQueue.GetResponse();
+      }
+   DSIThread_MutexUnlock(&stMutexResponseQueue);
+
+   return stResponse;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Private Functions
+//////////////////////////////////////////////////////////////////////////////////
+DSI_THREAD_RETURN ANTFSClientChannel::ANTFSThreadStart(void *pvParameter_)
+{
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadInit("ANTFSClient");
+   #endif
+
+   ((ANTFSClientChannel *)pvParameter_)->ANTFSThread();
+
+   return 0;
+}
+
+///////////////////////////////////////////////////////////////////////
+// ANTFS Task Thread
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::ANTFSThread(void)
+{
+   ANTFS_CLIENT_RESPONSE eResponse;
+   bANTFSThreadRunning = TRUE;
+
+   while (bKillThread == FALSE)
+   {
+      eResponse = ANTFS_CLIENT_RESPONSE_NONE;
+
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Awaiting Requests...");
+      #endif
+
+      DSIThread_MutexLock(&stMutexCriticalSection);
+
+      if (*pbCancel)
+      {
+         *pbCancel = FALSE;
+
+         if (eANTFSRequest != ANTFS_REQUEST_INIT && eANTFSRequest != ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+         {
+            eANTFSRequest = ANTFS_REQUEST_NONE;                    //Clear any other request
+         }
+
+         AddResponse(ANTFS_CLIENT_RESPONSE_CANCEL_DONE);
+      }
+
+      if ((eANTFSRequest == ANTFS_REQUEST_NONE) && (bKillThread == FALSE))
+      {
+         UCHAR ucResult = DSIThread_CondTimedWait(&stCondRequest, &stMutexCriticalSection, (ULONG) (stInitParams.ucBeaconTimeout * 1000));
+         if (ucResult != DSI_THREAD_ENONE)
+         {
+            #if defined(DEBUG_FILE)
+               if(ucResult == DSI_THREAD_EOTHER)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): CondTimedWait() Failed!");
+            #endif
+
+            // If connected to a host, and we have not received any requests, go back to link state
+            if ((eANTFSRequest == ANTFS_REQUEST_NONE)  && (stInitParams.ucBeaconTimeout != CMD_TIMEOUT_DISABLED) && (eANTFSState >= ANTFS_CLIENT_STATE_CONNECTED) && (ucLinkCommandInProgress == ANTFS_CMD_NONE))
+            {
+               eANTFSRequest = ANTFS_REQUEST_CONNECTION_LOST;
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): No requests received, dropping back to link");
+               #endif
+            }
+
+            // If we are in link state, reload the beacon
+            // We do this in order to be able to detect serial failures while in this state
+            if((eANTFSState == ANTFS_CLIENT_STATE_BEACONING) && (eANTFSRequest == ANTFS_REQUEST_NONE))
+            {
+               if(SwitchToLink() == RETURN_SERIAL_ERROR)
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Serial error while beaconing");
+                  #endif
+
+                  if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                     eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+               }
+            }
+            
+            // If ping is disabled, go back to transport state if we were waiting for an application response
+            // We need to do this to avoid getting stuck in busy state if the application never sends a response
+            if((stInitParams.ucBeaconTimeout == CMD_TIMEOUT_DISABLED) && (eANTFSRequest == ANTFS_REQUEST_NONE))
+            {
+               if(eANTFSState == ANTFS_CLIENT_STATE_ERASING)
+               {
+                  ucRequestResponse = ERASE_RESPONSE_REJECT;
+                  eANTFSRequest = ANTFS_REQUEST_ERASE_RESPONSE;
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): No response received for the erase request, rejecting...");
+                  #endif
+               }
+               else if(eANTFSState == ANTFS_CLIENT_STATE_DOWNLOADING_WAIT_FOR_DATA)
+               {
+                  ucRequestResponse = DOWNLOAD_RESPONSE_NOT_READY;
+                  ulTransferBytesRemaining = 0;
+                  ulTransferBurstIndex = 0;
+                  ulTransferFileSize = 0;
+                  usTransferCrc = 0;
+                  eANTFSRequest = ANTFS_REQUEST_DOWNLOAD_RESPONSE;
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): No response received for the download request, rejecting...");
+                  #endif
+               }
+               else if(eANTFSState == ANTFS_CLIENT_STATE_UPLOADING_WAIT_FOR_RESPONSE)
+               {
+                  ucRequestResponse = UPLOAD_RESPONSE_NOT_READY;
+                  ulTransferBlockOffset = 0;
+                  ulTransferMaxIndex = 0;
+                  ulTransferBlockSize = 0;
+                  usTransferCrc = 0;
+                  eANTFSRequest = ANTFS_REQUEST_UPLOAD_RESPONSE;
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): No response received for the upload request, rejecting...");
+                  #endif
+               }
+            }
+         }
+      }
+
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+      if (bKillThread)
+         break;      
+
+      if (eANTFSRequest != ANTFS_REQUEST_NONE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Request received");
+         #endif
+
+         switch (eANTFSRequest)
+         {
+            case ANTFS_REQUEST_INIT:
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Idle.");
+                  #endif
+
+                  ResetClientState();
+                  eANTFSState = ANTFS_CLIENT_STATE_IDLE;   
+                  eResponse = ANTFS_CLIENT_RESPONSE_INIT_PASS;
+               }   // ANTFS_REQUEST_INIT
+               break;               
+
+            case ANTFS_REQUEST_OPEN_BEACON:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Opening beacon...");
+                  #endif
+                  
+                  eANTFSState = ANTFS_CLIENT_STATE_OPENING;
+
+                  eReturn = AttemptOpenBeacon();
+
+                  if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Open beacon serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Opening beacon failed.");
+                     #endif
+                     eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+                  }
+                  else if (eReturn == RETURN_STOP)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Opening beacon stopped.");
+                     #endif
+                     AttemptCloseBeacon();
+                     eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+                  }
+                  else if (eReturn == RETURN_PASS)
+                  {
+                     SwitchToLink();
+                     eANTFSState = ANTFS_CLIENT_STATE_BEACONING;
+                     eResponse = ANTFS_CLIENT_RESPONSE_BEACON_OPEN;
+
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Beacon Open...");
+                     #endif
+                  }
+               }   // ANTFS_REQUEST_OPEN_BEACON
+               break;            
+
+            case ANTFS_REQUEST_CLOSE_BEACON:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Closing beacon...");
+                  #endif
+
+                  eReturn = AttemptCloseBeacon();
+
+                  if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Close beacon serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_PASS)
+                  {
+                     ResetClientState();
+                     eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+                     eResponse = ANTFS_CLIENT_RESPONSE_BEACON_CLOSED;
+                  }
+               }   // ANTFS_CLOSE_BEACON
+               break;
+
+            case ANTFS_REQUEST_CONNECT:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Connecting to host device...");
+                  #endif
+
+                  eReturn = SwitchToAuthenticate();
+
+                  if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Serial error while connecting to host device.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Connecting to host device failed.");
+                     #endif
+                     eANTFSState = ANTFS_CLIENT_STATE_BEACONING;
+                     eANTFSRequest = ANTFS_REQUEST_NONE;   
+                  }
+                  else if (eReturn == RETURN_PASS)
+                  {
+                     eANTFSRequest = ANTFS_REQUEST_NONE;
+                     eANTFSState = ANTFS_CLIENT_STATE_CONNECTED;
+                     eResponse = ANTFS_CLIENT_RESPONSE_CONNECT_PASS;
+
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Connected to host device...");
+                     #endif
+                  }
+               }   // ANTFS_REQUEST_CONNECT
+               break;
+
+            case ANTFS_REQUEST_DISCONNECT:
+               {
+                  RETURN_STATUS eReturn;
+                  ANTFS_CLIENT_STATE ePrevState = eANTFSState;
+
+                  #if defined(DEBUG_FILE)
+                      DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Disconnecting...");
+                  #endif
+
+                  eReturn = SwitchToLink();
+
+                  if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Serial error while disconnecting from host device.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Disconnecting from host device failed.");
+                     #endif
+
+                     eANTFSState = ePrevState;      // Remain in previous state
+                     eANTFSRequest = ANTFS_REQUEST_NONE;   
+                  }
+                  else if (eReturn == RETURN_PASS)
+                  {                     
+                     if(stHostDisconnectParams.ucCommandType == DISCONNECT_COMMAND_BROADCAST)
+                     {                        
+                        ResetClientState();
+                        eANTFSRequest = ANTFS_REQUEST_NONE;
+                        eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+                        eResponse = ANTFS_CLIENT_RESPONSE_DISCONNECT_PASS;
+
+                        #if defined(DEBUG_FILE)
+                           DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): End of ANT-FS session. Return to broadcast.");
+                        #endif
+                     }
+                     else
+                     {
+                        eANTFSRequest = ANTFS_REQUEST_NONE;
+                        eANTFSState = ANTFS_CLIENT_STATE_BEACONING;
+                        eResponse = ANTFS_CLIENT_RESPONSE_DISCONNECT_PASS;
+
+                        #if defined(DEBUG_FILE)
+                           DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Disconnected from host device...");
+                        #endif
+                     }
+                  }
+               }   // ANTFS_REQUEST_DISCONNECT
+               break;
+
+            case ANTFS_REQUEST_PING:
+               {
+                  // Do nothing
+                  eANTFSRequest = ANTFS_REQUEST_NONE;
+               }   // ANTFS_REQUEST_PING
+               break;
+
+            case ANTFS_REQUEST_PAIR:
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Pairing request.");
+                  #endif
+                  DSIThread_MutexLock(&stMutexPairingTimeout);
+                     eANTFSState = ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE;
+                     eResponse = ANTFS_CLIENT_RESPONSE_PAIRING_REQUEST;
+                     ucPairingTimeout = stInitParams.ucPairingTimeout;      // Changed from PAIRING_TIMEOUT to match the timeout at host, but this might be too short
+                  DSIThread_MutexUnlock(&stMutexPairingTimeout);
+               }   // ANTFS_REQUEST_PAIR
+               break;
+
+            case ANTFS_REQUEST_AUTHENTICATE:
+               {
+                  RETURN_STATUS eReturn;
+
+                  DSIThread_MutexLock(&stMutexPairingTimeout);
+                     if(bTimeoutEvent)
+                     {
+                        bAcceptRequest = FALSE;
+                        bTimeoutEvent = FALSE;
+                        AddResponse(ANTFS_CLIENT_RESPONSE_PAIRING_TIMEOUT);
+                        #if defined(DEBUG_FILE)
+                           DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Pairing timeout.");
+                        #endif
+                     }
+                     eANTFSState = ANTFS_CLIENT_STATE_AUTHENTICATING;
+                  DSIThread_MutexUnlock(&stMutexPairingTimeout);
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authenticating...");
+                  #endif
+
+                  eReturn = AttemptAuthenticateResponse();
+
+                  if (eReturn == RETURN_PASS)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication request accepted.");
+                     #endif
+
+                     SwitchToTransport(); // We passed auth, so go to transport state
+                     eResponse = ANTFS_CLIENT_RESPONSE_AUTHENTICATE_PASS;
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication failed.");
+                     #endif
+                     SwitchToAuthenticate();      // Stand by ready for retry
+                  }
+                  else if (eReturn == RETURN_REJECT)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication request rejected.");
+                     #endif
+
+                     SwitchToLink();    // We failed auth, so go to link state
+                     eResponse = ANTFS_CLIENT_RESPONSE_AUTHENTICATE_REJECT;
+                  }
+                  else if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_STOP)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication stopped.");
+                     #endif
+                     SwitchToAuthenticate();
+                  }
+                  else //RETURN_NA
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Authentication NA.");
+                     #endif
+
+                     SwitchToAuthenticate();
+                     eResponse = ANTFS_CLIENT_RESPONSE_AUTHENTICATE_NA;
+                  }
+               }   // ANTFS_REQUEST_AUTHENTICATE
+               break;
+
+            case ANTFS_REQUEST_CHANGE_LINK:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                      DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Changing radio frequency and channel period...");
+                  #endif
+
+                  eReturn = SwitchLinkParameters();
+                  if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Serial error while changing radio frequency/period.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Changing radio frequency and channel period failed.");
+                     #endif
+                     eANTFSRequest = ANTFS_REQUEST_NONE;   
+                  }
+                  else if (eReturn == RETURN_PASS)
+                  {
+                     eANTFSRequest = ANTFS_REQUEST_NONE;
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Changed radio frequency and channel period.");
+                     #endif
+                  }
+               }   // ANTFS_REQUEST_CHANGE_LINK
+               break;
+
+            case ANTFS_REQUEST_ERASE:
+               {
+                  #if defined(DEBUG_FILE)
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::ANTFSThread():  Erase request for index: %hu.", stHostRequestParams.usFileIndex);
+                     DSIDebug::ThreadWrite((char*) aucString);
+                  #endif                  
+                  eANTFSState = ANTFS_CLIENT_STATE_ERASING;
+                  eResponse = ANTFS_CLIENT_RESPONSE_ERASE_REQUEST;      
+               } // ANTFS_REQUEST_ERASE
+               break;
+
+            case ANTFS_REQUEST_ERASE_RESPONSE:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::ANTFSThread(): Erasing... Response: %u.", ucRequestResponse);
+                     DSIDebug::ThreadWrite((char*)aucString);
+                  #endif
+
+                  eReturn = AttemptEraseResponse();
+                  if (eReturn == RETURN_PASS)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Erase complete.");
+                     #endif
+
+                     SwitchToTransport();
+                     eResponse = ANTFS_CLIENT_RESPONSE_ERASE_PASS;
+                  }
+                  else if (eReturn == RETURN_REJECT)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Erase request rejected.");
+                     #endif
+
+                     SwitchToTransport();
+                     eResponse = ANTFS_CLIENT_RESPONSE_ERASE_REJECT;
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Erase fail.");
+                     #endif
+                     SwitchToTransport();
+                     eResponse = ANTFS_CLIENT_RESPONSE_ERASE_FAIL;
+                  }
+                  else if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Erase serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+                  }
+                  else
+                  {
+                     SwitchToTransport();
+                  }
+               }   // ANTFS_REQUEST_ERASE_RESPONSE
+               break;
+
+            case ANTFS_REQUEST_DOWNLOAD:
+               {
+                  #if defined(DEBUG_FILE)
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::ANTFSThread():  Download request for index: %d.", stHostRequestParams.usFileIndex);
+                     DSIDebug::ThreadWrite((char*) aucString);
+                  #endif      
+                  usTransferDataFileIndex = stHostRequestParams.usFileIndex;
+                  eANTFSState = ANTFS_CLIENT_STATE_DOWNLOADING_WAIT_FOR_DATA;
+                  eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_REQUEST;      
+               } // ANTFS_REQUEST_DOWNLOAD
+               break;
+
+            case ANTFS_REQUEST_DOWNLOAD_RESPONSE:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Downloading...");
+                  #endif
+                  eANTFSState = ANTFS_CLIENT_STATE_DOWNLOADING;
+                  eReturn = AttemptDownloadResponse();
+
+                  if (eReturn == RETURN_PASS)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Download completed.");
+                     #endif
+
+                     SwitchToTransport();
+                     eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_PASS;
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Download failed.");
+                     #endif
+                     SwitchToTransport(); 
+                     eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_FAIL;
+                  }
+                  else if (eReturn == RETURN_REJECT)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Download request rejected.");
+                     #endif
+
+                     SwitchToTransport();
+                     switch(ucRequestResponse)
+                     {
+                        case DOWNLOAD_RESPONSE_DOES_NOT_EXIST:
+                           eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_INVALID_INDEX;
+                           break;
+                        case DOWNLOAD_RESPONSE_NOT_DOWNLOADABLE:
+                           eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_FILE_NOT_READABLE;
+                           break;
+                        case DOWNLOAD_RESPONSE_NOT_READY:
+                           eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_NOT_READY;
+                           break;
+                        case DOWNLOAD_RESPONSE_REQUEST_INVALID:                     
+                        default:
+                           eResponse = ANTFS_CLIENT_RESPONSE_DOWNLOAD_REJECT;
+                           break;
+                     }
+                  }
+                  else if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Download serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else
+                  {
+                     SwitchToTransport();
+                  }
+                  
+               } // ANTFS_REQUEST_DOWNLOAD_RESPONSE
+               break;
+
+               case ANTFS_REQUEST_UPLOAD:
+               {
+                  #if defined(DEBUG_FILE)
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::ANTFSThread():  Upload request for index: %d.", stHostRequestParams.usFileIndex);
+                     DSIDebug::ThreadWrite((char*) aucString);
+                  #endif      
+                  // TODO: Implement uploads - for now, all upload requests are rejected         
+               } // ANTFS_REQUEST_UPLOAD
+               break;
+
+               case ANTFS_REQUEST_UPLOAD_RESPONSE:
+               {
+                  RETURN_STATUS eReturn;
+
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Uploading...");
+                  #endif
+                  eANTFSState = ANTFS_CLIENT_STATE_UPLOADING;
+                  eReturn = AttemptUploadResponse();
+
+                  if (eReturn == RETURN_PASS)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Upload completed.");
+                     #endif
+
+                     SwitchToTransport();
+                     eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_PASS;
+                  }
+                  else if (eReturn == RETURN_FAIL)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Upload failed.");
+                     #endif
+                     SwitchToTransport(); 
+                     eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_FAIL;
+                  }
+                  else if (eReturn == RETURN_REJECT)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Upload request rejected.");
+                     #endif
+
+                     SwitchToTransport();
+                     switch(ucRequestResponse)
+                     {
+                        case UPLOAD_RESPONSE_DOES_NOT_EXIST:
+                           eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_INVALID_INDEX;
+                           break;
+                        case UPLOAD_RESPONSE_NOT_WRITEABLE:
+                           eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_FILE_NOT_WRITEABLE;
+                           break;
+                        case UPLOAD_RESPONSE_INSUFFICIENT_SPACE:
+                           eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_INSUFFICIENT_SPACE;
+                           break; 
+                        case UPLOAD_RESPONSE_REQUEST_INVALID: 
+                        default:
+                           eResponse = ANTFS_CLIENT_RESPONSE_UPLOAD_REJECT;
+                           break;
+                     }
+                  }
+                  else if (eReturn == RETURN_SERIAL_ERROR)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread(): Upload serial error.");
+                     #endif
+
+                     DSIThread_MutexLock(&stMutexCriticalSection);
+                     if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+                        eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+                     DSIThread_MutexUnlock(&stMutexCriticalSection);
+                  }
+                  else
+                  {
+                     SwitchToTransport();
+                  }                  
+               } // ANTFS_REQUEST_UPLOAD_RESPONSE
+               break;
+
+            default:
+               break;
+         }
+
+         //This is where to handle the internal requests, because they can happen asyncronously.
+         //We will also clear the request here.
+         DSIThread_MutexLock(&stMutexCriticalSection);
+
+         if (eResponse != ANTFS_CLIENT_RESPONSE_NONE)
+            AddResponse(eResponse);
+
+         if (eANTFSRequest == ANTFS_REQUEST_CONNECTION_LOST)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Connection lost.");
+            #endif
+
+            eANTFSRequest = ANTFS_REQUEST_NONE;
+
+            if (eANTFSState >= ANTFS_CLIENT_STATE_CONNECTED)
+            {
+               SwitchToLink();
+               AddResponse(ANTFS_CLIENT_RESPONSE_CONNECTION_LOST);
+            }
+            else
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Connection lost - ignored.");
+               #endif
+            }
+         }
+         else if (eANTFSRequest == ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Serial error!");
+            #endif
+            HandleSerialError();
+            AddResponse(ANTFS_CLIENT_RESPONSE_SERIAL_FAIL);
+         }
+         else if (eANTFSRequest == ANTFS_REQUEST_SERIAL_ERROR_HANDLED)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Serial error handled");
+            #endif
+            ResetClientState();
+            eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+            eANTFSRequest = ANTFS_REQUEST_INIT;
+         }
+         else
+         {
+               eANTFSRequest = ANTFS_REQUEST_NONE;                    //Clear any other request
+         }
+
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+      }
+
+   }
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  Exiting thread.");
+   #endif
+
+   eANTFSRequest = ANTFS_REQUEST_NONE;
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+      bANTFSThreadRunning = FALSE;
+      DSIThread_CondSignal(&stCondANTFSThreadExit);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+
+   #if defined(__cplusplus)
+      return;
+   #else
+      ExitThread(0);
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::ANTFSThread():  C code reaching return statement unexpectedly.");
+      #endif
+      return;                                            // Code should not be reached.
+   #endif
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Returns: TRUE if the message is for the ANT-FS channel
+BOOL ANTFSClientChannel::FilterANTMessages(ANT_MESSAGE* pstMessage_, UCHAR ucANTChannel_)
+{ 
+   // Some messages do not include the channel number in the response, so
+   // they might get processed incorrectly
+   if(pstMessage_->ucMessageID == MESG_RESPONSE_EVENT_ID)
+   {
+      if(pstMessage_->aucData[MESG_EVENT_ID_OFFSET] == MESG_NETWORK_KEY_ID)
+      {
+         if(pstMessage_->aucData[MESG_CHANNEL_OFFSET] == ucNetworkNumber)
+            return TRUE;  // this is the network we are using
+      }
+      else if(pstMessage_->aucData[MESG_EVENT_ID_OFFSET] == MESG_RADIO_TX_POWER_ID)
+      {
+         return TRUE; // configured by client if per channel settings not available
+      }
+   }
+   else if(pstMessage_->ucMessageID == MESG_STARTUP_MESG_ID)
+   {
+      return TRUE;
+   }
+
+   if(ucANTChannel_ == ucChannelNumber)
+      return TRUE;
+
+   return FALSE;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// Returns: TRUE if the message has been handled by ANT-FS client, FALSE otherwise
+BOOL ANTFSClientChannel::ANTProtocolEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_)
+{
+   if ((ucMessageCode_ == MESG_RESPONSE_EVENT_ID) && (ucChannel_ == ucChannelNumber))
+   {
+      #if defined(DEBUG_FILE)
+         UCHAR aucString[256];
+         SNPRINTF((char *) aucString, 256, "ANTFSClientChannel::ANTProtocolEventProcess():  MESG_RESPONSE_EVENT_ID - 0x%02X", aucResponseBuf[1]);
+         DSIDebug::ThreadWrite((char *) aucString);
+      #endif
+
+      if (aucResponseBuf[1] == MESG_BURST_DATA_ID)
+      {
+         if (aucResponseBuf[2] != RESPONSE_NO_ERROR)
+         {
+            #if defined(DEBUG_FILE)
+               UCHAR aucString1[256];
+               SNPRINTF((char *) aucString1, 256, "ANTFSClientChannel::ANTProtocolEventProcess():  Burst transfer error:  0x%02X.", aucResponseBuf[2]);
+               DSIDebug::ThreadWrite((char *) aucString1);
+            #endif
+            bTxError = TRUE;
+         }
+      }
+   }
+
+   //else if (ucMessageCode_ == MESG_SERIAL_ERROR_ID)
+   //{
+   //   #if defined(DEBUG_FILE)
+   //      {
+   //         UCHAR aucString[256];
+   //         SNPRINTF((char *) aucString, 256, "ANTFSClientChannel::ANTProtocolEventProcess():  Serial Error.");
+   //         DSIDebug::ThreadWrite((char *) aucString);
+   //      }
+   //   #endif
+
+   //   DSIThread_MutexLock(&stMutexCriticalSection);
+   //   *pbCancel = TRUE;
+   //   DSIThread_CondSignal(&stCondRxEvent);
+
+   //   if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
+   //      eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
+   //   DSIThread_CondSignal(&stCondRequest);
+   //   DSIThread_MutexUnlock(&stMutexCriticalSection);
+   //}
+
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+// Returns: TRUE if the message has been handled by ANT-FS client, FALSE otherwise
+BOOL ANTFSClientChannel::ANTChannelEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_)
+{
+   // Check that we're getting a message from the correct channel.
+   if((ucChannel_ != ucChannelNumber) || ((aucRxBuf[0] & CHANNEL_NUMBER_MASK)  != ucChannelNumber))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Message received on wrong channel.");
+      #endif
+      return FALSE; // message can get passed on to the application
+   }
+
+   switch (ucMessageCode_)
+   {
+      case EVENT_RX_BROADCAST:
+         break;   // we're not going to process broadcasts or pass them to the application
+
+      case EVENT_RX_ACKNOWLEDGED:         
+         aucRxBuf[0] |= SEQUENCE_LAST_MESSAGE;   // mark it as being the last message and process as burst
+      case EVENT_RX_BURST_PACKET:   // fall thru
+         if (!bRxError)
+         {
+            if ((aucRxBuf[0] & SEQUENCE_NUMBER_ROLLOVER) == 0)  // Start of a burst.
+            {
+               // Check that this is an ANT-FS message
+               if(aucRxBuf[ANTFS_CONNECTION_OFFSET + 1] != ANTFS_COMMAND_ID)
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Invalid ANT-FS message.");
+                  #endif
+                  bRxError = TRUE;
+               }
+               else
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Burst Rx started");
+                  #endif
+               }
+               ulPacketCount = 1;
+               bReceivedCommand = FALSE;  
+
+               if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
+               {
+                  if((aucRxBuf[ANTFS_COMMAND_OFFSET + 1] == ANTFS_DOWNLOAD_ID) ||
+                     (aucRxBuf[ANTFS_COMMAND_OFFSET + 1] == ANTFS_UPLOAD_REQUEST_ID) ||
+                     (aucRxBuf[ANTFS_COMMAND_OFFSET + 1] == ANTFS_UPLOAD_DATA_ID))    // These should always be longer than one packet
+                  {                     
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Premature end of burst transfer.");
+                     #endif
+                     bRxError = TRUE;
+                  }
+                  else
+                  {                     
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Reception of burst complete. (0)");
+                     #endif
+                     bReceivedCommand = TRUE;
+                  }                  
+               }
+               #if defined(DEBUG_FILE)
+               else
+               {
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  Receiving burst... (0)");
+               }
+               #endif
+            }
+            else // Other packets in the burst
+            {   
+               if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
+               {     
+                  #if defined(DEBUG_FILE)
+                     char szString[256];
+                     SNPRINTF(szString, 256, "ANTFSClientChannel::ANTChannelEventProcess():  Reception of burst complete. (%lu).", ulPacketCount);
+                     DSIDebug::ThreadWrite(szString);
+                  #endif
+                  bReceivedCommand = TRUE;
+               }
+               else
+               {
+                  #if defined(DEBUG_FILE)                     
+                     char szString[256];
+                     SNPRINTF(szString, 256, "ANTFSClientChannel::ANTChannelEventProcess():  Receiving burst... (%lu).", ulPacketCount);
+                     DSIDebug::ThreadWrite(szString);
+                  #endif
+                  ulPacketCount++;
+               }   
+            }         
+            
+            // Process burst content
+            if(eANTFSState == ANTFS_CLIENT_STATE_BEACONING)
+            {
+               DecodeLinkCommand(&aucRxBuf[1]);
+            }
+            else if((eANTFSState >= ANTFS_CLIENT_STATE_CONNECTED) && (eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT))
+            {
+               DecodeAuthenticateCommand(aucRxBuf[0], &aucRxBuf[1]);
+            }
+            else if(eANTFSState == ANTFS_CLIENT_STATE_UPLOADING)
+            {
+               UploadInputData(aucRxBuf[0], &aucRxBuf[1]);
+            }
+            else if(eANTFSState >= ANTFS_CLIENT_STATE_TRANSPORT)
+            {
+               DecodeTransportCommand(aucRxBuf[0], &aucRxBuf[1]);
+            }
+
+         }   // if(!bRxError)
+
+         if(aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
+         {
+            DSIThread_MutexLock(&stMutexCriticalSection);
+            bReceivedBurst = TRUE;
+            bNewRxEvent = TRUE;
+            DSIThread_CondSignal(&stCondRxEvent);
+            DSIThread_MutexUnlock(&stMutexCriticalSection);
+         }
+         break;
+
+      case EVENT_TRANSFER_RX_FAILED:
+         DSIThread_MutexLock(&stMutexCriticalSection);
+            if(eANTFSRequest != ANTFS_REQUEST_NONE)
+            {
+               bRxError = TRUE;  // No need to signal an error, as no request is being processed
+            }
+            bReceivedBurst = FALSE;
+            bReceivedCommand = FALSE;
+            ucLinkCommandInProgress = ANTFS_CMD_NONE;   // Clear command, to allow the host to retry
+            DSIThread_CondSignal(&stCondRxEvent);
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  EVENT_TRANSFER_RX_FAILED");
+         #endif
+         break;
+
+      case EVENT_TRANSFER_TX_COMPLETED:
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  EVENT_TRANSFER_TX_COMPLETED");
+         #endif
+         break;
+
+      case EVENT_TRANSFER_TX_FAILED:         
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  EVENT_TRANSFER_TX_FAILED");
+         #endif
+         bTxError = TRUE;
+         break;
+
+      case EVENT_TRANSFER_TX_START:
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  EVENT_TRANSFER_TX_START");
+         #endif
+         break;
+
+      case EVENT_TX:
+         LoadBeacon();         
+         pclANT->SendBroadcastData(ucChannelNumber, aucBeacon);
+         #if defined(DEBUG_FILE2)
+            UCHAR aucString[256];
+            SNPRINTF((char *) aucString, 256, "ANTChannelEventProcess():  Beacon [0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X]", 
+               aucBeacon[0], aucBeacon[1], aucBeacon[2], aucBeacon[3], aucBeacon[4], aucBeacon[5], aucBeacon[6], aucBeacon[7]);
+            DSIDebug::ThreadWrite((char*) aucString);
+         #endif
+         break;
+
+      case EVENT_CHANNEL_CLOSED:
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::ANTChannelEventProcess():  EVENT_CHANNEL_CLOSED");
+         #endif
+         break;
+
+      default:
+         break;
+   }
+
+   return TRUE; // message has been handled, do not pass to application 
+}
+
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetDefaultBeacon(void)
+{
+   stInitParams.ucBeaconFrequency = ANTFS_RF_FREQ;
+   stInitParams.ucLinkPeriod = BEACON_PERIOD_8_HZ;
+   stInitParams.ulSerialNumber = 0;   // Use the USB device serial number by default
+   stInitParams.usBeaconDeviceType = 1;
+   stInitParams.usBeaconDeviceManufID = 1;
+   stInitParams.bPairingEnabled = TRUE;
+   stInitParams.bUploadEnabled = FALSE;
+   stInitParams.bDataAvailable = FALSE;
+   stInitParams.ucAuthType = AUTH_COMMAND_PAIR;
+   stInitParams.ucBeaconTimeout = (UCHAR) (COMMAND_TIMEOUT/1000);   // In seconds
+   stInitParams.ucPairingTimeout = (UCHAR) (AUTH_TIMEOUT/1000);   // In seconds
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::ResetClientState(void)
+{   
+   // Clear all state variables, while keeping the configuration
+   *pbCancel = FALSE;
+   ulPacketCount = 0;
+   bTxError = FALSE;
+   bRxError = FALSE;
+   bReceivedBurst = FALSE;
+   bReceivedCommand = FALSE;
+   bNewRxEvent = FALSE;
+
+   memset(aucResponseBuf, 0, sizeof(aucResponseBuf));
+   memset(aucRxBuf, 0, sizeof(aucRxBuf));   
+
+   ucPairingTimeout = MAX_UCHAR;
+   bTimeoutEvent = FALSE;
+   bReturnToBroadcast = FALSE;
+
+   ulHostSerialNumber = 0;
+   stHostFriendlyName.bNameSet = FALSE;
+   stHostFriendlyName.ucIndex = 0;
+   stHostFriendlyName.ucSize = 0;
+   memset(stHostFriendlyName.acFriendlyName, 0, FRIENDLY_NAME_MAX_LENGTH);
+   ucPassKeyIndex = 0;
+   ucAuthCommandType = MAX_UCHAR;
+   bAcceptRequest = FALSE;
+   
+   memset(&stHostRequestParams, 0, sizeof(stHostRequestParams));
+   ucRequestResponse = MAX_UCHAR; 
+
+   usTransferDataFileIndex = 0;
+   ulTransferFileSize = 0;
+   ulTransferBurstIndex = 0;
+   ulTransferBytesRemaining = 0;
+   ulTransferMaxIndex = 0;
+   ulTransferBlockSize = 0;
+   ulTransferBlockOffset = 0;
+   usTransferCrc = 0;
+   ulTransferBufferSize = 0;
+   ulDownloadProgress = 0;
+   pucDownloadData = (UCHAR*) NULL;
+
+   if(eANTFSState == ANTFS_CLIENT_STATE_OFF)
+   {
+      pucTransferBufferDynamic = (UCHAR*) NULL;
+   }
+   else
+   {
+      // Deallocate dynamically allocated memory if we had an error during a transfer
+      if (pucTransferBufferDynamic)
+      {
+         delete[] pucTransferBufferDynamic;
+         pucTransferBufferDynamic = (UCHAR*)NULL;
+      }
+
+      eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+   }
+   
+   eANTFSRequest = ANTFS_REQUEST_NONE;
+   ucLinkCommandInProgress = ANTFS_CMD_NONE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSClientChannel::ReInitDevice(void)
+{
+   if (eANTFSState != ANTFS_CLIENT_STATE_OFF)
+      this->Close();
+   
+   bKillThread = FALSE; 
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::ReInitDevice(): Initializing");
+   #endif
+
+   if (hANTFSThread == NULL)
+   {
+      hANTFSThread = DSIThread_CreateThread(&ANTFSClientChannel::ANTFSThreadStart, this);
+      if (hANTFSThread == NULL)
+         return FALSE;
+   }
+
+   if (!bTimerRunning)
+   {
+      if (DSIThread_MutexInit(&stMutexPairingTimeout) != DSI_THREAD_ENONE)
+      {
+         return FALSE;
+      }
+
+      pclTimer = new DSITimer(&ANTFSClientChannel::TimerStart, this, 1000, TRUE);
+      if (pclTimer->NoError() == FALSE)
+      {
+         DSIThread_MutexDestroy(&stMutexPairingTimeout);
+         return FALSE;
+      }
+      bTimerRunning = TRUE;
+   }
+
+   DSIThread_MutexLock(&stMutexResponseQueue);
+      clResponseQueue.Clear();                     // Should this be done in ResetClientState instead?
+   DSIThread_MutexUnlock(&stMutexResponseQueue);
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+      eANTFSRequest = ANTFS_REQUEST_INIT;
+      DSIThread_CondSignal(&stCondRequest);
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+
+   return TRUE;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// Frequency:  1 Hz
+///////////////////////////////////////////////////////////////////////
+DSI_THREAD_RETURN ANTFSClientChannel::TimerStart(void *pvParameter_)
+{
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadInit("ANTFSClient_Timer");
+   #endif
+
+   ((ANTFSClientChannel *)pvParameter_)->TimerCallback();
+
+   return 0;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::TimerCallback(void)
+{
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::TimerCallback():  Entering critical section.");
+   #endif
+
+   DSIThread_MutexLock(&stMutexPairingTimeout);
+
+   if(eANTFSState == ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE)
+   {
+      if((ucPairingTimeout > 0) && (ucPairingTimeout != CMD_TIMEOUT_DISABLED))
+      {
+         ucPairingTimeout--;
+      }
+
+      if(ucPairingTimeout == 0) // Timeout
+      {
+         #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("Timeout event.");
+         ucPairingTimeout = MAX_UCHAR;
+         bTimeoutEvent = TRUE;
+         #endif
+      }
+   }
+   DSIThread_MutexUnlock(&stMutexPairingTimeout);
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::TimerCallback():  Left critical section.");
+   #endif
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+   if((bTimeoutEvent == TRUE) && (eANTFSState == ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE))
+   {
+      // Reject the authentication request
+      eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+      DSIThread_CondSignal(&stCondRequest);
+   }
+   DSIThread_MutexUnlock(&stMutexCriticalSection);
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::HandleSerialError(void)
+{   
+   // We ended up here because we did not receive the expected response to a serial message
+   // Most likely, ANT was in the wrong state, so attempt to close the channel.
+   // No errors raised from here, as we do not know what state we are in.
+
+   UCHAR ucChannelStatus = 0;
+
+   if(pclANT->CloseChannel(ucChannelNumber, ANT_CLOSE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::HandleSerialError():  Failed to close channel.");
+      #endif
+   }
+
+   if(pclANT->UnAssignChannel(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::HandleSerialError():  Failed to unassign channel.");
+      #endif
+   }
+
+   if(pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::HandleSerialError():  Failed ANT_GetChannelStatus().");
+      #endif
+   }
+   #if defined(DEBUG_FILE)
+   else if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) != STATUS_UNASSIGNED_CHANNEL)
+   {
+      char szString[256];
+      SNPRINTF(szString, 256, "ANTFSClientChannel::HandleSerialError():  Channel state... 0x%x.", ucChannelStatus);
+      DSIDebug::ThreadWrite(szString);
+   }
+   #endif
+
+   DSIThread_MutexLock(&stMutexCriticalSection);
+
+   eANTFSRequest = ANTFS_REQUEST_SERIAL_ERROR_HANDLED;   // Reset state machine
+   DSIThread_CondSignal(&stCondRequest);
+
+   DSIThread_MutexUnlock(&stMutexCriticalSection); 
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::AddResponse(ANTFS_CLIENT_RESPONSE eResponse_)
+{
+   DSIThread_MutexLock(&stMutexResponseQueue);
+      clResponseQueue.AddResponse(eResponse_);
+      DSIThread_CondSignal(&stCondWaitForResponse);
+   DSIThread_MutexUnlock(&stMutexResponseQueue);
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::LoadBeacon(void)
+{
+   UCHAR ucBeaconStatus2;
+
+   // Status Byte 2
+   if (ucLinkCommandInProgress == ANTFS_CMD_NONE)
+   {
+      if(eANTFSState < ANTFS_CLIENT_STATE_CONNECTED)
+      {
+          ucBeaconStatus2 = REMOTE_DEVICE_STATE_LINK ;
+      }
+      else if(eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT)
+      {
+         ucBeaconStatus2 = REMOTE_DEVICE_STATE_AUTH;
+      }
+      else
+      {
+         ucBeaconStatus2 = REMOTE_DEVICE_STATE_TRANS;
+      }
+   }
+   else
+   {
+      ucBeaconStatus2 = REMOTE_DEVICE_STATE_BUSY;
+   }
+
+   aucBeacon[ANTFS_CONNECTION_OFFSET] = ANTFS_BEACON_ID;    // ANT-FS Beacon ID
+   aucBeacon[STATUS1_OFFSET] = ucActiveBeaconStatus1;         // Status Byte 1
+   aucBeacon[STATUS2_OFFSET] = ucBeaconStatus2;               // Status Byte 2
+   aucBeacon[AUTHENTICATION_TYPE_OFFSET] = stInitParams.ucAuthType;   // Authentication Type   
+
+   if (eANTFSState >= ANTFS_CLIENT_STATE_CONNECTED) // AUTH & TRANS
+   {
+      // Host serial number
+      Convert_ULONG_To_Bytes(ulHostSerialNumber,
+                           &aucBeacon[AUTH_HOST_SERIAL_NUMBER_OFFSET+3],
+                           &aucBeacon[AUTH_HOST_SERIAL_NUMBER_OFFSET+2],
+                           &aucBeacon[AUTH_HOST_SERIAL_NUMBER_OFFSET+1],
+                           &aucBeacon[AUTH_HOST_SERIAL_NUMBER_OFFSET]);
+   }
+   else
+   {
+      // Device descriptor
+      Convert_USHORT_To_Bytes(stInitParams.usBeaconDeviceType, 
+                           &aucBeacon[DEVICE_TYPE_OFFSET_HIGH],
+                           &aucBeacon[DEVICE_TYPE_OFFSET_LOW]);   // Device type
+
+      Convert_USHORT_To_Bytes(stInitParams.usBeaconDeviceManufID,
+                           &aucBeacon[MANUFACTURER_ID_OFFSET_HIGH],
+                           &aucBeacon[MANUFACTURER_ID_OFFSET_LOW]);   // Manufacturer
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptOpenBeacon(void)
+{
+   UCHAR ucChannelStatus;
+
+   if(eANTFSState != ANTFS_CLIENT_STATE_OPENING)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   if(pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_GetChannelStatus().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+   }
+
+   if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_TRACKING_CHANNEL)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon(): ANT-FS Broadcast mode, skipping channel initialization");
+      #endif
+      return RETURN_PASS;
+   }
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Full Init Begin");
+   #endif
+
+   if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_ASSIGNED_CHANNEL)
+   {      
+      if(pclANT->UnAssignChannel(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_UnAssignChannel().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+   }
+
+   if (pclANT->SetNetworkKey(ucNetworkNumber, (UCHAR *) aucTheNetworkkey, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetNetworkKey().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   if (pclANT->AssignChannel(ucChannelNumber, 0x10, ucNetworkNumber, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_AssignChannel().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetChannelPeriod().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   if (pclANT->SetChannelRFFrequency(ucChannelNumber, ucActiveBeaconFrequency, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetChannelRFFreq().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   if(bCustomTxPower)
+   {
+      if(pclANT->SetChannelTransmitPower(ucChannelNumber, ucLinkTxPower, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetChannelTransmitPower(), setting power level for all channels.");
+         #endif
+         
+         if(pclANT->SetAllChannelsTransmitPower(ucLinkTxPower, MESSAGE_TIMEOUT) == FALSE)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetAllChannelsTransmitPower().");
+            #endif
+
+            return RETURN_SERIAL_ERROR;
+         }
+      }
+   }
+
+   if (pclANT->SetChannelID(ucChannelNumber, usRadioChannelID, ucTheDeviceType, ucTheTransmissionType, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_SetChannelId().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   #if defined(DEBUG_FILE)
+      DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Opening channel...");
+   #endif
+
+   if (pclANT->OpenChannel(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptOpenBeacon():  Failed ANT_OpenChannel().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptCloseBeacon(void)
+{
+   if(bReturnToBroadcast == FALSE)
+   {
+      if(pclANT->CloseChannel(ucChannelNumber, ANT_CLOSE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptCloseBeacon(): Failed to close beacon channel");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+   }
+
+   bReturnToBroadcast = FALSE;
+   eANTFSState = ANTFS_CLIENT_STATE_IDLE;
+   eANTFSRequest = ANTFS_REQUEST_NONE;
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptAuthenticateResponse(void)
+{
+   RETURN_STATUS eReturn = RETURN_FAIL;
+   UCHAR aucTxAuth[8 + TX_PASSWORD_MAX_LENGTH]; // Response + auth string
+   UCHAR ucTxPasswordLength = 0;
+   UCHAR ucTxRetries;
+
+   ANTFS_DATA stHeader = {8, aucBeacon};
+   ANTFS_DATA stData;
+   ANTFS_DATA stFooter = {0, NULL};
+
+   ANTFRAMER_RETURN eTxComplete;
+
+   if((eANTFSState < ANTFS_CLIENT_STATE_CONNECTED) || (eANTFSState >= ANTFS_CLIENT_STATE_TRANSPORT))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptAuthenticateResponse():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   memset(aucTxAuth,0x00,sizeof(aucTxAuth));
+   
+   LoadBeacon();
+
+   aucTxAuth[ANTFS_CONNECTION_OFFSET] = ANTFS_RESPONSE_ID;
+   aucTxAuth[ANTFS_RESPONSE_OFFSET] = ANTFS_RESPONSE_AUTH_ID ;
+   if(ucAuthCommandType == AUTH_COMMAND_REQ_SERIAL_NUM)
+   {
+      aucTxAuth[AUTH_RESPONSE_OFFSET] = AUTH_RESPONSE_NA;
+      if(ucFriendlyNameSize != 0)
+      {
+         ucTxPasswordLength = ucFriendlyNameSize;
+         memcpy(&aucTxAuth[8], aucFriendlyName, ucTxPasswordLength);
+      }
+      eReturn = RETURN_NA;
+   }
+   else if(bAcceptRequest == TRUE)
+   {
+      aucTxAuth[AUTH_RESPONSE_OFFSET] = AUTH_RESPONSE_ACCEPT;
+      if((ucAuthCommandType == AUTH_COMMAND_PAIR) && (ucPassKeySize != 0))
+      {
+         ucTxPasswordLength = ucPassKeySize;
+         memcpy(&aucTxAuth[8], aucPassKey, ucTxPasswordLength);
+      }
+      eReturn = RETURN_PASS;
+   }
+   else
+   {
+      aucTxAuth[AUTH_RESPONSE_OFFSET] = AUTH_RESPONSE_REJECT;
+      eReturn = RETURN_REJECT;
+   }
+   
+   aucTxAuth[AUTH_FRIENDLY_NAME_LENGTH_OFFSET] = ucTxPasswordLength;
+   
+   Convert_ULONG_To_Bytes(stInitParams.ulSerialNumber,
+                           &aucTxAuth[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 3],
+                           &aucTxAuth[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 2],
+                           &aucTxAuth[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 1],
+                           &aucTxAuth[AUTH_REMOTE_SERIAL_NUMBER_OFFSET]);
+
+   stData.ulSize = ucTxPasswordLength + 8;
+   stData.pucData = aucTxAuth;
+
+   ucTxRetries = 8;
+   do{
+      eTxComplete = pclANT->SendANTFSClientTransfer(ucChannelNumber, &stHeader, &stData, &stFooter, ACKNOWLEDGED_TIMEOUT, NULL);
+      #if defined(DEBUG_FILE)
+      if (eTxComplete == ANTFRAMER_FAIL)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptAuthenticateResponse():  Tx error.");
+      else if (eTxComplete == ANTFRAMER_TIMEOUT)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptAuthenticateResponse():  Tx timeout.");
+      #endif
+    } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
+
+   if (eTxComplete != ANTFRAMER_PASS)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptAuthenticateResponse():  Tx failed.");
+      #endif
+      return RETURN_FAIL;
+   }
+
+   return eReturn;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptEraseResponse(void)
+{
+   RETURN_STATUS eReturn = RETURN_FAIL;
+   UCHAR aucBuffer[8];
+
+   ANTFS_DATA stHeader = {8, aucBeacon};
+   ANTFS_DATA stData = {8, aucBuffer};
+   ANTFS_DATA stFooter = {0, NULL};
+
+   ANTFRAMER_RETURN eTxComplete;
+
+   if((eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptEraseResponse():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }   
+   
+   LoadBeacon();
+
+   memset(aucBuffer,0x00,sizeof(aucBuffer));
+   aucBuffer[ANTFS_CONNECTION_OFFSET] = ANTFS_RESPONSE_ID;
+   aucBuffer[ANTFS_RESPONSE_OFFSET] = ANTFS_RESPONSE_ERASE_ID;
+   aucBuffer[ERASE_RESPONSE_OFFSET] = ucRequestResponse;
+
+   if(ucRequestResponse == ERASE_RESPONSE_OK)
+   {
+      eReturn = RETURN_PASS;
+   }
+   else
+   {
+      eReturn = RETURN_REJECT;
+   }
+
+   eTxComplete = pclANT->SendANTFSClientTransfer(ucChannelNumber, &stHeader, &stData, &stFooter, ACKNOWLEDGED_TIMEOUT, NULL);
+
+   if (eTxComplete != ANTFRAMER_PASS)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptEraseResponse():  Tx failed.");
+         if (eTxComplete == ANTFRAMER_FAIL)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptEraseResponse():  Tx error.");
+         else if (eTxComplete == ANTFRAMER_TIMEOUT)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptEraseResponse():  Tx timeout.");
+      #endif
+      return RETURN_FAIL;
+   }
+
+   return eReturn;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptDownloadResponse()
+{
+   RETURN_STATUS eReturn = RETURN_FAIL;   
+   UCHAR aucDownloadHeader[24];   // Beacon + Response
+   UCHAR aucDownloadFooter[8];   // CRC footer
+   ANTFS_DATA stHeader = {24, aucDownloadHeader};
+   ANTFS_DATA stFooter = {8, aucDownloadFooter};
+   ANTFS_DATA stData;
+
+   USHORT usSavedCrc = 0;
+   ULONG ulSavedOffset = 0;
+
+   ANTFRAMER_RETURN eTxComplete;   
+   UCHAR ucNoRxTicks;   
+   BOOL bDone = FALSE;
+   BOOL bStatus = FALSE;
+
+   if((eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }   
+
+   bReceivedCommand = FALSE;
+   bReceivedBurst = FALSE;
+   bRxError = FALSE;
+
+   do
+   {
+      if(ucRequestResponse == DOWNLOAD_RESPONSE_OK)
+      {
+         // If this is not an initial request, verify the CRC
+         if(stHostRequestParams.bInitialRequest == FALSE && stHostRequestParams.usCRCSeed != 0)
+         {
+            if(ulTransferBurstIndex < ulSavedOffset)
+            {
+               usTransferCrc = CRC_Calc16(pucDownloadData, ulTransferBurstIndex);
+            }
+            else
+            {
+               usTransferCrc = CRC_UpdateCRC16(usSavedCrc, &pucDownloadData[ulSavedOffset], ulTransferBurstIndex - ulSavedOffset);
+            }
+
+            if(usTransferCrc != stHostRequestParams.usCRCSeed)
+            {
+               #if defined(DEBUG_FILE)
+                  UCHAR aucString[256];
+                  SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::AttemptDownloadResponse(): CRC Check Failed - Expected 0x%04X, Got 0x%04X", usTransferCrc, stHostRequestParams.usCRCSeed);
+                  DSIDebug::ThreadWrite((char*) aucString);
+               #endif
+                  ucRequestResponse = DOWNLOAD_RESPONSE_CRC_FAILED;
+            }
+         }
+         else   // Use seed provided by host
+         {
+            usTransferCrc = stHostRequestParams.usCRCSeed;
+         }
+      }
+
+      if ((!bReceivedBurst) &&(!bReceivedCommand))  //prevents us from sending requests until the Rx bursts have stopped and been cleared.
+      {
+         bRxError = FALSE;
+
+         // Send out the download response
+         LoadBeacon();
+         memset(aucDownloadHeader, 0, sizeof(aucDownloadHeader));
+         memcpy(aucDownloadHeader, aucBeacon, 8);
+         aucDownloadHeader[ANTFS_CONNECTION_OFFSET + 8] = ANTFS_RESPONSE_ID;
+         aucDownloadHeader[ANTFS_RESPONSE_OFFSET + 8] = ANTFS_RESPONSE_DOWNLOAD_ID;
+         aucDownloadHeader[DOWNLOAD_RESPONSE_OFFSET + 8] = ucRequestResponse;
+         Convert_ULONG_To_Bytes(ulTransferBytesRemaining,
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 3 + 8],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 2 + 8],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 1 + 8],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 8]);
+         Convert_ULONG_To_Bytes(ulTransferBurstIndex,
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 3 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 2 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 1 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 16]);
+         Convert_ULONG_To_Bytes(ulTransferFileSize,
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 3 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 2 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 1 + 16],
+                                 &aucDownloadHeader[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 16]);
+
+         if(ucRequestResponse == DOWNLOAD_RESPONSE_OK)
+         {      
+            ULONG ulDownloadTimeout;
+            
+            if(ulTransferBytesRemaining > 0)
+            {
+               usSavedCrc = usTransferCrc;
+               ulSavedOffset = ulTransferBurstIndex;
+               usTransferCrc = CRC_UpdateCRC16(usTransferCrc, &pucDownloadData[ulTransferBurstIndex], ulTransferBytesRemaining);
+            }
+            
+            memset(aucDownloadFooter, 0, sizeof(aucDownloadFooter));
+            Convert_USHORT_To_Bytes(usTransferCrc,
+                                 &aucDownloadFooter[DOWNLOAD_RESPONSE_CRC_OFFSET + 1],
+                                 &aucDownloadFooter[DOWNLOAD_RESPONSE_CRC_OFFSET]);
+
+            stData.pucData = &pucDownloadData[ulTransferBurstIndex];
+            stData.ulSize = ulTransferBytesRemaining;
+
+            // Figure out our timeout value from the size of the transfer
+            ulDownloadTimeout = BROADCAST_TIMEOUT + (ulTransferBytesRemaining * 2);
+            if(ulTransferBytesRemaining > ((MAX_ULONG / BROADCAST_TIMEOUT)/2))
+               ulDownloadTimeout = MAX_ULONG - 1;
+
+            eTxComplete = pclANT->SendANTFSClientTransfer(ucChannelNumber, &stHeader, &stFooter, &stData, ulDownloadTimeout, &ulDownloadProgress);      
+            eReturn = RETURN_PASS;
+         }
+         else
+         {
+            eTxComplete = pclANT->SendTransfer(ucChannelNumber, aucDownloadHeader, 24, ACKNOWLEDGED_TIMEOUT);
+            eReturn = RETURN_REJECT;
+         }         
+
+         if (eTxComplete == ANTFRAMER_PASS)
+            return eReturn;   // Response transmitted successfully, we are done
+
+         #if defined(DEBUG_FILE)
+            if (eTxComplete == ANTFRAMER_FAIL)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Tx error sending download response.");
+            else if (eTxComplete == ANTFRAMER_TIMEOUT)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Tx timeout sending download response.");
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Waiting for host to attempt retry...");
+         #endif            
+      }
+
+      // Do not need to clear bReceivedBurst here because it will be done if the transfer fails or we timeout
+      // Now we wait for a retry from the host
+      ucLinkCommandInProgress = ANTFS_CMD_NONE;
+      LoadBeacon();   // Reload beacon, to let host know we are ready for retry
+      pclANT->SendBroadcastData(ucChannelNumber, aucBeacon);
+      ucNoRxTicks = 5;
+      bStatus = FALSE;
+      while (bStatus == FALSE)
+      {
+         //Wait for an rxEvent before starting to check the data
+         //Since this event is fired for many circumstances we manage all the error checking below and
+         //just use this for the wait functionality.
+         DSIThread_MutexLock(&stMutexCriticalSection);
+         bNewRxEvent = FALSE;         
+         if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
+         {
+            DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, MESSAGE_TIMEOUT);
+         }
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+         if (*pbCancel == TRUE)
+         {
+            #if defined(DEBUG_FILE) 
+               DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Stopped.");
+            #endif
+            return RETURN_STOP;
+         }
+
+         if (!bReceivedBurst)
+         {
+            #if defined(DEBUG_FILE)               
+                  DSIDebug::ThreadWrite("-->Waiting for download request...");
+            #endif
+            ucNoRxTicks--;
+            if(ucNoRxTicks == 0)
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Timeout while waiting for host request retry");
+               #endif
+               return RETURN_FAIL;   // Timeout
+            }
+         }      
+
+         if (bReceivedCommand)        //If a command has been received, process it.
+         {
+            bReceivedCommand = FALSE;  //Clear these for any potential retries
+            bReceivedBurst = FALSE;     //Clearing these for retries
+
+            // Process request
+            if(ucLinkCommandInProgress == ANTFS_DOWNLOAD_ID)
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse(): Resuming download...");
+               #endif
+               bStatus = TRUE;
+               if(stHostRequestParams.usFileIndex != usTransferDataFileIndex)
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse(): Invalid index requested.");
+                  #endif
+                  ucRequestResponse = DOWNLOAD_RESPONSE_REQUEST_INVALID;
+               }
+               if(ucRequestResponse == DOWNLOAD_RESPONSE_OK)
+               {
+                  DSIThread_MutexLock(&stMutexCriticalSection);
+                  if(stHostRequestParams.ulOffset > ulTransferFileSize)
+                  {
+                     #if defined(DEBUG_FILE)
+                        DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse(): Invalid offset requested");
+                     #endif
+                     ucRequestResponse = DOWNLOAD_RESPONSE_REQUEST_INVALID;
+                  }
+                  else
+                  {
+                     // Adjust response parameters
+                     ulTransferBurstIndex = stHostRequestParams.ulOffset;
+                     ulTransferBytesRemaining = ulTransferFileSize - ulTransferBurstIndex;
+                     ulDownloadProgress = 0;
+                     if((stHostRequestParams.ulBlockSize != 0) && (ulTransferBytesRemaining > stHostRequestParams.ulBlockSize))
+                     {   // Host is limiting block size
+                        ulTransferBytesRemaining = stHostRequestParams.ulBlockSize;
+                     }
+                     if((ulTransferBlockSize != 0) && (ulTransferBytesRemaining > ulTransferBlockSize))
+                     {   // Client is limiting block size
+                        ulTransferBytesRemaining = ulTransferBlockSize;
+                     }
+                  }
+                  DSIThread_MutexUnlock(&stMutexCriticalSection);
+               }   // ucRequestResponse == DOWNLOAD_RESPONSE_OK
+            }   // ucLinkCommandInProgress == ANTFS_DOWNLOAD_ID
+         } // bReceivedCommand
+
+         if(bRxError)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptDownloadResponse():  Rx error");
+            #endif
+            bRxError = FALSE;
+         }         
+      } // Rx command loop
+
+   } while (!bDone);
+
+   return eReturn;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::AttemptUploadResponse()
+{
+   RETURN_STATUS eReturn = RETURN_FAIL;
+   UCHAR aucBuffer[24];
+
+   ANTFS_DATA stHeader = {sizeof(aucBeacon), aucBeacon};
+   ANTFS_DATA stData = {sizeof(aucBuffer), aucBuffer};
+   ANTFS_DATA stFooter = {0, NULL};
+
+   ANTFRAMER_RETURN eTxComplete;   
+
+   if((eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptUploadResponse():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   if(ucRequestResponse == UPLOAD_RESPONSE_OK)
+   {
+      // TODO: Uploads not supported yet, so for now, always reject
+      ucRequestResponse = UPLOAD_RESPONSE_REQUEST_INVALID;
+   }
+   
+   ulTransferBlockOffset = 0;
+   ulTransferMaxIndex = 0;
+   ulTransferBlockSize = 0;
+   usTransferCrc = 0;
+   eReturn = RETURN_REJECT;
+
+   LoadBeacon();
+
+   memset(aucBuffer, 0, sizeof(aucBuffer));
+   aucBuffer[ANTFS_CONNECTION_OFFSET] = ANTFS_RESPONSE_ID;
+   aucBuffer[ANTFS_RESPONSE_OFFSET] = ANTFS_RESPONSE_UPLOAD_ID;
+   aucBuffer[UPLOAD_RESPONSE_OFFSET] = ucRequestResponse;
+   Convert_ULONG_To_Bytes(ulTransferBlockOffset,
+                           &aucBuffer[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 3],
+                           &aucBuffer[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 2],
+                           &aucBuffer[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 1],
+                           &aucBuffer[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET]);
+   Convert_ULONG_To_Bytes(ulTransferMaxIndex,
+                           &aucBuffer[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 3],
+                           &aucBuffer[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 2],
+                           &aucBuffer[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 1],
+                           &aucBuffer[UPLOAD_RESPONSE_MAX_SIZE_OFFSET]);
+   Convert_ULONG_To_Bytes(ulTransferBlockSize,
+                           &aucBuffer[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 3],
+                           &aucBuffer[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 2],
+                           &aucBuffer[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 1],
+                           &aucBuffer[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET]);
+   Convert_USHORT_To_Bytes(usTransferCrc,
+                           &aucBuffer[UPLOAD_RESPONSE_CRC_OFFSET + 1],
+                           &aucBuffer[UPLOAD_RESPONSE_CRC_OFFSET]);
+
+   eTxComplete = pclANT->SendANTFSClientTransfer(ucChannelNumber, &stHeader, &stFooter, &stData, MESSAGE_TIMEOUT, NULL);
+
+   if (eTxComplete != ANTFRAMER_PASS)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptUploadResponse():  Tx failed.");
+         if (eTxComplete == ANTFRAMER_FAIL)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptUploadResponse():  Tx error.");
+         else if (eTxComplete == ANTFRAMER_TIMEOUT)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::AttemptUploadResponse():  Tx timeout.");
+      #endif
+      return RETURN_FAIL;
+   }
+
+   return eReturn;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::DecodeLinkCommand(UCHAR *pucLinkCommand_)
+{
+   UCHAR ucPeriod;
+
+   if(pucLinkCommand_[ANTFS_CONNECTION_OFFSET] != ANTFS_COMMAND_ID)
+      return;
+
+   switch (pucLinkCommand_[ANTFS_COMMAND_OFFSET])
+   {
+      case ANTFS_CONNECT_ID:
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeLinkCommand(): Received LINK request.");
+         #endif
+
+         ucActiveBeaconFrequency = pucLinkCommand_[TRANSPORT_CHANNEL_FREQ_OFFSET];   
+         ucPeriod= pucLinkCommand_[TRANSPORT_CHANNEL_PERIOD];    
+         SetANTChannelPeriod(ucPeriod);
+         ulHostSerialNumber = Convert_Bytes_To_ULONG(
+            pucLinkCommand_[HOST_ID_OFFSET+3],
+            pucLinkCommand_[HOST_ID_OFFSET+2],
+            pucLinkCommand_[HOST_ID_OFFSET+1],
+            pucLinkCommand_[HOST_ID_OFFSET]);
+
+         DSIThread_MutexLock(&stMutexCriticalSection);
+            eANTFSRequest = ANTFS_REQUEST_CONNECT;
+            DSIThread_CondSignal(&stCondRequest);
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+         break;
+      }   // CONNECT
+      case ANTFS_DISCONNECT_ID:
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeLinkCommand(): Received DISCONNECT request");
+         #endif
+
+         stHostDisconnectParams.ucCommandType = pucLinkCommand_[DISCONNECT_COMMAND_TYPE_OFFSET];
+         stHostDisconnectParams.ucTimeDuration = pucLinkCommand_[DISCONNECT_TIME_DURATION_OFFSET];
+         stHostDisconnectParams.ucAppSpecificDuration = pucLinkCommand_[DISCONNECT_APP_DURATION_OFFSET];
+
+         DSIThread_MutexLock(&stMutexCriticalSection);   
+            eANTFSRequest = ANTFS_REQUEST_DISCONNECT;
+            DSIThread_CondSignal(&stCondRequest);
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+         break;
+      }  // DISCONNECT
+      default:
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeLinkCommand(): Invalid command.");
+         #endif
+         break;
+      }
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::DecodeAuthenticateCommand(UCHAR ucControlByte_, UCHAR *pucAuthCommand_)
+{
+   if (((ucControlByte_ & ~SEQUENCE_LAST_MESSAGE) == 0) && (ucLinkCommandInProgress != ANTFS_CMD_NONE))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received new request, but client is busy processing something already.");
+      #endif
+      return;
+   }
+
+   if(pucAuthCommand_[ANTFS_CONNECTION_OFFSET] == ANTFS_COMMAND_ID)
+   {
+      if(pucAuthCommand_[ANTFS_COMMAND_OFFSET] == ANTFS_AUTHENTICATE_ID)
+      {
+         ucLinkCommandInProgress = ANTFS_AUTHENTICATE_ID;
+         ucAuthCommandType = pucAuthCommand_[AUTH_COMMAND_TYPE_OFFSET];
+      }
+   }
+      
+   if((ucLinkCommandInProgress == ANTFS_AUTHENTICATE_ID))
+   {
+      if((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // first packet
+      {         
+         ULONG ulRxHostSerialNumber = Convert_Bytes_To_ULONG(
+               pucAuthCommand_[HOST_ID_OFFSET+3],
+               pucAuthCommand_[HOST_ID_OFFSET+2],
+               pucAuthCommand_[HOST_ID_OFFSET+1],
+               pucAuthCommand_[HOST_ID_OFFSET]);
+         bAcceptRequest = TRUE;
+         if(ulRxHostSerialNumber != ulHostSerialNumber)   // Check host serial number
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Not the expected host");
+            #endif
+            bAcceptRequest = FALSE;
+         }
+      }
+
+      switch(ucAuthCommandType)
+      {
+         case AUTH_COMMAND_REQ_SERIAL_NUM:
+         {
+            if(ucControlByte_ & SEQUENCE_LAST_MESSAGE) // wait until the burst completes
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received AUTH serial number request.");
+               #endif
+               DSIThread_MutexLock(&stMutexCriticalSection);   
+                  eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+                  DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+            break;
+         }   // AUTH_COMMAND_REQ_SERIAL_NUM
+         case AUTH_COMMAND_GOTO_TRANSPORT:
+         {
+            if(ucControlByte_ & SEQUENCE_LAST_MESSAGE) // wait until the burst completes
+            {   
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received AUTH pass through request.");
+               #endif
+               if(stInitParams.ucAuthType != AUTH_COMMAND_GOTO_TRANSPORT)
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Pass through authentication not supported.");
+                  #endif
+                  bAcceptRequest = FALSE;
+               }
+               DSIThread_MutexLock(&stMutexCriticalSection);   
+                  eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+                  DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);               
+            }
+            break;
+         }   // AUTH_COMMAND_GOTO_TRANSPORT
+         case AUTH_COMMAND_PAIR:
+         {            
+            if((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // first packet
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received AUTH pairing request.");
+               #endif
+               stHostFriendlyName.bNameSet = FALSE;
+               stHostFriendlyName.ucIndex = 0;
+               stHostFriendlyName.ucSize = pucAuthCommand_[AUTH_FRIENDLY_NAME_LENGTH_OFFSET];
+               if(stHostFriendlyName.ucSize > FRIENDLY_NAME_MAX_LENGTH)
+                  stHostFriendlyName.ucSize = FRIENDLY_NAME_MAX_LENGTH;
+               memset(stHostFriendlyName.acFriendlyName, 0, FRIENDLY_NAME_MAX_LENGTH);
+            }
+            else   // read host friendly name
+            {
+               if(stHostFriendlyName.ucIndex < FRIENDLY_NAME_MAX_LENGTH)
+               {
+                  UCHAR ucNumBytes = FRIENDLY_NAME_MAX_LENGTH - stHostFriendlyName.ucIndex;
+                  if(ucNumBytes > 8)
+                  {
+                     ucNumBytes = 8;
+                  }
+                  memcpy((UCHAR*) &stHostFriendlyName.acFriendlyName[stHostFriendlyName.ucIndex], pucAuthCommand_, ucNumBytes);
+                  stHostFriendlyName.ucIndex += ucNumBytes;
+               }
+            }
+            if(ucControlByte_ & SEQUENCE_LAST_MESSAGE)   // last packet
+            {
+               ENUM_ANTFS_REQUEST eTheRequest;
+               if(stInitParams.bPairingEnabled && (stInitParams.ucAuthType <= AUTH_COMMAND_PASSKEY) && bAcceptRequest)
+               {
+                  if(stHostFriendlyName.ucSize > 0)
+                  {
+                     stHostFriendlyName.bNameSet = TRUE;
+                  }
+                  eTheRequest = ANTFS_REQUEST_PAIR;
+               }
+               else
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Pairing authentication not supported.");
+                  #endif
+                  bAcceptRequest = FALSE;
+                  eTheRequest = ANTFS_REQUEST_AUTHENTICATE;   
+               }
+               DSIThread_MutexLock(&stMutexCriticalSection);   
+                  eANTFSRequest = eTheRequest;                     
+               DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+            break;
+         }   // AUTH_COMMAND_PAIR
+         case AUTH_COMMAND_PASSKEY:
+         {
+            if ((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // initial packet
+            {
+               UCHAR ucPasswordSize = pucAuthCommand_[AUTH_PASSWORD_LENGTH_OFFSET];   // Passkey length
+
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received AUTH passkey request.");
+               #endif
+
+               if(ucPasswordSize != ucPassKeySize)
+               {
+                  bAcceptRequest = FALSE;   // Reject if lengths do not match       
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Incorrect string size");
+                  #endif
+               }
+               else
+               {
+                  ucPassKeyIndex = 0;
+               }
+            }
+            else
+            {
+               UCHAR ucCounter;
+
+               for (ucCounter = 0; ucCounter < 8; ucCounter++)
+               {
+                  if (ucPassKeyIndex >= ucPassKeySize)
+                     break;
+                  if (aucPassKey[ucPassKeyIndex++] != pucAuthCommand_[ucCounter])
+                  {
+                     bAcceptRequest = FALSE;  // Reject if passkeys are different
+                  }
+               }
+            }
+            if (ucControlByte_ & SEQUENCE_LAST_MESSAGE)   // last packet
+            {      
+               if((stInitParams.ucAuthType != AUTH_COMMAND_PASSKEY) && (stInitParams.ucAuthType != AUTH_COMMAND_GOTO_TRANSPORT) && (ucPassKeySize == 0))
+               {
+                  bAcceptRequest = FALSE;
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Passkey authentication not supported.");
+                  #endif
+               }
+               if (ucPassKeyIndex < ucPassKeySize)
+               {
+                  bAcceptRequest = FALSE;           // Reject if we did not get the complete passkey
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Incomplete passkey.");
+                  #endif
+               }
+               DSIThread_MutexLock(&stMutexCriticalSection);   
+                  eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+               DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+            break;
+         }   // AUTH_COMMAND_PASSKEY
+         default:
+         {
+            if (ucControlByte_ & SEQUENCE_LAST_MESSAGE)   // last packet
+               {
+                  #if defined(DEBUG_FILE)
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "Received unknown AUTH request: %u", ucAuthCommandType);
+                     DSIDebug::ThreadWrite((char*) aucString);
+                  #endif
+                  DSIThread_MutexLock(&stMutexCriticalSection);   
+                     eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
+                     bAcceptRequest = FALSE;   // Reject unknown auth requests
+                  DSIThread_CondSignal(&stCondRequest);
+                  DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+            break;
+         }
+      }
+   }   // ANTFS_AUTHENTICATE_ID
+   else if (pucAuthCommand_[ANTFS_COMMAND_OFFSET] == ANTFS_DISCONNECT_ID)
+   {
+      if (ucControlByte_ & SEQUENCE_LAST_MESSAGE) // don't do anything until the burst completes
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Received DISCONNECT request");
+         #endif
+
+         stHostDisconnectParams.ucCommandType = pucAuthCommand_[DISCONNECT_COMMAND_TYPE_OFFSET];
+         stHostDisconnectParams.ucTimeDuration = pucAuthCommand_[DISCONNECT_TIME_DURATION_OFFSET];
+         stHostDisconnectParams.ucAppSpecificDuration = pucAuthCommand_[DISCONNECT_APP_DURATION_OFFSET];
+
+         DSIThread_MutexLock(&stMutexCriticalSection);   
+            eANTFSRequest = ANTFS_REQUEST_DISCONNECT;
+            DSIThread_CondSignal(&stCondRequest);
+         DSIThread_MutexUnlock(&stMutexCriticalSection);
+      }
+   }   // ANTFS_DISCONNECT_ID
+   else if (pucAuthCommand_[ANTFS_COMMAND_OFFSET] == ANTFS_PING_ID)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeAuthenticateCommand(): Ping!");
+      #endif
+
+      DSIThread_MutexLock(&stMutexCriticalSection);   
+         ucLinkCommandInProgress = ANTFS_CMD_NONE;  
+         eANTFSRequest = ANTFS_REQUEST_PING;
+         DSIThread_CondSignal(&stCondRequest);
+      DSIThread_MutexUnlock(&stMutexCriticalSection);
+   }   // ANTFS_PING_ID
+   else
+   {
+      #if defined(DEBUG_FILE)
+         UCHAR aucString[256];
+         SNPRINTF((char *) aucString, 256, "ANTFSClientChannel::DecodeAuthenticateCommand(): Received invalid request: %u", pucAuthCommand_[ANTFS_COMMAND_OFFSET]);
+         DSIDebug::ThreadWrite((char*) aucString);
+      #endif
+      ucLinkCommandInProgress = ANTFS_CMD_NONE; 
+   }   // OTHER REQUESTS
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::DecodeTransportCommand(UCHAR ucControlByte_, UCHAR *pucTransCommand_)
+{
+   if (((ucControlByte_ & ~SEQUENCE_LAST_MESSAGE) == 0) && (ucLinkCommandInProgress != ANTFS_CMD_NONE))
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Received new request, but client is busy.");
+      #endif
+      return;
+   }
+
+   if(pucTransCommand_[ANTFS_CONNECTION_OFFSET] == ANTFS_COMMAND_ID)
+   {
+      ucLinkCommandInProgress = pucTransCommand_[ANTFS_COMMAND_OFFSET];
+   }
+
+   switch(ucLinkCommandInProgress)
+   {
+      case ANTFS_PING_ID:
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Ping!");
+            #endif
+            DSIThread_MutexLock(&stMutexCriticalSection);   
+               ucLinkCommandInProgress = ANTFS_CMD_NONE;  
+               eANTFSRequest = ANTFS_REQUEST_PING;
+               DSIThread_CondSignal(&stCondRequest);
+            DSIThread_MutexUnlock(&stMutexCriticalSection);
+         }   // ANTFS_PING_ID
+         break;
+
+      case ANTFS_DISCONNECT_ID:
+         {
+            if (ucControlByte_ & SEQUENCE_LAST_MESSAGE) // don't do anything until the burst completes
+            {
+               #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Received DISCONNECT request");
+               #endif
+               
+               stHostDisconnectParams.ucCommandType = pucTransCommand_[DISCONNECT_COMMAND_TYPE_OFFSET];
+               stHostDisconnectParams.ucTimeDuration = pucTransCommand_[DISCONNECT_TIME_DURATION_OFFSET];
+               stHostDisconnectParams.ucAppSpecificDuration = pucTransCommand_[DISCONNECT_APP_DURATION_OFFSET];
+
+               DSIThread_MutexLock(&stMutexCriticalSection);   
+                  eANTFSRequest = ANTFS_REQUEST_DISCONNECT;
+                  DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+         }  // ANTFS_DISCONNECT_ID
+         break;
+
+      case ANTFS_LINK_ID:
+         {
+            ULONG ulRxHostSerialNumber;
+
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Received LINK request.");
+            #endif
+            
+            ulRxHostSerialNumber = Convert_Bytes_To_ULONG(
+               pucTransCommand_[HOST_ID_OFFSET+3],
+               pucTransCommand_[HOST_ID_OFFSET+2],
+               pucTransCommand_[HOST_ID_OFFSET+1],
+               pucTransCommand_[HOST_ID_OFFSET]);            
+
+            if(ulHostSerialNumber == ulRxHostSerialNumber)
+            {
+               UCHAR ucPeriod= pucTransCommand_[TRANSPORT_CHANNEL_PERIOD]; 
+               ucActiveBeaconFrequency = pucTransCommand_[TRANSPORT_CHANNEL_FREQ_OFFSET];                  
+               SetANTChannelPeriod(ucPeriod);
+
+               DSIThread_MutexLock(&stMutexCriticalSection);
+                  eANTFSRequest = ANTFS_REQUEST_CHANGE_LINK;
+                  DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+            ucLinkCommandInProgress = ANTFS_CMD_NONE;
+         }   // ANTFS_LINK_ID
+         break;
+
+      case ANTFS_ERASE_ID:
+         {
+            if(ucControlByte_ & SEQUENCE_LAST_MESSAGE) // don't do anything unless the burst completes
+            {
+               ucRequestResponse = ERASE_RESPONSE_REJECT;   // set initial request parameters
+
+               stHostRequestParams.usFileIndex = Convert_Bytes_To_USHORT(
+                  pucTransCommand_[DATA_INDEX_OFFSET + 1],
+                  pucTransCommand_[DATA_INDEX_OFFSET]);         
+               stHostRequestParams.bInitialRequest = FALSE;
+               stHostRequestParams.ulBlockSize = 0;
+               stHostRequestParams.ulOffset = 0;
+               stHostRequestParams.usCRCSeed = 0;
+
+               #if defined(DEBUG_FILE)
+               {
+                  UCHAR aucString[256];
+                  SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::DecodeTransportCommand: Received ERASE request (%hu)", stHostRequestParams.usFileIndex);
+                  DSIDebug::ThreadWrite((char*) aucString);
+               }
+               #endif
+               
+               DSIThread_MutexLock(&stMutexCriticalSection);
+                  ucLinkCommandInProgress = ANTFS_ERASE_ID;
+                  eANTFSRequest = ANTFS_REQUEST_ERASE;
+                  DSIThread_CondSignal(&stCondRequest);
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+         }   // ANTFS_ERASE_ID
+         break;
+
+      case ANTFS_DOWNLOAD_ID:
+         {
+            if((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // first packet
+            {               
+               stHostRequestParams.usFileIndex = Convert_Bytes_To_USHORT(
+                  pucTransCommand_[DATA_INDEX_OFFSET + 1],
+                  pucTransCommand_[DATA_INDEX_OFFSET]);
+               stHostRequestParams.ulOffset = Convert_Bytes_To_ULONG(
+                  pucTransCommand_[DOWNLOAD_DATA_OFFSET_OFFSET + 3],
+                  pucTransCommand_[DOWNLOAD_DATA_OFFSET_OFFSET + 2],
+                  pucTransCommand_[DOWNLOAD_DATA_OFFSET_OFFSET + 1],
+                  pucTransCommand_[DOWNLOAD_DATA_OFFSET_OFFSET]);      
+               #if defined(DEBUG_FILE)
+               {
+                  UCHAR aucString[256];
+                  SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::DecodeTransportCommand: Received DOWNLOAD request (%hu/%lu)", stHostRequestParams.usFileIndex, stHostRequestParams.ulOffset);
+                  DSIDebug::ThreadWrite((char*) aucString);
+               }
+               #endif
+            }
+            else if (ucControlByte_ & SEQUENCE_LAST_MESSAGE)   // last (second) packet
+            {
+               stHostRequestParams.usCRCSeed = Convert_Bytes_To_USHORT(
+                  pucTransCommand_[DOWNLOAD_DATA_CRC_OFFSET + 1],
+                  pucTransCommand_[DOWNLOAD_DATA_CRC_OFFSET]);
+               stHostRequestParams.ulBlockSize = Convert_Bytes_To_ULONG(
+                  pucTransCommand_[DOWNLOAD_DATA_SIZE_OFFSET + 3],
+                  pucTransCommand_[DOWNLOAD_DATA_SIZE_OFFSET + 2],
+                  pucTransCommand_[DOWNLOAD_DATA_SIZE_OFFSET + 1],
+                  pucTransCommand_[DOWNLOAD_DATA_SIZE_OFFSET]);
+               stHostRequestParams.bInitialRequest = pucTransCommand_[DOWNLOAD_DATA_INITIAL_OFFSET] & 0x01;
+               stHostRequestParams.ulMaxSize = 0;
+
+               DSIThread_MutexLock(&stMutexCriticalSection);
+               if(eANTFSState == ANTFS_CLIENT_STATE_TRANSPORT)
+               {
+                  ucLinkCommandInProgress = ANTFS_DOWNLOAD_ID;
+                  eANTFSRequest = ANTFS_REQUEST_DOWNLOAD;
+                  DSIThread_CondSignal(&stCondRequest);
+               }
+               DSIThread_MutexUnlock(&stMutexCriticalSection);
+            }
+
+         }   // ANTFS_DOWNLOAD_ID
+         break;
+
+      case ANTFS_UPLOAD_REQUEST_ID:
+         {
+            if(stInitParams.bUploadEnabled)   // Only process if we support uploads
+            {
+               if((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // first packet
+               {
+                  stHostRequestParams.bInitialRequest = FALSE;
+                  stHostRequestParams.usFileIndex = Convert_Bytes_To_USHORT(
+                     pucTransCommand_[DATA_INDEX_OFFSET + 1],
+                     pucTransCommand_[DATA_INDEX_OFFSET]);
+                  stHostRequestParams.ulMaxSize = Convert_Bytes_To_ULONG(
+                     pucTransCommand_[UPLOAD_MAX_SIZE_OFFSET + 3],
+                     pucTransCommand_[UPLOAD_MAX_SIZE_OFFSET + 2],
+                     pucTransCommand_[UPLOAD_MAX_SIZE_OFFSET + 1],
+                     pucTransCommand_[UPLOAD_MAX_SIZE_OFFSET]);
+               }
+               else if (ucControlByte_ & SEQUENCE_LAST_MESSAGE)   // last (second) packet
+               {
+                  stHostRequestParams.ulOffset = Convert_Bytes_To_ULONG(
+                     pucTransCommand_[DATA_OFFSET_SMALL_OFFSET + 3],
+                     pucTransCommand_[DATA_OFFSET_SMALL_OFFSET + 2],
+                     pucTransCommand_[DATA_OFFSET_SMALL_OFFSET + 1],
+                     pucTransCommand_[DATA_OFFSET_SMALL_OFFSET]);
+                  stHostRequestParams.bInitialRequest = FALSE;
+                  stHostRequestParams.ulBlockSize = 0;
+                  stHostRequestParams.usCRCSeed = 0;
+
+                  #if defined(DEBUG_FILE)
+                  {
+                     UCHAR aucString[256];
+                     SNPRINTF((char*) aucString, 256, "ANTFSClientChannel::DecodeTransportCommand: Received UPLOAD request (%hu/%lu)", stHostRequestParams.usFileIndex, stHostRequestParams.ulOffset);
+                     DSIDebug::ThreadWrite((char*) aucString);
+                  }
+                  #endif
+
+                  DSIThread_MutexLock(&stMutexCriticalSection);
+                  if(eANTFSState == ANTFS_CLIENT_STATE_TRANSPORT)
+                  {
+                     stHostRequestParams.bInitialRequest = TRUE;
+                     ucLinkCommandInProgress = ANTFS_UPLOAD_REQUEST_ID;
+                     //eANTFSRequest = ANTFS_REQUEST_UPLOAD;
+                     // TODO: Uploads not implemented, should send upload request to application
+                     // Reject the request, for now
+                     ucRequestResponse = UPLOAD_RESPONSE_REQUEST_INVALID; 
+                     eANTFSRequest = ANTFS_REQUEST_UPLOAD_RESPONSE;
+                     DSIThread_CondSignal(&stCondRequest);
+                  }
+                  DSIThread_MutexUnlock(&stMutexCriticalSection);                  
+               }
+            }
+            else
+            {
+				if (ucControlByte_ & SEQUENCE_LAST_MESSAGE) 
+				{
+				   // Reject if uploads are not supported
+				   DSIThread_MutexLock(&stMutexCriticalSection);
+					  ucRequestResponse = UPLOAD_RESPONSE_REQUEST_INVALID; 
+					  eANTFSRequest = ANTFS_REQUEST_UPLOAD_RESPONSE;
+					  DSIThread_CondSignal(&stCondRequest);
+				   DSIThread_MutexUnlock(&stMutexCriticalSection);  
+				}
+            }
+         }   // ANTFS_UPLOAD_ID
+         break;
+
+      case ANTFS_UPLOAD_DATA_ID:
+         {
+            if(stInitParams.bUploadEnabled && eANTFSState == ANTFS_CLIENT_STATE_UPLOADING_WAIT_FOR_RESPONSE)   // Only process if we support uploads
+            {
+               if((ucControlByte_ & SEQUENCE_NUMBER_ROLLOVER) == 0) // first packet
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Received UPLOAD DATA.");
+                  #endif
+                  stHostRequestParams.usCRCSeed = Convert_Bytes_To_USHORT(
+                     pucTransCommand_[UPLOAD_DATA_CRC_SEED_OFFSET + 1],
+                     pucTransCommand_[UPLOAD_DATA_CRC_SEED_OFFSET]);
+                  stHostRequestParams.ulOffset = Convert_Bytes_To_ULONG(
+                     pucTransCommand_[UPLOAD_DATA_DATA_OFFSET_OFFSET + 3],
+                     pucTransCommand_[UPLOAD_DATA_DATA_OFFSET_OFFSET + 2],
+                     pucTransCommand_[UPLOAD_DATA_DATA_OFFSET_OFFSET + 1],
+                     pucTransCommand_[UPLOAD_DATA_DATA_OFFSET_OFFSET]);
+               }
+               if(ucControlByte_ & SEQUENCE_LAST_MESSAGE)
+               {
+                  #if defined(DEBUG_FILE)
+                     DSIDebug::ThreadWrite("ANTFSClientChannel::DecodeTransportCommand(): Upload contains no data.");
+                  #endif
+               }
+            }
+         } // ANTFS_UPLOAD_DATA_ID:
+         break;
+
+      default:
+         {
+            #if defined(DEBUG_FILE)
+               UCHAR aucString[256];
+               SNPRINTF((char *) aucString, 256, "ANTFSClientChannel::DecodeTransportCommand(): Received invalid request: %u", ucLinkCommandInProgress);
+               DSIDebug::ThreadWrite((char*) aucString);
+            #endif
+            ucLinkCommandInProgress = ANTFS_CMD_NONE;
+         }   // DEFAULT
+         break;
+   }
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::UploadInputData(UCHAR ucControlByte_, UCHAR* pucMesg_)
+{
+   // TODO: Implement upload
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::SwitchToLink(void)
+{
+   if(eANTFSState < ANTFS_CLIENT_STATE_IDLE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   if(eANTFSState > ANTFS_CLIENT_STATE_IDLE)
+   {
+      // Reload beacon link configuration
+      ucActiveBeaconStatus1 = 0;
+      ucActiveBeaconStatus1 |= ((stInitParams.ucLinkPeriod & BEACON_PERIOD_MASK) << BEACON_PERIOD_SHIFT);
+      ucActiveBeaconStatus1 |= stInitParams.bPairingEnabled * PAIRING_AVAILABLE_FLAG_MASK;
+      ucActiveBeaconStatus1 |= stInitParams.bUploadEnabled * UPLOAD_ENABLED_FLAG_MASK;
+      ucActiveBeaconStatus1 |= stInitParams.bDataAvailable * DATA_AVAILABLE_FLAG_MASK;   
+      
+      ucActiveBeaconFrequency = stInitParams.ucBeaconFrequency;   
+      if(pclANT->SetChannelRFFrequency(ucChannelNumber, ucActiveBeaconFrequency, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink():  Failed ANT_SetChannelRFFreq().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+
+      SetANTChannelPeriod(stInitParams.ucLinkPeriod);
+      if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink():  Failed ANT_SetChannelPeriod().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+
+      if(bCustomTxPower)
+      {
+         if(pclANT->SetChannelTransmitPower(ucChannelNumber, ucLinkTxPower, MESSAGE_TIMEOUT) == FALSE)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink():  Failed ANT_SetChannelTransmitPower(), setting power level for all channels.");
+            #endif
+            
+            if(pclANT->SetAllChannelsTransmitPower(ucLinkTxPower, MESSAGE_TIMEOUT) == FALSE)
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink():  Failed ANT_SetAllChannelsTransmitPower().");
+               #endif
+
+               return RETURN_SERIAL_ERROR;
+            }
+         }
+      }
+
+      if(bReturnToBroadcast) // No need to reload beacon if going back to broadcast
+      {
+         ucLinkCommandInProgress = ANTFS_CMD_NONE;
+         return RETURN_PASS;
+      }
+   }   
+
+   eANTFSState = ANTFS_CLIENT_STATE_BEACONING;
+   ucLinkCommandInProgress = ANTFS_CMD_NONE;
+
+   bReceivedCommand = FALSE;
+   bReceivedBurst = FALSE;
+   bRxError = FALSE;   
+
+   LoadBeacon();
+   if(pclANT->SendBroadcastData(ucChannelNumber, aucBeacon) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToLink(): Failed to load beacon.");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }   
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::SwitchToAuthenticate(void)
+{
+   if(eANTFSState < ANTFS_CLIENT_STATE_BEACONING)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   if(eANTFSState < ANTFS_CLIENT_STATE_CONNECTED)
+   {
+      if(pclANT->SetChannelRFFrequency(ucChannelNumber, ucActiveBeaconFrequency, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate():  Failed ANT_SetChannelRFFreq().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+
+      if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
+      {
+         #if defined(DEBUG_FILE)
+            DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate():  Failed ANT_SetChannelPeriod().");
+         #endif
+         return RETURN_SERIAL_ERROR;
+      }
+
+      if(bCustomTxPower)
+      {
+         if(pclANT->SetChannelTransmitPower(ucChannelNumber, ucSessionTxPower, MESSAGE_TIMEOUT) == FALSE)
+         {
+            #if defined(DEBUG_FILE)
+               DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate():  Failed ANT_SetChannelTransmittPower(), setting power level for all channels.");
+            #endif
+            
+            if(pclANT->SetAllChannelsTransmitPower(ucSessionTxPower, MESSAGE_TIMEOUT) == FALSE)
+            {
+               #if defined(DEBUG_FILE)
+                  DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate():  Failed ANT_SetAllChannelsTransmittPower().");
+               #endif
+
+               return RETURN_SERIAL_ERROR;
+            }
+         }
+      }
+   }
+
+   ucPairingTimeout = MAX_UCHAR;
+   eANTFSState = ANTFS_CLIENT_STATE_CONNECTED;
+   ucLinkCommandInProgress = ANTFS_CMD_NONE;
+
+   bReceivedCommand = FALSE;
+   bReceivedBurst = FALSE;
+   bRxError = FALSE;
+
+   LoadBeacon();
+   if(pclANT->SendBroadcastData(ucChannelNumber, aucBeacon) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToAuthenticate(): Failed to load beacon.");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }   
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::SwitchToTransport(void)
+{
+   if(eANTFSState < ANTFS_CLIENT_STATE_CONNECTED)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToTransport():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   eANTFSState = ANTFS_CLIENT_STATE_TRANSPORT;
+   ucLinkCommandInProgress = ANTFS_CMD_NONE;
+
+   bReceivedCommand = FALSE;
+   bReceivedBurst = FALSE;
+   bRxError = FALSE;
+
+   LoadBeacon();
+   if(pclANT->SendBroadcastData(ucChannelNumber, aucBeacon) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchToTransport(): Failed to load beacon.");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }   
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+ANTFSClientChannel::RETURN_STATUS ANTFSClientChannel::SwitchLinkParameters(void)
+{
+   if(eANTFSState < ANTFS_CLIENT_STATE_TRANSPORT)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchLinkParameters():  Device is not in correct state.");
+      #endif
+
+      return RETURN_FAIL;
+   }
+
+   if(pclANT->SetChannelRFFrequency(ucChannelNumber, ucActiveBeaconFrequency, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchLinkParameters():  Failed ANT_SetChannelRFFreq().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchLinkParameters():  Failed ANT_SetChannelPeriod().");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }
+
+   ucLinkCommandInProgress = ANTFS_CMD_NONE;
+
+   LoadBeacon();
+   if(pclANT->SendBroadcastData(ucChannelNumber, aucBeacon) == FALSE)
+   {
+      #if defined(DEBUG_FILE)
+         DSIDebug::ThreadWrite("ANTFSClientChannel::SwitchLinkParameters(): Failed to load beacon.");
+      #endif
+      return RETURN_SERIAL_ERROR;
+   }   
+
+   return RETURN_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////
+void ANTFSClientChannel::SetANTChannelPeriod(UCHAR ucLinkPeriod_)
+{
+   switch (ucLinkPeriod_)
+   {
+      default: // Shouldn't happen.
+      case BEACON_PERIOD_0_5_HZ:
+         usTheMessagePeriod = 65535;
+         break;
+      case BEACON_PERIOD_1_HZ:
+         usTheMessagePeriod = 32768;
+         break;
+      case BEACON_PERIOD_2_HZ:
+         usTheMessagePeriod = 16384;
+         break;
+      case BEACON_PERIOD_4_HZ:
+         usTheMessagePeriod = 8192;
+         break;
+      case BEACON_PERIOD_8_HZ:
+         usTheMessagePeriod = 4096;
+         break;
+      case BEACON_PERIOD_KEEP:
+         usTheMessagePeriod = usBeaconChannelPeriod;
+         break;
+   }
+
+   ucActiveBeaconStatus1 &= ~BEACON_PERIOD_MASK;
+   ucActiveBeaconStatus1 |= ((ucLinkPeriod_ & BEACON_PERIOD_MASK) << BEACON_PERIOD_SHIFT);
+}
+
+

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.cpp.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a00c16ae2835d4f6590e67de7d676dac
+timeCreated: 1468561033
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 777 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.hpp

@@ -0,0 +1,777 @@
+/*
+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.
+*/
+ 
+
+#if !defined(ANTFS_CLIENT_CHANNEL_HPP)
+#define ANTFS_CLIENT_CHANNEL_HPP
+
+#include "types.h"
+#include "dsi_thread.h"
+#include "dsi_timer.hpp"
+#include "dsi_framer_ant.hpp"
+#include "dsi_debug.hpp"
+
+#include "dsi_response_queue.hpp"
+#include "dsi_ant_message_processor.hpp"
+#include "antfs_client_interface.hpp"
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Definitions
+//////////////////////////////////////////////////////////////////////////////////
+typedef struct 
+{
+   char acFriendlyName[FRIENDLY_NAME_MAX_LENGTH];
+   BOOL bNameSet;
+   UCHAR ucIndex;
+   UCHAR ucSize;
+} ANTFS_FRIENDLY_NAME;
+
+/////////////////////////////////////////////////////////////////
+// This class implements the ANT-FS Client specification.
+// It is intended to be used together with another class that manages
+// the connection to an ANT USB stick (e.g. DSIANTDevice or
+// .NET ANT_Device).
+/////////////////////////////////////////////////////////////////
+class ANTFSClientChannel : public ANTFSClientInterface, public DSIANTMessageProcessor
+{
+   private:
+
+      //////////////////////////////////////////////////////////////////////////////////
+      // Private Definitions
+      //////////////////////////////////////////////////////////////////////////////////
+
+      enum ENUM_ANTFS_REQUEST
+      {
+         ANTFS_REQUEST_NONE = 0,
+         ANTFS_REQUEST_INIT,                                    // Init()
+         ANTFS_REQUEST_OPEN_BEACON,                             // OpenBeacon()
+         ANTFS_REQUEST_CLOSE_BEACON,                            // CloseBeacon()
+         ANTFS_REQUEST_CONNECT,                                 // From Host: Switch to Authenticate
+         ANTFS_REQUEST_DISCONNECT,                              // From Host: End session
+         ANTFS_REQUEST_PING,                                    // From Host: Keep session alive
+         ANTFS_REQUEST_AUTHENTICATE,                            // From Host: Send authentication Response
+         ANTFS_REQUEST_PAIR,                                    // From Host: Send pairing request to application
+         ANTFS_REQUEST_CHANGE_LINK,                             // From Host: Switch frequency/period
+         ANTFS_REQUEST_DOWNLOAD,                                // From Host: Download requested
+         ANTFS_REQUEST_DOWNLOAD_RESPONSE,                       // SendDownloadResponse();
+         ANTFS_REQUEST_UPLOAD,                                  // From Host: Upload requested
+         ANTFS_REQUEST_UPLOAD_RESPONSE,                         // SendUploadResponse()
+         ANTFS_REQUEST_ERASE,                                   // From Host: Erase request
+         ANTFS_REQUEST_ERASE_RESPONSE,                          // SendEraseResponse()
+         ANTFS_REQUEST_CONNECTION_LOST,                         // Internal, keep these at the end of the list order is important
+         ANTFS_REQUEST_HANDLE_SERIAL_ERROR,                     // Internal
+         ANTFS_REQUEST_SERIAL_ERROR_HANDLED                     // Internal
+      };
+
+      enum RETURN_STATUS
+      {
+         RETURN_FAIL = 0,
+         RETURN_PASS,
+         RETURN_STOP,
+         RETURN_REJECT,
+         RETURN_NA,
+         RETURN_SERIAL_ERROR
+      };
+
+      //////////////////////////////////////////////////////////////////////////////////
+      // Private Variables
+      //////////////////////////////////////////////////////////////////////////////////
+      DSIResponseQueue<ANTFS_CLIENT_RESPONSE> clResponseQueue;
+
+      BOOL bInitFailed;
+
+      UCHAR aucResponseBuf[MESG_MAX_SIZE_VALUE];
+      UCHAR aucRxBuf[MESG_MAX_SIZE_VALUE];
+
+      DSI_THREAD_ID hANTFSThread;                           // Handle for the ANTFS thread.
+      DSI_MUTEX stMutexResponseQueue;                       // Mutex used with the response queue
+      DSI_MUTEX stMutexCriticalSection;                     // Mutex used with the wait condition
+      DSI_MUTEX stMutexPairingTimeout;                      // Mutex used with the pairing timeouts      
+      DSI_CONDITION_VAR stCondANTFSThreadExit;              // Event to signal the ANTFS thread has ended
+      DSI_CONDITION_VAR stCondRequest;                      // Event to signal there is a new request
+      DSI_CONDITION_VAR stCondRxEvent;                      // Event to signal there is a new Rx message or failure
+      DSI_CONDITION_VAR stCondWaitForResponse;              // Event to signal there is a new response to the application
+
+      DSITimer *pclTimer;
+      volatile BOOL bTimerRunning;      
+      volatile BOOL bANTFSThreadRunning;
+      volatile BOOL bKillThread;
+      volatile BOOL bCancel;       // Internal cancel parameter to use if not configured
+      volatile BOOL *pbCancel;
+
+      DSIFramerANT *pclANT;
+
+      // ANT Channel parameters
+      UCHAR ucNetworkNumber;
+      //UCHAR ucChannelNumber;
+      USHORT usRadioChannelID;      // ANT Channel Device ID
+      UCHAR ucTheDeviceType;            
+      UCHAR ucTheTransmissionType;    
+      USHORT usTheMessagePeriod;       
+      UCHAR aucTheNetworkkey[8];     
+      
+      UCHAR ucLinkTxPower;
+      UCHAR ucSessionTxPower;
+      BOOL bCustomTxPower;      
+
+      // Bursting
+      volatile ULONG ulPacketCount;
+      volatile BOOL bTxError;
+      volatile BOOL bRxError;
+      volatile BOOL bReceivedBurst;
+      volatile BOOL bReceivedCommand;
+      volatile BOOL bNewRxEvent;
+
+      // Beacon parameters
+      ANTFS_CLIENT_PARAMS stInitParams;         // Initial parameters
+      UCHAR aucFriendlyName[FRIENDLY_NAME_MAX_LENGTH];   // Cache application defined friendly name
+      UCHAR aucPassKey[PASSWORD_MAX_LENGTH];    // Cache application defined passkey
+      UCHAR ucPassKeySize;                      // PassKey length
+      UCHAR ucFriendlyNameSize;                 // Friendly name length
+      UCHAR ucActiveBeaconFrequency;            // Active radio frequency for the beacon
+      UCHAR ucActiveBeaconStatus1;              // Beacon Status 1 byte
+      UCHAR aucBeacon[8];                       // Beacon buffer
+      USHORT usBeaconChannelPeriod;             // If custom period (not defined by ANT-FS)
+
+      // ANT-FS Broadcast
+      BOOL bReturnToBroadcast;                  // Default action when closing the beacon
+
+      // Link state
+      ULONG ulHostSerialNumber;
+
+      // Authentication state
+      ANTFS_FRIENDLY_NAME stHostFriendlyName;   // Host Friendly Name
+      UCHAR ucPassKeyIndex;                     // Current location of auth string Tx block
+      UCHAR ucAuthCommandType;                  // Authentication command type in progress
+      BOOL bAcceptRequest;                      // Accept/reject authentication request
+
+      // Pairing
+      UCHAR ucPairingTimeout;
+      volatile BOOL bTimeoutEvent;
+
+      // Disconnect
+      ANTFS_DISCONNECT_PARAMS stHostDisconnectParams; // Parameters received from the hsot on a disconnect request
+
+      // Transport state
+      ANTFS_REQUEST_PARAMS stHostRequestParams; // Parameters received from the host on a file transfer request
+      UCHAR ucRequestResponse;                  // Response from the application to the request      
+
+      // Data transfer
+      USHORT usTransferDataFileIndex;           // Index of current file being transferred
+      volatile ULONG ulTransferFileSize;        // File size of current transfer, in bytes
+      volatile ULONG ulTransferBurstIndex;      // Current location within the burst block, in bytes
+      volatile ULONG ulTransferBytesRemaining;  // Total remaining data length of the current block, in bytes
+      volatile ULONG ulTransferMaxIndex;        // Upper limit of the current transmitted burst block, in bytes
+      volatile ULONG ulTransferBlockSize;       // Maximum block size, limited by client device      
+      volatile USHORT usTransferCrc;            // Data CRC      
+      volatile ULONG ulDownloadProgress;        // Current download progress (number of bytes transferred)
+
+      volatile ULONG ulTransferBlockOffset;     // Offset, in bytes, of the data block provided by the application
+      volatile ULONG ulTransferBufferSize;
+      
+      UCHAR *pucDownloadData;                   // Buffer with data to download
+      UCHAR *pucTransferBufferDynamic;          // Dynamic buffer for uploads
+
+      volatile ENUM_ANTFS_REQUEST eANTFSRequest;
+      volatile ANTFS_CLIENT_STATE eANTFSState;
+      volatile UCHAR ucLinkCommandInProgress; 
+
+      //////////////////////////////////////////////////////////////////////////////////
+      // Private Function Prototypes
+      //////////////////////////////////////////////////////////////////////////////////
+      
+      void ANTFSThread(void);
+      static DSI_THREAD_RETURN ANTFSThreadStart(void *pvParameter_);
+      void TimerCallback(void);
+      static DSI_THREAD_RETURN TimerStart(void *pvParameter_);
+
+      void SetDefaultBeacon(void);
+      void ResetClientState(void);
+      BOOL ReInitDevice(void);
+
+      void HandleSerialError(void);     
+
+      BOOL FilterANTMessages(ANT_MESSAGE* pstMessage_, UCHAR ucANTChannel_);
+      BOOL ANTProtocolEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_);
+      BOOL ANTChannelEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_);
+
+      void AddResponse(ANTFS_CLIENT_RESPONSE eResponse_);
+      void LoadBeacon(void);
+      
+      RETURN_STATUS AttemptOpenBeacon(void);
+      RETURN_STATUS AttemptCloseBeacon(void);
+      RETURN_STATUS AttemptAuthenticateResponse(void);
+      RETURN_STATUS AttemptEraseResponse(void);
+      RETURN_STATUS AttemptDownloadResponse(void);
+      RETURN_STATUS AttemptUploadResponse(void);
+
+      void DecodeLinkCommand(UCHAR *pucLinkCommand_);
+      void DecodeAuthenticateCommand(UCHAR ucControlByte_, UCHAR *pucAuthCommand_);
+      void DecodeTransportCommand(UCHAR ucControlByte_, UCHAR *pucTransCommand_);
+      void UploadInputData(UCHAR ucControlByte_, UCHAR* pucMesg_);
+
+      RETURN_STATUS SwitchToLink(void);
+      RETURN_STATUS SwitchToAuthenticate(void);
+      RETURN_STATUS SwitchToTransport(void);
+      RETURN_STATUS SwitchLinkParameters(void);
+
+      void SetANTChannelPeriod(UCHAR ucLinkPeriod_);    
+
+   public:
+
+      //////////////////////////////////////////////////////////////////////////////////
+      // Public Function Prototypes
+      //////////////////////////////////////////////////////////////////////////////////
+
+      ANTFSClientChannel();
+      ~ANTFSClientChannel();
+
+      BOOL Init(DSIFramerANT* pclANT_, UCHAR ucChannel_);
+      /////////////////////////////////////////////////////////////////
+      // Begins to initialize the ANTFSClientChannel object.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Parameters:
+      //    *pclANT_:         Pointer to a DSIFramerANT object.
+      //    ucChannel_:       Channel number to use for the ANT-FS host
+      // Operation:
+      //    This function is used from a class managing the connection
+      //    to ANT (e.g. DSIANTDevice or .NET ANT_Device), to
+      //    initialize the ANTFSClientChannel object. It is not possible
+      //    to change the channel number once ANT-FS is running.
+      //    The function returns immediately, and the ANTFSHostChannel object
+      //    will send a response of ANTFS_HOST_RESPONSE_INIT_PASS.
+      //    IT IS NOT NECESSARY TO CALL THIS FUNCTION DIRECTLY FROM USER APPLICATIONS.
+      /////////////////////////////////////////////////////////////////
+
+      void Close(void);
+      /////////////////////////////////////////////////////////////////
+      // Stops any pending actions, closes all threads and cleans
+      // up any dynamic memory being used by the library.
+      // Operation:
+      //    This function is used from a class managing the connection
+      //    to ANT (e.g. DSIANTDevice or .NET ANT_Device), to
+      //    clean up any resources in use by the ANT-FS host.
+      //    IT IS NOT NECESSARY TO CALL THIS FUNCTION DIRECTLY FROM USER APPLICATIONS.
+      /////////////////////////////////////////////////////////////////
+
+      void ProcessMessage(ANT_MESSAGE* pstMessage_, USHORT usMesgSize_);
+      /////////////////////////////////////////////////////////////////
+      // Processes incoming ANT messages as per the ANT-FS Technology
+      // Specification
+      // Parameters:
+      //    pstMessage_:      Pointer to an ANT message structure
+      //    usMesgSize_:      ANT message size
+      // Operation:
+      //    This function is used from a class managing the connection
+      //    to ANT (e.g. DSIANTDevice or .NET ANT_Device).
+      //    IT IS NOT NECESSARY TO CALL THIS FUNCTION DIRECTLY FROM USER APPLICATIONS.
+      /////////////////////////////////////////////////////////////////
+
+      void ProcessDeviceNotification(ANT_DEVICE_NOTIFICATION eCode_, void* pvParameter_);
+      /////////////////////////////////////////////////////////////////
+      // Processes device level notifications
+      // Parameters:
+      //    eCode_:          Device notification event code
+      //    pvParameter_:    Pointer to struct defining specific parameters related 
+      //                     to the event code
+      // Operation:
+      //    This function is used from a class managing the connection
+      //    to ANT (e.g. DSIANTDevice or .NET ANT_Device).
+      //    IT IS NOT NECESSARY TO CALL THIS FUNCTION DIRECTLY FROM USER APPLICATIONS.
+      /////////////////////////////////////////////////////////////////
+
+      void Cancel(void);
+      /////////////////////////////////////////////////////////////////
+      // Cancels any pending actions and returns the library to the
+      // appropriate ANTFS layer if possible.  ie if the library was
+      // executing a download command in the transport layer, the
+      // library would be returned to ANTFS_CLIENT_STATE_TRANSPORT after
+      // execution of this function.
+      /////////////////////////////////////////////////////////////////
+
+      // TODO: Serial number is configured within InitParams.  Should it be a
+      //    separate SetSerialNumber function for consistency with the host, or
+      //    should the host be configured with a struct as in this function?
+      ANTFS_RETURN ConfigureClientParameters(ANTFS_CLIENT_PARAMS* pstInitParams_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the ANTFS Client configuration parameters.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Parameters:
+      //   *pstInitParams_:   A pointer to an
+      //                      ANTFS_PARAMS structure that defines the
+      //                      configuration parameters of the client
+      //                      device
+      // Operation:
+      //      This function can only be used before the beacon is open;
+      //      Changes are only applied when calling OpenBeacon().
+      //      Certain parameters can be changed at any time, see
+      //          SetPairingEnabled
+      //          SetUploadEnabled
+      //          SetDataAvailable
+      //          SetBeaconTimeout
+      //          SetPairingTimeout
+      //      If the client is not configured prior to opening the
+      //      beacon, the default ANT-FS PC beacon configuration is used.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SetPairingEnabled(BOOL bEnable_);
+      /////////////////////////////////////////////////////////////////
+      // Enable handling of pairing authentication requests, and indicate
+      // so in the beacon.
+      // Parameters:
+      //    bEnable_:         Set to TRUE to enable pairing and FALSE
+      //                      to disable.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    This function can be used at any time, except while handling
+      //    an authentication request
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SetUploadEnabled(BOOL bEnable_);
+      /////////////////////////////////////////////////////////////////
+      // Enable uploads, indicating so in the beacon.
+      // Parameters:
+      //    bEnable_:         Set to TRUE to enable pairing and FALSE
+      //                      to disable.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    This function can be used at any time, except while handling
+      //    a transport request (i.e. during an upload)
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SetDataAvailable(BOOL bDataAvailable_);
+      /////////////////////////////////////////////////////////////////
+      // Indicate in the beacon whether data is available for download.
+      // Parameters:
+      //    bDataAvailable_:  Set to TRUE if data is available and
+      //                      FALSE if not.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    This function can be used at any time, except while handling
+      //    a transport request (i.e. during a download)
+      /////////////////////////////////////////////////////////////////
+
+      // TODO: SetState (Status1 byte, consistent with integrated FS interface)?
+      
+      void SetBeaconTimeout(UCHAR ucTimeout_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the time the client will wait without receiving any
+      // commands from the host before dropping back to the link state
+      // Parameters:
+      //   ucTimeout_:           Timeout, in seconds. Set to 0xFF to
+      //                         disable (infinite timeout). 
+      //                         Zero is not an allowed value.
+      /////////////////////////////////////////////////////////////////
+
+      void SetPairingTimeout(UCHAR ucTimeout_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the time the client will wait without receiving any
+      // response from the application to a pairing request before
+      // rejecting it
+      // Parameters:
+      //   ucTimeout_:           Timeout, in seconds. Set to 0xFF to
+      //                         disable (infinite timeout).
+      //                         Zero is not an allowed value.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SetFriendlyName(UCHAR* pucFriendlyName_, UCHAR ucFriendlyNameSize_);
+      /////////////////////////////////////////////////////////////////
+      // Set up a friendly name for the ANT-FS client
+      // Parameters:
+      //    *pucFriendlyName: A pointer to a character string
+      //                      containing the friendly name of the client.
+      //                      Set to NULL to disable
+      //    ucFriendlyNameSize: Size of the friendly name string (max 255)
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    This function can be used at any time, except while handling
+      //    an authentication request.
+      //    No friendly name will be sent with authentication responses
+      //    unless configured with this command.
+      //    The friendly name is cached by the client library.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SetPassKey(UCHAR* pucPassKey_, UCHAR ucPassKeySize_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the pass key for the client to establish authenticated
+      // sessions with a host device
+      // Parameters:
+      //    *pucPassKey:      Array containing the pass key
+      //                      Set to NULL to disable
+      //    ucPassKeySize:    Size of the passkey (max 255)
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    This function can be used at any time, except while handling
+      //    an authentication request.
+      //    PassKey authentication is disabled by default, unless
+      //    this command is called to configure a key.
+      //    The passkey is cached by the client library.
+      /////////////////////////////////////////////////////////////////
+
+      void SetChannelID(UCHAR ucDeviceType_, UCHAR ucTransmissionType_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the ANT Channel ID for the ANT-FS Client
+      // Parameters:
+      //   ucDeviceType_:        ANT Channel Device Type
+      //   ucTransmissionType_:  ANT Channel Transmission Type
+      // Operation:
+      //   Configuration changes are applied when the beacon is opened
+      /////////////////////////////////////////////////////////////////
+
+      void SetChannelPeriod(USHORT usChannelPeriod_);
+      /////////////////////////////////////////////////////////////////
+      // Set up a custom ANT channel period
+      // Parameters:
+      //   usChannelPeriod_:     Message count, in seconds * 32768.  
+      //                         For example, for 4Hz, set to 8192.
+      // Operation:
+      //   Use this function if using ANT-FS broadcast and configuring a
+      //   beacon period not defined in the ANT-FS Technology Specification
+      //   When using this option, set the Link Period beacon parameter to 
+      //   BEACON_PERIOD_KEEP.  This is the channel period the client will 
+      //   use when in LINK state or when it returns to broadcast.
+      /////////////////////////////////////////////////////////////////
+
+      void SetNetworkKey(UCHAR ucNetwork_, UCHAR ucNetworkKey[]);
+      /////////////////////////////////////////////////////////////////
+      // Set up the network key to use with the ANT-FS Client
+      // Parameters:   
+      //   ucNetwork_:        Network number
+      //   ucNetorkKey_:      Array containing the 8-byte network key      
+      // Operation:
+      //   Configuration changes are applied when the beacon is opened
+      /////////////////////////////////////////////////////////////////
+
+      void SetTxPower(UCHAR ucPairingLv_, UCHAR ucConnectedLv_);
+      /////////////////////////////////////////////////////////////////
+      // Set up the transmit power for the ANT-FS Channel.
+      // Parameters:
+      //      ucPairingLv_:   Power level to use while beaconing (link)
+      //      ucConnectedLv_: Power level to use during a session
+      // Operation:
+      //      This command can be used to facilitate pairing when 
+      //      proximity search is used in the host device.
+      //      If the ANT part does not support setting the transmit power
+      //      on a per channel basis, it is set for all channels
+      //      Configuration changes are applied when the client switches
+      //      to the link and authentication states.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN OpenBeacon(void);
+      /////////////////////////////////////////////////////////////////
+      // Begins the channel configuration to transmit the ANT-FS beacon
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation: 
+      //    This function will configure the beacon and start broadcasting.
+      //    If the channel is already open (i.e. broadcast mode), only the
+      //    contents of the beacon will change, not the channel configuration.
+      //    Once the channel is successfully configured and opened,
+      //    a response of ANTFS_CLIENT_RESPONSE_BEACON_OPEN will be sent.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN CloseBeacon(BOOL bReturnToBroadcast_ = FALSE);
+      /////////////////////////////////////////////////////////////////
+      // Closes the ANT-FS beacon.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Parameters:
+      //      bReturnToBroadcast_:   If TRUE, the channel will remain
+      //                         open, and the application can continue
+      //                         to process messages. If FALSE,
+      //                         the channel will be closed.
+      // Operation: 
+      //    Once the channel is successfully closed, a response of 
+      //    ANTFS_CLIENT_RESPONSE_BEACON_CLOSED will be sent,
+      //    and the ANTFSClient will be in the ANTFS_STATE_IDLE state.
+      //    If the ReturnToBroadcast parameter is not used, the default 
+      //    behavior will be to close the channel and stop broadcasting.
+      /////////////////////////////////////////////////////////////////
+            
+      BOOL GetEnabled(void);
+      /////////////////////////////////////////////////////////////////
+      // Returns the current status of ANT-FS message processing
+      // Returns TRUE if ANT-FS is enabled.  Otherwise, it returns FALSE.
+      // Operation:
+      //    This function is used from a class managing the connection
+      //    to ANT (e.g. DSIANTDevice or .NET ANT_Device).
+      //    IT IS NOT NECESSARY TO CALL THIS FUNCTION DIRECTLY FROM USER APPLICATIONS.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_CLIENT_STATE GetStatus(void);
+      /////////////////////////////////////////////////////////////////
+      // Returns the current library status.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetHostName(UCHAR *aucHostFriendlyName_, UCHAR *pucBufferSize_);
+      /////////////////////////////////////////////////////////////////
+      // Copies at most ucBufferSize_ characters from the host's
+      // friendly name string (for the most recent session) into the 
+      // supplied pucHostFriendlyName_ buffer.
+      // Parameters:
+      //    *aucFriendlyName_: A pointer to a buffer where the remote
+      //                      device friendly name will be copied.
+      //    *pucBufferSize_:  Pointer to a UCHAR variable that should contain the
+      //                      maximum size of the buffer pointed to by 
+      //                      aucHostFriendlyName_.
+      //                      After the function returns, the UCHAR variable
+      //                      will be set to reflect the size of the friendly 
+      //                      name string that has been copied to the buffer.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    If the host's friendly name string has fewer than ucBufferSize_
+      //    characters, the *aucFriendlyName_ buffer will be padded with 
+      //    zeroes.  
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetRequestParameters(ANTFS_REQUEST_PARAMS* pstRequestParams_);
+      /////////////////////////////////////////////////////////////////
+      // Gets the full parameters for a download, upload or erase request
+      // received from the host.
+      //
+      // Parameters:
+      //    *pstRequestParams_: Pointer to an ANTFS_REQUEST_PARAMS
+      //                      structure that will receive the details
+      //                      of the download, upload or erase request.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    This function makes available all of the parameters received
+      //    from the host when requesting a data transfer.  These 
+      //    parameters are available for information purposes; the client
+      //    application only needs to process the index to handle the
+      //    request.
+      //    This information is valid while a download, upload or erase
+      //    request is in progress.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetRequestedFileIndex(USHORT *pusIndex_);
+      /////////////////////////////////////////////////////////////////
+      // Gets the index requested for a download, upload or erase request
+      // Parameters:
+      //    *pulByteProgress_: Pointer to a USHORT that will receive
+      //                      the current fle index requested
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    This information is valid while a download, upload or erase
+      //    request is in progress.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetDownloadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_);
+      /////////////////////////////////////////////////////////////////
+      // Gets the transfer progress of a pending or a complete
+      // download.
+      // Parameters:
+      //    *pulByteProgress_: Pointer to a ULONG that will receive
+      //                      the current byte progress of a pending or
+      //                      complete download.
+      //    *pulTotalLength_: Pointer to a ULONG that will receive the
+      //                      total expected length of the download.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      // A data download occurs when information is requested from a
+      // remote device.  This function may be called at any point
+      // during a download as a progress indicator.  After the transfer
+      // is complete, this information is valid until another request
+      // for a data transfer is made.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetUploadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_);
+      /////////////////////////////////////////////////////////////////
+      // Gets the transfer progress of a pending or a complete
+      // upload.
+      // Parameters:
+      //    *pulByteProgress_: Pointer to a ULONG that will receive
+      //                      the current byte progress of a pending or
+      //                      complete upload.
+      //    *pulTotalLength_: Pointer to a ULONG that will receive the
+      //                      total expected length of the upload.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      // A data upload occurs when information is sent to a
+      // remote device.  This function may be called at any point
+      // during an upload as a progress indicator.  After the transfer
+      // is complete, this information is valid until another request
+      // for a data transfer is made.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetTransferData(ULONG *pulDataSize_ , void *pvData_ = NULL);
+      /////////////////////////////////////////////////////////////////
+      // Gets the received data from a transfer (upload).
+      //
+      // Parameters:
+      //    *ulDataSize_:     Pointer to a ULONG that will receive
+      //                      the size of the data available in bytes.
+      //    *pvData_:         Pointer to a buffer where the received data
+      //                      will be copied.  NULL can be passed to this
+      //                      parameter so that the size can be retrieved
+      //                      without copying any data.  The application
+      //                      can then call this function again to after it
+      //                      has allocated a buffer of sufficient size to
+      //                      handle the data.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      /////////////////////////////////////////////////////////////////
+
+      BOOL GetDisconnectParameters(ANTFS_DISCONNECT_PARAMS* pstDisconnectParams_);
+      /////////////////////////////////////////////////////////////////
+      // Gets the full parameters for a disconnect command
+      // received from the host.
+      //
+      // Parameters:
+      //    *pstRequestParams_: Pointer to an ANTFS_DISCONNECT_PARAMS
+      //                      structure that will receive the details
+      //                      of the disconnect request.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    This function makes available all of the parameters received
+      //    from the host when requesting to disconnect from the client.  
+      //    These parameters can let the client know whether it is
+      //    returning to broadcast/link state, as well as if it needs
+      //    to make itself undiscoverable for a period of time.
+      //    This information is valid after an ANTFS_RESPONSE_DISCONNECT_PASS
+      //    is received
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SendPairingResponse(BOOL bAccept_);
+      /////////////////////////////////////////////////////////////////
+      // Sends a response to a pairing request.
+      // Parameters:
+      //    bAccept_:         Set this value to TRUE to accept the
+      //                      pairing request, and FALSE to reject it.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    A pairing request will automatically be rejected if no
+      //    response is sent within the pairing timeout, and the 
+      //    application will receive an ANTFS_CLIENT_RESPONSE_PAIRING_TIMEOUT
+      //    response.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SendDownloadResponse(UCHAR ucResponse_, ANTFS_DOWNLOAD_PARAMS* pstDownloadInfo_, ULONG ulDataLength_, void *pvData_);
+      /////////////////////////////////////////////////////////////////
+      // Sends the response to a download request from an authenticated
+      // device.
+      // Parameters:
+      //    ucResponse_:      The response to the download request.
+      //    stDownloadInfo_:  Pointer to an ANTFS_CLIENT_DOWNLOAD_PARAMS
+      //                      structure holding the parameters of the
+      //                      download response.
+      //    ulDataLength_:    The byte length of the data block to be 
+      //                      downloaded to the host device. This is the
+      //                      size of the entire file, as specified in
+      //                      the directory.  Set to zero if no data 
+      //                      is to be downloaded.
+      //    *pvData_:         Pointer to the location where the data
+      //                      to be downloaded is stored.  The pointer 
+      //                      should correspond with the beginning of the
+      //                      file, without applying any offsets. 
+      //                      Set to NULL if no data is to be 
+      //                      downloaded (response rejected).
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    The data block provided to this function should be the entire
+      //    file. Handling of offsets and CRC calculations is done
+      //    internally within the library.
+      //    Once the request is posted, the application must wait for the
+      //    response from the library.  Possible responses are:
+      //       ANTFS_CLIENT_RESPONSE_DOWNLOAD_PASS
+      //       ANTFS_CLIENT_RESPONSE_DOwNLOAD_REJECT
+      //       ANTFS_CLIENT_RESPONSE_DOWNLOAD_FAIL
+      //       ANTFS_CLIENT_RESPONSE_SERIAL_FAIL
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SendUploadResponse(UCHAR ucResponse_, ANTFS_UPLOAD_PARAMS* pstUploadInfo_, ULONG ulDataLength_, void *pvData_);
+      /////////////////////////////////////////////////////////////////
+      // Sends the response to an upload request from an authenticated
+      // device.
+      // Parameters:
+      //    ucResponse_:      The response to the upload request.
+      //    pstUploadInfo_:   Pointer to an ANTFS_UPLOAD_PARAMS
+      //                      structure holding the parameters of the
+      //                      upload response.
+      //    ulDataLength_:    The byte length of the data that is 
+      //                      currently stored at the requested upload
+      //                      location.  Set to zero if uploading to a
+      //                      new index or if the uploaded data will
+      //                      overwrite all existing data
+      //    *pvData_:         Pointer to the location of the data at the
+      //                      requested upload index. Set to NULL
+      //                      if no data is available or if the uploaded
+      //                      data will overwrite the existing file.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    The data block provided to this function should be the entire
+      //    file. Handling of offsets and CRC calculations is done
+      //    internally within the library.
+      //    Once the request is posted, the application must wait for the
+      //    response from the library.  Possible responses are:
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_PASS
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_REJECT
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_FAIL
+      //       ANTFS_CLIENT_RESPONSE_SERIAL_FAIL
+      // Upon receiving ANTFS_CLIENT_RESPONSE_UPLOAD_PASS the uploaded data
+      // will be available in the transfer buffer.  See GetTransferData().
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_RETURN SendEraseResponse(UCHAR ucResponse_);
+      /////////////////////////////////////////////////////////////////
+      // Sends a response to a request to erase a file from an
+      // authenticated remote device
+      // Parameters:
+      //    ucResponse_:      The response to the erase request.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      /////////////////////////////////////////////////////////////////
+
+      ANTFS_CLIENT_RESPONSE WaitForResponse(ULONG ulMilliseconds_);
+      /////////////////////////////////////////////////////////////////
+      // Wait for a response from the ANTFS client library
+      // Parameters:
+      //    ulMilliseconds_:  Set this value to the minimum time to
+      //                      wait before returning.  If the value is
+      //                      0, the function will return immediately.
+      //                      If the value is DSI_THREAD_INFINITE, the
+      //                      function will not time out.
+      // If one or more responses are pending before the timeout
+      // expires the function will return the first response that
+      // occurred.  If no response is pending at the time the timeout
+      // expires, ANTFS_CLIENT_RESPONSE_NONE is returned.
+      // Operation:
+      // Some of the events return parameters associated with the event.
+      // Possible events and parameters:
+      //    ANTFS_CLIENT_RESPONSE_PAIRING_REQUEST   -  GetHostName()
+      //    ANTFS_CLIENT_RESPONSE_DOWNLOAD_REQUEST  -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_UPLOAD_REQUEST    -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_ERASE_REQUEST     -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_UPLOAD_PASS       -  GetTransferData()
+      /////////////////////////////////////////////////////////////////
+};
+
+
+#endif // ANTFS_CLIENT_CHANNEL_HPP

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_channel.hpp.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: aaccda854c9464ac8a0eed0c4f964607
+timeCreated: 1468561033
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 384 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_interface.hpp

@@ -0,0 +1,384 @@
+/*
+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.
+*/
+
+
+#if !defined(ANTFS_CLIENT_INTERFACE_H)
+#define ANTFS_CLIENT_INTERFACE_H
+
+#include "types.h"
+#include "antfs_interface.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+// ANT-FS Client Responses
+typedef enum
+{
+   ANTFS_CLIENT_RESPONSE_NONE = 0,
+   ANTFS_CLIENT_RESPONSE_INIT_PASS,
+   ANTFS_CLIENT_RESPONSE_SERIAL_FAIL,   
+   ANTFS_CLIENT_RESPONSE_BEACON_OPEN,
+   ANTFS_CLIENT_RESPONSE_BEACON_CLOSED,   
+   ANTFS_CLIENT_RESPONSE_CONNECT_PASS,
+   ANTFS_CLIENT_RESPONSE_DISCONNECT_PASS,
+   ANTFS_CLIENT_RESPONSE_CONNECTION_LOST,
+   ANTFS_CLIENT_RESPONSE_AUTHENTICATE_NA,
+   ANTFS_CLIENT_RESPONSE_AUTHENTICATE_PASS,
+   ANTFS_CLIENT_RESPONSE_AUTHENTICATE_REJECT,
+   ANTFS_CLIENT_RESPONSE_PAIRING_REQUEST,
+   ANTFS_CLIENT_RESPONSE_PAIRING_TIMEOUT,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_REQUEST,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_PASS,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_REJECT,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_INVALID_INDEX,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_FILE_NOT_READABLE,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_NOT_READY,
+   ANTFS_CLIENT_RESPONSE_DOWNLOAD_FAIL,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_REQUEST,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_PASS,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_REJECT,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_INVALID_INDEX,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_FILE_NOT_WRITEABLE,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_INSUFFICIENT_SPACE,
+   ANTFS_CLIENT_RESPONSE_UPLOAD_FAIL,
+   ANTFS_CLIENT_RESPONSE_ERASE_REQUEST,
+   ANTFS_CLIENT_RESPONSE_ERASE_PASS,
+   ANTFS_CLIENT_RESPONSE_ERASE_REJECT,
+   ANTFS_CLIENT_RESPONSE_ERASE_FAIL,
+   ANTFS_CLIENT_RESPONSE_CANCEL_DONE
+} ANTFS_CLIENT_RESPONSE;
+
+// ANT-FS Client States
+typedef enum
+{
+   ANTFS_CLIENT_STATE_OFF = 0,      // Object created, but not initialized (e.g. no threads running)
+   ANTFS_CLIENT_STATE_IDLE,         // Object initialized (e.g. threads running), but not processing messages
+   ANTFS_CLIENT_STATE_OPENING,
+   ANTFS_CLIENT_STATE_DISCONNECTING,   
+   ANTFS_CLIENT_STATE_BEACONING,    // LINK
+   ANTFS_CLIENT_STATE_CONNECTED,    // AUTH
+   ANTFS_CLIENT_STATE_AUTHENTICATING,
+   ANTFS_CLIENT_STATE_PAIRING_WAIT_FOR_RESPONSE,
+   ANTFS_CLIENT_STATE_TRANSPORT,
+   ANTFS_CLIENT_STATE_DOWNLOADING,
+   ANTFS_CLIENT_STATE_DOWNLOADING_WAIT_FOR_DATA,
+   ANTFS_CLIENT_STATE_UPLOADING,
+   ANTFS_CLIENT_STATE_UPLOADING_WAIT_FOR_RESPONSE,
+   ANTFS_CLIENT_STATE_ERASING,
+} ANTFS_CLIENT_STATE;
+
+// ANT-FS Client Parameters
+typedef struct
+{
+   ULONG ulSerialNumber;            // Client serial number.  Set to zero to use the serial number of the USB device.
+   USHORT usBeaconDeviceType;       // Client device type (in beacon)
+   USHORT usBeaconDeviceManufID;    // Client manufacturing ID (in beacon)
+   UCHAR ucBeaconFrequency;         // Link Radio Frequency
+   UCHAR ucLinkPeriod;              // Link Channel Period      
+   BOOL bPairingEnabled;            // Pairing is enabled/disabled
+   BOOL bUploadEnabled;             // Upload is enabled/disabled
+   BOOL bDataAvailable;             // Data is available/not available for download
+   UCHAR ucAuthType;                // Authentication type to include in beacon   
+   UCHAR ucBeaconTimeout;           // In seconds.  Timeout disabled = 0xFF.
+   UCHAR ucPairingTimeout;          // In seconds.  Timeout disabled = 0xFF.
+} ANTFS_CLIENT_PARAMS;
+
+// Parameters received from host for the requested download/upload/erase
+typedef struct
+{
+   USHORT usFileIndex;     // (Download/Upload/Erase) File index
+   ULONG ulOffset;         // (Download/Upload) Current offset
+   ULONG ulBlockSize;      // (Download) Maximum number of bytes in download block
+   ULONG ulMaxSize;        // (Upload) Offset + total remaining bytes.
+   USHORT usCRCSeed;       // (Download) CRC seed for the current download
+   BOOL bInitialRequest;   // (Download) Flag indicating this is an initial request
+} ANTFS_REQUEST_PARAMS;
+
+// Parameters received from host for disconnect command
+typedef struct
+{
+   UCHAR ucCommandType;    // Disconnect command type
+   UCHAR ucTimeDuration;   // Requested amount in time (in 30 s increments) to become undiscoverable
+   UCHAR ucAppSpecificDuration;  // Requested application specific undiscoverable time
+} ANTFS_DISCONNECT_PARAMS;
+
+
+// Client defined parameters for a download response
+typedef struct
+{
+   USHORT usFileIndex;     // File index
+   ULONG ulMaxBlockSize;   // Maximum burst block size that can be sent by the client
+} ANTFS_DOWNLOAD_PARAMS;
+
+
+// Client defined parameters for an upload response
+typedef struct
+{
+   USHORT usFileIndex;     // File index
+   ULONG ulMaxSize;        // Maximum number of bytes that can be written to the file
+   ULONG ulMaxBlockSize;   // Maximum burst block size that can be received by the client
+} ANTFS_UPLOAD_PARAMS;
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Function Prototypes
+//////////////////////////////////////////////////////////////////////////////////
+
+// TODO: Is this class used for anything?  Do we need it? 
+class ANTFSClientInterface
+{
+   public:         
+      virtual ~ANTFSClientInterface(){}
+
+      virtual void Close(void) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Stops any pending actions, and cleans up any dynamic memory 
+      // being used by the library.
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN ConfigureClientParameters(ANTFS_CLIENT_PARAMS* pstInitParams_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Set up ANTFSClient configuration parameters.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Parameters:
+      //   *pstInitParams_:   A pointer to an
+      //                      ANTFS_PARAMS structure that defines the
+      //                      configuration parameters of the client
+      //                      device
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN OpenBeacon() = 0;
+      /////////////////////////////////////////////////////////////////
+      // Begins the channel configuration to transmit the ANT-FS beacon
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation: 
+      //    Once the channel is successfully configured and opened,
+      //    a response of ANTFS_RESPONSE_BEACON_OPEN will be sent.
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN CloseBeacon(BOOL bReturnToBroadcast_ = FALSE) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Closes the ANT-FS beacon.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Parameters:
+      //      bReturnToBroadcast_:   If TRUE, the channel will remain
+      //                         open, and the application can continue
+      //                         to process messages. If FALSE,
+      //                         the channel will be closed.
+      // Operation: 
+      //    Once the channel is successfully closed, a response of 
+      //    ANTFS_CLIENT_RESPONSE_BEACON_CLOSED will be sent,
+      //    and the ANTFSClient will be in the ANTFS_STATE_IDLE state.
+      //    If the ReturnToBroadcast parameter is not used, the default 
+      //    behavior will be to close the channel and stop broadcasting.
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_CLIENT_STATE GetStatus(void) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Returns the current library status.
+      /////////////////////////////////////////////////////////////////
+
+      virtual BOOL GetHostName(UCHAR *aucHostFriendlyName_, UCHAR *pucBufferSize_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Copies at most ucBufferSize_ characters from the host's
+      // friendly name string (for the most recent session) into the 
+      // supplied pucHostFriendlyName_ buffer.
+      // Parameters:
+      //    *aucFriendlyName_: A pointer to a buffer where the remote
+      //                      device friendly name will be copied.
+      //    *pucBufferSize_:  Pointer to a UCHAR variable that should contain the
+      //                      maximum size of the buffer pointed to by 
+      //                      aucHostFriendlyName_.
+      //                      After the function returns, the UCHAR variable
+      //                      will be set to reflect the size of the friendly 
+      //                      name string that has been copied to the buffer.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    If the host's friendly name string has fewer than ucBufferSize_
+      //    characters, the *aucFriendlyName_ buffer will be padded with 
+      //    zeroes.  
+      /////////////////////////////////////////////////////////////////
+
+      virtual BOOL GetRequestParameters(ANTFS_REQUEST_PARAMS* stRequestParams_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Gets the parameters for a download, upload or erase request
+      // received from the host
+      //
+      // Parameters:
+      //    *pstRequestParams_: Pointer to an ANTFS_REQUEST_PARAMS
+      //                      structure that will receive the details
+      //                      of the download, upload or erase request.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      /////////////////////////////////////////////////////////////////
+
+      virtual BOOL GetDownloadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Gets the transfer progress of a pending or a complete
+      // download.
+      // Parameters:
+      //    *pulByteProgress_: Pointer to a ULONG that will receive
+      //                      the current byte progress of a pending or
+      //                      complete download.
+      //    *pulTotalLength_: Pointer to a ULONG that will receive the
+      //                      total expected length of the download.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      // Operation:
+      //    A data download occurs when information is requested from a
+      //    remote device.  This function may be called at any point
+      //    during a download as a progress indicator.  After the transfer
+      //    is complete, this information is valid until another request
+      //    for a data transfer is made.
+      /////////////////////////////////////////////////////////////////
+
+      virtual BOOL GetTransferData(ULONG *pulDataSize_ , void *pvData_ = NULL) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Gets the received data from a transfer (upload).
+      //
+      // Parameters:
+      //    *ulDataSize_:     Pointer to a ULONG that will receive
+      //                      the size of the data available in bytes.
+      //    *pvData_:         Pointer to a buffer where the received data
+      //                      will be copied.  NULL can be passed to this
+      //                      parameter so that the size can be retrieved
+      //                      without copying any data.  The application
+      //                      can then call this function again to after it
+      //                      has allocated a buffer of sufficient size to
+      //                      handle the data.
+      // Returns TRUE if successful.  Otherwise, it returns FALSE.
+      /////////////////////////////////////////////////////////////////      
+
+      virtual ANTFS_RETURN SendPairingResponse(BOOL bAccept_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Sends a response to a pairing request.
+      // Parameters:
+      //    bAccept_:         Set this value to TRUE to accept the
+      //                      pairing request, and FALSE to reject it.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    A pairing request will automatically be rejected if no
+      //    response is sent within the pairing timeout, and the 
+      //    application will receive an ANTFS_RESPONSE_PAIRING_TIMEOUT
+      //    response.
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN SendDownloadResponse(UCHAR ucResponse_, ANTFS_DOWNLOAD_PARAMS* stDownloadInfo_, ULONG ulDataLength_, void *pvData_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Sends the response to a download request from an authenticated
+      // device.
+      // Parameters:
+      //    ucResponse_:      The response to the download request.
+      //    stDownloadInfo_:  Pointer to an ANTFS_DOWNLOAD_PARAMS
+      //                      structure holding the parameters of the
+      //                      download response.
+      //    ulDataLength_:    The byte length of the data block to be 
+      //                      downloaded to the host device. This is the
+      //                      size of the entire file, as specified in
+      //                      the directory.  Set to zero if no data 
+      //                      is to be downloaded.
+      //    *pvData_:         Pointer to the location where the data
+      //                      to be downloaded is stored.  The pointer 
+      //                      should correspond with the beginning of the
+      //                      file, without applying any offsets. 
+      //                      Set to NULL if no data is to be 
+      //                      downloaded (response rejected).
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    The data block provided to this function should be the entire
+      //    file. Handling of offsets and CRC calculations is done
+      //    internally within the library.
+      //    Once the request is posted, the application must wait for the
+      //    response from the library.  Possible responses are:
+      //       ANTFS_CLIENT_RESPONSE_DOWNLOAD_PASS
+      //       ANTFS_CLIENT_RESPONSE_DOwNLOAD_REJECT
+      //       ANTFS_CLIENT_RESPONSE_DOWNLOAD_FAIL
+      //       ANTFS_CLIENT_RESPONSE_SERIAL_FAIL
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN SendUploadResponse(UCHAR ucResponse_, ANTFS_UPLOAD_PARAMS* stUploadInfo_, ULONG ulDataLength_, void *pvData_) = 0;
+     /////////////////////////////////////////////////////////////////
+      // Sends the response to an upload request from an authenticated
+      // device.
+      // Parameters:
+      //    ucResponse_:      The response to the upload request.
+      //    pstUploadInfo_:   Pointer to an ANTFS_UPLOAD_PARAMS
+      //                      structure holding the parameters of the
+      //                      upload response.
+      //    ulDataLength_:    The byte length of the data that is 
+      //                      currently stored at the requested upload
+      //                      location.  Set to zero if uploading to a
+      //                      new index or if the uploaded data will
+      //                      overwrite all existing data
+      //    *pvData_:         Pointer to the location of the data at the
+      //                      requested upload index. Set to NULL
+      //                      if no data is available or if the uploaded
+      //                      data will overwrite the existing file.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      // Operation:
+      //    The data block provided to this function should be the entire
+      //    file. Handling of offsets and CRC calculations is done
+      //    internally within the library.
+      //    Once the request is posted, the application must wait for the
+      //    response from the ANTFSClient object.  Possible responses are:
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_PASS
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_REJECT
+      //       ANTFS_CLIENT_RESPONSE_UPLOAD_FAIL
+      //       ANTFS_CLIENT_RESPONSE_SERIAL_FAIL
+      // Upon receiving ANTFS_CLIENT_RESPONSE_UPLOAD_PASS the uploaded data
+      // will be available in the transfer buffer.  See GetTransferData().
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_RETURN SendEraseResponse(UCHAR ucResponse_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Sends a response to a request to erase a file from an
+      // authenticated remote device
+      // Parameters:
+      //    ucResponse_:      The response to the erase request.
+      // Returns ANTFS_RETURN_PASS if successful.  Otherwise, it returns 
+      // ANTFS_RETURN_FAIL if the library is in the wrong state, or 
+      // ANTFS_RETURN_BUSY if the library is busy with another request.
+      /////////////////////////////////////////////////////////////////
+
+      virtual ANTFS_CLIENT_RESPONSE WaitForResponse(ULONG ulMilliseconds_) = 0;
+      /////////////////////////////////////////////////////////////////
+      // Wait for a response from the ANTFS client library
+      // Parameters:
+      //    ulMilliseconds_:  Set this value to the minimum time to
+      //                      wait before returning.  If the value is
+      //                      0, the function will return immediately.
+      //                      If the value is DSI_THREAD_INFINITE, the
+      //                      function will not time out.
+      // If one or more responses are pending before the timeout
+      // expires the function will return the first response that
+      // occurred.  If no response is pending at the time the timeout
+      // expires, ANTFS_CLIENT_RESPONSE_NONE is returned.
+      // Operation:
+      // Some of the events return parameters associated with the event.
+      // Possible events and parameters:
+      //    ANTFS_CLIENT_RESPONSE_PAIRING_REQUEST   -  GetHostName()
+      //    ANTFS_CLIENT_RESPONSE_DOWNLOAD_REQUEST  -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_UPLOAD_REQUEST    -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_ERASE_REQUEST     -  GetRequestParameters()
+      //    ANTFS_CLIENT_RESPONSE_UPLOAD_PASS       -  GetTransferData()
+      /////////////////////////////////////////////////////////////////      
+};
+
+
+#endif // ANTFS_CLIENT_INTERFACE_H

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_client_interface.hpp.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 788d826afa6664da3b3e665c71de247e
+timeCreated: 1468561033
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 194 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.c

@@ -0,0 +1,194 @@
+/*
+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.
+*/
+
+#include "types.h"
+#include "dsi_convert.h"
+#include "antfs_directory.h"
+
+
+
+
+typedef struct
+{
+   UCHAR  usFileIndexByte0;
+   UCHAR  usFileIndexByte1;
+   UCHAR  ucFileDataType;
+   UCHAR  ucFileSubType;
+   UCHAR  usFileNumberByte0;
+   UCHAR  usFileNumberByte1;
+   UCHAR  ucSpecificFlags;
+   UCHAR  ucGeneralFlags;
+   UCHAR  ulFileSizeByte0;
+   UCHAR  ulFileSizeByte1;
+   UCHAR  ulFileSizeByte2;
+   UCHAR  ulFileSizeByte3;
+   UCHAR  ulTimeStampByte0;
+   UCHAR  ulTimeStampByte1;
+   UCHAR  ulTimeStampByte2;
+   UCHAR  ulTimeStampByte3;
+} ANTFSP_DIRECTORY_LOOKUP;
+
+///////////////////////////////////////////////////////////////////////
+ULONG ANTFSDir_GetNumberOfFileEntries(void *pvDirectory_, ULONG ulDirectoryFileLength_)
+{  
+   ANTFS_DIRECTORY_HEADER *psDirHeader;   
+
+   if (pvDirectory_ == NULL)
+      return 0;
+
+   psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
+
+   if (psDirHeader->ucVersion != 1)
+      return 0;
+
+   if (psDirHeader->ucElementLength != 16)
+      return 0;   
+
+   if ((sizeof(ANTFS_DIRECTORY_HEADER) + psDirHeader->ucElementLength) > ulDirectoryFileLength_)   //return 0 if the directory size is smaller than the header + 1 entry
+      return 0;
+
+   return ((ulDirectoryFileLength_ - sizeof(ANTFS_DIRECTORY_HEADER)) / psDirHeader->ucElementLength);   
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSDir_LookupFileEntry(void *pvDirectory_, ULONG ulDirectoryFileLength_, ULONG ulFileEntry_, ANTFSP_DIRECTORY *pusDirectoryStruct_)
+{
+   ANTFS_DIRECTORY_HEADER *psDirHeader;
+   ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;   
+
+   if (pvDirectory_ == NULL)
+      return FALSE;
+
+   psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
+
+   if (psDirHeader->ucVersion != 1)
+      return FALSE;
+
+   if (psDirHeader->ucElementLength != 16)
+      return FALSE;
+
+   if (pusDirectoryStruct_ == (ANTFSP_DIRECTORY*)NULL)
+      return FALSE;
+
+   if ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulFileEntry_ + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
+   {      
+      psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulFileEntry_));      
+
+      pusDirectoryStruct_->usFileIndex = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
+      pusDirectoryStruct_->ucFileDataType = psCurrentDirElement->ucFileDataType;
+      pusDirectoryStruct_->ucFileSubType = psCurrentDirElement->ucFileSubType;
+      pusDirectoryStruct_->usFileNumber = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileNumberByte1,psCurrentDirElement->usFileNumberByte0);
+      pusDirectoryStruct_->ucSpecificFlags = psCurrentDirElement->ucSpecificFlags;
+      pusDirectoryStruct_->ucGeneralFlags = psCurrentDirElement->ucGeneralFlags;
+      pusDirectoryStruct_->ulFileSize = Convert_Bytes_To_ULONG(psCurrentDirElement->ulFileSizeByte3,psCurrentDirElement->ulFileSizeByte2,psCurrentDirElement->ulFileSizeByte1,psCurrentDirElement->ulFileSizeByte0);
+      pusDirectoryStruct_->ulTimeStamp = Convert_Bytes_To_ULONG(psCurrentDirElement->ulTimeStampByte3,psCurrentDirElement->ulTimeStampByte2,psCurrentDirElement->ulTimeStampByte1,psCurrentDirElement->ulTimeStampByte0);
+
+      return TRUE;                  
+   }
+
+   return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSDir_GetNewFileList(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT *pusFileIndexList_, USHORT * pusListLength_)
+{  
+   ANTFS_DIRECTORY_HEADER *psDirHeader;
+   ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;
+   ULONG ulElementNum = 0;
+   USHORT usNumberOfMatches = 0;
+
+   if (pvDirectory_ == NULL)
+      return FALSE;
+
+   psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
+
+   if (psDirHeader->ucVersion != 1)
+      return FALSE;
+
+   if (psDirHeader->ucElementLength != 16)
+      return FALSE;
+
+   while ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulElementNum + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
+   {
+      psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulElementNum));
+
+      if (psCurrentDirElement->ucFileDataType == 0x80)  //ANTFS+ data type
+      {
+         if (psCurrentDirElement->ucFileSubType == 4)  //ANTFS+ session sub type 
+         {
+            if ((!(psCurrentDirElement->ucGeneralFlags & ANTFS_GENERAL_FLAG_ARCHIVE)) &&
+               (psCurrentDirElement->ucGeneralFlags & ANTFS_GENERAL_FLAG_READ))            //This has never been downloaded and can be read
+            {               
+               usNumberOfMatches++;
+
+               if (pusFileIndexList_ != NULL)
+               {
+                  *pusFileIndexList_ = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
+                  pusFileIndexList_ ++;
+               }                  
+            }
+         }
+      }      
+
+      ulElementNum++;
+   }
+
+   if (pusListLength_ != NULL)
+      *pusListLength_ = usNumberOfMatches;  
+
+   return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////
+BOOL ANTFSDir_LookupFileIndex(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT usFileIndex_, ANTFSP_DIRECTORY *pusDirectoryStruct_)
+{
+   ANTFS_DIRECTORY_HEADER *psDirHeader;
+   ANTFSP_DIRECTORY_LOOKUP *psCurrentDirElement;
+   ULONG ulElementNum = 0;   
+
+   if (pvDirectory_ == NULL)
+      return FALSE;
+
+   psDirHeader = (ANTFS_DIRECTORY_HEADER*)pvDirectory_;
+
+   if (psDirHeader->ucVersion != 1)
+      return FALSE;
+
+   if (psDirHeader->ucElementLength != 16)
+      return FALSE;
+
+   if (pusDirectoryStruct_ == (ANTFSP_DIRECTORY*)NULL)
+      return FALSE;
+
+   while ((sizeof(ANTFS_DIRECTORY_HEADER) + ((ulElementNum + 1) * psDirHeader->ucElementLength)) <= ulDirectoryFileLength_)
+   {
+      USHORT usCurrentFileIndex;
+      psCurrentDirElement = (ANTFSP_DIRECTORY_LOOKUP *)((UCHAR*)pvDirectory_ + sizeof(ANTFS_DIRECTORY_HEADER) + (psDirHeader->ucElementLength * ulElementNum));
+
+      usCurrentFileIndex = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileIndexByte1,psCurrentDirElement->usFileIndexByte0);
+
+      if (usCurrentFileIndex == usFileIndex_)  //If this is the index we want.
+      {
+         pusDirectoryStruct_->usFileIndex = usCurrentFileIndex;
+         pusDirectoryStruct_->ucFileDataType = psCurrentDirElement->ucFileDataType;
+         pusDirectoryStruct_->ucFileSubType = psCurrentDirElement->ucFileSubType;
+         pusDirectoryStruct_->usFileNumber = Convert_Bytes_To_USHORT(psCurrentDirElement->usFileNumberByte1,psCurrentDirElement->usFileNumberByte0);
+         pusDirectoryStruct_->ucSpecificFlags = psCurrentDirElement->ucSpecificFlags;
+         pusDirectoryStruct_->ucGeneralFlags = psCurrentDirElement->ucGeneralFlags;
+         pusDirectoryStruct_->ulFileSize = Convert_Bytes_To_ULONG(psCurrentDirElement->ulFileSizeByte3,psCurrentDirElement->ulFileSizeByte2,psCurrentDirElement->ulFileSizeByte1,psCurrentDirElement->ulFileSizeByte0);
+         pusDirectoryStruct_->ulTimeStamp = Convert_Bytes_To_ULONG(psCurrentDirElement->ulTimeStampByte3,psCurrentDirElement->ulTimeStampByte2,psCurrentDirElement->ulTimeStampByte1,psCurrentDirElement->ulTimeStampByte0);
+
+         return TRUE;                  
+      }    
+      ulElementNum++;
+   }
+ 
+
+   return FALSE;
+}

+ 8 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.c.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6f6df2b40272640398f7140b77bc087e
+timeCreated: 1468561033
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 131 - 0
Assets/AdvancedAnt/Plugins/Ant/ANT_WrappedLib.bundle/Contents/Resources/ANT_LIB/software/ANTFS/antfs_directory.h

@@ -0,0 +1,131 @@
+/*
+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.
+*/
+
+#if !defined(ANTFS_DIRECTORY_H)
+#define ANTFS_DIRECTORY_H
+
+
+#include "types.h"
+
+#define ANTFS_GENERAL_FLAG_READ        ((UCHAR)0x80)
+#define ANTFS_GENERAL_FLAG_WRITE       ((UCHAR)0x40)
+#define ANTFS_GENERAL_FLAG_ERASE       ((UCHAR)0x20)
+#define ANTFS_GENERAL_FLAG_ARCHIVE     ((UCHAR)0x10)
+#define ANTFS_GENERAL_FLAG_APPEND      ((UCHAR)0x08)
+#define ANTFS_GENERAL_FLAG_CRYPTO      ((UCHAR)0x04)
+
+#define ANTFS_SPECIFIC_FLAG_SELECTED   ((UCHAR)0x01)
+
+//////////////////////////////////////////////////////////////////////////////////
+// Public Definitions
+//////////////////////////////////////////////////////////////////////////////////
+
+typedef struct
+{
+   UCHAR ucVersion;
+   UCHAR ucElementLength;
+   UCHAR ucTimeFormat;
+   UCHAR ucReserved01;
+   UCHAR ucReserved02;
+   UCHAR ucReserved03;
+   UCHAR ucReserved04;
+   UCHAR ucReserved05;
+   ULONG ulSystemTime;
+   ULONG ulTimeStamp;  
+} ANTFS_DIRECTORY_HEADER;
+
+typedef struct
+{
+   USHORT usFileIndex;
+   UCHAR  ucFileDataType;
+   UCHAR  ucFileSubType;
+   USHORT usFileNumber;
+   UCHAR  ucSpecificFlags;
+   UCHAR  ucGeneralFlags;
+   ULONG  ulFileSize;
+   ULONG  ulTimeStamp;
+} ANTFSP_DIRECTORY;
+
+
+#define MAX_DATA_SIZE                  65535
+//////////////////////
+
+#if defined(__cplusplus)
+   extern "C" {
+#endif
+
+ULONG ANTFSDir_GetNumberOfFileEntries(void *pvDirectory_, ULONG ulDirectoryFileLength_);
+/////////////////////////////////////////////////////////////////
+// Returns the number of file entries contained in the direcotry.
+//
+// Parameters:
+//    *pvDirectory_   : Pointer to the downloaded directory file
+//    ulDirectoryFileLength_ :  Length of the downloaded directory file
+//
+// Returns the number of file entries contained in the directory.
+/////////////////////////////////////////////////////////////////
+
+BOOL ANTFSDir_LookupFileEntry(void *pvDirectory_, ULONG ulDirectoryFileLength_, ULONG ulFileEntry_, ANTFSP_DIRECTORY *pusDirectoryStruct_);
+/////////////////////////////////////////////////////////////////
+// Fills in the directory struct with information from the directory
+// file.  
+//
+// Parameters:
+//    *pvDirectory_   : Pointer to the downloaded directory file
+//    ulDirectoryFileLength_ :  Length of the downloaded directory file
+//    ulFileEntry_    : Entry number of the file that needs to be looked up (this parameter is zero based).
+//    *pusDirectoryStruct_ : Pointer to a ANTFSP_DIRECTORY struct where 
+//                      the information from the directory will be filled in.
+//                      The calling applicaiton should allocate an 
+//                      ANTFSP_DIRECTORY struct and provide the pointer to it.
+// Returns TRUE if successful.  Otherwise, it returns FALSE.
+/////////////////////////////////////////////////////////////////
+
+BOOL ANTFSDir_GetNewFileList(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT *pusFileIndexList, USHORT * pusListLength);
+/////////////////////////////////////////////////////////////////
+// Decodes the directory and generates a list of files that needs
+// that needs to be downloaded.
+//
+// Parameters:
+//    *pvDirectory_   : Pointer to the downloaded directory file
+//    ulDirectoryFileLength_ :  Length of the downloaded directory file
+//    *pusFileIndexList : Pointer to a USHORT array where the list
+//                      of file indexes will be written. NULL can be 
+//                      passed to this parameter so that the size can 
+//                      be returned without actually writing the list.
+//                      The application can then call this function again
+//                      after it has allocated an array of sufficient 
+//                      size to handle the list.
+//    *pusListLength  : Pointer to a USHORT that will receive
+//                      the number of files the list will contain.
+// Returns TRUE if successful.  Otherwise, it returns FALSE.
+/////////////////////////////////////////////////////////////////
+
+BOOL ANTFSDir_LookupFileIndex(void *pvDirectory_, ULONG ulDirectoryFileLength_, USHORT usFileIndex_, ANTFSP_DIRECTORY *pusDirectoryStruct_);
+/////////////////////////////////////////////////////////////////
+// Fills in the directory struct with information from the directory
+// file.  
+//
+// Parameters:
+//    *pvDirectory_   : Pointer to the downloaded directory file
+//    ulDirectoryFileLength_ :  Length of the downloaded directory file
+//    usFileIndex_    : Indext of the file that needs to be looked up.
+//    *pusDirectoryStruct_ : Pointer to a ANTFSP_DIRECTORY struct where 
+//                      the information from the directory will be filled in.
+//                      The calling applicaiton should allocate an 
+//                      ANTFSP_DIRECTORY struct and provide the pointer to it.
+// Returns TRUE if successful.  Otherwise, it returns FALSE.
+/////////////////////////////////////////////////////////////////
+
+#if defined(__cplusplus)
+   }
+#endif
+
+
+#endif // !defined(ANTFS_DIRECTORY_H)

Some files were not shown because too many files changed in this diff