protected void onChannelResponse(ANT_Response response)
 {
     try
     {
         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
             DeviceNumber = (ushort)chID.deviceNumber;
         }
         Parse(response.getDataPayload());
     }
     catch
     {
     }
 }
        protected override void handleNonRxFailChannelResponse(ANT_Managed_Library.ANT_Response response)
        {
            if (response.responseID == (byte)ANT_Managed_Library.ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E)
            {
                switch (response.messageContents[1])
                {
                case 16:       //Page 16 - General Page
                {
                    //Get new values

                    byte   curElapsedTimeAcc = response.messageContents[3];
                    byte   curDistAcc        = response.messageContents[4];
                    ushort curInstSpeed      = (ushort)(response.messageContents[5] + ((ushort)response.messageContents[6] << 8));
                    //heartRate = response.messageContents[7],

                    //If we aren't initialized we can't do the calculations yet and we just save the values below
                    if (isInitialized)
                    {
                        //Get the distance increase out of the accumulated field
                        int distIncrease = curDistAcc - lastDistAcc;
                        if (distIncrease < 0)
                        {
                            distIncrease = 255 + distIncrease;
                        }

                        if (distIncrease == 0)                          //Some devices like the rower don't reset the speed value when the rowing stops
                        {
                            if (++idleCount >= MAX_NO_EVENT_STOP_COUNT) //depending on page setup of machine, this is at least 1.5s, max 3s
                            {
                                curInstSpeed = 0;
                                idleCount    = MAX_NO_EVENT_STOP_COUNT;         //Always set, so we don't rollover
                            }
                        }
                        else
                        {
                            idleCount = 0;
                        }

                        //System.Console.Out.WriteLine(feDataSource.type + ", " + curData.distAcc + ", " + distIncrease);

                        //TODO: qc Keep checking if this is the same device as original connection?
                        //if((FitEquipType)(response.messageContents[2] & 0x1F) != feDataSource.type)

                        if (curInstSpeed == 0xFFFF)         //If instantaneous speed is invalid, we have to manually calculate it
                        {
                            //Average speed over last 16 msgs
                            //System.Console.Write(String.Format("Pre Speed = {0}, ", calcSpeed));
                            double calcTimeDiff = curElapsedTimeAcc - lastElapsedTimeAcc;

                            if (calcTimeDiff > 0)           //If there is no time diff, it is probably because the broadcast data wasn't updated, so don't try and predict speed from it
                            {
                                calcSpeed  = (calcSpeed * 7 / 8);
                                calcSpeed += (((double)distIncrease * 4) / calcTimeDiff) / 8;         //Add the fractional contributed by this msg. Time is in 0.25s units, so multiply dist by 4
                            }

                            incrementDistanceAndUpdate(distIncrease, calcSpeed, lastInstCadence, powerW: lastInstPower);
                        }
                        else
                        {
                            incrementDistanceAndUpdate(distIncrease, ((double)curInstSpeed) / 1000, lastInstCadence, powerW: lastInstPower);
                        }
                    }
                    else         //When we are initializing we determine the sport type
                    {
                        switch (response.messageContents[2] & 0x1F)
                        {
                        case 19:             //Treadmill
                            sportType = racerSportType.Running;
                            break;

                        case 22:                //Rower
                            sportType = racerSportType.Rowing;
                            break;

                        case 21:                //Biking
                            sportType = racerSportType.Biking;
                            break;

                        case 20:                //Elliptical
                            sportType = racerSportType.Running;
                            break;

                        case 23:                //Climber
                            sportType = racerSportType.Running;
                            break;

                        case 24:                //Nordic Ski machine
                            sportType = racerSportType.Skiing;
                            break;

                        default:
                            sportType = racerSportType.Unknown;
                            break;
                        }

                        isInitialized = true;
                    }

                    //Save for next time
                    lastElapsedTimeAcc = curElapsedTimeAcc;
                    lastDistAcc        = curDistAcc;
                }
                break;

                //case 17: //general settings Page, not on bike, shows on rower, but not very useful
                //    {
                //        System.Console.Out.WriteLine("Cycle Length:" + response.messageContents[4] + ",Incline:" + (response.messageContents[5] + (response.messageContents[5] << 8)) + ",Resist:" + response.messageContents[7]);
                //    }
                //    break;
                //case 18: //metabolic data, doesn't show on rower or bike
                //    {
                //        System.Console.Out.WriteLine("BurnRate:" + (response.messageContents[5] + (response.messageContents[6] << 8)) + ",Cal:" + response.messageContents[7]);
                //    }
                //    break;
                case 19:     //treadmill data
                {
                    lastInstCadence = response.messageContents[5];
                }
                break;

                case 21:     //bike data
                case 22:     //Row data, same format as bike for cad and power
                case 20:     //Elliptical, same format as bike for cad and power
                case 24:     //Nordic Skier, same format as bike for cad and power
                {
                    lastInstCadence = response.messageContents[5];
                    lastInstPower   = (ushort)(response.messageContents[6] + (response.messageContents[7] << 8));
                    //System.Console.Out.WriteLine("Cadence:" + response.messageContents[5] + ",Power:" + (response.messageContents[6] + (response.messageContents[7] << 8)));
                    //System.Console.Out.WriteLine("SPM:"+response.messageContents[5]+"Power:"+(response.messageContents[6] + (response.messageContents[7] << 8)));
                }
                break;
                }
            }
        }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////
        // DeviceResponse
        //
        // Called whenever a message is received from ANT unless that message is a
        // channel event message.
        //
        // response: ANT message
        ////////////////////////////////////////////////////////////////////////////////
        protected void DeviceResponse(ANT_Response response)
        {
            switch ((ANT_ReferenceLibrary.ANTMessageID) response.responseID)
            {
                case ANT_ReferenceLibrary.ANTMessageID.STARTUP_MESG_0x6F:
                {
                    Console.Write("RESET Complete, reason: ");

                    byte ucReason = response.messageContents[0];

                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_POR_0x00)
                        Console.WriteLine("RESET_POR");
                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_RST_0x01)
                        Console.WriteLine("RESET_RST");
                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_WDT_0x02)
                        Console.WriteLine("RESET_WDT");
                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_CMD_0x20)
                        Console.WriteLine("RESET_CMD");
                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_SYNC_0x40)
                        Console.WriteLine("RESET_SYNC");
                    if(ucReason == (byte) ANT_ReferenceLibrary.StartupMessage.RESET_SUSPEND_0x80)
                        Console.WriteLine("RESET_SUSPEND");
                    break;
                }
                case ANT_ReferenceLibrary.ANTMessageID.VERSION_0x3E:
                {
                    Console.WriteLine("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)
                            {
                                foreach (SensorProcessor s in _SensorProcessors)
                                {

                                    s.UnassignChannel();
                                }
                            }
                            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.OPEN_CHANNEL_0x4B:
                        case ANT_ReferenceLibrary.ANTMessageID.UNASSIGN_CHANNEL_0x41:
                        {
                            if (response.getChannelEventCode() != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00)
                            {
                                Console.WriteLine(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)
                            {
                                Console.WriteLine("Extended messages not supported in this ANT product");
                                break;
                            }
                            else if(response.getChannelEventCode() != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00)
                            {
                                Console.WriteLine(String.Format("Error {0} configuring {1}", response.getChannelEventCode(), response.getMessageID()));
                                break;
                            }
                            Console.WriteLine("Extended messages enabled");
                            break;
                        }
                        case ANT_ReferenceLibrary.ANTMessageID.REQUEST_0x4D:
                        {
                            if (response.getChannelEventCode() == ANT_ReferenceLibrary.ANTEventID.INVALID_MESSAGE_0x28)
                            {
                                Console.WriteLine("Requested message not supported in this ANT product");
                                break;
                            }
                            break;
                        }
                        default:
                        {
                            Console.WriteLine("Unhandled response " + response.getChannelEventCode() + " to message " + response.getMessageID());                            break;
                        }
                    }
                    break;
                }
            }
        }
