private void startChannel()
        {
            //Just try this in case we get an active channel for some reason
            channel.closeChannel(500);
            channel.unassignChannel(500);

            if (!channel.assignChannel(ANT_ReferenceLibrary.ChannelType.BASE_Master_Transmit_0x10, 0, 500))
            {
                statusReport = "Failed to start, assign() failed";
            }
            else if (!channel.setChannelID((ushort)deviceNum, false, 9, 5, 500))
            {
                statusReport = "Failed to start, setChannelId() failed";
            }
            else if (!channel.setChannelFreq(57, 500))
            {
                statusReport = "Failed to start, setChannelFreq() failed";
            }
            else if (!channel.setChannelPeriod(32768, 500))
            {
                statusReport = "Failed to start, setChannelPeriod() failed";
            }
            else if (!channel.setChannelTransmitPower(ANT_ReferenceLibrary.TransmitPower.RADIO_TX_POWER_0DB_0x03, 500))
            {
                statusReport = "Failed to start, setChannelTransmitPower() failed";
            }
            else if (!channel.openChannel(500))
            {
                statusReport = "Failed to start, openChannel() failed";
            }
            else
            {
                statusReport = "Remote Control Channel is open";
            }
        }
Example #2
0
 void Closed()
 {
     Debug.WriteLine("unassign channel");
     if (channel.unassignChannel(500))
     {
         isClosed = true;
         OnClosed?.Invoke(this);
         channel.channelResponse -= ChannelResponse;
         OnSearchEnded            = null;
         OnAccumPowerReceived     = null;
         OnClosed = null;
     }
 }
        /// <summary>
        /// Handle channel responses, while in broadcast mode
        /// </summary>
        /// <param name="response">ANT channel events</param>
        public void HandleChannelResponses(ANT_Response response)
        {
            // Make sure we are not processing responses if ANT-FS is active
            if (antfsClient.GetStatus() != ANTFS_ClientChannel.State.Idle)
            {
                return;
            }

            if ((response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40))
            {
                if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03)
                {
                    channel0.sendBroadcastData(txBuffer);
                    txBuffer[7]++;
                    Console.Write("Tx: " + Demo.CursorStrings[cursorIndex++] + "\r");
                    cursorIndex &= 3;
                }
                else if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07)
                {
                    Console.WriteLine("Channel Closed");
                    Console.WriteLine("Unassigning Channel...");
                    if (channel0.unassignChannel(500))
                    {
                        Console.WriteLine("Unassigned Channel");
                        Console.WriteLine("Press enter to exit");
                        demoDone = true;
                    }
                }
            }
            else if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F)
            {
                // Look for request page
                if (response.messageContents[1] == 0x46)
                {
                    if (response.messageContents[6] == 0 &&
                        response.messageContents[7] == 0x43 &&
                        response.messageContents[8] == 0x02)
                    {
                        Console.WriteLine("Remote device requesting ANT-FS session");
                    }
                    antfsClient.OpenBeacon();
                }
            }
        }
