【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
五、基础知识
暂无
六、实验步骤
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;
到此,广播过程就结束了,很简单吧,哈哈。
- 【BLE】CC2541之开启广播过程
- [BLE] CC2541的开启广播过程
- 【BLE】CC2541之广播MAC
- 【BLE】CC2541之动态广播
- 【BLE】CC2541之修改广播时间
- 【BLE】CC2541之修改广播通道
- 【BLE】CC2541之连接时广播
- <蓝牙BLE>BLEcc2540开启广播的过程
- 【BLE】CC2541之主机端获取广播包数据
- 【BLE】CC2541之通过广播发送自定义数据
- BLE CC2541修改广播时间
- 【BLE】CC2541之notify
- 【BLE】CC2541之按键
- 【BLE】CC2541之RSSI
- 【BLE】CC2541之OLED
- 【BLE】CC2541之indicate
- 【BLE】CC2541之timer3
- 【BLE】CC2541之看门狗
- HDU 5303 Delicious Apples(思维题)
- ios开发中遇到的各种错(一)
- GitHub、SVN和TFS版本管理工具
- Spring 整合 Hibernate
- Spring 开发第一步导入jar包
- 【BLE】CC2541之开启广播过程
- Mysql 二进制日志
- FileReference 上传文件,java接收
- 安卓加密
- android 4.2以上版本永不休眠
- Unity Mesh Collider 顶点太多报错
- 给stardict添加本地辞典
- 构造函数理解
- Storm里的jave类加载问题