Exemple #4
0
        /// <overloads>Requests a message from the device and returns the response</overloads>
        /// <summary>
        /// Request a message from device and returns the response. 
        /// Throws exception on timeout.
        /// </summary>
        /// <param name="channelNum">Channel to send request on</param>
        /// <param name="messageID">Request to send</param>
        /// <param name="responseWaitTime">Time to wait for device success response</param>
        public ANT_Response requestMessageAndResponse(byte channelNum, ANT_ReferenceLibrary.RequestMessageID messageID, UInt32 responseWaitTime)
        {
            if (!initializedUSB)
                throw new ObjectDisposedException("ANTDevice object has been disposed");

            ANTMessageItem response = new ANTMessageItem();
            if (ANT_RequestMessage(unmanagedANTFramerPtr, channelNum, (byte)messageID, ref response, responseWaitTime) == 0)
                throw new ANT_Exception("Timed out waiting for requested message");
            ANT_Response retVal = new ANT_Response(this, channelNum, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray());
            return retVal;
        }
Exemple #5
0
        private void responsePollFunc()
        {
            ushort messageSize = 0;
            byte channelNum;
            bool isMsgForChannel;

            pollingOn = true;   //Set to false on shutdown to terminate the thread
            #if (ANTFS_DEBUGGING)
            ANT_Common.initDebugLogThread("Device" + USBDeviceNum + "_ANTReceive"); // We still need this for ANT-FS!  Will not be created if debug disabled
            #endif
            while (initializedUSB && pollingOn)    //check continuously; this thread is terminated on destruction of the class
            {
                // We only wait in the unmanged code for 100 ms because we want this thread to be responsive on our side.
                // It does mean that we are running through a lot more cycles than we need to
                messageSize = ANT_WaitForMessage(unmanagedANTFramerPtr, 100);

                if (messageSize == (ushort)0xFFFE)   //DSI_FRAMER_TIMEDOUT
                    continue;   //Expected, just keep looping

                ANTMessage newMessage = new ANTMessage();
                messageSize = ANT_GetMessage(unmanagedANTFramerPtr, ref newMessage);

                if (messageSize == (ushort)0xFFFF)  // DSI_FRAMER_ERROR - in current library could be from CRC error, Write error, Read error, or DeviceGone
                {
                    serialErrorCode error;
                    bool isCritical = false;

                    switch(newMessage.msgID)
                    {
                        case 0x02:  //DSI_FRAMER_ANT_ESERIAL
                            switch(newMessage.ucharBuf[0])
                            {
                                case 0x04:  //ESERIAL -> DSI_FRAMER_ANT_CRC_ERROR
                                    error = serialErrorCode.MessageLost_CrcError;
                                    break;
                                case 0x02:  //ESERIAL -> DSI_SERIAL_EWRITE
                                    error = serialErrorCode.SerialWriteError;
                                    break;
                                case 0x03:  //ESERIAL -> DSI_SERIAL_EREAD
                                    error = serialErrorCode.SerialReadError;
                                    isCritical = true;
                                    break;
                                case 0x01:  //ESERIAL -> DSI_SERIAL_DEVICE_GONE
                                    error = serialErrorCode.DeviceConnectionLost;
                                    isCritical = true;
                                    break;
                                default:
                                    error = serialErrorCode.Unknown;
                                    System.Diagnostics.Debug.Fail("Unknown serial failure, why isn't this known?");
                                    break;
                            }
                            break;
                        case 0x01:  //DSI_FRAMER_ANT_EQUEUE_OVERFLOW
                            error = serialErrorCode.MessageLost_QueueOverflow;
                            break;
                        case 0x03:  //DSI_FRAMER_ANT_EINVALID_SIZE
                            error = serialErrorCode.MessageLost_TooLarge;
                            break;
                        default:
                            error = serialErrorCode.Unknown;
                            System.Diagnostics.Debug.Fail("Unknown serial failure, why isn't this known?");
                            break;
                    }

                    if(isCritical)
                    {
                        //System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(x => shutdown())); //Clean up all resources on another thread to allow this one to close cleanly
                        pollingOn = false;  //Just stop polling, since we will never get new messages now. Allow the user to dispose of the device.
                    }

                    //If application has subscribed to the event we can inform them
                    if (serialError != null)
                        serialError(this, error, isCritical);
                    else   //Debug.Fail is a no-op in release mode, so we will only see this in debugging, in release mode we don't want to do anything intrusive (ie:message box, exception)
                        System.Diagnostics.Debug.Fail("Device Serial Communication Failure, HandleSerialError not handled by application");

                    if (isCritical)
                        break;  //If the device is dead, exit the polling loop
                    else
                        continue;
                }

                isMsgForChannel = false;
                channelNum = Byte.MaxValue;

                switch (newMessage.msgID)   //Check if we send to channel or protocol response func
                {
                    // Send on Channel event
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40:
                        if (newMessage.ucharBuf[1] == (byte)ANT_ReferenceLibrary.ANTMessageID.EVENT_0x01)
                            isMsgForChannel = true;
                        break;
                    // or any of the transmission events
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.ACKNOWLEDGED_DATA_0x4F:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BROADCAST_DATA_0x5D:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_ACKNOWLEDGED_DATA_0x5E:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.BURST_DATA_0x50:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.EXT_BURST_DATA_0x5F:
            #if (!REFERENCE_DESIGN)
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.ADV_BURST_DATA_0x72:
            #endif
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BROADCAST_DATA_0xC1:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_ACKNOWLEDGED_DATA_0xC2:
                    case (byte)ANT_ReferenceLibrary.ANTMessageID.RSSI_BURST_DATA_0xC3:
                        isMsgForChannel = true;
                        break;
                }

                ANT_Response newResponse;

                //Now dispatch to appropriate event
                //The messages are buffered in the ant library so we just dispatch with current thread
                //then no matter how long the event call takes we still won't miss messages
                if (isMsgForChannel)
                {
                    channelNum = (byte)(newMessage.ucharBuf[0] & 0x1F); //Mask out what channel this is for. [We can eventually switch to use the c++ code to determine the channel, but we should do it all together with getMessage to avoid extra marshalling and copying and remove the processing in C# above]
                    if (antChannels != null && channelNum < antChannels.Length)
                    {
                        if (antChannels[channelNum] != null)
                            antChannels[channelNum].MessageReceived(newMessage, messageSize);
                    }
                    else
                    {
                        if (serialError != null)
                            serialError(this, serialErrorCode.MessageLost_InvalidChannel, false);
                    }
                }
                else
                {
                    newResponse = new ANT_Response(this, newMessage.ucharBuf[0], DateTime.Now, newMessage.msgID, newMessage.ucharBuf.Take(messageSize).ToArray());

                    if (deviceResponse != null) //Ensure events are assigned before we call the event
                        deviceResponse(newResponse);
                }

            }
        }
