[SNMP4J] Extend DefaultTcpTransportMapping to support NTCIP PMPP

Bruno Abreu bruno.abreu at livingdata.pt
Fri Jan 26 19:10:07 CET 2018


Hello again,

first of all, thank you for you quick reply to our previous post regarding
SocketTimeout: http://oosnmp.net/pipermail/snmp4j/2018-January/005886.html

Now we have another request. As already stated, we are using SNMP4J to handle
the NTCIP-PMPP protocol. But we have specific needs when reading messages from
a particular device. Namely, because some characters might be escaped, we need
to keep reading until the end mark is reached. The strategy of using the
length from the message header just doesn't work because the message size
might have changed.

For that we need to extend the DefaultTcpTransportMapping and
DefaultTcpTransportMapping.ServerThread classes and override the following
methods:

>From DefaultTcpTransportMapping:
- private void addBufferToReadBuffer(SocketEntry entry, ByteBuffer byteBuffer);

>From DefaultTcpTransportMapping.ServerThread:
- private boolean readMessage(SelectionKey sk, SocketChannel readChannel,
TcpAddress incomingAddress) throws IOException;
- private void readSnmpMessagePayload(SocketChannel readChannel, TcpAddress
incomingAddress, SocketEntry entry, ByteBuffer byteBuffer) throws IOException;

In order to this we had to change the visibility of some of the members of
these classes, either because we want to override them or because they are
accessed from the overriden methods. The following patch contains the changes
we had to apply to DefaultTcpTransportMapping:

«««
--- DefaultTcpTransportMapping.java.2.5.11	2018-01-26 11:36:14.019589314 +0000
+++ DefaultTcpTransportMapping.java	2018-01-26 13:47:50.000000000 +0000
@@ -62,17 +62,17 @@ public class DefaultTcpTransportMapping
   private static final LogAdapter logger =
       LogFactory.getLogger(DefaultTcpTransportMapping.class);

-  private Map<Address, SocketEntry> sockets = new Hashtable<Address,
SocketEntry>();
-  private WorkerTask server;
-  private ServerThread serverThread;
+  protected Map<Address, SocketEntry> sockets = new Hashtable<Address,
SocketEntry>();
+  protected WorkerTask server;
+  protected ServerThread serverThread;

-  private CommonTimer socketCleaner;
+  protected CommonTimer socketCleaner;
   // 1 minute default timeout
-  private long connectionTimeout = 60000;
+  protected long connectionTimeout = 60000;
   private boolean serverEnabled = false;

   private static final int MIN_SNMP_HEADER_LENGTH = 6;
-  private MessageLengthDecoder messageLengthDecoder =
+  protected MessageLengthDecoder messageLengthDecoder =
       new SnmpMesssageLengthDecoder();
   private int maxBusyLoops = DEFAULT_MAX_BUSY_LOOPS;

@@ -603,12 +603,12 @@ public class DefaultTcpTransportMapping
     }
   }

-  class ServerThread implements WorkerTask {
-    private byte[] buf;
+  protected class ServerThread implements WorkerTask {
+    protected byte[] buf;
     private volatile boolean stop = false;
     private Throwable lastError = null;
     private ServerSocketChannel ssc;
-    private Selector selector;
+    protected Selector selector;

     private LinkedList<SocketEntry> pending = new LinkedList<SocketEntry>();

@@ -993,7 +993,7 @@ public class DefaultTcpTransportMapping
       }
     }

-    private boolean readMessage(SelectionKey sk, SocketChannel readChannel,
+    protected boolean readMessage(SelectionKey sk, SocketChannel readChannel,
                                 TcpAddress incomingAddress) throws IOException {
       SocketEntry entry = (SocketEntry) sk.attachment();
       if (entry == null) {
@@ -1075,7 +1075,7 @@ public class DefaultTcpTransportMapping
       return false;
     }

-    private void readSnmpMessagePayload(SocketChannel readChannel, TcpAddress
incomingAddress,
+    protected void readSnmpMessagePayload(SocketChannel readChannel,
TcpAddress incomingAddress,
                                         SocketEntry entry, ByteBuffer
byteBuffer) throws IOException {
       MessageLength messageLength =
           messageLengthDecoder.getMessageLength(ByteBuffer.wrap(byteBuffer.array()));
@@ -1142,7 +1142,7 @@ public class DefaultTcpTransportMapping
       }
     }

-    private void dispatchMessage(TcpAddress incomingAddress,
+    protected void dispatchMessage(TcpAddress incomingAddress,
                                  ByteBuffer byteBuffer, long bytesRead,
                                  Object sessionID) {
       byteBuffer.flip();
@@ -1225,7 +1225,7 @@ public class DefaultTcpTransportMapping
     }
   }

-  private void addBufferToReadBuffer(SocketEntry entry, ByteBuffer byteBuffer) {
+  protected void addBufferToReadBuffer(SocketEntry entry, ByteBuffer
byteBuffer) {
     if (logger.isDebugEnabled()) {
       logger.debug("Adding data "+byteBuffer+" to read buffer
"+entry.getReadBuffer());
     }
@@ -1243,7 +1243,7 @@ public class DefaultTcpTransportMapping
     }
   }

-  private void socketClosedRemotely(SelectionKey sk, SocketChannel
readChannel, TcpAddress incomingAddress) throws IOException {
+  protected void socketClosedRemotely(SelectionKey sk, SocketChannel
readChannel, TcpAddress incomingAddress) throws IOException {
     logger.debug("Socket closed remotely");
     sk.cancel();
     readChannel.close();
»»»


So, our question is: are these visibility changes something you'd consider
applying in a future release of SNMP4J?

In any case, thank you very much for your attention,
Bruno Abreu

-- 
Living Data - Sistemas de Informação e Apoio à Decisão, Lda.
LxFactory - Rua Rodrigues de Faria, 103, edifício I, 4º piso
1300-501 LISBOA                       Phone:  +351 213622163
Portugal                              URL: www.livingdata.pt




More information about the SNMP4J mailing list