十一、设备初始化(ADK4.0)
1.1 首先初始化连接库
sinkConnectionInit();à
ConnectionInitEx2(); theCm.task.handler = connectionBluestackHandler;
连接库初始化完毕后,发送CL_INIT_CFM给ClientTask(/APPtask/MainTask),ClientTask在接收到该消息后,开始初始化Codec和GAIA。sinkInitCodecTask(); | GaiaInit(task, 1);
1.2 初始化Codec
sinkInitCodecTask();
Codec初始化完毕之后,sendInitCfmToApp()调用向ClientTask发送CODEC_INIT_CFM消息,ClientTask在接收到该消息后,开始初始化HFP。
1.3 HFP初始化
sinkHfpInit();à
HfpInit(); à
lHfp->task.handler = hfpProfileHandler;
hfpServicesInit();
hfpServiceChannelRegister(theHfp->services);à CL_RFCOMM_REGISTER_CFM
hfpProfileHandler()àcase CL_RFCOMM_REGISTER_CFM:à
hfpInitRfcommRegisterCfm();à
hfpRegisterServiceRecord(service); à/* registering an SDP record */
hfpServiceChannelRegister(service); /* Register RFCOMM channel for next service */
hfpProfileHandler()àcase CL_SDP_REGISTER_CFM:à
hfpInitSdpRegisterCfm()à
hfpInitSdpRegisterComplete()à
hfpInitCfmToApp(); à
MessageSend(theHfp->clientTask, HFP_INIT_CFM, message);
1.4 杂散外设初始化
HFP初始化完毕之后,HFP任务发送HFP_INIT_CFM信号给ClientTask,ClientTask在接收到该信号后,进行后续的一些杂散外设(如LCD,LED,USB)的初始化,以及一些必要的扫尾工作,这些初始化工作主要有下面两个调用完成。
InitEarlyUserFeatures(); | sinkInitComplete();
InitEarlyUserFeatures();à
buttonManagerInit();
configManagerInit(TRUE); à/* Once system Managers initialized, load up configuration */
InitA2dp();
usbInit();
displayInit();
dutInit();
stateManagerEnterLimboState();
sinkInitComplete()à
RegisterDeviceIdServiceRecord();
sinkAvrcpInit(); /* initialize the AVRCP library */
InitUserFeatures(); àLedManagerEnableLEDS ();|MessageSystemTask(&theSink.task);|
MessageSend( &theSink.task , EventUsrPowerOn , NULL ) ; /*Power on*/
sinkBleInitialiseDevice(); /* Perform BLE Initialization */
sinkAncInit(); /* Initialize ANC */
1.5 开机操作
case (EventUsrPowerOn):
stateManagerPowerOn();à
PioSetPowerPin ( TRUE ) ;
stateManagerEnterConnectableState( TRUE );
if(theSink.features.PairIfPDLLessThan
|| theSink.features.AutoReconnectPowerOn
|| theSink.panic_reconnect)à
MessageSend(&theSink.task, EventSysEnterPairingEmptyPDL, 0);
MessageSend(&theSink.task, EventUsrRssiPair, 0);
sinkBlePowerOnEvent(); /* Power on BLE */
stateManagerEnterConnectableState();à
sinkEnableConnectable();
stateManagerSetState ( deviceConnectable ) ;
if ( theSink.features.pair_mode_en ) /*if we want to auto enter pairing mode*/
stateManagerEnterConnDiscoverableState( req_disc );à
sinkEnableConnectable(); /* Make the device connectable */
sinkEnableDiscoverable(); /* Make the device discoverable */
stateManagerSetState(deviceConnDiscoverable);
当系统检测到A2DP或者SLC(HFP)链路断开时,或者设备开启了手动进入连接配对功能时,设备自动进入重连状态,其会从PDL中按顺序寻找可能的设备进行连接。具体调用关系是:首先调用sinkEnableMultipointConnectable()让设备进入可连接状态,然后向主任务先后发送两个用户信号: EventUsrEnterPairing, EventUsrEstablishSLC,前者的回调函数会设备进入可连接,可发现状态;后者会试图建立SLC连接。
sinkHandleSlcDisconnectInd()à
handleA2DPSignallingDisconnected()à
ButtonsLevelDetect()àif(theSink.features.GoConnectableButtonPress)à
sinkEnableMultipointConnectable();à
if((theSink.MultipointEnable)&&(stateManagerGetState() != deviceLimbo))
sinkEnableConnectable(); /* make device connectable */
/*Who sends EventUsrEnterPairing and EventUsrEstablishSLC msgs to the apptask???*/
MessageSend(&theSink.task, EventUsrEnterPairing, 0);
MessageSend(&theSink.task, EventUsrEstablishSLC, 0);
case (EventUsrEnterPairing):à
stateManagerEnterConnDiscoverableState( TRUE );
case ( EventUsrEstablishSLC ) :à
slcEstablishSLCRequest() ;
slcEstablishSLCRequest()首先获取PDL大小,然后取出首个已配对设备,判断其支持的profile是否被当前设备支持,是则尝试进行连接,否则发送信号通知apptask开始继续SLC连接(EventSysContinueSlcConnectRequest),无论连接成功与否,BlueStack都会通过信号返回此次连接的结果(HFP_SLC_CONNECT_CFM)。
slcEstablishSLCRequest() ;à
gSlcData.gListID = 0;
gSlcData.gPdlSize = ConnectionTrustedDeviceListSize();
slcIsListIdAvailable(gSlcData.gListID); gSlcData.gListID++;
slcAttemptConnection();à
if(attributes.profiles & (sink_hfp | sink_a2dp | sink_avrcp))
slcConnectDevice(&ag_addr.addr, attributes.profiles);
else
MessageSend(&theSink.task, EventSysContinueSlcConnectRequest, 0);
case EventSysContinueSlcConnectRequest:
slcContinueEstablishSLCRequest();à /* attempt next connection */
slcGetNextListID();
slcAttemptConnection();
slcConnectDevice(&ag_addr.addr, attributes.profiles);à
HfpSlcConnectRequest(bd_addr, hfp_handsfree_and_headset, hfp_handsfree_all);
A2dpSignallingConnectRequest(bd_addr);
1.6 客户主动发起连接
当设备powerOn过程中会自动进入connectable模式,并试图连接PDL中设备,同样,在用户干预(对应按键按下,GAIA操作等)控制设备进入connectable&discoverable模式时,也会试图连接PDL中设备,当前两者操作都没有可以连接配对设备时,设备在connectable &discoverable状态会驻留一段时间,等待客户设备主动发起连接。对于到来的的客户连接请求,服务器首先会进行能力的交互,然后进行认证和鉴权流程,如果认证通过,双方建立其一条ACL链路,并通知上层应用。
手册CS-207482-UGP5_WritingBlueCoreApplication.pdf中例举了如何在两个蓝牙设备之间建立ACL链路,在该例子中,应用层使用L2CAP协议,使用简单的Just works的认证机制,其涉及到的消息以及API如下图所示:

