Bug 1141616: Lookup service channel in Bluedroid's OPP manager, r=btian
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 09 Sep 2015 13:20:57 +0200
changeset 261394 ee015390f701973fdaa46f06f010c2a6ca2198d3
parent 261393 a08d93552eba364d3ea3e4ccc5bad56673ec044b
child 261395 64bab3289232d1e464cd058829fcdaa87f97349b
push id17392
push usertdz@users.sourceforge.net
push dateWed, 09 Sep 2015 11:21:37 +0000
treeherderb2g-inbound@ee015390f701 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1141616
milestone43.0a1
Bug 1141616: Lookup service channel in Bluedroid's OPP manager, r=btian Bluedroid's |BluetoothOppManager| now retrieves the OBEX service's channel from the remote device. Previously this was done by the Bluedroid driver internally, but having this functionality in the manager itself will allow for future code sharing with the BlueZ backend.
dom/bluetooth/bluedroid/BluetoothOppManager.cpp
dom/bluetooth/bluedroid/BluetoothOppManager.h
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -50,16 +50,20 @@ namespace {
 
   /*
    * The format of the appended header of an PUT request is
    * [headerId:1][header length:4]
    * P.S. Length of name header is 4 since unicode is 2 bytes per char.
    */
   static const uint32_t kPutRequestAppendHeaderSize = 5;
 
+  // The default timeout we permit to wait for SDP updating if we can't get
+  // service channel.
+  static const double kSdpUpdatingTimeoutMs = 3000.0;
+
   // UUID of OBEX Object Push
   static const BluetoothUuid kObexObjectPush = {
     {
       0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
       0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
     }
   };
 
@@ -193,16 +197,17 @@ private:
 BluetoothOppManager::BluetoothOppManager() : mConnected(false)
                                            , mRemoteObexVersion(0)
                                            , mRemoteConnectionFlags(0)
                                            , mRemoteMaxPacketLength(0)
                                            , mLastCommand(0)
                                            , mPacketLength(0)
                                            , mPutPacketReceivedLength(0)
                                            , mBodySegmentLength(0)
+                                           , mNeedsUpdatingSdpRecords(false)
                                            , mAbortFlag(false)
                                            , mNewFileFlag(false)
                                            , mPutFinalFlag(false)
                                            , mSendTransferCompleteFlag(false)
                                            , mSuccessFlag(false)
                                            , mIsServer(true)
                                            , mWaitingForConfirmationFlag(false)
                                            , mFileLength(0)
@@ -289,20 +294,27 @@ BluetoothOppManager::ConnectInternal(con
   mIsServer = false;
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs || sInShutdown || mSocket) {
     OnSocketConnectError(mSocket);
     return;
   }
 
+  mNeedsUpdatingSdpRecords = true;
+
+  nsString uuid;
+  BluetoothUuidHelper::GetString(BluetoothServiceClass::OBJECT_PUSH, uuid);
+
+  if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
+
   mSocket = new BluetoothSocket(this);
-  mSocket->Connect(aDeviceAddress, kObexObjectPush,
-                   BluetoothSocketType::RFCOMM, -1,
-                   false, true);
 }
 
 void
 BluetoothOppManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
@@ -1604,23 +1616,66 @@ BluetoothOppManager::AcquireSdcardMountL
   return true;
 }
 
 void
 BluetoothOppManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
                                          const nsAString& aServiceUuid,
                                          int aChannel)
 {
-  MOZ_ASSERT(false);
+  BluetoothUuid serviceUuid;
+  StringToUuid(aServiceUuid, serviceUuid);
+
+  if (aChannel < 0) {
+    BluetoothService* bs = BluetoothService::Get();
+    if (!bs || sInShutdown) {
+      OnSocketConnectError(mSocket);
+      return;
+    }
+
+    if (mNeedsUpdatingSdpRecords) {
+      mNeedsUpdatingSdpRecords = false;
+      mLastServiceChannelCheck = TimeStamp::Now();
+    } else {
+      // Refresh SDP records until it gets valid service channel
+      // unless timeout is hit.
+      TimeDuration duration = TimeStamp::Now() - mLastServiceChannelCheck;
+      if (duration.ToMilliseconds() >= kSdpUpdatingTimeoutMs) {
+        OnSocketConnectError(mSocket);
+        return;
+      }
+    }
+
+    if (!bs->UpdateSdpRecords(aDeviceAddress, this)) {
+      OnSocketConnectError(mSocket);
+      return;
+    }
+  }
+
+  mSocket->Connect(aDeviceAddress, serviceUuid,
+                   BluetoothSocketType::RFCOMM, aChannel,
+                   false, true);
 }
 
 void
 BluetoothOppManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
 {
-  MOZ_ASSERT(false);
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs || sInShutdown) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
+
+  nsString uuid;
+  BluetoothUuidHelper::GetString(BluetoothServiceClass::OBJECT_PUSH, uuid);
+
+  if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
 }
 
 void
 BluetoothOppManager::Connect(const nsAString& aDeviceAddress,
                              BluetoothProfileController* aController)
 {
   MOZ_ASSERT(false);
 }
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h
@@ -141,16 +141,28 @@ private:
   int mLastCommand;
 
   int mPacketLength;
   int mPutPacketReceivedLength;
   int mBodySegmentLength;
   int mUpdateProgressCounter;
 
   /**
+   * When it is true and the target service on target device couldn't be found,
+   * refreshing SDP records is necessary.
+   */
+  bool mNeedsUpdatingSdpRecords;
+
+  /**
+   * This holds the time when OPP manager fail to get service channel and
+   * prepare to refresh SDP records.
+   */
+  mozilla::TimeStamp mLastServiceChannelCheck;
+
+  /**
    * Set when StopSendingFile() is called.
    */
   bool mAbortFlag;
 
   /**
    * Set when receiving the first PUT packet of a new file
    */
   bool mNewFileFlag;