Files

236 lines
8.0 KiB
C
Raw Permalink Normal View History

2025-08-19 09:49:41 +08:00
/****************************************Copyright (c)************************************************
**
**--------------File Info-----------------------------------------------------------------------------
** File name:ble_nus.c
** Last modified Date:
** Last Version:
** Descriptions :<EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
**---------------------------------------------------------------------------------------------------*/
#include "sdk_common.h"
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˴<EFBFBD><CBB4><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD>ء<EFBFBD><D8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>sdk_config.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>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<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󳤶ȣ<F3B3A4B6><C8A3>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
#define BLE_NUS_MAX_TX_CHAR_LEN BLE_NUS_MAX_DATA_LEN //TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󳤶ȣ<F3B3A4B6><C8A3>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
//SoftDevice<63><EFBFBD>ġ<EFBFBD>Write<74><65><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
{
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>лص<D0BB>ʱ<EFBFBD><CAB1><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>
ble_nus_evt_t evt;
//<2F><><EFBFBD><EFBFBD>write<74>¼<EFBFBD><C2BC><EFBFBD><E1B9B9>ָ<EFBFBD>벢ָ<EBB2A2><D6B8>GATT<54>¼<EFBFBD><C2BC><EFBFBD>write
ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
//<2F><><EFBFBD><EFBFBD>evt<76><EFBFBD><E1B9B9>
memset(&evt, 0, sizeof(ble_nus_evt_t));
//ָ<>򴮿<EFBFBD>͸<EFBFBD><CDB8>ʵ<EFBFBD><CAB5>
evt.p_nus = p_nus;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
//дRX<52><58><EFBFBD><EFBFBD>ֵ
if ((p_evt_write->handle == p_nus->rx_handles.value_handle) &&
(p_nus->data_handler != NULL))
{
//<2F><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
evt.type = BLE_NUS_EVT_RX_DATA;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
evt.params.rx_data.p_data = p_evt_write->data;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
evt.params.rx_data.length = p_evt_write->len;
//ִ<>лص<D0BB>
p_nus->data_handler(&evt);
}
else
{
// Do Nothing. This event is not relevant for this service.
}
}
//SoftDevice<63><EFBFBD>ġ<EFBFBD>BLE_GATTS_EVT_HVN_TX_COMPLETE<54><45><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static void on_hvx_tx_complete(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
{
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>evt<76><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>лص<D0BB>ʱ<EFBFBD><CAB1><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>
ble_nus_evt_t evt;
//<2F><><EFBFBD><EFBFBD>evt
memset(&evt, 0, sizeof(ble_nus_evt_t));
//<2F><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
evt.type = BLE_NUS_EVT_TX_RDY;
//ָ<>򴮿<EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
evt.p_nus = p_nus;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
//ִ<>лص<D0BB>
p_nus->data_handler(&evt);
}
//<2F><><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BLE<4C>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5>¼<EFBFBD><C2BC>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
if ((p_context == NULL) || (p_ble_evt == NULL))
{
return;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><E1B9B9>ָ<EFBFBD>벢ָ<EBB2A2>򴮿<EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><E1B9B9>
ble_nus_t * p_nus = (ble_nus_t *)p_context;
//<2F>ж<EFBFBD><D0B6>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
switch (p_ble_evt->header.evt_id)
{
//д<>¼<EFBFBD>
case BLE_GATTS_EVT_WRITE:
on_write(p_nus, p_ble_evt);
break;
//TX<54><58><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
on_hvx_tx_complete(p_nus, p_ble_evt);
break;
default:
// No implementation needed.
break;
}
}
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
{
ret_code_t err_code;
//<2F><><EFBFBD><EFBFBD>16λUUID<49><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ble_uuid_t ble_uuid;
//<2F><><EFBFBD><EFBFBD>128λUUID<49><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UUID<49><44><EFBFBD><EFBFBD>
ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ble_add_char_params_t add_char_params;
//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Ƿ<EFBFBD>ΪNULL
VERIFY_PARAM_NOT_NULL(p_nus);
VERIFY_PARAM_NOT_NULL(p_nus_init);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><E1B9B9><EFBFBD>е<EFBFBD><D0B5>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
p_nus->data_handler = p_nus_init->data_handler;
//<2F><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>UUID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>SoftDevice
err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type);
VERIFY_SUCCESS(err_code);
//UUID<49><44><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD>ֵ<EFBFBD><D6B5>ֵ<EFBFBD><D6B5>ble_uuid<69><64><EFBFBD><EFBFBD>
ble_uuid.type = BLE_UUID_TYPE_BLE;
ble_uuid.uuid = BLE_UUID_NUS_SERVICE;
//<2F><><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&ble_uuid,
&p_nus->service_handle);
VERIFY_SUCCESS(err_code);
/*---------------------<2D><><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>--------------------*/
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>
//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>add_char_params
memset(&add_char_params, 0, sizeof(add_char_params));
//RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UUID
add_char_params.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
//RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UUID<49><44><EFBFBD><EFBFBD>
add_char_params.uuid_type = p_nus->uuid_type;
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>󳤶<EFBFBD>
add_char_params.max_len = BLE_NUS_MAX_RX_CHAR_LEN;
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>ֵ<EFBFBD>ij<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
add_char_params.init_len = sizeof(uint8_t);
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ<EFBFBD>ɱ䳤<C9B1><E4B3A4>
add_char_params.is_var_len = true;
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>д
add_char_params.char_props.write = 1;
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֶ<EFBFBD>
add_char_params.char_props.read = 1;
//<2F><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧд
add_char_params.char_props.write_wo_resp = 1;
//<2F><><EFBFBD>ö<EFBFBD>/дRX<52><58><EFBFBD><EFBFBD>ֵ<EFBFBD>İ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ް<EFBFBD>ȫ<EFBFBD><C8AB>
add_char_params.read_access = SEC_OPEN;
add_char_params.write_access = SEC_OPEN;
//Ϊ<><CEAA><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>
err_code = characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->rx_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
/*---------------------<2D><><EFBFBD><EFBFBD>RX<52><58><EFBFBD><EFBFBD>-END------------------------*/
/*---------------------<2D><><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>--------------------*/
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>
//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>add_char_params
memset(&add_char_params, 0, sizeof(add_char_params));
//TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UUID
add_char_params.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC;
//TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UUID<49><44><EFBFBD><EFBFBD>
add_char_params.uuid_type = p_nus->uuid_type;
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>󳤶<EFBFBD>
add_char_params.max_len = BLE_NUS_MAX_TX_CHAR_LEN;
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>ֵ<EFBFBD>ij<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
add_char_params.init_len = sizeof(uint8_t);
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ<EFBFBD>ɱ䳤<C9B1><E4B3A4>
add_char_params.is_var_len = true;
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>֧<EFBFBD><D6A7>֪ͨ
add_char_params.char_props.notify = 1;
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD>ʣ<EFBFBD>֧<EFBFBD>ֶ<EFBFBD>
add_char_params.char_props.read = 1;
//<2F><><EFBFBD>ö<EFBFBD>/дRX<52><58><EFBFBD><EFBFBD>ֵ<EFBFBD>İ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ް<EFBFBD>ȫ<EFBFBD><C8AB>
add_char_params.read_access = SEC_OPEN;
add_char_params.write_access = SEC_OPEN;
add_char_params.cccd_write_access = SEC_OPEN;
//Ϊ<><CEAA><EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>
return characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->tx_handles);
/*---------------------<2D><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>-END------------------------*/
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD>
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;
//<2F><>֤p_uartsû<73><C3BB>ָ<EFBFBD><D6B8>NULL
VERIFY_PARAM_NOT_NULL(p_nus);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>ʾû<CABE>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>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;
}
//<2F><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hvx_params
memset(&hvx_params, 0, sizeof(hvx_params));
//TX<54><58><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
hvx_params.handle = p_nus->tx_handles.value_handle;
//<2F><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
hvx_params.p_data = p_data;
//<2F><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
hvx_params.p_len = p_length;
//<2F><><EFBFBD><EFBFBD>Ϊ֪ͨ
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
//<2F><><EFBFBD><EFBFBD>TX<54><58><EFBFBD><EFBFBD>ֵ֪ͨ
return sd_ble_gatts_hvx(conn_handle, &hvx_params);
}
#endif // NRF_MODULE_ENABLED(BLE_NUS)