示例#1
0
        /// <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));
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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);
        }
示例#6
0
        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));
        }
示例#7
0
 /// <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);
示例#8
0
 /// <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);
示例#9
0
 /// <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)));
 }
示例#10
0
 /// <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*/
 }
示例#11
0
 /// <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);
示例#12
0
 /// <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);
示例#13
0
        /// <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));
        }
示例#14
0
 /// <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)));
 }
示例#15
0
 /// <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)));
 }