/// <summary>
        /// Handle ANT-FS response events
        /// </summary>
        public void HandleClientResponses(ANTFS_ClientChannel.Response response)
        {
            Console.WriteLine(Print.AsString(response));   // Display response
            switch (response)
            {
            case ANTFS_ClientChannel.Response.ConnectionLost:
            case ANTFS_ClientChannel.Response.DisconnectPass:
                // Close the channel
                if (antfsClient.GetDisconnectParameters().CommandType == (byte)DisconnectType.Broadcast)
                {
                    channel0.closeChannel();
                }
                else
                {
                    antfsClient.CloseBeacon();
                }
                break;

            case ANTFS_ClientChannel.Response.BeaconClosed:
                demoDone = true;
                Console.WriteLine("Press enter to exit");
                break;

            case ANTFS_ClientChannel.Response.PairingRequest:
                Console.WriteLine("Pairing request from " + antfsClient.GetHostName());
                antfsClient.SendPairingResponse(true);
                break;

            case ANTFS_ClientChannel.Response.DownloadRequest:
                try
                {
                    ushort index = antfsClient.GetRequestedFileIndex();
                    if (index == 0)
                    {
                        antfsClient.SendDownloadResponse(DownloadResponse.Ok, index, dirFS.ToByteArray());
                    }
                    else
                    {
                        antfsClient.SendDownloadResponse(DownloadResponse.Ok, index, ReadFile(dirFS.GetFileSize(index)));
                    }
                }
                catch (ANTFS_Exception)
                {
                    antfsClient.SendDownloadResponse(DownloadResponse.InvalidIndex, 0, null);
                }
                break;

            default:
                break;
            }
        }
        /// <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 "V":
                case "v":
                    Console.WriteLine("ANT-FS Library Version " + ANTFS_ClientChannel.GetLibraryVersion());
                    break;

                case "S":
                case "s":
                    Console.WriteLine("Status: " + Print.AsString(antfsClient.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);
            }
        }
        /// <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);
            }
        }
        /// <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;
            }
        }