static XaMessageRequest createXaMessageRequest(ByteQueue queue) throws ModbusTransportException { // Remove the XA header int transactionId = ModbusUtils.popShort(queue); int protocolId = ModbusUtils.popShort(queue); if (protocolId != ModbusUtils.IP_PROTOCOL_ID) throw new ModbusTransportException("Unsupported IP protocol id: " + protocolId); ModbusUtils.popShort(queue); // Length, which we don't care about. // Create the modbus response. ModbusRequest request = ModbusRequest.createModbusRequest(queue); return new XaMessageRequest(request, transactionId); }
@Override public synchronized ModbusResponse sendImpl(ModbusRequest request) throws ModbusTransportException { if (!connected) { LOG.debug("No connection in Port: " + ipParameters.getPort()); throw new ModbusTransportException( new Exception("TCP Listener has no active connection!"), request.getSlaveId()); } if (!initialized) { LOG.debug("Listener already terminated " + ipParameters.getPort()); return null; } // Wrap the modbus request in a ip request. OutgoingRequestMessage ipRequest; if (ipParameters.isEncapsulated()) { ipRequest = new EncapMessageRequest(request); StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipRequest.getMessageData(), 0, ipRequest.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Encap Request: " + sb.toString()); } else { ipRequest = new XaMessageRequest(request, getNextTransactionId()); StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipRequest.getMessageData(), 0, ipRequest.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Xa Request: " + sb.toString()); } // Send the request to get the response. IpMessageResponse ipResponse; try { // Send data via handler! handler.conn.DEBUG = true; ipResponse = (IpMessageResponse) handler.conn.send(ipRequest); if (ipResponse == null) { throw new ModbusTransportException( new Exception("No valid response from slave!"), request.getSlaveId()); } StringBuilder sb = new StringBuilder(); for (byte b : Arrays.copyOfRange(ipResponse.getMessageData(), 0, ipResponse.getMessageData().length)) { sb.append(String.format("%02X ", b)); } LOG.debug("Response: " + sb.toString()); return ipResponse.getModbusResponse(); } catch (Exception e) { LOG.debug( e.getLocalizedMessage() + ", Port: " + ipParameters.getPort() + ", retries: " + retries); if (retries < 10 && !e.getLocalizedMessage().contains("Broken")) { retries++; } else { /* * To recover from a Broken Pipe, the only way is to restart serverSocket */ LOG.debug("Restarting Socket, Port: " + ipParameters.getPort() + ", retries: " + retries); // Close the serverSocket first to prevent new messages. try { if (serverSocket != null) serverSocket.close(); } catch (IOException e2) { LOG.debug("Error closing socket" + e2.getLocalizedMessage(), e); getExceptionHandler().receivedException(e2); } // Close all open connections. if (handler != null) { handler.closeConnection(); terminateListener(); } if (!initialized) { LOG.debug("Listener already terminated " + ipParameters.getPort()); return null; } executorService = Executors.newCachedThreadPool(); try { startListener(); } catch (Exception e2) { LOG.warn("Error trying to restart socket" + e2.getLocalizedMessage(), e); throw new ModbusTransportException(e2, request.getSlaveId()); } retries = 0; } LOG.warn( "Error sending request, Port: " + ipParameters.getPort() + ", msg: " + e.getMessage()); // Simple send error! throw new ModbusTransportException(e, request.getSlaveId()); } }