发现一个服务的基本思路是搜索Primary Service的UUID(0x2800),如果找到,即可获得它的句柄范围。 第一次我们从0x0001开始搜索,找到一个服务后,从该服务的句柄末尾开始继续搜索,可以找到第二个服务的句柄范围。 反复执行发现服务操作,就可以依次找到全部服务的句柄范围。根据上面所描述,给出nrf52832的代码
时间: 2024-03-19 10:44:33 浏览: 105
以下是在nRF52832上实现发现服务的基本代码示例:
```
#include <stdbool.h>
#include <stdint.h>
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_scan.h"
#include "nrf_error.h"
#include "nrf_log.h"
#define SCAN_INTERVAL 0x00A0 // 扫描间隔,单位为 0.625ms
#define SCAN_WINDOW 0x0050 // 扫描窗口,单位为 0.625ms
#define SCAN_TIMEOUT 0x0000 // 扫描超时时间,单位为 10ms,0 表示无限扫描
#define BLE_UUID_GENERIC_ACCESS_SERVICE 0x1800 // Generic Access服务的UUID
#define BLE_UUID_PRIMARY_SERVICE 0x2800 // Primary Service服务的UUID
static uint8_t m_scan_buffer_data[NRF_BLE_SCAN_SCAN_BUFFER_SIZE];
static nrf_ble_scan_t m_scan;
static bool m_is_discovery_complete = false;
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
ret_code_t err_code;
switch (p_scan_evt->scan_evt_id)
{
case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
m_is_discovery_complete = true;
break;
case NRF_BLE_SCAN_EVT_SCAN_REPORT:
// 处理扫描到的蓝牙设备信息
break;
default:
break;
}
}
static ret_code_t ble_scan_init(void)
{
ret_code_t err_code;
nrf_ble_scan_init_t scan_init = {
.p_scan_buffer = m_scan_buffer_data,
.scan_buffer_size = NRF_BLE_SCAN_SCAN_BUFFER_SIZE,
.connect_if_match = false,
.scan_evt_handler = scan_evt_handler,
};
err_code = nrf_ble_scan_init(&m_scan, &scan_init);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
nrf_ble_scan_filter_t filters[] =
{
// 设置扫描过滤器,将扫描结果仅限制为服务 UUID 为 Generic Access 或 Primary Service 的设备
{
.type = NRF_BLE_SCAN_FILTER_UUID,
.uuid = {BLE_UUID_GENERIC_ACCESS_SERVICE, BLE_UUID_PRIMARY_SERVICE},
.len = NRF_BLE_SCAN_UUIDS_FILTER_LEN,
},
};
err_code = nrf_ble_scan_filters_set(&m_scan, filters, sizeof(filters) / sizeof(nrf_ble_scan_filter_t));
if (err_code != NRF_SUCCESS)
{
return err_code;
}
err_code = nrf_ble_scan_start(&m_scan);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
return NRF_SUCCESS;
}
static ret_code_t ble_discover_services(uint16_t conn_handle)
{
ret_code_t err_code;
uint16_t start_handle = 0x0001;
uint16_t end_handle;
while (!m_is_discovery_complete)
{
// 发现Primary Service服务的句柄范围
err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, NULL);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// 等待发现Primary Service服务完成
while (!m_is_discovery_complete)
{
err_code = sd_app_evt_wait();
if (err_code != NRF_SUCCESS)
{
return err_code;
}
}
// 获取发现的Primary Service服务的句柄范围
err_code = sd_ble_gattc_service_count_get(conn_handle, &end_handle);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// 检查是否有更多的服务需要发现
if (end_handle == start_handle)
{
break;
}
else
{
start_handle = end_handle + 1;
}
}
return NRF_SUCCESS;
}
int main(void)
{
ret_code_t err_code;
err_code = nrf_ble_scan_init();
if (err_code != NRF_SUCCESS)
{
// 初始化扫描模块失败
return -1;
}
err_code = ble_scan_init();
if (err_code != NRF_SUCCESS)
{
// 启动扫描失败
return -1;
}
// 等待扫描完成
while (!m_is_discovery_complete)
{
err_code = sd_app_evt_wait();
if (err_code != NRF_SUCCESS)
{
// 等待事件失败
break;
}
}
// 开始发现从机设备的服务
err_code = ble_discover_services(conn_handle);
if (err_code != NRF_SUCCESS)
{
// 发现服务失败
return -1;
}
// 连接和服务发现完成,可以进行其他操作了
while (true)
{
// 循环执行其他任务
}
}
```
以上是一个基本的示例代码,仅供参考。具体的实现方式可能会根据不同的应用场景和需求而有所不同。
阅读全文