Exemple #6
0
        ////////////////////////////////////////////////////////////////////////////////
        // ChannelResponse
        //
        // Called whenever a channel event is recieved.
        //
        // response: ANT message
        ////////////////////////////////////////////////////////////////////////////////
        private 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.
                                case ANT_ReferenceLibrary.ANTEventID.EVENT_TX_0x03:
                                    {
                                        break;
                                    }
                                case ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01:
                                    {
                                      Console.WriteLine("Search timeout");
                                      Status = SensorStatus.Disconnected;
                                        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 (_Channel.unassignChannel(500))
                                        {
                                            Console.WriteLine("Unassigned Channel");
                                            Status = SensorStatus.Disconnected;
                                        }
                                        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:
                        {
                          Status = SensorStatus.Connected;
                          if (DeviceNumber == 0)
                          {
                            ANT_ChannelID chId = _Channel.requestID(500);
                            if (chId.deviceNumber > 0)
                            {
                              Console.WriteLine("Setting device number and transmission type...");
                              DeviceNumber = chId.deviceNumber;
                              TransmissionType = chId.transmissionTypeID;
                            }

                          }
                          Console.WriteLine("decoding payload....");
                                _Sensor.Decode(response.getDataPayload());
                                break;
                        }
                    default:
                        {
                            Console.WriteLine("Unknown Message " + response.responseID);
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Exemple #7
0
 /// <summary>
 /// Callback used by the .NET DLL for the Garmin device (USB1/2)
 /// </summary>
 /// <param name="response"></param>
 void DeviceResponse(ANT_Response response)
 {
     byte[] message_bytes = new byte[response.messageContents.Length + 3];
     //Add header bytes as expected by the ProcessMessage function
     message_bytes[2] = response.responseID;
     response.messageContents.CopyTo(message_bytes, 3);
     BeginInvoke(new EventHandler(delegate { ProcessMessage(message_bytes); }));
     
 }
 private void DeviceResponse(ANT_Response response)
 {
     // Debug.Log("[AntStick] " + decodeDeviceFeedback(response));
 }
        /// <summary>
        /// This function decodes the message code into human readable form and shows the error
        /// value on failures for device response events.
        /// </summary>
        /// <param name="response">The ANT Response received from the device.</param>
        /// <returns>A nicely formatted string</returns>
        private string decodeDeviceFeedback(ANT_Response response)
        {
            string toDisplay = "Device: ";

            // The ANTReferenceLibrary contains all the message and event codes in user-friendly
            // enums. This allows for more readable code and easy conversion to human readable
            // strings for display.

            // So, for the device response we first check if it is an event, then we check if it
            // failed, and display the failure if that is the case. "Events" use message code 0x40.
            if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
            {
                // We cast the byte to its messageID string and add the channel number byte.
                // associated with the message
                toDisplay += (ANT_ReferenceLibrary.ANTMessageID)response.messageContents[1] + ", Ch:" + response.messageContents[0];
                // Check if the eventID shows an error, if it does, show the error message.
                if ((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2] != ANT_ReferenceLibrary.ANTEventID.RESPONSE_NO_ERROR_0x00)
                    toDisplay += Environment.NewLine + ((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2]).ToString();
            }
            else   // If the message is not an event, we just show the messageID.
                toDisplay += ((ANT_ReferenceLibrary.ANTMessageID)response.responseID).ToString();

            // Finally we display the raw byte contents of the response, converting it to hex.
            toDisplay += Environment.NewLine + "::" + Convert.ToString(response.responseID, 16)
                      + ", " + BitConverter.ToString(response.messageContents) + Environment.NewLine;
            return toDisplay;
        }
        /// <summary>
        /// This function decodes the message code into human readable form and shows the error
        /// value on failures for channel response events.
        /// </summary>
        /// <param name="response">The ANT Response received from the channel.</param>
        /// <returns>A nicely formatted string.</returns>
        String decodeChannelFeedback(ANT_Response response)
        {
            // We use a stringbuilder for speed and better memory usage.
            StringBuilder stringToPrint;
            stringToPrint = new StringBuilder("Channel: ", 100);

            // In the channel feedback we will get either RESPONSE_EVENTs or receive events. If it
            // is a response event we display what the event was and the error code if it failed.
            // Mostly, these response_events will all be broadcast events from a Master channel.
            if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
                stringToPrint.AppendLine(((ANT_ReferenceLibrary.ANTEventID)response.messageContents[2]).ToString());
            else   // This is a receive event, so display the ID
                stringToPrint.AppendLine("Received " + ((ANT_ReferenceLibrary.ANTMessageID)response.responseID).ToString());

            // Always print the raw contents in hex, with leading '::' for easy visibility/parsing.
            // If this is a receive event it will contain the payload of the message.
            stringToPrint.Append("  :: ");
            stringToPrint.Append(Convert.ToString(response.responseID, 16));
            stringToPrint.Append(", ");
            stringToPrint.Append(BitConverter.ToString(response.messageContents) + Environment.NewLine);

            return stringToPrint.ToString();
        }
        private void ChannelResponse(ANT_Response response)
        {
            // Debug.Log("[AntStick] " + decodeChannelFeedback(response));

            if (response.responseID == (byte)ANT_ReferenceLibrary.ANTMessageID.RESPONSE_EVENT_0x40)
            {
                if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_SEARCH_TIMEOUT_0x01)
                {
                    Debug.LogWarning("[AntStick] Failed to connect to any device.");
                    Debug.LogWarning("[AntStick] <b>WARNING --- UNITY MAY CRASH!</b> Try lowering AntStick.CONNECT_TIMEOUT value.");
                    UpdateState(AntState.ConnectFail);
                    Stop();
                }

                if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_0x02)
                {
                    Stats.IncrementRxFailCount();
                }

                if (response.messageContents[2] == (byte)ANT_ReferenceLibrary.ANTEventID.EVENT_RX_FAIL_GO_TO_SEARCH_0x08)
                {
                    UpdateState(AntState.ReConnecting);
                    StartConnectTimeout();
                }
            }
            else
            {
                if (state == AntState.Starting || state == AntState.ReConnecting)
                {
                    Debug.Log("[AntStick] Successfully began receiving data.");
                    UpdateState(AntState.Connected);
                }

                DataPage dataPage = DataPage.BuildDataPageFromReceivedData(response.messageContents);
                Stats.IncrementPageCount(dataPage.DataPageNumber);
                dataPage.FireReceived();
            }
        }
 void OnChannelResponseRecieved(ANT_Response response)
 {
     lock (locker)
     {
         messageSubject.OnNext(new AntMessage(response.responseID, response.messageContents));
     }
 }
        ////////////////////////////////////////////////////////////////////////////////
        // 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);
            }
        }
