123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- /*
- 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. 2016
- All rights reserved.
- */
- //////////////////////////////////////////////////////////////////////////
- // To use the ANT-FS functionality in the managed library, you must:
- // 1. Import ANT_NET.dll as a reference
- // 2. Reference the ANT_Managed_Library and ANT_Managed_Library.ANTFS namespaces
- // 3. Include the following files in the working directory of your application:
- // - DSI_CP310xManufacturing_3_1.dll
- // - DSI_SiUSBXp_3_1.dll
- // - ANT_WrappedLib.dll
- // - ANT_NET.dll
- // 4. You will also need to copy ANT_NET.xml into your project for
- // Intellisense to work properly
- //////////////////////////////////////////////////////////////////////////
- using System;
- using System.Text;
- using System.IO;
- using System.Collections.Generic;
- using System.Threading;
- using ANT_Managed_Library;
- using ANT_Managed_Library.ANTFS;
- namespace ANTFS_Demo
- {
- /// <summary>
- /// This demo shows how to configure a basic ANT-FS host
- /// For a more featured demo, please refer to the source code of the ANT-FS PC tools (however, the host source code is in C++)
- /// </summary>
- public class HostDemo
- {
- // ANT-FS Configuration Parameters
- readonly string HostFriendlyName = "ConsoleHost"; // ANT-FS Host Friendly Name
- readonly byte ConnectRF = (byte)ANT_Managed_Library.ANTFS.RadioFrequency.Auto; // Radio Frequency to use once a connection is established (set by host)
- readonly uint ClientDeviceID = 0; // ANT-FS Client Device ID (Serial Number): Wildcard to match any client ID
- readonly ushort DeviceNumber = 0; // Device Number (ANT Channel ID): Wildcard to match any client Device Number
- readonly byte SearchTimeout = 60; // How long to search for a client device, in seconds
- ANT_Channel channel0; // ANT channel to use
- ANTFS_HostChannel antfsHost; // ANT-FS host
- ANTFS_Directory dirFS; // ANT-FS directory
- byte[] clientPassKey; // Used to store pass key retrieved from the client during pairing
- bool demoDone = false; // Signal when the demo is done to exit
- int cursorIndex = 0; // Index to handle cursor display while transmitting in broadcast mode
- ushort currentDownloadIndex = 0; // Current index being downloaded. Start with directory (0)
- Timer searchTimer; // Timer to limit search time, in case there are no client devices around
- /// <summary>
- /// Setup ANT-FS host to process messages from connected USB device
- /// </summary>
- public void Start(ANT_Device antDevice)
- {
- PrintMenu();
- try
- {
- // Create the ANT-FS host and attach it to a channel (in this case, 0)
- channel0 = antDevice.getChannel(0);
- antfsHost = new ANTFS_HostChannel(channel0);
-
- // Setup callback to handle ANT-FS response events
- antfsHost.OnResponse += new Action<ANTFS_HostChannel.Response>(HandleHostResponses);
- // Configure the host, and begin searching
- ConfigureHost(antDevice);
- while (!demoDone)
- {
- string command = Console.ReadLine();
- HandleUserInput(command);
- Thread.Sleep(0);
- }
- }
- catch(ANTFS_Exception antEx) // Handle exceptions thrown by ANT Managed library
- {
- Console.WriteLine("ANT-FS Exception: " + antEx.Message);
- }
- catch (Exception ex) // Handle other exceptions
- {
- Console.WriteLine("Demo failed: " + ex.Message);
- }
- finally
- {
- Console.WriteLine("Disconnecting module...");
- antDevice.Dispose(); // Close down the device completely and completely shut down all communication
- antfsHost.Dispose(); // Release all native resources used by the host
- Console.WriteLine("Demo has completed successfully!");
- }
- }
- /// <summary>
- /// Configure the host search parameters, and begin the search
- /// </summary>
- /// <param name="antDevice">ANT USB device</param>
- public void ConfigureHost(ANT_Device antDevice)
- {
- // Configure ANT channel parameters
- antfsHost.SetNetworkKey(Demo.NetworkNumber, Demo.NetworkKey);
- antfsHost.SetChannelID(Demo.DeviceType, Demo.TransmissionType);
- antfsHost.SetChannelPeriod(Demo.ChannelPeriod);
-
- // Configure search parameters
- if (antfsHost.AddSearchDevice(ClientDeviceID, Demo.ClientManufacturerID, Demo.ClientDeviceType) == 0)
- throw new Exception("Error adding search device: ");
- if (Demo.AntfsBroadcast)
- {
- // If we want to use ANT-FS broadcast mode, and start the channel in broadcast mode,
- // setup callback to handle responses for channel 0 while in broadcast mode
- channel0.channelResponse += new dChannelResponseHandler(HandleChannelResponses);
- // Configure the channel as a slave, and look for messages from the master in the channel callback
- // This demo will automatically switch to ANT-FS mode after a few seconds
- if (!antDevice.setNetworkKey(Demo.NetworkNumber, Demo.NetworkKey, 500))
- throw new Exception("Error configuring network key");
- if (!channel0.assignChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, Demo.NetworkNumber, 500))
- throw new Exception("Error assigning channel");
- if (!channel0.setChannelID(DeviceNumber, false, Demo.DeviceType, Demo.TransmissionType, 500))
- throw new Exception("Error configuring Channel ID");
- if (!channel0.setChannelFreq(Demo.SearchRF, 500))
- throw new Exception("Error configuring radio frequency");
- if (!channel0.setChannelPeriod(Demo.ChannelPeriod, 500))
- throw new Exception("Error configuring channel period");
- if (!channel0.openChannel(500))
- throw new Exception("Error opening channel");
- }
- else
- {
- // Start searching directly for an ANT-FS client matching the search criteria
- // NOTE: If not interested in the payload while in broadcast mode and intend to start a session right away,
- // you can specify useRequestPage = true to search for broadcast devices, and automatically request them
- // to switch to ANT-FS mode
- antfsHost.SearchForDevice(Demo.SearchRF, ConnectRF, DeviceNumber);
- }
-
- Console.WriteLine("Searching for devices...");
- // Setup a timer, so that we can cancel the search if no device is found
- searchTimer = new Timer(SearchExpired, null, SearchTimeout * 1000, Timeout.Infinite); // convert time to milliseconds
- }
-
- /// <summary>
- /// Handle ANT-FS response events
- /// </summary>
- public void HandleHostResponses(ANTFS_HostChannel.Response response)
- {
- Console.WriteLine(Print.AsString(response)); // Display response
- switch (response)
- {
- case ANTFS_HostChannel.Response.ConnectPass:
- // A device matching the search criteria was found
- // Disable the search timeout
- searchTimer.Change(Timeout.Infinite, Timeout.Infinite);
- // Obtain and display the device parameters
- ANTFS_SearchResults foundDevice = antfsHost.GetFoundDeviceParameters();
- if (foundDevice != null)
- Console.WriteLine(foundDevice.ToString());
- else
- Console.WriteLine("Error obtaining device parameters");
- break;
- case ANTFS_HostChannel.Response.AuthenticatePass:
- // The authentication request was accepted
- // If using Pairing authentication mode, the client will send a Passkey after accepting the request
- byte[] authString = antfsHost.GetAuthResponse();
- if (authString.Length > 0)
- {
- Console.WriteLine("Received Passkey: Stored for use in next session");
- clientPassKey = authString; // Store Passkey for future use
- }
- break;
- case ANTFS_HostChannel.Response.DownloadPass:
- // Download completed successfully
- // Retrieve downloaded data
- byte[] dlData = antfsHost.GetTransferData();
- if ((dlData.Length > 0))
- {
- if (currentDownloadIndex == 0) // Directory
- {
- // Parse downloaded directory
- Console.WriteLine("Received Directory");
- dirFS = new ANTFS_Directory(dlData);
- Console.WriteLine(dirFS.ToString());
- }
- else
- {
- // Store downloaded file
- Console.WriteLine("Downloaded file " + currentDownloadIndex + ", Download size: " + antfsHost.GetDownloadSize());
- if (dlData != null)
- {
- File.WriteAllBytes("rawdataout.txt", dlData);
- Console.WriteLine("Saved to: rawdataout.txt");
- }
- else
- {
- Console.WriteLine("No data available");
- }
- }
- }
- else
- {
- Console.WriteLine("No data available");
- }
- break;
- case ANTFS_HostChannel.Response.DisconnectPass:
- case ANTFS_HostChannel.Response.ConnectionLost:
- case ANTFS_HostChannel.Response.CancelDone:
- Console.WriteLine("Press any key to exit");
- demoDone = true;
- break;
- default:
- break;
- }
- }
- /// <summary>
- /// Handle ANT channel responses, while in broadcast mode
- /// </summary>
- /// <param name="response">ANT channel event</param>
- public void HandleChannelResponses(ANT_Response response)
- {
- // Make sure we are not processing responses if ANT-FS is active
- if (antfsHost.GetStatus() != ANTFS_HostChannel.State.Idle)
- return;
- if (response.responseID == (byte) ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E)
- {
- Console.Write("Rx: " + Demo.CursorStrings[cursorIndex++] + "\r");
- cursorIndex &= 3;
- if (response.getDataPayload()[7] >= 40) // Receive data for about 10 seconds
- {
- antfsHost.RequestSession(Demo.SearchRF, ConnectRF); // Request ANT-FS session
- }
- }
- }
- /// <summary>
- /// Cancel the search after the timeout has expired
- /// </summary>
- /// <param name="state">timer param</param>
- private void SearchExpired(Object state)
- {
- lock (this)
- {
- ANTFS_HostChannel.State currentState = antfsHost.GetStatus();
- if (currentState == ANTFS_HostChannel.State.Searching)
- {
- Console.WriteLine("No devices found...");
- antfsHost.Cancel();
- }
- }
- }
- /// <summary>
- /// Display user menu
- /// </summary>
- public void PrintMenu()
- {
- Console.WriteLine(Environment.NewLine);
- Console.WriteLine("M - Print this menu");
- Console.WriteLine("A - Authenticate");
- Console.WriteLine("D - Download");
- Console.WriteLine("U - Upload");
- Console.WriteLine("E - Erase");
- Console.WriteLine("X - Disconnect");
- Console.WriteLine("C - Cancel");
- Console.WriteLine("P - Print directory");
- Console.WriteLine("V - Request version");
- Console.WriteLine("S - Request status");
- Console.WriteLine("Q - Quit");
- Console.WriteLine(Environment.NewLine);
- }
- /// <summary>
- /// Process user input and execute requested commands
- /// </summary>
- /// <param name="command">User command</param>
- public void HandleUserInput(string command)
- {
- try
- {
- switch (command)
- {
- case "M":
- case "m":
- PrintMenu();
- break;
- case "A":
- case "a":
- // Send authentication request based on user selection
- // The library will wait for the configured timeout to receive a response to the request
- Console.WriteLine("Select authentication mode:");
- Console.WriteLine("1 - Skip authentication");
- Console.WriteLine("2 - Request pairing");
- Console.WriteLine("3 - Send passkey");
- string authChoice = Console.ReadLine();
- switch (authChoice)
- {
- case "1":
- antfsHost.Authenticate(AuthenticationType.None, 60000); // Passthru authentication. Timeout = 60 sec
- break;
- case "2":
- antfsHost.Authenticate(AuthenticationType.Pairing, HostFriendlyName, 60000); // Request pairing. Timeout = 60 sec
- break;
- case "3":
- if (clientPassKey != null)
- antfsHost.Authenticate(AuthenticationType.PassKey, clientPassKey, 60000); // Use passkey, if we have one. Timeout = 60 sec
- else
- Console.WriteLine("Try pairing first");
- break;
- default:
- Console.WriteLine("Invalid authentication type.");
- break;
- }
- break;
- case "D":
- case "d":
- // Send a download request based on user selection
- Console.WriteLine("Select the file index to download.");
- Console.WriteLine("Choose 0 for the directory");
- string downloadChoice = Console.ReadLine();
- currentDownloadIndex = Demo.ParseInput(downloadChoice);
- antfsHost.Download(currentDownloadIndex, 0, 0); // Start download from the beginning, and do not limit size
- break;
- case "U":
- case "u":
- // Send an upload request based on user selection
- Console.WriteLine("Select the file index to upload.");
- string uploadChoice = Console.ReadLine();
- byte[] ulData;
- if (File.Exists("rawdataout.txt"))
- ulData = File.ReadAllBytes("rawdataout.txt");
- else
- ulData = new byte[200];
- antfsHost.Upload(Demo.ParseInput(uploadChoice), ulData);
- Console.WriteLine("Uploading: {0} bytes", ulData.Length);
- break;
- case "E":
- case "e":
- // Send an erase request depending on user selection
- Console.WriteLine("Select the file index to erase");
- string eraseChoice = Console.ReadLine();
- antfsHost.EraseData(Demo.ParseInput(eraseChoice));
- break;
- case "X":
- case "x":
- // Disconnect from the remote device
- antfsHost.Disconnect();
- break;
- case "C":
- case "c":
- // Cancel pending operations
- antfsHost.Cancel();
- break;
- case "P":
- case "p":
- if (dirFS != null)
- Console.WriteLine(dirFS.ToString());
- else
- Console.WriteLine("Try requesting the directory first");
- break;
- case "V":
- case "v":
- Console.WriteLine("ANT-FS Library Version " + antfsHost.GetLibraryVersion());
- break;
- case "S":
- case "s":
- Console.WriteLine("Status: " + Print.AsString(antfsHost.GetStatus()));
- break;
- case "Q":
- case "q":
- demoDone = true;
- break;
- default:
- break;
- }
- }
- catch (ANTFS_RequestFailed_Exception antEx)
- {
- // Inform the user that the operation requested failed, and resume operation
- Console.WriteLine(antEx.Message);
- }
- catch (System.ArgumentException argEx)
- {
- // Inform the user about the invalid input, and resume operation
- Console.WriteLine(argEx.Message);
- }
- }
- }
- }
|