LE Scatternet
LE scatternet示例工程可以作为开发同时支持Peripheral Role和Central Role的应用程序的框架。
Scatternet特征:
在同一时间,作为Peripheral角色与多个Central建立连线。
在同一时间,作为Peripheral角色和Central角色。
不支持角色转换。
环境需求
该示例支持以下开发工具包:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
为快速搭建起开发环境,可参考 快速入门 中提供的详细指导。
硬件连线
该示例工程需要支持用户命令接口。 具体连线介绍请参考 User Command Interface 中的 Data UART连接。
配置
配置选项
该示例工程全部配置选项在
samples\bluetooth\ble_scatternet\src\app_flags.h
中,
开发者可以根据实际需求配置。
/** @brief Config APP LE link number */
#define APP_MAX_LINKS 2
/** @brief Config airplane mode support: 0-Not built in, 1-built in, use user command to set*/
#define F_BT_AIRPLANE_MODE_SUPPORT 0
/** @brief Config device name characteristic and appearance characteristic property: 0-Not writeable, 1-writeable, save to flash*/
#define F_BT_GAPS_CHAR_WRITEABLE 0
/** @brief Config set physical: 0-Not built in, 1-built in, use user command to set*/
#define F_BT_LE_5_0_SET_PHY_SUPPORT 0
/** @brief Config local address type: 0-pulic address, 1-static random address */
#define F_BT_LE_USE_STATIC_RANDOM_ADDR 0
飞行模式的设置:
配置
F_BT_AIRPLANE_MODE_SUPPORT
以打开飞行模式(默认关闭)。打开飞行模式后,系统会关闭蓝牙功能。更多信息请参考 代码介绍 中的 Airplane Mode设置。GAP service characteristic的可写属性:
配置
F_BT_GAPS_CHAR_WRITEABLE
以打开该功能(默认关闭)。更多信息请参考 LE Host 中的 GAP Service Characteristic的可写属性。静态随机地址的使用:
配置
F_BT_LE_USE_STATIC_RANDOM_ADDR
以打开该功能(默认关闭)。更多信息请参考 LE Host 中的 本地设备使用Static Random Address。PHY 设置:
配置
F_BT_LE_5_0_SET_PHY_SUPPORT
以打开该功能(默认关闭)。更多信息请参考 LE Host 中的 Physical (PHY)设置。
生成系统配置文件
开发者可以通过MP Tool配置以下项目:
Configurable Item |
Value |
---|---|
LE Master Link Num |
≥1 |
LE Slave Link Num |
≥1 |
备注
开发者配置的
LE Master Link Num
值与LE Slave Link Num
值之和应大于等于app_flags.h
中配置的APP_MAX_LINKS
值。
更多有关于MP Tool配置的信息请参考 快速入门 中的 生成System Config File。
编译和下载
该示例可以在SDK文件夹中找到:
Project file: samples\bluetooth\ble_scatternet\proj\rtl87x2g\mdk
Project file: samples\bluetooth\ble_scatternet\proj\rtl87x2g\gcc
编译和运行该示例请遵循以下步骤:
打开项目文件。
要编译目标文件, 请参考 快速入门 的 编译APP Image 中列出的步骤。
编译成功后,目录
samples\bluetooth\ble_scatternet\proj\rtl87x2g\mdk\bin
下会生成app bin文件app_MP_sdk_xxx.bin
。要下载app bin到 EVB,请参考 快速入门 的 MP Tool 下载 中列出的步骤。
在EVB上按下 reset 键,程序将开始运行。
测试验证
将示例工程烧录到EVB后,开发者可以使用两个开发板分别运行 LE Peripheral 示例工程和 LE Central 示例工程。
与另一块开发板对测
准备三块开发板分别命名为 DUT, Tester 1 和 Tester 2 ,开发者可以使用 Debug Analyzer
做 Log验证 。
准备步骤
使用MP Tool将 DUT 地址设为[00:11:22:33:44:80],然后编译 LE Scatternet示例工程并下载images到 DUT 上。 开发者可以在电脑的串口辅助工具端输入用户命令,请参考 User Command Interface 中的 如何使用命令。
使用MP Tool将 Tester 1 地址设为[00:11:22:33:44:81],然后编译 LE Peripheral示例工程,并下载images到 Tester 1 上。更多信息请参考 LE Peripheral 中的 编译和下载。
使用MP Tool将 Tester 2 地址设为[00:11:22:33:44:85],然后编译 LE Central示例工程,并下载images到 Tester 2 上。更多信息请参考 LE Central 中的 编译和下载。
更多关于如何修改 蓝牙地址 的细节请查阅 快速入门 中的 生成System Config File。
测试步骤
因为同时支持Peripheral Role和Central Role, 所以测试流程是 LE Peripheral 的测试流程和 LE Central 的测试流程的结合。
与Tester 1连接
按 Tester 1 上的 reset 键, Tester 1 将开始发送可连接广播。
如果成功启动广播,会打印下面的 Debug Analyzer 日志。 如果没有看到下列日志,说明广播启动失败。请检查软件和硬件环境。
[APP] !**GAP adv start
按 DUT 上的 reset 键,开发者可以在电脑的串口辅助工具端输入用户命令。
如果 DUT 成功启动且串口辅助工具配置成功, 开发者会看到如下日志。串口辅助工具端会显示本地地址。 如果没有看到下列日志,请检查软件和硬件环境。
local bd addr: xx:xx:xx:xx:xx:xxDUT 和 Tester 1 间的测试流程如下:
Step
DUT User Command
Description
DUT Log
1
bondclear
删除 DUT 端的绑定信息。
Debug Analyzer shows:
[GAP] !**le_clear_all_keys
2
scan
DUT 开始扫描附近的LE设备。
Debug Analyzer shows:
[APP] !**GAP scan start
[APP] GAP_MSG_LE_SCAN_INFO: bd_addr 00::11::22::33::44::80, bdtype 0, adv_type 0x0, rssi -17, data_len 23
3
stopscan
停止扫描。
Debug Analyzer shows:
[APP] !**GAP scan stop
4
showdev
显示扫描到的设备列表,该设备列表通过simple LE service的UUID筛选。
Serial port assistant tool shows:
Advertising and Scan response: filter uuid = 0xA00A dev list
RemoteBd[0] = [00:11:22:33:44:81] type = 0
5
condev 0
作为Central role发起连线。
Serial port assistant tool shows:
Connected success conn_id 0
与Tester 2连接
按 Tester 2 上的 reset 键,开发者可以在电脑的串口辅助工具端输入用户命令。
如果 Tester 2 成功启动且串口辅助工具配置成功, 开发者会看到如下日志。串口辅助工具端会显示本地地址。 如果没有看到下列日志,请检查软件和硬件环境。
local bd addr: xx:xx:xx:xx:xx:xx
此部分 DUT 和 Tester 2 的测试流程如下:
Step
DUT User Command
Tester 2 User Command
Description
Tester 2 Log
DUT Log
6
bond clear
清除 Tester 2 端的绑定信息。
Debug Analyzer shows:
[GAP] !**le_clear_all_keys
7
startadv
DUT 发送可连接可扫描的非定向广播。
Debug Analyzer shows:
[APP] !**GAP adv start
8
scan
Tester 2 开始扫描附近的LE设备。
Debug Analyzer shows:
[APP] !**GAP scan start
[APP] GAP_MSG_LE_SCAN_INFO: bd_addr 00::11::22::33::44::80, bdtype 0, adv_type 0x0, rssi -17, data_len 23
9
stopscan
Tester 2 停止扫描。
Debug Analyzer shows:
[APP] !**GAP scan stop
10
showdev
显示扫描到的设备列表。该设备列表通过simple LE service的UUID筛选。
Serial port assistant tool shows:
Advertising and Scan response: filter uuid = 0xA00A dev list
RemoteBd[0] = [00:11:22:33:44:80] type = 0
11
condev 0
Tester 2 发起向 DUT 建立连线,
0
表示 DUT 在设备列表中的序列号Serial port assistant tool shows:
Connected success conn_id 0
12
showcon
显示 DUT 端已经建立的连线。
Serial port assistant tool shows:
ShowCon conn_id 0 state 0x00000002 role 1
RemoteBd = [00:11:22:33:44:81] type = 0
ShowCon conn_id 1 state 0x00000002 role 2
RemoteBd = [00:11:22:33:44:85] type = 0
active link num 2, idle link num 0
与Tester 1和Tester 2交互
此时, DUT 已经分别作为Central Role和Peripheral Role与 Tester 1 和 Tester 2 建立了连线。接着将进行以下测试:
Step
DUT User Command
Tester 2 User Command
Description
Tester 2 Log
DUT Log
13
sauth 0
DUT 向Tester 1发送配对请求。
Serial port assistant tool shows:
Pair succes
14
disc 0
断开与 Tester 1 的连线。
Serial port assistant tool shows:
Disconnect conn_id 0
15
disc 1
断开与 Tester 2 的连线。
Serial port assistant tool shows:
Disconnect conn_id 1
16
condev 0
Dut 与 Tester 1 回连。
Serial port assistant tool shows:
Connected success conn_id 0
17
startadv
Dut 发送可连接可扫描非定向广播。
Serial port assistant tool shows:
GAP adv start
18
condev 0
Tester 2 与 DUT 回连。
Serial port assistant tool shows:
Connected success conn_id 0
Pair success
19
sauth 0
DUT 向 Tester 1 发送配对请求。
Serial port assistant tool shows:
Pair success
20
conupdreq 1 x30 x40 0 1000
DUT 向 Tester 2 发送连接参数更新请求。
Debug Analyzer shows:
[APP] !**app_handle_conn_param_update_evt update success:conn_id 0, conn_interval 0x3c, conn_slave_latency 0x0, conn_supervision_timeout 0x3e8
Debug Analyzer shows:
[APP] !**app_handle_conn_param_update_evt update success:conn_id 1, conn_interval 0x3c, conn_slave_latency 0x0, conn_supervision_timeout 0x3e8
21
conupdreq 0 x30 x40 0 1000
DUT 向 Tester 1 发送连接参数更新请求。
Debug Analyzer shows:
[APP] !**app_handle_conn_param_update_evt update success:conn_id 0, conn_interval 0x3c, conn_slave_latency 0x0, conn_supervision_timeout 0x3e8
22
setphy 1 1
DUT 将与 Tester 2 的PHY设为2M。
Debug Analyzer shows:
[BTIFMSG] ↗BTIF_MSG_LE_PHY_UPDATE_INFO (CMD:0x01AB) cause:0x0000 link_id:0x000A tx_phy:0x02(BTIF_LE_PHY_2M) rx_phy:0x02(BTIF_LE_PHY_2M)
Debug Analyzer shows:
[BTIFMSG] ↗BTIF_MSG_LE_PHY_UPDATE_INFO (CMD:0x01AB) cause:0x0000 link_id:0x0012 tx_phy:0x02(BTIF_LE_PHY_2M) rx_phy:0x02(BTIF_LE_PHY_2M)
[APP] !**GAP_MSG_LE_PHY_UPDATE_INFO:conn_id 1, cause 0x0, rx_phy 2, tx_phy 2
23
setphy 0 1
DUT 将与 Tester 1 的PHY设为2M。
Debug Analyzer shows:
[BTIFMSG] ↗BTIF_MSG_LE_PHY_UPDATE_INFO (CMD:0x01AB) cause:0x0000 link_id:0x000A tx_phy:0x02(BTIF_LE_PHY_2M) rx_phy:0x02(BTIF_LE_PHY_2M)
[APP] !**GAP_MSG_LE_PHY_UPDATE_INFO:conn_id 0, cause 0x0, rx_phy 2, tx_phy 2
24
simpdis 0
DUT 发起discovery流程,获取Simple LE Service信息。
Debug Analyzer shows:
[APP] !**app_client_callback: discover simp procedure done
25
gapdis 0
DUT 发起discovery流程,获取GAP Service信息。
Debug Analyzer shows:
[APP] !**GAPS_READ_DEVICE_NAME: device name BLE_PERIPHERAL
代码介绍
本章将按照以下几个部分进行介绍:
源码路径 中介绍项目目录和源代码文件。
Bluetooth Host介绍 中介绍了Bluetooth Host相关信息。
初始化 中介绍Scatternet相关参数和Bluetooth Host初始化。
多链路管理 中介绍了链路管理模块。
GAP消息处理 中介绍Scatternet相关的GAP消息处理。
GAP回调函数处理 中介绍Scatternet相关的GAP回调函数处理。
Profile Client消息回调函数 中介绍了Scatternet相关的Profile Client回调函数处理。
Profile Service消息回调函数 中介绍了Scatternet相关的Profile Service回调函数处理。
Airplane Mode设置 中介绍了设置飞行模式的流程。
源码路径
工程目录:
samples\bluetooth\ble_scatternet\proj
。源码目录:
samples\bluetooth\ble_scatternet\src
。
LE scatternet示例工程中的源文件当前被分为几个组,如下所示:
└── Project: scatternet
└── secure_only_app
└── Device includes startup code
├── CMSE Library Non-secure callable library
├── Lib includes all binary symbol files that user application is built on
├── ROM_NS.lib
└── lowerstack.lib
└── rtl87x2g_sdk.lib
└── gap_utils.lib
├── peripheral includes all peripheral drivers and module code used by the application
├── Profile includes LE profiles or services used by the sample application
└── APP includes the ble_scatternet user application implementation
├── app_task.c
├── main.c
├── link_mgr.c
├── scatternet_app.c
├── user_cmd.c
├── user_cmd_parse.c
└── data_uart.c
示例工程使用与 bt_host_0_0
匹配的默认GAP LIB,请参阅文档 Bluetooth Host Image 中的 GAP LIB的使用方法 以获取更多信息。
Bluetooth Host介绍
示例工程默认使用Bluetooth Host image版本 bt_host_0_0
,更多信息可参阅
Bluetooth Host Image。
关于Bluetooth Host所支持的蓝牙功能的详细信息,请参阅文件 bin\rtl87x2g\bt_host_image\bt_host_0_0\bt_host_config.h
。
初始化
当EVB启动并且芯片复位时, main()
函数将被调用,它执行以下初始化函数:
int main(void)
{
board_init();
le_gap_init(APP_MAX_LINKS);
gap_lib_init();
app_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
task_init();
os_sched_start();
return 0;
}
le_gap_init()
用于初始化GAP并配置链接个数。app_le_profile_init()
用于初始化profile。app_le_gap_init()
用于初始化GAP参数,开发者可以自行配置以下参数:Device name和device appearance,Advertising参数,Scan参数,GAP Bond Manager参数(请参考 LE Host 中的 Device Name和Device Appearance的配置, Advertising参数的配置, Scan参数的配置, Bond Manager参数的配置)。
void app_le_gap_init(void)
{
/* Device name and device appearance */
......
/* Scan parameters */
......
/* GAP Bond Manager parameters */
......
/* Set device name and device appearance */
le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);
/* Set scan parameters */
le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode);
le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval);
le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window);
le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy),
&scan_filter_policy);
le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate),
&scan_filter_duplicate);
/* Set advertising parameters */
le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data);
le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data);
/* 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_gap_callback);
......
}
多链路管理
应用的链路控制模块在 link_mgr.h
中定义。
typedef struct
{
T_GAP_CONN_STATE conn_state; /**< Connection state. */
T_GAP_REMOTE_ADDR_TYPE bd_type; /**< remote BD type*/
uint8_t bd_addr[GAP_BD_ADDR_LEN]; /**< remote BD */
} T_APP_LINK;
extern T_APP_LINK app_link_table[APP_MAX_LINKS];
app_link_table
用于保存链路相关信息。
GAP消息处理
当APP从Bluetooth Host接收到GAP消息时,函数 app_handle_gap_msg()
会被调用。
当收到 GAP_MSG_LE_CONN_STATE_CHANGE
消息后, app_handle_conn_state_evt()
会更新 app_link_table
中的信息。
void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
{
if (conn_id >= APP_MAX_LINKS)
{
return;
}
APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d, conn_state(%d -> %d), disc_cause 0x%x",
conn_id, app_link_table[conn_id].conn_state, new_state, disc_cause);
app_link_table[conn_id].conn_state = new_state;
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_ERROR2("app_handle_conn_state_evt: connection lost, conn_id %d, cause 0x%x", conn_id,
disc_cause);
}
data_uart_print("Disconnect conn_id %d\r\n", conn_id);
memset(&app_link_table[conn_id], 0, sizeof(T_APP_LINK));
}
break;
case GAP_CONN_STATE_CONNECTED:
{
le_get_conn_addr(conn_id, app_link_table[conn_id].bd_addr,
&app_link_table[conn_id].bd_type);
data_uart_print("Connected success conn_id %d\r\n", conn_id);
}
break;
default:
break;
}
}
GAP回调函数处理
app_gap_callback()
用于处理GAP回调函数消息,
更多信息参见 LE Host 中的 Bluetooth LE GAP回调函数。
T_APP_RESULT app_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;
switch (cb_type)
{
/* common msg*/
case GAP_MSG_LE_READ_RSSI:
.......
}
Profile Client消息回调函数
当APP使用 xxx_add_client 注册specific client时,APP需注册回调函数以处理specific client的消息。 APP可以针对不同的clients注册不同的回调函数,也可以注册通用回调函数以处理specific clients的消息。
app_client_callback()
是通用回调函数,根据 client ID 区分不同的clients。
void app_le_profile_init(void)
{
client_init(3);
gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS);
simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS);
bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS);
client_register_general_client_cb(app_client_callback);
}
T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
APP_PRINT_INFO2("app_client_callback: client_id %d, conn_id %d",
client_id, conn_id);
if (client_id == CLIENT_PROFILE_GENERAL_ID)
{
T_CLIENT_APP_CB_DATA *p_client_app_cb_data = (T_CLIENT_APP_CB_DATA *)p_data;
switch (p_client_app_cb_data->cb_type)
{
case CLIENT_APP_CB_TYPE_DISC_STATE:
......
}
else if (client_id == gaps_client_id)
{
T_GAPS_CLIENT_CB_DATA *p_gaps_cb_data = (T_GAPS_CLIENT_CB_DATA *)p_data;
switch (p_gaps_cb_data->cb_type)
{
case GAPS_CLIENT_CB_TYPE_DISC_STATE:
......
}
}
Scatternet示例工程支持的GATT profile clients包括 GAP Service Client, Simple LE Service Client 和 Battery Service Client 。
Profile Service消息回调函数
当APP使用 xxx_add_service 注册specific service时,APP需要注册回调函数以处理specific service的消息。
APP需要调用 server_register_app_cb()
注册回调函数以处理profile server layer的信息。
APP可以针对不同的services注册不同的回调函数,也可以注册通用回调函数以处理specific services和profile server layer的消息。
app_profile_callback()
通用回调函数,根据 service ID 区分不同的services。
void app_le_profile_init(void)
{
server_init(2);
simp_srv_id = simp_ble_service_add_service(app_profile_callback);
bas_srv_id = bas_add_service(app_profile_callback);
server_register_app_cb(app_profile_callback);
}
更多信息参见 LE Host 中的 GATT Profile Server。
- 通用profile server回调函数
SERVICE_PROFILE_GENERAL_ID
是profile server layer使用的service ID。Profile server layer包含两种消息类型:-
该消息用于通知GAP启动流程中的服务注册流程已经结束。
PROFILE_EVT_SEND_DATA_COMPLETE
Profile server layer使用该消息向APP通知发送notification或者indication的结果。
T_APP_RESULT app_profile_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
是battery service的service ID。T_APP_RESULT app_profile_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
是simple LE service的service ID。T_APP_RESULT app_profile_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: ...... }
Airplane Mode设置
- 注册GAP Common回调函数APP需要调用
gap_register_app_cb()
以注册回调函数。
void app_le_gap_init(void) { ...... gap_register_app_cb(app_gap_common_callback); }
GAP Common回调函数消息处理
void app_gap_common_callback(uint8_t cb_type, void *p_cb_data) { T_GAP_CB_DATA cb_data; memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA)); APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type); switch (cb_type) { case GAP_MSG_WRITE_AIRPLAN_MODE: APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x", cb_data.p_gap_write_airplan_mode_rsp->cause); break; case GAP_MSG_READ_AIRPLAN_MODE: APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d", cb_data.p_gap_read_airplan_mode_rsp->cause, cb_data.p_gap_read_airplan_mode_rsp->mode); break; default: break; } return; }该回调函数可处理
GAP_MSG_WRITE_AIRPLAN_MODE
和GAP_MSG_READ_AIRPLAN_MODE
消息。
相关APIs
gap_write_airplan_mode()
用于写airplane mode。gap_read_airplan_mode()
用于读airplane mode。
static T_USER_CMD_PARSE_RESULT cmd_wairplane(T_USER_CMD_PARSED_VALUE *p_parse_value) { T_GAP_CAUSE cause; uint8_t mode = p_parse_value->dw_param[0]; cause = gap_write_airplan_mode(mode); return (T_USER_CMD_PARSE_RESULT)cause; } static T_USER_CMD_PARSE_RESULT cmd_rairplane(T_USER_CMD_PARSED_VALUE *p_parse_value) { T_GAP_CAUSE cause; cause = gap_read_airplan_mode(); return (T_USER_CMD_PARSE_RESULT)cause; }