//DecodeMessage input event
        public void DecodeMessage(object sender, DataReceivedArgs e)
        {
            foreach (byte c in e.Data)
            {
                if (rcvState == StateReception.Waiting)
                {
                    messageAvailable = false;
                }

                switch (rcvState)
                {
                case StateReception.Waiting:
                    if (c == 0xFE)
                    {
                        rcvState = StateReception.FunctionMSB;
                    }
                    break;

                case StateReception.FunctionMSB:
                    msgDecodedFunction = (ushort)(c << 8);
                    rcvState           = StateReception.FunctionLSB;
                    break;

                case StateReception.FunctionLSB:
                    msgDecodedFunction += (ushort)(c << 0);
                    rcvState            = StateReception.PayloadLengthMSB;
                    break;

                case StateReception.PayloadLengthMSB:
                    msgDecodedPayloadLength = (ushort)(c << 8);
                    rcvState = StateReception.PayloadLengthLSB;
                    break;

                case StateReception.PayloadLengthLSB:
                    msgDecodedPayloadLength += (ushort)(c << 0);

                    if (msgDecodedPayloadLength > 0)
                    {
                        msgDecodedPayloadIndex = 0;
                        msgDecodedPayload      = new byte[msgDecodedPayloadLength];
                        rcvState = StateReception.Payload;
                    }
                    else
                    {
                        rcvState = StateReception.CheckSum;     //if no payload, skip to CheckSum state
                    }
                    break;

                case StateReception.Payload:

                    if (msgDecodedPayloadIndex < msgDecodedPayloadLength)
                    {
                        msgDecodedPayload[msgDecodedPayloadIndex] = c;
                        msgDecodedPayloadIndex++;
                        if (msgDecodedPayloadIndex == msgDecodedPayloadLength)
                        {
                            rcvState = StateReception.CheckSum;
                        }
                    }

                    break;

                case StateReception.CheckSum:
                    receivedCheckSum   = c;
                    calculatedCheckSum = mesEncoder.CalculateChecksum(msgDecodedFunction, msgDecodedPayloadLength, msgDecodedPayload);
                    messageAvailable   = true;
                    if (calculatedCheckSum == receivedCheckSum)
                    {
                        //Console.WriteLine("checksum ok received: " + receivedCheckSum.ToString("X2") +
                        //                  " calculated: " + calculatedCheckSum.ToString("X2"));
                        CheckSumErrorOccured = false;
                    }
                    else
                    {
                        // Console.WriteLine("checksum error received: " + receivedCheckSum.ToString("X2") +
                        //                   " calculated: " + calculatedCheckSum.ToString("X2"));
                        CheckSumErrorOccured = true;
                    }

                    OnDataDecoded(msgDecodedFunction, msgDecodedPayloadLength, msgDecodedPayload, receivedCheckSum, CheckSumErrorOccured);

                    rcvState = StateReception.Waiting;

                    break;

                default:
                    rcvState = StateReception.Waiting;
                    break;
                }
            }
        }