private void ClearReadBufferBeforeCurrentPosition() { MemoryStream TempStream = new MemoryStream(); ReadBuffer.CopyTo(TempStream); ReadBuffer.Dispose(); ReadBuffer = TempStream; }
/// <summary> /// Отправка запроса к счетчику и получение данных /// </summary> /// <param name="Query">Запрос к счетчику в формате массива L1</param> /// <param name="Answer">Ответ счетчика в формате массива L1</param> /// <return>Успех</return>> public void OblikQuery(byte[] Query, out byte[] Answer) { bool success = false; //Флаг успеха операции SerialPort com = null; try { com = new SerialPort { PortName = "COM" + _ConParams.Port.ToString(), BaudRate = _ConParams.Baudrate.Value, Parity = Parity.None, DataBits = 8, StopBits = StopBits.One, ReadTimeout = 500, WriteTimeout = 500, DtrEnable = false, RtsEnable = false, Handshake = Handshake.None }; Answer = null; try { com.Open(); } catch (Exception e) { ChangeIOStatus(e.Message); throw new OblikIOException(e.Message); } int r = _ConParams.Repeats.Value; ChangeCmdStatus(StringsTable.SendReq); while ((r > 0) && (!success)) //Повтор при ошибке { com.DiscardOutBuffer(); //очистка буфера передачи com.DiscardInBuffer(); //очистка буфера приема try { if (Query == null) { throw new ArgumentNullException(paramName: nameof(Query)); } com.Write(Query, 0, Query.Length); } catch (Exception e) { ChangeIOStatus(e.Message); throw new OblikIOException(e.Message); } try { Answer = new byte[2]; r--; //Получение результата L1 ReadAnswer(com, _ConParams.Timeout.Value, 1, out byte[] ReadBuffer); Answer[0] = ReadBuffer[0]; if (Answer[0] != 1) { throw new OblikIOException(ParseChannelError(Answer[0])); } //Получение количества байт в ответе ReadAnswer(com, _ConParams.Timeout.Value, 1, out ReadBuffer); Answer[1] = ReadBuffer[0]; int len = ReadBuffer[0] + 1; Array.Resize(ref Answer, len + 2); //Получение всего ответа ReadAnswer(com, (int)(_ConParams.Timeout.Value / 5u), len, out ReadBuffer); ReadBuffer.CopyTo(Answer, 2); success = (ReadBuffer.Length == len); if (Answer[2] != 0) { throw new OblikIOException(ParseSegmentError(Answer[2])); } //Проверка контрольной суммы byte cs = 0; for (int i = 0; i < Answer.Length; i++) { cs ^= Answer[i]; } if (cs != 0) { throw new OblikIOException(StringsTable.CSCError); } } catch (Exception e) { success = false; ChangeIOStatus(e.Message); } } } finally { if (com != null) { com.Dispose(); } } if (!success) { ChangeIOStatus(StringsTable.ReqError); throw new OblikIOException(StringsTable.QueryErr); } }
bool IResponse.Read(ReadBuffer stream) { Span <byte> start; switch (state) { case STATE_INIT: headerOwned = allocator.Rent(Protocol.HeaderLength); // make it exactly HeaderLength long for bound checks header = headerOwned.Memory.Take(Protocol.HeaderLength); state = STATE_READ_HEADER; goto case STATE_READ_HEADER; case STATE_READ_HEADER: Debug.Assert(headerOwned != null); start = header.Span; dataReadOffset += stream.CopyTo(start.Slice(dataReadOffset)); Debug.Assert(dataReadOffset <= Protocol.HeaderLength); if (dataReadOffset < Protocol.HeaderLength) { return(true); // continue reading } Debug.Assert(dataReadOffset == Protocol.HeaderLength); try { if (!ProcessHeader(start)) { goto case STATE_DONE; // response has no body } } finally { headerOwned.Dispose(); headerOwned = null; } dataReadOffset = 0; state = STATE_READ_BODY; goto case STATE_READ_BODY; case STATE_READ_BODY: start = body.Span; dataReadOffset += stream.CopyTo(start.Slice(dataReadOffset)); Debug.Assert(dataReadOffset <= start.Length); if (dataReadOffset < start.Length) { return(true); // not done yet } Debug.Assert(dataReadOffset == start.Length); goto case STATE_DONE; case STATE_DONE: state = STATE_DONE; break; } return(false); }