LE Peripheral
The LE peripheral sample demonstrates how to use the LE GAP peripheral role to develop many different peripheral-role based applications. LE GAP peripheral role can send connectable advertising events and it can accept the establishment of LE link and become a peripheral role in the link.
The sample uses LE host and LE manager module. The above figure shows the relationships between several modules in the sample.
More information about these modules can be found in the LE Host and LE Manager documentation.
Requirements
The sample supports the following development kits:
Hardware Platforms |
Board Name |
Build Target |
---|---|---|
RTL87x3E HDK |
RTL87x3E EVB |
ble_peripheral_4M_bank0 ble_peripheral_16M_bank0 |
RTL87x3D HDK |
RTL87x3D EVB |
ble_peripheral_8M_bank0 ble_peripheral_16M_bank0 ble_peripheral_cs_16M_bank0 |
This sample project can be found under board\evb\ble_peripheral
in SDK folder structure.
Developers can choose the project according to the Board Name
and choose the Build Target
according to the flash map.
When built for an xxx_4M_xxx
build target, the sample is configured to compile and run with a 4M flash map.
When built for an xxx_8M_xxx
build target, the sample is configured to compile and run with an 8M flash map.
When built for an xxx_16M_xxx
build target, the sample is configured to compile and run with a 16M flash map.
To quickly set up the development environment, please refer to the detailed instructions provided in Quick Start.
Wiring
Please refer to EVB Interfaces and Modules in Quick Start.
Configurations
Configurable Items
All contents that can be configured for the sample are in
src\sample\ble_peripheral\app_peripheral_flags.h
,
developers can configure according to actual needs.
/** @brief Config APP LE link number */
#define APP_MAX_LINKS 1
/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */
#define F_BT_DLPS_EN 0
/** @brief Config ANCS Client: 0-Not built in, 1-Open ANCS client function */
#define F_APP_BT_GATT_CLIENT_SUPPORT 0
#define F_APP_BT_ANCS_CLIENT_SUPPORT (F_APP_BT_GATT_CLIENT_SUPPORT & 1)
#define F_BT_ANCS_APP_FILTER (F_APP_BT_ANCS_CLIENT_SUPPORT & 1)
#define F_BT_ANCS_GET_APP_ATTR (F_APP_BT_ANCS_CLIENT_SUPPORT & 0)
/** @brief Config ANCS Client debug log: 0-close, 1-open */
#define F_BT_ANCS_CLIENT_DEBUG (F_APP_BT_ANCS_CLIENT_SUPPORT & 0)
Developers can open or close the ANCS client module through the macro F_APP_BT_GATT_CLIENT_SUPPORT
and F_APP_BT_ANCS_CLIENT_SUPPORT
.
For more information about the ANCS module, please refer to ANCS Client.
Generating System Config File
Developers shall configure the following items through MCUConfig Tool:
Configurable Item |
Value |
---|---|
LE link number |
≥ APP_MAX_LINKS |
LE slave link number |
≥ APP_MAX_LINKS |
For more information about MCUConfig Tool Configuration, please refer to MCUConfig Tool.
Building and Downloading
Take the project rtl87x3e_ble_peripheral.uvprojx
and target ble_peripheral_4M_bank0
as an example, to build and run the sample with Keil development environment, follow the steps listed below:
Open
rtl87x3e_ble_peripheral.uvprojx
.Choose the build target
ble_peripheral_4M_bank0
.Building the target.
After a successful build, the APP bin file
ble_peripheral_bank0_MP-v0.0.0.0-xxx.bin
will be generated in the directorybin\rtl87x3e\flash_4M_dualbank\bank0
.Download APP bin into EVB.
Press the reset button on the EVB and it will start LE advertising.
Experimental Verification
After downloading the sample bin to the EVB, developers can test it either by using another
kit that is running the LE Central sample, or a phone installed LE APPs like LightBlue
.
Testing with Another Kit
Please refer to Testing with Another Kit in LE Central.
Testing with Phone
Press the reset button on DUT and DUT will start sending connectable undirected advertising events.
If the advertisement is successfully enabled, the following Debug Analyzer log will be printed. If developers don’t see the following log, it means that the advertisement failed to start. Please check if the software and hardware environment is configured correctly.
[APP] !**app_peripheral_adv_callback: BLE_EXT_ADV_MGR_ADV_ENABLED
Run
LightBlue
on iOS device to search for and connect with DUT, as shown below:Developers can implement actions like scanning, connecting, pairing, discovering services, deleting bond information, disconnecting, etc., on the phone-end.
Code Overview
The main purpose of this chapter is to help sample developers become familiar with the development process related to the Peripheral Role. This chapter will be introduced according to the following several parts:
The directories of the project and source code files will be introduced in chapter Source Code Directory.
The main function will be introduced in chapter Initialization.
The configurable GAP parameters of this sample will be introduced in chapter GAP Parameter Initialization.
The GAP message handler of this sample will be introduced in chapter GAP Message Handler.
The GAP callback handler of this sample will be introduced in chapter GAP Callback Handler.
The profile message callback of this sample will be introduced in chapter Profile Message Callback.
The ANCS client module will be introduced in chapter ANCS Client.
Source Code Directory
Project directory:
board\evb\ble_peripheral
.Source code directory:
src\sample\ble_peripheral
.
Source files in the sample project are currently categorized into several groups as below:
└── ble_peripheral_4M_bank0
├── include ROM UUID header files. Developers do not need to modify it.
├── lib Includes all binary symbol files that user application is built on.
├── gap_utils.lib
├── ROM.lib
├── upperstack_4M.lib
├── hal_utils.lib
├── ble_mgr.lib
└── sysm.lib
├── cmsis The cmsis source code. Developers do not need to modify it.
├── ble The LE profiles source code.
├── bas.c
├── ancs_gatt_client.c
└── simple_ble_service.c
├── app The application source code.
├── app_peripheral_main.c Main entry
├── app_peripheral_gap.c LE GAP initialization and message handler
├── app_peripheral_service.c LE profile server role initialization
├── app_peripheral_client.c LE profile client role initialization
├── app_peripheral_adv.c Advertising manager
├── app_peripheral_task.c APP task
└── ancs_sample.c ANCS client role sample code
└── io_hal
Initialization
main()
function is invoked when the EVB is powered on and the chip boots up,
and it performs the following initialization functions:
int main(void)
{
board_init();
le_gap_init(APP_MAX_LINKS);
gap_lib_init();
app_peripheral_gap_init();
app_peripheral_service_init();
app_peripheral_client_init();
pwr_mgr_init();
task_init();
os_sched_start();
return 0;
}
le_gap_init()
function is used to initialize GAP and configure link number.app_peripheral_service_init()
function andapp_peripheral_client_init()
function are used to initialize profile.app_peripheral_gap_init()
function is used to initialize the GAP parameters.
GAP Parameter Initialization
The app_peripheral_gap_init()
function is used to initialize the GAP parameters.
Developers can easily customize the sample by modifying the following parameter values.
void app_peripheral_gap_init(void)
{
/* Device name and device appearance */
uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIPHERAL";
uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
/* GAP Bond Manager parameters */
......
/* Setup the GAP Bond Manager */
gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
&auth_use_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
&auth_sec_req_flags);
/* register GAP message callback */
le_register_app_cb(app_peripheral_gap_callback);
/* LE manager module initialize */
app_peripheral_gap_ble_mgr_init();
/* Advertising parameters initialize */
app_peripheral_adv_init_conn_public();
}
-
Configure device name with the parameter
GAP_PARAM_DEVICE_NAME
.Configure appearance with the parameter
GAP_PARAM_APPEARANCE
.
gap_set_param()
andle_bond_set_param()
Initialize GAP pairing parameters.
-
Register the GAP message callback function
app_peripheral_gap_callback()
, and all GAP callback messages will be handled in this callback. app_peripheral_gap_ble_mgr_init()
Initialize the LE manager library. More information on LE manager library initialization can be found in the chapter LE Manager Initialization of LE Manager.
void app_peripheral_gap_ble_mgr_init(void) { BLE_MGR_PARAMS param = {0}; param.ble_ext_adv.enable = true; param.ble_ext_adv.adv_num = 1; ble_mgr_init(¶m); }
app_peripheral_adv_init_conn_public()
Initialize advertising parameters. More information on LE Extended Advertising can be found in the chapter Advertising Manager Initialization of LE Manager.
More information on LE GAP initialization and startup flow can be found in the chapter GAP Parameters Initialization of LE Host.
GAP Message Handler
app_peripheral_gap_handle_msg()
function is invoked whenever a GAP message is received from the Bluetooth Host.
More information on GAP messages can be found in the chapter Bluetooth LE GAP Message of LE Host.
When the sample handles a GAP message, the ble_mgr_handle_gap_msg()
shall be called to handle the GAP message.
void app_peripheral_gap_handle_msg(T_IO_MSG *p_gap_msg)
{
T_LE_GAP_MSG gap_msg;
uint8_t conn_id;
memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
ble_mgr_handle_gap_msg(p_gap_msg->subtype, &gap_msg);
APP_PRINT_TRACE1("app_peripheral_gap_handle_msg: subtype %d", p_gap_msg->subtype);
switch (p_gap_msg->subtype)
{
case GAP_MSG_LE_DEV_STATE_CHANGE:
{
app_peripheral_gap_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
gap_msg.msg_data.gap_dev_state_change.cause);
}
break;
......
default:
break;
}
}
The peripheral sample will call app_peripheral_adv_start()
to start advertising when receiving GAP_INIT_STATE_STACK_READY
.
If app_peripheral_adv_start()
returns true
, it means the LE manager library has already received this command and is ready to execute.
When the LE peripheral sample runs on the EVB, the device will send connectable advertising events and can be scanned and connected as a peripheral role by a remote device.
void app_peripheral_gap_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
{
APP_PRINT_INFO3("app_peripheral_gap_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
new_state.gap_init_state, new_state.gap_adv_state, cause);
if (gap_dev_state.gap_init_state != new_state.gap_init_state)
{
if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
{
APP_PRINT_INFO0("app_peripheral_gap_handle_dev_state_evt: GAP stack ready");
/*start advertising*/
app_peripheral_adv_start(0);
}
}
gap_dev_state = new_state;
}
When the LE peripheral sample receives the GAP_CONN_STATE_DISCONNECTED
message, it will call the app_peripheral_adv_start()
function again to start advertising.
After disconnecting, the LE peripheral sample will be restored to the status that is discoverable and connectable again.
void app_peripheral_gap_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
{
APP_PRINT_INFO4("app_peripheral_gap_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
conn_id, gap_conn_state, new_state, disc_cause);
switch (new_state)
{
case GAP_CONN_STATE_DISCONNECTED:
{
if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
{
APP_PRINT_ERROR1("app_peripheral_gap_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
}
app_peripheral_adv_start(0);
}
break;
......
}
}
GAP Callback Handler
app_peripheral_gap_callback()
function is used to handle GAP callback messages.
More information on GAP callback can be found in the chapter Bluetooth LE GAP Callback of LE Host.
When the sample handles GAP callback, the ble_mgr_handle_gap_cb()
shall be called to handle the callback message.
T_APP_RESULT app_peripheral_gap_callback(uint8_t cb_type, void *p_cb_data)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
ble_mgr_handle_gap_cb(cb_type, p_cb_data);
APP_PRINT_TRACE1("app_peripheral_gap_callback: cb_type = 0x%x", cb_type);
switch (cb_type)
{
case GAP_MSG_LE_DATA_LEN_CHANGE_INFO:
APP_PRINT_INFO3("app_peripheral_gap_callback: GAP_MSG_LE_DATA_LEN_CHANGE_INFO conn_id %d, tx octets 0x%x, max_tx_time 0x%x",
p_data->p_le_data_len_change_info->conn_id, p_data->p_le_data_len_change_info->max_tx_octets,
p_data->p_le_data_len_change_info->max_tx_time);
break;
......
}
}
Profile Message Callback
When xxx_add_service is used to register a specific service, the callback function shall be registered to handle the message from the specific service.
The developer shall call server_register_app_cb()
to register the callback function used to handle the message from the profile server layer.
Developers can register different callback functions to handle different services or register a general callback function to handle all messages from specific services and the profile server layer.
app_peripheral_service_callback()
function is the general callback function. app_peripheral_service_callback()
can distinguish different services by service ID.
void app_peripheral_service_init(void)
{
server_init(2);
simp_srv_id = simp_ble_service_add_service(app_peripheral_service_callback);
bas_srv_id = bas_add_service(app_peripheral_service_callback);
server_register_app_cb(app_peripheral_service_callback);
}
More information can be found in the chapter GATT Profile Server of LE Host.
- General profile server callback
SERVICE_PROFILE_GENERAL_ID
is the service ID used by the profile server layer. The message used by the profile server layer contains two message types:-
This message is used to inform that the service registration process has been completed in GAP Start Flow.
PROFILE_EVT_SEND_DATA_COMPLETE
This message is used to inform the result of sending the notification or indication.
T_APP_RESULT app_peripheral_service_callback(T_SERVER_ID service_id, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; if (service_id == SERVICE_PROFILE_GENERAL_ID) { T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data; switch (p_param->eventId) { case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event. APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d", p_param->event_data.service_reg_result); break; case PROFILE_EVT_SEND_DATA_COMPLETE: ...... break; ...... }
-
- Battery Service
bas_srv_id
is the service ID of the battery service.T_APP_RESULT app_peripheral_service_callback(T_SERVER_ID service_id, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; ...... else if (service_id == bas_srv_id) { T_BAS_CALLBACK_DATA *p_bas_cb_data = (T_BAS_CALLBACK_DATA *)p_data; switch (p_bas_cb_data->msg_type) { case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION: ...... }
- Simple LE Service
simp_srv_id
is the service ID of simple LE service.T_APP_RESULT app_peripheral_service_callback(T_SERVER_ID service_id, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; ...... else if (service_id == simp_srv_id) { TSIMP_CALLBACK_DATA *p_simp_cb_data = (TSIMP_CALLBACK_DATA *)p_data; switch (p_simp_cb_data->msg_type) { case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION: ...... }
ANCS Client
The purpose of this chapter is to provide an overview of the ANCS client.
ANCS is Apple notification center service. It is a notification service in the iOS system. After the device is connected to the iOS mobile phone, the device first needs to enable the notification function of the iOS system, that is, the GATT client on the device discovers the ANCS on the iOS, and enables the notify function of its notification source characteristics. After that, the iOS system will push messages to the device.
ANCS Source Code
ANCS client related source files is ancs_gatt_client.c
and ancs_sample.c
. If developers want to use ANCS client, these files need to be added in Keil project.
ancs_gatt_client.c
can be find insrc\ble\bt_gatt_client
.ANCS client based on
bt_gatt_client.h
. Developers do not need to modify this file.ancs_sample.c
can be find insrc\sample\ble_peripheral
.ANCS routines are defined in
ancs_sample.c
andancs_sample.h
. If other applications want to access this function, developers can copyancs_sample.h
andancs_sample.c
to the target APP directory. Then, developers can customize the ANCS routines inancs_sample.c
.
Enable ANCS Client
Developers can open or close the ANCS client module through the macro
F_APP_BT_GATT_CLIENT_SUPPORT
andF_APP_BT_ANCS_CLIENT_SUPPORT
.Developers can open or close the debug log through the macro
F_BT_ANCS_CLIENT_DEBUG
.Developers can open or close the filter by category_id through the macro
F_BT_ANCS_APP_FILTER
.
/** @brief Config ANCS Client: 0-Not built-in, 1-Open ANCS client function */
#define F_APP_BT_GATT_CLIENT_SUPPORT 0
#define F_APP_BT_ANCS_CLIENT_SUPPORT (F_APP_BT_GATT_CLIENT_SUPPORT & 1)
#define F_BT_ANCS_APP_FILTER (F_APP_BT_ANCS_CLIENT_SUPPORT & 1)
#define F_BT_ANCS_GET_APP_ATTR (F_APP_BT_ANCS_CLIENT_SUPPORT & 0)
/** @brief Config ANCS Client debug log: 0-close, 1-open */
#define F_BT_ANCS_CLIENT_DEBUG (F_APP_BT_ANCS_CLIENT_SUPPORT & 0)
ANCS Client Flow
The ANCS client flow is shown in the figure below:
Initialize ANCS client in
app_peripheral_client_init()
.void app_peripheral_client_init(void) { #if F_APP_BT_GATT_CLIENT_SUPPORT gatt_client_init(GATT_CLIENT_DISCOV_MODE_REG_SVC_BIT | GATT_CLIENT_DISCOV_MODE_USE_EXT_CLIENT); #if F_APP_BT_ANCS_CLIENT_SUPPORT app_ancs_client_init(); #endif #endif } void app_ancs_client_init(void) { os_queue_init(&ancs_link_queue); ancs_client_init(ancs_client_cb); }
The developer shall call
gatt_client_init()
to initialize GATT Client Manager.The developer shall call
ancs_client_init()
to initialize ANCS client.Request Pairing.
iOS system doesn’t supply the interface to initiate security procedures. If the peripheral device wants to pair with an iOS device, the peripheral device needs to request pairing. More information can be found in the chapter Request Pairing of LE Host.
Start service discovery when the authentication procedure is completed.
void app_peripheral_gap_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause) { ...... case GAP_AUTHEN_STATE_COMPLETE: { if (cause == GAP_SUCCESS) { #if F_APP_BT_GATT_CLIENT_SUPPORT gatt_client_start_discovery_all(le_get_conn_handle(conn_id), NULL); #endif APP_PRINT_INFO0("app_peripheral_gap_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success"); } else { APP_PRINT_INFO0("app_peripheral_gap_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed"); } } break; ...... }
ANCS notification enable.
T_APP_RESULT ancs_client_cb(uint16_t conn_handle, uint8_t type, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; switch (type) { case GATT_MSG_ANCS_CLIENT_DIS_DONE: { T_ANCS_CLIENT_DIS_DONE *p_dis_done = (T_ANCS_CLIENT_DIS_DONE *)p_data; if (p_dis_done->is_found) { APP_PRINT_INFO0("ANCS BLE Client CB: discover procedure done."); ancs_client_cfg_cccd(conn_handle, ANCS_DATA_SOURCE, true); ancs_client_cfg_cccd(conn_handle, ANCS_NOTIFICATION_SOURCE, true); } else { APP_PRINT_ERROR0("ANCS BLE Client CB: discover request failed."); } } break; ...... default: break; } }
The developer can call
ancs_client_cfg_cccd()
to enable the notification of data source and notification source.Parse notification source data and get notification attribute.
T_APP_RESULT ancs_client_cb(uint16_t conn_handle, uint8_t type, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; switch (type) { case GATT_MSG_ANCS_CLIENT_NOTIFICATION_SOURCE: { T_ANCS_CLIENT_NOTIFICATION_SOURCE *p_notify = (T_ANCS_CLIENT_NOTIFICATION_SOURCE *)p_data; app_parse_notification_source_data(conn_handle, p_notify); } break; ...... default: break; } }
The
app_parse_notification_source_data()
is used to parse notification source data.void app_parse_notification_source_data(uint16_t conn_handle, T_ANCS_CLIENT_NOTIFICATION_SOURCE *p_notify_src) { //User can filter by category_id here, for demo purposes, we didn't filter any CategoryID here. #if F_BT_ANCS_APP_FILTER //Filter social and other category & phone category & email category if (p_notify_src->category_id == NS_CATEGORY_ID_SOCIAL || p_notify_src->category_id == NS_CATEGORY_ID_OTHER || p_notify_src->category_id == NS_CATEGORY_ID_INCOMING_CALL || p_notify_src->category_id == NS_CATEGORY_ID_EMAIL) { #endif if (p_notify_src->event_id != NS_EVENT_ID_NOTIFICATION_REMOVED) { uint8_t attr_id_list[14]; uint8_t cur_index = 0; attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_APP_IDENTIFIER; attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_TITLE; attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_SUB_TITLE; attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE; attr_id_list[cur_index++] = LO_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = HI_WORD(ANCS_MAX_ATTR_LEN); attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_MESSAGE_SIZE; attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_DATE; attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_POSITIVE_ACTION_LABEL; attr_id_list[cur_index++] = DS_NOTIFICATION_ATTR_ID_NEGATIVE_ACTION_LABEL; if (ancs_client_cp_get_notification_attr(conn_handle, p_notify_src->notification_uid, attr_id_list, cur_index) == true) { return; } } #if F_BT_ANCS_APP_FILTER } #endif }
The developer can call
ancs_client_cp_get_notification_attr()
to get notification attribute.Parse data source data.
T_APP_RESULT ancs_client_cb(uint16_t conn_handle, uint8_t type, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; switch (type) { case GATT_MSG_ANCS_CLIENT_DATA_SOURCE: { T_ANCS_CLIENT_DATA_SOURCE *p_notify = (T_ANCS_CLIENT_DATA_SOURCE *)p_data; app_parse_data_source_data(conn_handle, p_notify->p_value, p_notify->value_size); } break; ...... default: break; } }
The
app_parse_data_source_data()
is used to parse data source data.
Troubleshooting
How to Modify the Parameters of Advertising Data?
The advertising data is defined in the following array adv_data
, and developers can directly modify the content of the array to modify the advertising data.
static const uint8_t adv_data[] =
{
/* Flags */
0x02, /* length */
GAP_ADTYPE_FLAGS, /* type="Flags" */
GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
/* Service */
0x03, /* length */
GAP_ADTYPE_16BIT_COMPLETE,
LO_WORD(GATT_UUID_SIMPLE_PROFILE),
HI_WORD(GATT_UUID_SIMPLE_PROFILE),
/* Local name */
0x0F, /* length */
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'B', 'L', 'E', '_', 'P', 'E', 'R', 'I', 'P', 'H', 'E', 'R', 'A', 'L',
};