0
点赞
收藏
分享

微信扫一扫

Android 蓝牙 BLE扫描、广播、连接、数据收发源码分析(3)- inquiry扫描结果处理

android-蓝牙A2dp-avrcp-hfp-opp-配对流程-ble-rfcomm源码流程

Android 蓝牙低功耗ble 广播、扫描、连接、数据读写源码流程分析大全 - 点击下载

首先提前注册扫描结果回调函数。bta_dm_search_cb回调赋值

在我们开始设备Inquiry的时候,先前已经提到过,调用btif_dm_start_discover函数,在这个函数中,调用了BTA_DmSearch函数,用它来搜寻附近可被发现的蓝牙设备,在这个函数中,传入了bte_search_devices_evt回调函数,当我们搜索得到的结果,最后都会调用它向上层上报搜索结果

 

 来到BTA_DmSearch函数中,我们看到组装了p_msg消息,其中的事件为BTA_DM_API_SEARCH_EVT,并且其中把回调函数赋值,也就是p_msg->p_cback = bte_search_devices_evt,最后使用bta_sys_sendmsg发送

 对于bta_sys_sendmsg发送消息的处理已经非常熟悉了,最后会根据传过来的event的主事件id,来决定调用的事件处理函数,BTA_DM_API_SEARCH_EVT的主事件id为BTA_ID_DM_SEARCH,所以这里调用bta_dm_search_sm_execute函数来处理

 来到bta_dm_search_sm_execute函数中,根据当前bta_dm_search的状态,获取状态执行表

 在我们刚开始进行inquiry的时候,bta_dm_search的状态为idle

 在idle状态下的列表,这个表格根据我们传入的event事件,得到我们将要执行的事件处理函数的ACTION,同时设置bta_dm_search的下一个状态,这里下一个状态active

 这里根据我们得到的ACTION,在事件处理函数中找到对应的事件处理函数,这里是bta_dm_search_start

 

我们之前传递的p_msg被赋值给了p_data->search,在这个函数中,我们看到:

bta_dm_search_cb.p_search_cback = p_data->search.p_cback

而:

p_data->search.p_cback = p_msg->p_cback = bte_search_devices_evt

所以:

bta_dm_search_cb.p_search_cback = bte_search_devices_evt

在这里完成了bta_dm_search_cb.p_search_cback回调函数的赋值

当inquiry完成后,controller会上报一个事件,也就是inquiry complete,从控制器上报的event事件,交由btu_hcic_process_event来处理

 

 由于我们上报的是inquiry complete事件,所以这里选择btu_hcif_inquiry_comp_evt函数来执行,我们看到在里面调用了btm_process_inq_complete函数

 在函数中,首先调用了btm_acl_update_busy_level函数向上层汇报状态

 后来接着清除了状态标志位并且调用了回调函数,关于回调函数,我们后面会说到

 在btm_acl_update_busy_level函数中,组装了一个evt,其中event为BTM_BL_UPDATE_EVT,最后调用了btm_cb.p_bl_changed_cb回调函数执行

 在这里我们来分析下btm_cb.p_bl_changed_cb是如何被赋值的,首先在bta_dm_sys_hw_cback函数中,我们调用了BTM_RegBusyLevelNotif函数,在里面传递了bta_dm_bl_change_cback回调函数

 在BTM_RegBusyLevelNotif函数中,将传递进来的回调函数,也就是bta_dm_bl_change_cback回调赋值给btm_cb.p_bl_changed_cb,至此,完成了btm_cb.p_bl_changed_cb的赋值

 在bta_dm_bl_change_cback函数中,我们传递过来的事件为BTM_BL_UPDATE_EVT,在这里还是组装msg消息,事件类型为BTM_DM_ACL_CHANGE_EVT,然后调用bta_sys_sendmsg发送

 

因为我们传递过来的event为BTA_DM_ACL_CHANGE_EVT,它的主事件id为BTA_DM_ID,所以这里调用bta_dm_sm_execute函数,在这个函数,我们获取到子事件id,然后根据子事件id,找到该id下标对应的处理函数

 在bta_dm_action中根据子事件id,选择对应的函数,这里要执行的是bta_dm_acl_change函数

 来到bta_dm_acl_change函数中,我们的事件为BTM_BL_UPDATA_EVT,在这里调用bta_dm_cb.p_sec_cback回调,而这个回调我们之前介绍过,就是bte_dm_evt回调函数,其中传递的事件类型为BTA_DM_BUSY_LEVEL_EVT

 bte_dm_evt函数中,将事件处理从bte层上下文切换到btif层上下文处理,在里面接着调用btif_dm_upstreams_evt,event事件依然为BTA_DM_BUSY_LEVEL_EVT

 在btif_dm_upstreams_evt函数中,根据我们传入的event,最终我们看到,将btif_dm_inquiry_in_process这个flag设置为false,表明inquiry查询进程结束

 分析完了btm_process_inq_complete函数中的第一部分btm_process_inq_complete 后,我们接着分析后面一部分,p_inq_cb这个回调函数,我们看下是在哪里被赋值的,首先是来到bta_dm_search_start函数中,在这里面我们调用BTM_StartInquiry函数来进行inquiry查询扫描,其中在这个函数中传入了bta_dm_inq_cmpl_cb这个回调函数,这个函数在inquiry完成之后会被执行,上报消息给到上层

 

