BinExchangeChar GetByte(byte ch)
        {
            BinExchangeChar ret;

            if (PrevMagicChar == false)
            {
                if (ch != MAGIC_SYMBOL)
                {
                    ret           = new BinExchangeChar(false, true, ch); //Не спец. симпол, просто данные
                    PrevMagicChar = false;
                }
                else
                {
                    ret           = new BinExchangeChar(false, false, ch); //Спец. символ, ждем следующий
                    PrevMagicChar = true;
                }
            }
            else
            {
                if (ch != MAGIC_SYMBOL)
                {
                    ret           = new BinExchangeChar(true, false, ch); //Начало пакета
                    PrevMagicChar = false;
                }
                else
                {
                    ret           = new BinExchangeChar(false, true, ch); //Экранирование спец. символа
                    PrevMagicChar = false;
                }
            }
            return(ret);
        }
        public BinExchangePackage Parse(byte ch)
        {
            BinExchangeChar dta = GetByte(ch);

            switch (state)
            {
            case States.MAIN:     //ищем начало пакета
                if (dta.Start)    //если нашли начало пакета
                {
                    pack        = new BinExchangePackage();
                    DataCounter = 0;
                    state       = States.GET_HEADER;
                }
                break;

            ///////////////////////////
            case States.GET_HEADER:       //Читаем заголовок
                if (dta.CharDetect)       //если прочли символ
                {
                    if (DataCounter == 0) //если читаем 1-й байт
                    {
                        pack.Len = dta.Ch;
                        DataCounter++;
                    }
                    else
                    {
                        pack.Len   |= (UInt16)(dta.Ch << 8);
                        DataCounter = 0;

                        if (pack.Len > max_len)    //пакет слишком большой
                        {
                            DropsIncr();

                            pack.Status = BinExchangePackage.StatusCodes.PACK_TOO_LONG;
                            state       = States.MAIN;
                            return(pack);
                        }
                        else if (pack.Len > 0)     //если пакет не пустой
                        {
                            pack.Data = new byte[pack.Len];
                            state     = States.GET_DATA;
                        }
                        else
                        {
                            state = States.GET_CRC;
                        }
                    }
                }
                else if (dta.Start)    //если обнаружили начало пакета, хотя тут должен быть заголовок
                {
                    DropsIncr();

                    //начинаем сначала
                    pack        = new BinExchangePackage();
                    DataCounter = 0;
                    state       = States.GET_HEADER;
                }
                break;

            ///////////////////////////
            case States.GET_DATA:     //Читаем данные
                if (dta.CharDetect)   //если прочли символ
                {
                    pack.Data[DataCounter] = dta.Ch;
                    DataCounter++;
                    if (DataCounter >= pack.Len)    //если прочли все
                    {
                        DataCounter = 0;
                        state       = States.GET_CRC;
                    }
                }
                else if (dta.Start)     //если обнаружили начало пакета, хотя тут должны быть данные
                {
                    DropsIncr();

                    //начинаем сначала
                    pack        = new BinExchangePackage();
                    DataCounter = 0;
                    state       = States.GET_HEADER;
                }
                break;

            ///////////////////////////
            case States.GET_CRC:          //принимаем CRC
                if (dta.CharDetect)       //если прочли символ
                {
                    if (DataCounter == 0) //если читаем 1-й байт
                    {
                        pack.crc16 = dta.Ch;
                        DataCounter++;
                    }
                    else
                    {
                        pack.crc16 |= (UInt16)(dta.Ch << 8);
                        DataCounter = 0;

                        ///// ToDo: добавить ошибку CRC

                        //Проверяем CRC
                        if (Crc16(pack.Data, pack.Len) == pack.crc16)
                        {
                            state       = States.MAIN;
                            pack.Status = BinExchangePackage.StatusCodes.OK;
                            return(pack);
                        }
                        else
                        {
                            DropsIncr();

                            pack.Status = BinExchangePackage.StatusCodes.CRC_ERROR;
                            state       = States.MAIN;
                            return(pack);
                        }
                    }
                }
                else if (dta.Start)     //если обнаружили начало пакета, хотя тут должен быть заголовок
                {
                    DropsIncr();

                    //начинаем сначала
                    pack        = new BinExchangePackage();
                    DataCounter = 0;
                    state       = States.GET_HEADER;
                }
                break;
            }

            return(null);
        }