一、项目代码路径与编译
1.1 项目代码路径
light demo项目工程位于协议栈代码app/example/bluetooth/light目录下。如果需要创建一个新工程,可以在bluetooth目录下参照light工程创建对应的工程文件夹。
1.2 编译指令
天猫精灵蓝牙mesh协议栈编译指令为:aos make bluetooth.project_name@chip_name
light demo的编译指令为aos make bluetooth.light@chip_name。
比如采用telink8250芯片,对应编译指令aos make bluetooth.light@tc825x
或者采用nordic10040芯片,对应编译指令aos make bluetooth.light@pca10040
注:以上编译指令如果对编译环境有要求,需要联系芯片厂商提供对应对编译环境安装包。编译生成对bin文件位于根目录out目录下。
二、应用层接口
基于天猫精灵蓝牙mesh协议栈开发一个产品,原则上对接实现3个软件接口即可完整对接整个蓝牙mesh功能。
需要对接的3个软件接口如下:
• 设备模型定义
• 设备默认组播设置
• 协议栈事件响应
2.1 设备模型定义
根据设备需要实现的具体功能,定义设备模型;demo中定义的灯模型具备开关、亮度调节、色温调节功能,所以定义的设备模型如下:
Primary Element Configuration Server Model
Health Server Model
Generic OnOff Server Model
Lightness Server Model
CTL Server Model
Vendor Server Model
注:上述模型中,Lightness Server依赖于Generic Level Server,CTL Server依赖于CTL Setup Server。
代码如下:
static struct bt_mesh_model element_models[] = {
BT_MESH_MODEL_CFG_SRV(),
BT_MESH_MODEL_HEALTH_SRV(),
MESH_MODEL_GEN_ONOFF_SRV(&g_elem_state[0]),
MESH_MODEL_GEN_LEVEL_SRV(&g_elem_state[0]),
MESH_MODEL_LIGHTNESS_SRV(&g_elem_state[0]),
MESH_MODEL_CTL_SRV(&g_elem_state[0]),
MESH_MODEL_CTL_SETUP_SRV(&g_elem_state[0]),
};
2.2 设备默认组播设置
根据灯品类产品规范,灯需要默认绑定组播地址为0xC000和0xCFFF。
代码如下:
#define DEFAULT_MESH_GROUP1 0xC000
#define DEFAULT_MESH_GROUP2 0xCFFF
void mesh_sub_init(u16_t *p_sub)
{
uint16_t sub_list[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
memset(sub_list, 0, sizeof(sub_list));
#ifdef DEFAULT_MESH_GROUP1
sub_list[0] = DEFAULT_MESH_GROUP1;
#endif
#ifdef DEFAULT_MESH_GROUP2
sub_list[1] = DEFAULT_MESH_GROUP2;
#endif
memcpy(p_sub, sub_list, sizeof(sub_list));
}
2.3 协议栈事件响应
该软件接口主要处理协议栈触发的具体事件,代码如下:
void user_event(E_GENIE_EVENT event, void *p_arg)
{
E_GENIE_EVENT next_event = event;
switch(event) {
case GENIE_EVT_SW_RESET:
case GENIE_EVT_HW_RESET_START:
BT_DBG_R("FLASH x5");
led_flash(5);
reset_light_para();
break;
case GENIE_EVT_SDK_MESH_INIT:
user_init();
if (!genie_reset_get_flag()) {
next_event = GENIE_EVT_SDK_ANALYZE_MSG;
}
break;
case GENIE_EVT_SDK_MESH_PROV_SUCCESS:
BT_DBG_R("FLASH x3");
led_flash(3);
break;
case GENIE_EVT_SDK_TRANS_CYCLE:
case GENIE_EVT_SDK_ACTION_DONE:
{
S_ELEM_STATE *p_elem = (S_ELEM_STATE *)p_arg;
_led_set(p_elem->elem_index, p_elem->state.onoff[T_CUR], p_elem->state.actual[T_CUR], p_elem->state.temp[T_CUR]);
if(event == GENIE_EVT_SDK_ACTION_DONE)
save_light_state(p_elem);
break;
}
case GENIE_EVT_SDK_INDICATE:
break;
case GENIE_EVT_SDK_VENDOR_MSG:
{
vendor_model_msg_handle((vnd_model_msg *)p_arg);
break;
}
case GENIE_EVT_HW_RESET_DONE:
printk("GENIE_EVT_HW_RESET_DONE\n");
break;
default:
break;
}
if(next_event != event) {
genie_event(next_event, p_arg);
}
}
2.4 协议栈事件说明
GENIE_EVT_SW_RESET
GENIE_EVT_HW_RESET_START
GENIE_EVT_SDK_MESH_INIT
GENIE_EVT_SDK_MESH_PROV_SUCCESS
GENIE_EVT_SDK_TRANS_CYCLE
GENIE_EVT_SDK_ACTION_DONE
GENIE_EVT_SDK_INDICATE
GENIE_EVT_SDK_VENDOR_MSG
GENIE_EVT_HW_RESET_DONE