blob: 411da04f8dca179e55b603b65d72551e5b090055 [file] [log] [blame]
#include "cwmp/model.h"
#include "cwmp/xmlet.h"
#include "cwmp/log.h"
#include "cwmp_private.h"
int cwmp_model_copy_parameter_object(parameter_node_t * object_param, parameter_node_t * new_node, int instance_number)
{
parameter_node_t * tmp_node, *curr_node, *next_newnode;
// FUNCTION_TRACE();
if(!object_param || !new_node)
{
return CWMP_ERROR;
}
if(instance_number > 0)
{
memcpy(new_node, object_param, sizeof(parameter_node_t));
new_node->name = TRstrdup(TRitoa(instance_number));
new_node->child = NULL;
new_node->next_sibling = NULL;
for(tmp_node=object_param; tmp_node; tmp_node = tmp_node->next_sibling)
{
if(!tmp_node->next_sibling)
{
tmp_node->next_sibling = new_node;
break;
}
}
}
for(tmp_node=object_param->child, curr_node=NULL; tmp_node; tmp_node=tmp_node->next_sibling)
{
next_newnode = MALLOC(sizeof(parameter_node_t));
if(NULL == next_newnode)
{
cwmp_log_error("next_newnode malloc return NULL");
goto fail;
}
memset(next_newnode, 0, sizeof(parameter_node_t));
memcpy(next_newnode, tmp_node, sizeof(parameter_node_t));
next_newnode->name = TRstrdup(tmp_node->name);
next_newnode->parent = new_node;
next_newnode->child = NULL;
next_newnode->next_sibling = NULL;
if(!curr_node)
{
new_node->child = next_newnode;
}
else
{
curr_node->next_sibling = next_newnode;
}
curr_node = next_newnode;
cwmp_model_copy_parameter_object(tmp_node, next_newnode, 0);
}
return CWMP_OK;
fail:
//todo: if need to free other node ???
return CWMP_ERROR;
}
int cwmp_model_copy_parameter(parameter_node_t * param, parameter_node_t ** new_param, int instance_number)
{
int rv;
if(!param)
return CWMP_OK;
// FUNCTION_TRACE();
parameter_node_t * object_param = param->child; //object param like InternetGatewayDevice.WANDevice.{i}
parameter_node_t * new_node = MALLOC(sizeof(parameter_node_t));
if (!new_node)
{
cwmp_log_error("cwmp model copy parameter malloc new node failed ...\n");
return CWMP_ERROR;
}
new_node->name = NULL;
new_node->rw = 0;
new_node->type = 0;
new_node->value = NULL;
new_node->parent = param;
rv = cwmp_model_copy_parameter_object(object_param, new_node, instance_number);
*new_param = new_node;
if(rv != CWMP_OK)
{
cwmp_log_error("cwmp_model: copy parameter failed");
cwmp_model_free_parameter(new_node);
*new_param = NULL;
}
return rv;
}
int cwmp_model_free_parameter(parameter_node_t * param)
{
parameter_node_t *tmp_param = NULL;
parameter_node_t *next_param = NULL;
if(!param)
{
return CWMP_OK;
}
for(tmp_param=param->child; tmp_param; tmp_param=next_param)
{
next_param = tmp_param->next_sibling;
cwmp_model_delete_parameter(tmp_param);
}
FREE(param->name);
FREE(param);
return CWMP_OK;
}
int cwmp_model_delete_parameter(parameter_node_t * param)
{
parameter_node_t *tmp_param = NULL;
parameter_node_t *next_param = NULL;
parameter_node_t *parent = NULL;
// FUNCTION_TRACE();
if(!param)
{
return CWMP_OK;
}
parent = param->parent;
for(tmp_param=parent->child; tmp_param; tmp_param=tmp_param->next_sibling)
{
if(tmp_param->next_sibling == param)
{
tmp_param->next_sibling = param->next_sibling;
break;
}
}
return cwmp_model_free_parameter(param);
}
void* cwmp_model_find_func(model_func_t * func_list, int func_count, const char * func_name)
{
// FUNCTION_TRACE();
if(!func_name || func_count <= 0)
return NULL;
model_func_t * f = func_list;
int i;
// FUNCTION_TRACE();
for(i=0; i<func_count; i++, f++)
{
if(TRstrcasecmp(func_name, f->name) == 0)
{
return f->func;
}
}
return NULL;
}
int cwmp_model_create_parameter(parameter_node_t * param, xmlnode_t * node, model_func_t * func_list, int func_count, pool_t * pool);
int cwmp_model_init_parameter(parameter_node_t * param, xmlnode_t * node, model_func_t * func_list, int func_count, pool_t * pool)
{
// FUNCTION_TRACE();
param->get = NULL;
param->set = NULL;
param->notify = NULL;
param->add = NULL;
param->del = NULL;
param->refresh = NULL;
if(!node)
{
return CWMP_OK;
}
char *nodename = node->nodeName;
char *name, *value, *attr_nc;
if(! TRstrcasecmp(nodename, DEVICE_MODEL_OBJECT_NODE))
{
param->type = TYPE_OBJECT;
}
else
{
char * type = cwmp_xml_get_node_attribute(node, "type");
if(!type)
{
param->type = TYPE_STRING;
}
else
{
param->type = cwmp_get_type_value(type);
}
}
name = cwmp_xml_get_node_attribute(node, "name");
if(!name)
{
return CWMP_ERROR;
}
param->name = TRstrdup(name);
value = cwmp_xml_get_node_attribute(node, "rw");
if(value)
{
param->rw = TRatoi(value);
}
memset(&(param->attr), 0, sizeof(parameter_node_attr_t));
attr_nc = cwmp_xml_get_node_attribute(node, "noti_rw");
if(attr_nc)
{
param->attr.nc = TRatoi(attr_nc);
}
//value = cwmp_xml_get_node_attribute(node, "value");
//if(value)
//{
// param->value = pool_pstrdup(pool, value);
//}
if(param->type == TYPE_OBJECT)
{
value = cwmp_xml_get_node_attribute(node, "add_func");
if(value)
{
param->add = (parameter_add_handler_pt)cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
value = cwmp_xml_get_node_attribute(node, "del_func");
if(value)
{
param->del = (parameter_del_handler_pt)cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
value = cwmp_xml_get_node_attribute(node, "refresh_func");
if(value)
{
param->refresh = (parameter_refresh_handler_pt)cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
}
else
{
value = cwmp_xml_get_node_attribute(node, "get_func");
if(value)
{
param->get = (parameter_get_handler_pt) cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
value = cwmp_xml_get_node_attribute(node, "set_func");
if(value)
{
param->set = (parameter_set_handler_pt)cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
value = cwmp_xml_get_node_attribute(node, "notify_func");
if(value)
{
param->notify = (parameter_notify_handler_pt)cwmp_model_find_func(func_list, func_count, value);//dlsym(cwmp->dev_lib, value);;
}
}
return CWMP_OK;
}
int cwmp_model_create_child_parameter(parameter_node_t * child_param, xmlnode_t * child_node, model_func_t * func_list, int func_count, pool_t * pool)
{
// FUNCTION_TRACE();
cwmp_model_create_parameter(child_param, child_node, func_list, func_count, pool);
xmlnode_t * next_node = XmlNodeGetNextSibling(child_node);
parameter_node_t * last_sibling = child_param;
while(next_node)
{
parameter_node_t * next_param = (parameter_node_t *)pool_pcalloc(pool, sizeof(parameter_node_t));
if(NULL == next_param)
{
cwmp_log_error("next_param pool pcalloc return null");
return CWMP_ERROR;
}
cwmp_model_create_parameter(next_param, next_node, func_list, func_count, pool);
next_node = XmlNodeGetNextSibling(next_node);
next_param->parent = child_param;
last_sibling->next_sibling = next_param;
last_sibling = next_param;
}
return CWMP_OK;
}
int cwmp_model_create_parameter(parameter_node_t * param, xmlnode_t * node, model_func_t * func_list, int func_count, pool_t * pool)
{
// FUNCTION_TRACE();
cwmp_model_init_parameter(param, node, func_list, func_count, pool);
cwmp_log_debug("name %s: %p,%p", param->name, param->get, param->set);
xmlnode_t * child_node = XmlNodeGetFirstChild(node);
if(!child_node)
{
return CWMP_OK;
}
parameter_node_t * child_param = (parameter_node_t *)pool_pcalloc(pool, sizeof(parameter_node_t));
if(NULL == child_param)
{
cwmp_log_error("child_param pool_pcalloc return NULL");
return CWMP_ERROR;
}
cwmp_model_create_child_parameter(child_param, child_node, func_list, func_count, pool);
param->child = child_param;
child_param->parent = param;
return CWMP_OK;
}
static int cwmp_model_init_object(cwmp_t * cwmp, parameter_node_t *param)
{
parameter_node_t *node = NULL;
// FUNCTION_TRACE();
if(!param)
{
cwmp_log_error("input param is null");
return CWMP_ERROR;
}
if(param->type == TYPE_OBJECT && param->refresh)
{
param->refresh(cwmp, param, callback_register_task);
}
for (node = param->child; node; node = node->next_sibling)
{
cwmp_model_init_object(cwmp, node);
}
return CWMP_OK;
}
int cwmp_model_refresh_object(cwmp_t * cwmp, parameter_node_t *param, int flag, callback_register_func_t callback_reg)
{
parameter_node_t *node = NULL;
// FUNCTION_TRACE();
if(!param)
{
return CWMP_ERROR;
}
if(param->refresh && flag == 1)
{
param->refresh(cwmp, param, callback_reg);
}
for (node = param->child; node; node = node->next_sibling)
{
if(TRstrcmp(param->name, "{i}") != 0)
{
cwmp_model_refresh_object(cwmp, node, 1, callback_reg);
}
}
return CWMP_OK;
}
int cwmp_model_load_parameter(cwmp_t * cwmp, xmldoc_t * doc, model_func_t * func_list, int func_count)
{
pool_t * pool = cwmp->pool;
xmlnode_t * root_node;
xmlnode_t * model_node;
ASSERT(doc != NULL);
FUNCTION_TRACE();
root_node = XmlNodeGetFirstChild(& doc->node);
if (! root_node)
{
cwmp_log_error("xml document root is null!");
return CWMP_ERROR;
}
cwmp_log_debug("model load: xml node name is %s\n", root_node->nodeName);
model_node = cwmp_xml_get_child_with_name(root_node, DEVICE_MODEL_NODE);
if (model_node == NULL)
{
cwmp_log_error("device model node not found!");
return CWMP_ERROR;
}
parameter_node_t * root_param = pool_pcalloc(pool, sizeof(parameter_node_t));
if(NULL == root_param)
{
cwmp_log_error("root_param pool_pcalloc return NULL!");
return CWMP_ERROR;
}
cwmp_model_create_parameter(root_param, model_node, func_list, func_count, pool);
cwmp->root = root_param->child;
cwmp_log_info("init model object");
cwmp_model_init_object(cwmp, cwmp->root);
return CWMP_OK;
}
int cwmp_model_load_xml(cwmp_t * cwmp, const char * xmlfile, model_func_t * func_list, int func_count)
{
xmldoc_t * doc;
size_t xmllen, nread ;
FUNCTION_TRACE();
#if 0
FILE * fp = fopen(xmlfile, "rb");
if(!fp)
{
cwmp_log_error("xmlfile is NULL\n");
return CWMP_ERROR;
}
fseek(fp, 0, SEEK_END);
xmllen = ftell(fp);
if(xmllen <= 0)
{
cwmp_log_error("ftell return %d!\n", xmllen);
fclose(fp);
return CWMP_ERROR;
}
char * buf = (char*)MALLOC(sizeof(char)*(xmllen+1));
if(!buf)
{
cwmp_log_error("model load: malloc fail\n");
fclose(fp);
return CWMP_ERROR;
}
memset(buf, 0, sizeof(char)*(xmllen+1));
fseek(fp, 0, SEEK_SET);
nread = fread(buf, 1, xmllen, fp);
if(nread <= 0)
{
fclose(fp);
FREE(buf);
return CWMP_ERROR;
}
#else
struct stat statbuf;
if(stat(xmlfile,&statbuf) < 0)
{
cwmp_log_info("Get file len fail! file path:%s", xmlfile);
return CWMP_ERROR;
}
int size=statbuf.st_size;
char * buf = (char*)MALLOC(sizeof(char)*(size+1));
if(!buf)
{
cwmp_log_error("model load: malloc fail\n");
return CWMP_ERROR;
}
memset(buf, 0, sizeof(char)*(size+1));
FILE * fp = fopen(xmlfile, "rb");
if(!fp)
{
cwmp_log_error("xmlfile is NULL\n");
FREE(buf);
return CWMP_ERROR;
}
fseek(fp, 0, SEEK_SET);
nread = fread(buf, 1, size, fp);
if(nread <= 0)
{
fclose(fp);
FREE(buf);
return CWMP_ERROR;
}
#endif
buf[nread] = 0;
pool_t * pool = pool_create(POOL_DEFAULT_SIZE);
if(NULL == pool)
{
cwmp_log_error("pool create return null");
fclose(fp);
FREE(buf);
return CWMP_ERROR;
}
doc = XmlParseBuffer(pool, buf);
if (!doc)
{
cwmp_log_error("model load: create doc faild\n");
goto finish;
}
cwmp_model_load_parameter(cwmp, doc, func_list, func_count);
//cwmp_model_load_inform_info(cwmp, doc);
//cwmp_model_load_device_info(cwmp, doc);
finish:
fclose(fp);
// if(NULL != buf)
{
FREE(buf);
}
// if(NULL != pool)
{
pool_destroy(pool);
}
return CWMP_OK;
}