/// <summary> /// This function gets message from the remote unit. /// </summary> /// <param name="Rxmsg">Received message</param> /// <param name="Txmsg">Transmited message, information about this frmae could be necessary to properly init received frame. /// </param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is imposible because of a communication error – loss of /// communication with a station /// ALRes_DisInd: Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result GetMessage(out ModBusMessage Rxmsg, ModBusMessage Txmsg) { Rxmsg = null; try { InterCharStopwatch.Reset(); InterCharStopwatch.Start(); if (!CheckCharTimeout(GetProtocolParameters.ResponseTimeOutSpan, InterCharStopwatch)) { GetIProtocolParent.IncStRxNoResponseCounter(); return(AL_ReadData_Result.ALRes_DatTransferErrr); } GetIProtocolParent.TimeMaxResponseDelayAdd(InterCharStopwatch.ElapsedMilliseconds); Rxmsg = m_Pool.GetEmptyISesDBuffer(); Rxmsg.userDataLength = Rxmsg.userBuffLength; Rxmsg.offset = 0; bool first = true; do { byte lastChar; InterCharStopwatch.Reset(); InterCharStopwatch.Start(); switch (GetICommunicationLayer.GetChar(out lastChar)) { case TGetCharRes.Success: if (!Rxmsg.WriteByte(lastChar)) { return(AL_ReadData_Result.ALRes_DatTransferErrr); } if (first) { first = false; } else { GetIProtocolParent.TimeCharGapAdd(CAS.Lib.RTLib.Processes.Timer.ToUSeconds(InterCharStopwatch.Elapsed)); } break; case TGetCharRes.DisInd: return(AL_ReadData_Result.ALRes_DisInd); } }while (CheckCharTimeout(((ModBus_ProtocolParameters)GetProtocolParameters).TimeoutCharacterSpan, InterCharStopwatch)); Rxmsg.userDataLength = Rxmsg.offset; Rxmsg.offset = 0; if (CheckCharTimeout(((ModBus_ProtocolParameters)GetProtocolParameters).TimeoutCharacterSpan, InterCharStopwatch)) { Flush(((ModBus_ProtocolParameters)GetProtocolParameters).InterframeGapSpan); Rxmsg.ReturnEmptyEnvelope(); Rxmsg = null; GetIProtocolParent.IncStRxFragmentedCounter(); return(AL_ReadData_Result.ALRes_DatTransferErrr); } return(AL_ReadData_Result.ALRes_Success); } catch (DisconnectException) { return(AL_ReadData_Result.ALRes_DisInd); } }
} //GetMessage /// <summary> /// Transmit message to the remote unit. /// </summary> /// <param name="Txmsg">Message to be transmitted</param> /// <returns> /// ALRes_Success: /// Operation accomplished successfully /// ALRes_DisInd: /// Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result TransmitMessage(MBUS_message Txmsg) { Flush(((MBUS_ProtocolParameters)GetProtocolParameters).InterframeGapSpan); GetIProtocolParent.IncStTxFrameCounter(); switch (GetICommunicationLayer.FrameEndSignal(Txmsg)) { case TFrameEndSignalRes.Success: break; case TFrameEndSignalRes.DisInd: return(AL_ReadData_Result.ALRes_DisInd); } return(AL_ReadData_Result.ALRes_Success); }
/// <summary> /// Transmit message to the remote unit. /// </summary> /// <param name="toSendMessage">Message to be transmitted</param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is imposible because of a communication error – loss of /// communication with a station /// ALRes_DisInd: Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result TransmitMessage(FrameStateMachine toSendMessage) { FrameStateMachine preparedToSend = m_Pool.GetEmptyISesDBuffer(); //tworzymy nowego message'a do wyslania- bedzie on zawieral dodatkowo bajty sumy kontrolna i wstawione znaki preparedToSend.PrepareFrameToBeSend(toSendMessage); switch (GetICommunicationLayer.FrameEndSignal(preparedToSend)) { case TFrameEndSignalRes.Success: GetIProtocolParent.IncStTxFrameCounter(); //uzupelniamy statystyki break; case TFrameEndSignalRes.DisInd: return(AL_ReadData_Result.ALRes_DisInd); } preparedToSend.ReturnEmptyEnvelope(); return(AL_ReadData_Result.ALRes_Success); }
/// <summary> /// Transmit message to the remote unit. /// </summary> /// <param name="message">Message to be transmitted</param> /// <returns> /// ALRes_Success: /// Operation accomplished successfully /// ALRes_DisInd: /// Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result TransmitMessage(ModBusMessage message) { try { Flush(((ModBus_ProtocolParameters)GetProtocolParameters).Timeout35Span); //flush may throw DisconnectException } catch (DisconnectException ex) { AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Information, 130, $"ModBusProtocol.TransmitMessage.Flush: exception has been caught {ex.Message}"); return(AL_ReadData_Result.ALRes_DisInd); } GetIProtocolParent.IncStTxFrameCounter(); switch (GetICommunicationLayer.FrameEndSignal(message)) { case TFrameEndSignalRes.Success: break; case TFrameEndSignalRes.DisInd: return(AL_ReadData_Result.ALRes_DisInd); } return(AL_ReadData_Result.ALRes_Success); }
/// <summary> ///This function gets message from the remote unit. /// </summary> /// <param name="cRxmsg">received message</param> /// <param name="cTxmsg">transmited message, information about this frmae are necessary for checking if this is correct answer</param> /// <param name="cInfinitewait">true if this function should wait infinite time for the first character - true for slave side , false in master </param> /// <param name="cStation_addrress">address of station - When this function is used by slavet</param> /// <param name="cReset">the value is set to true if we expected response, but have gor request - we must reset and wait for response </param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is imposible because of a communication error – loss of /// communication with a station /// ALRes_DisInd: Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> private AL_ReadData_Result GetMessage(out FrameStateMachine cRxmsg, FrameStateMachine cTxmsg, bool cInfinitewait, int cStation_addrress, ref bool cReset) { IntercharStopwatch.StartReset(); TimeSpan currTimeOut; if (!cInfinitewait) { currTimeOut = this.GetProtocolParameters.ResponseTimeOutSpan; } else { currTimeOut = TimeSpan.MaxValue; } RecStateEnum currRecState = RecStateEnum.RSE_BeforeHeading; cRxmsg = m_Pool.GetEmptyISesDBuffer(); cRxmsg.InitMsg(cTxmsg); bool continueDo = true; bool flushWait = false; do { RecEventEnum lastRecEvent = RecEventEnum.REE_TimeOut; byte lastChar; switch (GetICommunicationLayer.GetChar(out lastChar, Convert.ToInt32(currTimeOut.TotalMilliseconds))) { case TGetCharRes.Success: switch (cRxmsg.DepositeChar(lastChar)) { case FrameStateMachine.DepCharacterTypeEnum.DCT_Last: lastRecEvent = RecEventEnum.REE_NewCharLastOne; break; case FrameStateMachine.DepCharacterTypeEnum.DCT_Reset_Answer: GetIProtocolParent.IncStRxSynchError(); //wrong frame type so synchronization error must be monitored cReset = true; lastRecEvent = RecEventEnum.REE_NewChar; break; case FrameStateMachine.DepCharacterTypeEnum.DCT_Ordinary: lastRecEvent = RecEventEnum.REE_NewChar; break; case FrameStateMachine.DepCharacterTypeEnum.DCT_SOH: lastRecEvent = RecEventEnum.REE_NewCharSOH; break; } break; case TGetCharRes.Timeout: lastRecEvent = RecEventEnum.REE_TimeOut; break; case TGetCharRes.DisInd: cRxmsg.ReturnEmptyEnvelope(); cRxmsg = null; AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Verbose, 115, $"SBUSProtocol.GetMessage(): {nameof(TGetCharRes.DisInd)} has occured during receiving frame, I am exitting the receiving loop and returning AL_ReadData_Result.ALRes_DisInd"); return(AL_ReadData_Result.ALRes_DisInd); } switch (currRecState) { case RecStateEnum.RSE_BeforeHeading: { #region RecStateEnum.RSE_BeforeHeading switch (lastRecEvent) { case RecEventEnum.REE_NewChar: break; case RecEventEnum.REE_NewCharSOH: { currRecState = RecStateEnum.RSE_InsideFrame; GetIProtocolParent.TimeMaxResponseDelayAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_ms(IntercharStopwatch.Reset))); currTimeOut = ((SBUS_ProtocolParameters)GetProtocolParameters).TimeoutSpanAfterFrame; break; } case RecEventEnum.REE_TimeOut: GetIProtocolParent.IncStRxNoResponseCounter(); cRxmsg.ReturnEmptyEnvelope(); cRxmsg = null; AssemblyTraceEvent.Tracer.TraceEvent ( TraceEventType.Verbose, 137, "SBUSProtocol.GetMessage():RecStateEnum.RSE_BeforeHeading: RecEventEnum.REE_TimeOut has occurred during receiving frame, I am exiting the receiving loop with AL_ReadData_Result.ALRes_DatTransferErrr" ); return(AL_ReadData_Result.ALRes_DatTransferErrr); } ; break; #endregion } case RecStateEnum.RSE_InsideFrame: { #region RecStateEnum.RSE_InsideFrame switch (lastRecEvent) { case RecEventEnum.REE_NewChar: GetIProtocolParent.TimeCharGapAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_us(IntercharStopwatch.Reset))); break; case RecEventEnum.REE_NewCharLastOne: GetIProtocolParent.TimeCharGapAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_us(IntercharStopwatch.Reset))); continueDo = false; break; case RecEventEnum.REE_TimeOut: if (flushWait) { AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Information, 200, "SBUSProtocol.GetMessage(): Timeout has occurred during receiving frame, I am emitting the receiving loop"); continueDo = false; break; } else { currTimeOut = ((SBUS_ProtocolParameters)GetProtocolParameters).TimeoutSpanAfterFrame; flushWait = true; break; } } ; break; #endregion } } }while (continueDo); return(AL_ReadData_Result.ALRes_Success); }//GetMessage
/// <summary> /// This function gets message from the remote unit. /// </summary> /// <param name="receiveMessage">Received message</param> /// <param name="transmitMessage">Transited message, information about this frame could be necessary to properly initialize received frame. /// </param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is imposable because of a communication error – loss of /// communication with a station /// ALRes_DisInd: Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result GetMessage(out ModBusMessage receiveMessage, ModBusMessage transmitMessage) { receiveMessage = null; try { InterCharStopwatch.Reset(); InterCharStopwatch.Start(); if (!CheckCharTimeout(GetProtocolParameters.ResponseTimeOutSpan, InterCharStopwatch)) { GetIProtocolParent.IncStRxNoResponseCounter(); return(AL_ReadData_Result.ALRes_DatTransferErrr); } GetIProtocolParent.TimeMaxResponseDelayAdd(InterCharStopwatch.ElapsedMilliseconds); receiveMessage = m_Pool.GetEmptyISesDBuffer(); receiveMessage.userDataLength = receiveMessage.userBuffLength; receiveMessage.offset = 0; bool first = true; do { byte lastChar; InterCharStopwatch.Reset(); InterCharStopwatch.Start(); switch (GetICommunicationLayer.GetChar(out lastChar)) { case TGetCharRes.Success: if (!receiveMessage.WriteByte(lastChar)) { AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Warning, 77, "ModBusProtocol.GetMessage: cannot write character received from the Communication Layer"); return(AL_ReadData_Result.ALRes_DatTransferErrr); } if (first) { first = false; } else { GetIProtocolParent.TimeCharGapAdd(CAS.Lib.RTLib.Processes.Timer.ToUSeconds(InterCharStopwatch.Elapsed)); } break; case TGetCharRes.DisInd: return(AL_ReadData_Result.ALRes_DisInd); } }while (CheckCharTimeout(((ModBus_ProtocolParameters)GetProtocolParameters).Timeout15Span, InterCharStopwatch)); receiveMessage.userDataLength = receiveMessage.offset; receiveMessage.offset = 0; if (CheckCharTimeout(((ModBus_ProtocolParameters)GetProtocolParameters).Timeout35Span, InterCharStopwatch)) { Flush(((ModBus_ProtocolParameters)GetProtocolParameters).Timeout35Span); receiveMessage.ReturnEmptyEnvelope(); receiveMessage = null; GetIProtocolParent.IncStRxFragmentedCounter(); return(AL_ReadData_Result.ALRes_DatTransferErrr); } return(AL_ReadData_Result.ALRes_Success); } catch (DisconnectException) { return(AL_ReadData_Result.ALRes_DisInd); } }
/// <summary> /// This function gets message from the remote unit. /// </summary> /// <param name="Rxmsg">Received message</param> /// <param name="Txmsg">Transmited message, information about this frmae could be necessary to properly init received frame. /// </param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is imposible because of a communication error – loss of /// communication with a station /// ALRes_DisInd: Disconnect indication – connection has been shut down remotely or lost because of /// communication error. Data is unavailable /// </returns> protected override AL_ReadData_Result GetMessage(out MBUS_message Rxmsg, MBUS_message Txmsg) { int QuantityOfByteInMessage = 0; bool cInfinitewait = false; IntercharStopwatch.StartReset(); TimeSpan currTimeOut; if (!cInfinitewait) { currTimeOut = this.GetProtocolParameters.ResponseTimeOutSpan; } else { currTimeOut = TimeSpan.MaxValue; } RecStateEnum currRecState = RecStateEnum.RSE_BeforeHeading; Rxmsg = m_Pool.GetEmptyISesDBuffer(); Rxmsg.InitMsg(Txmsg); bool continueDo = true; bool flushWait = false; do { RecEventEnum lastRecEvent = RecEventEnum.REE_TimeOut; byte lastChar; switch (GetICommunicationLayer.GetChar(out lastChar, Convert.ToInt32(currTimeOut.TotalMilliseconds))) { case TGetCharRes.Success: switch (Rxmsg.DepositeChar(lastChar)) { case DepCharacterTypeEnum.DCT_Last: lastRecEvent = RecEventEnum.REE_NewCharLastOne; break; case DepCharacterTypeEnum.DCT_Reset_Answer: GetIProtocolParent.IncStRxSynchError(); //dostalismy ramke nie taka jak trzeba wiec ustawiamy blad jako blad synchronizacji lastRecEvent = RecEventEnum.REE_NewChar; break; case DepCharacterTypeEnum.DCT_Ordinary: lastRecEvent = RecEventEnum.REE_NewChar; break; case DepCharacterTypeEnum.DCT_SOH: lastRecEvent = RecEventEnum.REE_NewCharSOH; break; } QuantityOfByteInMessage++; break; case TGetCharRes.Timeout: lastRecEvent = RecEventEnum.REE_TimeOut; break; case TGetCharRes.DisInd: Rxmsg.ReturnEmptyEnvelope(); return(AL_ReadData_Result.ALRes_DisInd); } switch (currRecState) { case RecStateEnum.RSE_BeforeHeading: { #region RecStateEnum.RSE_BeforeHeading switch (lastRecEvent) { case RecEventEnum.REE_NewChar: break; case RecEventEnum.REE_NewCharSOH: { currRecState = RecStateEnum.RSE_InsideFrame; GetIProtocolParent.TimeMaxResponseDelayAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_ms(IntercharStopwatch.Reset))); currTimeOut = ((MBUS_ProtocolParameters)GetProtocolParameters).CharacterTimeoutSpan; break; } case RecEventEnum.REE_TimeOut: GetIProtocolParent.IncStRxNoResponseCounter(); Rxmsg.ReturnEmptyEnvelope(); Rxmsg = null; return(AL_ReadData_Result.ALRes_DatTransferErrr); } ; break; #endregion } case RecStateEnum.RSE_InsideFrame: { #region RecStateEnum.RSE_InsideFrame switch (lastRecEvent) { case RecEventEnum.REE_NewChar: GetIProtocolParent.TimeCharGapAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_us(IntercharStopwatch.Reset))); break; case RecEventEnum.REE_NewCharLastOne: GetIProtocolParent.TimeCharGapAdd((long)(CAS.Lib.RTLib.Processes.Stopwatch.ConvertTo_us(IntercharStopwatch.Reset))); continueDo = false; break; case RecEventEnum.REE_TimeOut: if (flushWait) { continueDo = false; break; } else { currTimeOut = ((MBUS_ProtocolParameters)GetProtocolParameters).ResponseTimeOutSpan;//TimeoutAfterFrameTicks; flushWait = true; break; } } ; break; #endregion } } }while (continueDo); return(AL_ReadData_Result.ALRes_Success); } //GetMessage