nRF5 SDK 有个函数sd_ble_gatts_service_add,该怎么正确理解这个函数呢???
时间: 2024-06-12 17:03:25 浏览: 133
该函数是用于向SoftDevice添加GATT服务的函数,其中sd_ble_gatts_service_add函数的参数包括:
1. conn_handle:连接句柄,指定服务所属的连接。
2. p_uuid:服务的UUID,指定服务的唯一标识符。
3. p_handle:服务句柄,这是一个指向16位整数数组的指针,指定要分配的服务句柄范围。如果为NULL,则由SoftDevice分配。
4. handle_count:句柄计数,指定要分配的服务句柄数。
5. p_context:服务上下文,指定要与服务关联的上下文数据。可以为NULL。
该函数的作用是向SoftDevice添加一个GATT服务,将服务的UUID、句柄范围和上下文数据等信息传递给SoftDevice,SoftDevice会为该服务分配句柄并将其添加到GATT数据库中。添加成功后,应用程序就可以使用该服务和其特征进行通信。
需要注意的是,该函数必须在连接建立后调用,否则会返回错误。另外,该函数在执行时会阻塞应用程序的执行,直到服务添加完成。
相关问题
NRF5 SDK的函数 sd_ble_gatts_characteristic_add
函数名称:sd_ble_gatts_characteristic_add
功 能:添加GATT服务的特征
参 数:
uint16_t service_handle:服务句柄
ble_gatts_char_md_t const * p_char_md:特征元数据指针
ble_gatts_attr_t const * p_attr_char_value:特征值指针
uint16_t * p_handles:特征句柄指针
返回值:返回一个错误代码,用于表明函数是否执行成功
函数描述:该函数用于向GATT数据库添加特征。特征是GATT服务的一个组成部分,用于描述服务中的某个特定值。在添加特征时,应先创建服务,然后添加特征。
注意事项:
1.特征元数据中应包含特征的属性(如读、写、通知等)。
2.特征值的长度应小于等于GATT MTU(最大传输单元)的长度。
3.特征句柄指针将用于存储添加特征后返回的特征句柄。
4.特征句柄用于标识一个特征,以便后续操作。
5.特征句柄的值应大于等于服务句柄,小于等于服务句柄+服务中特征的数量。
6.如果在添加特征时指定了写权限,则在写入特征值时应使用sd_ble_gatts_value_set函数。
请给出Nordic nRF5 SDK中创建新的BLE服务的详细示例
好的,下面是使用Nordic nRF5 SDK创建新的BLE服务的详细示例:
1. 首先,在nRF5 SDK中打开“examples\ble_peripheral\ble_app_template”示例。
2. 在“ble_app”文件夹中,打开“ble_srv_common.h”文件。此文件包含了一些常用的BLE服务定义,你可以通过阅读该文件来了解BLE服务的实现方式。
3. 在“ble_app”文件夹中,打开“ble_srv_common.c”文件。此文件包含了一些常用的BLE服务实现代码,你可以通过阅读该文件来了解BLE服务的实现方式。
4. 在“ble_app”文件夹中,创建一个新的文件夹,命名为“my_service”。
5. 在“my_service”文件夹中,创建一个新的文件,命名为“my_service.h”。在该文件中,你需要定义你的自定义BLE服务的UUID,以及相关的特性和属性等信息。例如:
```
#ifndef MY_SERVICE_H
#define MY_SERVICE_H
#include "ble.h"
#include "ble_srv_common.h"
#define BLE_UUID_MY_SERVICE 0x1234 // 自定义服务的UUID
// 自定义服务的特性UUID
#define BLE_UUID_MY_SERVICE_CHARACTERISTIC 0x5678
// 自定义服务的特性值结构体
typedef struct
{
uint8_t value;
} ble_my_service_characteristic_t;
// 自定义服务的事件结构体
typedef struct
{
ble_my_service_characteristic_t char_value;
} ble_my_service_evt_t;
// 自定义服务的事件句柄类型
typedef void (*ble_my_service_evt_handler_t) (ble_my_service_evt_t * p_evt);
// 自定义服务的初始化函数
uint32_t ble_my_service_init(void);
// 自定义服务的事件注册函数
void ble_my_service_evt_handler_register(ble_my_service_evt_handler_t evt_handler);
#endif // MY_SERVICE_H
```
6. 在“my_service”文件夹中,创建一个新的文件,命名为“my_service.c”。在该文件中,你需要实现你的自定义BLE服务的初始化、事件处理等功能。例如:
```
#include "my_service.h"
static uint16_t m_service_handle; // 自定义服务的句柄
static ble_gatts_char_handles_t m_char_handles; // 自定义服务的特性句柄
static ble_my_service_evt_handler_t m_evt_handler; // 自定义服务的事件处理函数
// 自定义服务的事件回调函数
static void my_service_evt_handler(ble_evt_t const * p_ble_evt)
{
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
break;
case BLE_GAP_EVT_DISCONNECTED:
break;
case BLE_GATTS_EVT_WRITE:
if (p_ble_evt->evt.gatts_evt.params.write.handle == m_char_handles.value_handle)
{
ble_my_service_evt_t evt;
evt.char_value.value = p_ble_evt->evt.gatts_evt.params.write.data[0];
m_evt_handler(&evt);
}
break;
default:
break;
}
}
// 自定义服务的事件注册函数
void ble_my_service_evt_handler_register(ble_my_service_evt_handler_t evt_handler)
{
m_evt_handler = evt_handler;
}
// 自定义服务的初始化函数
uint32_t ble_my_service_init(void)
{
uint32_t err_code;
ble_uuid_t ble_uuid;
ble_uuid128_t base_uuid = {BLE_UUID_MY_SERVICE_BASE};
// 生成自定义服务的UUID
err_code = sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type);
VERIFY_SUCCESS(err_code);
ble_uuid.uuid = BLE_UUID_MY_SERVICE;
// 添加自定义服务
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &m_service_handle);
VERIFY_SUCCESS(err_code);
// 添加自定义服务的特性
ble_gatts_char_md_t char_md;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.write = 1;
ble_gatts_attr_md_t attr_md;
memset(&attr_md, 0, sizeof(attr_md));
attr_md.read_perm = BLE_GAP_CONN_SEC_MODE_OPEN;
attr_md.write_perm = BLE_GAP_CONN_SEC_MODE_OPEN;
attr_md.vloc = BLE_GATTS_VLOC_STACK;
ble_uuid_t char_uuid;
char_uuid.uuid = BLE_UUID_MY_SERVICE_CHARACTERISTIC;
char_uuid.type = ble_uuid.type;
ble_gatts_attr_t attr;
memset(&attr, 0, sizeof(attr));
attr.p_uuid = &char_uuid;
attr.p_attr_md = &attr_md;
attr.init_len = sizeof(ble_my_service_characteristic_t);
attr.max_len = sizeof(ble_my_service_characteristic_t);
attr.p_value = NULL;
err_code = sd_ble_gatts_characteristic_add(m_service_handle, &char_md, &attr, &m_char_handles);
VERIFY_SUCCESS(err_code);
// 注册事件回调函数
err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) DEVICE_NAME, strlen(DEVICE_NAME));
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, TX_POWER);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_SCAN_INIT, 0, TX_POWER);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, 0, TX_POWER);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gap_ppcp_set(&ppcp);
VERIFY_SUCCESS(err_code);
return NRF_SUCCESS;
}
```
7. 在“main.c”文件中,包含“my_service.h”头文件,并在初始化函数中调用“ble_my_service_init()”函数来初始化你的自定义BLE服务。例如:
```
#include "my_service.h"
int main(void)
{
uint32_t err_code;
// 初始化BLE协议栈
ble_stack_init();
// 初始化GAP参数
gap_params_init();
// 初始化GATT参数
gatt_init();
// 初始化自定义服务
err_code = ble_my_service_init();
APP_ERROR_CHECK(err_code);
// 启动广播
advertising_start();
// 进入主循环
for (;;)
{
idle_state_handle();
}
}
```
到此为止,我们已经完成了一个简单的自定义BLE服务的创建实例。你可以根据自己的需要修改“my_service.h”和“my_service.c”文件,来实现更加复杂的自定义BLE服务。
阅读全文