<蓝牙BLE>BLEcc2540开启广播的过程

转自大香瓜的博客

一、简介

本篇介绍在应用层如何开启广播,且解析协议栈在此操作后做了什么。


二、开启广播

<蓝牙BLE>BLEcc2540开启广播的过程_第1张图片

在应用层开启广播功能其实非常简单,只要把TRUE传给GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED就可以了。


三、解析协议栈在此操作后做了什么

1、GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED

[cpp]  view plain copy
  1. case GAPROLE_ADVERT_ENABLED:  
  2.   if ( len == sizeof( uint8 ) )  
  3.   {  
  4.     uint8 oldAdvEnabled = gapRole_AdvEnabled;  
  5.     gapRole_AdvEnabled = *((uint8*)pValue);  
  6.   
  7.     if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )  
  8.     {  
  9.       // Turn off Advertising  
  10.       if ( gapRole_state == GAPROLE_ADVERTISING )  
  11.       {  
  12.         VOID GAP_EndDiscoverable( gapRole_TaskID );  
  13.       }  
  14.     }  
  15.     else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )  
  16.     {  
  17.       // Turn on Advertising  
  18.       if ( (gapRole_state == GAPROLE_STARTED)  
  19.           || (gapRole_state == GAPROLE_WAITING)  
  20.           || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )  
  21.       {  
  22.         VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );  
  23.       }  
  24.     }  
  25.   }  
  26.   else  
  27.   {  
  28.     ret = bleInvalidRange;  
  29.   }  
  30.   break;  

其中gapRole_AdvEnabled默认是TRUE

[cpp]  view plain copy
  1. static uint8  gapRole_AdvEnabled = TRUE;  

首先,每次进到这个函数里,就会把gapRole_AdvEnabled的值保存到oldAdvEnabled,再把新的状态写到gapRole_AdvEnabled。也就是这两句:

[cpp]  view plain copy
  1. uint8 oldAdvEnabled = gapRole_AdvEnabled;  
  2. gapRole_AdvEnabled = *((uint8*)pValue);  

其次,对oldAdvEnabled(旧的广播开关状态)和gapRole_AdvEnabled(新传入的广播开关状态)这两个变量进行了判断:

1)在广播状态下,想关闭广播----->关闭广播

2)在不广播的状态下,想开启广播--->开启广播


然而代码中并没有将另外两种情况编写进来,也就是

3)在广播状态下,还想开启广播

4)在不广播的状态下,还想关闭广播

协议栈把这两种情况划入了else的bleInvalidRange。


第2)种情况的开广播,调用了gapRole_TaskID任务中的START_ADVERTISING_EVT事件。

[cpp]  view plain copy
  1. else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )  
  2. {  
  3.   // Turn on Advertising  
  4.   if ( (gapRole_state == GAPROLE_STARTED)  
  5.       || (gapRole_state == GAPROLE_WAITING)  
  6.       || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )  
  7.   {  
  8.     VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );  
  9.   }  
  10. }  

2、START_ADVERTISING_EVT事件

[cpp]  view plain copy
  1. if ( events & START_ADVERTISING_EVT )  
  2. {  
  3.   if ( gapRole_AdvEnabled )  
  4.   {  
  5.     gapAdvertisingParams_t params;  
  6.   
  7.     // Setup advertisement parameters  
  8.     params.eventType = gapRole_AdvEventType;  
  9.     params.initiatorAddrType = gapRole_AdvDirectType;  
  10.     VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );  
  11.     params.channelMap = gapRole_AdvChanMap;  
  12.     params.filterPolicy = gapRole_AdvFilterPolicy;  
  13.   
  14.     if ( GAP_MakeDiscoverable( gapRole_TaskID, ¶ms ) != SUCCESS )  
  15.     {  
  16.       gapRole_state = GAPROLE_ERROR;  
  17.         
  18.       // Notify the application with the new state change  
  19.       if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )  
  20.       {  
  21.         pGapRoles_AppCGs->pfnStateChange( gapRole_state );  
  22.       }  
  23.     }  
  24.   }  
  25.   return ( events ^ START_ADVERTISING_EVT );  
  26. }  
事件中调用GAP_MakeDiscoverable即可开启广播。

如果广播不成功,则会调用函数指针pGapRoles_AppCGs指向的回调函数,并且传入参数GAPROLE_ERROR,以此来通知应用层广播不成功。

那么调用的又是哪个回调函数呢?

追踪一下pGapRoles_AppCGs发现有个注册回调函数的函数

[cpp]  view plain copy
  1. /********************************************************************* 
  2.  * @brief   Does the device initialization. 
  3.  * 
  4.  * Public function defined in peripheral.h. 
  5.  */  
  6. bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks )  
  7. {  
  8.   if ( gapRole_state == GAPROLE_INIT )  
  9.   {  
  10.     // Clear all of the Application callbacks  
  11.     if ( pAppCallbacks )  
  12.     {  
  13.       pGapRoles_AppCGs = pAppCallbacks;  
  14.     }  
  15.   
  16.     // Start the GAP  
  17.     gapRole_SetupGAP();  
  18.   
  19.     return ( SUCCESS );  
  20.   }  
  21.   else  
  22.   {  
  23.     return ( bleAlreadyInRequestedMode );  
  24.   }  
  25. }  

再追踪一下这个注册函数,发现在应用层的SBP_START_DEVICE_EVT事件中对此进行了注册

[cpp]  view plain copy
  1. if ( events & SBP_START_DEVICE_EVT )  
  2. {  
  3.   // Start the Device  
  4.   VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );  
  5.   
  6.   // Start Bond Manager  
  7.   VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );  
  8.   
  9.   // Set timer for first periodic event  
  10.   osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );  
  11.   
  12.   return ( events ^ SBP_START_DEVICE_EVT );  
  13. }  

所以当广播开启不成功之后,会调用simpleBLEPeripheral_PeripheralCBs的回调函数peripheralStateNotificationCB的GAPROLE_ERROR

[cpp]  view plain copy
  1. // GAP Role Callbacks  
  2. static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =  
  3. {  
  4.   peripheralStateNotificationCB,  // Profile State Change Callbacks  
  5.   NULL                            // When a valid RSSI is read from controller (not used by application)  
  6. };  

[cpp]  view plain copy
  1. case GAPROLE_ERROR:  
  2.   {  
  3.     #if (defined HAL_LCD) && (HAL_LCD == TRUE)  
  4.       HalLcdWriteString( "Error",  HAL_LCD_LINE_3 );  
  5.     #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)  
  6.   }  
  7.   break;  

到此,广播过程就结束了,很简单吧,哈哈。


你可能感兴趣的:(蓝牙,广播,BLE)