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