Bug 1102703 - Extend internal interfaces to sync with android lollipop and bluez 5.26 (handsfree). r=btian, r=tzimmermann
☠☠ backed out by b4926227268f ☠ ☠
authorBruce Sun <brsun@mozilla.com>
Thu, 08 Jan 2015 11:46:43 +0800
changeset 248495 db035be5bc6ccbb71556e4fe7e9f19750daa1a58
parent 248494 411ab2917e49547a133d95282849eff928a59344
child 248496 9f067e4973ebec2447d6caa7dadea196c5d2ca39
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian, tzimmermann
bugs1102703
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1102703 - Extend internal interfaces to sync with android lollipop and bluez 5.26 (handsfree). r=btian, r=tzimmermann
dom/bluetooth/BluetoothCommon.h
dom/bluetooth/BluetoothInterface.h
dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp
dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h
dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h
--- a/dom/bluetooth/BluetoothCommon.h
+++ b/dom/bluetooth/BluetoothCommon.h
@@ -317,16 +317,22 @@ enum BluetoothHandsfreeConnectionState
   HFP_CONNECTION_STATE_DISCONNECTING
 };
 
 enum BluetoothHandsfreeNetworkState {
   HFP_NETWORK_STATE_NOT_AVAILABLE,
   HFP_NETWORK_STATE_AVAILABLE
 };
 
+enum BluetoothHandsfreeWbsConfig {
+  HFP_WBS_NONE, /* Neither CVSD nor mSBC codec, but other optional codec.*/
+  HFP_WBS_NO,   /* CVSD */
+  HFP_WBS_YES   /* mSBC */
+};
+
 enum BluetoothHandsfreeNRECState {
   HFP_NREC_STOPPED,
   HFP_NREC_STARTED
 };
 
 enum BluetoothHandsfreeServiceType {
   HFP_SERVICE_TYPE_HOME,
   HFP_SERVICE_TYPE_ROAMING
--- a/dom/bluetooth/BluetoothInterface.h
+++ b/dom/bluetooth/BluetoothInterface.h
@@ -75,69 +75,82 @@ public:
   { }
 
   virtual void
   AudioStateNotification(BluetoothHandsfreeAudioState aState,
                          const nsAString& aBdAddr)
   { }
 
   virtual void
-  VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState)
+  VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState,
+                               const nsAString& aBdAddr)
   { }
 
   virtual void
-  AnswerCallNotification()
+  AnswerCallNotification(const nsAString& aBdAddr)
+  { }
+
+  virtual void
+  HangupCallNotification(const nsAString& aBdAddr)
   { }
 
   virtual void
-  HangupCallNotification()
+  VolumeNotification(BluetoothHandsfreeVolumeType aType,
+                     int aVolume,
+                     const nsAString& aBdAddr)
   { }
 
   virtual void
-  VolumeNotification(BluetoothHandsfreeVolumeType aType, int aVolume)
+  DialCallNotification(const nsAString& aNumber,
+                       const nsAString& aBdAddr)
   { }
 
   virtual void
-  DialCallNotification(const nsAString& aNumber)
-  { }
-
-  virtual void
-  DtmfNotification(char aDtmf)
+  DtmfNotification(char aDtmf,
+                   const nsAString& aBdAddr)
   { }
 
   virtual void
-  NRECNotification(BluetoothHandsfreeNRECState aNrec)
+  NRECNotification(BluetoothHandsfreeNRECState aNrec,
+                   const nsAString& aBdAddr)
   { }
 
   virtual void
-  CallHoldNotification(BluetoothHandsfreeCallHoldType aChld)
+  WbsNotification(BluetoothHandsfreeWbsConfig aWbs,
+                  const nsAString& aBdAddr)
   { }
 
   virtual void
-  CnumNotification()
+  CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
+                       const nsAString& aBdAddr)
+  { }
+
+  virtual void
+  CnumNotification(const nsAString& aBdAddr)
   { }
 
   virtual void
-  CindNotification()
+  CindNotification(const nsAString& aBdAddr)
   { }
 
   virtual void
-  CopsNotification()
+  CopsNotification(const nsAString& aBdAddr)
   { }
 
   virtual void
-  ClccNotification()
+  ClccNotification(const nsAString& aBdAddr)
   { }
 
   virtual void
-  UnknownAtNotification(const nsACString& aAtString)
+  UnknownAtNotification(const nsACString& aAtString,
+                        const nsAString& aBdAddr)
   { }
 
   virtual void
-  KeyPressedNotification()
+  KeyPressedNotification(const nsAString& aBdAddr)
   { }
 
 protected:
   BluetoothHandsfreeNotificationHandler()
   { }
 };
 
 class BluetoothHandsfreeResultHandler
@@ -168,82 +181,95 @@ public:
   virtual void DeviceStatusNotification() { }
 
   virtual void CopsResponse() { }
   virtual void CindResponse() { }
   virtual void FormattedAtResponse() { }
   virtual void AtResponse() { }
   virtual void ClccResponse() { }
   virtual void PhoneStateChange() { }
