<蓝牙BLE>BLEcc2540开启广播的过程
来源:互联网 发布:sql server 2012安装 编辑:程序博客网 时间:2024/05/17 23:35
转自大香瓜的博客
一、简介
本篇介绍在应用层如何开启广播,且解析协议栈在此操作后做了什么。
二、开启广播
在应用层开启广播功能其实非常简单,只要把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 );
- }
如果广播不成功,则会调用函数指针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 Callbacks
- static 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>BLEcc2540开启广播的过程
- [BLE] CC2541的开启广播过程
- 【BLE】CC2541之开启广播过程
- 蓝牙解析(part5):BLE的广播通信
- 蓝牙BLE 广播数据
- <蓝牙BLE>cc2540从机连接时的动态广播
- <蓝牙BLE>如何修改蓝牙广播时间
- <蓝牙BLE>cc2540修改动态广播
- 蓝牙4.0 BLE 广播包解析
- 低功耗蓝牙BLE之广播
- 蓝牙4.0 BLE 广播包解析
- 蓝牙4.0 BLE peripheral 广播设置
- 低功耗蓝牙BLE之广播
- 低功耗蓝牙BLE之广播
- 低功耗蓝牙BLE之广播
- Ble蓝牙的使用手册
- 【蓝牙BLE】cc2540主机获取广播包存在的一些问题。
- 对于ble ios作为中心设备收不到蓝牙外设广播信息的解决办法
- spring mvc与Mybatis整合——(四)mvc与mybatis整合
- ubuntu13.04安装 robot operating system机器人系统
- CC2541、CC2640 SNV Flash 读写
- [.Net码农]FastReport.NET WebReport标签使用教程
- LinkedList中的remove方法
- <蓝牙BLE>BLEcc2540开启广播的过程
- c++中,结构体和联合体的区别
- Activity的四种加载模式及有关Activity横竖屏切换的问题
- ViewDragHelper之拖动加载(类似淘宝)
- 网上收集的一些Xmanager注册码
- php简单对象与数组的转换
- 【网络流】最大流:PIGS【EK模板、建图题】
- ubuntu设置开机自动登陆与登录自动运行脚本
- git版本控制