provisioner config level client demo¶
示例说明¶
示例功能简介
- 参考: 示例功能简介
如何运行示例代码
- 参考: 示例运行概要
如何设置 ble mesh 角色
- 参考: ble mesh 角色设置
如何处理 ble mesh 协议栈和应用协议栈的信息交互
示例功能简介¶
该示例主要体现的功能点如下:¶
- 设备支持mesh proxy,可以通过手机,经gatt连接快速配置入网。
- 节点上有一个generic level client,可以通过手机单独控制任一 client。
- 可以跟level server 配合,设置 client 的 publication 功能来控制server 的灯开关。
- 节点支持relay可控,可以手动打开或关闭relay,便于部署。
- 节点支持proxy server beacon 可控,可以手动打开或关闭该beacon,便于部署。
示例运行概要¶
硬件环境¶
该示例运行在 BLE Dongle 开发板上(开发板的详细信息,参考硬件支持包),用到硬件外设如下:¶
按键
botton 3 button 4 同时按下 ,心跳灯会快闪,设备重启并重新初始化,该操作会丢弃所有之前配置,设备变成unprovision 状态
PIN
PIN 7 8 短路 : relay 功能打开,LED2 蓝灯亮
PIN 10 11短路 : 延迟一分钟后 关闭proxy server beacon 功能打开,LED1红灯亮
指示灯
- led1 :
- 绿灯
- 熄灭, 设备proxy server beacon 功能打开;
- 常亮, 设备proxy server beacon 功能关闭;
- 蓝灯
- 熄灭, 保留;
- 常亮, 保留;
- 红灯
- 熄灭, 保留;
- 常亮, 保留;
- led2 :
- 绿灯
- 闪烁, 设备正常工作;
- 常亮/长灭, 设备异常;
- 蓝灯
- 熄灭, relay 功能关闭;
- 常亮, relay 功能打开;
- 红灯
- 熄灭, 保留;
- 常亮, 保留;
软件环境¶
- 设备端运行 ble mesh sdk 的 examples 目录下 provisioner_config_level_client示例。
- 手机端运行 任意厂商符合mesh标准的app。
软件运行流程¶
1. 用户自己函数入口
在 mesh_user_main.c 中, mesh_user_main_init()初始化自己数据。(需要注意:不能阻塞)
2. 开启mesh协议栈调度
在用户函数执行完后,系统自动开启ble协议栈调度。
3. 示例代码
void mesh_user_main_init(void)
{
///user data init
provisioner_config_client_init();
LOG(LOG_LVL_INFO,"mesh_user_main_init\n");
}
例程初始状态¶
- 设备正常上电后:
- led1 :
- 绿灯
- 熄灭, 设备proxy server beacon 功能默认打开;
- 蓝灯
- 熄灭, 保留;
- 红灯
- 熄灭, 保留;
- led2 :
- 绿灯
- 闪烁, 设备正常工作;
- 蓝灯
- 熄灭, relay 功能默认关闭;
- 红灯
- 熄灭, 保留;
ble mesh 角色设置¶
设置流程¶
static void user_role_init(void)
{
//1.role init
provision_init(MESH_ROLE_UNPROV_DEVICE, mesh_provisioner_evt_cb);
//2. data init
provisioner_data_init();
//3. set client own uniaddr
init_elmt_addr(USER_CLENT_UNICAST_ADDRESS);
}
1. 定义协议栈内部事件通知回调函数
/* provision device event callback function */
static void mesh_provisioner_evt_cb(mesh_prov_evt_type_t type , mesh_prov_evt_param_t param)
{
LOG(LOG_LVL_INFO,"mesh_provisioner_evt_cb type : %d\n",type);
switch(type)
{
case PROV_EVT_BEACON :
{
#ifdef MESH_TEST_UART_CTRL
UART_user_unprovisioned_dev_beacon_rx_callback(param.prov.p_beacon->dev_uuid,param.prov.p_beacon->oob_info,¶m.prov.p_beacon->uri_hash);
#endif /*MESH_TEST_UART_CTRL*/
//action link open
}
break;
case PROV_EVT_LINK_ACK ://(NO ACTION)
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_link_ack_rx_callback();
#endif /*MESH_TEST_UART_CTRL*/
}
break;
case PROV_EVT_CAPABILITIES :
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_capabilities_rx_callback(param.prov.p_dev_capabilities);
#endif /*MESH_TEST_UART_CTRL*/
//action start pdu
}
break;
case PROV_EVT_READ_PEER_PUBLIC_KEY_OOB : //alert input dialog
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_read_peer_public_key_oob(NULL);
#endif /*MESH_TEST_UART_CTRL*/
//action read peer public key
}
break;
case PROV_EVT_AUTH_DISPLAY_NUMBER : //provisioner expose random number (NO ACTION)
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_provision_output_auth_value(param.prov.p_output_val);
#endif /*MESH_TEST_UART_CTRL*/
}
break;
case PROV_EVT_AUTH_INPUT_NUMBER : //alert input dialog
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_provision_input_auth_value(param.prov.p_input_val,NULL);
#endif /*MESH_TEST_UART_CTRL*/
//action input complete
}
break;
case PROV_EVT_PROVISION_DONE : //(NO ACTION)
{
#ifdef MESH_TEST_UART_CTRL
UART_user_provisioner_provision_done(param.prov.done_state.success,param.prov.done_state.reason);//TODO:
#endif /*MESH_TEST_UART_CTRL*/
}
break;
default:
break;
}
}
2. 设置角色,注册事件回调
provision_init(MESH_ROLE_UNPROV_DEVICE, mesh_provisioner_evt_cb);
3. 初始化角色相关的数据
static void provisioner_data_init(void)
{
volatile mesh_prov_evt_param_t evt_param;
uint8_t bd_addr[GAP_BD_ADDR_LEN];
//get bd_addr
mesh_core_params_t core_param;
core_param.mac_address = bd_addr;
mesh_core_params_get(MESH_CORE_PARAM_MAC_ADDRESS,&core_param);
//1. Method of configuring network access
evt_param.prov.method = PROVISION_BY_ADV;
provision_config(PROV_SET_PROVISION_METHOD,evt_param);
//2. distribution data
//send message will use the first netkey.
//See @access_tx_pdu_set -> @get_netkey_by_dst_addr -> @dm_netkey_get_first_handle
evt_param.prov.p_distribution = &m_prov_user.distribution;
provision_config(PROV_SET_DISTRIBUTION_DATA,evt_param);
//3. static auth value
evt_param.prov.p_static_val = m_prov_user.static_value;
provision_config(PROV_SET_AUTH_STATIC,evt_param);
//4. PROV_SET_INVITE_DURATION
evt_param.prov.attention_duration = USER_ATTENTION_DURATION;
provision_config(PROV_SET_INVITE_DURATION,evt_param);
//5. private key
memcpy(m_prov_user.prov_private_key,bd_addr,GAP_BD_ADDR_LEN);
evt_param.prov.p_prov_private_key = m_prov_user.prov_private_key;
provision_config(PROV_SET_PRIVATE_KEY,evt_param);
}
4. 协议栈开始完整运行
监听协议栈事件。。。。
ble mesh 协议栈和应用协议栈的信息交互¶
实现消息交互的处理函数¶
根据收到的事件,做相应处理或回复¶
//协议->用户
typedef enum
{
/*******PROVISIONER*******/
PROV_EVT_BEACON,
PROV_EVT_CAPABILITIES,
PROV_EVT_READ_PEER_PUBLIC_KEY_OOB,
PROV_EVT_AUTH_DISPLAY_NUMBER,//provisioner expose random number (NO ACTION)
PROV_EVT_AUTH_INPUT_NUMBER, //alert input dialog
PROV_EVT_PROVISION_DONE, //(NO ACTION)
/*******UNPROV DEVICE*******/
UNPROV_EVT_INVITE_MAKE_ATTENTION,//(NO ACTION)
UNPROV_EVT_EXPOSE_PUBLIC_KEY, //(NO ACTION)
UNPROV_EVT_AUTH_INPUT_NUMBER,//alert input dialog
UNPROV_EVT_AUTH_DISPLAY_NUMBER,//unprov_device expose random number //(NO ACTION)
UNPROV_EVT_PROVISION_DONE, //(NO ACTION)
} mesh_prov_evt_type_t;
//用户->协议栈(回复)
typedef enum
{
/*******PROVISIONER*******/
//PROV_EVT_AUTH_INPUT_NUMBER
PROV_ACTION_AUTH_INPUT_NUMBER_DONE,//input random number done
//PROV_EVT_READ_PEER_PUBLIC_KEY_OOB
PROV_ACTION_READ_PEER_PUBLIC_KEY_OOB_DONE,
//PROV_EVT_BEACON
PROV_ACTION_SET_LINK_OPEN,
//PROV_EVT_CAPABILITIES
PROV_ACTION_SEND_START_PDU,
/*******UNPROV DEVICE*******/
//UNPROV_EVT_AUTH_INPUT_NUMBER
UNPROV_ACTION_AUTH_INPUT_NUMBER_DONE,//input random number done
} mesh_prov_action_type_t;
void provision_action_send (mesh_prov_action_type_t type , mesh_prov_evt_param_t param);