+
+  virtual void ConfigureWbs() { }
 };
 
 class BluetoothHandsfreeInterface
 {
 public:
   virtual void Init(
     BluetoothHandsfreeNotificationHandler* aNotificationHandler,
-    BluetoothHandsfreeResultHandler* aRes) = 0;
+    int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
 
   virtual void Connect(const nsAString& aBdAddr,
                        BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void Disconnect(const nsAString& aBdAddr,
                           BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void ConnectAudio(const nsAString& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void DisconnectAudio(const nsAString& aBdAddr,
                                BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Voice Recognition */
 
-  virtual void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
+  virtual void StartVoiceRecognition(const nsAString& aBdAddr,
+                                     BluetoothHandsfreeResultHandler* aRes) = 0;
+  virtual void StopVoiceRecognition(const nsAString& aBdAddr,
+                                    BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Volume */
 
   virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
+                             const nsAString& aBdAddr,
                              BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Device status */
 
   virtual void DeviceStatusNotification(
     BluetoothHandsfreeNetworkState aNtkState,
     BluetoothHandsfreeServiceType aSvcType,
     int aSignal, int aBattChg, BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Responses */
 
-  virtual void CopsResponse(const char* aCops,
+  virtual void CopsResponse(const char* aCops, const nsAString& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld,
                             BluetoothHandsfreeCallState aCallSetupState,
                             int aSignal, int aRoam, int aBattChg,
+                            const nsAString& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void FormattedAtResponse(const char* aRsp,
+  virtual void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr,
                                    BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+  virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode,
+                          int aErrorCode, const nsAString& aBdAddr,
                           BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
                             BluetoothHandsfreeCallState aState,
                             BluetoothHandsfreeCallMode aMode,
                             BluetoothHandsfreeCallMptyType aMpty,
                             const nsAString& aNumber,
                             BluetoothHandsfreeCallAddressType aType,
+                            const nsAString& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Phone State */
 
   virtual void PhoneStateChange(int aNumActive, int aNumHeld,
                                 BluetoothHandsfreeCallState aCallSetupState,
                                 const nsAString& aNumber,
                                 BluetoothHandsfreeCallAddressType aType,
                                 BluetoothHandsfreeResultHandler* aRes) = 0;
 
+  /* Wide Band Speech */
+  virtual void ConfigureWbs(const nsAString& aBdAddr,
+                            BluetoothHandsfreeWbsConfig aConfig,
+                            BluetoothHandsfreeResultHandler* aRes) = 0;
+
 protected:
   BluetoothHandsfreeInterface();
   virtual ~BluetoothHandsfreeInterface();
 };
 
 //
 // Bluetooth Advanced Audio Interface
 //
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
@@ -12,16 +12,19 @@ BEGIN_BLUETOOTH_NAMESPACE
 
 //
 // Handsfree module
 //
 
 BluetoothHandsfreeNotificationHandler*
   BluetoothDaemonHandsfreeModule::sNotificationHandler;
 
+nsString BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress(
+  NS_ConvertUTF8toUTF16(BLUETOOTH_ADDRESS_NONE));
+
 void
 BluetoothDaemonHandsfreeModule::SetNotificationHandler(
   BluetoothHandsfreeNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
 
 nsresult
@@ -404,16 +407,29 @@ BluetoothDaemonHandsfreeModule::PhoneSta
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
+nsresult
+BluetoothDaemonHandsfreeModule::ConfigureWbsCmd(
+  const nsAString& aBdAddr,
+  BluetoothHandsfreeWbsConfig aConfig,
+  BluetoothHandsfreeResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // TODO: to be implemented
+
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 // Responses
 //
 
 void
 BluetoothDaemonHandsfreeModule::ErrorRsp(
   const BluetoothDaemonPDUHeader& aHeader,
   BluetoothDaemonPDU& aPDU, BluetoothHandsfreeResultHandler* aRes)
 {
@@ -657,16 +673,22 @@ public:
     }
 
     /* Read address */
     rv = UnpackPDU(
       pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
     if (NS_FAILED(rv)) {
       return rv;
     }
+
+    if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) {
+      sConnectedDeviceAddress = aArg2;
+    } else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) {
+      sConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+    }
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
 BluetoothDaemonHandsfreeModule::ConnectionStateNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
@@ -681,18 +703,17 @@ class BluetoothDaemonHandsfreeModule::Au
   : private PDUInitOp
 {
 public:
   AudioStateInitOp(BluetoothDaemonPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeAudioState& aArg1,
-               nsString& aArg2) const
+  operator () (BluetoothHandsfreeAudioState& aArg1, nsString& aArg2) const
   {
     BluetoothDaemonPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -712,68 +733,146 @@ void
 BluetoothDaemonHandsfreeModule::AudioStateNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   AudioStateNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::AudioStateNotification,
     AudioStateInitOp(aPDU));
 }
 
+// Init operator class for VoiceRecognitionNotification
+class BluetoothDaemonHandsfreeModule::VoiceRecognitionInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  VoiceRecognitionInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothHandsfreeVoiceRecognitionState& aArg1,
+               nsString& aArg2) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read state */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   VoiceRecognitionNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
-    UnpackPDUInitOp(aPDU));
+    VoiceRecognitionInitOp(aPDU));
 }
 
+// Init operator class for AnswerCallNotification
+class BluetoothDaemonHandsfreeModule::AnswerCallInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  AnswerCallInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::AnswerCallNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   AnswerCallNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::AnswerCallNotification,
-    UnpackPDUInitOp(aPDU));
+    AnswerCallInitOp(aPDU));
 }
 
+// Init operator class for HangupCallNotification
+class BluetoothDaemonHandsfreeModule::HangupCallInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  HangupCallInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::HangupCallNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   HangupCallNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::HangupCallNotification,
-    UnpackPDUInitOp(aPDU));
+    HangupCallInitOp(aPDU));
 }
 
 // Init operator class for VolumeNotification
 class BluetoothDaemonHandsfreeModule::VolumeInitOp MOZ_FINAL
   : private PDUInitOp
 {
 public:
   VolumeInitOp(BluetoothDaemonPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2) const
+  operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2,
+               nsString& aArg3) const
   {
     BluetoothDaemonPDU& pdu = GetPDU();
 
     /* Read volume type */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read volume */
     rv = UnpackPDU(pdu, UnpackConversion<uint8_t, int>(aArg2));
     if (NS_FAILED(rv)) {
       return rv;
     }
+
+    /* Read address */
+    // TODO
+    aArg3 = sConnectedDeviceAddress;
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
 BluetoothDaemonHandsfreeModule::VolumeNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
@@ -788,138 +887,344 @@ class BluetoothDaemonHandsfreeModule::Di
   : private PDUInitOp
 {
 public:
   DialCallInitOp(BluetoothDaemonPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (nsString& aArg1, nsString& aArg2) const
   {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
     /* Read number */
-    nsresult rv = UnpackPDU(GetPDU(), UnpackString0(aArg1));
+    nsresult rv = UnpackPDU(pdu, UnpackString0(aArg1));
     if (NS_FAILED(rv)) {
       return rv;
     }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
 BluetoothDaemonHandsfreeModule::DialCallNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   DialCallNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::DialCallNotification,
     DialCallInitOp(aPDU));
 }
 
+// Init operator class for DtmfNotification
+class BluetoothDaemonHandsfreeModule::DtmfInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  DtmfInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (char& aArg1, nsString& aArg2) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read tone */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::DtmfNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   DtmfNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::DtmfNotification,
-    UnpackPDUInitOp(aPDU));
+    DtmfInitOp(aPDU));
 }
 
+// Init operator class for NRECNotification
+class BluetoothDaemonHandsfreeModule::NRECInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  NRECInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothHandsfreeNRECState& aArg1, nsString& aArg2) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read state */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::NRECNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   NRECNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::NRECNotification,
-    UnpackPDUInitOp(aPDU));
+    NRECInitOp(aPDU));
 }
 
+// Init operator class for CallHoldNotification
+class BluetoothDaemonHandsfreeModule::CallHoldInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  CallHoldInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothHandsfreeCallHoldType& aArg1, nsString& aArg2) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read type */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::CallHoldNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   CallHoldNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::CallHoldNotification,
-    UnpackPDUInitOp(aPDU));
+    CallHoldInitOp(aPDU));
 }
 
+// Init operator class for CnumNotification
+class BluetoothDaemonHandsfreeModule::CnumInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  CnumInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::CnumNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   CnumNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::CnumNotification,
-    UnpackPDUInitOp(aPDU));
+    CnumInitOp(aPDU));
 }
 
+// Init operator class for CindNotification
+class BluetoothDaemonHandsfreeModule::CindInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  CindInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::CindNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   CindNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::CindNotification,
-    UnpackPDUInitOp(aPDU));
+    CindInitOp(aPDU));
 }
 
