【BLE】CC2541之开启广播过程

来源:互联网 发布:网络诈骗小金额 编辑:程序博客网 时间:2024/06/05 18:24

本篇博文最后修改时间:2016年11月11日,09:31。


一、简介

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


二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Amart RF开发板(主芯片CC2541)


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、实验前提
1、在进行本文步骤前,请先阅读以下博文:
暂无

2、在进行本文步骤前,请先实现以下博文:
暂无


五、基础知识

暂无


六、实验步骤

1、开启广播simpleBLEPeripheral.c的SimpleBLEPeripheral_Init中


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


七、解析协议栈在开启广播的操作后做了什么

1、GAPRole_SetParameter函数中的GAPROLE_ADVERT_ENABLED

    case GAPROLE_ADVERT_ENABLED:      if ( len == sizeof( uint8 ) )      {        uint8 oldAdvEnabled = gapRole_AdvEnabled;        gapRole_AdvEnabled = *((uint8*)pValue);        if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )        {          // Turn off Advertising          if ( gapRole_state == GAPROLE_ADVERTISING )          {            VOID GAP_EndDiscoverable( gapRole_TaskID );          }        }        else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )        {          // Turn on Advertising          if ( (gapRole_state == GAPROLE_STARTED)              || (gapRole_state == GAPROLE_WAITING)              || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )          {            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );          }        }      }      else      {        ret = bleInvalidRange;      }      break;

其中gapRole_AdvEnabled默认是TRUE

static uint8  gapRole_AdvEnabled = TRUE;

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

        uint8 oldAdvEnabled = gapRole_AdvEnabled;        gapRole_AdvEnabled = *((uint8*)pValue);

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

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

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


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

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

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

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


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

        else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )        {          // Turn on Advertising          if ( (gapRole_state == GAPROLE_STARTED)              || (gapRole_state == GAPROLE_WAITING)              || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )          {            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );          }        }

2、START_ADVERTISING_EVT事件

  if ( events & START_ADVERTISING_EVT )  {    if ( gapRole_AdvEnabled )    {      gapAdvertisingParams_t params;      // Setup advertisement parameters      params.eventType = gapRole_AdvEventType;      params.initiatorAddrType = gapRole_AdvDirectType;      VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );      params.channelMap = gapRole_AdvChanMap;      params.filterPolicy = gapRole_AdvFilterPolicy;      if ( GAP_MakeDiscoverable( gapRole_TaskID, ¶ms ) != SUCCESS )      {        gapRole_state = GAPROLE_ERROR;                // Notify the application with the new state change        if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )        {          pGapRoles_AppCGs->pfnStateChange( gapRole_state );        }      }    }    return ( events ^ START_ADVERTISING_EVT );  }
事件中调用GAP_MakeDiscoverable即可开启广播。

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

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

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

/********************************************************************* * @brief   Does the device initialization. * * Public function defined in peripheral.h. */bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks ){  if ( gapRole_state == GAPROLE_INIT )  {    // Clear all of the Application callbacks    if ( pAppCallbacks )    {      pGapRoles_AppCGs = pAppCallbacks;    }    // Start the GAP    gapRole_SetupGAP();    return ( SUCCESS );  }  else  {    return ( bleAlreadyInRequestedMode );  }}

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

  if ( events & SBP_START_DEVICE_EVT )  {    // Start the Device    VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );    // Start Bond Manager    VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );    // Set timer for first periodic event    osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );    return ( events ^ SBP_START_DEVICE_EVT );  }

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

// GAP Role Callbacksstatic gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs ={  peripheralStateNotificationCB,  // Profile State Change Callbacks  NULL                            // When a valid RSSI is read from controller (not used by application)};

    case GAPROLE_ERROR:      {        #if (defined HAL_LCD) && (HAL_LCD == TRUE)          HalLcdWriteString( "Error",  HAL_LCD_LINE_3 );        #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)      }      break;

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


3 0
原创粉丝点击