转自大香瓜的博客

一、简介

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

二、开启广播

在应用层开启广播功能其实非常简单,只要把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. if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )
  7. {
  8. // Turn off Advertising
  9. if ( gapRole_state == GAPROLE_ADVERTISING )
  10. {
  11. VOID GAP_EndDiscoverable( gapRole_TaskID );
  12. }
  13. }
  14. else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )
  15. {
  16. // Turn on Advertising
  17. if ( (gapRole_state == GAPROLE_STARTED)
  18. || (gapRole_state == GAPROLE_WAITING)
  19. || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )
  20. {
  21. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  22. }
  23. }
  24. }
  25. else
  26. {
  27. ret = bleInvalidRange;
  28. }
  29. 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. // Setup advertisement parameters
  7. params.eventType = gapRole_AdvEventType;
  8. params.initiatorAddrType = gapRole_AdvDirectType;
  9. VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
  10. params.channelMap = gapRole_AdvChanMap;
  11. params.filterPolicy = gapRole_AdvFilterPolicy;
  12. if ( GAP_MakeDiscoverable( gapRole_TaskID, ¶ms ) != SUCCESS )
  13. {
  14. gapRole_state = GAPROLE_ERROR;
  15. // Notify the application with the new state change
  16. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
  17. {
  18. pGapRoles_AppCGs->pfnStateChange( gapRole_state );
  19. }
  20. }
  21. }
  22. return ( events ^ START_ADVERTISING_EVT );
  23. }

事件中调用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. // Start the GAP
  16. gapRole_SetupGAP();
  17. return ( SUCCESS );
  18. }
  19. else
  20. {
  21. return ( bleAlreadyInRequestedMode );
  22. }
  23. }

再追踪一下这个注册函数,发现在应用层的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. // Start Bond Manager
  6. VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
  7. // Set timer for first periodic event
  8. osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
  9. return ( events ^ SBP_START_DEVICE_EVT );
  10. }

所以当广播开启不成功之后,会调用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;

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

蓝牙BLEBLEcc2540开启广播的过程相关推荐

  1. 针对蓝牙4.0 BLE通讯过程的逆向和攻击

    本文讲的是针对蓝牙4.0 BLE通讯过程的逆向和攻击,从6个月前,我就开始针对BLE设备进行学习和研究,其中接触到了一些关于BLE逆向的博客和文章,但是相关内容都没有给出很好的方案.因此通过我的这篇文 ...

  2. nrf52832 学习笔记(三)蓝牙从机广播

    nrf52832 学习笔记(三)蓝牙从机广播 蓝牙从机要想被主机连接,首先需要发送广播信息,周围主机通过扫描广播信号,根据从机的广播信息,判断是否连接. 蓝牙协议栈初始化 不管是主机还是从机,要想使用 ...

  3. 黑苹果oc清除nvram_黑苹果完善之路-英特尔蓝牙「开启/关闭」功能完善教程

    小编开篇提醒:玩转黑苹果有风险,建议随时备份好自己的重要数据. 很多机友安装黑苹果之后,打开蓝牙选项却发现[关闭蓝牙]选项是灰色的,无法进行选择,但是一些具有强迫症的机友内心可能会接受不了,所以就此出 ...

  4. Android官方开发文档Training系列课程中文版:电池续航时间优化之按需开启广播接收器

    原文地址:http://android.xsoftlab.net/training/monitoring-device-state/manifest-receivers.html 监测设备状态变化最简 ...

  5. Android 蓝牙相关的广播

    2019独角兽企业重金招聘Python工程师标准>>> Android 蓝牙相关的广播 监听蓝牙相关的广播并获得相关的信息,蓝牙相关的广播主要集中在BluetoothAdapter和 ...

  6. android蓝牙广播自定义,Android 蓝牙相关的广播

    Android 蓝牙相关的广播 监听蓝牙相关的广播并获得相关的信息,蓝牙相关的广播主要集中在BluetoothAdapter和BluetoothDevice类中, 可以通过在AndroidManife ...

  7. [高通MSM8953_64][Android10]默认关闭蓝牙以及开启蓝牙状态栏不显示图标

    文章目录 开发平台基本信息 问题描述 解决方法 1.默认关闭蓝牙 2.开启蓝牙状态栏不显示图标 开发平台基本信息 芯片: MSM8953_64 版本: Android 10 kernel: msm-4 ...

  8. android 蓝牙相关广播,Android 蓝牙相关的广播

    Android 蓝牙相关的广播 监听蓝牙相关的广播并获得相关的信息,蓝牙相关的广播主要集中在BluetoothAdapter和BluetoothDevice类中, 可以通过在AndroidManife ...

  9. BLE蓝牙笔记----广播连接过程

    本文是参考一些博文和书籍做的笔记,如有不适联系删除 参考:https://www.cnblogs.com/iini/p/8977806.html 参考文章: <BLE4.0 低功耗蓝牙 协议 总 ...

最新文章

  1. 第八期直播《立体视觉之立体匹配理论与实战》精彩回录
  2. MSTP和MPLS专线有什么区别?——Vecloud
  3. 探秘音视频网络优化与全球化部署最佳实践
  4. 甲流病人初筛(信息学奥赛一本通-T1399)
  5. 继承20161223
  6. 2个recordset合并_史上最全!8种办法玩转Excel文字合并,总有一款适合你!
  7. 软件开发高手须掌握的4大SQL精髓语句(综合篇)
  8. caxa线切割怎样画链轮_Autocad实战教程-线切割画链轮
  9. 计算机无法识别1136打印机,惠普HP M1136打印机驱动安装失败的多种解决办法
  10. ORACLE局域网连接
  11. 只有单号,用这个方法自动识别快递公司,快速查询出物流
  12. 如何使用api调用AI抠图服务
  13. python weekday()函数
  14. 美团点评2020校招笔试题1(栈,堆)
  15. VS Code + GCC 搭建 STM32 开发环境
  16. 字符串数组长度的几种求法
  17. Bosun安装、配置、部署
  18. 【源码】电压控制DC/DC双向变换器仿真
  19. sweet home 3d 免费的家居设计软件
  20. 现在很多的APP都有“附近的人“功能,这是哪个知识实现的呢!

热门文章

  1. 测不准原理?记一次Guava队列问题的排查
  2. Mysql教程(Windows)
  3. k8s探针检测php,K8s探针
  4. 什么是面向对象?面向对象的特征?面向对象和面向过程的区别?
  5. 【动态规划】区间动态规划
  6. 计算机网络-什么是因特网
  7. U3D_API_解析
  8. 基于Java的雷电游戏设计(含源文件)
  9. 以“人”为本,精准营销
  10. grails springboot_Spring Boot 和 Grails 的不同点