Bug 1207011 - Send Bluetooth OBEX End-of-Body header individually to improve the compatibility with other devices. r=btian
authorJamin Liu <6jamin@gmail.com>
Wed, 30 Sep 2015 03:41:00 +0200
changeset 265515 2e7784fb1b3de2b4650ed16fdd1497b5e9cbd055
parent 265335 b8f68e468d43c13a13081a911c73718a6954edcb
child 265516 25f60d147da222beb28a2a4a3bcdaa80c4663ad7
push id15472
push usercbook@mozilla.com
push dateFri, 02 Oct 2015 11:51:34 +0000
treeherderfx-team@2c33ef6b27e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1207011
milestone44.0a1
Bug 1207011 - Send Bluetooth OBEX End-of-Body header individually to improve the compatibility with other devices. r=btian
dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
@@ -837,18 +837,19 @@ BluetoothPbapManager::ReplyToGet(uint16_
   /**
    * This response consists of following parts:
    * - Part 1: [response code:1][length:2]
    *
    * If |mPhonebookSizeRequired| is true,
    * - Part 2: [headerId:1][length:2][PhonebookSize:4]
    * - Part 3: [headerId:1][length:2][EndOfBody:0]
    * Otherwise,
-   * - Part 2: [headerId:1][length:2][Body:var]
-   * - (optional) Part 3: [headerId:1][length:2][EndOfBody:0]
+   * - Part 2a: [headerId:1][length:2][EndOfBody:0]
+   *   or
+   * - Part 2b: [headerId:1][length:2][Body:var]
    */
   uint8_t* res = new uint8_t[mRemoteMaxPacketLength];
   uint8_t opcode;
 
   // ---- Part 1: [response code:1][length:2] ---- //
   // [response code:1][length:2] will be set in |SendObexData|.
   // Reserve index for them here
   unsigned int index = kObexRespHeaderSize;
@@ -878,50 +879,64 @@ BluetoothPbapManager::ReplyToGet(uint16_
     // ---- Part 3: [headerId:1][length:2][EndOfBody:0] ---- //
     opcode = ObexResponseCode::Success;
     index += AppendHeaderEndOfBody(&res[index]);
 
     mPhonebookSizeRequired = false;
   } else {
     MOZ_ASSERT(mVCardDataStream);
 
-    // ---- Part 2: [headerId:1][length:2][Body:var] ---- //
-    // Compute remaining packet size to append Body, excluding Body's header
-    uint32_t remainingPacketSize =
-      mRemoteMaxPacketLength - kObexBodyHeaderSize - index;
-
-    // Read vCard data from input stream
-    uint32_t numRead = 0;
-    nsAutoArrayPtr<char> buf(new char[remainingPacketSize]);
-    nsresult rv = mVCardDataStream->Read(buf, remainingPacketSize, &numRead);
+    uint64_t bytesAvailable = 0;
+    nsresult rv = mVCardDataStream->Available(&bytesAvailable);
     if (NS_FAILED(rv)) {
-      BT_LOGR("Failed to read from input stream. rv=0x%x",
+      BT_LOGR("Failed to get available bytes from input stream. rv=0x%x",
               static_cast<uint32_t>(rv));
       return false;
     }
 
-    if (numRead) {
-      index += AppendHeaderBody(&res[index],
-                                remainingPacketSize,
-                                (uint8_t*) buf.forget(),
-                                numRead);
-    }
-
-    // More GET requests are required if remaining packet size isn't
-    // enough for 1) number of bytes read plus 2) one EndOfBody's header
-    if (numRead + kObexBodyHeaderSize > remainingPacketSize) {
-      opcode = ObexResponseCode::Continue;
-    } else {
-      // ---- Part 3: [headerId:1][length:2][EndOfBody:0] ---- //
-      opcode = ObexResponseCode::Success;
+    /*
+     * In practice, some platforms can only handle zero length End-of-Body
+     * header separately with Body header.
+     * Thus, append End-of-Body only if the data stream had been sent out,
+     * otherwise, send 'Continue' to request for next GET request.
+     */
+    if (!bytesAvailable) {
+      // ----  Part 2a: [headerId:1][length:2][EndOfBody:0] ---- //
       index += AppendHeaderEndOfBody(&res[index]);
 
       // Close input stream
       mVCardDataStream->Close();
       mVCardDataStream = nullptr;
+
+      opcode = ObexResponseCode::Success;
+    } else {
+      // Compute remaining packet size to append Body, excluding Body's header
+      uint32_t remainingPacketSize =
+        mRemoteMaxPacketLength - kObexBodyHeaderSize - index;
+
+      // Read vCard data from input stream
+      uint32_t numRead = 0;
+      nsAutoArrayPtr<char> buf(new char[remainingPacketSize]);
+      rv = mVCardDataStream->Read(buf, remainingPacketSize, &numRead);
+      if (NS_FAILED(rv)) {
+        BT_LOGR("Failed to read from input stream. rv=0x%x",
+                static_cast<uint32_t>(rv));
+        return false;
+      }
+
+      // |numRead| must be non-zero as |bytesAvailable| is non-zero
+      MOZ_ASSERT(numRead);
+
+      // ----  Part 2b: [headerId:1][length:2][Body:var] ---- //
+      index += AppendHeaderBody(&res[index],
+                                remainingPacketSize,
+                                (uint8_t*) buf.forget(),
+                                numRead);
+
+      opcode = ObexResponseCode::Continue;
     }
   }
 
   SendObexData(res, opcode, index);
   delete [] res;
 
   return true;
 }