Added ability to measure round-trip latency and to assure message integrity.
diff --git a/apps/foo/src/main/java/org/onlab/onos/foo/TestMessageStream.java b/apps/foo/src/main/java/org/onlab/onos/foo/TestMessageStream.java
index 4a44682..a7a3e6a 100644
--- a/apps/foo/src/main/java/org/onlab/onos/foo/TestMessageStream.java
+++ b/apps/foo/src/main/java/org/onlab/onos/foo/TestMessageStream.java
@@ -6,24 +6,21 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
+import static com.google.common.base.Preconditions.checkState;
+
 /**
  * Fixed-length message transfer buffer.
  */
 public class TestMessageStream extends MessageStream<TestMessage> {
 
     private static final String E_WRONG_LEN = "Illegal message length: ";
+    private static final long START_TAG = 0xfeedcafedeaddeedL;
+    private static final long END_TAG = 0xbeadcafedeaddeedL;
+    private static final int META_LENGTH = 40;
 
     private final int length;
 
-    /**
-     * Create a new buffer for transferring messages of the specified length.
-     *
-     * @param length message length
-     * @param ch     backing channel
-     * @param loop   driver loop
-     */
-    public TestMessageStream(int length, ByteChannel ch,
-                             IOLoop<TestMessage, ?> loop) {
+    public TestMessageStream(int length, ByteChannel ch, IOLoop<TestMessage, ?> loop) {
         super(loop, ch, 64 * 1024, 500);
         this.length = length;
     }
@@ -33,26 +30,37 @@
         if (rb.remaining() < length) {
             return null;
         }
-        TestMessage message = new TestMessage(length);
-        rb.get(message.data());
-        return message;
+
+        long startTag = rb.getLong();
+        checkState(startTag == START_TAG, "Incorrect message start");
+
+        long size = rb.getLong();
+        long requestorTime = rb.getLong();
+        long responderTime = rb.getLong();
+        byte[] padding = padding(length);
+        rb.get(padding);
+
+        long endTag = rb.getLong();
+        checkState(endTag == END_TAG, "Incorrect message end");
+
+        return new TestMessage((int) size, requestorTime, responderTime, padding);
     }
 
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * This implementation enforces the message length against the buffer
-     * supported length.
-     *
-     * @throws IllegalArgumentException if message size does not match the
-     *                                  supported buffer size
-     */
     @Override
     protected void write(TestMessage message, ByteBuffer wb) {
         if (message.length() != length) {
             throw new IllegalArgumentException(E_WRONG_LEN + message.length());
         }
-        wb.put(message.data());
+
+        wb.putLong(START_TAG);
+        wb.putLong(message.length());
+        wb.putLong(message.requestorTime());
+        wb.putLong(message.responderTime());
+        wb.put(message.padding(), 0, length - META_LENGTH);
+        wb.putLong(END_TAG);
     }
 
+    public byte[] padding(int msgLength) {
+        return new byte[msgLength - META_LENGTH];
+    }
 }