初始版本
This commit is contained in:
235
components/ble/ble_services/ble_nus/ble_nus.c
Normal file
235
components/ble/ble_services/ble_nus/ble_nus.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/****************************************Copyright (c)************************************************
|
||||
**
|
||||
**--------------File Info-----------------------------------------------------------------------------
|
||||
** File name:ble_nus.c
|
||||
** Last modified Date:
|
||||
** Last Version:
|
||||
** Descriptions :串口透传服务文件
|
||||
**---------------------------------------------------------------------------------------------------*/
|
||||
#include "sdk_common.h"
|
||||
//这里设置了串口透传服务程序模块的“编译开关”,所以要在sdk_config.h中启用BLE_NUS
|
||||
#if NRF_MODULE_ENABLED(BLE_NUS)
|
||||
#include "ble.h"
|
||||
#include "ble_nus.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#if 0
|
||||
#define NRF_LOG_MODULE_NAME ble_nus
|
||||
#if BLE_NUS_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL BLE_NUS_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR BLE_NUS_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR BLE_NUS_CONFIG_DEBUG_COLOR
|
||||
#else // BLE_NUS_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif // BLE_NUS_CONFIG_LOG_ENABLED
|
||||
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
#endif
|
||||
|
||||
#define BLE_NUS_MAX_RX_CHAR_LEN BLE_NUS_MAX_DATA_LEN //RX特征最大长度(字节数)
|
||||
#define BLE_NUS_MAX_TX_CHAR_LEN BLE_NUS_MAX_DATA_LEN //TX特征最大长度(字节数)
|
||||
|
||||
//SoftDevice提交的“Write”事件处理函数
|
||||
static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
|
||||
{
|
||||
//定义一个串口透传事件结构体变量,用于执行回调时传递参数
|
||||
ble_nus_evt_t evt;
|
||||
//定义write事件结构体指针并指向GATT事件的write
|
||||
ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
||||
|
||||
//清空evt结构体
|
||||
memset(&evt, 0, sizeof(ble_nus_evt_t));
|
||||
//指向串口透传实例
|
||||
evt.p_nus = p_nus;
|
||||
//设置连接句柄
|
||||
evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
|
||||
//写RX特征值
|
||||
if ((p_evt_write->handle == p_nus->rx_handles.value_handle) &&
|
||||
(p_nus->data_handler != NULL))
|
||||
{
|
||||
//设置事件类型
|
||||
evt.type = BLE_NUS_EVT_RX_DATA;
|
||||
//设置数据
|
||||
evt.params.rx_data.p_data = p_evt_write->data;
|
||||
//设置数据长度
|
||||
evt.params.rx_data.length = p_evt_write->len;
|
||||
//执行回调
|
||||
p_nus->data_handler(&evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do Nothing. This event is not relevant for this service.
|
||||
}
|
||||
}
|
||||
|
||||
//SoftDevice提交的“BLE_GATTS_EVT_HVN_TX_COMPLETE”事件处理函数
|
||||
static void on_hvx_tx_complete(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
|
||||
{
|
||||
//定义一个串口透传事件结构体变量evt,用于执行回调时传递参数
|
||||
ble_nus_evt_t evt;
|
||||
//清零evt
|
||||
memset(&evt, 0, sizeof(ble_nus_evt_t));
|
||||
//设置事件类型
|
||||
evt.type = BLE_NUS_EVT_TX_RDY;
|
||||
//指向串口透传服务实例
|
||||
evt.p_nus = p_nus;
|
||||
//设置连接句柄
|
||||
evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
|
||||
//执行回调
|
||||
p_nus->data_handler(&evt);
|
||||
}
|
||||
|
||||
|
||||
//串口透传服务BLE事件监视者的事件回调函数
|
||||
void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
|
||||
{
|
||||
//检查参数是否有效
|
||||
if ((p_context == NULL) || (p_ble_evt == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//定义一个串口透传结构体指针并指向串口透传结构体
|
||||
ble_nus_t * p_nus = (ble_nus_t *)p_context;
|
||||
//判断事件类型
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
//写事件
|
||||
case BLE_GATTS_EVT_WRITE:
|
||||
on_write(p_nus, p_ble_evt);
|
||||
break;
|
||||
//TX就绪事件
|
||||
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
|
||||
on_hvx_tx_complete(p_nus, p_ble_evt);
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//初始化串口透传服务
|
||||
uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
//定义16位UUID结构体变量
|
||||
ble_uuid_t ble_uuid;
|
||||
//定义128位UUID结构体变量,并初始化为串口透传服务UUID基数
|
||||
ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
|
||||
//定义特征参数结构体变量
|
||||
ble_add_char_params_t add_char_params;
|
||||
//检查指针是否为NULL
|
||||
VERIFY_PARAM_NOT_NULL(p_nus);
|
||||
VERIFY_PARAM_NOT_NULL(p_nus_init);
|
||||
|
||||
//拷贝串口透传服务初始化结构体中的事件句柄
|
||||
p_nus->data_handler = p_nus_init->data_handler;
|
||||
|
||||
//将自定义UUID基数添加到SoftDevice
|
||||
err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
//UUID类型和数值赋值给ble_uuid变量
|
||||
ble_uuid.type = BLE_UUID_TYPE_BLE;
|
||||
ble_uuid.uuid = BLE_UUID_NUS_SERVICE;
|
||||
|
||||
//添加串口透传服务
|
||||
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
|
||||
&ble_uuid,
|
||||
&p_nus->service_handle);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
/*---------------------以下代码添加RX特征--------------------*/
|
||||
//添加RX特征
|
||||
//配置参数之前先清零add_char_params
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
//RX特征的UUID
|
||||
add_char_params.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
|
||||
//RX特征的UUID类型
|
||||
add_char_params.uuid_type = p_nus->uuid_type;
|
||||
//设置RX特征值的最大长度
|
||||
add_char_params.max_len = BLE_NUS_MAX_RX_CHAR_LEN;
|
||||
//设置RX特征值的初始长度
|
||||
add_char_params.init_len = sizeof(uint8_t);
|
||||
//设置RX的特征值长度为可变长度
|
||||
add_char_params.is_var_len = true;
|
||||
//设置RX特征的性质支持写
|
||||
add_char_params.char_props.write = 1;
|
||||
//设置RX特性的性质支持读
|
||||
add_char_params.char_props.read = 1;
|
||||
//设置RX特征的性质支持无响应写
|
||||
add_char_params.char_props.write_wo_resp = 1;
|
||||
//设置读/写RX特征值的安全需求:无安全性
|
||||
add_char_params.read_access = SEC_OPEN;
|
||||
add_char_params.write_access = SEC_OPEN;
|
||||
//为串口透传服务添加RX特征
|
||||
err_code = characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->rx_handles);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
/*---------------------添加RX特征-END------------------------*/
|
||||
|
||||
/*---------------------以下代码添加TX特征--------------------*/
|
||||
//添加TX特征
|
||||
//配置参数之前先清零add_char_params
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
//TX特征的UUID
|
||||
add_char_params.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC;
|
||||
//TX特征的UUID类型
|
||||
add_char_params.uuid_type = p_nus->uuid_type;
|
||||
//设置TX特征值的最大长度
|
||||
add_char_params.max_len = BLE_NUS_MAX_TX_CHAR_LEN;
|
||||
//设置TX特征值的初始长度
|
||||
add_char_params.init_len = sizeof(uint8_t);
|
||||
//设置TX的特征值长度为可变长度
|
||||
add_char_params.is_var_len = true;
|
||||
//设置TX特征的性质:支持通知
|
||||
add_char_params.char_props.notify = 1;
|
||||
//设置TX特性的性质:支持读
|
||||
add_char_params.char_props.read = 1;
|
||||
//设置读/写RX特征值的安全需求:无安全性
|
||||
add_char_params.read_access = SEC_OPEN;
|
||||
add_char_params.write_access = SEC_OPEN;
|
||||
add_char_params.cccd_write_access = SEC_OPEN;
|
||||
//为串口透传服务添加TX特征
|
||||
return characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->tx_handles);
|
||||
/*---------------------添加TX特征-END------------------------*/
|
||||
}
|
||||
|
||||
//蓝牙数据上传发送,并进行反馈
|
||||
uint32_t ble_nus_data_send(ble_nus_t * p_nus,
|
||||
uint8_t * p_data,
|
||||
uint16_t * p_length,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
//验证p_uarts没有指向NULL
|
||||
VERIFY_PARAM_NOT_NULL(p_nus);
|
||||
|
||||
//如果连接句柄无效,表示没有和主机建立连接,返回NRF_ERROR_NOT_FOUND
|
||||
if (conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (*p_length > BLE_NUS_MAX_DATA_LEN)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
//设置之前先清零hvx_params
|
||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
||||
//TX特征值句柄
|
||||
hvx_params.handle = p_nus->tx_handles.value_handle;
|
||||
//发送的数据
|
||||
hvx_params.p_data = p_data;
|
||||
//发送的数据长度
|
||||
hvx_params.p_len = p_length;
|
||||
//类型为通知
|
||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
||||
//发送TX特征值通知
|
||||
return sd_ble_gatts_hvx(conn_handle, &hvx_params);
|
||||
}
|
||||
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(BLE_NUS)
|
||||
Reference in New Issue
Block a user