Example #4
0
    ////////////////////////////////////////////////////////////////////////////////
    // ChannelResponse
    //
    // Called whenever a channel event is recieved.
    //
    // response: ANT message
    ////////////////////////////////////////////////////////////////////////////////
    void ChannelResponse(ANT_Response response)
    {
        //With the messageQueue we can deal with ANT response in the Unity main thread
        if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
        {
            messageQueue.Enqueue(response);
        }

        try
        {
            switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
            {
            case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
            {
                switch (response.getChannelEventCode())
                {
                // This event indicates that a message has just been
                // sent over the air. We take advantage of this event to set
                // up the data for the next message period.
                case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                {
                    // Broadcast data will be sent over the air on
                    // the next message period
                    if (broadcasting)
                    {
                        channel.sendBroadcastData(txBuffer);
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                {
                    Debug.Log("Search Timeout");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                {
                    if (!hideRXFAIL)
                    {
                        Debug.Log("Rx Fail");
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                {
                    Debug.Log("Burst receive has failed");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05:
                {
                    Debug.Log("Transfer Completed");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06:
                {
                    Debug.Log("Transfer Failed");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                {
                    channel.unassignChannel(500);
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                {
                    Debug.Log("Go to Search");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                {
                    Debug.Log("Channel Collision");
                    break;
                }

                case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A:
                {
                    Debug.Log("Burst Started");
                    break;
                }

                default:
                {
                    Debug.Log("Unhandled Channel Event " + response.getChannelEventCode());
                    break;
                }
                }
                break;
            }

            case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
            case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
            case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
            case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
            case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
            case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
            {
                if (response.isExtended() && isBackgroundScan == true)
                {
                    RXQueue.Enqueue(response.messageContents);
                }
                else
                {
                    RXQueue.Enqueue(response.getDataPayload());
                }
                break;
            }

            default:
            {
                Debug.Log("Unknown Message " + response.responseID);
                break;
            }
            }
        }
        catch (Exception ex)
        {
            Debug.Log("Channel response processing failed with exception: " + ex.Message);
        }
    }
Example #5
0
        ////////////////////////////////////////////////////////////////////////////////
        // ChannelResponse
        //
        // Called whenever a channel event is recieved.
        //
        // response: ANT message
        ////////////////////////////////////////////////////////////////////////////////
        public void ChannelResponse(ANT_Response response)
        {
            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    // This event indicates that a message has just been
                    // sent over the air. We take advantage of this event to set
                    // up the data for the next message period.
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                    {
                        txBuffer[0]++;          // Increment the first byte of the buffer

                        // Broadcast data will be sent over the air on
                        // the next message period
                        if (bBroadcasting)
                        {
                            channel0.sendBroadcastData(txBuffer);

                            if (bDisplay)
                            {
                                // Echo what the data will be over the air on the next message period
                                Console.WriteLine("Tx: (" + response.antChannel.ToString() + ")" + BitConverter.ToString(txBuffer));
                            }
                        }
                        else
                        {
                            string[] ac = { "|", "/", "_", "\\" };
                            Console.Write("Tx: " + ac[iIndex++] + "\r");
                            iIndex &= 3;
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        Console.WriteLine("Rx Fail");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                    {
                        Console.WriteLine("Burst receive has failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05:
                    {
                        Console.WriteLine("Transfer Completed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06:
                    {
                        Console.WriteLine("Transfer Failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        // This event should be used to determine that the channel is closed.
                        Console.WriteLine("Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel0.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            Console.WriteLine("Press enter to exit");
                            bDone = true;
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A:
                    {
                        Console.WriteLine("Burst Started");
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:

                {
                    if (bDisplay)
                    {
                        if (response.isExtended())                              // Check if we are dealing with an extended message
                        {
                            ANT_ChannelID chID = response.getDeviceIDfromExt(); // Channel ID of the device we just received a message from

                            if (chID.deviceTypeID == 120)
                            {
                                this.Heartrate = System.Convert.ToString(response.getDataPayload()[7]);                               // Device type for HR monitor is 120
                            }
                            else if (chID.deviceTypeID == 11)
                            {
                                if (response.getDataPayload()[0] == 10)
                                {
                                    this.pwr     = response.getDataPayload()[7];
                                    this.cadence = response.getDataPayload()[4];
                                }
                            }

                            if (chID.deviceTypeID == 120)
                            {
                                this.Heartrate = System.Convert.ToString(response.getDataPayload()[7]);
                            }
                            Console.Write("Chan ID(" + chID.deviceNumber.ToString() + "," + chID.deviceTypeID.ToString() + "," + chID.transmissionTypeID.ToString() + ") - ");
                        }
                        if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E ||
                            response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D)
                        {
                            Console.Write("Rx:(" + response.antChannel.ToString() + "): ");
                        }
                        else if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F ||
                                 response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E)
                        {
                            Console.Write("Acked Rx:(" + response.antChannel.ToString() + "): ");
                        }
                        else
                        {
                            Console.Write("Burst(" + response.getBurstSequenceNumber().ToString("X2") + ") Rx:(" + response.antChannel.ToString() + "): ");
                        }

                        //Console.Write(BitConverter.ToString(response.getDataPayload()) + Environment.NewLine);  // Display data payload
                        Console.Write("  Heart Rate is: " + this.Heartrate + Environment.NewLine);
                    }
                    else
                    {
                        string[] ac = { "|", "/", "_", "\\" };
                        Console.Write("Rx: " + ac[iIndex++] + "\r");
                        iIndex &= 3;
                    }
                    break;
                }

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #6
0
        internal void ChannelResponse0(ANT_Response response)
        {
            Random rnd = new Random();

            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                    {
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        Console.WriteLine("Rx Fail");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                    {
                        Console.WriteLine("Burst receive has failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05:
                    {
                        Console.WriteLine("Transfer Completed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06:
                    {
                        Console.WriteLine("Transfer Failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        Console.WriteLine("Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel0.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            Console.WriteLine("Press enter to exit");
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A:
                    {
                        Console.WriteLine("Burst Started");
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
                {
                    // Process received messages here
                }
                break;

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #7
0
        void startNextSearch()
        {
            if (searchChannel != null || antStick == null)  //Check if device is present and the channel is valid
            {
                //Ensure we are still connected
                try
                {
                    searchChannel.requestStatus(1000); //Check if we get an exception...means we are disconnected, otherwise continue
                }
                catch (Exception)
                {
                    try
                    {
                        //We get to this code almost always because the device is dead, so try to restart it
                        ANT_Device.shutdownDeviceInstance(ref antStick);
                        searchChannel = null;
                        foreach (AntPlus_Connection i in deviceList)
                        {
                            i.connectedChannel = null;
                        }

                        findUsableAntDevice();
                        //Now fall through and attempt to restart search
                    }
                    catch (Exception)
                    {
                        //System.Windows.MessageBox.Show("Opening Device Failed. Try removing then re-inserting the stick, then try again.");
                        return;
                    }
                }
            }   //end check if device and search channel (if there is one) are valid

            //Check if we still need to search or have all the equipment already
            List <int> usedChannels = new List <int>();

            foreach (AntPlus_Connection i in deviceList)
            {
                switch (i.getConnStatus())
                {
                case AntPlus_Connection.ConnState.Closed:
                case AntPlus_Connection.ConnState.Searching:
                    i.setConnStatus(AntPlus_Connection.ConnState.InSrchQueue);
                    break;

                case AntPlus_Connection.ConnState.InSrchQueue:
                    break;

                case AntPlus_Connection.ConnState.Connected:
                case AntPlus_Connection.ConnState.DrpdToSrch:
                    usedChannels.Add(i.connectedChannel.getChannelNum());
                    break;
                }
            }

            if (usedChannels.Count == deviceList.Count)
            {
                return;     //we have all the equipment already
            }
            //Get new search channel if neccesary
            if (searchChannel == null)
            {
                if (usedChannels.Count >= numChannelsForDevices)
                {
                    return;     //no free channels
                }
                //Find the first free channel and start the search
                for (int i = 0; i < numChannelsForDevices; ++i)
                {
                    if (!usedChannels.Contains(i))
                    {
                        searchChannel = antStick.getChannel(i);
                        searchChannel.channelResponse += new dChannelResponseHandler(antChannel_channelResponse_FeSearch);
                        break;
                    }
                }
            }

            //Search for a search period for given device parameters
            //Find the next device to search for

            while (true)  //We know there is at least one device we need to search for, because of the check above, so this will never loop infinitely
            {
                ++searchingDeviceIndex;
                if (searchingDeviceIndex >= deviceList.Count)
                {
                    searchingDeviceIndex = 0;
                }
                if (deviceList[searchingDeviceIndex].connectedChannel == null)
                {
                    break;
                }
            }

            //Now set the channel parameters to start the next search
            try
            {
                if (searchChannel == null)
                {
                    throw new ApplicationException("Couldn't allocate a channel for search");
                }

                ds_AntPlus.AntChannelProfile srch = deviceList[searchingDeviceIndex].dataSource.searchProfile;
                deviceList[searchingDeviceIndex].setConnStatus(AntPlus_Connection.ConnState.Searching);

                if (!searchChannel.assignChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 0, 500))
                {
                    //Usually because the channel is in wrong state
                    searchChannel.closeChannel(500);
                    searchChannel.unassignChannel(500);
                    if (!searchChannel.assignChannel(ANT_ReferenceLibrary.ChannelType.BASE_Slave_Receive_0x00, 0, 500))
                    {
                        throw new ApplicationException("Failed to assign channel");
                    }
                }

                //Handle setting the search timeout
                byte timeout = 4; //default 4*2.5=10 seconds for each device
                if (deviceList.Count - usedChannels.Count == 1)
                {
                    timeout = 255;  //search forever if we only have one device to find; If one of the other devices resets it will startNextSearch again so we won't get stuck
                }
                if (!searchChannel.setLowPrioritySearchTimeout(timeout, 500))
                {
                    throw new ApplicationException("Failed to set low-pri search timeout");
                }

                if (!searchChannel.setChannelSearchTimeout(0, 500))
                {
                    throw new ApplicationException("Failed to set search timeout");
                }

                if (!searchChannel.setChannelFreq(srch.rfOffset, 500))
                {
                    throw new ApplicationException("Failed to set channel frequency");
                }

                if (!searchChannel.setChannelPeriod(srch.messagePeriod, 500))
                {
                    throw new ApplicationException("Failed to set channel period");
                }

                if (!searchChannel.setChannelID(srch.deviceNumber, srch.pairingEnabled, srch.deviceType, srch.transType, 500))
                {
                    throw new ApplicationException("Failed to set channel ID");
                }

                if (!searchChannel.openChannel(500))
                {
                    throw new ApplicationException("Failed to open channel");
                }
            }
            catch (Exception ex)
            {
                //System.Windows.MessageBox.Show("Search Channel Open Failed: " + ex.Message +". If you still need to connect other fitness equipment, you may need to restart the application.");
            }
        }
Example #8
0
    void DeviceResponse(ANT_Response response)
    {
        switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
        {
        case ANT_ReferenceLibrary.ANTMessageID.STARTUP_MESG_0x6F:
        {
            Debug.Log("RESET Complete, reason: ");

            var ucReason = response.messageContents[0];

            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_POR_0x00)
            {
                Debug.Log("RESET_POR");
            }
            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_RST_0x01)
            {
                Debug.Log("RESET_RST");
            }
            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_WDT_0x02)
            {
                Debug.Log("RESET_WDT");
            }
            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_CMD_0x20)
            {
                Debug.Log("RESET_CMD");
            }
            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_SYNC_0x40)
            {
                Debug.Log("RESET_SYNC");
            }
            if (ucReason == (byte)ANT_ReferenceLibrary.StartupMessage.RESET_SUSPEND_0x80)
            {
                Debug.Log("RESET_SUSPEND");
            }
            break;
        }

        case ANT_ReferenceLibrary.ANTMessageID.VERSION_0x3E:
        {
            Debug.Log("VERSION: " + new ASCIIEncoding().GetString(response.messageContents));
            break;
        }

        case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
        {
            switch (response.getMessageID())
            {
            case ANT_ReferenceLibrary.ANTMessageID.CLOSE_CHANNEL_0x4C:
            {
                if (response.getChannelEventCode() ==
                    ANT_ReferenceLibrary.ANTEventID.CHANNEL_IN_WRONG_STATE_0x15)
                {
                    Debug.Log("Channel is already closed");
                    Debug.Log("Unassigning Channel...");
                    if (_channel.unassignChannel(500))
                    {
                        Debug.Log("Unassigned Channel");
                        Debug.Log("Press enter to exit");
                        bDone = true;
                    }
                }

                break;
            }

            case ANT_ReferenceLibrary.ANTMessageID.NETWORK_KEY_0x46:
            case ANT_ReferenceLibrary.ANTMessageID.ASSIGN_CHANNEL_0x42:
            case ANT_ReferenceLibrary.ANTMessageID.CHANNEL_ID_0x51:
            case ANT_ReferenceLibrary.ANTMessageID.CHANNEL_RADIO_FREQ_0x45:
            case ANT_ReferenceLibrary.ANTMessageID.CHANNEL_MESG_PERIOD_0x43:
            case ANT_ReferenceLibrary.ANTMessageID.OPEN_CHANNEL_0x4B:
            case ANT_ReferenceLibrary.ANTMessageID.UNASSIGN_CHANNEL_0x41:
            {
                if (response.getChannelEventCode() != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00)
                {
                    Debug.Log(String.Format("Error {0} configuring {1}", response.getChannelEventCode(),
                                            response.getMessageID()));
                }

                break;
            }

            case ANT_ReferenceLibrary.ANTMessageID.RX_EXT_MESGS_ENABLE_0x66:
            {
                if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.INVALID_MESSAGE_0x28)
                {
                    Debug.Log("Extended messages not supported in this ANT product");
                    break;
                }
                else if (response.getChannelEventCode() !=
                         ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00)
                {
                    Debug.Log(String.Format("Error {0} configuring {1}", response.getChannelEventCode(),
                                            response.getMessageID()));
                    break;
                }

                Debug.Log("Extended messages enabled");
                break;
            }

            case ANT_ReferenceLibrary.ANTMessageID.REQUEST_0x4D:
            {
                if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.INVALID_MESSAGE_0x28)
                {
                    Debug.Log("Requested message not supported in this ANT product");
                    break;
                }

                break;
            }

            default:
            {
                Debug.Log("Unhandled response " + response.getChannelEventCode() + " to message " +
                          response.getMessageID());
                break;
            }
            }

            break;
        }
        }
    }
Example #9
0
        /// <summary>
        /// A new measurment has been recieved from the HRM.
        /// </summary>
        /// <param name="response">The response object recieved by the ANT+ driver. This contains the status of the HRM device and the value measured by the sensor.</param>
        static void ChannelResponse(ANT_Response response)
        {
            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        Console.WriteLine("Rx Fail");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                    {
                        Console.WriteLine("Burst receive has failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        // This event should be used to determine that the channel is closed.
                        Console.WriteLine("Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel0.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            Console.WriteLine("Press enter to exit");
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision");
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
                {
                    // Send the recieved packet to Unity
                    AsynchronousSocketListener.Send(response.messageContents[8].ToString());

                    Console.WriteLine(response.messageContents[8]);
                    Console.Write(BitConverter.ToString(response.getDataPayload()) + Environment.NewLine);          // Display data payload

                    break;
                }

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #10
0
        static void ChannelResponsePower(ANT_Response response)
        {
            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    // This event indicates that a message has just been
                    // sent over the air. We take advantage of this event to set
                    // up the data for the next message period.
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "pacchetto potenza inviato con successo", 2 });
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        Console.WriteLine("Rx Fail");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                    {
                        Console.WriteLine("Burst receive has failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05:
                    {
                        Console.WriteLine("Transfer Completed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06:
                    {
                        Console.WriteLine("Transfer Failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        // This event should be used to determine that the channel is closed.
                        Console.WriteLine("Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel2.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            Console.WriteLine("Press enter to exit");
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision banana");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A:
                    {
                        Console.WriteLine("Burst Started");
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
                {
                }
                break;

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #11
0
        void ChannelResponseCadenza(ANT_Response response)
        {
            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())         //identifica che tipo di messaggio è stato ricevuto
                    {
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "Cadence sensor timeout", 0 });
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "RX Failed", 0 });
                        pagineCadenzaRicevute++;
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        channel0.unassignChannel(500);
                        workerDebug.RunWorkerAsync(argument: new object[] { "channel closed", 0 });
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "Serching", 0 });
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "Channel collision", 0 });
                        pagineCadenzaRicevute++;
                        break;
                    }

                    default:
                    {
                        // Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        workerDebug.RunWorkerAsync(argument: new object[] { "Unhandled Channel Event " + response.getChannelEventCode(), 0 });
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                {
                    //Console.Write(BitConverter.ToString(response.getDataPayload()) + " cadenza:  " + cadenza + " inmovinento: " + inMovimentoCadenza + Environment.NewLine);  // Display data payload

                    if (!worker.IsBusy)
                    {
                        worker.RunWorkerAsync(argument: new object[] { calcolaCadenza(response.getDataPayload()), 0 });
                        workerDebug.RunWorkerAsync(argument: new object[] { "RX Success", 0 });         //i made this to sent ant integer used to select the ui element to change without creating other backgrouworkers
                                                                                                        //pattern {message,selector} (selecort: 0=cadence; 1=speed; 2=power; 3=hr);
                        Thread.Sleep(150);
                    }



                    break;
                }

                default:
                {
                    textBoxLogCadence.Text = ("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #12
0
        void ChannelResponseVelocita(ANT_Response response)
        {
            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        workerDebug.RunWorkerAsync(argument: new object[] { "RX Failed", 1 });
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        // This event should be used to determine that the channel is closed.
                        Console.WriteLine("Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel1.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            Console.WriteLine("Press enter to exit");
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision");
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
                {
                    if (true)
                    {
                        if (response.isExtended())                              // Check if we are dealing with an extended message
                        {
                            ANT_ChannelID chID = response.getDeviceIDfromExt(); // Channel ID of the device we just received a message from
                            Console.Write("Chan ID(" + chID.deviceNumber.ToString() + "," + chID.deviceTypeID.ToString() + "," + chID.transmissionTypeID.ToString() + ") - ");
                        }
                        if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E ||
                            response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D)
                        {
                            Console.Write("Rx:(" + response.antChannel.ToString() + "): ");            //questo è quello importante
                        }
                        else if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F ||
                                 response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E)
                        {
                            Console.Write("Acked Rx:(" + response.antChannel.ToString() + "): ");
                        }
                        else
                        {
                            Console.Write("Burst(" + response.getBurstSequenceNumber().ToString("X2") + ") Rx:(" + response.antChannel.ToString() + "): ");
                        }

                        isMoving = checkMovement(response.getDataPayload());

                        velocita = calcolaVelocita(response.getDataPayload());

                        if (!worker.IsBusy)
                        {
                            worker.RunWorkerAsync(argument: new object[] { velocita, 1 });
                            Thread.Sleep(100);          //added this to avoid calling the worker while its busy. yeah, i know, its not an elegant solution but this is what i can do at the moment :)
                        }


                        workerDebug.RunWorkerAsync(argument: new object[] { "RX Success", 1 });

                        setPower(calcolaVelocita(response.getDataPayload()));
                    }

                    break;
                }

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Example #13
0
        ////////////////////////////////////////////////////////////////////////////////
        // ChannelResponse
        //
        // Called whenever a channel event is received.
        //
        // response: ANT message
        ////////////////////////////////////////////////////////////////////////////////
        static void ChannelResponse(ANT_Response response)
        {
            //Console.WriteLine(DateTime.Now + " - Processing Channel Response: " + (ANT_ReferenceLibrary.ANTMessageID)response.responseID);
            Random rnd = new Random();

            try
            {
                switch ((ANT_ReferenceLibrary.ANTMessageID)response.responseID)
                {
                // 0x40 = Channel Message

                case ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                {
                    switch (response.getChannelEventCode())
                    {
                    // This event indicates that a message has just been
                    // sent over the air. We take advantage of this event to set
                    // up the data for the next message period.
                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                    {
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                    {
                        Console.WriteLine("Search Timeout");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02:
                    {
                        Console.WriteLine("Rx Fail");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_RX_FAILED_0x04:
                    {
                        Console.WriteLine("Burst receive has failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_COMPLETED_0x05:
                    {
                        Console.WriteLine("Transfer Completed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_FAILED_0x06:
                    {
                        Console.WriteLine("Transfer Failed");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_CLOSED_0x07:
                    {
                        // This event should be used to determine that the channel is closed.
                        Console.WriteLine(DateTime.Now + " - ANT Channel Closed");
                        Console.WriteLine("Unassigning Channel...");
                        if (channel0.unassignChannel(500))
                        {
                            Console.WriteLine("Unassigned Channel");
                            //Console.WriteLine("Press enter to exit");
                            //bDone = true;
                        }
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08:
                    {
                        Console.WriteLine("Go to Search");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_CHANNEL_COLLISION_0x09:
                    {
                        Console.WriteLine("Channel Collision");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.EVENT_TRANSFER_TX_START_0x0A:
                    {
                        Console.WriteLine("Burst Started");
                        break;
                    }

                    case ANT_ReferenceLibrary.ANTEventID.NO_EVENT_0x00:
                    {
                        Console.WriteLine("No_Event_0x00 - " + response.getChannelEventCode());
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("Unhandled Channel Event " + response.getChannelEventCode());
                        break;
                    }
                    }
                    break;
                }

                case ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                case ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                case ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                case ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:

                case ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
                {
                    // Process received messages here

                    //Console.WriteLine("Channel - ResponseID: " + response.responseID);

                    byte[] Payload = new byte[8];
                    Payload = response.getDataPayload();
                    //Console.WriteLine("Channel - Payload[6]: " + Payload[6]);
                    //Console.WriteLine("Channel - Payload[7]: " + Payload[7]);
                    // Command Number: 0-65535
                    int CommandNumber = 0;
                    CommandNumber = BitConverter.ToUInt16(Payload, 6);

                    WriteLog("Received CommandNumber: " + CommandNumber);

                    string processName = "ZwiftApp";
                    //string processName = "notepad";

                    Process[] targetProcess = Process.GetProcessesByName(processName);
                    if (targetProcess.Length > 0)
                    {
                        WriteLog(processName + " found");
                        Process p = targetProcess[0];
                        IntPtr  h = p.MainWindowHandle;

                        SetForegroundWindow(h);

                        INPUT[]    inputs = new INPUT[1];
                        KEYBDINPUT kb     = new KEYBDINPUT();
                        uint       result;

                        inputs[0].type = 1;                                         //keyboard

                        // Prepare Keyboard Entry !

                        kb.time        = 0;
                        kb.dwExtraInfo = IntPtr.Zero;
                        kb.wVk         = (ushort)0x00;


                        //
                        // ANT command codes:
                        //
                        // 32768 - Down
                        // 32769 - Up
                        // 32770 - Right
                        // 32771 - Left
                        // 32772 - SpaceBar
                        // 32773 - Enter
                        // 32774 - G
                        // 32775 - ESC
                        // 32776 - Snapshot
                        // 32777 - SwitchView
                        // 32778 - ElbowFlick
                        // 32779 - ANT Devices Pairing
                        // 32780 - 0 = View 0
                        // 32781 - 1 = View 1
                        // 32784 - 4 = View 4
                        // 32785 - 5 = View 5
                        // 32786 - 6 = View 6
                        // 32787 - 7 = View 7
                        // 32788 - 8 = View 8
                        // 32789 - 9 = View 9
                        // 32790 - Pg Up = FTP Bias Up
                        // 32791 - Pg Down = FTP Bias Down
                        // 32792 - Tab
                        //

                        ushort key_wScan   = 0x50;
                        uint   key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);

                        switch (CommandNumber)
                        {
                        case 32768:
                        {
                            key_wScan   = 0x50;                                                           // Down + Extended (E0)
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32769:
                        {
                            key_wScan   = 0x48;                                                           // Up + Extended (E0)
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32770:
                        {
                            key_wScan   = 0x4d;                                                           // Right + Extended (E0)
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32771:
                        {
                            key_wScan   = 0x4b;                                                           // Left + Extended (E0)
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32772:
                        {
                            key_wScan   = 0x39;                                                           // SpaceBar
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32773:
                        {
                            key_wScan   = 0x1c;                                                           // Enter
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32774:
                        {
                            key_wScan   = 0x22;                                                           // G = US-G = 0x22 - Azerty / Qwerty
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32775:
                        {
                            key_wScan   = 0x01;                                                           // ESC
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32776:
                        {
                            key_wScan   = 0x44;                                                           // F10 - Snapshot
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32778:
                        {
                            key_wScan   = 0x3b;                                                           // F1 - ElbowFlick
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32779:
                        {
                            key_wScan   = 0x10;                                                           // A = US-Q = 0x10 - Azerty / Qwerty
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32780:
                        {
                            key_wScan   = 0x52;                                                           // Num 0 - View 0
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32781:
                        {
                            key_wScan   = 0x4f;                                                           // Num 1 - View 1
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32782:
                        {
                            key_wScan   = 0x50;                                                           // Num 2 - View 2
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32783:
                        {
                            key_wScan   = 0x51;                                                           // Num  3 - View 3
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32784:
                        {
                            key_wScan   = 0x4b;                                                           // Num 4 - View 4
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32785:
                        {
                            key_wScan   = 0x4c;                                                           // Num 5 - View 5
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32786:
                        {
                            key_wScan   = 0x4d;                                                           // Num 6 - View 6
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32787:
                        {
                            key_wScan   = 0x47;                                                           // Num 7 - View 7
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32788:
                        {
                            key_wScan   = 0x48;                                                           // Num 8 - View 8
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32789:
                        {
                            key_wScan   = 0x49;                                                           // Num 9 - View 9
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        case 32790:
                        {
                            key_wScan   = 0x49;                                                           // PgUp + Extended (E0) - FTP Bias Up
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32791:
                        {
                            key_wScan   = 0x51;                                                           // PgDown + Extended (E0) - FTP Bias Down
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);
                            break;
                        }

                        case 32792:
                        {
                            key_wScan   = 0x0f;                                                           // Tab - Skip Block
                            key_dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.ScanCode);
                            break;
                        }

                        default:
                        {
                            break;
                        }
                        }

                        //kb.wScan = 0x01; // Esc

                        //kb.wScan = 0x10; // A = Paired Device
                        //kb.wScan = 0x12; // E - Select your Workout
                        //kb.wScan = 0x14; // T = User Customisation
                        //kb.wScan = 0x22; // G - HR-Power Graph
                        //kb.wScan = 0x44; // F10 = Screenshot


                        kb.wScan   = key_wScan;
                        kb.dwFlags = key_dwFlags;

                        //kb.wScan = 0x32; // M

                        //kb.dwFlags = (uint) (KeyEventF.KeyDown | KeyEventF.ScanCode);
                        //kb.dwFlags = (uint) (KeyEventF.KeyDown | KeyEventF.ScanCode | KeyEventF.ExtendedKey);

                        inputs[0].ki = kb;

                        result = SendInput(1, inputs, Marshal.SizeOf(inputs[0]));
                    }
                    else
                    {
                        WriteLog("Zwift Application not found");
                    }
                }
                break;

                default:
                {
                    Console.WriteLine("Unknown Message " + response.responseID);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }