手机与蓝牙耳机配对失败笔记

安全简单配(Secure Simple Pairing) 采用了四个关联的模型,这四个模式是数字比较( Numeric Comparison),使用简单(Just Works),带外(Out Of Band),秘钥接入(Passkey Entry)。
蓝牙规范中的配对分为三种过程,分别是
Bluetooth InBand, OOB Discovery only,OOB Discovery and Authentication。 OOB是out of band,即非蓝牙传输方式如NFC.
整个配对分四个步骤:
1.通过inquiry来搜索设备.
2.通过page建立蓝牙物理连接(ACL Link)
3.link key生成.
4.link key生成后,可通过三种方式进行鉴权:Numeric Compare(6位随机密码比较), Passkey Entry(一方显示数据,另一方输入密码),Just works(不鉴权,直接使用)
蓝牙配对失败:
bt-btm  : btm_simple_pair_complete()  Pair State: 9   Status:5   sec_state: 1   //配对失败Log   Status:5//鉴权失败
/* Pairing State */ system/bt/stack/btm/btm_int.h
enum
{
    BTM_PAIR_STATE_IDLE,                        /* Idle                                         */
    BTM_PAIR_STATE_GET_REM_NAME,                /* Getting the remote name (to check for SM4)   */
    BTM_PAIR_STATE_WAIT_PIN_REQ,                /* Started authentication, waiting for PIN req (PIN is pre-fetched) */
    BTM_PAIR_STATE_WAIT_LOCAL_PIN,              /* Waiting for local PIN code                   */
    BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM,        /* Waiting user 'yes' to numeric confirmation   */
    BTM_PAIR_STATE_KEY_ENTRY,                   /* Key entry state (we are a keyboard)          */
    BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP,          /* Waiting for local response to peer OOB data  */
    BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS,           /* Waiting for local IO capabilities and OOB data */
    BTM_PAIR_STATE_INCOMING_SSP,                /* Incoming SSP (got peer IO caps when idle)    */
    BTM_PAIR_STATE_WAIT_AUTH_COMPLETE,          /* All done, waiting authentication cpmplete    */
    BTM_PAIR_STATE_WAIT_DISCONNECT              /* Waiting to disconnect the ACL                */
};
 
/*
**  Defentions for HCI Error Codes that are past in the events                  system/bt/stack/include/hcidefs.h
*/
#define HCI_ERR_AUTH_FAILURE                            0x05                        //鉴权失败
例:手机与蓝牙耳机 HAVIT I11(00:0C:8A:48:43:EC)配对不上分析:
Settings-->Bluetooth---->ON
点击扫描到的HAVIT I11耳机,无法连接,一直弹出框Couldn't communicate with HAVIT I11.
相关log:
1963 2003 I bt_btm : BDA 00:0c:8a:48:43:ec
1963 2003 I bt_btm : Inquire BDA 00:0c:8a:48:43:ec
1963 2003 I bt_btm : BTM_InqDbRead: bd addr [000c8a4843ec]
1963 2003 D bt_btm : btm_find_dev_type - device_type = 1 addr_type = 0
1963 2003 I bt_btm : btm_sec_rmt_name_request_complete
1963 2003 D bt_btm : btm_acl_resubmit_page
1963 2003 I bt_btm : Security Manager: rmt_name_complete PairState: 1 RemName: status: 4 State:0 p_dev_rec: 0xefc5e06c
1963 2003 I bt_btm : btm_sec_rmt_name_request_complete() continue bonding sm4: 0x0000, status:0x4
1963 2003 W bt_btm : btm_sec_rmt_name_request_complete() Retrying RNR due to page timeout
1963 2003 I bt_btm : BTM_ReadRemoteDeviceName: bd addr [000c8a4843ec]
1963 2003 I bt_btm : no device found in inquiry db
1963 2003 D bt_btm : btm_acl_paging discing:0, paging:0 BDA: 000c8a4843ec
1963 2003 D bt_btm : connecting_bda: 000c8a4843ec
1963 2003 I bt_btm : btm_find_or_alloc_dev

