/// <summary> /// prepare a telegram /// </summary> /// <param name="station">station that shoud received telegram</param> /// <param name="block">block description to be written</param> protected override void PrepareReqWriteValue(IBlockDescription block, int station) { if ((Medium_T)block.dataType == Medium_T.Input) { string _msg = "Input is read only resource"; TraceEvent(TraceEventType.Information, 192, _msg); throw new ArgumentException(_msg, "block"); } PrepareFrameHeader(station, block, Definitions.DataType2SbusCode4Write((Medium_T)block.dataType)); offset = (ushort)(m_DataTypePos + CmdLength); Debug.Assert(offset == regCountPos); WriteByte((byte)(userDataLength - offset - W_countLength - 1)); //<w-count> WriteInt16((short)(block.startAddress)); //<address-RTC>, <address-IOF>, <text-number> switch (DataType) { case SbusCode.coWriteFlag: case SbusCode.coWriteOutput: WriteByte((byte)block.length); //<fio-count> break; case SbusCode.coWriteRegister: case SbusCode.coWriteTimer: case SbusCode.coWriteCounter: break; case SbusCode.coWriteText: WriteInt16(0); //<char-position> break; default: break; } }
AL_ReadData_Result IApplicationLayerSlave.ReadCMD(out IBlockDescription command, int address, out ProtocolCmd cmd, out IReadCMDValue frame) { command = null; cmd = ProtocolCmd.coRR; frame = null; return(AL_ReadData_Result.ALRes_DisInd); //not implemented }
/// <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> /// Gets a buffer from a pool and initiates it. After filling it up with the data can be send to the data provider remote /// unit by the WriteData. /// </summary> /// <param name="block">Data description allowing to prepare appropriate header of the frame.</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <returns>A buffer ready to be filled up with the data and write down to the destination – remote station. /// </returns> IWriteValue IApplicationLayerMaster.GetEmptyWriteDataBuffor(IBlockDescription block, int station) { T_ALMessage frame = m_Pool.GetEmptyISesDBuffer(); frame.PrepareReqWriteValue(block, station); return(frame); }
ApplicationLayerResults IApplicationLayerSlave.ReadCMD(out IBlockDescription command, int address, out ProtocolCmd cmd, out IReadCMDValue frame) { command = null; cmd = ProtocolCmd.coRR; frame = null; return(ApplicationLayerResults.ConnectionFails); //not implemented }
/// <summary> /// Assigns description of the block of data to the message. /// </summary> /// <param name="station"></param> /// <param name="block"></param> public virtual void SetBlockDescription(int station, IBlockDescription block) { currStation = station; currBlockStartAddress = block.startAddress; currDataType = block.dataType; currBlockLength = block.length; }
/// <summary> /// Read Data /// </summary> /// <param name="block">Block description to be read</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <param name="data">The buffer with the requested data.</param> /// <param name="retries">Number of retries to get data.</param> /// <returns>Result of the operation</returns> AL_ReadData_Result IApplicationLayerMaster.ReadData(IBlockDescription block, int station, out IReadValue data, byte retries) { lock (this) { m_rPackNum++; data = null; myStatistic.IncStTxFrameCounter(); if ((m_errorfrequency > 0) && (m_rPackNum % (ulong)m_errorfrequency == 0)) { myStatistic.IncStRxFragmentedCounter(); myStatistic.RxDataBlock(false); return(AL_ReadData_Result.ALRes_DatTransferErrr); } data = (IReadValue)pool.GetEmptyISesDBuffer(); // Processes.Timer.Wait(Processes.Timer.TInOneSecond/4); ((NULL_message)data).SetBlockDescription(station, block); ((NULL_message)data).ReadFromDB(); bool success = true; if (CommunicationThroughCommunicationLayer) { success = SendReceive(); } if (success) { myStatistic.IncStRxFrameCounter(); } myStatistic.RxDataBlock(success); return(AL_ReadData_Result.ALRes_Success); } }
public virtual bool WriteData(object data, IBlockDescription dataAddress, Interface pipeInterface) { this.myMachine.ClearCounter(); myMachine.myStatistics.NewState = Statistics.SegmentStatistics.States.WriteWaitingToBeConn; myOnExitCondition.Wait(myMachine); return(myMachine.CurrentSegmentState.WriteData(data, dataAddress, pipeInterface)); }
/// <summary> /// Read Data /// </summary> /// <param name="block">Block description to be read</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <param name="data">The frame with the requested data.</param> /// <param name="retries">Number of retries to get data.</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> AL_ReadData_Result IApplicationLayerMaster.ReadData (IBlockDescription block, int station, out IReadValue data, byte retries) { data = null; if (!m_protocol.GetICommunicationLayer.Connected) { return(AL_ReadData_Result.ALRes_DisInd); } T_ALMessage request = m_Pool.GetEmptyISesDBuffer(); T_ALMessage response; request.PrepareRequest(station, block); AL_ReadData_Result res = TxGetResponse(request, out response, retries); if (res == AL_ReadData_Result.ALRes_Success) { response.SetBlockDescription(station, block); data = (IReadValue)response; } else if (response != null && !((IEnvelope)response).InPool) { EventLogMonitor.WriteToEventLogInfo("TxGetResponse has failed and response != null && !( (IEnvelope)response ).InPool", 195); response.ReturnEmptyEnvelope(); } request.ReturnEmptyEnvelope(); m_protocol.GetIProtocolParent.RxDataBlock(res == AL_ReadData_Result.ALRes_Success); return(res); }
public IWriteValue GetEmptyWriteDataBuffor(IBlockDescription block, int station) { Assert.IsTrue(myConnected, "Must be connected while GetEmptyWriteDataBuffor"); MonitorEnter(); MonitorExit(); Assert.IsTrue(myNumberOfFacadeWriteValue == 0, "It seems a buffer is not returned to the pool before next write"); return(new FacadeWriteValue(this)); }
IResponseValue IApplicationLayerSlave.GetEmptySendDataBuffor (IBlockDescription block, int station) { SBUSbase_message frame = m_Pool.GetEmptyISesDBuffer(); frame.PrepareDataResponse(block); return(frame); }
protected override void PrepareFrameHeader(int station, IBlockDescription block, SbusCode code) { base.PrepareFrameHeader(station, block, code); this.FRAMELENGTH = userDataLength + CRCLength; this.SetStandardVersion(); this.SetStandardProtocolType(); this.SEQUENCE_NUMBER = sequencenumber++; }
protected override void PrepareRequest(int station, IBlockDescription block) { userDataLength = RequestLength; // stała długośc zapytania this.station = (byte)station; registers32AreUsed = false; //by default 16 bit registers are used, this variable as true is used only as extension switch ((Medium_T)block.dataType) { case Medium_T.Holding_32bit_register: dataType = Modbus_Functions.READ_HOLDING_REGISTERS; RegisterInFrame = true; registers32AreUsed = true; break; case Medium_T.Holding_register: dataType = Modbus_Functions.READ_HOLDING_REGISTERS; RegisterInFrame = true; break; case Medium_T.Input_register: dataType = Modbus_Functions.READ_INPUT_REGISTER; RegisterInFrame = true; break; case Medium_T.Holding_8bit_register_CONTROL: //CONTROL Micro XL extension dataType = Modbus_Functions.READ_HOLDING_REGISTERS_8BIT_CONTROL; RegisterInFrame = true; break; case Medium_T.Register_MemoryBank_CONTROL: //CONTROL Micro XL extension dataType = Modbus_Functions.READ_MEMORYBANK_CONTROL; bank = (byte)((block.startAddress & 0xFF0000) >> 16); RegisterInFrame = true; userDataLength++; // request for bank is longer than standard request (1 byte - bank number) break; case Medium_T.Coil: dataType = Modbus_Functions.READ_COILS; RegisterInFrame = false; break; case Medium_T.Discrete_input: dataType = Modbus_Functions.READ_DISCRETE_INPUT; RegisterInFrame = false; break; default: throw new NotImplementedException("Not yet implemented"); } address = (short)(block.startAddress & 0xFFFF); //MODBUS uses two byte addressing in case of 32 bit register the request quality is different if ((Medium_T)block.dataType == Medium_T.Holding_32bit_register) { reqQuantity = (short)((block.length * 2) & 0xFFFF); } else { reqQuantity = (short)(block.length & 0xFFFF); //MODBUS uses two byte length } }
protected override void PrepareRequest(int station, IBlockDescription block) { string request = String.Format("REQ;" + excelDDEItemBlock, block.startAddress, block.dataType, block.startAddress + block.length - 1, block.dataType); userDataLength = (ushort)request.Length; this.WriteString(request); this.SetBlockDescription(station, block); }
/// <summary> /// Gets a buffer from a pool and initiates it. After filling it up with the data can be send to the data provider remote /// unit by the WriteData. /// </summary> /// <param name="block">Data description allowing to prepare appropriate header of the frame.</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <returns>A buffer ready to be filled up with the data and write down to the destination – remote station. /// </returns> IWriteValue IApplicationLayerMaster.GetEmptyWriteDataBuffor(IBlockDescription block, int station) { lock (this) { NULL_message data = (NULL_message)pool.GetEmptyISesDBuffer(); data.SetBlockDescription(station, block); return((IWriteValue)data); } }
protected override void PrepareReqWriteValue(IBlockDescription block, int station) { base.PrepareReqWriteValue(block, station); //MBAP header: TransactionIdentifier = TransactionIdentifierCouter++; ProtocolIdentifierOffset = 0; this.offset = const_LengthOffset; myAssert.Assert(this.WriteInt16((short)(RequestLength - 6)), 151, "ModBUS: PrepareReqWriteValue: Cannot write RequestLength - 6");// nie wliczamy do tego poczatku naglowka }
protected override void PrepareRequest(int station, IBlockDescription block) { base.PrepareRequest(station, block); offset = 6; if (dataType == Modbus_Functions.READ_MEMORYBANK_CONTROL) //CONTROL Micro XL extension { offset++; //in READ_MEMORYBANK_CONTROL there is one additional field (Bank) before CRC } PutCRC16(); }
IResponseValue IApplicationLayerSlave.GetEmptySendDataBuffor(IBlockDescription block, int address) { return(null); // MBUS_message frame = (MBUS_message)pool.GetEmptyISesDBuffer(); // frame.dataType = (byte)block.dataType; // frame.address = System.Convert.ToInt16(block.startAddress); // if (((int)block.dataType >= 10) && ((int)block.dataType <= 15)) // frame.regCount = System.Convert.ToInt16(((block.length * 4) + 4)); // else frame.regCount = System.Convert.ToInt16( block.length); // return frame; }
bool IDataWrite.WriteData(object data, IBlockDescription addresss) { if (currInterfaceNum < 0) return false; bool result = interfaces[currInterfaceNum].WriteData(data, addresss); if (result) interfaces[currInterfaceNum].Retries.MarkSuccess(); else interfaces[currInterfaceNum].Retries.MarkFail(); return result; }
/// <summary> /// Initializes a new instance of the <see cref="ReadDataEntity"/> class and copies data from the <paramref name="dataBuffer"/> selected by the <paramref name="block"/>. /// </summary> /// <param name="dataBuffer">The data buffer holding source data.</param> /// <param name="block">The data block description to retrieved from the <paramref name="dataBuffer"/>.</param> public ReadDataEntity(IDataEntity dataBuffer, IBlockDescription block) { startAddress = block.startAddress; dataType = block.dataType; length = block.length; Tags = new string[block.length]; for (int i = 0; i < Tags.Length; i++) { Tags[i] = dataBuffer.Tags[i + block.startAddress]; } }
/// <summary> /// Gets a buffer from a pool and initiates. After filling it up with the data can be send to the data provider remote /// unit by the <see cref="WriteData"/>. /// </summary> /// <param name="block"><see cref="IBlockDescription"/> selecting the resource where the data block is to be written.</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable.</param> /// <returns> /// A buffer <see cref="IWriteValue"/> ready to be filled up with the data and written down by the <see cref="WriteData"/> /// to the destination – remote station. /// </returns> public IWriteValue GetEmptyWriteDataBuffor(IBlockDescription block, int station) { try { return(mDataProvider.GetEmptyWriteDataBuffor(block, station)); } catch (Exception ex) { TraceException(ex, 60); return(null); } }
/// <summary> /// Read Data /// </summary> /// <param name="block">Data block description to be read</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <param name="data">The buffer with the requested data.</param> /// <param name="retries">Number of retries to get data.</param> /// <returns>Result of the operation</returns> AL_ReadData_Result IApplicationLayerMaster.ReadData(IBlockDescription block, int station, out IReadValue data, byte retries) { lock (this) { rPackNum++; data = null; data = (IReadValue)pool.GetEmptyISesDBuffer(); System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); ((NULL_message)data).SetBlockDescription(station, block); ((NULL_message)data).ReadFromDB(); myStatistic.IncStTxFrameCounter(); myStatistic.IncStRxFrameCounter(); myStatistic.RxDataBlock(true); return(AL_ReadData_Result.ALRes_Success); } }
/// <summary> /// Reads process data from the selected location and device resources. /// </summary> /// <param name="pBlock"><see cref="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="IReadValue"/> containing the requested data.</param> /// <param name="pRetries">Number of retries to get data.</param> /// <returns>Result of the operation</returns> public AL_ReadData_Result ReadData(IBlockDescription pBlock, int pStation, out IReadValue pData, byte pRetries) { pData = null; try { return(mDataProvider.ReadData(pBlock, pStation, out pData, pRetries)); } catch (Exception ex) { if ((pData != null) && !pData.InPool) { pData.ReturnEmptyEnvelope(); } pData = null; TraceException(ex, 46); return(AL_ReadData_Result.ALRes_DatTransferErrr); } }
protected override void PrepareReqWriteValue(IBlockDescription block, int station) { base.PrepareReqWriteValue(block, station); offset = 6; if (dataType == Modbus_Functions.WRITE_MULTIPLE_REGISTERS) { offset += 5; // write two registers (for 32bit) is longer 5 bytes } if (dataType == Modbus_Functions.WRITE_MEMORYBANK_CONTROL) //CONTROL Micro XL extension { offset += 2; //in WRITE_MEMORYBANK_CONTROL there are additional fields: (Bank) and (byte count) before CRC } if (dataType == Modbus_Functions.WRITE_SINGLE_HOLDING_REGISTERS_8BIT_CONTROL) //CONTROL Micro XL extension { offset -= 1; //in WRITE_SINGLE_HOLDING_REGISTERS_8BIT_CONTROL the frame is shorter because we are sending 1 data byte instead of 16 bit (two bytes) before CRC } //MZTODO: tymczasowo zakladam, ze ilosc jest przesylana w polu 8bit powinno to byc wyjasnione z CONTROL'em PutCRC16(); }
protected override void PrepareRequest(int station, IBlockDescription block) { crc.clear(); userDataLength = 5; // stala dlugosc zapytania this.startbyte = MBUSConstans.StartShort; this.ShortFrameStation = (byte)station; crc.CRC_Calc((byte)station); switch ((MediumData)block.dataType) { case MediumData.Class2_Data: case MediumData.Class2_Data_Short: ShortFrameControlField = MBUSControlCodes.REQ_UD2_FCBSet; crc.CRC_Calc((byte)ShortFrameControlField); if ((MediumData)block.dataType == MediumData.Class2_Data_Short) { this.expectedDataAnalysisMode = DataAnalysisMode.Short; } else { this.expectedDataAnalysisMode = DataAnalysisMode.Full; } break; //case MediumData.Class1_Data: //case MediumData.Class1_Data_Short: // ShortFrameControlField = MBUSControlCodes.REQ_UD1_FCBSet; // crc.CRC_Calc( (byte)ShortFrameControlField ); // if ( (MediumData)block.dataType == MediumData.Class1_Data_Short ) // this.expectedDataAnalysisMode = DataAnalysisMode.Short; // else // this.expectedDataAnalysisMode = DataAnalysisMode.Full; // break; //TODO: dodac inne mozliwosci default: throw new NotImplementedException("PrepareRequest is implemented only for REQ_UD2"); } offset = 3; PutCRC(); myAssert.Assert(this.WriteByte((byte)MBUSConstans.Stop), 193, "Unable to put MBUSConstans.Stop in MBUS PrepareRequest"); MBUSTrace(TraceEventType.Verbose, 182, "PrepareRequest:" + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt") + this.ToString()); }
/// <summary> /// Prepares the frame header. /// </summary> /// <param name="station">The station address.</param> /// <param name="block">The block description.</param> /// <param name="code">The type of the SBUS frame.</param> protected virtual void PrepareFrameHeader(int station, IBlockDescription block, SbusCode code) { userDataLength = userBuffLength; this.FrameAttribute = AttributeCharacter.Telegram; this.offset = stationAddressPos; WriteByte((byte)station); this.DataType = code; offset = addressStartPos; WriteInt16((short)block.startAddress); //<text-number> or <address-RTC> or <address-IOF> switch (code) { case SbusCode.coReadText: WriteInt16(0); // <char-position> break; default: break; } this.SetBlockDescription(station, block); //It is used usaly while receiving. userDataLength = FrameRequestLength((ushort)block.length); }
/// <summary> /// Read Data /// </summary> /// <param name="block">Block description to be read</param> /// <param name="station">Address of the remote station connected to the common field bus. –1 if not applicable. /// </param> /// <param name="data">The buffer with the requested data.</param> /// <param name="retries">Number of retries to get data.</param> /// <returns>Result of the operation</returns> AL_ReadData_Result IApplicationLayerMaster.ReadData(IBlockDescription block, int station, out IReadValue data, byte retries) { lock (this) { InterFrameStopwatch.Reset(); InterFrameStopwatch.Start(); m_rPackNum++; data = null; bool TransmissionIsOK = true; data = (IReadValue)pool.GetEmptyISesDBuffer(); //informacja ze dziala transmitter: ((Message)data).TransmitterON(station); //Timer.Wait( Timer.TInOneSecond ); ((Message)data).SetBlockDescription(station, block); ((Message)data).ReadFromDB(); myStatistic.IncStTxFrameCounter(); myStatistic.IncStRxFrameCounter(); myStatistic.TimeCharGapAdd(1); myStatistic.TimeMaxResponseDelayAdd(InterFrameStopwatch.ElapsedMilliseconds); ((Message)data).TransmitterOFF(station); if (m_errorfrequency > 0 && (m_rPackNum % (100 / (ulong)m_errorfrequency)) == 0) { TransmissionIsOK = false; } if (TransmissionIsOK && ((Message)data).TestCommunication(station)) { myStatistic.RxDataBlock(true); return(AL_ReadData_Result.ALRes_Success); } else { myStatistic.RxDataBlock(false); data.ReturnEmptyEnvelope(); data = null; return(AL_ReadData_Result.ALRes_DatTransferErrr); } } }
public AL_ReadData_Result ReadData(IBlockDescription pBlock, int pStation, out IReadValue pData, byte pRetries) { Assert.IsTrue(myConnected, "Must be connected while ReadData"); MonitorEnter(); pData = null; myNumberOfReadOperations++; if (myBreakConnection) { myBreakConnection = false; myMakeError = false; myConnected = false; MonitorExit(); return(AL_ReadData_Result.ALRes_DisInd); } if (!myMakeError) { pData = new FacadeIReadValue(this); MonitorExit(); return(AL_ReadData_Result.ALRes_Success); } MonitorExit(); return(AL_ReadData_Result.ALRes_DatTransferErrr); }
/// <summary> /// Prepares the frame header. /// </summary> /// <param name="station">The station.</param> /// <param name="block">The block description.</param> /// <param name="code">The code.</param> protected override void PrepareFrameHeader(int station, IBlockDescription block, SbusCode code) { base.PrepareFrameHeader(station, block, code); FSPart = FrameSynchronisationChar; }
protected override void PrepareReqWriteValue(IBlockDescription block, int station) { }