ACL connection,Request IO Capability,Link Authenticated,L2CAP Connection等都是由BlueStack主动发起的,无需应用层干预。
在ADK的sink例程中,认证结束后,将当前已连接设备加入PDL,并通知应用层配对成功。
case CL_SM_AUTHENTICATE_CFM:
sinkHandleAuthenticateCfm();à
deviceManagerMarkTrusted(&cfm->bd_addr);
MessageSend (&theSink.task , EventSysPairingSuccessful , 0 );
case ( EventSysPairingSuccessful):
stateManagerEnterConnectableState(FALSE); /*SM:[ConnDisc]->[Connectable]*/
之后BlueStack通知设备,A2DP连接建立成功。其对应的角色以及消息发送流程如图所示:

case A2DP_SIGNALLING_CONNECT_CFM:
handleA2DPSignallingConnected();à
MessageSend(&theSink.task, EventSysA2dpConnected, 0);
connectA2dpStream( priority, D_SEC(5) );à
connectA2dpStream();à
openStream(priority, 0);
同时开启HFP连接,BlueStack首先发送CL_RFCOMM_CONNECT_IND信号给HFP库,HFP库随后通过HFP_SLC_CONNECT_IND信号通知应用层是否接受当前RFCOMM连接,随后依次进行一些HFP参数相关的交互,在应用层接收到HFP_SLC_CONNECT_CFM后,正式确认HFP连接成功。
case HFP_SLC_CONNECT_CFM:
sinkHandleSlcConnectCfm((HFP_SLC_CONNECT_CFM_T *) message);à
slcConnectionComplete(); /*Handle new connection setup */
slcConnectionSetup(); /* Handle common setup for new SLC/link loss */
MessageSendLater ( &theSink.task , EventSysCheckForAudioTransfer , 0 , 5000 ) ;
MessageSend (&theSink.task , EventSysSLCConnected , NULL );
至此,连接过程完成,设备处于已连接状态,随时接收到来的A2DP和HFP数据流请求。
十一、设备初始化(ADK4.0)的更多相关文章
- linux PCI设备初始化过程
linux PCI设备初始化过程 start_kernel->rest_init 这个函数会启动一个核心线程0, 核心线程然后调用init -> do_basic_setup. 然后我们开 ...
- rt-thread 之组件与设备初始化配置
@2019-03-08 [小记] rt-thread 初始化配置有两个分支: 第一,板级设备初始化 rt_components_board_init() 第二,内核组件初始化 rt_component ...
- linux内核中经常用到的设备初始化宏
内核使用了大量不同的宏来标记具有不同作用的函数和数据结构.如宏__init.__devinit等.这些宏在include/linux/init.h头文件中定义.编译器通过这些宏可以把代码优化放到合适的 ...
- Nouveau源代码分析(三):NVIDIA设备初始化之nouveau_drm_probe
Nouveau源代码分析(三) 向DRM注冊了Nouveau驱动之后,内核中的PCI模块就会扫描全部没有相应驱动的设备,然后和nouveau_drm_pci_table对比. 对于匹配的设备,PCI模 ...
- java Class的Long id初始化 为0的问题android数据库操做出现的 android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
java的class中的Long类型变量调用默认的 构造函数new后会被初始化为0. 这句话大家可能感觉这么低级的事情还用你说? 我想说的是这个会产生的一个应用场景 和 避免方法 场景:db插入时候p ...
- Towelroot v3.0版发布 将支持更多设备 Towelroot v3.0下载
Towelroot虽然已经发布一段时间了,虽然所Towelroot可以一键ROOT很多设备,虽然它只有100多K.不过还是有一小部分的机型没办法ROOT成功的,也不知道什么原因.不过不用担心,Geoh ...
- Swift从入门到精通第十一篇 - 初始化 初识
初始化(学习笔记) 环境Xcode 11.0 beta4 swift 5.1 初始化 初始化是类.结构体.枚举生成实例的过程,为该类的每个存储属性设置初始值,有些在实例使用前的设置或初始化也可在此实现 ...
- linux设备驱动程序-i2c(0)-i2c设备驱动源码实现
(基于4.14内核版本) 为了梳理清楚linux内核中的i2c实现框架,从本文开始,博主将分几个章节分别解析i2c总线在linux内核中的形成过程.匹配过程.以及设备驱动程序源码实现. 在介绍linu ...
- 第十一章 Net 5.0 快速开发框架 YC.Boilerplate --图数据库模块Neo4j
在线文档:http://doc.yc-l.com/#/README 在线演示地址:http://yc.yc-l.com/#/login 源码github:https://github.com/linb ...
随机推荐
- python中函数定义与调用顺序问题
def main(): try: mtd(3) except Exception as e: print("程序出现异常:", e) mtd(3) def mtd(a): if a ...
- JavaScript ES6函数式编程(三):函子
前面二篇学习了函数式编程的基本概念和常见用法.今天,我们来学习函数式编程的最后一个概念--函子(Functor). 相信有一部分同学对这个概念很陌生,毕竟现在已经有很多成熟的轮子,基本能满足我们日常的 ...
- 玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- WCF(一):初探WCF
目录: 一.什么是WCF 二.WCF能做什么 三.WCF的模型 四.WCF的基本概念 五.WCF的快速创建 1.WCF是什么? A.WindowsCommunication Foundation(WC ...
- java和python对比
一:解释性和编译型 梳理 编译型:源代码经过编译直接变为二进制的机器语言,每次都可以直接重新运行不需要翻译.典型的就是c语言. 解释性:java和python都是解释型,源代码经过编译变为字节码文件, ...
- ProvisionedAppxPackage VS AppxPackage
正文 先来说说问题的由来. 在 Preinstall 的 component 中,有一支 component 叫做 MS_StartApp,这个 component 的行为是在预安装时为目标机器装入一 ...
- Java基础系列二:Java泛型
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 一.泛型概述 1.定 ...
- 学习笔记之javascript编写简单计算器
感觉自己的的实力真的是有待提高,在编写计算器的过程中,出现了各种各样的问题,暴露了自己的基础不扎实,逻辑思维能力不够,学得知识不能运用到自己的demo中区.先介绍一些这个这个计算器的整体思路.大致 ...
- Luogu P1098 字符串的展开
这几天划了划水看了看初赛的试题,没写什么随笔. 今天刷刷洛谷试炼场.(不要问为什么我还在普及区) 题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串 ...
- appium 处理webview
折腾了一段时间,无论是模拟器还是真机,driver.contexts都只有NATIVE_APP,无奈放弃切换webview,直接查找定位元素 from time import sleep import ...