蓝牙之二十一-蓝牙免弹窗配对

这篇文章的缘由来自于一个需求,就是将手机和手机的配对方式变成,变成手机的和蓝牙音箱的配对方式一样,也就是将一部手机的角色变成和蓝牙音箱一样。

就拿前一篇博文一幅图来说。可以看到pc,手机,蓝牙音箱的图标是不同的,这在前一节里已经说明了,这是由COD字段决定的。

/* Default class of device
* {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS}
*
* SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony)
* MAJOR_CLASS:0x02 - PHONE
* MINOR_CLASS:0x0C - SMART_PHONE
*
*/
#ifndef BTA_DM_COD
#define BTA_DM_COD {0x5A, 0x02, 0x0C}
#endif
如果改成如下的方式,则变成带电话功能的蓝牙音箱了

#define BTA_DM_COD {0x5A, 0x40, 0x08}

蓝牙之二十一-蓝牙免弹窗配对_第1张图片

这里所描述的配对方式都是SSP方式。


/* bta security callback */
const tBTM_APPL_INFO bta_security =
{
    &bta_dm_authorize_cback,
    &bta_dm_pin_cback,
    &bta_dm_new_link_key_cback,
    &bta_dm_authentication_complete_cback,
    &bta_dm_bond_cancel_complete_cback,
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
    &bta_dm_sp_cback
#else
    NULL
#endif
#if BLE_INCLUDED == TRUE
#if SMP_INCLUDED == TRUE
    ,&bta_dm_ble_smp_cback
#endif
    ,&bta_dm_ble_id_key_cback
#endif
注意上面的BTM_IO_CAP_NONE这个很关键的。BTM_LOCAL_IO_CAPS的定义将决定bta_dm_sp_cback,这个函数是SSP的两个分级,如果确实将该函数赋给了上述的bta_security的


/* The IO capability of the local device (for Simple Pairing) */
#ifndef BTM_LOCAL_IO_CAPS
#define BTM_LOCAL_IO_CAPS               BTM_IO_CAP_IO
#endif

设备的IO能力会放在如下结构体的最后两个字段,本地和远端设备的能力,上面就是定义本地蓝牙设备IO能力的地方,在配对时,根据IO能力选择相应的能力。


/* Structure associated with BTA_DM_SP_CFM_REQ_EVT */
typedef struct
{
    /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */
    BD_ADDR         bd_addr;        /* peer address */
    DEV_CLASS       dev_class;      /* peer CoD */
    BD_NAME         bd_name;        /* peer device name */
    UINT32          num_val;        /* the numeric value for comparison. If just_works, do not show this number to UI */
    BOOLEAN         just_works;     /* TRUE, if "Just Works" association model */
    tBTA_AUTH_REQ   loc_auth_req;   /* Authentication required for local device */
    tBTA_AUTH_REQ   rmt_auth_req;   /* Authentication required for peer device */
    tBTA_IO_CAP     loc_io_caps;    /* IO Capabilities of local device */
    tBTA_AUTH_REQ   rmt_io_caps;    /* IO Capabilities of remote device */
} tBTA_DM_SP_CFM_REQ;


static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
                       uint8_t accept, uint32_t passkey)
{
    /* sanity check */
    if (interface_ready() == FALSE)
        return BT_STATUS_NOT_READY;

    return btif_dm_ssp_reply(bd_addr, variant, accept, passkey);
}
执行SSP确认请求的协议栈函数如下


1054 static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_ssp_cfm_req)

...
 if (p_ssp_cfm_req->just_works)
1099     {
...
129     pairing_cb.sdp_attempts = 0;
1130     HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name, cod,
1131                      (p_ssp_cfm_req->just_works ? BT_SSP_VARIANT_CONSENT : BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
1132                      p_ssp_cfm_req->num_val);
如果使用的是just work方式,则协议栈自行处理,就不会再弹窗给用户了。如果非just work方式,则ssp_request_cb的参数将是BT_SSP_VARIANT_PASSKEY_CONFIRMATION,从这个定义的名称可以看出,其是需要用户干预(手动确认)的配对方式,如果是BT_SSP_VARIANT_CONSENT,则是同意的方式,这中方式协议栈就处理掉了。一旦选择需要用户确认,那么HAL_CBACK将会回调,经过BondStateMachine最后到安卓的setting里,弹窗提示用户确认配对。

void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
为了便于跟踪btm里做了什么事,可以将打印信息的log打开,

+++ b/conf/bt_stack.conf
@@ -26,7 +26,7 @@ TraceConf=true
 #   BT_TRACE_LEVEL_EVENT   4    ( Debug messages for events )
 #   BT_TRACE_LEVEL_DEBUG   5    ( Full debug messages )
 #   BT_TRACE_LEVEL_VERBOSE 6    ( Verbose messages ) - Currently supported for TRC_BTAPP only.
-TRC_BTM=2
+TRC_BTM=5
 TRC_HCI=2
 TRC_L2CAP=2


你可能感兴趣的:(蓝牙)