Added API to get supported datamodel

- New API "bbf_dm_get_supported_dm" to get the schema for all
  objects/params/events/commands at once
This commit is contained in:
Neeraj Bijalwan 2021-10-22 18:59:56 +05:30 committed by Vivek Kumar Dutta
parent 0d04be3ad4
commit aa17126d32
8 changed files with 199 additions and 42 deletions

View file

@ -74,6 +74,10 @@ int get_dm_type(char *dm_str)
return DMT_HEXBIN;
else if (strcmp(dm_str, DMT_TYPE[DMT_BASE64]) == 0)
return DMT_BASE64;
else if (strcmp(dm_str, DMT_TYPE[DMT_COMMAND]) == 0)
return DMT_COMMAND;
else if (strcmp(dm_str, DMT_TYPE[DMT_EVENT]) == 0)
return DMT_EVENT;
else
return DMT_STRING;

View file

@ -175,6 +175,44 @@ int dm_ctx_clean_sub(struct dmctx *ctx)
return dm_ctx_clean_custom(ctx, CTX_INIT_SUB);
}
int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type)
{
int fault =0;
// Load dynamic objects and parameters
if (strlen(path) == 0)
path = "Device.";
if (path[strlen(path) - 1] != '.')
return usp_fault_map(USP_FAULT_INVALID_PATH);
ctx->in_param = path;
dmentry_instance_lookup_inparam(ctx);
ctx->stop = false;
switch(schema_type) {
case ALL_SCHEMA:
ctx->isinfo = 1;
ctx->isevent = 1;
ctx->iscommand =1;
break;
case PARAM_ONLY:
ctx->isinfo = 1;
break;
case EVENT_ONLY:
ctx->isevent = 1;
break;
case COMMAND_ONLY:
ctx->iscommand =1;
break;
}
ctx->nextlevel = first_level;
fault = dm_entry_get_supported_dm(ctx);
return usp_fault_map(fault);
}
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2)
{
int fault = 0;
@ -227,13 +265,13 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1,
fault = dm_entry_operate(ctx);
break;
case CMD_USP_LIST_OPERATE:
fault = dm_entry_list_operates(ctx);
fault = dm_get_supported_dm(ctx, ctx->in_param, 0, COMMAND_ONLY);
break;
case CMD_USP_LIST_EVENT:
fault = dm_entry_list_events(ctx);
fault = dm_get_supported_dm(ctx, ctx->in_param, 0, EVENT_ONLY);
break;
case CMD_GET_SCHEMA:
fault = dm_entry_get_schema(ctx);
fault = dm_get_supported_dm(ctx, ctx->in_param, 0, PARAM_ONLY);
break;
case CMD_GET_INSTANCES:
if (!arg1 || (arg1 && string_to_bool(arg1, &ctx->nextlevel) == 0))

View file

@ -24,6 +24,13 @@ enum ctx_init_enum {
CTX_INIT_SUB
};
typedef enum {
ALL_SCHEMA,
PARAM_ONLY,
EVENT_ONLY,
COMMAND_ONLY
} schema_type_t;
int dm_ctx_init(struct dmctx *ctx, unsigned int instance_mode);
int dm_ctx_init_sub(struct dmctx *ctx, unsigned int instance_mode);
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2);
@ -36,6 +43,7 @@ int dm_ctx_clean(struct dmctx *ctx);
int dm_ctx_clean_sub(struct dmctx *ctx);
void load_dynamic_arrays(struct dmctx *ctx);
void free_dynamic_arrays(void);
int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type);
/**
* @brief dm_debug_browse_path

View file

@ -17,31 +17,38 @@ supervisorctl update
sleep 5
supervisorctl status all
echo "Running memory check on datamodel"
ret=0
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-usp-get.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -u get Device.
ret=$?
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-usp-operate.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -u list_operate
ret=$(( ret + $? ))
function run_valgrind()
{
echo "Running $@ in valgrind"
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-usp-get.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm $@
ret=$(( ret + $? ))
}
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-usp-schema.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -u get_schema
ret=$(( ret + $? ))
echo "Running memory check on datamodel"
run_valgrind -u get Device.
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-usp-instances.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -u instances Device.
ret=$(( ret + $? ))
# Test memory leak for get_supported_dm
run_valgrind -u get_info Device. 0
run_valgrind -u get_info Device. 1
run_valgrind -u get_info Device. 2
run_valgrind -u get_info Device. 3
run_valgrind -u get_info Device. 4
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-cwmp-get.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -c get Device.
ret=$?
run_valgrind -u list_operate
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-cwmp-operate.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -c list_operate
ret=$(( ret + $? ))
run_valgrind -u get_schema
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-cwmp-schema.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -c get_schema
ret=$(( ret + $? ))
run_valgrind -u instances Device.
valgrind --xml=yes --xml-file=/builds/iopsys/bbf/memory-report-cwmp-instances.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/bbf/test/bbf_test/bbf_dm -c instances Device.
ret=$(( ret + $? ))
run_valgrind -c get Device.
run_valgrind -c list_operate
run_valgrind -c get_schema
run_valgrind -c instances Device.
if [ "$ret" -ne 0 ]; then
echo "Memory check failed"

View file

@ -46,6 +46,8 @@ static int get_linker_check_obj(DMOBJECT_ARGS);
static int get_linker_check_param(DMPARAM_ARGS);
static int get_linker_value_check_obj(DMOBJECT_ARGS);
static int get_linker_value_check_param(DMPARAM_ARGS);
static int mobj_get_supported_dm(DMOBJECT_ARGS);
static int mparam_get_supported_dm(DMPARAM_ARGS);
int bbfdatamodel_type = BBFDM_BOTH;
@ -59,6 +61,8 @@ char *DMT_TYPE[] = {
[DMT_TIME] = "xsd:dateTime",
[DMT_HEXBIN] = "xsd:hexBinary",
[DMT_BASE64] = "xsd:base64",
[DMT_COMMAND] = "xsd:command",
[DMT_EVENT] = "xsd:event"
};
struct dm_permession_s DMREAD = {"0", NULL};
@ -81,6 +85,18 @@ static int plugin_obj_match(DMOBJECT_ARGS)
return FAULT_9005;
}
static int obj_match_supported_dm(DMOBJECT_ARGS)
{
if(node->matched)
return 0;
if(!dmctx->inparam_isparam && strstr(node->current_object,dmctx->in_param) == node->current_object) {
node->matched ++;
dmctx->findparam = 1;
return 0;
}
return 0;
}
static int plugin_leaf_match(DMOBJECT_ARGS)
{
char *str;
@ -209,10 +225,10 @@ static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf
if (!bbfdatamodel_matches(leaf->bbfdm_type))
continue;
if (dmctx->iscommand != (leaf->type == DMT_COMMAND) || dmctx->isevent != (leaf->type == DMT_EVENT))
continue;
if(!dmctx->isinfo){
if (dmctx->iscommand != (leaf->type == DMT_COMMAND) || dmctx->isevent != (leaf->type == DMT_EVENT))
continue;
}
snprintf(dm_browse_path, MAX_DM_PATH, "%s%s", parent_node->current_object, leaf->parameter);
err = dmctx->method_param(dmctx, parent_node, leaf->parameter, leaf->permission, leaf->type, leaf->getvalue, leaf->setvalue, data, instance);
if (dmctx->stop)
@ -230,10 +246,10 @@ static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf
if (!bbfdatamodel_matches(jleaf->bbfdm_type))
continue;
if (dmctx->iscommand != (jleaf->type == DMT_COMMAND) || dmctx->isevent != (jleaf->type == DMT_EVENT))
continue;
if(!dmctx->isinfo){
if (dmctx->iscommand != (jleaf->type == DMT_COMMAND) || dmctx->isevent != (jleaf->type == DMT_EVENT))
continue;
}
snprintf(dm_browse_path, MAX_DM_PATH, "%s%s", parent_node->current_object, jleaf->parameter);
err = dmctx->method_param(dmctx, parent_node, jleaf->parameter, jleaf->permission, jleaf->type, jleaf->getvalue, jleaf->setvalue, data, instance);
if (dmctx->stop)
@ -1328,6 +1344,79 @@ static int mparam_get_schema_name(DMPARAM_ARGS)
return 0;
}
/* ***********************
* get supported data model
* ***********************/
static int mobj_get_supported_dm(DMOBJECT_ARGS)
{
char *perm = permission->val;
char *refparam = node->current_object;
const char **unique_keys = NULL;
if(node->matched && dmctx->isinfo){
if (node->obj)
unique_keys = node->obj->unique_keys;
add_list_parameter(dmctx, refparam, perm, "xsd:object", (char *)unique_keys);
}
return 0;
}
static int mparam_get_supported_dm(DMPARAM_ARGS)
{
char *value = NULL;
char *refparam;
dmastrcat(&refparam, node->current_object, lastname);
if(node->matched) {
if(type == DMT_EVENT) {
if(dmctx->isevent) {
if (get_cmd)
(get_cmd)(refparam, dmctx, data, instance, &value);
add_list_parameter(dmctx, refparam, value, DMT_TYPE[type], NULL);
}
} else if(type == DMT_COMMAND) {
if(dmctx->iscommand) {
if (get_cmd)
(get_cmd)(refparam, dmctx, data, instance, &value);
//add_list_parameter(dmctx, refparam, value, permission->val, NULL);
add_list_parameter(dmctx, refparam, value, DMT_TYPE[type], permission->val);
}
}
else {
add_list_parameter(dmctx, refparam, permission->val, DMT_TYPE[type], NULL);
}
}
return 0;
}
int dm_entry_get_supported_dm(struct dmctx *ctx)
{
DMOBJ *root = ctx->dm_entryobj;
DMNODE node = {.current_object = ""};
int err;
ctx->inparam_isparam = 0;
ctx->isgetschema = 1;
ctx->findparam = 1;
ctx->stop =0;
ctx->checkobj = obj_match_supported_dm;
ctx->checkleaf = NULL;
ctx->method_obj = mobj_get_supported_dm;
ctx->method_param = mparam_get_supported_dm;
err = dm_browse(ctx, &node, root, NULL, NULL);
return err;
}
/* **************
* get_instances
* **************/
@ -1759,7 +1848,7 @@ static int mparam_list_events_name(DMPARAM_ARGS)
if (get_cmd)
(get_cmd)(full_param, dmctx, data, instance, &value);
add_list_parameter(dmctx, full_param, value, permission->val, NULL);
add_list_parameter(dmctx, full_param, value, DMT_TYPE[type], NULL);
return 0;
}

