BLE工程——外设+广播者实现(使用peripheralBroadcaster.c)

为了实现外设+广播者的功能,除了直接使用peripheral.c和peripheral.h两个文件之外,TI还提供了peripheralBroadcaster.c和peripheralBroadcaster.h两个文件,下面就使用这两个文件来实现外设+广播者功能。我在《BLE工程——外设+广播者实现(使用peripheral.c)》一文的工程中进行修改。

1、将PROFILES工程组下peripheral.c和peripheral.h两个文件从工程中剔除,同时将peripheralBroadcaster.c和peripheralBroadcaster.h两个文件加入该工程组中。

BLE工程——外设+广播者实现(使用peripheralBroadcaster.c) - ziye334 - ziye334的博客

2、此时编译工程会出现错误,打开peripheral.c文件,将包含的头文件:

#include "hci.h"

改为:

#include "hci_tl.h"

3、此时,编译虽然通过了,但下载到开发板中设备却不广播。原因在于GAPRole_Init()函数中角色设置错误了,需要将:

gapRole_profileRole=(GAP_PROFILE_PERIPHERAL|GAP_PROFILE_BROADCASTER);

改为:

gapRole_profileRole = (GAP_PROFILE_PERIPHERAL);

之所以要这么改是因为gapRole_SetupGAP()->GAP_DeviceInit()函数内选择条件中并没有GAP_PROFILE_PERIPHERAL|GAP_PROFILE_BROADCASTER这样的选项。

4、此时设备会开始广播,手机连上之后,但不一会儿连接就断开了。这个问题的原因是连接参数更新出错。需要做如下修改:

a.定义两个变量,一个用来保存连接的间隔参数,另一个用来保存连接延时个数。

static uint16 gapRole_ConnInterval = 0;

static uint16 gapRole_ConnSlaveLatency = 0;

b.在设备连接时,即gapRole_ProcessGAPMsg()函数的GAP_LINK_ESTABLISHED_EVENT选项中保存连接参数,添加如下两句:

if ( pPkt->hdr.status == SUCCESS )

{

  ......

  /* Store connection information */

  gapRole_ConnInterval = pPkt->connInterval;

  gapRole_ConnSlaveLatency = pPkt->connLatency;

  ......

}

c.当连接参数更新超时时,重新更新连接参数。将GAPRole_ProcessEvent()函数中的if ( events & UPDATE_PARAMS_TIMEOUT_EVT )条件内的:

/* 这就是连接后会断开的原因 */

VOID GAP_TerminateLinkReq( gapRole_TaskID, gapRole_ConnectionHandle, 

                   HCI_DISCONNECT_REMOTE_USER_TERM );

修改为:

gapRole_SendUpdateParam( gapRole_ConnInterval, gapRole_ConnSlaveLatency );

5、此时,虽然连接后连接不会断,但是按下JoyStick的上键是并没有开始广播。主要的原因是peripheralBroadcaster.c对用于保存广播状态的变量gapRole_AdvEnabled设置不明确,需要在如下几处做修改:

a.当设备连接时,系统会自动关闭广播,但代码并没有改变gapRole_AdvEnabled的状态,所以需要在gapRole_ProcessGAPMsg()函数的GAP_LINK_ESTABLISHED_EVENT选项中,添加语句:

if ( pPkt->hdr.status == SUCCESS )

{

  .....

  gapRole_AdvEnabled = FALSE;

}

b.每次设置打开/关闭广播时都要设置gapRole_AdvEnabled变量,即在GAPRole_SetParameter()中的GAPROLE_ADVERT_ENABLED选项中,添加语句:

if ( (gapRole_state == GAPROLE_CONNECTED) && (advEnabled == TRUE) )

{

gapRole_AdvEnabled = TRUE;

......

}

else if ( ..... )

{

gapRole_AdvEnabled = FALSE;

......

}

c.gapRole_ProcessGAPMsg()函数下的GAP_LINK_TERMINATED_EVENT选项中添加:

if ( gapRole_state == GAPROLE_CONNECTED_ADV )

{

  ......

}

else

{

.......

gapRole_AdvEnabled = TRUE;

}

6、此时,设备连接上后,按下JoyStick的上键则开始广播,再按下JoyStick的上键广播就会广播,但如再按下JoyStick的上键打算再次打开广播就会出现错误。造成这种原因是:连接后打开再关闭广播,此时设备的状态被设置成GAPROLE_WAITING状态,所以再次打开广播时GAPRole_ProcessEvent()的if ( events & START_ADVERTISING_EVT )条件下的:

if ( gapRole_state == GAPROLE_CONNECTED )

{

  /* 不可连接广播 */

  params.eventType = GAP_ADTYPE_ADV_NONCONN_IND;

}

else

{

  params.eventType = gapRole_AdvEventType;

  params.initiatorAddrType = gapRole_AdvDirectType;

  VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, 

                    B_ADDR_LEN );

}

由于状态不是GAPROLE_CONNECTED,所以广播会被设置成连接的广播,所以会出错。要修正这个问题,需要将gapRole_ProcessGAPMsg()函数中的GAP_END_DISCOVERABLE_DONE_EVENT选项下的:

gapRole_state = GAPROLE_WAITING;

修改成:

if (gapRole_state == GAPROLE_CONNECTED_ADV)

{

  gapRole_state = GAPROLE_CONNECTED;

}

else if (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT)

{

  gapRole_AdvEnabled = TRUE;

              

  VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );

}

else

{

  gapRole_state = GAPROLE_WAITING;

}

7、此时,广播的控制正常,但是当设备处于连接+广播状态,此时断开连接后设备将不再广播,所以打开simpleBLEPeripheral.c文件,将原先peripheralStateNotificationCB()函数中的GAPROLE_WAITING选项下的:

static uint8  auto_stop_adv= 0;

if ( auto_stop_adv )

{

  uint8 adv_enabled_status = 1;

  GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), 

                      &adv_enabled_status);

  auto_stop_adv = 0;

}

if ( gapProfileState == GAPROLE_CONNECTED_ADV )        

{

  auto_stop_adv = 1;

}

修改为:

if ( gapProfileState == GAPROLE_CONNECTED_ADV ) 

{

  uint8 adv_enabled_status = 1;

  GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), 

                      &adv_enabled_status); 

}

 

到此,就基本上修改完成了,将程序下载进SmartRF开发板中,在SmartRF首次运行时,就默认已经将广播打开了。

<1>按下JoyStick的上键,则将会将广播关闭,LCD上显示disconnect。

<2>在按下JoyStick的上键,则再次打开广播,LCD上显示advertising。

<3>手机连接SmartRF后,LCD上显示connected。

<4>按下JoyStick的上键,开启广播,LCD上显示connected advertising。此时,手机就可再次收到广播信号,但无法连接。

<5>按下JoyStick的上键,关闭广播,LCD上显示再次显示connected。

<6>手机断开,广播再次开启,且是可连接的广播,此时LCD显示advertising。

<7>如果手机连接了SmartRF,且不可连接广播开启着,此时手机断开连接,会继续广播,但变成可连接广播,LCD显示advertising。

评论

© ziye334 | Powered by LOFTER