蓝牙Remove Bond的流程分析
Posted libs-liu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝牙Remove Bond的流程分析相关的知识,希望对你有一定的参考价值。
此篇文章简单分析一下蓝牙解除配对在协议栈中的工作流程。分析的协议栈版本是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);//解配的设备没有处于连接状态则执行 }
从上面的代码可以看出,核心的地方就两处:
- bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; 标记该设备是要解除配对的,后续会删除其link key
- btm_remove_acl 做实际的断开连接的操作。
以上是关于蓝牙Remove Bond的流程分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段