/// <summary> /// Reads process data from the selected location and device resources. /// </summary> /// <param name="pBlock"><see cref="T:CAS.Lib.CommonBus.ApplicationLayer.IBlockDescription" /> selecting the resource containing the data block to be read.</param> /// <param name="pStation">Address of the remote station connected to the common field bus. –1 if not applicable.</param> /// <param name="pData">The buffer <see cref="T:CAS.Lib.CommonBus.ApplicationLayer.IReadValue" /> containing the requested data.</param> /// <param name="pRetries">Number of retries to get data.</param> /// <returns>Result of the operation</returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public AL_ReadData_Result ReadData(IBlockDescription pBlock, int pStation, out IReadValue pData, byte pRetries) { pData = null; if (pBlock.dataType != 0) { TraceSource.TraceMessage(TraceEventType.Error, 149, $"Wrong dataType: {pBlock.dataType}; only data type = 0 is expected"); m_statistic.IncStRxInvalid(); } if (!Connected) { TraceSource.TraceMessage(TraceEventType.Verbose, 165, $"ReadData failed because it is not connected; retries/limit={m_RetryCount}/{this.m_TextReaderProtocolParameters.MaxNumberOfRetries}."); return(AL_ReadData_Result.ALRes_DisInd); } m_statistic.IncStTxFrameCounter(); IDataEntity _copy = Interlocked.Exchange <IDataEntity>(ref m_Fifo, m_Fifo); bool _retResult = _copy != null; m_statistic.RxDataBlock(_retResult); if (!_retResult) { m_statistic.IncStRxNoResponseCounter(); TraceSource.TraceMessage(TraceEventType.Information, 186, $"ReadData failed; retries/limit={m_RetryCount}/{this.m_TextReaderProtocolParameters.MaxNumberOfRetries}."); return(AL_ReadData_Result.ALRes_DatTransferErrr); } m_statistic.IncStRxFrameCounter(); pData = new ReadDataEntity(_copy, pBlock); TraceSource.TraceMessage(TraceEventType.Verbose, 191, $"ReadData succeeded for [{pStation}/{pBlock.startAddress}]"); return(AL_ReadData_Result.ALRes_Success); }
/// <summary> /// Transits frame and gets response. Response is analyzed to much the sent frame. /// </summary> /// <param name="Txmsg">Frame to be sent.</param> /// <param name="Rxmsg">Received frame</param> /// <param name="cRetries">Number of retries to get frame from remote unit.</param> /// <returns> /// ALRes_Success: Operation accomplished successfully /// ALRes_DatTransferErrr: Data transfer is impossible 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 TxGetResponse(T_ALMessage Txmsg, out T_ALMessage Rxmsg, byte cRetries) { Rxmsg = null; TGRState currState = TGRState.TxReq; if (Txmsg == null) { AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Information, 83, "ApplicationLayerMaster.TxGetResponse - Transmitted message cannot be null."); return(AL_ReadData_Result.ALRes_DatTransferErrr); } while (true) { switch (currState) { case TGRState.TxReq: Timer.WaitTimeout(m_protocol.GetProtocolParameters.InterframeGapSpan, InterfrarmeStopwatch); switch (m_protocol.TransmitMessage(Txmsg)) { case AL_ReadData_Result.ALRes_Success: currState = TGRState.RxRes; break; case AL_ReadData_Result.ALRes_DisInd: return(AL_ReadData_Result.ALRes_DisInd); case AL_ReadData_Result.ALRes_DatTransferErrr: return(AL_ReadData_Result.ALRes_DatTransferErrr); } break; case TGRState.RxRes: if (Txmsg == null) { AssemblyTraceEvent.Tracer.TraceEvent(TraceEventType.Information, 105, "ApplicationLayerMaster.TxGetResponse - Before: m_protocol.GetMessage( out Rxmsg, Txmsg ): Transmitted message cannot be null."); return(AL_ReadData_Result.ALRes_DatTransferErrr); } AL_ReadData_Result res = m_protocol.GetMessage(out Rxmsg, Txmsg); InterfrarmeStopwatch.Reset(); InterfrarmeStopwatch.Start(); switch (res) { case AL_ReadData_Result.ALRes_Success: InterfrarmeStopwatch.Reset(); InterfrarmeStopwatch.Start(); ProtocolALMessage.CheckResponseResult lastCheckResult = Rxmsg.CheckResponseFrame(Txmsg); switch (lastCheckResult) { case ProtocolALMessage.CheckResponseResult.CR_OK: m_Statistic.IncStRxFrameCounter(); return(AL_ReadData_Result.ALRes_Success); case ProtocolALMessage.CheckResponseResult.CR_SynchError: m_Statistic.IncStRxSynchError(); break; case ProtocolALMessage.CheckResponseResult.CR_Incomplete: m_Statistic.IncStRxFragmentedCounter(); break; case ProtocolALMessage.CheckResponseResult.CR_CRCError: m_Statistic.IncStRxCRCErrorCounter(); break; case ProtocolALMessage.CheckResponseResult.CR_Invalid: m_Statistic.IncStRxInvalid(); break; case ProtocolALMessage.CheckResponseResult.CR_NAK: m_Statistic.IncStRxNAKCounter(); break; } if (!((IEnvelope)Rxmsg).InPool) { Rxmsg.ReturnEmptyEnvelope(); } Rxmsg = null; currState = TGRState.Retray; break; //return AL_ReadData_Result.ALRes_DatTransferErrr; case AL_ReadData_Result.ALRes_DisInd: if (Rxmsg != null) { if (!((IEnvelope)Rxmsg).InPool) { Rxmsg.ReturnEmptyEnvelope(); } Rxmsg = null; } return(AL_ReadData_Result.ALRes_DisInd); default: currState = TGRState.Retray; break; } break; case TGRState.Retray: if (Rxmsg != null) { if (!((IEnvelope)Rxmsg).InPool) { Rxmsg.ReturnEmptyEnvelope(); } Rxmsg = null; } if (cRetries == 0) { return(AL_ReadData_Result.ALRes_DatTransferErrr); } cRetries--; currState = TGRState.TxReq; break; } }//while (true) }