public bool SerialWriteMessage(KuscMessageParams.MESSAGE_GROUP group, KuscMessageParams.MESSAGE_REQUEST request, string data)
        {
            _serialSem.WaitOne();
            _txMessageBuffer.Clear();                            // Prepere sending list to contain new frame

            _txMessageBuffer.Add(KuscMessageParams.MSG_MAGIC_A); // First frame char contain magic.
            _txMessageBuffer.Add(Convert.ToChar(group));         // Second frame char contain group.
            _txMessageBuffer.Add(Convert.ToChar(request));       // Second frame char contain message request.
            _txMessageBuffer.Add(Convert.ToChar(data.Length));   // Third frame contain number of bytes of data.
            if (data != string.Empty)
            {
                foreach (char dataItem in data)
                {
                    if (dataItem >= 0x30) // Dont convert special sings.
                    {
                        char c = Convert.ToChar(Convert.ToInt32(dataItem) - 0x30);
                        _txMessageBuffer.Add(c);
                    }
                    else
                    {
                        _txMessageBuffer.Add(dataItem);
                    }
                }
            }

            // Calc CRC-8:
            char crc = KuscUtil.CalcCrc8(_txMessageBuffer.ToArray());

            _txMessageBuffer.Add(crc);

            // Now send the frame
            foreach (var item in _txMessageBuffer)
            {
                SerialWriteChar(item);
            }
            _serialSem.Release();
            return(true);
        }
        private static int ParseMessage(string msg)
        {
            int _rxReadByte = 0;

            cRxState = UART_READ_STATE.START_RX_MESSAGE_READ;

            while (true)
            {
                try
                {
                    switch (cRxState)
                    {
                    case UART_READ_STATE.START_RX_MESSAGE_READ:
                        _rxMsgBuffer.Clear();
                        _rxDataArray.Clear();
                        _rxReadByte = 0;
                        cRxState    = UART_READ_STATE.FIND_MAGIC;
                        break;

                    case UART_READ_STATE.FIND_MAGIC:

                        _rxReadByte++;
                        if (msg[KuscMessageParams.MSG_MAGIC_LOCATION] == KuscMessageParams.MSG_MAGIC_A)
                        {
                            _rxMsgBuffer.Add(msg[KuscMessageParams.MSG_MAGIC_LOCATION]);
                            cRxState = UART_READ_STATE.READ_GROUP;
                        }
                        else
                        {
                            return(_rxReadByte);
                        }

                        cRxState = UART_READ_STATE.READ_GROUP;
                        break;

                    case UART_READ_STATE.READ_GROUP:

                        _rxMsgBuffer.Add(msg[KuscMessageParams.MSG_GROUP_LOCATION]);
                        _rxReadByte++;
                        cRxState = UART_READ_STATE.READ_REQUEST;
                        break;

                    case UART_READ_STATE.READ_REQUEST:

                        _rxMsgBuffer.Add(msg[KuscMessageParams.MSG_REQUEST_LOCATION]);
                        cRxState = UART_READ_STATE.READ_DATA_SIZE;
                        _rxReadByte++;
                        break;

                    case UART_READ_STATE.READ_DATA_SIZE:

                        _rxMsgBuffer.Add(msg[KuscMessageParams.MSG_REQUEST_DATA_SIZE_LOCATION]);
                        cRxState = UART_READ_STATE.READ_DATA_SIZE;
                        _rxReadByte++;
                        if (msg[KuscMessageParams.MSG_REQUEST_DATA_SIZE_LOCATION] == 0x0)      // check if there is data to read.
                        {
                            cRxState = UART_READ_STATE.CHECK_CRC;
                        }
                        else
                        {
                            cRxState = UART_READ_STATE.READ_DATA;
                        }
                        break;

                    case UART_READ_STATE.READ_DATA:

                        int dataSize = Convert.ToInt32(msg[KuscMessageParams.MSG_REQUEST_DATA_SIZE_LOCATION]);
                        if (dataSize > msg.Length)
                        {
                            return(0);
                        }
                        for (int idx = 0; idx <= dataSize; idx++)
                        {
                            _rxDataArray.Add(msg[KuscMessageParams.MSG_REQUEST_DATA_LOCATION + idx]);
                        }
                        _rxReadByte += dataSize;
                        cRxState     = UART_READ_STATE.CHECK_CRC;
                        break;

                    case UART_READ_STATE.CHECK_CRC:
                        int  crcLocation = KuscMessageParams.MSG_REQUEST_DATA_LOCATION + Convert.ToInt32(msg[KuscMessageParams.MSG_REQUEST_DATA_SIZE_LOCATION]);
                        char crcGiven    = msg[crcLocation];
                        char crcCalc     = KuscUtil.CalcCrc8(msg.ToArray());
                        cRxState = UART_READ_STATE.JUMP_FUNCTION;
                        break;

                    case UART_READ_STATE.JUMP_FUNCTION:

                        _groups[msg[KuscMessageParams.MSG_GROUP_LOCATION] - 1]((KuscMessageParams.MESSAGE_REQUEST)msg[KuscMessageParams.MSG_REQUEST_LOCATION], string.Join(",", _rxDataArray.ToArray()));
                        cRxState = UART_READ_STATE.FINISH_ROUND;
                        break;

                    case UART_READ_STATE.FINISH_ROUND:
                        return(_rxReadByte);
                    }
                }
                catch (Exception)
                {
                }
            }
        }