static cps_api_return_code_t get_interface( const char * name, cps_api_get_params_t *param, size_t *ix) { cps_api_object_t obj = cps_api_object_create(); uint_t ifix = cps_api_interface_name_to_if_index(name); cps_api_int_if_key_create(cps_api_object_key(obj),true,0,ifix); if (!cps_api_object_list_append(param->list,obj)) { cps_api_object_delete(obj); return cps_api_ret_code_ERR; } cps_api_object_attr_add(obj,cps_api_if_STRUCT_A_NAME,name,strlen(name)+1); cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_IFINDEX,ifix); unsigned int mtu; if (nas_os_util_int_mtu_get(name,&mtu)!=STD_ERR_OK) return cps_api_ret_code_ERR; cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_MTU,mtu); db_interface_state_t astate; db_interface_operational_state_t ostate; if (nas_os_util_int_admin_state_get(name,&astate,&ostate)!=STD_ERR_OK) return cps_api_ret_code_ERR; cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_ADMIN_STATE,astate); cps_api_object_attr_add_u32(obj,cps_api_if_STRUCT_A_OPER_STATE,ostate); hal_mac_addr_t mac; if (nas_os_util_int_mac_addr_get(name,&mac)!=STD_ERR_OK) return cps_api_ret_code_ERR; cps_api_object_attr_add(obj,cps_api_if_STRUCT_A_IF_MACADDR,&mac,sizeof(mac)); return cps_api_ret_code_OK; }
t_std_error nas_mirror_get_session_info(cps_api_object_list_t list, nas_mirror_id_t id){ std_mutex_simple_lock_guard lock(&nas_mirror_mutex); auto it = nas_mirror_table.find(id); if(it == nas_mirror_table.end()){ NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"No NAS Mirror session with Id %d exist",(int)id); return STD_ERR(MIRROR,NEXIST,0); } cps_api_object_t obj=cps_api_object_create(); if (obj==NULL) { NAS_MIRROR_LOG(ERR,0,"Failed to create a new object"); return STD_ERR(MIRROR,NOMEM,0); } if (!cps_api_object_list_append(list,obj)) { cps_api_object_delete(obj); NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Failed to append object to object list"); return STD_ERR(MIRROR,FAIL,0); } nas_mirror_fill_object(obj,it); return STD_ERR_OK; }
t_std_error nas_sflow_get_session_info(cps_api_object_list_t list,nas_sflow_id_t id){ std_mutex_simple_lock_guard lock(&nas_sflow_mutex); nas_sflow_map_it it = nas_sflow_table.find(id); if(it == nas_sflow_table.end()){ NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"No NAS sFlow session with Id %d exist",(int)id); return STD_ERR(SFLOW,NEXIST,0); } cps_api_object_t obj=cps_api_object_create(); if(obj == NULL){ NAS_SFLOW_LOG(ERR,0,"Failed to create new object"); return STD_ERR(SFLOW,NOMEM,0); } if (!cps_api_object_list_append(list,obj)) { cps_api_object_delete(obj); return STD_ERR(SFLOW,FAIL,0); } nas_sflow_fill_object(obj,it); return STD_ERR_OK; }
extern "C" cps_api_return_code_t cps_api_commit_one(cps_api_operation_types_t type, cps_api_object_t obj, size_t retry_count, size_t ms_delay_between) { cps_api_transaction_params_t tr; if (cps_api_transaction_init(&tr)!=cps_api_ret_code_OK) { return cps_api_ret_code_ERR; } cps_api_transaction_guard tr_g(&tr); cps_api_key_set_attr(cps_api_object_key(obj),type); if (!cps_api_object_list_append(tr.change_list,obj)) { return cps_api_ret_code_ERR; } bool inf = retry_count==0; if (ms_delay_between==0) ms_delay_between = BASIC_WAIT_TIME; ms_delay_between = MILLI_TO_MICRO(ms_delay_between); cps_api_return_code_t rc = cps_api_ret_code_ERR; while (inf || (retry_count >0) ) { rc = cps_api_commit(&tr); if (rc==cps_api_ret_code_OK) { //since this will be erased by the caller remove it from the transaction list break; } if (!inf) --retry_count; std_usleep(ms_delay_between); } cps_api_object_list_remove(tr.change_list,0); return rc; }
cps_api_return_code_t cps_api_process_get_request(cps_api_get_params_t *param, size_t ix) { cps_api_return_code_t rc = cps_api_ret_code_ERR; char buff[SCRATCH_LOG_BUFF]; cps_api_channel_t handle; cps_api_key_t *key = cps_api_object_key(cps_api_object_list_get(param->filters,ix)); if (!cps_api_get_handle(*key,handle)) { EV_LOG(ERR,DSAPI,0,"NS","Failed to find owner for %s", cps_api_key_print(key,buff,sizeof(buff)-1)); return cps_api_ret_code_NO_SERVICE; } do { cps_api_object_t o = cps_api_object_list_get(param->filters,ix); if (o==NULL) { EV_LOG(ERR,DSAPI,0,"NS","Missing filters... %s", cps_api_key_print(key,buff,sizeof(buff)-1)); break; } if (!cps_api_send_one_object(handle,cps_api_msg_o_GET,o)) { EV_LOG(ERR,DSAPI,0,"NS","Failed to send request %s", cps_api_key_print(key,buff,sizeof(buff)-1)); break; } uint32_t op; do { if (param->timeout > 0) { fd_set rset; FD_ZERO(&rset); FD_SET(handle,&rset); if ((rc=cps_api_timeout_wait(handle,&rset,param->timeout,"CPS-OP-GET"))!=cps_api_ret_code_OK) { EV_LOG(ERR,DSAPI,0,"CPS-OP-GET","Send request %s timed out", cps_api_key_print(key,buff,sizeof(buff)-1)); break; } } size_t len; if (!cps_api_receive_header(handle,op,len)) break; if (op!=cps_api_msg_o_GET_RESP) break; cps_api_object_guard og (cps_api_receive_object(handle,len)); if (og.valid() && cps_api_object_list_append(param->list,og.get())) { og.release(); } else break; } while (op == cps_api_msg_o_GET_RESP); if (op!=cps_api_msg_o_GET_DONE) break; //leave an error code rc = cps_api_ret_code_OK; } while (0); cps_api_disconnect_owner(handle); return rc; }
static bool get_netlink_data(int rt_msg_type, struct nlmsghdr *hdr, void *data) { if (rt_msg_type <= RTM_SETLINK) { cps_api_object_list_t * list = (cps_api_object_list_t*)data; cps_api_object_t obj = cps_api_object_create(); if (nl_get_if_info(rt_msg_type,hdr,obj)) { if (cps_api_object_list_append(*list,obj)) { return true; } } return false; } return true; }
static bool process_route_and_add_to_list(int rt_msg_type, struct nlmsghdr *nh, void *context) { cps_api_object_list_t *list = (cps_api_object_list_t*) context; cps_api_object_t obj=cps_api_object_create(); if (!cps_api_object_list_append(*list,obj)) { cps_api_object_delete(obj); return false; } if (!nl_to_route_info(nh->nlmsg_type,nh,obj)) { return false; } return true; }
static bool py_add_object_to_trans( cps_api_transaction_params_t *tr, PyObject *dict) { PyObject *_req = PyDict_GetItemString(dict,"change"); PyObject *_op = PyDict_GetItemString(dict,"operation"); if (_op==NULL || _req==NULL) { return false; } PyObject *_prev = PyDict_GetItemString(dict,"previous"); if (_prev!=NULL) { if (cps_api_object_list_size(tr->change_list)!= cps_api_object_list_size(tr->prev)) { return false; } cps_api_object_guard og(dict_to_cps_obj(_req)); if (!og.valid()) return false; if (!cps_api_object_list_append(tr->prev,og.get())) { return false; } og.release(); } using cps_oper = cps_api_return_code_t (*)(cps_api_transaction_params_t * trans, cps_api_object_t object); static std::map<std::string,cps_oper> trans = { {"delete",cps_api_delete }, {"create",cps_api_create}, {"set",cps_api_set}, {"rpc",cps_api_action} }; if (trans.find(PyString_AsString(_op))==trans.end()) { return false; } cps_oper oper = trans[PyString_AsString(_op)]; cps_api_object_t obj = dict_to_cps_obj(_req); cps_api_object_guard og(obj); if (!og.valid()) return false; if (oper(tr,obj)!=cps_api_ret_code_OK) { return false; } og.release(); return true; }
static cps_api_return_code_t _write_function(void * context, cps_api_transaction_params_t * param,size_t ix) { cps_api_object_t obj = cps_api_object_list_get(param->change_list,ix); if (obj==NULL) return cps_api_ret_code_ERR; cps_api_operation_types_t op = cps_api_object_type_operation(cps_api_object_key(obj)); cps_api_object_t prev = cps_api_object_create(); if (prev==NULL) return cps_api_ret_code_ERR; if (!cps_api_object_list_append(param->prev,prev)) { cps_api_object_delete(prev); return cps_api_ret_code_ERR; } cps_api_key_t _local_key; cps_api_key_init(&_local_key,cps_api_qualifier_TARGET,cps_api_obj_cat_ROUTE,cps_api_route_obj_EVENT,0); if (cps_api_key_matches(&_local_key,cps_api_object_key(obj),true)) { os_send_refresh(nas_nl_sock_T_ROUTE); } else { return _op(op,context,obj,prev); } return cps_api_ret_code_OK; }
t_std_error nas_sflow_get_all_info(cps_api_object_list_t list){ std_mutex_simple_lock_guard lock(&nas_sflow_mutex); nas_sflow_map_it it = nas_sflow_table.begin(); for ( ; it != nas_sflow_table.end() ; ++it){ cps_api_object_t obj=cps_api_object_create(); if(obj == NULL){ NAS_SFLOW_LOG(ERR,0,"Failed to create new object"); return STD_ERR(SFLOW,NOMEM,0); } if (!cps_api_object_list_append(list,obj)) { cps_api_object_delete(obj); return STD_ERR(SFLOW,FAIL,0); } nas_sflow_fill_object(obj,it); } return STD_ERR_OK; }
t_std_error nas_mirror_get_all_info(cps_api_object_list_t list){ std_mutex_simple_lock_guard lock(&nas_mirror_mutex); auto it = nas_mirror_table.begin(); for ( ; it != nas_mirror_table.end() ; ++it){ cps_api_object_t obj=cps_api_object_create(); if (obj==NULL) { NAS_MIRROR_LOG(ERR,0,"Failed to create a new object"); return STD_ERR(MIRROR,NOMEM,0); } if (!cps_api_object_list_append(list,obj)) { cps_api_object_delete(obj); NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Failed to append object to object list"); return STD_ERR(MIRROR,FAIL,0); } nas_mirror_fill_object(obj,it); } return STD_ERR_OK; }
static cps_api_return_code_t _read_function (void * context, cps_api_get_params_t * param, size_t key_ix) { py_callbacks_t *cb = (py_callbacks_t*)context; GILLock gil; PyObject *p = PyDict_New(); PyRef dict(p); py_cps_util_set_item_to_dict(p,"filter",cps_obj_to_dict(cps_api_object_list_get( param->filters,key_ix))); py_cps_util_set_item_to_dict(p,"list",PyList_New(0)); PyObject * res = cb->execute("get",p); PyRef ret(res); if (res==NULL || !PyBool_Check(res) || (Py_False == (res))) { return cps_api_ret_code_ERR; } PyObject *d = PyDict_GetItemString(p,"list"); if (d!=NULL && PyList_Check(d)) { size_t ix = 0; size_t mx = PyList_Size(d); for ( ; ix < mx ; ++ix ) { PyObject *o = PyList_GetItem(d,ix); if (o==NULL || !PyDict_Check(o)) continue; cps_api_object_guard og(dict_to_cps_obj(o)); if (og.valid() && cps_api_object_list_append(param->list,og.get())) { og.release(); continue; } return cps_api_ret_code_ERR; } } return cps_api_ret_code_OK; }
static t_std_error dn_pas_fan_set1( cps_api_transaction_params_t *param, cps_api_qualifier_t qual, uint_t entity_type, uint_t slot, uint_t fan_idx, bool speed_valid, uint_t speed, bool speed_pct_valid, uint_t speed_pct ) { cps_api_key_t rec_key[1]; pas_fan_t *rec; cps_api_object_t old_obj; pas_oper_fault_state_t prev_oper_fault_state[1]; t_std_error rc = STD_ERR_OK; uint_t targ_speed = 0; bool notif = false; /* Look up object in cache */ cps_api_key_init(rec_key, cps_api_qualifier_OBSERVED, cps_api_obj_CAT_BASE_PAS, BASE_PAS_FAN_OBJ, 3, entity_type, slot, fan_idx ); rec = (pas_fan_t *) dn_pas_res_get(rec_key); if (rec == 0) { /* Not found */ return (STD_ERR(PAS, NEXIST, 0)); } *prev_oper_fault_state = *rec->oper_fault_state; old_obj = cps_api_object_create(); if (old_obj == CPS_API_OBJECT_NULL) return (STD_ERR(PAS, NOMEM, 0)); dn_pas_obj_key_fan_set(old_obj, qual, true, entity_type, true, slot, true, fan_idx ); cps_api_object_attr_add_u16(old_obj, BASE_PAS_FAN_SPEED, rec->targ_speed ); if (!cps_api_object_list_append(param->prev, old_obj)) { cps_api_object_delete(old_obj); return (STD_ERR(PAS, FAIL, 0)); } old_obj = CPS_API_OBJECT_NULL; /* No longer owned */ targ_speed = rec->targ_speed; if (speed_pct_valid) { targ_speed = (speed_pct * rec->max_speed) / 100; } if (speed_valid) targ_speed = speed; if (targ_speed == rec->targ_speed) return rc; dn_pas_lock(); if(!dn_pald_diag_mode_get()) { rc = sdi_fan_speed_set(rec->sdi_resource_hdl, targ_speed); } dn_pas_unlock(); if (STD_IS_ERR(rc)) { dn_pas_oper_fault_state_update(rec->oper_fault_state, PLATFORM_FAULT_TYPE_EHW ); } else { rec->targ_speed = targ_speed; } if (rec->oper_fault_state->oper_status != prev_oper_fault_state->oper_status) { notif = true; } if (notif) dn_fan_notify(rec); return (rc); }
PyObject * py_cps_get(PyObject *self, PyObject *args) { PyObject * param_list; cps_api_get_params_t gr; if (cps_api_get_request_init (&gr)==cps_api_ret_code_ERR) { py_set_error_string("Failed to initialize the get req"); return nullptr; } cps_api_get_request_guard rg(&gr); PyObject *res_obj; if (! PyArg_ParseTuple( args, "O!O", &PyList_Type, ¶m_list,&res_obj)) { py_set_error_string("Failed to parse input args."); return nullptr; } PyObject * lst = NULL; if (PyDict_Check(res_obj)) { PyObject *l = PyList_New(0); PyRef _l(l); if (l==NULL) { py_set_error_string("Can not create a list."); return nullptr; } PyObject *_prev = PyDict_GetItemString(res_obj,"list"); if (_prev!=NULL) { PyDict_DelItemString(res_obj,"list"); } if (!py_cps_util_set_item_to_dict(res_obj,"list",l)) { py_set_error_string("Can not create a list."); return nullptr; } lst = l; } if (PyList_Check(res_obj)) { lst = res_obj; } if (lst==NULL) { py_set_error_string("The return args are invalid."); return nullptr; } Py_ssize_t str_keys = PyList_Size(param_list); { Py_ssize_t ix = 0; for ( ;ix < str_keys ; ++ix ) { PyObject *strObj = PyList_GetItem(param_list, ix); if (PyString_Check(strObj)) { // cps_api_object_t o = cps_api_object_list_create_obj_and_append(gr.filters); if (o==NULL) { py_set_error_string("Memory allocation error."); return nullptr; } if (!cps_api_key_from_string(cps_api_object_key(o),PyString_AsString(strObj))) { py_set_error_string("Memory allocation error."); return nullptr; } } if (PyDict_Check(strObj)) { cps_api_object_t o = dict_to_cps_obj(strObj); if (o==NULL) { py_set_error_string("Can't convert from a python to internal object"); return nullptr; } if (!cps_api_object_list_append(gr.filters,o)) { cps_api_object_delete(o); py_set_error_string("Memory allocation error."); return nullptr; } } } } gr.keys = NULL; gr.key_count = 0; cps_api_return_code_t rc; { NonBlockingPythonContext l; rc = cps_api_get(&gr); } if (rc!=cps_api_ret_code_OK) { Py_RETURN_FALSE; } size_t ix = 0; size_t mx = cps_api_object_list_size(gr.list); for ( ; ix < mx ; ++ix) { cps_api_object_t obj = cps_api_object_list_get(gr.list,ix); PyObject *d = cps_obj_to_dict(obj); PyRef r(d); if (d==NULL) { py_set_error_string("Memory allocation error."); return nullptr; } if (PyList_Append(lst,d)) { py_set_error_string("Memory allocation error."); return nullptr; } } Py_RETURN_TRUE; }
cps_api_return_code_t cps_api_process_commit_request(cps_api_transaction_params_t *param, size_t ix) { cps_api_return_code_t rc = cps_api_ret_code_ERR; cps_api_object_t obj = cps_api_object_list_get(param->change_list,ix); cps_api_object_t pre = cps_api_object_list_get(param->prev,ix); if (obj==NULL) { EV_LOG(ERR,DSAPI,0,"CPS IPC","No Commit Object"); return rc; } cps_api_channel_t handle; cps_api_key_t *key = cps_api_object_key(obj); char buff[CPS_API_KEY_STR_MAX]; EV_LOG(TRACE,DSAPI,0, "CPS IPC", "Object for commit request: %s ", cps_api_key_name_print(key, buff, sizeof(buff))); if (!cps_api_get_handle(*key,handle)) { EV_LOG(ERR,DSAPI,0,"CPS IPC","No Service"); return cps_api_ret_code_NO_SERVICE; } rc = cps_api_ret_code_ERR; fd_set rset; FD_ZERO(&rset); FD_SET(handle,&rset); do { if (!cps_api_send_one_object(handle,cps_api_msg_o_COMMIT_CHANGE,obj)) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Could not send COMMIT CHANGE "); break; } if (!cps_api_send_one_object(handle,cps_api_msg_o_COMMIT_PREV,pre)) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Could not send COMMIT PREV "); break; } uint32_t op; size_t len; if (param->timeout > 0) { if ((rc=cps_api_timeout_wait(handle,&rset,param->timeout,"CPS-OP-TR"))!=cps_api_ret_code_OK) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction Response timed out "); break; } } rc = cps_api_ret_code_ERR; if (!cps_api_receive_header(handle,op,len)) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Failed to read the receive header "); break; } if (op == cps_api_msg_o_COMMIT_OBJECT) { cps_api_object_guard og(cps_api_receive_object(handle,len)); if (!og.valid()) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response missing cur object.."); break; } cps_api_object_clone(obj,og.get()); if (!cps_api_receive_header(handle,op,len)) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Failed to read the receive header for prev object "); break; } if (op!=cps_api_msg_o_COMMIT_OBJECT) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response header incorrect for prev object" ); break; } if (len>0) { cps_api_object_guard og(cps_api_receive_object(handle,len)); if (!og.valid()) { EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response missing resp object.."); break; } obj = cps_api_object_list_get(param->prev,ix); if (obj==NULL) { //if there was no previous object passed by client override if (cps_api_object_list_append(param->prev,og.get())) { og.release(); rc = cps_api_ret_code_OK; } } else { //take the previous provided by the client if the key is valid //assume that the data is valid too if (cps_api_key_get_len(cps_api_object_key(og.get()))>0) { cps_api_object_clone(obj,og.get()); } rc = cps_api_ret_code_OK; } } } if (op == cps_api_msg_o_RETURN_CODE) { if (!cps_api_receive_data(handle,&rc,sizeof(rc))) break; } } while (0); cps_api_disconnect_owner(handle); return rc; }
static t_std_error dn_pas_psu_get1( cps_api_get_params_t *param, cps_api_qualifier_t qual, uint_t slot ) { cps_api_key_t rec_key[1]; pas_psu_t *rec; cps_api_object_t resp_obj; /* Look up object in cache */ cps_api_key_init(rec_key, cps_api_qualifier_OBSERVED, cps_api_obj_CAT_BASE_PAS, BASE_PAS_PSU_OBJ, 1, slot ); rec = (pas_psu_t *) dn_pas_res_get(rec_key); if (rec == 0) { /* Not found */ return (STD_ERR(PAS, NEXIST, 0)); } /* Compose respose object */ resp_obj = cps_api_object_create(); if (resp_obj == CPS_API_OBJECT_NULL) { EV_LOG_ERR(ev_log_t_PAS, 3, "PAS", "%s, allocate response object failed\n", __FUNCTION__); return (STD_ERR(PAS, NOMEM, 0)); } dn_pas_obj_key_psu_set(resp_obj, qual, true, slot); dn_pas_lock(); if ((!rec->valid || qual == cps_api_qualifier_REALTIME) && !dn_pald_diag_mode_get()) { /* Cache not valid or realtime object requested => Update cache from hardware */ dn_entity_poll(rec->parent, true); } if (rec->parent->present) { /* Add result attributes to response object */ cps_api_object_attr_add_u8(resp_obj, BASE_PAS_PSU_INPUT_TYPE, rec->input_type ); cps_api_object_attr_add_u8(resp_obj, BASE_PAS_PSU_FAN_AIRFLOW_TYPE, rec->fan_airflow_type ); } dn_pas_unlock(); /* Add response object to get response */ if (!cps_api_object_list_append(param->list, resp_obj)) { cps_api_object_delete(resp_obj); return (STD_ERR(PAS, FAIL, 0)); } return (STD_ERR_OK); }
static t_std_error dn_pas_fan_get1( cps_api_get_params_t *param, cps_api_qualifier_t qual, uint_t entity_type, uint_t slot, uint_t fan_idx ) { cps_api_key_t rec_key[1]; pas_fan_t *rec; cps_api_object_t resp_obj; /* Look up object in cache */ cps_api_key_init(rec_key, cps_api_qualifier_OBSERVED, cps_api_obj_CAT_BASE_PAS, BASE_PAS_FAN_OBJ, 3, entity_type, slot, fan_idx ); rec = (pas_fan_t *) dn_pas_res_get(rec_key); if (rec == 0) { /* Not found */ return (STD_ERR(PAS, NEXIST, 0)); } /* Compose respose object */ resp_obj = cps_api_object_create(); if (resp_obj == CPS_API_OBJECT_NULL) { EV_LOG_ERR(ev_log_t_PAS, 3, "PAS", "%s, allocate response object failed\n", __FUNCTION__); return (STD_ERR(PAS, NOMEM, 0)); } dn_pas_obj_key_fan_set(resp_obj, qual, true, entity_type, true, slot, true, fan_idx ); dn_pas_lock(); if ((!rec->valid || qual == cps_api_qualifier_REALTIME) && !dn_pald_diag_mode_get()) { /* Cache not valid or realtime object requested => Update cache from hardware */ dn_entity_poll(rec->parent, true); } if (rec->parent->present) { /* Add result attributes to response object */ if (qual == cps_api_qualifier_TARGET) { cps_api_object_attr_add_u16(resp_obj, BASE_PAS_FAN_SPEED, rec->targ_speed ); } else { cps_api_object_attr_add_u8(resp_obj, BASE_PAS_FAN_OPER_STATUS, rec->oper_fault_state->oper_status ); cps_api_object_attr_add_u8(resp_obj, BASE_PAS_FAN_FAULT_TYPE, rec->oper_fault_state->fault_type ); cps_api_object_attr_add_u16(resp_obj, BASE_PAS_FAN_SPEED, rec->obs_speed ); cps_api_object_attr_add_u8(resp_obj, BASE_PAS_FAN_SPEED_PCT, rec->max_speed != 0 ? (100 * rec->obs_speed) / rec->max_speed : 0 ); cps_api_object_attr_add_u16(resp_obj, BASE_PAS_FAN_MAX_SPEED, rec->max_speed ); } } dn_pas_unlock(); /* Add response object to get response */ if (!cps_api_object_list_append(param->list, resp_obj)) { cps_api_object_delete(resp_obj); return (STD_ERR(PAS, FAIL, 0)); } return (STD_ERR_OK); }