前言

有一个项目使用了 nRF52832 芯片作为主控,其中有用到蓝牙功能。在对蓝牙接口进一步封装的时候,发现 SDK 居然没有停止广播的接口,咨询了代理 FAE,对方也没有找到关闭广播的接口。后来通过分析代码,修改了 SDK 解决了这个问题。这次发出来是因为遇到很多人在问这个问题,记得自己解决过,就发出来。

遗憾的是,当初为了赶项目,很多问题解决之后没有及时做记录,现在已经记不清当时的解决思路了,毕竟第一次接触 Nordic 芯片,后面又基本没用上,不过 Nordic SDK 的代码风格还是很赞的。

想不明白,为什么 Nordic 不提供关闭蓝牙广播的接口,SDK已经迭代了那么多个版本了,可能是因为对功耗影响不大所以没有必要提供了?还是说有其他的方式可以关闭蓝牙广播接口?

补丁

适用于 SDK15

From 67a4b2c241626e51192f6e1d528a07ba0ac4ab8d Mon Sep 17 00:00:00 2001
From: lmx <lovemengx@qq.com>
Date: Thu, 6 Jun 2019 18:37:50 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9SDK:=20ble=5Fadvertising,=20?=
=?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=AF=E4=BB=A5=E9=9A=8F=E6=84=8F=E5=81=9C?=
=?UTF-8?q?=E6=AD=A2=E5=B9=BF=E6=92=AD=E7=9A=84=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit ---
.../ble/ble_advertising/ble_advertising.c | 29 ++++++++++++++-----
.../ble/ble_advertising/ble_advertising.h | 11 +++++++
2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/components/ble/ble_advertising/ble_advertising.c b/components/ble/ble_advertising/ble_advertising.c
index e09c2dd..5907b2f 100644
--- a/components/ble/ble_advertising/ble_advertising.c
+++ b/components/ble/ble_advertising/ble_advertising.c
@@ -459,6 +459,7 @@ uint32_t ble_advertising_init(ble_advertising_t * const p_advertising
p_advertising->error_handler = p_init->error_handler;
p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
p_advertising->p_adv_data = &p_advertising->adv_data;
+ p_advertising->flags = BLE_ADVERTISING_FLAGS_ENABLE; // add lmx 20190606 memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address)); @@ -531,6 +532,18 @@ static bool phy_is_valid(uint32_t const * const p_phy)
}
} +// add lmx 20190606 设置标志位
+uint32_t ble_advertising_set_flag(ble_advertising_t * const p_advertising, ble_advertising_flags_t flags)
+{
+ if (p_advertising->initialized == false)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_advertising->flags = flags;
+
+ return NRF_SUCCESS;
+} uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
ble_adv_mode_t advertising_mode)
@@ -644,18 +657,20 @@ uint32_t ble_advertising_start(ble_advertising_t * const p_advertising, if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
{
-
ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params);
if (ret != NRF_SUCCESS)
{
return ret;
}
- ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);
-
- if (ret != NRF_SUCCESS)
- {
- return ret;
- }
+ // add lmx 20190606
+ if(BLE_ADVERTISING_FLAGS_ENABLE == p_advertising->flags)
+ {
+ ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
} if (p_advertising->evt_handler != NULL)
diff --git a/components/ble/ble_advertising/ble_advertising.h b/components/ble/ble_advertising/ble_advertising.h
index 8840821..96ef6f2 100644
--- a/components/ble/ble_advertising/ble_advertising.h
+++ b/components/ble/ble_advertising/ble_advertising.h
@@ -141,6 +141,13 @@ typedef void (*ble_adv_evt_handler_t) (ble_adv_evt_t const adv_evt);
/**@brief BLE advertising error handler type. */
typedef void (*ble_adv_error_handler_t) (uint32_t nrf_error); +// add lmx 20190606
+typedef enum
+{
+ BLE_ADVERTISING_FLAGS_ENABLE, // 表示可以启用广播
+ BLE_ADVERTISING_FLAGS_DISABLE, // 表示禁止启用广播
+}ble_advertising_flags_t;
+
typedef struct
{
bool initialized;
@@ -166,6 +173,7 @@ typedef struct
bool whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */
bool whitelist_reply_expected; /**< Flag to verify that the whitelist is only set when requested. */
bool whitelist_in_use; /**< This module needs to be aware of whether or not a whitelist has been set (e.g. using the Peer Manager) in order to start advertising with the proper advertising params (filter policy). */
+ ble_advertising_flags_t flags; // add lmx 20190606
} ble_advertising_t; typedef struct
@@ -257,6 +265,9 @@ void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising, u
uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
ble_adv_mode_t advertising_mode); +// add lmx 20190606 设置标志位
+uint32_t ble_advertising_set_flag(ble_advertising_t * const p_advertising, ble_advertising_flags_t flags);
+ /**@brief Function for setting the peer address.
*
--
2.21.0.windows.1

应用

启动蓝牙并等待连接

// 启动蓝牙并等待连接
int8_t bluetooth_start(void)
{
uint32_t err_code = 0; if(BLE_ADV_EVT_IDLE != ble_adv_event)
{
NRF_LOG_ERROR("ble_adv_event != BLE_ADV_EVT_IDLE...");
NRF_LOG_FLUSH();
return -2;
} ble_advertising_set_flag(&m_advertising, BLE_ADVERTISING_FLAGS_ENABLE);
err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code); return 0;
}

停止蓝牙广播并断开连接


// 停止蓝牙广播并断开连接
int8_t bluetooth_stop(void)
{
uint32_t err_code; if(BLE_ADV_EVT_FAST != ble_adv_event)
{
return -2;
} ble_advertising_set_flag(&m_advertising, BLE_ADVERTISING_FLAGS_DISABLE);
if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
{
err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
APP_ERROR_CHECK(err_code); // 这里建议增加超时机制, 不宜死循环一直等待
while (m_conn_handle != BLE_CONN_HANDLE_INVALID)
{
NRF_LOG_INFO("wait disconnect...");
NRF_LOG_FLUSH();
nrf_delay_ms(10);
}
} sd_ble_gap_adv_stop(m_advertising.adv_handle);
err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_IDLE);
APP_ERROR_CHECK(err_code); return 0;
}

注意

这里省略了初始化部分,提供启动和停止两个函数的实现意在表明使用方法,具体可参考 SDK 示例代码。

【单片机】nRF52832 实现停止蓝牙广播接口的更多相关文章

  1. 『转』android官网翻译好的蓝牙API接口说明

    Develop API Guides 连接 蓝牙 本文内容 基础知识 蓝牙权限 设置蓝牙 查找设备 查询配对的设备 发现设备 连接设备 连接为服务器 连接为客户端 管理连接 使用配置文件 供应商特定的 ...

  2. 微信小程序之蓝牙广播信息

    期初第一次做蓝牙开锁的时候遇到的最尖锐的问题就是ios设备如何对获取的广播信息进行读取,大概用了4中方式,都无法解决,最后不得不求助官方人员.给了一个方法,大家可以参考.在此附图: 由于mac地址是6 ...

  3. 微信小程序连接低功率蓝牙控制单片机上硬件设备

    1.软件部分介绍 微信小程序是一种新的应用,用户不需要下载应用只用通过扫二维码或者打开链接就能使用,使用完后不需要卸载,直接关闭就行了.微信在2017年初推出微信小程序开发环境.任何企业,媒体,个人都 ...

  4. [安卓] 20、基于蓝牙BLE的广播包高频快速搜索

    前言: 之前介绍过很多蓝牙beacon.搜索.连接.通讯的文章.不过最近我发现:之前写的蓝牙广播包搜索的工程,搜索频率太慢,而且不能一直保持搜索状态.因此,这里探讨下高频蓝牙广播包扫描 -- 蓝牙BL ...

  5. nrf52832蓝牙开发踩过的坑

    接触nrf52832芯片已经有一段时间了,记录我踩过的坑.这些坑大多都补回来了,愿后来的开发者没有坑~ 先来点开胃小菜 一.环境问题 安装离线包遇到的错误--svdconv exited with a ...

  6. 蓝牙Beacon广播数据包格式以及解析

    目录 1. 获取原始蓝牙广播包 2. 安装WireShark软件 3. 分析Beacon广播包数据 3.1 第一个数据包格式 3.2 第二个数据包格式 3.3 Android程序开发中的蓝牙广播包 4 ...

  7. [Andriod官方API指南]连接之蓝牙

    Bluetooth —— 蓝牙 The Android platform includes support for the Bluetooth network stack, which allows ...

  8. [IOT] 自制蓝牙工牌办公室定位系统 (二)—— 基于ESP32的蓝牙信号扫描系统

      前面章节: 自制蓝牙工牌办公室定位系统 (一)-- 阿里物联网平台概览及打通端到云(硬核·干货)   目录: 1.蓝牙广播简介 2.蓝牙扫描简介 3.基于蓝牙广播和蓝牙扫描常见应用 4.ESP32 ...

  9. Android 开发 蓝牙开发

    前言 蓝牙开发其实分2个部分,一个是正常蓝牙功能的开发(比如Android蓝牙的互相连接.读取蓝牙列表.文件传输.蓝牙耳机等等).另外一个是BLE蓝牙开发(属于低功耗蓝牙设备,设备大多是血糖仪.蓝牙手 ...

  10. Android BLE蓝牙详细解读

    代码地址如下:http://www.demodashi.com/demo/15062.html 随着物联网时代的到来,越来越多的智能硬件设备开始流行起来,比如智能手环.心率检测仪.以及各式各样的智能家 ...

随机推荐

  1. 谣言检测(RDCL)——《Towards Robust False Information Detection on Social Networks with Contrastive Learning》

    论文信息 论文标题:Towards Robust False Information Detection on Social Networks with Contrastive Learning论文作 ...

  2. vue 使用vuex 刷新时保存数据

    created () { this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getIte ...

  3. .NET7 gRPC JSON转码+OpenAPI

    gRPC JSON转码 gRPC JSON 转码允许浏览器应用调用 gRPC 服务,就像它们是使用 JSON 的 RESTful API 一样. 浏览器应用不需要生成 gRPC 客户端或了解 gRPC ...

  4. Git创建、diff代码、回退版本、撤回代码,学废了吗

    .eye-care { background-color: rgba(199, 237, 204, 1); padding: 10px } .head-box { display: flex } .t ...

  5. java反序列化漏洞cc_link_one

    CC-LINK-one 前言 这里也正式进入的java的反序列化漏洞了,简单介绍一下CC是什么借用一些官方的解释:Apache Commons是Apache软件基金会的项目,曾经隶属于Jakarta项 ...

  6. 【题解】UVA10228 A Star not a Tree?

    题面传送门 解决思路 本题数据范围较小,可以使用模拟退火算法(随机化). 顾名思义,模拟退火就是一个类似于降温的过程.先设置一个较大的初温,每次随机改变状态,若使答案更优,则采取更优答案,否则根据其与 ...

  7. 2022-11-02 Acwing每日一题

    逆序对的个数 给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆 ...

  8. JAVA 用分苹果来理解本题

    思路 其实这是一道非常经典的分苹果问题:有m个一样的苹果和n个一样的盘子,把苹果放盘子里,每个盘子允许0-m个苹果,求问有多少种分法? 与本题的共通之点在于,输入的正整数可以看成m个苹果,拆分出的加数 ...

  9. c++题目:切香肠

    c++题目:切香肠 题目 题目描述 有 n 条香肠,每条香肠的长度相等.我们打算将这些香肠切开后全部分给 k 名客人,且要求每名客人获得一样多的香肠.请问最少需要切几刀?注意一刀只能切断一条香肠,每个 ...

  10. MySQL遇到的坑:sql_mode=only_full_group_by不兼容

    描述: 解决方案: show variables like "%sql_mode%"; SET sql_mode=(SELECT REPLACE(@@sql_mode," ...