View file

@ -177,6 +177,7 @@ struct dmctx
bool isgetschema;
bool iscommand;
bool isevent;
bool isinfo;
};
typedef struct dmnode {
@ -433,6 +434,7 @@ void dmentry_instance_lookup_inparam(struct dmctx *ctx);
int dm_entry_get_value(struct dmctx *dmctx);
int dm_entry_get_name(struct dmctx *ctx);
int dm_entry_get_schema(struct dmctx *ctx);
int dm_entry_get_supported_dm(struct dmctx *ctx);
int dm_entry_get_instances(struct dmctx *ctx);
int dm_entry_add_object(struct dmctx *dmctx);
int dm_entry_delete_object(struct dmctx *dmctx);

View file

@ -3,6 +3,9 @@
#include <libbbfdm/dmentry.h>
#include <libbbfdm/dmbbfcommon.h>
#ifndef CMD_GET_INFO
#define CMD_GET_INFO (CMD_EXTERNAL_COMMAND + 1)
#endif
static int g_proto = BBFDM_USP;
typedef struct {
@ -19,9 +22,10 @@ cmd_t CMD[] = {
//{ CMD_DEL_OBJECT, "del"},
//{ CMD_USP_OPERATE, "operate"},
{ CMD_USP_LIST_OPERATE, "list_operate"},
//{ CMD_USP_LIST_EVENT, "list_event"},
{ CMD_USP_LIST_EVENT, "list_event"},
{ CMD_GET_SCHEMA, "get_schema"},
{ CMD_GET_INSTANCES, "instances"}
{ CMD_GET_INSTANCES, "instances"},
{ CMD_GET_INFO, "get_info"}
};
int get_cmd_from_str(char *str)
@ -53,19 +57,24 @@ int usp_dm_exec(int cmd, char *path, char *arg1, char *arg2)
struct dm_parameter *n;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
printf("cmd[%d], path[%s]", cmd, path);
printf("cmd[%d], path[%s]\n", cmd, path);
set_bbfdatamodel_type(g_proto);
dm_ctx_init(&bbf_ctx, 0);
fault = dm_entry_param_method(&bbf_ctx, cmd, path, arg1, arg2);
if(cmd == CMD_GET_INFO){
fault = dm_get_supported_dm(&bbf_ctx, path, false, atoi(arg1));
} else {
fault = dm_entry_param_method(&bbf_ctx, cmd, path, arg1, arg2);
}
if (!fault) {
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
printf(" %s::%s::%s\n", n->name, n->data, n->type);
}
} else {
printf("Fault %d", fault);
printf("Fault %d\n", fault);
}
dm_ctx_clean(&bbf_ctx);
@ -83,16 +92,16 @@ int main(int argc, char *argv[])
if (strcmp(argv[1], "-c") == 0)
g_proto = BBFDM_CWMP;
cmd = get_cmd_from_str(argv[2]);
if (argc > 3 && strlen(argv[3]))
param = argv[3];
if (argc > 4 && strlen(argv[4]))
value = argv[3];
if (argc > 4 && strlen(argv[4])){
value = argv[4];
}
usp_dm_exec(cmd, param, value, NULL);
free_dynamic_arrays();
}

View file

@ -976,12 +976,12 @@ static void test_api_bbfdm_valid_library_event(void **state)
list_for_each_entry(n, &ctx->list_parameter, list) {
if (strcmp(n->name, "Device.X_IOPSYS_EU_WakeUp!") == 0) {
assert_string_equal(n->type, "0");
assert_string_equal(n->type, "xsd:event");
assert_null(n->data);
}
if (strcmp(n->name, "Device.X_IOPSYS_EU_Boot!") == 0) {
assert_string_equal(n->type, "0");
assert_string_equal(n->type, "xsd:event");
event_args *args = (event_args *)n->data;
assert_non_null(args);
const char **event_param = args->param;