1963 2003 I bt_btm : BDA 00:0c:8a:48:43:ec
1963 2003 I bt_btm : Inquire BDA 00:0c:8a:48:43:ec
1963 2003 I bt_btm : BTM_InqDbRead: bd addr [000c8a4843ec]
1963 2003 D bt_btm : btm_find_dev_type - device_type = 1 addr_type = 0
1963 2003 I bt_btm : btm_sec_rmt_name_request_complete
1963 2003 D bt_btm : btm_acl_resubmit_page
1963 2003 I bt_btm : Security Manager: rmt_name_complete PairState: 1 RemName: status: 4 State:0 p_dev_rec: 0xefc5e06c
1963 2003 I bt_btm : btm_sec_rmt_name_request_complete() continue bonding sm4: 0x0000, status:0x4
1963 2003 I bt_btm : btm_sec_rmt_name_request_complete() reset RNR retry count
1963 2003 I bt_btm : btm_sec_change_pairing_state() Old: 1
1963 2003 I bt_btm : btm_sec_change_pairing_state() New: 0 pairing_flags:0x1
1963 2003 I bt_btm : BTM_InqDbRead: bd addr [000c8a4843ec]
1963 2003 D bt_btm : btm_find_dev_type - device_type = 1 addr_type = 0
1963 2003 D bt_btif : btif_transfer_context event 3, len 280
1963 2003 I bt_btm : BTM_IsAclConnectionUp: RemBdAddr: 000c8a4843ec
1963 2003 D bt_btm : btm_sec_clear_ble_keys() Clearing BLE Keys
1963 2003 I bt_btm : btm_ble_resolving_list_remove_dev
1963 2003 D bt_btm : Device not in resolving list
1963 2003 I bt_btm : BTM: BTM_DeleteStoredLinkKey: delete_all_flag: FALSE
1963 2003 I bt_btif : BTA got event 0x1f02
1963 2003 E bt_btif : bta_gattc_mark_bg_conn unable to find the bg connection mask for: 00:0c:8a:48:43:ec
1963 2003 I bt_btif : BTA got event 0x1f0c
1963 2003 D bt_btif : bta_gattc_co_cache_reset()
1963 1990 D bt_btif : btif task fetched event a001
1963 1990 D bt_btif : btif_context_switched
1963 1990 I bt_btif : btif_dm_upstreams_cback ev: BTA_DM_AUTH_CMPL_EVT
1963 1990 D bt_btif : btif_dm_auth_cmpl_evt: bond state=1
1963 1990 D bt_btif : in, bd addr:00:0c:8a:48:43:ec, prop type:4, len:4
1963 1990 I bt_btif_dm: check_cod remote_cod = 0x00240404 cod = 0x00000580
1963 1990 D bt_btif : bond_state_changed: state=0, prev_state=1, sdp_attempts = 0
1963 1990 I bt_btif : HAL bt_hal_cbacks->bond_state_changed_cb
1963 1990 I BluetoothBondStateMachine: bondStateChangeCallback: Status: 10 Address: 00:0C:8A:48:43:EC newState: 0
1963 1995 D BluetoothAdapterProperties: Failed to remove device: 00:0C:8A:48:43:EC
snoop log:获取remote_name超时:
手机与蓝牙耳机配对失败笔记_第1张图片
frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
    public static final int BOND_NONE = 10;    
    public static final int BOND_BONDING = 11;   
    public static final int BOND_BONDED = 12;

packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
    
    static final int BOND_STATE_NONE = 0;
    static final int BOND_STATE_BONDING = 1;
    static final int BOND_STATE_BONDED = 2;

    private void sendIntent(BluetoothDevice device, int newState, int reason) {
        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
        int oldState = BluetoothDevice.BOND_NONE;
        if (devProp != null) {
            oldState = devProp.getBondState();
        }
        if (oldState == newState) return;
        mAdapterProperties.onBondStateChanged(device, newState);

        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
        if (newState == BluetoothDevice.BOND_NONE)
            intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
        mAdapterService.sendBroadcastAsUser(intent, UserHandle.ALL,
                AdapterService.BLUETOOTH_PERM);
        infoLog("Bond State Change Intent:" + device + " OldState: " + oldState
                + " NewState: " + newState);
    }


     void bondStateChangeCallback(int status, byte[] address, int newState) {
        BluetoothDevice device = mRemoteDevices.getDevice(address);

        if (device == null) {
            infoLog("No record of the device:" + device);
            // This device will be added as part of the BONDING_STATE_CHANGE intent processing
            // in sendIntent above
            device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
        }

        infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device
                + " newState: " + newState);

        Message msg = obtainMessage(BONDING_STATE_CHANGE);
        msg.obj = device;

        if (newState == BOND_STATE_BONDED)
            msg.arg1 = BluetoothDevice.BOND_BONDED;
        else if (newState == BOND_STATE_BONDING)
            msg.arg1 = BluetoothDevice.BOND_BONDING;
        else
            msg.arg1 = BluetoothDevice.BOND_NONE;
        msg.arg2 = status;

        sendMessage(msg);
    }

