Exemple #1
0
        private async Task HandleRequestAsync()
        {
            while (true)
            {
#if ModBusDebug
                Debug.WriteLine($"Begin reading header from Master at IP: {EndPoint}");
#endif
                int readBytes = await Stream.ReadAsync(_mbapHeader, 0, 6).ConfigureAwait(false);

                if (readBytes == 0)
                {
#if ModBusDebug
                    Debug.WriteLine($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
#endif
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }

                ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
#if ModBusDebug
                Debug.WriteLine($"Master at {EndPoint} sent header: \"{string.Join(", ", _mbapHeader)}\" with {frameLength} bytes in PDU");
#endif

                _messageFrame = new byte[frameLength];
                readBytes     = await Stream.ReadAsync(_messageFrame, 0, frameLength).ConfigureAwait(false);

                if (readBytes == 0)
                {
#if ModBusDebug
                    Debug.WriteLine($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
#endif
                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                    return;
                }
#if ModBusDebug
                Debug.WriteLine($"Read frame from Master at {EndPoint} completed {readBytes} bytes");
#endif
                byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
#if ModBusDebug
                Debug.WriteLine($"RX from Master at {EndPoint}: {string.Join(", ", frame)}");
#endif

                var request = ModbusMessageFactory.CreateModbusRequest(_messageFrame);
                request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));

                // perform action and build response
                IModbusMessage response = _slave.ApplyRequest(request);
                response.TransactionId = request.TransactionId;

                // write response
                byte[] responseFrame = Transport.BuildMessageFrame(response);
#if ModBusDebug
                Debug.WriteLine($"TX to Master at {EndPoint}: {string.Join(", ", responseFrame)}");
#endif
                await Stream.WriteAsync(responseFrame, 0, responseFrame.Length).ConfigureAwait(false);
            }
        }
Exemple #2
0
        private async Task HandleRequestAsync()
        {
            var serialTransport = (IModbusSerialTransport)Transport;

            while (true)
            {
                try
                {
                    // read request and build message
                    byte[] frame = serialTransport.ReadRequest();

                    //Create the request
                    IModbusMessage request = _modbusFactory.CreateModbusRequest(frame);

                    //Check the message
                    if (serialTransport.CheckFrame && !serialTransport.ChecksumsMatch(request, frame))
                    {
                        string msg = $"Checksums failed to match {string.Join(", ", request.MessageFrame)} != {string.Join(", ", frame)}.";
                        //Logger.Warning(msg);
                        throw new IOException(msg);
                    }

                    //Apply the request
                    // TODO: почистить класс и предусмотреть броадкаст request.SlaveAddress ==0
                    IModbusMessage response = _slaveNetwork.GetSlave(request.SlaveAddress)
                                              .ApplyRequest(request);

                    if (response == null)
                    {
                        serialTransport.IgnoreResponse();
                    }
                    else
                    {
                        Transport.Write(response);
                    }
                }
                catch (IOException /*ioe*/)
                {
                    //Logger.Warning($"IO Exception encountered while listening for requests - {ioe.Message}");
                    serialTransport.DiscardInBuffer();

                    ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                }
                catch (TimeoutException /*te*/)
                {
                    //Logger.Trace($"Timeout Exception encountered while listening for requests - {te.Message}");
                    serialTransport.DiscardInBuffer();
                }
                catch (InvalidOperationException)
                {
                    // when the underlying transport is disposed
                    break;
                }
                catch (Exception /*ex*/)
                {
                    //Logger.Error($"{GetType()}: {ex.Message}");
                    serialTransport.DiscardInBuffer();
                }

                /* // OLD CODE
                 * // //Logger.Debug($"Begin reading header from Master at IP: {EndPoint}");
                 *
                 * int readBytes = await Stream.ReadAsync(_mbapHeader, 0, 6).ConfigureAwait(false);
                 * if (readBytes == 0)
                 * {
                 *  //Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                 *  ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                 *  return;
                 * }
                 *
                 * ushort frameLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(_mbapHeader, 4));
                 * //Logger.Debug($"Master at {EndPoint} sent header: \"{string.Join(", ", _mbapHeader)}\" with {frameLength} bytes in PDU");
                 *
                 * _messageFrame = new byte[frameLength];
                 * readBytes = await Stream.ReadAsync(_messageFrame, 0, frameLength).ConfigureAwait(false);
                 * if (readBytes == 0)
                 * {
                 *  //Logger.Debug($"0 bytes read, Master at {EndPoint} has closed Socket connection.");
                 *  ModbusMasterTcpConnectionClosed?.Invoke(this, new TcpConnectionEventArgs(EndPoint));
                 *  return;
                 * }
                 *
                 * //Logger.Debug($"Read frame from Master at {EndPoint} completed {readBytes} bytes");
                 * byte[] frame = _mbapHeader.Concat(_messageFrame).ToArray();
                 * //Logger.Trace($"RX from Master at {EndPoint}: {string.Join(", ", frame)}");
                 *
                 * var request = _modbusFactory.CreateModbusRequest(_messageFrame);
                 * request.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(frame, 0));
                 *
                 * IModbusSlave slave = _slaveNetwork.GetSlave(request.SlaveAddress);
                 *
                 * if (slave != null)
                 * {
                 *  //TODO: Determine if this is appropriate
                 *
                 *  // perform action and build response
                 *  IModbusMessage response = slave.ApplyRequest(request);
                 *  response.TransactionId = request.TransactionId;
                 *
                 *  // write response
                 *  byte[] responseFrame = Transport.BuildMessageFrame(response);
                 *  //Logger.Information($"TX to Master at {EndPoint}: {string.Join(", ", responseFrame)}");
                 *  await Stream.WriteAsync(responseFrame, 0, responseFrame.Length).ConfigureAwait(false);
                 * }
                 */
            }
        }