码迷,mamicode.com
首页 > 其他好文 > 详细

蓝牙Remove Bond的流程分析

时间:2018-06-17 23:18:27      阅读:708      评论:0      收藏:0      [点我收藏+]

标签:tin   device   eve   api   str   type   执行   success   需要   

此篇文章简单分析一下蓝牙解除配对在协议栈中的工作流程。分析的协议栈版本是Android8.0

协议栈的接口都定义在bluetooth.cc这个文件中:

static int remove_bond(const bt_bdaddr_t* bd_addr) {
  if (is_restricted_mode() && !btif_storage_is_restricted_device(bd_addr))
    return BT_STATUS_SUCCESS;
  /* sanity check */
  if (interface_ready() == false) return BT_STATUS_NOT_READY;
  return btif_dm_remove_bond(bd_addr);
}

这里需要注意一下bt_bdaddr_t 是一个结构体,内部一个元素是数组。

 /** Bluetooth Address */
 typedef struct {
    uint8_t address[6];
 } __attribute__((packed))bt_bdaddr_t;

进入btif_dm_remove_bond:

bt_status_t btif_dm_remove_bond(const bt_bdaddr_t* bd_addr) {
  bdstr_t bdstr;
  btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_REMOVE_BOND,
                        (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
  return BT_STATUS_SUCCESS;
}

这个函数btif_transfer_context 是将remove bond这件事情交给bt_jni_workqueue_thread来处理。在该线程中执行的函数就是btif_dm_generic_evt

static void btif_dm_generic_evt(uint16_t event, char* p_param) {
  BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
  switch (event) {
    case BTIF_DM_CB_REMOVE_BOND: {
      btif_dm_cb_remove_bond((bt_bdaddr_t*)p_param);
    } break;
  }
}

执行的函数:btif_dm_cb_remove_bond 

void btif_dm_cb_remove_bond(bt_bdaddr_t* bd_addr) {
    BTA_DmRemoveDevice((uint8_t*)bd_addr->address);
}

函数执行到了BTA层面。

tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr) {
  tBTA_DM_API_REMOVE_DEVICE* p_msg =
   (tBTA_DM_API_REMOVE_DEVICE*)osi_calloc(sizeof(tBTA_DM_API_REMOVE_DEVICE));
  p_msg->hdr.event = BTA_DM_API_REMOVE_DEVICE_EVT;
  bdcpy(p_msg->bd_addr, bd_addr);
  bta_sys_sendmsg(p_msg);
  return BTA_SUCCESS;
}

这边是发送了一个BTA_DM_API_REMOVE_DEVICE_EVT到另一个线程:bt_workqueue_thread,这个线程是专门处理bt里面的队列的,当队列里面有数据都会在这个线程里面处理。

通过bta_sys_sendmsg发送的信号都会经过bta_sys_event来处理,bta_sys_event会根据相应的事件路由到相应的处理函数。这里处理这个事件的函数是:

/*******************************************************************************
 *
 * Function         bta_dm_remove_device
 *
 * Description      Removes device, disconnects ACL link if required.
 ***
 ******************************************************************************/
void bta_dm_remove_device(tBTA_DM_MSG* p_data) {
  tBTA_DM_API_REMOVE_DEVICE* p_dev = &p_data->remove_dev;//获取消息
  bool continue_delete_other_dev = false;/* If ACL exists for the device in the remove_bond message*/
  bool continue_delete_dev = false;
  uint8_t other_transport = BT_TRANSPORT_INVALID;
/*首先判断该address 是否存有link*/
  if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
      BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) {
    APPL_TRACE_DEBUG("%s: ACL Up count  %d", __func__,
                     bta_dm_cb.device_list.count);
    continue_delete_dev = false;
    /* Take the link down first, and mark the device for removal when
     * disconnected */
    for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
      if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
                 p_dev->bd_addr)) {
        uint8_t transport = BT_TRANSPORT_BR_EDR;
        transport = bta_dm_cb.device_list.peer_device[i].transport;
        bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;//设置标志位,在acl link状态改变的函数中会去删除link key
        btm_remove_acl(p_dev->bd_addr, transport);//已经存在link,那么要先删除这条linkbreak;
      }
    }
  } else {
    continue_delete_dev = true;
  }
...
  /* Delete the device mentioned in the msg */
  if (continue_delete_dev) bta_dm_process_remove_device(p_dev->bd_addr);//解配的设备没有处于连接状态则执行
}

从上面的代码可以看出,核心的地方就两处:

  1. bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; 标记该设备是要解除配对的,后续会删除其link key
  2. btm_remove_acl 做实际的断开连接的操作。

 

蓝牙Remove Bond的流程分析

标签:tin   device   eve   api   str   type   执行   success   需要   

原文地址:https://www.cnblogs.com/libs-liu/p/9193864.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!