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); }
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); }