title: Parsing raw data received from bluetooth HDP device
body: <p>I am trying to read data from an Omron 708-BT Blood Pressure Monitor which is certified by the continua health alliance. I am following this example <a href="https://github.com/james11/BluetoothHDPActivity/tree/3f64bf701fbbfa51cbc3472d5826a7b1c6957ad4/src/com/larc/bluetooth/health" rel="nofollow noreferrer">of a Bluetooth HDP App</a>. I am managing to connect to the device and retrieve data in byte format but cannot parse the data to get the values needed. I am trying to follow the IEEE Blood Pressure specification specified on page 19 of this <a href="http://www.telemedicina.ufsc.br/padroes/images/11073_10407_2008.pdf" rel="nofollow noreferrer">PDF</a>.</p>
  <p>Here is the code which has been added to the example code linked above.</p>
  <pre><code>//Variables in the class
  private int count;
  private byte[] invoke = {0x00, 0x00};
  private class ReadThread extends Thread {
      private ParcelFileDescriptor mFd;
  
      public ReadThread(ParcelFileDescriptor fd) {
          super();
          mFd = fd;
      }
  
      @Override
      public void run() {
          FileInputStream fis = new FileInputStream(mFd.getFileDescriptor());
          final byte data[] = new byte[300];
          try {
              while(fis.read(data) &gt; -1) {
                  // At this point, the application can pass the raw data to a parser that
                  // has implemented the IEEE 11073-xxxxx specifications.  Instead, this sample
                  // simply indicates that some data has been received
                  Log.e(&quot;Test&quot;, data.toString()); 
  
                   if (data[0] != (byte) 0x00)
                   {
                       String test = byte2hex(data);
                       Log.i(TAG, test);
                       if(data[0] == (byte) 0xE2){
                           Log.i(TAG, &quot;E2&quot;);
                           count = 1;
                           
                           (new WriteThread(mFd)).start();
                           try {
                               sleep(100);
                           } catch (InterruptedException e) {
                               e.printStackTrace();
                           }
                           Log.i(TAG, &quot;Seconds Write Thread&quot;);
                           count = 2;
                           (new WriteThread(mFd)).start();
                       }
                       else if (data[0] == (byte)0xE7){
                           Log.i(TAG, &quot;E7&quot;);
                           
                           count = 3; 
                           //set invoke id so get correct response
                           invoke = new byte[] { data[6], data[7] };
                           (new WriteThread(mFd)).start();     
                           //parse data!!
                           int number_of_data_packets = data[25];
                           int packet_start = 30;
                           final int SYS_DIA_MAP_DATA = 1;
                           final int PULSE_DATA = 2;
                           final int ERROR_CODE_DATA = 3;
  
                           for (int i = 0; i &lt; number_of_data_packets; i++){
                                  Log.e(&quot;TEST&quot;, Integer.toString(i));
                                 int obj_handle = data[packet_start+1];
                                 switch (obj_handle)
                                 {
                                 case SYS_DIA_MAP_DATA:
                                     int sys = byteToUnsignedInt(data[packet_start+9]);
                                     int dia = byteToUnsignedInt(data[packet_start+11]);
                                     int map = byteToUnsignedInt(data[packet_start+13]);
                                     //create team string... 9+13~9+20   
                                     Log.e(&quot;RESULT&quot;, &quot;sys is &quot;+ sys);
                                     sendMessage(RECEIVED_SYS, sys);
                                     Log.e(&quot;RESULT&quot;, &quot;dia is &quot;+ dia);
                                     sendMessage(RECEIVED_DIA, dia);
                                     Log.e(&quot;RESULT&quot;, &quot;map is &quot;+ map);
  
                                     break;
                                 case PULSE_DATA:
                                     //parse
                                     int pulse = byteToUnsignedInt(data[packet_start+5]);
                                     Log.e(&quot;RESULT&quot;, &quot;pulse is &quot; + pulse);
                                     sendMessage(RECEIVED_PUL, pulse);
                                     break;
                                 case ERROR_CODE_DATA:
                                     //need more signal
                                     break;
                                 }
                                 packet_start += 1;//4 + data[packet_start+3];   //4 = ignore beginning four bytes
                             }  
                       }
                       else if (data[0] == (byte) 0xE4)
                       {
                     
                           count = 4;
                           (new WriteThread(mFd)).start();
                       }
                       //zero out the data
                       for (int i = 0; i &lt; data.length; i++){
                           data[i] = (byte) 0x00;
                       }
                   }
                   sendMessage(STATUS_READ_DATA, 0);
              }
          } catch(IOException ioe) {}
          if (mFd != null) {
              try {
                  mFd.close();
              } catch (IOException e) { /* Do nothing. */ }
          }
          sendMessage(STATUS_READ_DATA_DONE, 0);
      }
  }
  
  private class WriteThread extends Thread {
      private ParcelFileDescriptor mFd;
  
      public WriteThread(ParcelFileDescriptor fd) {
          super();
          mFd = fd;
      }
  
      @Override
      public void run() {
          FileOutputStream fos = new FileOutputStream(mFd.getFileDescriptor());
          final byte data_AR[] = new byte[] {         (byte) 0xE3, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x2C, 
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x50, (byte) 0x79,
                                                      (byte) 0x00, (byte) 0x26,
                                                      (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x80, (byte) 0x00,
                                                      (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x08,  //bt add for phone, can be automate in the future
                                                      (byte) 0x3C, (byte) 0x5A, (byte) 0x37, (byte) 0xFF, 
                                                      (byte) 0xFE, (byte) 0x95, (byte) 0xEE, (byte) 0xE3,
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00, 
                                                      (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
          final byte data_DR[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x12,
                                                      (byte) 0x00, (byte) 0x10,
                                                      (byte) invoke[0], (byte) invoke[1],
                                                      (byte) 0x02, (byte) 0x01,
                                                      (byte) 0x00, (byte) 0x0A,
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x0D, (byte) 0x1D,
                                                      (byte) 0x00, (byte) 0x00 };
  
          final byte get_MDS[] = new byte[] {         (byte) 0xE7, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x0E,
                                                      (byte) 0x00, (byte) 0x0C,
                                                      (byte) 0x00, (byte) 0x24,
                                                      (byte) 0x01, (byte) 0x03,
                                                      (byte) 0x00, (byte) 0x06,
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x00 };
  
          final byte data_RR[] = new byte[] {         (byte) 0xE5, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x02,
                                                      (byte) 0x00, (byte) 0x00 };
  
          final byte data_RRQ[] = new byte[] {        (byte) 0xE4, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x02,
                                                      (byte) 0x00, (byte) 0x00 };
  
          final byte data_ABORT[] = new byte[] {      (byte) 0xE6, (byte) 0x00,
                                                      (byte) 0x00, (byte) 0x02,
                                                      (byte) 0x00, (byte) 0x00 };
          try {
              Log.i(TAG, String.valueOf(count));
              if (count == 1)
              {
                  fos.write(data_AR);
                  Log.i(TAG, &quot;Association Responded!&quot;);
              }  
              else if (count == 2)
              {
                  fos.write(get_MDS);
                  Log.i(TAG, &quot;Get MDS object attributes!&quot;);
              }
              else if (count == 3) 
              {
                  fos.write(data_DR);
                  Log.i(TAG, &quot;Data Responsed!&quot;);
              }
              else if (count == 4)
              {
                  fos.write(data_RR);
                  Log.i(TAG, &quot;Data Released!&quot;);
              }
          } catch(IOException ioe) {}
      }
  </code></pre>
  <p>The hex representation of the data is the following. I believe this data hold the values from the blood pressure values but may be wrong. The only reason I believe this is because in the PDF linked above it days the data will start with the hex value e7.</p>
  <blockquote>
  <p>03-23 20:14:44.186: I/BluetoothHDPService(23652):
  e70000da00d80024020300d20000000a00cc0928002000104f4d524f4e204845414c544843415245000c48454d2d373038312d4954000984000a0008002209225835c3280a5a000800010004100700010a4400024000092d00360002003200010001001653455249414c5f4e554d4245523a200000000000004100050001001046575f5245564953494f4e3a203130310914000400005dc00a4b0016000200120201000801000001000200070202000200000a450010c0101f00ffffffff00640000000000000a550008000100040a620006098700082010010100013600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</p>
  </blockquote>