目录

tr069_oid.h

tr069_oid.c

demo.c


tr069_oid.h

/* Dependencies ------------------------------------------------------------------------------------------------------*/#ifndef __CPE_OID_REG_H
#define __CPE_OID_REG_H 1#include "easy_macros.h"
#include "rbtree.h"
#include "flog.h"/* Constants ---------------------------------------------------------------------------------------------------------*/#define TR069_OID_ITEM_SIZE 64  /* 参数路径单项的最大长度 Device.DeviceInfo.XXXX 中 DeviceInfo的最大长度 */
#define TR069_OID_SIZE      256 /* 参数路径的最大长度  ,Device.DeviceInfo.XXXX 的最大长度             *//* 参数节点类型 Device.DeviceInfo.1.A  A为叶子,其余为枝干          */
enum TR069_OID_ITEM_TYPE {TR069_OID_ITEM_TYPE_BRANCH, //枝干TR069_OID_ITEM_TYPE_LEAF    //叶子
};/* 参数节点Object类型 Device.DeviceInfo.1.A ^   Table 矢量,其余为Scalar 标量*/
enum TR069_OID_TYPE {TR069_OID_TYPE_TABLE,   //表TR069_OID_TYPE_SCALAR,  //标量
};/* Types -------------------------------------------------------------------------------------------------------------*/struct tr069_oid;
struct tr069_oid_leaf;/***  参数设置回调函数*  说明:*      当接口 "tr069_oid_set_parameter_values" 被调用时,该回调函数将被调用。*      该回调函数在参数注册时被参数树保存。使用 "tr069_oid_register" 注册。*  参数说明:*      node        被设置的节点,禁止直接修改该数据结构,会影响参数树的结构。*      isObj       参数路径中是否存在可创建/可删除节点,当存在时,其值为真值,否则为假。*                  如: 设置 Device.IP.Interface.1.IPv4Address.2.IPAddress,该值为真。*      nObj        参数路径中出现的实例号个数。当 isObj 为真时,该参数可用。*                  当参数为 Device.IP.Interface.1.IPv4Address.2.IPAddress 时,nObj==2.*      ObjInsNums  参数路径中出现的实例号数组。当 isObj 为真时,该参数可用。*                  当参数为 Device.IP.Interface.1.IPv4Address.2.IPAddress 时,ObjInsNums[0]==1, ObjInsNums[1] = 2.*      argc        用户注册参数个数,该参数为 "tr069_oid_register" 注册时填写 的 "set_argc"。*      argv        用户注册参数,该参数为 "tr069_oid_register" 注册时填写 的 "set_argv"。*/
typedef void (*tr069_oid_set_fn_t)(struct tr069_oid *node, bool isObj, int nObj, int ObjInsNums[], int argc, void *argv[]);/***  目标创建回调函数*  说明:*      当接口 "tr069_oid_add_object" 被调用时,该回调函数将被调用。*      该回调函数在参数注册时被参数树保存。使用 "tr069_oid_register" 注册。*  参数说明:*      node        被添加的节点,禁止直接修改该数据结构,会影响参数树的结构。*                  当 注册 "Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress" ,可使用 "tr069_oid_add_object" 接口添加实例*                  当 tr069_oid_add_object(参数树, Device.IP.Interface.)被调用时,注册的该回调函数将被调用。*      currObjIdx  当前添加的实例参数路径中的实例号位置,起始值为 1。*                  若支持添加object的参数路径为 Device.A.{i}.{i}.{i}.{i}.{i}.{i}.{i}.{i}.name*                  添加一个实例 Device.A. 时, currObjIdx==1*                  添加一个实例 Device.A.1. 时, currObjIdx==2*                  添加一个实例 Device.A.1.1. 时, currObjIdx==3*                  ...*                  添加一个实例 Device.A.1.1.1.1.1.1.1. 时, currObjIdx==8**      nPrevObj        创建的当前参数路径之前中出现的实例号个数。*      prevObjInsNums  创建的当前参数路径之前中出现的实例号。**      参数 nPrevObj 和 prevObjInsNums 的例子:*                  AddObject: Device.A.        nPrevObj==0,    prevObjInsNums=NULL*                  AddObject: Device.A.1.      nPrevObj==1,    prevObjInsNums={1,}*                  AddObject: Device.A.1.1.    nPrevObj==2,    prevObjInsNums={1,1,}*                      ...*                  AddObject: Device.A.1.1.1.2.3.1.1. nPrevObj==8, prevObjInsNums={1,1,1,2,3,1,1,}**      argc        用户注册参数个数,该参数为 "tr069_oid_register" 注册时填写 的 "add_argc"。*      argv        用户注册参数,该参数为 "tr069_oid_register" 注册时填写 的 "add_argv"。*      ObjInsNum   生成的实例号。 1,2,3,4,5...*      aliasName   别名:TR069协议规定。**  返回值:    *      AddObject成功,生成实例号填入 ObjInsNum , 并返回真值。否则返回假。*/
typedef bool (*tr069_oid_addobj_fn_t)(struct tr069_oid *node, int currObjIdx, int nPrevObj, int prevObjInsNums[], int argc, void *argv[], int *ObjInsNum, char aliasName[TR069_OID_ITEM_SIZE]);/***  目标删除回调函数*  说明:*      当接口 "tr069_oid_delete_object" 被调用时,该回调函数将被调用。*      该回调函数在参数注册时被参数树保存。使用 "tr069_oid_register" 注册。*  参数说明:(见AddObject接口回调   tr069_oid_addobj_fn_t        )*      node        被删除的节点,禁止直接修改该数据结构,会影响参数树的结构。*      nObj        参数路径中出现的实例号个数。当 isObj 为真时,该参数可用。*                  当参数为 Device.IP.Interface.1.IPv4Address.2.IPAddress 时,nObj==2.*      ObjInsNums  参数路径中出现的实例号数组。当 isObj 为真时,该参数可用。*                  当参数为 Device.IP.Interface.1.IPv4Address.2.IPAddress 时,ObjInsNums[0]==1, ObjInsNums[1] = 2.*      argc        用户注册参数个数,该参数为 "tr069_oid_register" 注册时填写 的 "set_argc"。*      argv        用户注册参数,该参数为 "tr069_oid_register" 注册时填写 的 "set_argv"。*/
typedef bool (*tr069_oid_delobj_fn_t)(struct tr069_oid *node, int nObj, int ObjInsNums[], int argc, void *argv[]);/* TR069 OID树节点结构 */
struct tr069_oid {char oidNameItem[TR069_OID_ITEM_SIZE];/* 参数路径中的单项名称 */char oidAliasNameItem[TR069_OID_ITEM_SIZE];/* 参数单项名称的别名 */unsigned int oidInstanceNum; /* 实例号 */enum TR069_OID_ITEM_TYPE node_type; /* 节点单项类型:枝干 或 叶子 */enum TR069_OID_TYPE oid_type; /* 目标节点类型:是否可创建,表或标量 */int writeable; //是否可写/* 保存下一级 */rt_rbtree_t child;  //该节点下的下一级节点//A.B1.C.D//A.B2.C.D//A.B3.C.D//A.child => B1, B2, B3struct tr069_oid *father;   //所有节点指向该节点的父节点// A.B.C.D => D.father = &C;struct tr069_oid_leaf *leaf_value;    //每个a.b.c.d的叶子"d"需要malloc该块内存struct tr069_oid_obj_opt *obj_operation; //每个A.{i}.B 中的"{i}"需要malloc该块内存//并将注册时的参数列表填入该块内存
};/* TR069 OID树叶子节点数据:供用户使用 */
struct tr069_oid_leaf {tr069_oid_set_fn_t set_fn;  /* 参数设置回调函数,在注册参数时提供 */int set_argc;/* 参数设置用户参数个数 */void **set_argv;/* 参数设置用户参数 */char value[TR069_OID_SIZE];/* 参数值 */int Notification; /* 参数通知级别:参考TR069协议 *///check in ParameterAttributeStruct, "GetParameterAttribute"
};/* 目标创建删除用户回调函数 */
struct tr069_oid_obj_opt {/* 目标创建 */tr069_oid_addobj_fn_t add_fn;int add_argc;void **add_argv;/* 目标删除 */tr069_oid_delobj_fn_t del_fn;int del_argc;void **del_argv;
};/* TR069 OID路径名结构 */
struct tr069_oid_names {int count;/* 获取的参数名个数 */ParameterInfoStruct *NameList;/* 参数名 */
};/* TR069 OID 值结构 */
struct tr069_oid_values {int count;/* 获取的参数值的个数 */ParameterValueStruct *ValueList;/* 参数值 */
};/* TR069 OID 属性值结构 */
struct tr069_oid_attrs {int count;/* 参数属性个数 */ParameterAttributeStruct *AttrList;/* 参数属性 */
};/* Macros ------------------------------------------------------------------------------------------------------------*/#define TR069_OID_GetParamNamesShow(tree, str, nextlevel, printfn) \{\printfn("\n--------------GetParamNames %s--------------\n", str); \struct tr069_oid_names *__names = tr069_oid_get_parameter_names(tree, str, nextlevel);\int __inames;\for(__inames=0;__inames<__names->count;__inames++) {\printfn(">> %d/%d:{ \"parameter\": \"%s\", \"writable\": \"%d\" }\n", \__inames, __names->count, __names->NameList[__inames].Name, __names->NameList[__inames].Writable);\}\printfn("------------------------------------------------------\n");\tr069_oid_get_parameter_names_free(__names);\}#define TR069_OID_GetParamValuesShow(tree, str, printfn) \{\printfn("\n-----------GetParamValues %s-----------\n", str); \struct tr069_oid_values *__values = tr069_oid_get_parameter_values(tree, str);\int __ivalues;\for(__ivalues=0;__ivalues<__values->count;__ivalues++) {\printfn(">> %d/%d:{ \"parameter\": \"%s\", \"value\": \"%s\" }\n", \__ivalues, __values->count, __values->ValueList[__ivalues].Name, __values->ValueList[__ivalues].Value);\}\printfn("------------------------------------------------------\n");\tr069_oid_get_parameter_values_free(__values);\}#define TR069_OID_GetParamAttributeShow(tree, str, printfn) \{\printfn("\n------------GetParamAttribute %s------------\n", str); \struct tr069_oid_attrs *__attrs = tr069_oid_get_parameter_attributes(tree, str);\int __iattrs;\for(__iattrs=0;__iattrs<__attrs->count;__iattrs++) {\printfn(">> %d/%d:{ \"parameter\": \"%s\", \"notification\": \"%d\" }\n", \__iattrs, __attrs->count, __attrs->AttrList[__iattrs].Name, __attrs->AttrList[__iattrs].Notification);\}\printfn("------------------------------------------------------\n");\tr069_oid_get_parameter_attributes_free(__attrs);\}/* Globals -----------------------------------------------------------------------------------------------------------*//* Functions ---------------------------------------------------------------------------------------------------------*/
/***  参数树的创建/初始化 与 摧毁*/
rt_rbtree_t tr069_oid_tree_create();
void tr069_oid_tree_destroy(rt_rbtree_t oid_root);/***  参数注册*  函数说明:*      当使用 接口 tr069_oid_tree_create 创建参数树后,可以使用该接口注册一个参数。*  函数参数列表:*      oid_root        参数树*      ParameterPath   一个完整的参数路径, 如 "Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress"*      writeable       是否可写(0-不可写,1-可写),值得一提的是,该值只决定了 ParameterPath 路径规定的最后一个参数,而其他参数的可写性,*                      由接口内部决定,如 参数 "Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress" 的可写性为:*                      可写的有:         Interface IPv4Address *                      不可写的有:  Device IP {i} *                      由参数 writeable 决定 IPAddress 是否可写*      default_value   一个默认值,字符串形式*      Notification    通知级别,参考TR069协议中的 ParameterAttributeStruct 结构,取值 0~6*      set_fn          参考 tr069_oid_set_fn_t *      set_argc        set_fn 的入参*      set_argv        set_fn 的入参*      add_fn          参考 tr069_oid_addobj_fn_t *      add_argc        add_fn 的入参*      add_argv        add_fn 的入参*      del_fn          参考 tr069_oid_delobj_fn_t *      del_argc        del_fn 的入参*      del_argv        del_fn 的入参*/
int tr069_oid_register(rt_rbtree_t oid_root, char ParameterPath[TR069_OID_SIZE], int writeable, char default_value[TR069_OID_SIZE], int Notification,tr069_oid_set_fn_t set_fn, int set_argc, void *set_argv[],tr069_oid_addobj_fn_t add_fn, int add_argc, void *add_argv[],tr069_oid_delobj_fn_t del_fn, int del_argc, void *del_argv[]);/***  参数轮询*  函数说明:*      该参数将轮询此树的所有节点, display 将被调用。 遗憾的是, oid 将不被允许修改, 否则会捣乱树结构, oid只读。*  函数参数列表:*      oid_root    参数树*      display     轮询树是被调用的回调函数*                  oid 参数节点*                  arg 用户数据*      arg         用户数据, 将被透传至 display 的参数列表中*/
void tr069_oid_display(rt_rbtree_t oid_root, void (*display)(struct tr069_oid *oid, void *arg), void *arg);/***  参数名获取*  函数说明:*      GetParameterNames *  函数参数列表:*      oid_root    参数树*      pathPrefix  参数路径, 如 "Device."*      nextlevel   是否只获取下一级参数节点, 取值0或1,参考标准协议。*  返回值   *      结构 struct tr069_oid_names 该结构需要使用 tr069_oid_get_parameter_names_free 进行释放*      */
struct tr069_oid_names *tr069_oid_get_parameter_names(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE], int nextlevel);
void tr069_oid_get_parameter_names_free(struct tr069_oid_names *oid_names);/***  参数获取*  函数说明:*      GetParameterValues*  函数参数列表:*      oid_root    参数树*      pathPrefix  参数路径, 如 "Device."*  返回值*      结构    struct tr069_oid_values   , 需要使用 tr069_oid_get_parameter_values_free 释放内存*      *      */
struct tr069_oid_values *tr069_oid_get_parameter_values(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE]);
void tr069_oid_get_parameter_values_free(struct tr069_oid_values *oid_values);/***  参数设置*  函数说明:*      SetParameterValues*  函数参数列表:*      oid_root    参数树*      paramPath   参数的完整路径, 如 "Device.IPsec.Enable"*      paramValue  参数值, 字符串*  返回值*      结构 struct tr069_oid, 很遗憾, 这个返回值不许修改,否则会损坏树结构。*/
struct tr069_oid *tr069_oid_set_parameter_values(rt_rbtree_t oid_root, char paramPath[TR069_OID_SIZE], char paramValue[TR069_OID_SIZE]);/***  参数属性获取*  函数说明:*      GetParamAttributes*  函数参数列表:*      oid_root    参数树*      pathPrefix  参数路径, 如 "Device."*  返回值*      结构      struct tr069_oid_attrs, 需要使用 tr069_oid_get_parameter_attributes_free 释放内存*/
struct tr069_oid_attrs *tr069_oid_get_parameter_attributes(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE]);
void tr069_oid_get_parameter_attributes_free(struct tr069_oid_attrs *oid_attrs);/***  参数属性设置*  函数说明:*      SetParamAttributes*  函数参数列表:*      oid_root    参数树*      paramPath   参数的完整路径, 如 "Device.IPsec.Enable"*      Notification    通知级别,参考TR069协议中的 ParameterAttributeStruct 结构,取值 0~6*  返回值*      结构 struct tr069_oid, 很遗憾, 这个返回值不许修改,否则会损坏树结构。*/
struct tr069_oid *tr069_oid_set_parameter_attributes(rt_rbtree_t oid_root, char paramPath[TR069_OID_SIZE], int Notification);/***  目标实例添加和删除*  函数说明:*      AddObject DeleteObject*  函数参数列表:*      oid_root        参数树*      ParameterPath   参数路径, 如 注册了 Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress*                      此时 Device.IP.Interface. 是支持 AddObject 的,当 调用了 tr069_oid_add_object , 参见注册接口:*                      tr069_oid_register 的 add_fn 将被调用, 需要生成   实例号。*      pathPrefix      参数路径, 如添加了目标实例 1,-> 可使用 "Device.IP.Interface.1." 对其进行删除, 可调用该接口删除该实例。*  返回值*      tr069_oid_add_object 成功返回实例号, 失败返回 VOS_ERROR*      */
int tr069_oid_add_object(rt_rbtree_t oid_root, char ParameterPath[TR069_OID_SIZE]);
int tr069_oid_delete_object(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE]);#endif //__CPE_OID_REG_H

