Bug 802590 - Patch 3: Implemented the logic, r=qdot
authorEric Chou <echou@mozilla.com>
Fri, 19 Oct 2012 14:16:13 +0800
changeset 110881 96184c897bfcb26e64dd7d0c434bbaa4b231b019
parent 110880 93f9402ae7bc26c8d9076242a10c9638072fe23b
child 110882 9098fb489c6e8556e58bab376b81eff405941e73
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersqdot
bugs802590
milestone19.0a1
Bug 802590 - Patch 3: Implemented the logic, r=qdot
dom/bluetooth/BluetoothOppManager.cpp
dom/bluetooth/BluetoothOppManager.h
--- a/dom/bluetooth/BluetoothOppManager.cpp
+++ b/dom/bluetooth/BluetoothOppManager.cpp
@@ -95,16 +95,17 @@ BluetoothOppManager::BluetoothOppManager
                                            , mRemoteObexVersion(0)
                                            , mRemoteConnectionFlags(0)
                                            , mRemoteMaxPacketLength(0)
                                            , mAbortFlag(false)
                                            , mReadFileThread(nullptr)
                                            , mPacketLeftLength(0)
                                            , mReceiving(false)
                                            , mPutFinal(false)
+                                           , mWaitingForConfirmationFlag(false)
 {
   // FIXME / Bug 800249:
   //   mConnectedDeviceAddress is Bluetooth address of connected device,
   //   we will be able to get this value after bug 800249 lands. For now,
   //   just assign a fake value to it.
   mConnectedDeviceAddress.AssignASCII("00:00:00:00:00:00");
 }
 
@@ -214,17 +215,32 @@ BluetoothOppManager::StopSendingFile(Blu
 
   return true;
 }
 
 void
 BluetoothOppManager::ConfirmReceivingFile(bool aConfirm,
                                           BluetoothReplyRunnable* aRunnable)
 {
-  // FIXME(Eric): Will implement in the third patch
+  if (!mWaitingForConfirmationFlag) {
+    NS_WARNING("We are not waiting for a confirmation now.");
+    return;
+  }
+
+  NS_ASSERTION(mPacketLeftLength == 0,
+               "Should not be in the middle of receiving a PUT packet.");
+
+  mWaitingForConfirmationFlag = false;
+  ReplyToPut(mPutFinal, aConfirm);
+
+  if (mPutFinal || !aConfirm) {
+    mReceiving = false;
+    FileTransferComplete(mConnectedDeviceAddress, aConfirm, true, sFileName,
+                         sSentFileLength, sContentType);
+  }
 }
 
 // Virtual function of class SocketConsumer
 void
 BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
 {
   uint8_t opCode;
   int packetLength;
@@ -367,18 +383,18 @@ BluetoothOppManager::ReceiveSocketData(U
       if (!mReceiving) {
         MOZ_ASSERT(mPacketLeftLength == 0);
         ParseHeaders(&aMessage->mData[3], receivedLength - 3, &pktHeaders);
 
         pktHeaders.GetName(sFileName);
         pktHeaders.GetContentType(sContentType);
         pktHeaders.GetLength(&sFileLength);
 
-        ReceivingFileConfirmation(mConnectedDeviceAddress, sFileName, sFileLength, sContentType);
         mReceiving = true;
+        mWaitingForConfirmationFlag = true;
       }
 
       /*
        * A PUT request from remote devices may be divided into multiple parts.
        * In other words, one request may need to be received multiple times,
        * so here we keep a variable mPacketLeftLength to indicate if current
        * PUT request is done.
        */
@@ -390,22 +406,27 @@ BluetoothOppManager::ReceiveSocketData(U
         mPacketLeftLength = packetLength - receivedLength;
       } else {
         NS_ASSERTION(mPacketLeftLength >= receivedLength,
                      "Invalid packet length");
         mPacketLeftLength -= receivedLength;
       }
 
       if (mPacketLeftLength == 0) {
-        ReplyToPut(mPutFinal);
+        if (mWaitingForConfirmationFlag) {
+          ReceivingFileConfirmation(mConnectedDeviceAddress, sFileName,
+                                    sFileLength, sContentType);
+        } else {
+          ReplyToPut(mPutFinal, true);
 
-        if (mPutFinal) {
-          mReceiving = false;
-          FileTransferComplete(mConnectedDeviceAddress, true, true, sFileName,
-                               sSentFileLength, sContentType);
+          if (mPutFinal) {
+            mReceiving = false;
+            FileTransferComplete(mConnectedDeviceAddress, true, true, sFileName,
+                                 sSentFileLength, sContentType);
+          }
         }
       }
     }
   }
 }
 
 void
 BluetoothOppManager::SendConnectRequest()
@@ -571,29 +592,37 @@ BluetoothOppManager::ReplyToDisconnect()
   SetObexPacketInfo(req, ObexResponseCode::Success, index);
 
   UnixSocketRawData* s = new UnixSocketRawData(index);
   memcpy(s->mData, req, s->mSize);
   SendSocketData(s);
 }
 
 void
-BluetoothOppManager::ReplyToPut(bool aFinal)
+BluetoothOppManager::ReplyToPut(bool aFinal, bool aContinue)
 {
   if (!mConnected) return;
 
   // Section 3.3.2 "Disconnect", IrOBEX 1.2
   // [opcode:1][length:2][Headers:var]
   uint8_t req[255];
   int index = 3;
 
-  if (aFinal) {
-    SetObexPacketInfo(req, ObexResponseCode::Success, index);
+  if (aContinue) {
+    if (aFinal) {
+      SetObexPacketInfo(req, ObexResponseCode::Success, index);
+    } else {
+      SetObexPacketInfo(req, ObexResponseCode::Continue, index);
+    }
   } else {
-    SetObexPacketInfo(req, ObexResponseCode::Continue, index);
+    if (aFinal) {
+      SetObexPacketInfo(req, ObexResponseCode::Unauthorized, index);
+    } else {
+      SetObexPacketInfo(req, ObexResponseCode::Unauthorized & (~FINAL_BIT), index);
+    }
   }
 
   UnixSocketRawData* s = new UnixSocketRawData(index);
   memcpy(s->mData, req, s->mSize);
   SendSocketData(s);
 }
 
 void
--- a/dom/bluetooth/BluetoothOppManager.h
+++ b/dom/bluetooth/BluetoothOppManager.h
@@ -78,32 +78,33 @@ private:
                       uint32_t aProcessedLength,
                       uint32_t aFileLength);
   void ReceivingFileConfirmation(const nsString& aAddress,
                                  const nsString& aFileName,
                                  uint32_t aFileLength,
                                  const nsString& aContentType);
   void ReplyToConnect();
   void ReplyToDisconnect();
-  void ReplyToPut(bool aFinal);
+  void ReplyToPut(bool aFinal, bool aContinue);
   virtual void OnConnectSuccess() MOZ_OVERRIDE;
   virtual void OnConnectError() MOZ_OVERRIDE;
   virtual void OnDisconnect() MOZ_OVERRIDE;
 
   bool mConnected;
   int mConnectionId;
   int mLastCommand;
   uint8_t mRemoteObexVersion;
   uint8_t mRemoteConnectionFlags;
   int mRemoteMaxPacketLength;
   bool mAbortFlag;
   int mPacketLeftLength;
   nsString mConnectedDeviceAddress;
   bool mReceiving;
   bool mPutFinal;
+  bool mWaitingForConfirmationFlag;
 
   nsCOMPtr<nsIDOMBlob> mBlob;
   nsCOMPtr<nsIThread> mReadFileThread;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif