OSDN Git Service

Resolve Pairing failure with IPhone
authorGanesh Ganapathi Batta <ganeshg@broadcom.com>
Mon, 28 Apr 2014 23:30:55 +0000 (16:30 -0700)
committerMatthew Xie <mattx@google.com>
Tue, 6 May 2014 08:14:25 +0000 (01:14 -0700)
When pairing is initiated from the iPhone side, it sets Bonding bit
without MITM. We responded to this with No bonding, No MITM. This resulted
in JustWorks & Unauthenticated link key. After pairing iPhone initiates a
RFCOMM connection. This caused a link key upgrade to be done, which the iPhone
rejected, resulting in pairing failure. To resolve this the following
enhancements were made
1. If locally initiated pairing always set Bonding bit + MITM
2. If remote initiated
a. copy over the bonding bit
b. if peer has DisplayYesNo set MITM
3. As a fallback if remote had MITM, enable MITM in our response
This forces pairing to use Bonding bit+MITM thus resulting in authenticated
combination linkkey

Change-Id: I08f16c80821bc822023180d01868614ba41e6d88

btif/co/bta_dm_co.c
btif/include/btif_dm.h
btif/src/btif_dm.c

index 13a5c8f..abf52bf 100644 (file)
@@ -75,6 +75,7 @@ void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, tBTA_OOB_DATA *p_o
 #if (BTM_OOB_INCLUDED == TRUE)
     btif_dm_set_oob_for_io_req(p_oob_data);
 #endif
+    btif_dm_proc_io_req(bd_addr, p_io_cap, p_oob_data, p_auth_req, is_orig);
     BTIF_TRACE_DEBUG1("bta_dm_co_io_req *p_oob_data = %d", *p_oob_data);
     BTIF_TRACE_DEBUG1("bta_dm_co_io_req *p_io_cap = %d", *p_io_cap);
     BTIF_TRACE_DEBUG1("bta_dm_co_io_req *p_auth_req = %d", *p_auth_req);
@@ -99,10 +100,7 @@ void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, tBTA_OOB_DATA *p_o
 void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
                       tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req)
 {
-    UNUSED(bd_addr);
-    UNUSED(io_cap);
-    UNUSED(oob_data);
-    UNUSED(auth_req);
+    btif_dm_proc_io_rsp(bd_addr, io_cap, oob_data, auth_req);
 }
 
 /*******************************************************************************
index ed03e34..37f11b7 100644 (file)
@@ -36,6 +36,17 @@ void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data);
 void btif_dm_on_disable(void);
 
 /**
+ * Callout for handling io_capabilities request
+ */
+void btif_dm_proc_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, tBTA_OOB_DATA *p_oob_data,
+                      tBTA_AUTH_REQ *p_auth_req, BOOLEAN is_orig);
+/**
+ * Callout for handling io_capabilities response
+ */
+void btif_dm_proc_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+                      tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
+
+/**
  * Out-of-band functions
  */
 #if (BTM_OOB_INCLUDED == TRUE)
index 40d21fd..3688bb9 100644 (file)
@@ -84,6 +84,8 @@ typedef struct
     UINT8   is_temp;
     UINT8   pin_code_len;
     UINT8   is_ssp;
+    UINT8   auth_req;
+    UINT8   io_cap;
     UINT8   autopair_attempts;
     UINT8   is_local_initiated;
     UINT8   sdp_attempts;
@@ -2215,6 +2217,63 @@ void btif_dm_execute_service_request(UINT16 event, char *p_param)
     return;
 }
 
+void btif_dm_proc_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, tBTA_OOB_DATA *p_oob_data,
+                      tBTA_AUTH_REQ *p_auth_req, BOOLEAN is_orig)
+{
+    UINT8   yes_no_bit = BTA_AUTH_SP_YES & *p_auth_req;
+    /* if local initiated:
+    **      1. set DD + MITM
+    ** if remote initiated:
+    **      1. Copy over the auth_req from peer's io_rsp
+    **      2. Set the MITM if peer has it set or if peer has DisplayYesNo (iPhone)
+    ** as a fallback set MITM+GB if peer had MITM set
+    */
+    UNUSED (bd_addr);
+    UNUSED (p_io_cap);
+    UNUSED (p_oob_data);
+
+
+    BTIF_TRACE_DEBUG2("+%s: p_auth_req=%d", __FUNCTION__, *p_auth_req);
+    if(pairing_cb.is_local_initiated)
+    {
+        /* if initing/responding to a dedicated bonding, use dedicate bonding bit */
+        *p_auth_req = BTA_AUTH_DD_BOND | BTA_AUTH_SP_YES;
+    }
+    else if (!is_orig)
+    {
+        /* peer initiated paring. They probably know what they want.
+        ** Copy the mitm from peer device.
+        */
+        BTIF_TRACE_DEBUG2("%s: setting p_auth_req to peer's: %d",
+                __FUNCTION__, pairing_cb.auth_req);
+        *p_auth_req = (pairing_cb.auth_req & BTA_AUTH_BONDS);
+
+        /* copy over the MITM bit as well. In addition if the peer has DisplayYesNo, force MITM */
+        if ((yes_no_bit) || (pairing_cb.io_cap & BTM_IO_CAP_IO) )
+            *p_auth_req |= BTA_AUTH_SP_YES;
+    }
+    else if (yes_no_bit)
+    {
+        /* set the general bonding bit for stored device */
+        *p_auth_req = BTA_AUTH_GEN_BOND | yes_no_bit;
+    }
+    BTIF_TRACE_DEBUG2("-%s: p_auth_req=%d", __FUNCTION__, *p_auth_req);
+}
+
+void btif_dm_proc_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+                      tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req)
+{
+    UNUSED (bd_addr);
+    UNUSED (oob_data);
+    
+    if(auth_req & BTA_AUTH_BONDS)
+    {
+        BTIF_TRACE_DEBUG2("%s auth_req:%d", __FUNCTION__, auth_req);
+        pairing_cb.auth_req = auth_req;
+        pairing_cb.io_cap = io_cap;
+    }
+}
+
 #if (BTM_OOB_INCLUDED == TRUE)
 void btif_dm_set_oob_for_io_req(tBTA_OOB_DATA  *p_oob_data)
 {