tr069_oid.c


/* Dependencies ------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>#include "tr069_oid.h"/* Types -------------------------------------------------------------------------------------------------------------*//* Constants ---------------------------------------------------------------------------------------------------------*/
#define TABLE_NODE "TABLE"/* Macros ------------------------------------------------------------------------------------------------------------*/
/* Globals -----------------------------------------------------------------------------------------------------------*//* Functions ---------------------------------------------------------------------------------------------------------*//* 正则化检验参数字符串是否合法 *  例如:Device.FaultMgmt.ExpeditedEvent.{2}.PerceivedSeverity*/
static int _unused oid_string_pattern_check(char *oidString)
{
#define OID_REGEX_PATTERN "^Device\\.[a-zA-Z]\\w+\\.(([a-zA-Z0-9]\\w+|\\{[0-9a-z]\\})\\.)*[a-zA-Z0-9]\\w+"
//                           ^Device\\.[a-zA-Z]\\w+\\.(([a-zA-Z]\\w+|\\{[0-9a-z]\\})\\.)*[a-zA-Z0-9]\\w+int ret = VOS_ERROR;int status = 0;int flag = REG_EXTENDED;regmatch_t pmatch[1];const size_t nmatch = 1;regex_t reg;const char *pattern = OID_REGEX_PATTERN;regcomp(&reg, pattern, flag);status = regexec(&reg, oidString, nmatch, pmatch, 0);if(status == REG_NOMATCH){ret = VOS_ERROR;}else if(status == 0){ret = VOS_OK;}regfree(&reg);return ret;
}/* OID 节点项的对比函数 */
static int _unused __tr069_oid_node_cmp(void *d1, void *d2)
{struct tr069_oid *oid1 = d1, *oid2 = d2;char *oidName1 = oid1->oidNameItem;char *oidName2 = oid2->oidNameItem;if(strncmp(oidName1, oidName2, TR069_OID_ITEM_SIZE) > 0) return GT;else if(strncmp(oidName1, oidName2, TR069_OID_ITEM_SIZE) == 0) return EQ;else if(strncmp(oidName1, oidName2, TR069_OID_ITEM_SIZE) < 0) return LT;return EQ;
}/* OID 树的创建 */
static void _unused __tr069_oid_tree_create(rt_rbtree_t *tree)
{*tree = rt_rbtree_init_nonmalloc("OIDTree", __tr069_oid_node_cmp);
}/* 初始化OID的树的根 */
rt_rbtree_t tr069_oid_tree_create()
{rt_rbtree_t oid_root;__tr069_oid_tree_create(&oid_root);return oid_root;
}/* 获取参数名中Item的项数*  例如:Device.FaultMgmt.ExpeditedEvent.{2}.PerceivedSeverity 返回 5*/
static int _unused __get_N_item(char path[TR069_OID_SIZE])
{int iItem = 0;int iChar = 0;int len = strlen(path);while(path[iChar] != '\0' && iChar <= len) {while(path[iChar] != '.' && path[iChar] != '\0') {iChar++;}iItem++;iChar++;}return iItem;
}/* 获取参数名中某一项的 名称*  例如:*      ParameterPath = Device.FaultMgmt.ExpeditedEvent.{2}.PerceivedSeverity *      iItem = 2*   那么, oidNameItem = FaultMgmt*/
static int _unused __get_I_item_name(char path[TR069_OID_SIZE], int iItem, char oidNameItem[TR069_OID_ITEM_SIZE])
{int __iItem = 0;int iChar = 0;int len = strlen(path);while(path[iChar] != '\0' && iChar <= len) {memset(oidNameItem, 0, TR069_OID_ITEM_SIZE);int i = 0;while(path[iChar] != '.' && path[iChar] != '\0') {oidNameItem[i++] = path[iChar++];}oidNameItem[i] = '\0';__iItem++;iChar++;if(__iItem == iItem) {return iItem;}}return -1;
}/* 向树种递归添加节点,若不存在该节点则创建 */
static struct tr069_oid * _unused
__oid_tree_add_node(struct tr069_oid *father, rt_rbtree_t tree, char currPath[TR069_OID_SIZE], int writeable, char *defaultValue, int Notification, tr069_oid_set_fn_t set_fn, int set_argc, void *set_argv[],tr069_oid_addobj_fn_t add_fn, int add_argc, void *add_argv[],tr069_oid_delobj_fn_t del_fn, int del_argc, void *del_argv[])
{/* OID名称 */char oidNameItem[TR069_OID_ITEM_SIZE] = {0};char oidNameItemTmp[TR069_OID_ITEM_SIZE] = {0};memset(oidNameItem, 0, TR069_OID_ITEM_SIZE);memset(oidNameItemTmp, 0, TR069_OID_ITEM_SIZE);/* 获取项数 */int nItem = __get_N_item(currPath);__get_I_item_name(currPath, 1, oidNameItem);/* 解析出第一项名称 *//* 是否为“{3}”类型   */int oidTableNode = 0;if(oidNameItem[0] == '{') {oidTableNode = 1;if(!add_fn || !del_fn) {vos_err_print("Error: Must fill 'add_fn' and 'del_fn' when register a addable object OID.\n");return NULL;}}/* 申请内存 */struct tr069_oid *new_node = malloc(sizeof(struct tr069_oid));VOS_MemZero(new_node->oidNameItem, TR069_OID_ITEM_SIZE);VOS_MemZero(new_node->oidAliasNameItem, TR069_OID_ITEM_SIZE);new_node->obj_operation = NULL;new_node->leaf_value = NULL;new_node->father = father;if(oidTableNode) {VOS_Snprintf(oidNameItemTmp, TR069_OID_ITEM_SIZE, TABLE_NODE);new_node->father->writeable = 1;new_node->oid_type = TR069_OID_TYPE_TABLE;new_node->obj_operation = malloc(sizeof(struct tr069_oid_obj_opt ));new_node->obj_operation->add_fn = add_fn;new_node->obj_operation->add_argc = add_argc;new_node->obj_operation->add_argv = add_argv;new_node->obj_operation->del_fn = del_fn;new_node->obj_operation->del_argc = del_argc;new_node->obj_operation->del_argv = del_argv;} else {VOS_StrCpy(oidNameItemTmp, oidNameItem);if(nItem == 1) {new_node->writeable = writeable; //叶子new_node->node_type = TR069_OID_ITEM_TYPE_LEAF;} else {new_node->writeable = 0; //枝干不可写new_node->node_type = TR069_OID_ITEM_TYPE_BRANCH;}new_node->oid_type = TR069_OID_TYPE_SCALAR;}VOS_StrCpy(new_node->oidNameItem, oidNameItemTmp);new_node->oidInstanceNum = 0;int exist_flag = 0;rt_rbtree_node_t *node = rt_rbtree_search(tree, new_node);if( node ) { //已存在的节点if(oidTableNode) {free(new_node->obj_operation);}free(new_node);new_node = node->data;new_node->father = father;if(nItem != 1) {new_node->node_type = TR069_OID_ITEM_TYPE_BRANCH;} else if(nItem == 1) {new_node->writeable = writeable; //叶子new_node->node_type = TR069_OID_ITEM_TYPE_LEAF;}exist_flag = 1;} else {    //不存在该节点exist_flag = 0;__tr069_oid_tree_create(&new_node->child);rt_rbtree_insert(tree, new_node, sizeof(struct tr069_oid));}/* 若为最后一项:叶子节点 */if(nItem == 1) {if(exist_flag) return NULL;new_node->node_type = TR069_OID_ITEM_TYPE_LEAF;new_node->writeable = writeable; //只设置最后一个叶子节点new_node->leaf_value = malloc(sizeof(struct tr069_oid_leaf));VOS_StrnCpy(new_node->leaf_value->value, defaultValue, TR069_OID_SIZE);new_node->leaf_value->Notification = Notification;new_node->leaf_value->set_fn = set_fn;new_node->leaf_value->set_argc = set_argc;new_node->leaf_value->set_argv = set_argv;return new_node;/* 非叶子节点,递归添加 */} else {new_node->node_type = TR069_OID_ITEM_TYPE_BRANCH;new_node->leaf_value = NULL;
//        new_node->writeable = 0; //枝干不可写int iChar = 0;while(currPath[iChar++] != '.');__oid_tree_add_node(new_node, new_node->child, &currPath[iChar], writeable, defaultValue, Notification, set_fn, set_argc, set_argv, add_fn, add_argc, add_argv, del_fn, del_argc, del_argv);}return NULL;
}/* 获取路径下的项 */
static struct tr069_oid _unused* __oid_tree_find_oid_path(rt_rbtree_t tree, char currPath[TR069_OID_SIZE])
{char oidNameItem[TR069_OID_ITEM_SIZE] = {0};memset(oidNameItem, 0, TR069_OID_ITEM_SIZE);int nItem = __get_N_item(currPath);__get_I_item_name(currPath, 1, oidNameItem);struct tr069_oid *find_node = malloc(sizeof(struct tr069_oid));memset(find_node->oidNameItem, 0, TR069_OID_ITEM_SIZE);memset(find_node->oidAliasNameItem, 0, TR069_OID_ITEM_SIZE);//    VOS_MemZero(find_node->ParameterPath, TR069_OID_SIZE);VOS_StrCpy(find_node->oidNameItem, oidNameItem);rt_rbtree_node_t *node = rt_rbtree_search(tree, find_node);if( node ) { //存在该节点free(find_node);find_node = node->data;if(nItem == 1) {return find_node;} else {int iChar = 0;while(currPath[iChar++] != '.');return __oid_tree_find_oid_path(find_node->child, &currPath[iChar]);}}return NULL;
}/* 递归获取树下面所有的节点数 */
static int _unused __oid_tree_subcount(rt_rbtree_t tree, int nextlevel)
{int count = 0;struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(tree); node; node=rt_rbtree_getnext(node)) {this_oid = node->data;if(VOS_StrnCmp(TABLE_NODE, this_oid->oidNameItem, TR069_OID_ITEM_SIZE) == 0) continue;count++;if(!nextlevel) {count += __oid_tree_subcount(this_oid->child, nextlevel);}}return count;
}/* 递归获取树下面所有的叶子节点数 */
static int _unused __oid_tree_subleafcount(rt_rbtree_t tree)
{int count = 0;struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(tree); node; node=rt_rbtree_getnext(node)) {this_oid = node->data;if(VOS_StrnCmp(TABLE_NODE, this_oid->oidNameItem, TR069_OID_ITEM_SIZE) == 0) continue;if(this_oid->node_type == TR069_OID_ITEM_TYPE_LEAF) {count++;continue;}count += __oid_tree_subleafcount(this_oid->child);}return count;
}/* 递归获取树下面所有的节点数 */
static void __tr069_oid_oids_get(struct tr069_oid *oid, ParameterInfoStruct *NameList, int *ioid, int nextlevel)
{struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(oid->child); node; node=rt_rbtree_getnext(node), this_oid = NULL) {this_oid = node->data;if(VOS_StrnCmp(TABLE_NODE, this_oid->oidNameItem, TR069_OID_ITEM_SIZE) == 0) continue;VOS_MemZero(NameList[*ioid].Name, sizeof(char)*TR069_OID_SIZE);NameList[*ioid].Writable = this_oid->writeable;char tmp[TR069_OID_SIZE] = {0};struct tr069_oid *tmp_oid = NULL;for(tmp_oid = this_oid; tmp_oid; tmp_oid = tmp_oid->father) {VOS_MemZero(tmp, TR069_OID_SIZE);VOS_StrCat(tmp, NameList[*ioid].Name);VOS_Sprintf(NameList[*ioid].Name, "%s%s%s", tmp_oid->oidNameItem, tmp_oid->node_type==TR069_OID_ITEM_TYPE_LEAF?"":".", tmp);}(*ioid)++;if(!nextlevel && this_oid) { //如果不止获取下一级节点__tr069_oid_oids_get(this_oid, NameList, ioid, nextlevel);}}
}/* 递归获取树下面所有的叶子节点数 */
static void __tr069_oid_oids_getleaf_value(struct tr069_oid *oid, ParameterValueStruct *ValuesList, int *ioid)
{struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(oid->child); node; node=rt_rbtree_getnext(node), this_oid = NULL) {this_oid = node->data;if(VOS_StrnCmp(TABLE_NODE, this_oid->oidNameItem, TR069_OID_ITEM_SIZE) == 0) continue;if(this_oid->node_type == TR069_OID_ITEM_TYPE_LEAF) {char tmp[TR069_OID_SIZE] = {0};struct tr069_oid *tmp_oid = NULL;for(tmp_oid = this_oid; tmp_oid; tmp_oid = tmp_oid->father) {VOS_MemZero(tmp, TR069_OID_SIZE);VOS_StrCat(tmp, ValuesList[*ioid].Name);VOS_Sprintf(ValuesList[*ioid].Name, "%s%s%s", tmp_oid->oidNameItem, tmp_oid->node_type==TR069_OID_ITEM_TYPE_LEAF?"":".", tmp);}
//            printf("%s: %s\n", tmp_oid->oidNameItem, oid_values->ValueList[i].Name);VOS_StrnCpy(ValuesList[*ioid].Value, this_oid->leaf_value->value, TR069_OID_SIZE);(*ioid)++;continue;} else {__tr069_oid_oids_getleaf_value(this_oid, ValuesList, ioid);}}
}/* 递归获取树下面所有的叶子节点数 */
static void __tr069_oid_oids_getleaf_attr(struct tr069_oid *oid, ParameterAttributeStruct *AttrsList, int *ioid)
{struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(oid->child); node; node=rt_rbtree_getnext(node), this_oid = NULL) {this_oid = node->data;if(VOS_StrnCmp(TABLE_NODE, this_oid->oidNameItem, TR069_OID_ITEM_SIZE) == 0) continue;if(this_oid->node_type == TR069_OID_ITEM_TYPE_LEAF) {char tmp[TR069_OID_SIZE] = {0};struct tr069_oid *tmp_oid = NULL;for(tmp_oid = this_oid; tmp_oid; tmp_oid = tmp_oid->father) {VOS_MemZero(tmp, TR069_OID_SIZE);VOS_StrCat(tmp, AttrsList[*ioid].Name);VOS_Sprintf(AttrsList[*ioid].Name, "%s%s%s", tmp_oid->oidNameItem, tmp_oid->node_type==TR069_OID_ITEM_TYPE_LEAF?"":".", tmp);}
//            printf("%s: %s\n", tmp_oid->oidNameItem, oid_values->ValueList[i].Name);AttrsList[*ioid].Notification = this_oid->leaf_value->Notification;(*ioid)++;continue;} else {__tr069_oid_oids_getleaf_attr(this_oid, AttrsList, ioid);}}
}/* 注册一个参数 */
int tr069_oid_register(rt_rbtree_t oid_root, char absolutePath[TR069_OID_SIZE], int writeable, char default_value[TR069_OID_SIZE], int Notification,tr069_oid_set_fn_t set_fn, int set_argc, void *set_argv[],tr069_oid_addobj_fn_t add_fn, int add_argc, void *add_argv[],tr069_oid_delobj_fn_t del_fn, int del_argc, void *del_argv[])
{if(VOS_OK != oid_string_pattern_check(absolutePath)) {vos_err_print("TR069 Notmatch: %s\n", absolutePath);return VOS_ERROR;}if(!default_value ) {//必须有默认值vos_err_print("TR069 must need default value.\n");return VOS_ERROR;}struct tr069_oid *oid = __oid_tree_add_node(NULL, oid_root, absolutePath, writeable, default_value, Notification, set_fn, set_argc, set_argv, add_fn, add_argc, add_argv, del_fn, del_argc, del_argv);if(oid) {return VOS_OK;} else {
//        vos_warning_print("Exist Node: %s\n", absolutePath);return VOS_ERROR;}return VOS_OK;
}/* 递归操作一个OID */
static void __tr069_oid_display(rt_rbtree_t this_tree, void (*display)(struct tr069_oid *oid, void *arg), void *arg)
{if(!this_tree) return;struct tr069_oid *this_oid = NULL;rt_rbtree_node_t *node = NULL;for(node = rt_rbtree_getfirst(this_tree); node; node=rt_rbtree_getnext(node)) {this_oid = node->data;display(this_oid, arg);__tr069_oid_display(this_oid->child, display, arg);}
}/* 操作一个OID */
_api void tr069_oid_display(rt_rbtree_t oid_root, void (*display)(struct tr069_oid *oid, void *arg), void *arg)
{__tr069_oid_display(oid_root, display, arg);
}/* GetParameterNames */
_api struct tr069_oid_names *
tr069_oid_get_parameter_names(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE], int nextlevel)
{int count = 0;struct tr069_oid_names *oid_names = malloc(sizeof(struct tr069_oid_names));oid_names->count = 0;oid_names->NameList = NULL;struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, pathPrefix);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", pathPrefix);return oid_names;}if(!nextlevel) (count)++;count += __oid_tree_subcount(oid_item->child, nextlevel);oid_names->count = count;oid_names->NameList = malloc(sizeof(ParameterInfoStruct)*(count));int i = 0;if(!nextlevel) {strcpy(oid_names->NameList[i].Name, pathPrefix);oid_names->NameList[i].Writable = oid_item->writeable;(i)++;}__tr069_oid_oids_get(oid_item, oid_names->NameList, &i, nextlevel);    return oid_names;
}/* GetParameterNames Free */
_api void tr069_oid_get_parameter_names_free(struct tr069_oid_names *oid_names)
{if(!oid_names)return;free(oid_names->NameList);free(oid_names);
}/* 查询一个参数 */
/* GetParameterValues */
_api struct tr069_oid_values *
tr069_oid_get_parameter_values(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE])
{int count = 0;struct tr069_oid_values *oid_values = malloc(sizeof(struct tr069_oid_values));oid_values->count = 0;oid_values->ValueList = NULL;struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, pathPrefix);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", pathPrefix);return oid_values;}if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {count ++;}count += __oid_tree_subleafcount(oid_item->child);
//    vos_err_print("count = %d\n", count);oid_values->count = count;oid_values->ValueList = malloc(sizeof(ParameterValueStruct)*(count));VOS_MemZero(oid_values->ValueList, sizeof(ParameterValueStruct)*(count));int i = 0;
//    printf(">>>%s\n", oid_values->ValueList[i].Name);/* 如果是叶子 */if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {char tmp[TR069_OID_SIZE] = {0};struct tr069_oid *tmp_oid = NULL;for(tmp_oid = oid_item; tmp_oid; tmp_oid = tmp_oid->father) {VOS_MemZero(tmp, TR069_OID_SIZE);VOS_StrCat(tmp, oid_values->ValueList[i].Name);VOS_Sprintf(oid_values->ValueList[i].Name, "%s%s%s", tmp_oid->oidNameItem, tmp_oid->node_type==TR069_OID_ITEM_TYPE_LEAF?"":".", tmp);}(i)++;} else {__tr069_oid_oids_getleaf_value(oid_item, oid_values->ValueList, &i);}return oid_values;
}/* GetParameterValues Free */
_api void tr069_oid_get_parameter_values_free(struct tr069_oid_values *oid_values)
{if(!oid_values)return;free(oid_values->ValueList);free(oid_values);
}/* 查询一个参数 */
/* GetParameterAttribute */
_api struct tr069_oid_attrs *
tr069_oid_get_parameter_attributes(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE])
{int count = 0;struct tr069_oid_attrs *oid_attrs = malloc(sizeof(struct tr069_oid_attrs));oid_attrs->count = 0;oid_attrs->AttrList = NULL;struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, pathPrefix);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", pathPrefix);return oid_attrs;}if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {count ++;}count += __oid_tree_subleafcount(oid_item->child);
//    vos_err_print("count = %d\n", count);oid_attrs->count = count;oid_attrs->AttrList = malloc(sizeof(ParameterAttributeStruct)*(count));VOS_MemZero(oid_attrs->AttrList, sizeof(ParameterAttributeStruct)*(count));int i = 0;/* 如果是叶子 */if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {char tmp[TR069_OID_SIZE] = {0};struct tr069_oid *tmp_oid = NULL;for(tmp_oid = oid_item; tmp_oid; tmp_oid = tmp_oid->father) {VOS_MemZero(tmp, TR069_OID_SIZE);VOS_StrCat(tmp, oid_attrs->AttrList[i].Name);VOS_Sprintf(oid_attrs->AttrList[i].Name, "%s%s%s", tmp_oid->oidNameItem, tmp_oid->node_type==TR069_OID_ITEM_TYPE_LEAF?"":".", tmp);}(i)++;} else {__tr069_oid_oids_getleaf_attr(oid_item, oid_attrs->AttrList, &i);}return oid_attrs;
}/* GetParameterValues Free */
_api void tr069_oid_get_parameter_attributes_free(struct tr069_oid_attrs *oid_attrs)
{if(!oid_attrs)return;free(oid_attrs->AttrList);free(oid_attrs);
}static void _unused __tr069_tree_obj_count(struct tr069_oid * oid_tail, int **instanceNums, int *instanceCount)
{*instanceCount = 0;struct tr069_oid *tmp_oid = NULL;for(tmp_oid = oid_tail; tmp_oid; tmp_oid = tmp_oid->father) {if(tmp_oid->oidInstanceNum) {(*instanceCount)++;if(*instanceCount == 1) {*instanceNums = malloc(sizeof(int)*(*instanceCount));} else {*instanceNums = realloc(*instanceNums, sizeof(int)*(*instanceCount));}(*instanceNums)[(*instanceCount)-1] = tmp_oid->oidInstanceNum;}}int i;for(i=0; i<*instanceCount/2;i++) {(*instanceNums)[i] += (*instanceNums)[*instanceCount-1-i];(*instanceNums)[*instanceCount-1-i] = (*instanceNums)[i] - (*instanceNums)[*instanceCount-1-i];(*instanceNums)[i] -= (*instanceNums)[*instanceCount-1-i];}
}struct tr069_oid *tr069_oid_set_parameter_values(rt_rbtree_t oid_root, char paramPath[TR069_OID_SIZE], char paramValue[TR069_OID_SIZE])
{struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, paramPath);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", paramPath);return NULL;}if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {VOS_StrnCpy(oid_item->leaf_value->value, paramValue, TR069_OID_SIZE);int *instanceNums, instanceCount = 0;__tr069_tree_obj_count(oid_item, &instanceNums, &instanceCount);oid_item->leaf_value->set_fn(oid_item, instanceCount?true:false, instanceCount, instanceNums, oid_item->leaf_value->set_argc, oid_item->leaf_value->set_argv);if(instanceCount)free(instanceNums);return oid_item;}return NULL;
}struct tr069_oid *tr069_oid_set_parameter_attributes(rt_rbtree_t oid_root, char paramPath[TR069_OID_SIZE], int Notification)
{struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, paramPath);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", paramPath);return NULL;}if(oid_item->node_type == TR069_OID_ITEM_TYPE_LEAF) {oid_item->leaf_value->Notification = Notification;int *instanceNums, instanceCount = 0;__tr069_tree_obj_count(oid_item, &instanceNums, &instanceCount);oid_item->leaf_value->set_fn(oid_item, true, instanceCount, instanceNums, oid_item->leaf_value->set_argc, oid_item->leaf_value->set_argv);if(instanceCount)free(instanceNums);return oid_item;}return NULL;
}static struct tr069_oid *__tr069_oid_itemdup(struct tr069_oid *from,struct tr069_oid *father)
{struct tr069_oid *to = malloc(sizeof(struct tr069_oid));VOS_MemZero(to, sizeof(struct tr069_oid));VOS_Sprintf(to->oidNameItem, "%s", from->oidNameItem);to->oidInstanceNum = 0;VOS_Sprintf(to->oidAliasNameItem, "%s", from->oidAliasNameItem);to->father = father;to->oid_type = from->oid_type;to->node_type = from->node_type;to->writeable = from->writeable;/* 如果是叶子,需要分配内存 */if(from->node_type == TR069_OID_ITEM_TYPE_LEAF) {to->leaf_value = malloc(sizeof(struct tr069_oid_leaf));VOS_StrnCpy(to->leaf_value->value, from->leaf_value->value, TR069_OID_SIZE);to->leaf_value->Notification = from->leaf_value->Notification;to->leaf_value->set_fn = from->leaf_value->set_fn;to->leaf_value->set_argc = from->leaf_value->set_argc;to->leaf_value->set_argv = from->leaf_value->set_argv;}if(from->oid_type == TR069_OID_TYPE_TABLE) {to->obj_operation = malloc(sizeof(struct tr069_oid_obj_opt));to->obj_operation->add_fn = from->obj_operation->add_fn;to->obj_operation->add_argc = from->obj_operation->add_argc;to->obj_operation->add_argv = from->obj_operation->add_argv;to->obj_operation->del_fn = from->obj_operation->del_fn;to->obj_operation->del_argc = from->obj_operation->del_argc;to->obj_operation->del_argv = from->obj_operation->del_argv;}__tr069_oid_tree_create(&to->child);return to;}static void _unused __tr069_oid_tree_clone(struct tr069_oid * from_oid, struct tr069_oid * to_oid)
{to_oid->writeable = from_oid->writeable;struct tr069_oid *from_oid_item = NULL;rt_rbtree_node_t *from_node = NULL;for(from_node = rt_rbtree_getfirst(from_oid->child); from_node; from_node=rt_rbtree_getnext(from_node)) {from_oid_item = from_node->data;struct tr069_oid *to_oid_item = __tr069_oid_itemdup(from_oid_item, to_oid);rt_rbtree_insert(to_oid->child, to_oid_item, sizeof(struct tr069_oid));__tr069_oid_tree_clone(from_oid_item, to_oid_item);}
}_api int tr069_oid_add_object(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE])
{struct tr069_oid * oid_item = __oid_tree_find_oid_path(oid_root, pathPrefix);if(!oid_item) {vos_err_print("Not exist ParamPath: %s\n", pathPrefix);return VOS_ERROR;}if(!oid_item->writeable) {vos_err_print("ParamPath: %s is not writeable.\n", pathPrefix);return VOS_ERROR;}struct tr069_oid * template_item = __oid_tree_find_oid_path(oid_item->child, TABLE_NODE);if(!template_item) {vos_err_print("ParamPath: %s is not addable Object.\n", pathPrefix);return VOS_ERROR;}int oidInstanceNum;char aliasName[TR069_OID_ITEM_SIZE];//获取参数int *instanceNums, instanceCount = 0;__tr069_tree_obj_count(oid_item, &instanceNums, &instanceCount);//    vos_info_print("add object. %s, %s\n", oid_item->oidNameItem, template_item->oidNameItem);bool add_rlst = false;if(template_item->obj_operation)add_rlst = template_item->obj_operation->add_fn(oid_item, instanceCount+1, instanceCount, instanceNums, template_item->obj_operation->add_argc,template_item->obj_operation->add_argv,&oidInstanceNum, aliasName);//    vos_info_print("add object.\n");if(instanceCount) free(instanceNums);if(!add_rlst) {vos_err_print("ParamPath: %s add Object failed.\n", pathPrefix);return VOS_ERROR;}/* 实例 */struct tr069_oid * instance_item = malloc(sizeof(struct tr069_oid));VOS_MemZero(instance_item, sizeof(struct tr069_oid));VOS_Sprintf(instance_item->oidNameItem, "%d", oidInstanceNum);instance_item->oidInstanceNum = oidInstanceNum;VOS_Sprintf(instance_item->oidAliasNameItem, "%s", aliasName);instance_item->father = oid_item;#if 1 //为第一个分配add/delete内存instance_item->oid_type = template_item->oid_type;instance_item->node_type = template_item->node_type;instance_item->writeable = template_item->writeable;instance_item->obj_operation = malloc(sizeof(struct tr069_oid_obj_opt));instance_item->obj_operation->add_fn = template_item->obj_operation->add_fn;instance_item->obj_operation->add_argc = template_item->obj_operation->add_argc;instance_item->obj_operation->add_argv = template_item->obj_operation->add_argv;instance_item->obj_operation->del_fn = template_item->obj_operation->del_fn;instance_item->obj_operation->del_argc = template_item->obj_operation->del_argc;instance_item->obj_operation->del_argv = template_item->obj_operation->del_argv;
#endif__tr069_oid_tree_create(&instance_item->child);int ret = rt_rbtree_insert(oid_item->child, instance_item, sizeof(struct tr069_oid));if(ret != 0) {vos_err_print("ParamPath: %s instance Object %d exist.\n", pathPrefix, oidInstanceNum);free(instance_item);return VOS_ERROR;}__tr069_oid_tree_clone(template_item, instance_item);return oidInstanceNum;
}static void __tr069_oid_tree_destroy_loop(rt_rbtree_t tree);_api int tr069_oid_delete_object(rt_rbtree_t oid_root, char pathPrefix[TR069_OID_SIZE])
{struct tr069_oid * instance_item = __oid_tree_find_oid_path(oid_root, pathPrefix);if(!instance_item) {vos_err_print("Not exist ParamPath: %s\n", pathPrefix);return VOS_ERROR;}if(instance_item->oid_type != TR069_OID_TYPE_TABLE) {vos_err_print("ParamPath: %s is not object instance.\n", pathPrefix);return VOS_ERROR;}//获取参数int *instanceNums, instanceCount = 0;__tr069_tree_obj_count(instance_item, &instanceNums, &instanceCount);bool del_rlst = false;if(instance_item->obj_operation)del_rlst = instance_item->obj_operation->del_fn(instance_item, instanceCount, instanceNums, instance_item->obj_operation->del_argc,instance_item->obj_operation->del_argv);if(!del_rlst) {vos_err_print("ParamPath: %s delete Object failed.\n", pathPrefix);return VOS_ERROR;}//递归删除子树__tr069_oid_tree_destroy_loop(instance_item->child);//删除自己在父树种的叶子int ret_del = rt_rbtree_delete(instance_item->father->child, instance_item);if(ret_del != 0) {vos_warning_print("ParamPath: %s delete Object failed.\n", pathPrefix);return VOS_ERROR;}//释放自己的内存free(instance_item);return VOS_OK;
}/* 递归销毁树 */
static void __tr069_oid_tree_destroy_loop(rt_rbtree_t tree)
{rt_rbtree_t this_tree = tree;struct tr069_oid *this_node = NULL;rt_rbtree_node_t *find_node = NULL;for( find_node = rt_rbtree_getfirst(this_tree); find_node; find_node=rt_rbtree_getnext(find_node)) {this_node = find_node->data;__tr069_oid_tree_destroy_loop(this_node->child);rt_rbtree_destroy(this_node->child);if(this_node->leaf_value)free(this_node->leaf_value);if(this_node->obj_operation)free(this_node->obj_operation);free(this_node);}
}/* 销毁OID树 */
_api void tr069_oid_tree_destroy(rt_rbtree_t oid_root)
{__tr069_oid_tree_destroy_loop(oid_root);oid_root = NULL;
}