Exemple #14
0
        ////////////////////////////////////////////////////////////////////////////////
        // ChannelResponse
        //
        // Called whenever a channel event is recieved.
        //
        // response: ANT message
        ////////////////////////////////////////////////////////////////////////////////
        private void ChannelResponse(ANT_Response response)
        {
            bool bDisplay = true;
            bool bDone = false;
            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:
                                    {
                                        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 (_Channel.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:
                        {
                          Console.WriteLine("decoding payload....");
                                _Sensor.Decode(response.getDataPayload());
                            break;
                        }
                    default:
                        {
                            Console.WriteLine("Unknown Message " + response.responseID);
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Channel response processing failed with exception: " + ex.Message);
            }
        }
Exemple #15
0
        /// <overloads>Requests a message from the device and returns the response</overloads>
        /// <summary>
        /// Read User Nvm by sending Request Mesg capturing the response.        
        /// Throws exception on timeout.
        /// </summary>                
        /// <param name="address">NVM Address to read from</param>
        /// <param name="size">Number of bytes to read</param>
        /// <param name="responseWaitTime">Time to wait for device success response</param>
        public ANT_Response readUserNvm(UInt16 address, byte size, UInt32 responseWaitTime)
        {
           if (!initializedUSB)
              throw new ObjectDisposedException("ANTDevice object has been disposed");

           ANTMessageItem response = new ANTMessageItem();
           if (ANT_RequestUserNvmMessage(unmanagedANTFramerPtr, 0, (byte)ANT_ReferenceLibrary.RequestMessageID.USER_NVM_0x7C, ref response, address, size, responseWaitTime) == 0)
              throw new ANT_Exception("Timed out waiting for requested message");
           ANT_Response retVal = new ANT_Response(this, 0, DateTime.Now, response.antMsgData.msgID, response.antMsgData.ucharBuf.Take(response.dataSize).ToArray());
           return retVal;
        }