+// Init operator class for CopsNotification
+class BluetoothDaemonHandsfreeModule::CopsInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  CopsInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::CopsNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   CopsNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::CopsNotification,
-    UnpackPDUInitOp(aPDU));
+    CopsInitOp(aPDU));
 }
 
+// Init operator class for ClccNotification
+class BluetoothDaemonHandsfreeModule::ClccInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  ClccInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::ClccNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   ClccNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::ClccNotification,
-    UnpackPDUInitOp(aPDU));
+    ClccInitOp(aPDU));
 }
 
 // Init operator class for UnknownAtNotification
 class BluetoothDaemonHandsfreeModule::UnknownAtInitOp MOZ_FINAL
   : private PDUInitOp
 {
 public:
   UnknownAtInitOp(BluetoothDaemonPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsCString& aArg1) const
+  operator () (nsCString& aArg1, nsString& aArg2) const
   {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
     /* Read string */
-    nsresult rv = UnpackPDU(GetPDU(), UnpackCString0(aArg1));
+    nsresult rv = UnpackPDU(pdu, UnpackCString0(aArg1));
     if (NS_FAILED(rv)) {
       return rv;
     }
+
+    /* Read address */
+    // TODO
+    aArg2 = sConnectedDeviceAddress;
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
 BluetoothDaemonHandsfreeModule::UnknownAtNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   UnknownAtNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
     UnknownAtInitOp(aPDU));
 }
 
+// Init operator class for KeyPressedNotification
+class BluetoothDaemonHandsfreeModule::KeyPressedInitOp MOZ_FINAL
+  : private PDUInitOp
+{
+public:
+  KeyPressedInitOp(BluetoothDaemonPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1) const
+  {
+    BluetoothDaemonPDU& pdu = GetPDU();
+
+    /* Read address */
+    // TODO
+    aArg1 = sConnectedDeviceAddress;
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
 void
 BluetoothDaemonHandsfreeModule::KeyPressedNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
 {
   KeyPressedNotification::Dispatch(
     &BluetoothHandsfreeNotificationHandler::KeyPressedNotification,
-    UnpackPDUInitOp(aPDU));
+    KeyPressedInitOp(aPDU));
 }
 
 void
 BluetoothDaemonHandsfreeModule::HandleNtf(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
   void* aUserData)
 {
   static void (BluetoothDaemonHandsfreeModule::* const HandleNtf[])(
@@ -992,17 +1297,17 @@ public:
 
 private:
   nsRefPtr<BluetoothHandsfreeResultHandler> mRes;
 };
 
 void
 BluetoothDaemonHandsfreeInterface::Init(
   BluetoothHandsfreeNotificationHandler* aNotificationHandler,
-  BluetoothHandsfreeResultHandler* aRes)
+  int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes)
 {
   // Set notification handler _before_ registering the module. It could
   // happen that we receive notifications, before the result handler runs.
   mModule->SetNotificationHandler(aNotificationHandler);
 
   InitResultHandler* res;
 
   if (aRes) {
@@ -1105,37 +1410,37 @@ BluetoothDaemonHandsfreeInterface::Disco
 
   mModule->DisconnectAudioCmd(aBdAddr, aRes);
 }
 
 /* Voice Recognition */
 
 void
 BluetoothDaemonHandsfreeInterface::StartVoiceRecognition(
-  BluetoothHandsfreeResultHandler* aRes)
+  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->StartVoiceRecognitionCmd(aRes);
 }
 
 void
 BluetoothDaemonHandsfreeInterface::StopVoiceRecognition(
-  BluetoothHandsfreeResultHandler* aRes)
+  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->StopVoiceRecognitionCmd(aRes);
 }
 
 /* Volume */
 
 void
 BluetoothDaemonHandsfreeInterface::VolumeControl(
-  BluetoothHandsfreeVolumeType aType, int aVolume,
+  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->VolumeControlCmd(aType, aVolume, aRes);
 }
 
 /* Device status */
@@ -1151,63 +1456,66 @@ BluetoothDaemonHandsfreeInterface::Devic
   mModule->DeviceStatusNotificationCmd(aNtkState, aSvcType, aSignal,
                                        aBattChg, aRes);
 }
 
 /* Responses */
 
 void
 BluetoothDaemonHandsfreeInterface::CopsResponse(
-  const char* aCops, BluetoothHandsfreeResultHandler* aRes)
+  const char* aCops, const nsAString& aBdAddr,
+  BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->CopsResponseCmd(aCops, aRes);
 }
 
 void
 BluetoothDaemonHandsfreeInterface::CindResponse(
   int aSvc, int aNumActive, int aNumHeld,
   BluetoothHandsfreeCallState aCallSetupState,
   int aSignal, int aRoam, int aBattChg,
-  BluetoothHandsfreeResultHandler* aRes)
+  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld, aCallSetupState,
                            aSignal, aRoam, aBattChg, aRes);
 }
 
 void
 BluetoothDaemonHandsfreeInterface::FormattedAtResponse(
-  const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
+  const char* aRsp, const nsAString& aBdAddr,
+  BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->FormattedAtResponseCmd(aRsp, aRes);
 }
 
 void
 BluetoothDaemonHandsfreeInterface::AtResponse(
   BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
-  BluetoothHandsfreeResultHandler* aRes)
+  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->AtResponseCmd(aResponseCode, aErrorCode, aRes);
 }
 
 void
 BluetoothDaemonHandsfreeInterface::ClccResponse(
   int aIndex, BluetoothHandsfreeCallDirection aDir,
   BluetoothHandsfreeCallState aState,
   BluetoothHandsfreeCallMode aMode,
   BluetoothHandsfreeCallMptyType aMpty,
   const nsAString& aNumber,
   BluetoothHandsfreeCallAddressType aType,
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->ClccResponseCmd(aIndex, aDir, aState, aMode, aMpty, aNumber,
                            aType, aRes);
 }
 
@@ -1222,16 +1530,28 @@ BluetoothDaemonHandsfreeInterface::Phone
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   mModule->PhoneStateChangeCmd(aNumActive, aNumHeld, aCallSetupState, aNumber,
                                aType, aRes);
 }
 
+/* Wide Band Speech */
+
+void
+BluetoothDaemonHandsfreeInterface::ConfigureWbs(
+  const nsAString& aBdAddr, BluetoothHandsfreeWbsConfig aConfig,
+  BluetoothHandsfreeResultHandler* aRes)
+{
+  MOZ_ASSERT(mModule);
+
+  mModule->ConfigureWbsCmd(aBdAddr, aConfig, aRes);
+}
+
 void
 BluetoothDaemonHandsfreeInterface::DispatchError(
   BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus)
 {
   BluetoothResultRunnable1<BluetoothHandsfreeResultHandler, void,
                            BluetoothStatus, BluetoothStatus>::Dispatch(
     aRes, &BluetoothHandsfreeResultHandler::OnError,
     ConstantInitOp1<BluetoothStatus>(aStatus));
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
@@ -106,16 +106,22 @@ public:
   /* Phone State */
 
   nsresult PhoneStateChangeCmd(int aNumActive, int aNumHeld,
                                BluetoothHandsfreeCallState aCallSetupState,
                                const nsAString& aNumber,
                                BluetoothHandsfreeCallAddressType aType,
                                BluetoothHandsfreeResultHandler* aRes);
 
+  /* Wide Band Speech */
+
+  nsresult ConfigureWbsCmd(const nsAString& aBdAddr,
+                           BluetoothHandsfreeWbsConfig aConfig,
+                           BluetoothHandsfreeResultHandler* aRes);
+
 protected:
   nsresult Send(BluetoothDaemonPDU* aPDU,
                 BluetoothHandsfreeResultHandler* aRes);
 
   void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
                  BluetoothDaemonPDU& aPDU, void* aUserData);
 
   //
