extern "C" cps_api_return_code_t cps_api_get_objs(cps_api_object_t filt, cps_api_object_list_t obj_list,
        size_t retry_count, size_t ms_delay_between) {

    cps_api_return_code_t rc;
    cps_api_get_params_t get_req;

    if ((rc=cps_api_get_request_init(&get_req))!=cps_api_ret_code_OK) return rc;

    cps_api_get_request_guard rg(&get_req);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(get_req.filters);
    if (obj==nullptr) return cps_api_ret_code_ERR;
    if (!cps_api_object_clone(obj,filt)) return cps_api_ret_code_ERR;

    if (ms_delay_between==0) ms_delay_between = BASIC_WAIT_TIME;
    ms_delay_between = MILLI_TO_MICRO(ms_delay_between);

    cps_api_object_list_t _tmp_lst = get_req.list;
    get_req.list = obj_list;

    bool inf = retry_count==0;
    while (inf || (retry_count >0) ) {
        rc = cps_api_get(&get_req);
        if (rc==cps_api_ret_code_OK) break;
        if (!inf) --retry_count;
        std_usleep(ms_delay_between);
    }
    get_req.list = _tmp_lst;
    return rc;
}
TEST(std_nas_route_test, nas_route_arp_get) {
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_ROUTE_OBJ_NBR,
                                        cps_api_qualifier_TARGET);
    unsigned short af = 2;
    cps_api_set_key_data(obj,BASE_ROUTE_OBJ_NBR_AF,cps_api_object_ATTR_T_U16,
                                 &af,sizeof(af));

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);

        for ( size_t ix = 0 ; ix < mx ; ++ix ) {
            obj = cps_api_object_list_get(gp.list,ix);
            std::cout<<"ARP ENTRY "<<std::endl;
            std::cout<<"================================="<<std::endl;
            nas_route_dump_arp_object_content(obj);
            std::cout<<std::endl;
        }
    }

    cps_api_get_request_close(&gp);

}
static t_std_error dn_nas_get_phy_media_default_setting(PLATFORM_MEDIA_TYPE_t media_type, cps_api_object_t obj)
{
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);
    cps_api_get_request_guard rg(&gp);

    cps_api_object_t media_obj = cps_api_object_list_create_obj_and_append(gp.filters);
    t_std_error rc = STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_FAIL, 0);

    do {
        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(media_obj),
                                BASE_MEDIA_MEDIA_INFO_OBJ, cps_api_qualifier_OBSERVED)) {
            break;
        }
        cps_api_set_key_data_uint(media_obj, BASE_MEDIA_MEDIA_INFO_MEDIA_TYPE, &media_type, sizeof(media_type));
        cps_api_object_attr_add_u32(media_obj, BASE_MEDIA_MEDIA_INFO_MEDIA_TYPE, media_type);
        if (cps_api_get(&gp) != cps_api_ret_code_OK)
            break;

        if (0 == cps_api_object_list_size(gp.list))
            break;

        media_obj = cps_api_object_list_get(gp.list,0);
        if (!cps_api_object_clone(obj, media_obj)) {
            break;
        }
        rc = STD_ERR_OK;
    } while(0);
    return rc;
}
Example #4
0
t_std_error nas_get_lag_if_index (uint64_t ndi_port, hal_ifindex_t *lag_if_index)
{
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);
    cps_api_get_request_guard rg(&gp);

    EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C", "querying for ifindex of ndi lag id 0x%x ", ndi_port);
    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);

    cps_api_key_from_attr_with_qual(cps_api_object_key(obj), DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_OBJ,
            cps_api_qualifier_TARGET);

    cps_api_object_attr_add_u64(obj,BASE_IF_LAG_IF_INTERFACES_INTERFACE_LAG_OPAQUE_DATA, ndi_port);
    cps_api_object_attr_add(obj,IF_INTERFACES_INTERFACE_TYPE,
                  (const char *)IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG,
                  sizeof(IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG));

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);
        for (size_t ix = 0 ; ix < mx ; ++ix ) {
            cps_api_object_t obj = cps_api_object_list_get(gp.list,ix);
            cps_api_object_it_t it;
            cps_api_object_it_begin(obj,&it);
            cps_api_object_attr_t attr = cps_api_object_it_find(&it, DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX);
            if (!attr) {
               return  STD_ERR(INTERFACE, FAIL, 0);
            }
            *lag_if_index = cps_api_object_attr_data_u32(attr);
        }
    }
    return(STD_ERR_OK);
}
static cps_api_return_code_t _write_function(void * context, cps_api_transaction_params_t * param,size_t ix) {
    GILLock gil;

    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_object_t prev = cps_api_object_list_get(param->prev,ix);
    if(prev==NULL) {
        prev = cps_api_object_list_create_obj_and_append(param->prev);
    }
    if (prev==NULL) return cps_api_ret_code_ERR;

    cps_api_operation_types_t op = cps_api_object_type_operation(cps_api_object_key(obj));

    PyObject *p = PyDict_New();
    PyRef dict(p);

    py_cps_util_set_item_to_dict(p,"change",cps_obj_to_dict(obj));
    py_cps_util_set_item_to_dict(p,"previous",cps_obj_to_dict(prev));

    static const std::map<int,std::string> trans = {
            {cps_api_oper_DELETE,"delete" },
            {cps_api_oper_CREATE,"create"},
            {cps_api_oper_SET, "set"},
            {cps_api_oper_ACTION,"rpc"}
    };

    py_cps_util_set_item_to_dict(p,"operation",PyString_FromString(trans.at(op).c_str()));

    py_callbacks_t *cb = (py_callbacks_t*)context;
    PyObject *res = cb->execute("transaction",p);

    if (res==NULL || !PyBool_Check(res) || (Py_False==(res))) {
        return cps_api_ret_code_ERR;
    }
    PyRef ret(res);

    PyObject *ch = PyDict_GetItemString(p,"change");
    if (ch==NULL) return cps_api_ret_code_ERR;

    cps_api_object_t o = dict_to_cps_obj(ch);
    cps_api_object_guard og(o);
    if(og.valid()) {
        cps_api_object_clone(obj,og.get());
    }

    PyObject *pr = PyDict_GetItemString(p,"previous");
    if (pr==NULL) return cps_api_ret_code_ERR;
    og.set(dict_to_cps_obj(pr));
    if (og.valid()) {
        cps_api_object_clone(prev,og.get());
    }
    return cps_api_ret_code_OK;
}
static cps_api_return_code_t _phy_int_set(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_object_t prev = cps_api_object_list_create_obj_and_append(param->prev);
    if (prev==nullptr) return cps_api_ret_code_ERR;

    cps_api_operation_types_t op = cps_api_object_type_operation(cps_api_object_key(obj));

    if (op==cps_api_oper_SET) return _phy_set(obj,prev);

    EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Invalid operation");

    return cps_api_ret_code_ERR;
}
Example #7
0
extern "C" t_std_error dn_hal_get_interface_mac(hal_ifindex_t if_index, hal_mac_addr_t mac_addr)
{
    if(mac_addr == NULL) {
        EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C","mac_addr_ptr NULL");
        return(STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_PARAM, 0));
    }

    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    t_std_error rc = STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_FAIL, 0);

    do {
        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(obj),
                                DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_OBJ, cps_api_qualifier_TARGET)) {
            break;
        }

        cps_api_object_attr_add_u32(obj,DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX, if_index);

        if (cps_api_get(&gp) != cps_api_ret_code_OK)
            break;

        if (0 == cps_api_object_list_size(gp.list))
            break;

        obj = cps_api_object_list_get(gp.list,0);

        cps_api_object_attr_t attr = cps_api_object_attr_get(obj,DELL_IF_IF_INTERFACES_INTERFACE_PHYS_ADDRESS);
        if (attr != NULL) {
            void *_mac_str = cps_api_object_attr_data_bin(attr);
            size_t addr_len = strlen(static_cast<char *>(_mac_str));
            EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C","mac_addr %s, len %d",
                         _mac_str, addr_len);

            if (std_string_to_mac((hal_mac_addr_t *)mac_addr, static_cast<const char *>(_mac_str), addr_len)) {
                rc = STD_ERR_OK;
            }
        }

    } while (0);

    cps_api_get_request_close(&gp);
    return rc;
}
Example #8
0
t_std_error dn_nas_lag_get_ndi_ids (hal_ifindex_t if_index, nas_ndi_obj_id_table_handle_t ndi_id_data)
{
    if(ndi_id_data == NULL) {
        EV_LOG_ERR(ev_log_t_INTERFACE, 2, "INTF-C","Input ndi_data is NULL");
        return(STD_ERR(INTERFACE, PARAM, 0));
    }

    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    t_std_error rc = STD_ERR(INTERFACE, FAIL, 0);

    do {
        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(obj),
                DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_OBJ, cps_api_qualifier_TARGET)) {
            break;
        }

        cps_api_object_attr_add_u32(obj,DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX, if_index);
        cps_api_object_attr_add(obj,IF_INTERFACES_INTERFACE_TYPE,
                (const char *)IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG,
                sizeof(IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG));

        if (cps_api_get(&gp) != cps_api_ret_code_OK)
            break;

        if (0 == cps_api_object_list_size(gp.list))
            break;

        obj = cps_api_object_list_get(gp.list,0);
        cps_api_attr_id_t  attr_list[] = {BASE_IF_LAG_IF_INTERFACES_INTERFACE_LAG_OPAQUE_DATA};

        if (!nas_ndi_obj_id_table_cps_unserialize (ndi_id_data, obj, attr_list,
                                                   sizeof (attr_list)/sizeof (cps_api_attr_id_t)))
        {
            EV_LOG_ERR(ev_log_t_INTERFACE, 2, "INTF-C","Failed to get LAG opaque data");
            break;
        }
        rc = STD_ERR_OK;

    } while (0);

    cps_api_get_request_close(&gp);
    return rc;
}
t_std_error nas_switch_get_sys_mac_base(hal_mac_addr_t *mac_base)
{
    if(mac_base == NULL) {
        EV_LOG(ERR,NAS_L2,0,"NAS-L2-SWITCH","invalid parameter");
        return(STD_ERR_MK(e_std_err_BOARD, e_std_err_code_PARAM, 0));
    }

    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    t_std_error rc = STD_ERR_MK(e_std_err_BOARD, e_std_err_code_FAIL, 0);

    do {
        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(obj),
                                BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY, cps_api_qualifier_TARGET)) {
            break;
        }

        uint32_t switch_id = 0; /*  default switch ID. @TODO add switch id  */
        cps_api_set_key_data_uint(obj, BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY_SWITCH_ID, &switch_id, sizeof(switch_id));

        if (cps_api_get(&gp) != cps_api_ret_code_OK)
            break;

        if (0 == cps_api_object_list_size(gp.list))
            break;

        obj = cps_api_object_list_get(gp.list,0);

        cps_api_object_attr_t attr = cps_api_object_attr_get(obj, BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY_DEFAULT_MAC_ADDRESS);
        if (attr != NULL) {
            memcpy(*mac_base,cps_api_object_attr_data_bin(attr),sizeof(*mac_base));
            rc = STD_ERR_OK;
        }

    } while (0);

    cps_api_get_request_close(&gp);
    return rc;
}
static cps_api_return_code_t _phy_int_get (void * context, cps_api_get_params_t * param,
        size_t key_ix) {

    cps_api_object_t filt = cps_api_object_list_get(param->filters,key_ix);

    npu_id_t npu = 0;
    npu_id_t npu_max = (npu_id_t)nas_switch_get_max_npus();

    cps_api_object_attr_t _npu = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_NPU_ID);
    cps_api_object_attr_t _port = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_PORT_ID);
    cps_api_object_attr_t _hw_port = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_HARDWARE_PORT_ID);

    for ( npu = 0; npu<  npu_max ; ++npu){
        if (_npu!=NULL && cps_api_object_attr_data_u32(_npu)!=(uint32_t)npu) continue;

        unsigned int intf_max_ports = ndi_max_npu_port_get(npu);
        for (port_t port = 0; port < intf_max_ports ; ++port ) {
            if (_port!=NULL && cps_api_object_attr_data_u32(_port)!=port) continue;

            if (_hw_port!=NULL) {
                uint32_t hwport;
                if (get_hw_port(npu,port,hwport)) {
                    if (cps_api_object_attr_data_u32(_hw_port)!=hwport) continue;
                }
            }

            // skip invalid port or cpu port
            if (!ndi_port_is_valid(npu, port) || _is_cpu_port(npu, port)) {
                continue;
            }

            cps_api_object_t o = cps_api_object_list_create_obj_and_append(param->list);
            if (o==NULL) return cps_api_ret_code_ERR;

            make_phy_port_details(npu,port,o);
        }
    }
    return cps_api_ret_code_OK;
}
static cps_api_return_code_t _append_one_map(cps_api_get_params_t * param,
                                        uint_t switch_id,
                                        nas_qos_map *map,
                                        nas_qos_map_type_t map_type,
                                        nas_qos_map_entry_key_t search_key,
                                        bool is_map_entry
                                        )
{
    /* fill in data */
    cps_api_object_t ret_obj;

    ret_obj = cps_api_object_list_create_obj_and_append(param->list);
    if (ret_obj == NULL) {
        return cps_api_ret_code_ERR;
    }

    nas_attr_id_t obj_id = (is_map_entry? qos_map_entry_obj_id(map_type):
                            qos_map_obj_id(map_type));
    cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
            obj_id,
            cps_api_qualifier_TARGET);

    obj_id = qos_map_map_id_obj_id(map_type);
    nas_obj_id_t map_id = map->get_map_id();
    cps_api_set_key_data(ret_obj, obj_id,
            cps_api_object_ATTR_T_U64,
            &map_id, sizeof(uint64_t));

    map_entries *entries = map->get_map_entries();
    if (entries == NULL)
        return NAS_QOS_E_FAIL;

    if (is_map_entry) {
        return _fill_matching_map_entries(ret_obj, search_key, entries, map_type);
    }
    else {
        return _fill_matching_map(ret_obj, entries, map_type);
    }
}
TEST(std_nas_route_test, nas_peer_routing_config_get) {
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_ROUTE_PEER_ROUTING_CONFIG_OBJ,
                                        cps_api_qualifier_TARGET);

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);

        for ( size_t ix = 0 ; ix < mx ; ++ix ) {
            obj = cps_api_object_list_get(gp.list,ix);
            std::cout<<"Peer Routing Status "<<std::endl;
            std::cout<<"================================="<<std::endl;
            nas_route_dump_peer_routing_object_content(obj);
            std::cout<<std::endl;
        }
    }

    cps_api_get_request_close(&gp);

}
TEST(std_nas_route_test, nas_route_ipv6_get) {
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_ROUTE_OBJ_ENTRY,
                                        cps_api_qualifier_TARGET);
    unsigned int af = AF_INET6;
    cps_api_set_key_data(obj,BASE_ROUTE_OBJ_ENTRY_AF,cps_api_object_ATTR_T_U32,
                                 &af,sizeof(af));

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);

        std::cout<<"IPv6 FIB Entries"<<std::endl;
        std::cout<<"================================="<<std::endl;
        for ( size_t ix = 0 ; ix < mx ; ++ix ) {
            obj = cps_api_object_list_get(gp.list,ix);
            nas_route_dump_route_object_content(obj);
            std::cout<<std::endl;
        }
    }
    cps_api_get_request_close(&gp);
}
/**
  * This function provides NAS-QoS SCHEDULER_GROUP CPS API read function
  * @Param      Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_scheduler_group_read (void * context,
                                            cps_api_get_params_t * param,
                                            size_t ix)
{
    cps_api_object_t obj = cps_api_object_list_get(param->filters, ix);
    cps_api_object_attr_t sg_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID);
    uint32_t port_id = 0, level;
    bool have_port = false, have_level = false;
    if (!sg_attr) {
        cps_api_object_it_t it;
        cps_api_object_it_begin(obj, &it);
        for ( ; cps_api_object_it_valid(&it); cps_api_object_it_next(&it)) {
            cps_api_attr_id_t id = cps_api_object_attr_id(it.attr);
            if (id == BASE_QOS_SCHEDULER_GROUP_PORT_ID) {
                port_id = cps_api_object_attr_data_u32(it.attr);
                have_port = true;
            } else if (id == BASE_QOS_SCHEDULER_GROUP_LEVEL) {
                level = cps_api_object_attr_data_u32(it.attr);
                have_level = true;
            }
        }
    }

    if (!sg_attr && !have_port) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                     "Invalid input attributes for reading");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint_t switch_id = 0;
    nas_obj_id_t scheduler_group_id = (sg_attr? cps_api_object_attr_data_u64(sg_attr): 0);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Read switch id %u, scheduler_group id 0x%016lX\n",
                    switch_id, scheduler_group_id);

    std_mutex_simple_lock_guard p_m(&scheduler_group_mutex);

    if (have_port) {
        nas_qos_port_scheduler_group_init(port_id);
    }
    nas_qos_switch * p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    std::vector<nas_qos_scheduler_group *> sg_list;
    if (sg_attr) {
        nas_qos_scheduler_group *scheduler_group = p_switch->get_scheduler_group(scheduler_group_id);
        if (scheduler_group == NULL) {
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                         "Could not find scheduler group with ID %llu", scheduler_group_id);
            return NAS_QOS_E_FAIL;
        }
        sg_list.push_back(scheduler_group);
    } else {
        int match_level = have_level ? (int)level : -1;
        p_switch->get_port_scheduler_groups(port_id, match_level, sg_list);
    }

    /* fill in data */
    cps_api_object_t ret_obj;

    for (auto scheduler_group: sg_list) {
        ret_obj = cps_api_object_list_create_obj_and_append (param->list);
        if (ret_obj == NULL) {
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                         "Failed to create cps object");
            return cps_api_ret_code_ERR;
        }

        cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),BASE_QOS_SCHEDULER_GROUP_OBJ,
                cps_api_qualifier_TARGET);
        cps_api_set_key_data(ret_obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID,
                cps_api_object_ATTR_T_U32,
                &switch_id, sizeof(uint32_t));
        scheduler_group_id = scheduler_group->get_scheduler_group_id();
        cps_api_set_key_data(ret_obj, BASE_QOS_SCHEDULER_GROUP_ID,
                cps_api_object_ATTR_T_U64,
                &scheduler_group_id, sizeof(uint64_t));

        cps_api_object_attr_add_u32(ret_obj,
                                    BASE_QOS_SCHEDULER_GROUP_CHILD_COUNT,
                                    scheduler_group->get_child_count());

        for (uint32_t idx = 0; idx < scheduler_group->get_child_count(); idx++) {
            cps_api_object_attr_add_u64(ret_obj,
                                        BASE_QOS_SCHEDULER_GROUP_CHILD_LIST,
                                        scheduler_group->get_child_id(idx));
        }

        cps_api_object_attr_add_u32(ret_obj, BASE_QOS_SCHEDULER_GROUP_PORT_ID,
                                    scheduler_group->get_port_id());
        cps_api_object_attr_add_u32(ret_obj, BASE_QOS_SCHEDULER_GROUP_LEVEL,
                                    scheduler_group->get_level());
        cps_api_object_attr_add_u64(ret_obj, BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID,
                                    scheduler_group->get_scheduler_profile_id());
    }

    return cps_api_ret_code_OK;
}
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, &param_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;
}
static cps_api_return_code_t nas_qos_cps_api_scheduler_group_set(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj)
{
    cps_api_object_attr_t sg_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID);

    if (sg_attr == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                     "switch id and scheduler group id not specified in the message\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint_t switch_id = 0;
    nas_obj_id_t scheduler_group_id = cps_api_object_attr_data_u64(sg_attr);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Modify switch id %u, scheduler_group id %u\n",
                    switch_id, scheduler_group_id);

    nas_qos_scheduler_group * scheduler_group_p = nas_qos_cps_get_scheduler_group(switch_id,
                                                                                  scheduler_group_id);
    if (scheduler_group_p == NULL) {
        return NAS_QOS_E_FAIL;
    }

    /* make a local copy of the existing scheduler_group */
    nas_qos_scheduler_group scheduler_group(*scheduler_group_p);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Modify switch id %u, scheduler_group id %u . After copy\n",
                    switch_id, scheduler_group_id);

    cps_api_return_code_t rc = cps_api_ret_code_OK;
    if ((rc = nas_qos_cps_parse_attr(obj, scheduler_group)) != cps_api_ret_code_OK)
        return rc;

    if (scheduler_group.get_level() == 0 &&
        scheduler_group.dirty_attr_list().contains(BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID)) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                " Scheduler Group Level 0 node does not accept Scheduler Profile ID; "
                " Use Port Egress Object to configure Scheduler Profile!\n");
        return NAS_QOS_E_UNSUPPORTED;
    }

    try {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Modifying scheduler_group %u attr on port %u \n",
                     scheduler_group.get_scheduler_group_id(), scheduler_group.get_port_id());

        nas::attr_set_t modified_attr_list = scheduler_group.commit_modify(*scheduler_group_p, (sav_obj? false: true));

        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "done with commit_modify \n");


        // set attribute with full copy
        // save rollback info if caller requests it.
        // use modified attr list, current scheduler_group value
        if (sav_obj) {
            cps_api_object_t tmp_obj;
            tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return cps_api_ret_code_ERR;
            }
            nas_qos_store_prev_attr(tmp_obj, modified_attr_list, *scheduler_group_p);
       }

        // update the local cache with newly set values
        *scheduler_group_p = scheduler_group;

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Attr Modify error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Modify Unexpected error code");
        return NAS_QOS_E_FAIL;
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_scheduler_group_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj)
{
#ifndef R_1_0_DISABLE_SG_CREATE
    nas_obj_id_t scheduler_group_id = 0;

    cps_api_object_attr_t switch_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID);
    if (switch_attr == NULL ) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " switch id not specified in the message\n");
        return NAS_QOS_E_FAIL;
    }

    uint_t switch_id = cps_api_object_attr_data_u32(switch_attr);

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    nas_qos_scheduler_group scheduler_group(p_switch);

    if (nas_qos_cps_parse_attr(obj, scheduler_group) != cps_api_ret_code_OK)
        return NAS_QOS_E_FAIL;

    if (scheduler_group.get_level() == 0 &&
        scheduler_group.dirty_attr_list().contains(BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID)) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                " Scheduler Group Level 0 node does not accept Scheduler Profile ID; "
                " Use Port Egress Object to configure Scheduler Profile!\n");
        return NAS_QOS_E_FAIL;
    }

    try {
        scheduler_group_id = p_switch->alloc_scheduler_group_id();

        scheduler_group.set_scheduler_group_id(scheduler_group_id);

        scheduler_group.commit_create(sav_obj? false: true);

        p_switch->add_scheduler_group(scheduler_group);

        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new scheduler_group %u\n",
                     scheduler_group.get_scheduler_group_id());

        // update obj with new scheduler_group-id key
        cps_api_set_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID,
                cps_api_object_ATTR_T_U64,
                &scheduler_group_id, sizeof(uint64_t));

        // save for rollback if caller requests it.
        if (sav_obj) {
            cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return NAS_QOS_E_FAIL;
            }
            cps_api_object_clone(tmp_obj, obj);

        }

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create error code: %d ",
                    e.err_code);
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create Unexpected error code");
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;
    }

