简介
generic模型,就是sig mesh协议里面规定的一套通用功能模型,各个厂家只要按照协议去设计设备功能,设备之间即可兼容使用!
下面就用元素0x0106里面的“通用开关模型(generic_onoff_model)”来举例,了解并记录SDK里面,具体是如何应用generic模型的!
订阅、发布模式:
单播模式:
SDK代码参考
以下代码是一些代码片段,需要了解完整内容的话,可以在工程里面进行全局搜索!
只举例发布、订阅模式
客户端(gateway节点):
初始化
if (API_SUCCESS == retval){/* Register Configuration model client */retval = UI_register_config_model_client(element_handle);}if (API_SUCCESS == retval){/* Register Generic OnOff model client */retval = UI_register_generic_onoff_model_client(element_handle);}#ifdef USE_VENDORMODELif (API_SUCCESS == retval){/* Register Vendor Defined model server */retval = UI_register_vendor_defined_model_client(element_handle);}#endifUI_config_client_appkey_binding(0,0,UI_appkey);//重点printf("0x%08X 0x%08X 0x%02X\n",ms_iv_index.iv_index,ms_iv_index.iv_expire_time,ms_iv_index.iv_update_state);UI_prov_data.uaddr = 0x0001;//Get network keyretval = MS_access_cm_get_netkey_at_offset(0,0,UI_prov_data.netkey);if(retval == ACCESS_NO_MATCH) //if can't find netkey,generate it{UI_netkey_generate(UI_prov_data.netkey);}//Get key refresh stateMS_access_cm_get_key_refresh_phase(0,&key_refresh_state);key_refresh_state = (MS_ACCESS_KEY_REFRESH_PHASE_2 == key_refresh_state) ? 0x01 : 0x00;UI_prov_data.ivindex = ms_iv_index.iv_index;UI_prov_data.flags = ((ms_iv_index.iv_update_state & 0x01) << 1) | key_refresh_state;retval = UI_set_provision_data(UI_prov_data.uaddr);/* Set the Publish address for onoff and vendor model Client */UI_prov_data.uaddr = 0xCFFF;//重点UI_set_publish_address(UI_prov_data.uaddr, UI_generic_onoff_client_model_handle,MS_FALSE);//重点UI_set_publish_address(UI_prov_data.uaddr, UI_vendor_defined_client_model_handle,MS_FALSE);
发送“generic_onoff_set”命令
void UI_generic_onoff_set(UCHAR state){API_RESULT retval;MS_GENERIC_ONOFF_SET_STRUCT param;CONSOLE_OUT("Send Generic Onoff Set\n");param.onoff = state;param.tid = 0;param.optional_fields_present = 0x00;retval = MS_generic_onoff_set(¶m);//重点CONSOLE_OUT("Retval - 0x%04X\n", retval);}#define MS_generic_onoff_set(param) \MS_generic_onoff_client_send_reliable_pdu \(\MS_ACCESS_GENERIC_ONOFF_SET_OPCODE,\//重点param,\MS_ACCESS_GENERIC_ONOFF_STATUS_OPCODE\)
处理generic_onoff回调
API_RESULT UI_generic_onoff_client_cb(/* IN */ MS_ACCESS_MODEL_HANDLE* handle,/* IN */ UINT32 opcode,/* IN */ UCHAR* data_param,/* IN */ UINT16 data_len){API_RESULT retval;retval = API_SUCCESS;CONSOLE_OUT ("[GENERIC_ONOFF_CLIENT] Callback. Opcode 0x%04X\n", opcode);appl_dump_bytes(data_param, data_len);switch(opcode){case MS_ACCESS_GENERIC_ONOFF_STATUS_OPCODE://重点{CONSOLE_OUT("MS_ACCESS_GENERIC_ONOFF_STATUS_OPCODE\n");}break;}return retval;}
服务端(light节点):
初始化
if (API_SUCCESS == retval){/* Register Generic OnOff model server */retval = UI_register_generic_onoff_model_server(element_handle);}
绑定appkey
API_RESULT UI_sample_binding_app_key(void){MS_APPKEY_HANDLE handle;UINT8* key;UINT8 aid;DECL_CONST UINT8 t_key[16] = {0};API_RESULT retval;CONSOLE_OUT("Fetching App Key for Handle 0x0000\n");handle = 0x0000;retval = MS_access_cm_get_app_key(handle,&key,&aid);/* Check Retval. Print App Key */if (API_SUCCESS == retval){CONSOLE_OUT("App Key[0x%02X]: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",handle, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7],key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]);if (0 == EM_mem_cmp(key, t_key, 16)){/* NO AppKey Bound */retval = API_FAILURE;}else{/* Found a Valid App Key *//* Keeping the retval as API_SUCCESS */retval=MS_access_bind_model_app(UI_generic_onoff_server_model_handle, handle);//重点#ifdef USE_LIGHTNESSretval=MS_access_bind_model_app(UI_light_lightness_server_model_handle, handle);CONSOLE_OUT("BINDING App Key %04x (%04x %04x)\n",retval,UI_light_lightness_server_model_handle,handle);#endif#ifdef USE_CTLretval=MS_access_bind_model_app(UI_light_ctl_server_model_handle, handle);CONSOLE_OUT("BINDING App Key %04x (%04x %04x)\n",retval,UI_light_ctl_server_model_handle,handle);#endif#ifdef USE_HSLretval=MS_access_bind_model_app(UI_light_hsl_server_model_handle, handle);CONSOLE_OUT("BINDING App Key %04x (%04x %04x)\n",retval,UI_light_hsl_server_model_handle,handle);#endif#ifdef USE_SCENEretval=MS_access_bind_model_app(UI_scene_server_model_handle, handle);CONSOLE_OUT("BINDING App Key %04x (%04x %04x)\n",retval,UI_scene_server_model_handle,handle);#endif#ifdef USE_VENDORMODELretval=MS_access_bind_model_app(UI_vendor_defined_server_model_handle, handle);CONSOLE_OUT("BINDING App Key %04x (%04x %04x)\n",retval,UI_vendor_defined_server_model_handle,handle);#endif}}#ifdef EASY_BOUNDING//Provision ok,stop provision/config timeout handler by hqCONSOLE_OUT("Stop timer\n");EM_stop_timer(&procfg_timer_handle);blebrr_prov_started = MS_FALSE;#endifreturn retval;}
订阅0xCFFF
vm_subscriptiong_add (0xCFFF);//重点void vm_subscriptiong_add (MS_NET_ADDR addr){CONSOLE_OUT("vm_subscriptiong_add:%x\n",addr);MS_ACCESS_ADDRESS sub_addr;sub_addr.use_label=0;sub_addr.addr=addr;MS_access_ps_store_disable(MS_TRUE);MS_access_cm_add_model_subscription(UI_generic_onoff_server_model_handle,&sub_addr);#ifdef USE_LIGHTNESSMS_access_cm_add_model_subscription(UI_light_lightness_server_model_handle,&sub_addr);#endif#ifdef USE_CTLMS_access_cm_add_model_subscription(UI_light_ctl_server_model_handle,&sub_addr);MS_access_cm_add_model_subscription(UI_light_ctl_setup_server_model_handle,&sub_addr);#endif#ifdef USE_HSLMS_access_cm_add_model_subscription(UI_light_hsl_server_model_handle,&sub_addr);MS_access_cm_add_model_subscription(UI_light_hsl_setup_server_model_handle,&sub_addr);#endif#ifdef USE_SCENEMS_access_cm_add_model_subscription(UI_scene_server_model_handle,&sub_addr);MS_access_cm_add_model_subscription(UI_scene_setup_server_model_handle,&sub_addr);#endifMS_access_ps_store_disable(MS_FALSE);MS_access_ps_store_all_record();}
回调处理
static API_RESULT UI_generic_onoff_server_cb(/* IN */ MS_ACCESS_MODEL_REQ_MSG_CONTEXT* ctx,/* IN */ MS_ACCESS_MODEL_REQ_MSG_RAW* msg_raw,/* IN */ MS_ACCESS_MODEL_REQ_MSG_T* req_type,/* IN */ MS_ACCESS_MODEL_STATE_PARAMS* state_params,/* IN */ MS_ACCESS_MODEL_EXT_PARAMS* ext_params){MS_STATE_GENERIC_ONOFF_STRUCT param;MS_ACCESS_MODEL_STATE_PARAMS current_state_params;API_RESULT retval;retval = API_SUCCESS;/* Check message type */if (MS_ACCESS_MODEL_REQ_MSG_T_GET == req_type->type){CONSOLE_OUT("[GENERIC_ONOFF] GET Request.\n");UI_generic_onoff_model_state_get(state_params->state_type, 0, ¶m, 0);current_state_params.state_type = state_params->state_type;current_state_params.state = ¶m;/* Using same as target state and remaining time as 0 */}else if (MS_ACCESS_MODEL_REQ_MSG_T_SET == req_type->type)//重点{CONSOLE_OUT("[GENERIC_ONOFF] SET Request.\n");retval = UI_generic_onoff_model_state_set(state_params->state_type, 0, (MS_STATE_GENERIC_ONOFF_STRUCT*)state_params->state, 0);//重点current_state_params.state_type = state_params->state_type;current_state_params.state = (MS_STATE_GENERIC_ONOFF_STRUCT*)state_params->state;}/* See if to be acknowledged */if (0x01 == req_type->to_be_acked){CONSOLE_OUT("[GENERIC_ONOFF] Sending Response.\n");/* Parameters: Request Context, Current State, Target State (NULL: to be ignored), Remaining Time (0: to be ignored), Additional Parameters (NULL: to be ignored) */retval = MS_generic_onoff_server_state_update(ctx, ¤t_state_params, NULL, 0, NULL);}return retval;}static API_RESULT UI_generic_onoff_model_state_set(UINT16 state_t, UINT16 state_inst, void* param, UINT8 direction){API_RESULT retval;UCHAR proxy_state;retval = API_SUCCESS;switch (state_t){case MS_STATE_GENERIC_ONOFF_T:{MS_STATE_GENERIC_ONOFF_STRUCT* param_p;param_p = (MS_STATE_GENERIC_ONOFF_STRUCT*)param;/* Instantaneous Change */UI_generic_onoff.onoff = param_p->onoff;*param_p = UI_generic_onoff;CONSOLE_OUT("[state] current: 0x%02X\n", UI_generic_onoff.onoff);CONSOLE_OUT("[state] target: 0x%02X\n", UI_generic_onoff.target_onoff);CONSOLE_OUT("[state] remaining_time: 0x%02X\n", UI_generic_onoff.transition_time);proxy_state = UI_proxy_state_get();if(proxy_state==MS_PROXY_CONNECTED){EM_start_timer (&proxy_dly_thandle, (EM_TIMEOUT_MILLISEC | 100), proxy_dly_generic_onoff, NULL, 0);}else{generic_onoff_set_pl(param_p->onoff);//重点}/* Ignoring Instance and direction right now */}break;default:break;}return retval;}