@@ -208,70 +214,103 @@ protected:
 
   typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
                                          BluetoothHandsfreeAudioState,
                                          nsString,
                                          BluetoothHandsfreeAudioState,
                                          const nsAString&>
     AudioStateNotification;
 
-  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-    BluetoothHandsfreeVoiceRecognitionState>
+  typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
+    BluetoothHandsfreeVoiceRecognitionState, nsString,
+    BluetoothHandsfreeVoiceRecognitionState, const nsAString&>
     VoiceRecognitionNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     AnswerCallNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     HangupCallNotification;
 
+  typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
+    BluetoothHandsfreeVolumeType, int, nsString,
+    BluetoothHandsfreeVolumeType, int, const nsAString&>
+    VolumeNotification;
+
   typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
-                                         BluetoothHandsfreeVolumeType, int>
-    VolumeNotification;
-
-  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-                                         nsString, const nsAString&>
+    nsString, nsString,
+    const nsAString&, const nsAString&>
     DialCallNotification;
 
-  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-                                         char>
+  typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
+    char, nsString,
+    char, const nsAString&>
     DtmfNotification;
 
-  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-                                         BluetoothHandsfreeNRECState>
+  typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
+    BluetoothHandsfreeNRECState, nsString,
+    BluetoothHandsfreeNRECState, const nsAString&>
     NRECNotification;
 
+  typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
+    BluetoothHandsfreeCallHoldType, nsString,
+    BluetoothHandsfreeCallHoldType, const nsAString&>
+    CallHoldNotification;
+
   typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-                                         BluetoothHandsfreeCallHoldType>
-    CallHoldNotification;
-
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+    nsString,
+    const nsAString&>
     CnumNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     CindNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     CopsNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     ClccNotification;
 
-  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
-                                         nsCString, const nsACString&>
+  typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
+    nsCString, nsString,
+    const nsACString&, const nsAString&>
     UnknownAtNotification;
 
-  typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
+  typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
+    nsString,
+    const nsAString&>
     KeyPressedNotification;
 
+  class ConnectionStateInitOp;
   class AudioStateInitOp;
-  class ConnectionStateInitOp;
+  class VoiceRecognitionInitOp;
+  class AnswerCallInitOp;
+  class HangupCallInitOp;
+  class VolumeInitOp;
   class DialCallInitOp;
+  class DtmfInitOp;
+  class NRECInitOp;
+  class CallHoldInitOp;
+  class CnumInitOp;
+  class CindInitOp;
+  class CopsInitOp;
+  class ClccInitOp;
   class VolumeInitOp;
   class UnknownAtInitOp;
+  class KeyPressedInitOp;
 
   void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
                           BluetoothDaemonPDU& aPDU);
 
   void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
                      BluetoothDaemonPDU& aPDU);
 
   void VoiceRecognitionNtf(const BluetoothDaemonPDUHeader& aHeader,
@@ -316,16 +355,17 @@ protected:
   void KeyPressedNtf(const BluetoothDaemonPDUHeader& aHeader,
                      BluetoothDaemonPDU& aPDU);
 
   void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
                  BluetoothDaemonPDU& aPDU,
                  void* aUserData);
 
   static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
+  static nsString sConnectedDeviceAddress;
 };
 
 class BluetoothDaemonHandsfreeInterface MOZ_FINAL
   : public BluetoothHandsfreeInterface
 {
   class CleanupResultHandler;
   class InitResultHandler;
 
@@ -336,75 +376,86 @@ class BluetoothDaemonHandsfreeInterface 
   };
 
 public:
   BluetoothDaemonHandsfreeInterface(BluetoothDaemonHandsfreeModule* aModule);
   ~BluetoothDaemonHandsfreeInterface();
 
   void Init(
     BluetoothHandsfreeNotificationHandler* aNotificationHandler,
-    BluetoothHandsfreeResultHandler* aRes);
+    int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes);
   void Cleanup(BluetoothHandsfreeResultHandler* aRes);
 
   /* Connect / Disconnect */
 
   void Connect(const nsAString& aBdAddr,
                BluetoothHandsfreeResultHandler* aRes);
   void Disconnect(const nsAString& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes);
   void ConnectAudio(const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
   void DisconnectAudio(const nsAString& aBdAddr,
                        BluetoothHandsfreeResultHandler* aRes);
 
   /* Voice Recognition */
 
-  void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
-  void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
+  void StartVoiceRecognition(const nsAString& aBdAddr,
+                             BluetoothHandsfreeResultHandler* aRes);
+  void StopVoiceRecognition(const nsAString& aBdAddr,
+                            BluetoothHandsfreeResultHandler* aRes);
 
   /* Volume */
 
   void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
+                     const nsAString& aBdAddr,
                      BluetoothHandsfreeResultHandler* aRes);
 
   /* Device status */
 
   void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
                                 BluetoothHandsfreeServiceType aSvcType,
                                 int aSignal, int aBattChg,
                                 BluetoothHandsfreeResultHandler* aRes);
 
   /* Responses */
 