system/bt/stack/btm/Btm_sec.c
/*******************************************************************************
**
** Function         btm_sec_rmt_name_request_complete
**
** Description      This function is called when remote name was obtained from
**                  the peer device
**
** Returns          void
**
*******************************************************************************/
void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT8 status)
{
    tBTM_SEC_DEV_REC *p_dev_rec;
    int              i;
    DEV_CLASS        dev_class;
    UINT8            old_sec_state;

    BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete");
    if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda))
        || ((p_bd_addr != NULL) && !BTM_ACL_IS_CONNECTED(p_bd_addr)))
    {
        btm_acl_resubmit_page();
    }

    /* If remote name request failed, p_bd_addr is null and we need to search */
    /* based on state assuming that we are doing 1 at a time */
    if (p_bd_addr)
        p_dev_rec = btm_find_dev (p_bd_addr);
    else
    {
        p_dev_rec = &btm_cb.sec_dev_rec[0];

        for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
        {
            if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
                && (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME))
            {
                p_bd_addr = p_dev_rec->bd_addr;
                break;
            }
        }

        if (i == BTM_SEC_MAX_DEVICE_RECORDS)
            p_dev_rec = NULL;
    }


    /* Commenting out trace due to obf/compilation problems.
    */
#if (BT_USE_TRACES == TRUE)
    if (!p_bd_name)
        p_bd_name = (UINT8 *)"";

    if (p_dev_rec)
    {
        BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s  RemName: %s  status: %d State:%d  p_dev_rec: 0x%08x ",
                          btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
                          status, p_dev_rec->sec_state, p_dev_rec);
    }
    else
    {
        BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s  RemName: %s  status: %d",
                          btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
                          status);
    }
#endif

...........................

    /* Check if we were delaying bonding because name was not resolved */
    if ( btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME)
    {
        if (p_bd_addr && memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0)
        {
            BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() continue bonding sm4: 0x%04x, status:0x%x", p_dev_rec->sm4, status);
            if(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_CANCEL_DD)
            {
                btm_sec_bond_cancel_complete();
                return;
            }

            /* Handle RNR with retry mechanism */
            if((status == HCI_ERR_PAGE_TIMEOUT) && (p_dev_rec->rnr_retry_cnt < RNR_MAX_RETRY_ATTEMPTS))
            {
                BTM_TRACE_WARNING ("btm_sec_rmt_name_request_complete() Retrying RNR due to page timeout");
                if ((BTM_ReadRemoteDeviceName(p_bd_addr, NULL, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                {
                    p_dev_rec->rnr_retry_cnt++;
                    return;
                }
            }
            else
            {
                BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() reset RNR retry count ");
                p_dev_rec->rnr_retry_cnt = 0;
            }

            if (status != HCI_SUCCESS)
            {
                btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);

                if (btm_cb.api.p_auth_complete_callback)
                    (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
                                                            p_dev_rec->sec_bd_name, status);
                return;
            }

.................................
    /* Remote Name succeeded, execute the next security procedure, if any */
    status = (UINT8)btm_sec_execute_procedure (p_dev_rec);

    /* If result is pending reply from the user or from the device is pending */
    if (status == BTM_CMD_STARTED)
        return;

    /* There is no next procedure or start of procedure failed, notify the waiting layer */
    btm_sec_dev_rec_cback_event  (p_dev_rec, status, FALSE);
} 
Android 6.0蓝牙配对流程:参考此博客学习
http://blog.csdn.net/shichaog/article/details/52836804

你可能感兴趣的:(Bluetooth)