Exemplo n.º 1
0
        bool ProcessReceivedCharacter(char currentCharacter, CBusStateMachine state)
        {
            switch (state.ParserState)
            {
            case CBusStateMachine.StateMachineState.MESSAGE_COMPLETE:
            case CBusStateMachine.StateMachineState.NONE:
            {
                if (currentCharacter != STX_CHAR)
                {
                    //Serial interface seems to strip leading '\' character
                    //so just assume that the STX was received and that this is the first data character.
                    //So the next received character will be data 2
                    if (IsValidCharacter(currentCharacter))
                    {
                        state.ParserState = CBusStateMachine.StateMachineState.DATA2;
                    }
                    else
                    {
                        state.ParserState = CBusStateMachine.StateMachineState.ACK_RECEIVED;
                    }
                }
                else
                {
                    state.ParserState = CBusStateMachine.StateMachineState.STX_FOUND;
                }
                break;
            }

            case CBusStateMachine.StateMachineState.ACK_RECEIVED:
            {
                switch (currentCharacter)
                {
                case ACK_CHAR:
                    //Store the ack character...
                    state.ACK_Character = state.PreviousRxCharacter;
                    state.MessageType   = CBusMessageType.ACK;
                    return(true);

                //NAK Responses
                case NAK:
                    state.MessageType = CBusMessageType.NAK;
                    return(true);

                case NAK_CORRUPTED:
                    state.MessageType = CBusMessageType.NAK_CORRUPTED;
                    return(true);

                case NAK_NO_CLOCK:
                    state.MessageType = CBusMessageType.NAK_NO_CLOCK;
                    return(true);

                case NAK_MSG_TOO_LONG:
                    state.MessageType = CBusMessageType.NAK_MESSAGE_TOO_LONG;
                    return(true);

                default:
                    //Unexpected character
                    state.Reset();
                    break;
                }
                break;
            }

            case CBusStateMachine.StateMachineState.DATA1:
            {
                if (currentCharacter == ETX_CHAR_1)
                {
                    state.ParserState        = CBusStateMachine.StateMachineState.MESSAGE_COMPLETE;
                    state.CalculatedChecksum = CBusSALCommand.CalculateChecksum(state.CommandBytes, state.CommandLength);
                    state.MessageType        = CBusMessageType.SAL_MESSAGE_RECEIVED;
                    return(true);
                }
                else
                {
                    if (IsValidCharacter(currentCharacter))
                    {
                        state.ParserState = CBusStateMachine.StateMachineState.DATA2;
                    }
                    else
                    {
                        state.Reset();
                    }
                }
                break;
            }

            case CBusStateMachine.StateMachineState.DATA2:
            {
                var hex = string.Format("{0}{1}", state.PreviousRxCharacter, currentCharacter);

                byte data;
                if (byte.TryParse(hex, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out data))
                {
                    state.CommandBytes[state.CommandLength++] = data;
                    state.ParserState = CBusStateMachine.StateMachineState.DATA1;
                }
                else
                {
                    state.Reset();
                }

                break;
            }
            }

            if (state.ParserState != CBusStateMachine.StateMachineState.NONE)
            {
                state.MessageType = CBusMessageType.MESSAGE_PENDING;
            }

            return(false);
        }
Exemplo n.º 2
0
        public bool TryProcessReceivedBytes(char[] RxData, int rxDataLength, ref int DataPositionPointer, CBusStateMachine state)
        {
            state.BytesProcessed = 0;

            for (int i = DataPositionPointer; i < rxDataLength; ++i)
            {
                var currentCharacter = RxData[i];
                state.BytesProcessed++;
                DataPositionPointer++;

                var result = ProcessReceivedCharacter(currentCharacter, state);
                state.PreviousRxCharacter = currentCharacter;



                if (result)
                {
                    //If we have a valid check sum and message terminated by ETX_CHAR_1 & ETX_CHAR_2 then trat as a monitored SAL
                    if (/*state.CalculatedChecksum == 0 &&*/ state.MessageType == CBusMessageType.SAL_MESSAGE_RECEIVED)
                    {
                        //Has Valid check sum so could be a monitored SAL message
                        if ((i + 1) < rxDataLength)
                        {
                            if (RxData[i + 1] == ETX_CHAR_2)
                            {
                                DataPositionPointer++;
                                state.BytesProcessed++;
                                state.MessageType = CBusMessageType.MONITORED_SAL_MESSAGE_RECEIVED;
                            }
                        }
                    }

                    return(true);
                }
            }

            return(false);
        }