-  void CopsResponse(const char* aCops,
+  void CopsResponse(const char* aCops, const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
   void CindResponse(int aSvc, int aNumActive, int aNumHeld,
                     BluetoothHandsfreeCallState aCallSetupState,
                     int aSignal, int aRoam, int aBattChg,
+                    const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
-  void FormattedAtResponse(const char* aRsp,
+  void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
   void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+                  const nsAString& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes);
   void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
                     BluetoothHandsfreeCallState aState,
                     BluetoothHandsfreeCallMode aMode,
                     BluetoothHandsfreeCallMptyType aMpty,
                     const nsAString& aNumber,
                     BluetoothHandsfreeCallAddressType aType,
+                    const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
 
   /* Phone State */
 
   void PhoneStateChange(int aNumActive, int aNumHeld,
                         BluetoothHandsfreeCallState aCallSetupState,
                         const nsAString& aNumber,
                         BluetoothHandsfreeCallAddressType aType,
                         BluetoothHandsfreeResultHandler* aRes);
 
+  /* Wide Band Speech */
+  void ConfigureWbs(const nsAString& aBdAddr,
+                    BluetoothHandsfreeWbsConfig aConfig,
+                    BluetoothHandsfreeResultHandler* aRes);
+
 private:
   void DispatchError(BluetoothHandsfreeResultHandler* aRes,
                      BluetoothStatus aStatus);
 
   BluetoothDaemonHandsfreeModule* mModule;
 };
 
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp
@@ -70,79 +70,103 @@ struct BluetoothHandsfreeHALCallback
     ConnectionStateNotification;
 
   typedef BluetoothNotificationHALRunnable2<
     HandsfreeNotificationHandlerWrapper, void,
     BluetoothHandsfreeAudioState, nsString,
     BluetoothHandsfreeAudioState, const nsAString&>
     AudioStateNotification;
 
-  typedef BluetoothNotificationHALRunnable1<
+  typedef BluetoothNotificationHALRunnable2<
     HandsfreeNotificationHandlerWrapper, void,
-    BluetoothHandsfreeVoiceRecognitionState>
+    BluetoothHandsfreeVoiceRecognitionState, nsString,
+    BluetoothHandsfreeVoiceRecognitionState, const nsAString&>
     VoiceRecognitionNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     AnswerCallNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     HangupCallNotification;
 
+  typedef BluetoothNotificationHALRunnable3<
+    HandsfreeNotificationHandlerWrapper, void,
+    BluetoothHandsfreeVolumeType, int, nsString,
+    BluetoothHandsfreeVolumeType, int, const nsAString&>
+    VolumeNotification;
+
+  typedef BluetoothNotificationHALRunnable2<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, nsString, const nsAString&, const nsAString&>
+    DialCallNotification;
+
+  typedef BluetoothNotificationHALRunnable2<
+    HandsfreeNotificationHandlerWrapper, void,
+    char, nsString, char, const nsAString&>
+    DtmfNotification;
+
   typedef BluetoothNotificationHALRunnable2<
     HandsfreeNotificationHandlerWrapper, void,
-    BluetoothHandsfreeVolumeType, int>
-    VolumeNotification;
-
-  typedef BluetoothNotificationHALRunnable1<
-    HandsfreeNotificationHandlerWrapper, void, nsString, const nsAString&>
-    DialCallNotification;
-
-  typedef BluetoothNotificationHALRunnable1<
-    HandsfreeNotificationHandlerWrapper, void, char>
-    DtmfNotification;
-
-  typedef BluetoothNotificationHALRunnable1<
-    HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeNRECState>
+    BluetoothHandsfreeNRECState, nsString,
+    BluetoothHandsfreeNRECState, const nsAString&>
     NRECNotification;
 
-  typedef BluetoothNotificationHALRunnable1<
-    HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType>
+  typedef BluetoothNotificationHALRunnable2<
+    HandsfreeNotificationHandlerWrapper, void,
+    BluetoothHandsfreeCallHoldType, nsString,
+    BluetoothHandsfreeCallHoldType, const nsAString&>
     CallHoldNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     CnumNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     CindNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     CopsNotification;
 
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+  typedef BluetoothNotificationHALRunnable1<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     ClccNotification;
 
+  typedef BluetoothNotificationHALRunnable2<
+    HandsfreeNotificationHandlerWrapper, void,
+    nsCString, nsString, const nsACString&, const nsAString&>
+    UnknownAtNotification;
+
   typedef BluetoothNotificationHALRunnable1<
-    HandsfreeNotificationHandlerWrapper, void, nsCString, const nsACString&>
-    UnknownAtNotification;
-
-  typedef BluetoothNotificationHALRunnable0<
-    HandsfreeNotificationHandlerWrapper, void>
+    HandsfreeNotificationHandlerWrapper, void,
+    nsString, const nsAString&>
     KeyPressedNotification;
 
   // Bluedroid Handsfree callbacks
 
   static void
   ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr)
   {
+    if (aState == BTHF_CONNECTION_STATE_CONNECTED && aBdAddr) {
+      memcpy(&sConnectedDeviceAddress, aBdAddr,
+             sizeof(sConnectedDeviceAddress));
+    } else if (aState == BTHF_CONNECTION_STATE_DISCONNECTED) {
+      memset(&sConnectedDeviceAddress, 0,
+             sizeof(sConnectedDeviceAddress));
+    }
+
     ConnectionStateNotification::Dispatch(
       &BluetoothHandsfreeNotificationHandler::ConnectionStateNotification,
       aState, aBdAddr);
   }
 
   static void
   AudioState(bthf_audio_state_t aState, bt_bdaddr_t* aBdAddr)
   {
@@ -151,111 +175,128 @@ struct BluetoothHandsfreeHALCallback
       aState, aBdAddr);
   }
 
   static void
   VoiceRecognition(bthf_vr_state_t aState)
   {
     VoiceRecognitionNotification::Dispatch(
       &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
-      aState);
+      aState, &sConnectedDeviceAddress);
   }
 
   static void
   AnswerCall()
   {
     AnswerCallNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::AnswerCallNotification);
+      &BluetoothHandsfreeNotificationHandler::AnswerCallNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   HangupCall()
   {
     HangupCallNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::HangupCallNotification);
+      &BluetoothHandsfreeNotificationHandler::HangupCallNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   Volume(bthf_volume_type_t aType, int aVolume)
   {
     VolumeNotification::Dispatch(
       &BluetoothHandsfreeNotificationHandler::VolumeNotification,
-      aType, aVolume);
+      aType, aVolume, &sConnectedDeviceAddress);
   }
 
   static void
   DialCall(char* aNumber)
   {
     DialCallNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber);
+      &BluetoothHandsfreeNotificationHandler::DialCallNotification,
+      aNumber, &sConnectedDeviceAddress);
   }
 
   static void
   Dtmf(char aDtmf)
   {
     DtmfNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf);
+      &BluetoothHandsfreeNotificationHandler::DtmfNotification,
+      aDtmf, &sConnectedDeviceAddress);
   }
 
   static void
   NoiseReductionEchoCancellation(bthf_nrec_t aNrec)
   {
     NRECNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec);
+      &BluetoothHandsfreeNotificationHandler::NRECNotification,
+      aNrec, &sConnectedDeviceAddress);
   }
 
   static void
   CallHold(bthf_chld_type_t aChld)
   {
     CallHoldNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld);
+      &BluetoothHandsfreeNotificationHandler::CallHoldNotification,
+      aChld, &sConnectedDeviceAddress);
   }
 
   static void
   Cnum()
   {
     CnumNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::CnumNotification);
+      &BluetoothHandsfreeNotificationHandler::CnumNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   Cind()
   {
     CindNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::CindNotification);
+      &BluetoothHandsfreeNotificationHandler::CindNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   Cops()
   {
     CopsNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::CopsNotification);
+      &BluetoothHandsfreeNotificationHandler::CopsNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   Clcc()
   {
     ClccNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::ClccNotification);
+      &BluetoothHandsfreeNotificationHandler::ClccNotification,
+      &sConnectedDeviceAddress);
   }
 
   static void
   UnknownAt(char* aAtString)
   {
     UnknownAtNotification::Dispatch(
       &BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
-      aAtString);
+      aAtString, &sConnectedDeviceAddress);
   }
 
   static void
   KeyPressed()
   {
     KeyPressedNotification::Dispatch(
-      &BluetoothHandsfreeNotificationHandler::KeyPressedNotification);
+      &BluetoothHandsfreeNotificationHandler::KeyPressedNotification,
+      &sConnectedDeviceAddress);
   }
+
+  static bt_bdaddr_t sConnectedDeviceAddress;
+};
+
+bt_bdaddr_t BluetoothHandsfreeHALCallback::sConnectedDeviceAddress = {
+  {0, 0, 0, 0, 0, 0}
 };
 
 // Interface
 //
 
 BluetoothHandsfreeHALInterface::BluetoothHandsfreeHALInterface(
   const bthf_interface_t* aInterface)
 : mInterface(aInterface)
@@ -264,17 +305,17 @@ BluetoothHandsfreeHALInterface::Bluetoot
 }
 
 BluetoothHandsfreeHALInterface::~BluetoothHandsfreeHALInterface()
 { }
 
 void
 BluetoothHandsfreeHALInterface::Init(
   BluetoothHandsfreeNotificationHandler* aNotificationHandler,
-  BluetoothHandsfreeResultHandler* aRes)
+  int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes)
 {
   static bthf_callbacks_t sCallbacks = {
     sizeof(sCallbacks),
     BluetoothHandsfreeHALCallback::ConnectionState,
     BluetoothHandsfreeHALCallback::AudioState,
     BluetoothHandsfreeHALCallback::VoiceRecognition,
     BluetoothHandsfreeHALCallback::AnswerCall,
     BluetoothHandsfreeHALCallback::HangupCall,
@@ -395,45 +436,47 @@ BluetoothHandsfreeHALInterface::Disconne
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 /* Voice Recognition */
 
 void
 BluetoothHandsfreeHALInterface::StartVoiceRecognition(
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status = mInterface->start_voice_recognition();
 
   if (aRes) {
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::StartVoiceRecognition,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 void
 BluetoothHandsfreeHALInterface::StopVoiceRecognition(
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status = mInterface->stop_voice_recognition();
 
   if (aRes) {
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::StopVoiceRecognition,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 /* Volume */
 
 void
 BluetoothHandsfreeHALInterface::VolumeControl(
-  BluetoothHandsfreeVolumeType aType, int aVolume,
+  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status;
   bthf_volume_type_t type = BTHF_VOLUME_TYPE_SPK;
 
   if (NS_SUCCEEDED(Convert(aType, type))) {
     status = mInterface->volume_control(type, aVolume);
   } else {
@@ -473,32 +516,34 @@ BluetoothHandsfreeHALInterface::DeviceSt
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 /* Responses */
 
 void
 BluetoothHandsfreeHALInterface::CopsResponse(
-  const char* aCops, BluetoothHandsfreeResultHandler* aRes)
+  const char* aCops, const nsAString& aBdAddr,
+  BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status = mInterface->cops_response(aCops);
 
   if (aRes) {
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::CopsResponse,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 void
 BluetoothHandsfreeHALInterface::CindResponse(
   int aSvc, int aNumActive, int aNumHeld,
   BluetoothHandsfreeCallState aCallSetupState,
   int aSignal, int aRoam, int aBattChg,
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status;
   bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE;
 
   if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState))) {
     status = mInterface->cind_response(aSvc, aNumActive, aNumHeld,
                                        callSetupState, aSignal,
@@ -511,30 +556,32 @@ BluetoothHandsfreeHALInterface::CindResp
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::CindResponse,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 void
 BluetoothHandsfreeHALInterface::FormattedAtResponse(
-  const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
+  const char* aRsp, const nsAString& aBdAddr,
+  BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status = mInterface->formatted_at_response(aRsp);
 
   if (aRes) {
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::FormattedAtResponse,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
 void
 BluetoothHandsfreeHALInterface::AtResponse(
   BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status;
   bthf_at_response_t responseCode = BTHF_AT_RESPONSE_ERROR;
 
   if (NS_SUCCEEDED(Convert(aResponseCode, responseCode))) {
     status = mInterface->at_response(responseCode, aErrorCode);
   } else {
@@ -552,16 +599,17 @@ void
 BluetoothHandsfreeHALInterface::ClccResponse(
   int aIndex,
   BluetoothHandsfreeCallDirection aDir,
   BluetoothHandsfreeCallState aState,
   BluetoothHandsfreeCallMode aMode,
   BluetoothHandsfreeCallMptyType aMpty,
   const nsAString& aNumber,
   BluetoothHandsfreeCallAddressType aType,
+  const nsAString& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   bt_status_t status;
   bthf_call_direction_t dir = BTHF_CALL_DIRECTION_OUTGOING;
   bthf_call_state_t state = BTHF_CALL_STATE_ACTIVE;
   bthf_call_mode_t mode = BTHF_CALL_TYPE_VOICE;
   bthf_call_mpty_type_t mpty = BTHF_CALL_MPTY_TYPE_SINGLE;
   bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN;
@@ -608,9 +656,28 @@ BluetoothHandsfreeHALInterface::PhoneSta
 
   if (aRes) {
     DispatchBluetoothHandsfreeHALResult(
       aRes, &BluetoothHandsfreeResultHandler::PhoneStateChange,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
+/* Wide Band Speech */
+
+void
+BluetoothHandsfreeHALInterface::ConfigureWbs(
+  const nsAString& aBdAddr,
+  BluetoothHandsfreeWbsConfig aConfig,
+  BluetoothHandsfreeResultHandler* aRes)
+{
+  // TODO: to be implemented
+
+  bt_status_t status = BT_STATUS_UNSUPPORTED;
+
+  if (aRes) {
+    DispatchBluetoothHandsfreeHALResult(
+      aRes, &BluetoothHandsfreeResultHandler::ConfigureWbs,
+      ConvertDefault(status, STATUS_FAIL));
+  }
+}
+
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h
@@ -18,75 +18,87 @@ class BluetoothHALInterface;
 
 class BluetoothHandsfreeHALInterface MOZ_FINAL
   : public BluetoothHandsfreeInterface
 {
 public:
   friend class BluetoothHALInterface;
 
   void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler,
+            int aMaxNumClients,
             BluetoothHandsfreeResultHandler* aRes);
   void Cleanup(BluetoothHandsfreeResultHandler* aRes);
 
   /* Connect / Disconnect */
 
   void Connect(const nsAString& aBdAddr,
                BluetoothHandsfreeResultHandler* aRes);
   void Disconnect(const nsAString& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes);
   void ConnectAudio(const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
   void DisconnectAudio(const nsAString& aBdAddr,
                        BluetoothHandsfreeResultHandler* aRes);
 
   /* Voice Recognition */
 
-  void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
-  void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
+  void StartVoiceRecognition(const nsAString& aBdAddr,
+                             BluetoothHandsfreeResultHandler* aRes);
+  void StopVoiceRecognition(const nsAString& aBdAddr,
+                            BluetoothHandsfreeResultHandler* aRes);
 
   /* Volume */
 
   void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
+                     const nsAString& aBdAddr,
                      BluetoothHandsfreeResultHandler* aRes);
 
   /* Device status */
 
   void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
                                 BluetoothHandsfreeServiceType aSvcType,
                                 int aSignal, int aBattChg,
                                 BluetoothHandsfreeResultHandler* aRes);
 
   /* Responses */
 
-  void CopsResponse(const char* aCops,
+  void CopsResponse(const char* aCops, const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
   void CindResponse(int aSvc, int aNumActive, int aNumHeld,
                     BluetoothHandsfreeCallState aCallSetupState, int aSignal,
-                    int aRoam, int aBattChg,
+                    int aRoam, int aBattChg, const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
-  void FormattedAtResponse(const char* aRsp,
+  void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
   void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+                  const nsAString& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes);
   void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
                     BluetoothHandsfreeCallState aState,
                     BluetoothHandsfreeCallMode aMode,
                     BluetoothHandsfreeCallMptyType aMpty,
                     const nsAString& aNumber,
                     BluetoothHandsfreeCallAddressType aType,
+                    const nsAString& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
 
   /* Phone State */
 
   void PhoneStateChange(int aNumActive, int aNumHeld,
                         BluetoothHandsfreeCallState aCallSetupState,
                         const nsAString& aNumber,
                         BluetoothHandsfreeCallAddressType aType,
                         BluetoothHandsfreeResultHandler* aRes);
 
+  /* Wide Band Speech */
+
+  void ConfigureWbs(const nsAString& aBdAddr,
+                    BluetoothHandsfreeWbsConfig aConfig,
+                    BluetoothHandsfreeResultHandler* aRes);
+
 protected:
   BluetoothHandsfreeHALInterface(const bthf_interface_t* aInterface);
   ~BluetoothHandsfreeHALInterface();
 
 private:
   const bthf_interface_t* mInterface;
 };
 
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -52,16 +52,18 @@ namespace {
 
   // Wait 3.7 seconds until Dialer stops playing busy tone. '3' seconds is the
   // time window set in Dialer and the extra '0.7' second is a magic number.
   // The mechanism should be revised once we know the exact time at which
   // Dialer stops playing.
   static int sBusyToneInterval = 3700; //unit: ms
 } // anonymous namespace
 
+const int BluetoothHfpManager::MAX_NUM_CLIENTS = 1;
+
 static bool
 IsValidDtmf(const char aChar) {
   // Valid DTMF: [*#0-9ABCD]
   return (aChar == '*' || aChar == '#') ||
          (aChar >= '0' && aChar <= '9') ||
          (aChar >= 'A' && aChar <= 'D');
 }
 
@@ -303,17 +305,17 @@ public:
      */
     RunInit();
   }
 
   void RunInit()
   {
     BluetoothHfpManager* hfpManager = BluetoothHfpManager::Get();
 
-    mInterface->Init(hfpManager, this);
+    mInterface->Init(hfpManager, BluetoothHfpManager::MAX_NUM_CLIENTS, this);
   }
 
 private:
   BluetoothHandsfreeInterface* mInterface;
   nsRefPtr<BluetoothProfileResultHandler> mRes;
 };
 
 class InitResultHandlerRunnable MOZ_FINAL : public nsRunnable
@@ -633,18 +635,19 @@ BluetoothHfpManager::HandleVolumeChanged
   if (mReceiveVgsFlag) {
     mReceiveVgsFlag = false;
     return;
   }
 
   // Only send volume back when there's a connected headset
   if (IsConnected()) {
     NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
-    sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs,
-                                          new VolumeControlResultHandler());
+    sBluetoothHfpInterface->VolumeControl(
+      HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, mDeviceAddress,
+      new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
   nsCOMPtr<nsIMobileConnectionService> mcService =
     do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
@@ -762,17 +765,17 @@ BluetoothHfpManager::SendCLCC(Call& aCal
   if (callState == HFP_CALL_STATE_INCOMING &&
       FindFirstCall(nsITelephonyService::CALL_STATE_CONNECTED)) {
     callState = HFP_CALL_STATE_WAITING;
   }
 
   sBluetoothHfpInterface->ClccResponse(
     aIndex, aCall.mDirection, callState, HFP_CALL_MODE_VOICE,
     HFP_CALL_MPTY_TYPE_SINGLE, aCall.mNumber,
-    aCall.mType, new ClccResponseResultHandler());
+    aCall.mType, mDeviceAddress, new ClccResponseResultHandler());
 }
 
 class FormattedAtResponseResultHandler MOZ_FINAL
 : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -782,17 +785,17 @@ public:
 };
 
 void
 BluetoothHfpManager::SendLine(const char* aMessage)
 {
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   sBluetoothHfpInterface->FormattedAtResponse(
-    aMessage, new FormattedAtResponseResultHandler());
+    aMessage, mDeviceAddress, new FormattedAtResponseResultHandler());
 }
 
 class AtResponseResultHandler MOZ_FINAL
 : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -802,17 +805,17 @@ public:
 };
 
 void
 BluetoothHfpManager::SendResponse(BluetoothHandsfreeAtResponse aResponseCode)
 {
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   sBluetoothHfpInterface->AtResponse(
-    aResponseCode, 0, new AtResponseResultHandler());
+    aResponseCode, 0, mDeviceAddress, new AtResponseResultHandler());
 }
 
 class PhoneStateChangeResultHandler MOZ_FINAL
 : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
@@ -1356,34 +1359,34 @@ BluetoothHfpManager::AudioStateNotificat
   if (aState == HFP_AUDIO_STATE_CONNECTED ||
       aState == HFP_AUDIO_STATE_DISCONNECTED) {
     NotifyConnectionStateChanged(
       NS_LITERAL_STRING(BLUETOOTH_SCO_STATUS_CHANGED_ID));
   }
 }
 
 void
-BluetoothHfpManager::AnswerCallNotification()
+BluetoothHfpManager::AnswerCallNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NotifyDialer(NS_LITERAL_STRING("ATA"));
 }
 
 void
-BluetoothHfpManager::HangupCallNotification()
+BluetoothHfpManager::HangupCallNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NotifyDialer(NS_LITERAL_STRING("CHUP"));
 }
 
 void
 BluetoothHfpManager::VolumeNotification(
-  BluetoothHandsfreeVolumeType aType, int aVolume)
+  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(aVolume >= 0 && aVolume <= 15);
 
   if (aType == HFP_VOLUME_TYPE_MICROPHONE) {
     mCurrentVgm = aVolume;
   } else if (aType == HFP_VOLUME_TYPE_SPEAKER) {
@@ -1400,29 +1403,30 @@ BluetoothHfpManager::VolumeNotification(
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     NS_ENSURE_TRUE_VOID(os);
 
     os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
   }
 }
 
 void
-BluetoothHfpManager::DtmfNotification(char aDtmf)
+BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(IsValidDtmf(aDtmf));
 
   nsAutoCString message("VTS=");
   message += aDtmf;
   NotifyDialer(NS_ConvertUTF8toUTF16(message));
 }
 
 void
-BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld)
+BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
+                                          const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!IsSupportedChld((int)aChld)) {
     // We currently don't support Enhanced Call Control.
     // AT+CHLD=1x and AT+CHLD=2x will be ignored
     SendResponse(HFP_AT_RESPONSE_ERROR);
     return;
@@ -1430,17 +1434,18 @@ BluetoothHfpManager::CallHoldNotificatio
 
   SendResponse(HFP_AT_RESPONSE_OK);
 
   nsAutoCString message("CHLD=");
   message.AppendInt((int)aChld);
   NotifyDialer(NS_ConvertUTF8toUTF16(message));
 }
 
-void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber)
+void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber,
+                                               const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCString message = NS_ConvertUTF16toUTF8(aNumber);
 
   // There are three cases based on aNumber,
   // 1) Empty value:    Redial, BLDN
   // 2) >xxx:           Memory dial, ATD>xxx
@@ -1471,17 +1476,17 @@ void BluetoothHfpManager::DialCallNotifi
 
     nsAutoCString newMsg("ATD");
     newMsg += StringHead(message, message.Length() - 1);
     NotifyDialer(NS_ConvertUTF8toUTF16(newMsg));
   }
 }
 
 void
-BluetoothHfpManager::CnumNotification()
+BluetoothHfpManager::CnumNotification(const nsAString& aBdAddress)
 {
   static const uint8_t sAddressType[] {
     [HFP_CALL_ADDRESS_TYPE_UNKNOWN] = 0x81,
     [HFP_CALL_ADDRESS_TYPE_INTERNATIONAL] = 0x91 // for completeness
   };
 
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -1505,57 +1510,59 @@ public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     BT_WARNING("BluetoothHandsfreeInterface::CindResponse failed: %d",
                (int)aStatus);
   }
 };
 
 void
-BluetoothHfpManager::CindNotification()
+BluetoothHfpManager::CindNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   int numActive = GetNumberOfCalls(nsITelephonyService::CALL_STATE_CONNECTED);
   int numHeld = GetNumberOfCalls(nsITelephonyService::CALL_STATE_HELD);
   BluetoothHandsfreeCallState callState =
     ConvertToBluetoothHandsfreeCallState(GetCallSetupState());
 
-  sBluetoothHfpInterface->CindResponse(mService, numActive, numHeld,
-                                       callState, mSignal, mRoam, mBattChg,
-                                       new CindResponseResultHandler());
+  sBluetoothHfpInterface->CindResponse(
+    mService, numActive, numHeld,
+    callState, mSignal, mRoam, mBattChg,
+    aBdAddress,
+    new CindResponseResultHandler());
 }
 
 class CopsResponseResultHandler MOZ_FINAL
 : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     BT_WARNING("BluetoothHandsfreeInterface::CopsResponse failed: %d",
                (int)aStatus);
   }
 };
 
 void
-BluetoothHfpManager::CopsNotification()
+BluetoothHfpManager::CopsNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   sBluetoothHfpInterface->CopsResponse(
     NS_ConvertUTF16toUTF8(mOperatorName).get(),
-    new CopsResponseResultHandler());
+    aBdAddress, new CopsResponseResultHandler());
 }
 
 void
-BluetoothHfpManager::ClccNotification()
+BluetoothHfpManager::ClccNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint32_t callNumbers = mCurrentCallArray.Length();
   uint32_t i;
   for (i = 1; i < callNumbers; i++) {
     SendCLCC(mCurrentCallArray[i], i);
   }
@@ -1566,27 +1573,28 @@ BluetoothHfpManager::ClccNotification()
 
     SendCLCC(mCdmaSecondCall, 2);
   }
 
   SendResponse(HFP_AT_RESPONSE_OK);
 }
 
 void
-BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString)
+BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString,
+                                           const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BT_LOGR("[%s]", nsCString(aAtString).get());
 
   SendResponse(HFP_AT_RESPONSE_ERROR);
 }
 
 void
-BluetoothHfpManager::KeyPressedNotification()
+BluetoothHfpManager::KeyPressedNotification(const nsAString& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   bool hasActiveCall =
     (FindFirstCall(nsITelephonyService::CALL_STATE_CONNECTED) > 0);
 
   // Refer to AOSP HeadsetStateMachine.processKeyPressed
   if (FindFirstCall(nsITelephonyService::CALL_STATE_INCOMING)
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h
@@ -72,16 +72,18 @@ public:
 
 class BluetoothHfpManager : public BluetoothHfpManagerBase
                           , public BluetoothHandsfreeNotificationHandler
                           , public BatteryObserver
 {
 public:
   BT_DECL_HFP_MGR_BASE
 
+  static const int MAX_NUM_CLIENTS;
+
   void OnConnectError();
   void OnDisconnectError();
 
   virtual void GetName(nsACString& aName)
   {
     aName.AssignLiteral("HFP/HSP");
   }
 
@@ -112,29 +114,34 @@ public:
   //
   // Bluetooth notifications
   //
 
   void ConnectionStateNotification(BluetoothHandsfreeConnectionState aState,
                                    const nsAString& aBdAddress) MOZ_OVERRIDE;
   void AudioStateNotification(BluetoothHandsfreeAudioState aState,
                               const nsAString& aBdAddress) MOZ_OVERRIDE;
-  void AnswerCallNotification() MOZ_OVERRIDE;
-  void HangupCallNotification() MOZ_OVERRIDE;
+  void AnswerCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void HangupCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
   void VolumeNotification(BluetoothHandsfreeVolumeType aType,
-                          int aVolume) MOZ_OVERRIDE;
-  void DtmfNotification(char aDtmf) MOZ_OVERRIDE;
-  void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) MOZ_OVERRIDE;
-  void DialCallNotification(const nsAString& aNumber) MOZ_OVERRIDE;
-  void CnumNotification() MOZ_OVERRIDE;
-  void CindNotification() MOZ_OVERRIDE;
-  void CopsNotification() MOZ_OVERRIDE;
-  void ClccNotification() MOZ_OVERRIDE;
-  void UnknownAtNotification(const nsACString& aAtString) MOZ_OVERRIDE;
-  void KeyPressedNotification() MOZ_OVERRIDE;
+                          int aVolume,
+                          const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void DtmfNotification(char aDtmf,
+                        const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
+                            const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void DialCallNotification(const nsAString& aNumber,
+                            const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void CnumNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void CindNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void CopsNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void ClccNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void UnknownAtNotification(const nsACString& aAtString,
+                             const nsAString& aBdAddress) MOZ_OVERRIDE;
+  void KeyPressedNotification(const nsAString& aBdAddress) MOZ_OVERRIDE;
 
 private:
   class GetVolumeTask;
   class CloseScoTask;
   class CloseScoRunnable;
   class RespondToBLDNTask;
   class MainThreadTask;