十一、设备初始化(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数据流请求。

 

posted on 2019-01-29 13:51  arduino  阅读(1156)  评论(0编辑  收藏  举报

导航