有一个项目使用了 nRF52832 芯片作为主控,其中有用到蓝牙功能。在对蓝牙接口进一步封装的时候,发现 SDK 居然没有停止广播的接口,咨询了代理 FAE,对方也没有找到关闭广播的接口。后来通过分析代码,修改了 SDK 解决了这个问题。这次发出来是因为遇到很多人在问这个问题,记得自己解决过,就发出来。
遗憾的是,当初为了赶项目,很多问题解决之后没有及时做记录,现在已经记不清当时的解决思路了,毕竟第一次接触 Nordic 芯片,后面又基本没用上,不过 Nordic SDK 的代码风格还是很赞的。
想不明白,为什么 Nordic 不提供关闭蓝牙广播的接口,SDK已经迭代了那么多个版本了,可能是因为对功耗影响不大所以没有必要提供了?还是说有其他的方式可以关闭蓝牙广播接口?
适用于 SDK15
From 67a4b2c241626e51192f6e1d528a07ba0ac4ab8d Mon Sep 17 00:00:00 2001
From: lmx
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 示例代码。