/// <summary> /// Represents asynchronous processing of a modbus request /// </summary> /// <param name="request">An instance of modbus request to process</param> /// <returns>An enumeration of asynchronous actions to process</returns> protected virtual IEnumerable <Task> OnProcessRequestAsync <T>(IModbusClientRequest request) where T : IModbusResponse { this.ThrowIfDisposed(); yield return(this._semaphore.WaitAsync()); Task <IModbusResponse> readResult; try { yield return(this._transport.OpenConnectionAsync()); var writeResult = this.WriteRequestAsync(request); yield return(writeResult); readResult = this.ReadResponseAsync(request); yield return(readResult); yield return(this._transport.CloseConnectionAsync()); } finally { this._semaphore.Release(); } if (readResult.Result == null) { this._logger.Log(RESPONSE_ERROR, Category.ERROR, Priority.HIGH); Guard.Throw <ClientModbusResponseException>(RESPONSE_ERROR); } request.ValidateResponse(readResult.Result); yield return(Task.Factory.FromResult((T)readResult.Result)); }
/// <summary> /// Represents template method for validation in derived class. /// </summary> /// <param name="request">An instance of modbus request.</param> /// <param name="response">An instance of modbus response to validate.</param> protected override void OnValidateResponse(IModbusClientRequest request, IModbusResponse response) { base.OnValidateResponse(request, response); var tcpModbusRequest = (TcpModbusClientRequest)request; var tcpModbusResponse = (TcpModbusClientResponse)response; Guard.AgainstIsFalse <ClientModbusResponseException>( tcpModbusRequest.TransactionId == tcpModbusResponse.TransactionId, ResourceConstants.TRANSACTION_ID_ERROR_MESSAGE); }
/// <summary> /// Writes a modbus request to a transport. /// </summary> /// <param name="request">An instance of a modbus request to write</param> protected override void WriteRequest(IModbusClientRequest request) { var tcpModbusRequest = (TcpModbusClientRequest)request; tcpModbusRequest.TransactionId = this.GetNewTransactionId(); var frameToWrite = request.BuildRequestFrame(); this._transport.Write(frameToWrite, 0, frameToWrite.Length); }
private IEnumerable <Task> OnWriteRequestAsync(IModbusClientRequest request) { var tcpModbusRequest = (TcpModbusClientRequest)request; tcpModbusRequest.TransactionId = this.GetNewTransactionId(); var frameToWrite = request.BuildRequestFrame(); var writeTask = this._transport.WriteAsync(frameToWrite, 0, frameToWrite.Length); yield return(writeTask); }
/// <summary> /// Processes modbus request message. /// </summary> /// <typeparam name="T">The type of response</typeparam> /// <param name="request">The modbus request message.</param> /// <returns>The result of message processing.</returns> internal virtual T ProcessRequest <T>(IModbusClientRequest request) where T : class, IModbusResponse { this.ThrowIfDisposed(); T response; lock (this._syncObj) { this._transport.OpenConnection(); this.WriteRequest(request); response = (T)this.ReadResponse(request); this._transport.CloseConnection(); } if (response == null) { this._logger.Log(RESPONSE_ERROR, Category.ERROR, Priority.HIGH); Guard.Throw <ClientModbusResponseException>(RESPONSE_ERROR); } request.ValidateResponse(response); return(response); }
private IEnumerable <Task> OnReadResponseAsync(IModbusClientRequest request) { var bytesToRead = ProtocolConstants.MBAP_HEADER_LENGTH; var mbapHeader = new byte[bytesToRead]; var numBytesRead = 0; while (numBytesRead != ProtocolConstants.MBAP_HEADER_LENGTH) { var readTask = this._transport.ReadAsync(mbapHeader, numBytesRead, bytesToRead - numBytesRead); yield return(readTask); numBytesRead = readTask.Result; if (numBytesRead == 0) { this._logger.Log(ResourceConstants.TCP_MODBUS_READ_RESULT_WITH_ZERO_BYTES_MESSAGE, Category.ERROR, Priority.HIGH); Guard.Throw <ClientModbusResponseException>( ResourceConstants.TCP_MODBUS_READ_RESULT_WITH_ZERO_BYTES_MESSAGE); } } bytesToRead = (ushort)(mbapHeader[5] | (mbapHeader[4] << 8)); var frame = new byte[bytesToRead]; numBytesRead = 0; while (numBytesRead != bytesToRead) { var readTask = this._transport.ReadAsync(frame, numBytesRead, bytesToRead - numBytesRead); yield return(readTask); numBytesRead = readTask.Result; if (numBytesRead == 0) { this._logger.Log(ResourceConstants.TCP_MODBUS_READ_RESULT_WITH_ZERO_BYTES_MESSAGE, Category.ERROR, Priority.HIGH); Guard.Throw <ClientModbusResponseException>( ResourceConstants.TCP_MODBUS_READ_RESULT_WITH_ZERO_BYTES_MESSAGE); } } var response = request.CreateResponseFromFrame(mbapHeader.CombineArray(frame)); yield return(Task.Factory.FromResult(response)); }
/// <summary> /// Writes a modbus request to a transport asynchronously. /// </summary> /// <param name="request">An instance of a task that represents a modbus request to write</param> protected abstract Task WriteRequestAsync(IModbusClientRequest request);
/// <summary> /// Reads a modbus response from a transport asynchronously. /// </summary> /// <param name="request"></param> /// <returns>An instance of a task that represents a modbus response that has recently been read.</returns> protected abstract Task <IModbusResponse> ReadResponseAsync(IModbusClientRequest request);
/// <summary> /// Processes modbus request message. /// </summary> /// <typeparam name="T">The type of response</typeparam> /// <param name="request">The modbus request message.</param> /// <returns>The result of message processing.</returns> internal Task <T> ProcessRequestAsync <T>(IModbusClientRequest request) where T : class, IModbusResponse { this.ThrowIfDisposed(); return(Task.Factory.IterateWithResult <T>(OnProcessRequestAsync <T>(request))); }
/// <summary> /// Represents template method for validation in derived class. /// </summary> /// <param name="request">An instance of modbus request.</param> /// <param name="response">An instance of modbus response to validate.</param> protected virtual void OnValidateResponse(IModbusClientRequest request, IModbusResponse response) { /*none*/ }
/// <summary> /// Writes a modbus request to a transport. /// </summary> /// <param name="request">An instance of a modbus request to write</param> protected abstract void WriteRequest(IModbusClientRequest request);
/// <summary> /// Reads a modbus response from a transport. /// </summary> /// <param name="request"></param> /// <returns>An instance of a modbus response that has recently been read.</returns> protected abstract IModbusResponse ReadResponse(IModbusClientRequest request);
/// <summary> /// Reads a modbus response from a transport. /// </summary> /// <param name="request"></param> /// <returns>An instance of a modbus response that has recently been read.</returns> protected override IModbusResponse ReadResponse(IModbusClientRequest request) { var requestResponse = this.ReadResponseInternal(); return(request.CreateResponseFromFrame(requestResponse)); }
/// <summary> /// Writes a modbus request to a transport asynchronously. /// </summary> /// <param name="request">An instance of a task that represents a modbus request to write</param> protected override Task WriteRequestAsync(IModbusClientRequest request) { return(Task.Factory.Iterate(this.OnWriteRequestAsync(request))); }
/// <summary> /// Reads a modbus response from a transport asynchronously. /// </summary> /// <param name="request"></param> /// <returns>An instance of a task that represents a modbus response that has recently been read.</returns> protected override Task <IModbusResponse> ReadResponseAsync(IModbusClientRequest request) { return(Task.Factory.IterateWithResult <IModbusResponse>(this.OnReadResponseAsync(request))); }