demo.c

#include "cpe_oid_register.h"static char *OIDs[] = {
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoDLSIB.OffsetToPointA",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoDLSIB.MultiFrequencyBandListNRSIB.{i}.FreqBandIndicatorNR",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoDLSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.OffsetToCarrier",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoDLSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.subcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoDLSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.CarrierBandwidth",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoULSIB.AbsoluteFrequencyPointA",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoULSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.OffsetToCarrier",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.FrequencyInfoULSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.SubcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PHY.FrequencyInfoULSIB.ScsSpecificCarrierList.{i}.SCSSpecificCarrier.CarrierBandwidth",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.SSB.ssbPositionsInBurst.InOneGroup",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.SSB.SsbPeriodicityServingCell",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.SSB.SsPBCHBlockPower",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.SSB.SsbSubcarrierOffset",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.SubCarrierSpacingCommon",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.ReferenceSubcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern1.DlULTransmission",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern1.NrofDownlinkSlots",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern1.NrofDownlinkSymbols",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern1.NrofUplinkSlots",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern1.NrofUplinkSymbols",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern2.DlULTransmission",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern2.NrofDownlinkSlots",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern2.NrofDownlinkSymbols",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern2.NrofUplinkSlots",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.TddULDLConfigurationCommon.pattern2.NrofUplinkSymbols",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPDL.StartPrbPosition",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPDL.Bandwidth",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPDL.SubcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPDL.CyclicPrefix",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPUL.StartPrbPosition",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPUL.Bandwidth",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPUL.SubcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPUL.CyclicPrefix",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.BWPUL.TimeAlignmentTimerCommon",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RACHConfigGeneric.PrachConfigurationIndex",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RACH-ConfigGeneric.Msg1FDM",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACH-ConfigCommon.RACH-ConfigGeneric.Msg1FrequencyStart",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RACHConfigGeneric.ZeroCorrelationZoneConfig",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.GroupHopping",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.puschTimeDomainAllocationList.{i}.K2",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.puschTimeDomainAllocationList.{i}.MappingType",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.puschTimeDomainAllocationList.{i}.StartSymbolAndLength",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.Msg3DeltaPreamble",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUSCHConfigCommon.P0NominalWithGrant",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUCCHConfigCommon.PucchResourceCommon",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUCCHConfigCommon.PucchGroupHopping",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUCCHConfigCommon.HoppingId",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PUCCHConfigCommon.P0nominal",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RootType",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RootSequenceIndex",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.Msg1Subcarrier",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RestrictedSetConfig",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.DmrsTypeAPosition",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.ControlResourceSetZero",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.SearchSpaceZero",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.SearchSpaceSIB1",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.SearchSpaceOtherSystemInformation",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.PagingSearchSpace",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.RaSearchSpace",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.ControlResourceSetId",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.FrequencyDomainResources",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.Duration",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.commonControlResourceSet.CceRegMappingType",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.CceRegMappingType.RegBundleSize",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.CceRegMappingType.InterleaverSize",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.CceRegMappingType.ShiftIndex",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.PrecoderGranularity",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonControlResourceSet.PdcchDMRSScramblingID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.SearchSpaceId",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.ControlResourceSetId",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.MonitoringSlotPeriodicity",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.MonitoringSlotOffset",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.Duration",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.MonitoringSymbolsWithinSlot",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.nrofCandidates.AggregationLevel1",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.nrofCandidates.AggregationLevel2",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.nrofCandidates.AggregationLevel4",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.nrofCandidates.AggregationLevel8",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.nrofCandidates.AggregationLevel16",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.SearchSpaceType",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.DciFormat00And10En",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDCCH.CommonSearchSpaceList.{i}.UeSpecificDciFormats",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDSCH.PDSCHTimeDomainResourceAllocationList.{i}.K0",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDSCH.PDSCHTimeDomainResourceAllocationList.{i}.MappingType",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.PDSCH.PDSCHTimeDomainResourceAllocationList.{i}.StartSymbolAndLength",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.TotalNumberOfRAPreambles",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.SSBPerRACHOccasionChoice",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.CBPreamblesPerSSB",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACH-ConfigCommon.RaMsg3SizeGroupA",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACH-ConfigCommon.MessagePowerOffsetGroupB",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.NumberOfRAPreamblesGroupA",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RaContentionResolutionTimer",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RsrpThresholdSSB",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACH-ConfigCommon.RACH-ConfigGeneric.PreambleReceivedTargetPower",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RACHConfigGeneric.PrachConfiguration",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.RACHConfigGeneric.PowerRampingStep",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACH-ConfigCommon.RACH-ConfigGeneric.RaResponseWindow",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.PHY.RACHConfigCommon.Msg3TransformPrecoder",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T300",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T301",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T302",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T304",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T310",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T311",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T320",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.N310",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.N311",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T319",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.RRCTimers.T380",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.PLMNID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.CID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.NRCarrierARFCN",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.ssbFrequency",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.ssbSubcarrierSpacing",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.PhyCellID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.TAC",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.Qoffset",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.QRxLevMinOffsetCell",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.QQualMinOffsetCell",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.CIO",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.NRCell.{i}.Blacklisted",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.PLMNID.{i}.{i}",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.CID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.EUTRACarrierARFCN",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.PhyCellID",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.QOffset",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.QRxLevMinOffsetCell",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.QQualMinOffsetCell",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.CIO",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.Blacklisted",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.TAC",
"Device.Services.FAPService.{i}.CellConfig.NR.RAN.NeighborList.LTECell.{i}.EnbType","Device.Services.FAPService.{i}.Transport.SCTP.Enable",
"Device.Services.FAPService.{i}.Transport.SCTP.RTOInitial",
"Device.Services.FAPService.{i}.Transport.SCTP.RTOMin",
"Device.Services.FAPService.{i}.Transport.SCTP.RTOMax",
"Device.Services.FAPService.{i}.Transport.SCTP.MaxInitRetransmits",
"Device.Services.FAPService.{i}.Transport.SCTP.HBInterval",
"Device.Services.FAPService.{i}.Transport.SCTP.MaxPathRetransmits",
"Device.Services.FAPService.{i}.Transport.SCTP.MaxAssociationRetransmits",
"Device.Services.FAPService.{i}.Transport.SCTP.ValCookieLife","Device.DeviceInfo.ManufacturerOUI",
"Device.DeviceInfo.Manufacturer",
"Device.DeviceInfo.ModelName",
"Device.DeviceInfo.SerialNumber",
"Device.DeviceInfo.HardwareVersion",
"Device.DeviceInfo.SoftwareVersion",
"Device.DeviceInfo.HardwarePlatform",
"Device.DeviceInfo.AdditionalHardwareVersion",
"Device.DeviceInfo.AdditionalSoftwareVersion",
"Device.DeviceInfo.ProvisioningCode",
"Device.DeviceInfo.ProductClass",
"Device.DeviceInfo.UpTime",
"Device.DeviceInfo.3GPPSpecVersion",
"Device.DeviceInfo.FirstUseDate","Device.SoftwareCtrl.AutoActivateEnable",
"Device.SoftwareCtrl.ActivateTime",
"Device.SoftwareCtrl.ActivateEnable",
"Device.SoftwareCtrl.SystemCurrentVersion",
"Device.SoftwareCtrl.SystemBackupVersion","Device.ManagementServer.URL",
"Device.ManagementServer.Username",
"Device.ManagementServer.Password",
"Device.ManagementServer.PeriodicInformEnable",
"Device.ManagementServer.PeriodicInformTime",
"Device.ManagementServer.PeriodicInformInterval",
"Device.ManagementServer.ParameterKey",
"Device.ManagementServer.ConnectionRequestURL",
"Device.ManagementServer.ConnectionRequestUsername",
"Device.ManagementServer.ConnectionRequestPassword",
"Device.ManagementServer.UDPConnectionRequestAddress",
"Device.ManagementServer.STUNEnable",
"Device.ManagementServer.STUNServerAddress",
"Device.ManagementServer.STUNServerPort",
"Device.ManagementServer.STUNUsername",
"Device.ManagementServer.STUNPassword",
"Device.ManagementServer.STUNMaximumKeepAlivePeriod",
"Device.ManagementServer.STUNMinimumKeepAlivePeriod",
"Device.ManagementServer.NATDetected","Device.FaultMgmt.ExpeditedEvent.{i}.PerceivedSeverity",
"Device.FaultMgmt.ExpeditedEvent.{i}.AdditionalText",
"Device.FaultMgmt.ExpeditedEvent.{i}.AdditionalInformation",
"Device.FaultMgmt.QueuedEvent.{i}.SerialNumber",
"Device.FaultMgmt.QueuedEvent.{i}.OUI",
"Device.FaultMgmt.QueuedEvent.{i}.EventTime",
"Device.FaultMgmt.QueuedEvent.{i}.AlarmIdentifier",
"Device.FaultMgmt.QueuedEvent.{i}.NotificationType",
"Device.FaultMgmt.QueuedEvent.{i}.ManagedObjectInstance",
"Device.FaultMgmt.QueuedEvent.{i}.EventType",
"Device.FaultMgmt.QueuedEvent.{i}.ProbableCause",
"Device.FaultMgmt.QueuedEvent.{i}.SpecificProblem",
"Device.FaultMgmt.QueuedEvent.{i}.PerceivedSeverity",
"Device.FaultMgmt.QueuedEvent.{i}.AdditionalText",
"Device.FaultMgmt.QueuedEvent.{i}.AdditionalInformation","Device.LogMgmt.PeriodicUploadEnable",
"Device.LogMgmt.URL",
"Device.LogMgmt.Username",
"Device.LogMgmt.Password",
"Device.LogMgmt.PeriodicUploadInterval","Device.Ethernet.Interface.{i}.Enable",
"Device.Ethernet.Interface.{i}.Status",
"Device.Ethernet.Interface.{i}.MACAddress",
"Device.Ethernet.Interface.{i}.MaxBitRate",
"Device.Ethernet.Interface.{i}.SignTransMedia",
"Device.Ethernet.Interface.{i}.DuplexMode","Device.IP.Interface.{i}.IPv4Address.{i}.IPAddress",
"Device.IP.Interface.{i}.IPv4Address.{i}.DefaultGateway",
"Device.IP.Interface.{i}.IPv4Address.{i}.SubnetMask",
"Device.IP.Interface.{i}.IPv4Address.{i}.AddressingType",
"Device.IP.Interface.{i}.IPv4Address.{i}.PortType","Device.IPsec.Enable",
"Device.IPsec.MyKeyMode",
"Device.IPsec.Status",
"Device.IPsec.AHSupported",
"Device.IPsec.IKEv2SupportedEncryptionAlgorithms",
"Device.IPsec.ESPSupportedEncryptionAlgorithms",
"Device.IPsec.IKEv2SupportedPseudoRandomFunctions",
"Device.IPsec.SupportedIntegrityAlgorithms",
"Device.IPsec.SupportedDiffieHellmanGroupTransforms",NULL,};#define NOIDs ({int n=0;while(OIDs[n++]); n-1;})void oid_display(struct tr069_oid *oid, void *arg)
{printf("%s\n", oid->oidNameItem);
}void oid_set(struct tr069_oid *node, bool isObj, int nObj, int ObjInsNums[], int argc, void *argv[])
{}bool oid_add(struct tr069_oid *node, int currObjIdx, int nPrevObj, int prevObjInsNums[], int argc, void *argv[], int *ObjIns, char aliasName[TR069_OID_ITEM_SIZE])
{int instance_num = 1;*ObjIns = instance_num++;sprintf(aliasName, "Alias_%d", instance_num-1);return true;}bool oid_del(struct tr069_oid *node, int nObj, int ObjInsNums[], int argc, void *argv[])
{return true;
}int set_argc = 3;
void *set_argv[] = {"Rong","Tao","Sylincom"
};int add_argc = 3;
void *add_argv[] = {"Rong","Tao","Sylincom"
}; int del_argc = 3;
void *del_argv[] = {"Rong","Tao","Sylincom"
};int main()
{/* 创建一个树 */rt_rbtree_t oid_tree = tr069_oid_tree_create();/* 注册树节点:注册了所有节点,各模块视情况而定 */int ioid, Noids = NOIDs;for(ioid=0;ioid<Noids;ioid++) {char defaultV[64] = {0};    //需要一个默认值:字符串sprintf(defaultV, "%d", ioid);tr069_oid_register(oid_tree, OIDs[ioid], 1, defaultV, ioid%5, &oid_set, set_argc, set_argv, &oid_add, add_argc, add_argv, &oid_del, del_argc, del_argv);}/* 显示 */TR069_OID_GetParamNamesShow(oid_tree, "Device.", 0, printf);/* 下面以 Device.IP.Interface. 为例,测试该参数树工具接口 */TR069_OID_GetParamNamesShow(oid_tree, "Device.IP.Interface.", 0, printf);/* 添加一个实例 */int instanceNum = tr069_oid_add_object(oid_tree, "Device.IP.Interface.");printf("Instance Number: %d\n", instanceNum);TR069_OID_GetParamNamesShow(oid_tree, "Device.IP.Interface.", 0, printf);/* 添加一个二级实例 */instanceNum = tr069_oid_add_object(oid_tree, "Device.IP.Interface.1.IPv4Address.");printf("Instance Number: %d\n", instanceNum);TR069_OID_GetParamNamesShow(oid_tree, "Device.IP.Interface.", 0, printf);/*********************************************\*  参数值操作\*********************************************/TR069_OID_GetParamValuesShow(oid_tree, "Device.IP.Interface.", printf);/* 设置参数 */tr069_oid_set_parameter_values(oid_tree, "Device.IP.Interface.1.IPv4Address.1.AddressingType", "MyAddressingType");tr069_oid_set_parameter_values(oid_tree, "Device.IP.Interface.1.IPv4Address.1.DefaultGateway", "MyDefaultGateway");tr069_oid_set_parameter_values(oid_tree, "Device.IP.Interface.1.IPv4Address.1.IPAddress", "MyIPAddress");tr069_oid_set_parameter_values(oid_tree, "Device.IP.Interface.1.IPv4Address.1.PortType", "MyPortType");tr069_oid_set_parameter_values(oid_tree, "Device.IP.Interface.1.IPv4Address.1.SubnetMask", "MySubnetMask");TR069_OID_GetParamValuesShow(oid_tree, "Device.IP.Interface.", printf);/*********************************************\*  参数属性操作\*********************************************/TR069_OID_GetParamAttributeShow(oid_tree, "Device.IP.Interface.", printf);/* 设置属性 */tr069_oid_set_parameter_attributes(oid_tree, "Device.IP.Interface.1.IPv4Address.1.AddressingType", 1);tr069_oid_set_parameter_attributes(oid_tree, "Device.IP.Interface.1.IPv4Address.1.DefaultGateway", 1);tr069_oid_set_parameter_attributes(oid_tree, "Device.IP.Interface.1.IPv4Address.1.IPAddress", 1);tr069_oid_set_parameter_attributes(oid_tree, "Device.IP.Interface.1.IPv4Address.1.PortType", 1);tr069_oid_set_parameter_attributes(oid_tree, "Device.IP.Interface.1.IPv4Address.1.SubnetMask", 1);TR069_OID_GetParamAttributeShow(oid_tree, "Device.IP.Interface.", printf);/* 删除实例 */tr069_oid_delete_object(oid_tree, "Device.IP.Interface.1.IPv4Address.1.");tr069_oid_delete_object(oid_tree, "Device.IP.Interface.1.");/* 摧毁这个参数树 */tr069_oid_tree_destroy(oid_tree);return 0;
}

基于Linux内核红黑树的TR069参数解析工具:树形结构+CPE RPC支持相关推荐

  1. Linux 内核红黑树分析

    Android binder 内核实现是用红黑树的,理解红黑树我觉得是每一个Linux er的重中之重,感谢格子森同学的投稿,周末愉快. 内核版本为 linux4.2.1 本文主要从红黑树的代码实现入 ...

  2. 详解Linux内核红黑树算法的实现

    复制太难看了,以后试试 博文地址:http://blog.csdn.net/npy_lp/article/details/7420689 

  3. 查询Linux系统网卡流量负载,超好用linux系统查询网卡等流量参数的工具,分享给大家!!!...

    超好用linux系统查询网卡等流量参数的工具,分享给大家!!! 工作中大家或许会遇到这类情况:托管服务器流量超出限额,可是突然又不能像windows主机那样通过QQ管家或者360卫士等软件工具那样很直 ...

  4. 5 个基于Linux命令行的文件下载和网站浏览工具

    Linux命令行是GNU/Linux中最神奇迷人的部分,它是非常强大的工具.命令行本身功能多样,多种内建或者第三方的命令行应用使得Linux变得更加健壮和强大.Linux Shell支持多种不同类型的 ...

  5. php解析bt,PHP基于闭包思想实现的BT(torrent)文件解析工具实例详解

    PHP基于闭包思想实现的BT(torrent)文件解析工具实例详解 发布于 2017-09-08 20:05:36 | 124 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP( ...

  6. 介绍Shell脚本的参数解析工具

    Argbash是一个代码生成器,它为你的脚本生成一个量身定制的解析库.与其他bash模块的通用代码不同,它生成你的脚本所需的最少代码. Argbash是一个代码生成器,它为你的脚本生成一个量身定制的解 ...

  7. php解析命令行参数选项,PHP 命令行参数解析工具类的示例代码

    PHP 命令行参数解析工具类的示例代码 /** * 命令行参数解析工具类 * @author guolinchao */ class CommandLine { // 临时记录短选项的选项值 priv ...

  8. php解析torrent文件,PHP基于闭包思想实现的BT(torrent)文件解析工具实例详解

    本文实例讲述了PHP基于闭包思想实现的torrent文件解析工具.分享给大家供大家参考,具体如下: PHP对静态词法域的支持有点奇怪,内部匿名函数必须在参数列表后面加上use关键字,显式的说明想要使用 ...

  9. Python中最好用的命令行参数解析工具

    Python 做为一个脚本语言,可以很方便地写各种工具.当你在服务端要运行一个工具或服务时,输入参数似乎是一种硬需(当然你也可以通过配置文件来实现). 如果要以命令行执行,那你需要解析一个命令行参数解 ...

最新文章

  1. 烦人的Null,你可以走开点了
  2. 文本超出显示省略号/数字英文字母折行有关css 属性/显示两行,第二行省略号显示css方法...
  3. java finally块_Java中的finally块是什么?
  4. Solidity字符串类型
  5. Kotlin------函数和代码注释
  6. linux ssh命令详解
  7. access实验报告体会_Access实验报告 - 图文
  8. Django安装使用基础
  9. 栈和队列的算法题总结
  10. 瑞星2007正版序列号
  11. c语言中转义字符是由什么和什么构成,c语言中什么是转义字符
  12. Pandas中的 transform() 结合 groupby() 用法示例
  13. JavaWeb项目实战(2)安装JDK和Tomcat以及Eclipse构造开发环境
  14. 因特网上的计算机通常使用的网络协议为,计算机网络原理自考2015年10月真题
  15. onerror捕获异常
  16. Android Activity 的详细启动过程分析
  17. 5.接口参数过滤(phalapi框架总结)
  18. DJ8-2 主存储器的组织
  19. PAT_乙级_1003_筱筱
  20. 宫崎骏魔幻动画电影《哈尔的移动城堡》高清720P,国粤日三语

热门文章

  1. 剑指Offer30-包含min函数的栈(单调栈)
  2. C语言中结构体内存存储方式
  3. Linux内核分析 读书笔记 (第四章)
  4. 3_03 蛇形填数(数组)
  5. [数据结构与算法]RED-BLACK(红黑)树的实现TreeMap源码阅读
  6. 在vs 2008中使用iis来调试,或者说在iis中集成vs 2008的调试
  7. 超34款吸费手机被曝光下架 天语TCL大显等在其中
  8. postgreSQL源码分析——索引的建立与使用——总结篇
  9. 实现网页定时刷新或跳转到其他页面(Refresh头字段)
  10. linux词语大全,简单词语大全二字学习软件-简单词语大全四字下载v1.5.3-Linux公社...