#endif
    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_scheduler_group_delete(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj)
{
    cps_api_object_attr_t sg_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID);

    if (sg_attr == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " scheduler group id not specified in the message\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint_t switch_id = 0;
    nas_obj_id_t scheduler_group_id = cps_api_object_attr_data_u64(sg_attr);

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " switch: %u not found\n",
                     switch_id);
        return NAS_QOS_E_FAIL;
    }

    nas_qos_scheduler_group *scheduler_group_p = p_switch->get_scheduler_group(scheduler_group_id);
    if (scheduler_group_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " scheduler_group id: %u not found\n",
                     scheduler_group_id);

        return NAS_QOS_E_FAIL;
    }

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Deleting scheduler_group %u on switch: %u\n",
                 scheduler_group_p->get_scheduler_group_id(), p_switch->id());


    // delete
    try {
        scheduler_group_p->commit_delete(sav_obj? false: true);

        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Saving deleted scheduler_group %u\n",
                     scheduler_group_p->get_scheduler_group_id());

         // save current scheduler_group config for rollback if caller requests it.
        // use existing set_mask, existing config
        if (sav_obj) {
            cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return cps_api_ret_code_ERR;
            }
            nas_qos_store_prev_attr(tmp_obj, scheduler_group_p->set_attr_list(), *scheduler_group_p);
        }

        p_switch->remove_scheduler_group(scheduler_group_p->get_scheduler_group_id());

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Delete error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;
    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Delete: Unexpected error");
        return NAS_QOS_E_FAIL;
    }


    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_get_priority_group_info(
                                cps_api_get_params_t * param,
                                uint32_t switch_id, uint_t port_id,
                                bool match_local_id, uint_t local_id)
{
    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    uint_t count = p_switch->get_number_of_port_priority_groups(port_id);

    if  (count == 0) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "switch id %u, port id %u has no priority_groups\n",
                switch_id, port_id);

        return NAS_QOS_E_FAIL;
    }

    std::vector<nas_qos_priority_group *> pg_list(count);
    p_switch->get_port_priority_groups(port_id, count, &pg_list[0]);

    /* fill in data */
    cps_api_object_t ret_obj;

    for (uint_t i = 0; i < count; i++ ) {
        nas_qos_priority_group *priority_group = pg_list[i];

        // filter out unwanted priority_groups

        if (match_local_id && (priority_group->get_local_id() != local_id))
            continue;


        ret_obj = cps_api_object_list_create_obj_and_append(param->list);
        if (ret_obj == NULL) {
            return cps_api_ret_code_ERR;
        }

        cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
                BASE_QOS_PRIORITY_GROUP_OBJ,
                cps_api_qualifier_TARGET);
        uint32_t val_port = priority_group->get_port_id();
        uint8_t  val_local_id = priority_group->get_local_id();

        cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_PORT_ID,
                cps_api_object_ATTR_T_U32,
                &val_port, sizeof(uint32_t));
        cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID,
                cps_api_object_ATTR_T_BIN,
                &val_local_id, sizeof(uint8_t));

        cps_api_object_attr_add_u64(ret_obj, BASE_QOS_PRIORITY_GROUP_ID,
                priority_group->get_priority_group_id());

        // User configured objects
        if (priority_group->is_buffer_profile_set())
            cps_api_object_attr_add_u64(ret_obj,
                    BASE_QOS_PRIORITY_GROUP_BUFFER_PROFILE_ID,
                    priority_group->get_buffer_profile());

    }

    return cps_api_ret_code_OK;
}
/**
  * This function provides NAS-QoS priority_group stats CPS API read function
  * @Param    Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_priority_group_stat_read (void * context,
                                            cps_api_get_params_t * param,
                                            size_t ix)
{

    cps_api_object_t obj = cps_api_object_list_get(param->filters, ix);
    cps_api_object_attr_t port_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID);
    cps_api_object_attr_t local_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID);

    if (port_id_attr == NULL ||
        local_id_attr == NULL ) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Incomplete key: port-id, priority_group local id must be specified\n");
        return NAS_QOS_E_MISSING_KEY;
    }
    uint32_t switch_id = 0;
    nas_qos_priority_group_key_t key;
    key.port_id = cps_api_object_attr_data_u32(port_id_attr);
    key.local_id = *(uint8_t *)cps_api_object_attr_data_bin(local_id_attr);


    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
            "Read switch id %u, port_id %u priority_group local id %u stat\n",
            switch_id, key.port_id, key.local_id);

    std_mutex_simple_lock_guard p_m(&priority_group_mutex);

    // If the port is not be initialized yet, initialize it in NAS
    nas_qos_port_priority_group_init(key.port_id);

    nas_qos_switch *switch_p = nas_qos_get_switch(switch_id);
    if (switch_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "switch_id %u not found", switch_id);
        return NAS_QOS_E_FAIL;
    }

    nas_qos_priority_group * priority_group_p = switch_p->get_priority_group(key);
    if (priority_group_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Priority Group not found");
        return NAS_QOS_E_FAIL;
    }

    nas_qos_priority_group_stat_counter_t stats = {0};
    std::vector<BASE_QOS_PRIORITY_GROUP_STAT_t> counter_ids;

    cps_api_object_it_t it;
    cps_api_object_it_begin(obj,&it);
    for ( ; cps_api_object_it_valid(&it) ; cps_api_object_it_next(&it) ) {
        cps_api_attr_id_t id = cps_api_object_attr_id(it.attr);
        switch (id) {
        case BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID:
        case BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID:
            break;

        case BASE_QOS_PRIORITY_GROUP_STAT_PACKETS:
        case BASE_QOS_PRIORITY_GROUP_STAT_BYTES:
        case BASE_QOS_PRIORITY_GROUP_STAT_CURRENT_OCCUPANCY_BYTES:
        case BASE_QOS_PRIORITY_GROUP_STAT_WATERMARK_BYTES:
            counter_ids.push_back((BASE_QOS_PRIORITY_GROUP_STAT_t)id);
            break;

        default:
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Unknown priority_group STAT flag: %u, ignored", id);
            break;
        }
    }

    if (ndi_qos_get_priority_group_stats(priority_group_p->get_ndi_port_id(),
                                priority_group_p->ndi_obj_id(),
                                &counter_ids[0],
                                counter_ids.size(),
                                &stats) != STD_ERR_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Priority Group stats get failed");
        return NAS_QOS_E_FAIL;
    }

    // return stats objects to cps-app
    cps_api_object_t ret_obj = cps_api_object_list_create_obj_and_append(param->list);
    if (ret_obj == NULL) {
        return cps_api_ret_code_ERR;
    }

    cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
            BASE_QOS_PRIORITY_GROUP_STAT_OBJ,
            cps_api_qualifier_TARGET);
    cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID,
            cps_api_object_ATTR_T_U32,
            &(key.port_id), sizeof(uint32_t));
    cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID,
            cps_api_object_ATTR_T_BIN,
            &(key.local_id), sizeof(uint8_t));

    uint64_t val64;
    for (uint_t i=0; i< counter_ids.size(); i++) {
        BASE_QOS_PRIORITY_GROUP_STAT_t id = counter_ids[i];
        val64 = get_stats_by_type(&stats, id);
        cps_api_object_attr_add_u64(ret_obj, id, val64);
    }

    return  cps_api_ret_code_OK;

}
static cps_api_return_code_t nas_qos_cps_api_priority_group_set(
                                cps_api_object_t obj,
                                cps_api_object_t sav_obj)
{
    cps_api_object_t tmp_obj;

    cps_api_object_attr_t port_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_PORT_ID);
    cps_api_object_attr_t local_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID);

    if (port_id_attr == NULL ||
        local_id_attr == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key incomplete in the message\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint32_t switch_id = 0;
    uint_t port_id = cps_api_object_attr_data_u32(port_id_attr);
    uint8_t local_id = *(uint8_t *)cps_api_object_attr_data_bin(local_id_attr);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
            "Modify switch id %u, port id %u,  local_id %u \n",
            switch_id, port_id,  local_id);

    // If the port is not be initialized yet, initialize it in NAS
    nas_qos_port_priority_group_init(port_id);

    nas_qos_priority_group_key_t key;
    key.port_id = port_id;
    key.local_id = local_id;
    nas_qos_priority_group * priority_group_p = nas_qos_cps_get_priority_group(switch_id, key);
    if (priority_group_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                        "priority_group not found in switch id %u\n",
                        switch_id);
        return NAS_QOS_E_FAIL;
    }

    /* make a local copy of the existing priority_group */
    nas_qos_priority_group priority_group(*priority_group_p);

    cps_api_return_code_t rc = cps_api_ret_code_OK;
    if ((rc = nas_qos_cps_parse_attr(obj, priority_group)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Invalid information in the packet");
        return rc;
    }


    try {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Modifying switch id %u, port id %u priority_group info \n",
                switch_id, port_id);

        nas::attr_set_t modified_attr_list = priority_group.commit_modify(
                                    *priority_group_p, (sav_obj? false: true));


        // set attribute with full copy
        // save rollback info if caller requests it.
        // use modified attr list, current priority_group value
        if (sav_obj) {
            tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return cps_api_ret_code_ERR;
            }
            nas_qos_store_prev_attr(tmp_obj, modified_attr_list, *priority_group_p);
        }

        // update the local cache with newly set values
        *priority_group_p = priority_group;

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS priority_group Attr Modify error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS priority_group Modify Unexpected error code");
        return NAS_QOS_E_FAIL;
    }


    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_map_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj,
                                nas_qos_map_type_t map_type)
{
    uint_t switch_id;
    nas_obj_id_t map_id = 0;
    nas_qos_map_entry_key_t key;
    cps_api_return_code_t rc = cps_api_ret_code_OK;

    // check the request is on Map level or Entry level
    bool is_map_entry;
    if ((rc = qos_map_key_check(obj, map_type, &is_map_entry)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key error");
        return rc;
    }

    if (is_map_entry) {
        if ((rc = qos_map_entry_get_key(obj, map_type, switch_id, map_id, key)) != cps_api_ret_code_OK)
            return rc;

    }
    else {
        if ((rc = qos_map_get_switch_id(obj, map_type, switch_id)) != cps_api_ret_code_OK)
            return rc;

        // while creating map id, do not accept map-entry attributes.
        // Map-entry needs to be created separately.
        if (qos_map_entry_attr_is_set(obj, map_type)) {
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Inner list map entries must be created separately after map id is created\n");
            return NAS_QOS_E_INCONSISTENT;
        }
    }

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    try {
        if (!is_map_entry) {
            // Map id create

            nas_qos_map map(p_switch, map_type);

            map_id = p_switch->alloc_map_id();

            map.set_map_id(map_id);

            map.commit_create(sav_obj? false: true);

            p_switch->add_map(map);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new map %u\n",
                         map.get_map_id());

            // update obj with new map-id attr and key
            nas_attr_id_t map_id_obj_id = qos_map_map_id_obj_id(map_type);
            cps_api_set_key_data(obj,
                    map_id_obj_id,
                    cps_api_object_ATTR_T_U64,
                    &map_id, sizeof(uint64_t));

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
        else {
            // Map entry create
            nas_qos_map * p_map = p_switch->get_map(map_id);
            if (p_map == NULL) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu is not found", map_id);
                return NAS_QOS_E_FAIL;
            }

            if (p_map->get_type() != map_type) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu has mismatched type: %d vs expected %d",
                        map_id, p_map->get_type(), map_type);
                return NAS_QOS_E_INCONSISTENT;
            }

            nas_qos_map_entry entry(p_switch, map_id, map_type, key);

            if ((rc = nas_qos_cps_parse_attr(obj, entry)) != cps_api_ret_code_OK)
                return rc;

            //push a create to NPUs
            entry.commit_create(sav_obj? false: true);

            p_map->add_map_entry(key, entry);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                    "Created new map entry with key %u\n",
                         key.any);

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create error code: %d ",
                    (is_map_entry? "Map Entry": "Map"),
                    e.err_code);
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create Unexpected error code",
                    (is_map_entry? "Map Entry": "Map"));
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_map_set(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj,
                                nas_qos_map_type_t map_type)
{
    uint_t switch_id;
    nas_obj_id_t map_id;
    nas_qos_map_entry_key_t key;
    cps_api_return_code_t rc = cps_api_ret_code_OK;

    if ((rc = qos_map_entry_get_key(obj, map_type, switch_id, map_id, key)) != cps_api_ret_code_OK)
        return rc;

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Modify switch id %u, map id %u, key %u\n",
                    switch_id, map_id, key.any);

    nas_qos_map * map_p = nas_qos_cps_get_map(switch_id, map_id);
    if (map_p == NULL) {
        return NAS_QOS_E_FAIL;
    }

    map_entries  * entries = map_p->get_map_entries();
    if (entries == NULL) {
        return NAS_QOS_E_FAIL;
    }
    map_entries_iter_t it = entries->find(key.any);
    if (it == entries->end()) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Map entry does not exist in NAS\n");
        return NAS_QOS_E_KEY_VAL;
    }
    nas_qos_map_entry & entry = entries->at(key.any);

    /* make a local copy of the existing map entry*/
    nas_qos_map_entry old_entry(entry);

    if ((rc = nas_qos_cps_parse_attr(obj, entry)) != cps_api_ret_code_OK)
        return rc;

    if ((rc = nas_qos_cps_validate_set_attr_list(entry, map_type)) != cps_api_ret_code_OK)
        return rc;

    try {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Modifying map %u attr \n",
                     entry.get_map_id());

        if (entry.is_created_in_ndi() == false)
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "map is yet not created in ndi \n");

        nas::attr_set_t modified_attr_list = entry.commit_modify(old_entry, (sav_obj? false: true));

        // set attribute with full copy
        // save rollback info if caller requests it.
        // use modified attr list, current map value
        if (sav_obj) {
            cps_api_object_t tmp_obj;
            tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (tmp_obj == NULL) {
                return cps_api_ret_code_ERR;
            }

            nas_qos_store_prev_attr(tmp_obj, modified_attr_list, old_entry);
        }

        // update the local cache with newly set values
        old_entry = entry;

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS Map Attr Modify error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS Map Modify Unexpected error code");
        return NAS_QOS_E_FAIL;
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_map_delete(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj,
                                nas_qos_map_type_t map_type)
{
    uint_t switch_id;
    nas_obj_id_t map_id;
    nas_qos_map_entry_key_t key;
    cps_api_return_code_t rc = cps_api_ret_code_OK;

    // check the request is on Map level or Entry level
    bool is_map_entry;
    if ((rc = qos_map_key_check(obj, map_type, &is_map_entry)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key error");
        return rc;
    }

    if (is_map_entry) {
        if ((rc = qos_map_entry_get_key(obj, map_type, switch_id, map_id, key)) != cps_api_ret_code_OK)
            return rc;
    }
    else {
        if ((rc = qos_map_get_key(obj, map_type, switch_id, map_id)) != cps_api_ret_code_OK)
            return rc;
    }

    nas_qos_map * map_p = nas_qos_cps_get_map(switch_id, map_id);
    if (map_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " map id: %u not found\n",
                     map_id);

        return NAS_QOS_E_FAIL;
    }

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Deleting map %u on switch: %u\n",
                 map_id, switch_id);

    if (!is_map_entry) {
        // deleting a map requires deleting all map-entries first
        map_entries  * entries = map_p->get_map_entries();

        if (entries && entries->size() != 0) {
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                    "Map entry exists (%d), cannot delete the map\n",
                    entries->size());

            return NAS_QOS_E_INCONSISTENT;
        }
    }

    // delete
    try {
        if (!is_map_entry) {
            //Map level

            map_p->commit_delete(sav_obj? false: true);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Saving deleted map %u\n",
                         map_p->get_map_id());

            // save current map config for rollback if caller requests it.
            // use existing set_mask, existing config
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                nas_qos_store_prev_attr(tmp_obj, map_p->set_attr_list(), *map_p);
            }

            const_cast<nas_qos_switch &>(map_p->get_switch()).remove_map(map_id);
        }
        else {
            // map entry level
            map_entries  * entries = map_p->get_map_entries();
            if (entries == NULL)
                return NAS_QOS_E_FAIL;

            nas_qos_map_entry entry = entries->at(key.any);

            entry.commit_delete(sav_obj? false: true);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Saving deleted map %u entry, key %u\n",
                         map_p->get_map_id(), key.any);

            // save current map config for rollback if caller requests it.
            // use existing set_mask, existing config
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return NAS_QOS_E_FAIL;
                }
                nas_qos_store_prev_attr(tmp_obj, entry.set_attr_list(), entry);
            }

            map_p->del_map_entry(key);

        }
    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS Map Delete error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;
    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS Map Delete: Unexpected error");
        return NAS_QOS_E_FAIL;
    }


    return cps_api_ret_code_OK;
}