在BTM_StartInquiry函数中,p_inq被设置为&btm_cb.btm_inq_vars,而p_inq->p_inq_cmpl_cb = p_cmpl_cb,也就是bta_dm_inq_cmpl_cb,即:

btm_cb.btm_inq_vars.p_inq_cmpl_cb = bta_dm_inq_cmpl_cb

 而在我们的btm_process_inq_complete函数中,p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb,所以,最后我们执行的函数是bta_dm_inq_cmpl_cb,在这个函数中,我们一样也是组装了msg消息,event为BTA_DM_INQUIRY_CMPL_EVT,然后调用bta_sys_sendmsg发送

 由于BTA_DM_INQUIRY_CMPL_EVT的主事件id为BTA_ID_DM_SEARCH,所以这里调用的是bta_dm_search_sm_execute函数,它根据bta_dm_search的状态,查询bta_dm_search状态的table,然后赋值下一个状态,根据event在table中查找该事件对应的ACTION,这些action有函数和它们一一对应,然后执行这些函数

 之前已经将bta_dm_search的状态设置为active,所以这里选择bta_dm_search_search_active_st_table

 在列表中,根据我们传递的事件为INQUIRY_CMPL,下一个状态还是active

 根据对应ACTION,选择对应的函数执行,这里要执行的是bta_dm_inq_cmpl

 

在这个函数中,首先我们执行回调函数,向上层报告inquiry查询完成事件

然后看inquiry是否搜索到了设备,如果有搜索到设备,则对设备进行discover操作,如果没有搜索到设备,向上层传递search complete消息,也就是发送BTA_DM_SEARCH_CMPL_EVT事件消息,我们先一个个分析

 bta_dm_search_cb.p_search_cback我们介绍过,它就是bte_search_devices_evt回调函数,在这个函数里面,继续调用btif_dm_search_devices_evt函数,传递的事件为BTA_DM_INQ_CMPL_EVT,我们接着向下分析

 在函数中,我们处理的事件为BTA_DM

 

bta_dm_inq_cmpl函数第二部分,如果inquiry有搜索到设备,则进行discover操作,来到bta_dm_discover_device中,我们先判断搜索到的设备,是否需要名字,如果需要则调用bta_dm_read_remote_device_name进行名字的搜索

 在bta_dm_discover_device函数的后面,它组装消息,向btu线程发送事件消息,event类型为BTA_DM_DISCOVER_RESULT_EVT

 BTA_DM_DISCOVER_RESULT_EVT的主事件id为BTA_DM_ID_SEARCH,所以掉一共bta_dm_search_sm_execute函数,bta_dm_search现在的状态为active

 选择active状态下的bta_dm_search对应的状态转换表

 根据event事件,找到对应的ACTION为BTA_DM_SEARCH_RESULT,同事bta_dm_search下一个状态仍然为active

 根据ACTION,找到对应的处理函数,也就是bta_dm_search_result

在这个函数中,我们看到又执行了回调函数进行上报,也就是我们前面说的bte_search_devices_evt回调函数,同时,看下我们的discover操作有没有pending ,如果没有则继续去搜索下一个设备,如果有,则设置定时器,并且在回调函数里面继续执行搜索下一个设备的服务

 

 我们先来看上报部分,bte_search_devices_evt最终调用到的是btif_dm_search_devices_evt,同事传入的事件是BTA_DM_DISC_RES_EVT,在里面存储远端设备属性信息,然后通过jni函数向上层传递消息

 bta_dm_search_result函数中完成上报以后,如果没有pending,则执行bta_dm_discover_next_device函数,如果在我们inquiry查询结果中还有设备,则继续discover搜索服务,如果没有设备了,则组装消息,发送BTA_DM_SEARCH_CMPL_EVT事件,结束discover流程

 当我们这里inquiry查询中没有搜索到设备或者设备搜索完成,则组装消息,发送BTA_DM_SEARCH_CMPL_EVT事件,然后在active状态下的bta_dm_search中根据event事件,选择对应的ACTION所指向的处理函数执行,同时,bta_dm_search的下一个状态为idle

 对应处理函数为bta_dm_search_cmpl函数,在这里面又调用到了我们的回调函数bte_search_devices_evt回调函数来上报搜索结果

 当传入的事件是BTA_DM_DISC_CMPL_EVT,那么就会调用:HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STOPPED); 来通知上层,即便一条设备信息也搜索不到,也会通知上层,搜索扫描已经完成

至此,当inquiry完成后,收到inquiry complete事件的整个流程都分析完了

举报

相关推荐

0 条评论