title: How to read binary protocol from InputStream?
body: <p>I try to read a binary protocol from my serial port in Java. I use the <a href="http://rxtx.qbang.org/wiki/index.php/Main_Page" rel="nofollow">RXTX library</a> to read from the serial port. </p>
  
  <p>The protocol is the SiRF binary protocol for GPS receivers. The structure is:</p>
  
  <ul>
  <li>first two bytes are 0xA0 and 0xA2, which define the beginning of a data frame</li>
  <li>next two bytes are the payload length n</li>
  <li>next n bytes are the payload</li>
  <li>last two bytes are 0xB0 and 0xB3, which define the end of a data frame</li>
  </ul>
  
  <p>Although this structure is quite simple I am not able to read the data correctly. I tried two different ways:</p>
  
  <ol>
  <li><p>I wrote a thread, which reads from the <code>InputStream</code> and compares the input with 0xA0. If this matches, then the thread reads the next byte and compares to 0xA2. If this matches again, it reads the next two bytes and computes the payload length. After that, it reads the payload with length n bytes. At last, it reads the last two bytes and compares them to 0xB0 and 0xB3. When everything matches, it creates a hex string from the input and saves it to a queue. Here is my code:</p>
  
  <pre><code>try {
      byte[] size = new byte[2];
      byte[] checkSum = new byte[2];
      byte[] packet;
      int bytesRead = -1;
      while (in.available() &gt; 0) {
          if (getInput() == 0xA0) {
              if (getInput() == 0xA2) {
                  System.out.print("160,162,");
                  bytesRead = in.read(size);
                  int payLoadLength = (size[0] &lt;&lt; 8) | (size[1] &amp; 0xFF);
                  byte[] payload = new byte[payLoadLength];
                  bytesRead = in.read(payload);
                  bytesRead = in.read(checkSum);
                  if (getInput() == 0xB0) {
                      if (getInput() == 0xB3) {
                  System.out.println("out");
                  packet = new byte[2 + 2 + payLoadLength + 2 + 2];
                  packet[0] = (byte) START_1;
                  packet[1] = (byte) START_2;
                  packet[2] = size[0];
                  packet[3] = size[1];
                  for (int i = 0; i &lt; payload.length; i++) {
                      packet[i + 4] = payload[i];
                  }
                  packet[packet.length - 4] = checkSum[0];
                  packet[packet.length - 3] = checkSum[1];
                  packet[packet.length - 2] = (byte) END_1;
                  packet[packet.length - 1] = (byte) END_2;
                  StringBuffer hexString = new StringBuffer();
                  int[] output = new int[packet.length];
                  for (int i = 0; i &lt; packet.length; i++) {
                      output[i] = 0xFF &amp; packet[i];
                      hexString.append(Integer.toHexString(output[i]));
                  }
                  TransportMessage tm = new TransportMessage(hexString.toString());
                  boolean b = queue.offer(tm);
                  System.out.println(hexString.toString().toUpperCase());
                  if(!b)
                      System.err.println("TransportMessageQueue voll!");
              }
          } else {
              System.out.println();
          }
      }
  } 
      }
  } catch (IOException e) {
      System.out.println(e);
  }
  </code></pre>
  
  <p><code>getInput()</code> just reads a byte from the <code>InputStream</code>.</p></li>
  <li><p>I used the <code>SerialPortEventListener</code> from the RXTX library. Everytime something happens on the serial port, a SerialPortEvent is fired and I read the data in a similar way as in the first method.</p></li>
  </ol>
  
  <p>For debugging reasons I added several <code>System.out.println()</code> calls to show what exactly is read by the threads and it seems that I am missing nearly the half of all data frames sended via the <code>InputStream</code>.</p>
  
  <p>My question now is: What is the best way to read such a protocol from an <code>InputStream</code>? In my opinion I have to get my reading efforts synchronized with the data from the serial port, but I have no idea how to do that in Java.</p>