diff --git a/README.md b/README.md index b57fb0f0..fd4a17a2 100644 --- a/README.md +++ b/README.md @@ -343,11 +343,8 @@ BBF_VENDOR_PREFIX="X_TEST_COM_" The application should bring its shared library under **'/usr/lib/bbfdm/'** path that contains the sub tree of **Objects/Parameters** and the related functions **Get/Set/Add/Delete/Operate**. The new added objects, parameters and operates will be automatically shown by icwmpd and uspd/obuspa. -Each library should contains two Root tables: +Each library should contains the Root table: **“tDynamicObj”** -- **“tDynamicObj”** - -- **“tDynamicOperate”** #### DynamicObject definition @@ -361,19 +358,6 @@ The **DM_MAP_OBJ** structure contains three arguments: | `nextobject` | Pointer to a **DMOBJ** array which contains a list of the child objects | | `parameter` | Pointer to a **DMLEAF** array which contains a list of the child parameters | -#### DynamicOperate definition - -The “tDynamicOperate” table contains entries of **DM_MAP_OPERATE** structure. - -The **DM_MAP_OPERATE** structure contains two arguments: - -| Argument | Description | -| ------------------ | --------------------------------------------------------------------------------------------------------------- | -| `pathname` | A string of the path name operate. Example “Device.BBKSpeedTest”, “Device.WiFi.AccessPoint.*.X_IOPSYS_EU_Reset” | -| `operation` | The function to be executed in the operation | -| `type` | The type of the operation. Could be **sync** or **async** | -| `args` | The input and output arguments of the operation | - For the other tables, they are defined in the same way as the Object and Parameter definition described above. diff --git a/bin/Makefile.am b/bin/Makefile.am index 05bd4571..8b390360 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -35,8 +35,7 @@ libbbfdm_la_SOURCES = \ ../dmentry.c \ ../dmdynamiclibrary.c \ ../dmdynamicjson.c \ - ../dmmemjson.c \ - ../dmoperate.c \ + ../dmdynamicmem.c \ ../dmdiagnostics.c \ ../dmbbfcommon.c @@ -66,7 +65,6 @@ libbbfdm_la_SOURCES += \ ../dmtree/tr181/fast.c \ ../dmtree/tr181/interfacestack.c \ ../dmtree/tr181/usb.c \ - ../dmtree/tr181/datamodelversion.c \ ../dmtree/tr181/gre.c \ ../dmtree/tr181/dynamicdns.c \ ../dmtree/tr181/security.c \ diff --git a/dmdynamicjson.c b/dmdynamicjson.c index 5d98111c..d7cee120 100644 --- a/dmdynamicjson.c +++ b/dmdynamicjson.c @@ -10,41 +10,42 @@ */ #include "dmdynamicjson.h" -#include "dmmemjson.h" +#include "dmdynamicmem.h" #include "dmentry.h" LIST_HEAD(json_list); +LIST_HEAD(json_memhead); static void add_json_data_to_list(struct list_head *dup_list, char *name, char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *arg5, const char *arg6, const char *arg7, const char *arg8) { - struct dm_json_parameter *dm_json_parameter = dmcallocjson(1, sizeof(struct dm_json_parameter)); + struct dm_json_parameter *dm_json_parameter = dm_dynamic_calloc(&json_memhead, 1, sizeof(struct dm_json_parameter)); list_add_tail(&dm_json_parameter->list, dup_list); - if (name) dm_json_parameter->name = dmstrdupjson(name); - if (arg1) dm_json_parameter->arg1 = dmstrdupjson(arg1); - if (arg2) dm_json_parameter->arg2 = dmstrdupjson(arg2); - if (arg3) dm_json_parameter->arg3 = dmstrdupjson(arg3); - if (arg4) dm_json_parameter->arg4 = dmstrdupjson(arg4); - if (arg5) dm_json_parameter->arg5 = dmstrdupjson(arg5); - if (arg6) dm_json_parameter->arg6 = dmstrdupjson(arg6); - if (arg7) dm_json_parameter->arg7 = dmstrdupjson(arg7); - if (arg8) dm_json_parameter->arg8 = dmstrdupjson(arg8); + if (name) dm_json_parameter->name = dm_dynamic_strdup(&json_memhead, name); + if (arg1) dm_json_parameter->arg1 = dm_dynamic_strdup(&json_memhead, arg1); + if (arg2) dm_json_parameter->arg2 = dm_dynamic_strdup(&json_memhead, arg2); + if (arg3) dm_json_parameter->arg3 = dm_dynamic_strdup(&json_memhead, arg3); + if (arg4) dm_json_parameter->arg4 = dm_dynamic_strdup(&json_memhead, arg4); + if (arg5) dm_json_parameter->arg5 = dm_dynamic_strdup(&json_memhead, arg5); + if (arg6) dm_json_parameter->arg6 = dm_dynamic_strdup(&json_memhead, arg6); + if (arg7) dm_json_parameter->arg7 = dm_dynamic_strdup(&json_memhead, arg7); + if (arg8) dm_json_parameter->arg8 = dm_dynamic_strdup(&json_memhead, arg8); } static void delete_json_data_from_list(struct dm_json_parameter *dm_json_parameter) { list_del(&dm_json_parameter->list); - if (dm_json_parameter->name) dmfreejson(dm_json_parameter->name); - if (dm_json_parameter->arg1) dmfreejson(dm_json_parameter->arg1); - if (dm_json_parameter->arg2) dmfreejson(dm_json_parameter->arg2); - if (dm_json_parameter->arg3) dmfreejson(dm_json_parameter->arg3); - if (dm_json_parameter->arg4) dmfreejson(dm_json_parameter->arg4); - if (dm_json_parameter->arg5) dmfreejson(dm_json_parameter->arg5); - if (dm_json_parameter->arg6) dmfreejson(dm_json_parameter->arg6); - if (dm_json_parameter->arg7) dmfreejson(dm_json_parameter->arg7); - if (dm_json_parameter->arg8) dmfreejson(dm_json_parameter->arg8); - if (dm_json_parameter) dmfreejson(dm_json_parameter); + if (dm_json_parameter->name) dm_dynamic_free(dm_json_parameter->name); + if (dm_json_parameter->arg1) dm_dynamic_free(dm_json_parameter->arg1); + if (dm_json_parameter->arg2) dm_dynamic_free(dm_json_parameter->arg2); + if (dm_json_parameter->arg3) dm_dynamic_free(dm_json_parameter->arg3); + if (dm_json_parameter->arg4) dm_dynamic_free(dm_json_parameter->arg4); + if (dm_json_parameter->arg5) dm_dynamic_free(dm_json_parameter->arg5); + if (dm_json_parameter->arg6) dm_dynamic_free(dm_json_parameter->arg6); + if (dm_json_parameter->arg7) dm_dynamic_free(dm_json_parameter->arg7); + if (dm_json_parameter->arg8) dm_dynamic_free(dm_json_parameter->arg8); + if (dm_json_parameter) dm_dynamic_free(dm_json_parameter); } static void free_json_data_from_list(struct list_head *dup_list) @@ -88,7 +89,7 @@ static void free_node_object_tree_dynamic_array(DMOBJ *dm_entryobj) int free_json_dynamic_arrays(DMOBJ *dm_entryobj) { free_json_data_from_list(&json_list); - dmcleanmemjson(); + dm_dynamic_cleanmem(&json_memhead); free_node_object_tree_dynamic_array(dm_entryobj); return 0; } @@ -98,22 +99,22 @@ static void generate_prefixobj_and_obj_full_obj(char *full_obj, char **prefix_ob char *pch = NULL, *pchr = NULL, *tmp_obj = NULL; char *full_object = replace_str(full_obj, ".{i}.", "."); - char *str = dmstrdupjson(full_object); + char *str = dm_dynamic_strdup(&json_memhead, full_object); for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { if (pchr != NULL && *pchr != '\0') { if (*prefix_obj == NULL) { - dmasprintfjson(prefix_obj, "%s.", pch); + dm_dynamic_asprintf(&json_memhead, prefix_obj, "%s.", pch); } else { - tmp_obj = dmstrdupjson(*prefix_obj); - dmfreejson(*prefix_obj); - dmasprintfjson(prefix_obj, "%s%s.", tmp_obj, pch); - dmfreejson(tmp_obj); + tmp_obj = dm_dynamic_strdup(&json_memhead, *prefix_obj); + dm_dynamic_free(*prefix_obj); + dm_dynamic_asprintf(&json_memhead, prefix_obj, "%s%s.", tmp_obj, pch); + dm_dynamic_free(tmp_obj); } } else { - *obj = dmstrdupjson(pch); + *obj = dm_dynamic_strdup(&json_memhead, pch); } } - dmfreejson(str); + dm_dynamic_free(str); dmfree(full_object); } @@ -121,27 +122,27 @@ static char *generate_obj_without_instance(char *full_obj, bool is_obj) { char *pch = NULL, *pchr = NULL, *tmp_obj = NULL, *obj = NULL; - char *str = dmstrdupjson(full_obj); + char *str = dm_dynamic_strdup(&json_memhead, full_obj); for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { if (atoi(pch) == 0) { if (obj == NULL) { - dmasprintfjson(&obj, "%s.", pch); + dm_dynamic_asprintf(&json_memhead, &obj, "%s.", pch); } else { - tmp_obj = dmstrdupjson(obj); - dmfreejson(obj); + tmp_obj = dm_dynamic_strdup(&json_memhead, obj); + dm_dynamic_free(obj); if (is_obj) - dmasprintfjson(&obj, "%s%s.", tmp_obj, pch); + dm_dynamic_asprintf(&json_memhead, &obj, "%s%s.", tmp_obj, pch); else { if (pchr != NULL && *pchr != '\0') - dmasprintfjson(&obj, "%s%s.", tmp_obj, pch); + dm_dynamic_asprintf(&json_memhead, &obj, "%s%s.", tmp_obj, pch); else - dmasprintfjson(&obj, "%s%s", tmp_obj, pch); + dm_dynamic_asprintf(&json_memhead, &obj, "%s%s", tmp_obj, pch); } - dmfreejson(tmp_obj); + dm_dynamic_free(tmp_obj); } } } - if(str) dmfreejson(str); + if(str) dm_dynamic_free(str); return obj; } @@ -566,7 +567,7 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl return; //PARAM - pleaf[i].parameter = dmstrdupjson(param); + pleaf[i].parameter = dm_dynamic_strdup(&json_memhead, param); //permission json_object_object_get_ex(jobj, "write", &write); @@ -662,7 +663,7 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s //nextobj if (obj_number != 0) - next_obj = dmcallocjson(obj_number+1, sizeof(struct dm_obj_s)); + next_obj = dm_dynamic_calloc(&json_memhead, obj_number+1, sizeof(struct dm_obj_s)); else next_obj = NULL; @@ -670,7 +671,7 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s //leaf if (param_number != 0) { - next_leaf = dmcallocjson(param_number+1, sizeof(struct dm_leaf_s)); + next_leaf = dm_dynamic_calloc(&json_memhead, param_number+1, sizeof(struct dm_leaf_s)); pobj[index].leaf = next_leaf; } else { pobj[index].leaf = NULL; @@ -776,11 +777,11 @@ int load_json_dynamic_arrays(struct dmctx *ctx) } if (dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] == NULL) { - dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dmcallocjson(2, sizeof(struct dm_obj_s)); + dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_calloc(&json_memhead, 2, sizeof(struct dm_obj_s)); parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], 0, &json_list); } else { int idx = get_index_of_available_entry(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0]); - dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dmreallocjson(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s)); + dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_realloc(&json_memhead, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s)); memset(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s)); parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], idx, &json_list); } diff --git a/dmdynamiclibrary.c b/dmdynamiclibrary.c index 10dafda5..f16ed9f4 100644 --- a/dmdynamiclibrary.c +++ b/dmdynamiclibrary.c @@ -9,10 +9,12 @@ * */ +#include "dmdynamicmem.h" #include "dmdynamiclibrary.h" -#include "dmoperate.h" LIST_HEAD(loaded_library_list); +LIST_HEAD(dynamic_operate_list); +LIST_HEAD(library_memhead); struct loaded_library { @@ -20,6 +22,14 @@ struct loaded_library void *library; }; +struct dynamic_operate +{ + struct list_head list; + char *operate_path; + void *operate; + void *operate_args; +}; + static void add_list_loaded_libraries(struct list_head *library_list, void *library) { struct loaded_library *lib = calloc(1, sizeof(struct loaded_library)); @@ -40,6 +50,28 @@ static void free_all_list_open_library(struct list_head *library_list) } } +static void add_list_dynamic_operates(struct list_head *operate_list, char *operate_path, void *operate, void *operate_args) +{ + struct dynamic_operate *dyn_operate = calloc(1, sizeof(struct dynamic_operate)); + list_add_tail(&dyn_operate->list, operate_list); + dyn_operate->operate_path = strdup(operate_path); + dyn_operate->operate = operate; + dyn_operate->operate_args = operate_args; +} + +static void free_list_dynamic_operates(struct list_head *operate_list) +{ + struct dynamic_operate *dyn_operate; + while (operate_list->next != operate_list) { + dyn_operate = list_entry(operate_list->next, struct dynamic_operate, list); + list_del(&dyn_operate->list); + if (dyn_operate->operate_path) { + free(dyn_operate->operate_path); + } + FREE(dyn_operate); + } +} + static void dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryobj) { for (; (entryobj && entryobj->obj); entryobj++) { @@ -71,8 +103,74 @@ void free_library_dynamic_arrays(DMOBJ *dm_entryobj) DMNODE node = {.current_object = ""}; free_all_list_open_library(&loaded_library_list); + free_list_dynamic_operates(&dynamic_operate_list); + dm_dynamic_cleanmem(&library_memhead); dm_browse_node_dynamic_object_tree(&node, root); - FREE(dynamic_operate); +} + +static bool operate_find_root_entry(struct dmctx *ctx, char *in_param, DMOBJ **root_entry) +{ + int obj_found = 0; + DMOBJ *root = ctx->dm_entryobj; + DMNODE node = {.current_object = ""}; + + dm_check_dynamic_obj(ctx, &node, root, in_param, in_param, root_entry, &obj_found); + + return (obj_found && *root_entry) ? true : false; +} + + +static char *get_path_without_instance(char *path) +{ + char *pch = NULL, *pchr = NULL; + char res_path[512] = {0}; + unsigned pos = 0; + + char *str = dm_dynamic_strdup(&library_memhead, path); + + res_path[0] = 0; + for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { + if (atoi(pch) == 0) + pos += snprintf(&res_path[pos], sizeof(res_path) - pos, "%s%s", pch, (pchr != NULL && *pchr != '\0') ? "." : ""); + } + + if (str) + dm_dynamic_free(str); + + return dm_dynamic_strdup(&library_memhead, res_path); +} + +static int get_dynamic_operate_args(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + struct dynamic_operate *dyn_operate = NULL; + operation_args *operate_args = NULL; + + char *operate_path = get_path_without_instance(refparam); + list_for_each_entry(dyn_operate, &dynamic_operate_list, list) { + if (strcmp(dyn_operate->operate_path, operate_path) == 0) { + operate_args = (operation_args *)dyn_operate->operate_args; + break; + } + } + + *value = (char *)operate_args; + return 0; +} + +static int dynamic_operate_leaf(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct dynamic_operate *dyn_operate = NULL; + operation operate_func = NULL; + + char *operate_path = get_path_without_instance(refparam); + list_for_each_entry(dyn_operate, &dynamic_operate_list, list) { + if (strcmp(dyn_operate->operate_path, operate_path) == 0) { + operate_func = (operation)dyn_operate->operate; + break; + } + } + + return operate_func ? operate_func(ctx, refparam, (json_object *)value) : CMD_FAIL; } int load_library_dynamic_arrays(struct dmctx *ctx) @@ -150,17 +248,58 @@ int load_library_dynamic_arrays(struct dmctx *ctx) } } - //Dynamic Operate + //Dynamic Operate is deprecated now. It will be removed later. DM_MAP_OPERATE *dynamic_operate = NULL; *(void **) (&dynamic_operate) = dlsym(handle, "tDynamicOperate"); if (dynamic_operate) { for (int i = 0; dynamic_operate[i].path; i++) { - if (dynamic_operate[i].operate && dynamic_operate[i].type) - add_dynamic_operate(dynamic_operate[i].path, - dynamic_operate[i].operate, - dynamic_operate[i].type, - dynamic_operate[i].args); + if (dynamic_operate[i].operate && dynamic_operate[i].type) { + char parent_path[256] = {'\0'}; + char operate_path[256] = {'\0'}; + DMOBJ *dm_entryobj = NULL; + + char *object_path = replace_str(dynamic_operate[i].path, ".*.", "."); + snprintf(operate_path, sizeof(operate_path), "%s%s", object_path, !strstr(object_path, "()") ? "()" : ""); + dmfree(object_path); + + char *ret = strrchr(operate_path, '.'); + strncpy(parent_path, operate_path, ret - operate_path +1); + + bool obj_exists = operate_find_root_entry(ctx, parent_path, &dm_entryobj); + if (obj_exists == false || !dm_entryobj) + continue; + + add_list_dynamic_operates(&dynamic_operate_list, operate_path, dynamic_operate[i].operate, &dynamic_operate[i].args); + + if (dm_entryobj->dynamicleaf == NULL) { + dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf)); + dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT; + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT; + dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT; + } + + operation_args *args = &dynamic_operate[i].args; + DMLEAF *new_leaf = dm_dynamic_calloc(&library_memhead, 2, sizeof(struct dm_leaf_s)); + new_leaf[0].parameter = dm_dynamic_strdup(&library_memhead, ret+1); + new_leaf[0].permission = !strcmp(dynamic_operate[i].type, "sync") ? &DMSYNC : &DMASYNC; + new_leaf[0].type = DMT_COMMAND; + new_leaf[0].getvalue = (args->in || args->out) ? get_dynamic_operate_args : NULL; + new_leaf[0].setvalue = dynamic_operate_leaf; + new_leaf[0].bbfdm_type = BBFDM_USP; + + if (dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf == NULL) { + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = calloc(2, sizeof(DMLEAF *)); + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[0] = new_leaf; + } else { + int idx = get_leaf_idx_dynamic_array(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf); + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = realloc(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf, (idx + 2) * sizeof(DMLEAF *)); + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx] = new_leaf; + dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx+1] = NULL; + } + + } + } } diff --git a/dmdynamicmem.c b/dmdynamicmem.c new file mode 100644 index 00000000..6661e25a --- /dev/null +++ b/dmdynamicmem.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2019 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Amin Ben Ramdhane + * + */ + +#include "dmdynamicmem.h" + +inline void *__dm_dynamic_malloc(struct list_head *mem_list, size_t size) +{ + struct dm_dynamic_mem *m = malloc(sizeof(struct dm_dynamic_mem) + size); + if (m == NULL) return NULL; + list_add(&m->list, mem_list); + return (void *)m->mem; +} + +inline void *__dm_dynamic_calloc(struct list_head *mem_list, int n, size_t size) +{ + struct dm_dynamic_mem *m = calloc(n, sizeof(struct dm_dynamic_mem) + size); + if (m == NULL) return NULL; + list_add(&m->list, mem_list); + return (void *)m->mem; +} + +inline void *__dm_dynamic_realloc(struct list_head *mem_list, void *n, size_t size) +{ + struct dm_dynamic_mem *m = NULL; + if (n != NULL) { + m = container_of(n, struct dm_dynamic_mem, mem); + list_del(&m->list); + } + struct dm_dynamic_mem *new_m = realloc(m, sizeof(struct dm_dynamic_mem) + size); + if (new_m == NULL) { + dm_dynamic_free(m); + return NULL; + } else + m = new_m; + list_add(&m->list, mem_list); + return (void *)m->mem; +} + +inline void dm_dynamic_free(void *m) +{ + if (m == NULL) return; + struct dm_dynamic_mem *rm; + rm = container_of(m, struct dm_dynamic_mem, mem); + list_del(&rm->list); + free(rm); +} + +void dm_dynamic_cleanmem(struct list_head *mem_list) +{ + struct dm_dynamic_mem *dmm; + while (mem_list->next != mem_list) { + dmm = list_entry(mem_list->next, struct dm_dynamic_mem, list); + list_del(&dmm->list); + free(dmm); + } +} + +char *__dm_dynamic_strdup(struct list_head *mem_list, const char *s) +{ + size_t len = strlen(s) + 1; + void *new = __dm_dynamic_malloc(mem_list, len); + if (new == NULL) return NULL; + return (char *) memcpy(new, s, len); +} + +int __dm_dynamic_asprintf(struct list_head *mem_list, char **s, const char *format, ...) +{ + int size; + char *str = NULL; + va_list arg; + + va_start(arg, format); + size = vasprintf(&str, format, arg); + va_end(arg); + + if (size < 0 || str == NULL) + return -1; + + *s = __dm_dynamic_strdup(mem_list, str); + + free(str); + if (*s == NULL) + return -1; + return 0; +} diff --git a/dmdynamicmem.h b/dmdynamicmem.h new file mode 100644 index 00000000..3da5beee --- /dev/null +++ b/dmdynamicmem.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Amin Ben Ramdhane + * + */ + +#ifndef __DM_DYNAMIC_MEM_H +#define __DM_DYNAMIC_MEM_H + +#include + +struct dm_dynamic_mem +{ + struct list_head list; + char mem[0]; +}; + +void *__dm_dynamic_malloc(struct list_head *mem_list, size_t size); +void *__dm_dynamic_calloc(struct list_head *mem_list, int n, size_t size); +void *__dm_dynamic_realloc(struct list_head *mem_list, void *n, size_t size); +char *__dm_dynamic_strdup(struct list_head *mem_list, const char *s); +int __dm_dynamic_asprintf(struct list_head *mem_list, char **s, const char *format, ...); +void dm_dynamic_free(void *m); +void dm_dynamic_cleanmem(struct list_head *mem_list); + +#define dm_dynamic_malloc(m, x) __dm_dynamic_malloc(m, x) +#define dm_dynamic_calloc(m, n, x) __dm_dynamic_calloc(m, n, x) +#define dm_dynamic_realloc(m, x, n) __dm_dynamic_realloc(m, x, n) +#define dm_dynamic_strdup(m, x) __dm_dynamic_strdup(m, x) +#define dm_dynamic_asprintf(m, s, format, ...) __dm_dynamic_asprintf(m, s, format, ## __VA_ARGS__) + +#endif //__DM_DYNAMIC_MEM_H diff --git a/dmentry.c b/dmentry.c index d49f7ae1..b2b66d35 100644 --- a/dmentry.c +++ b/dmentry.c @@ -16,7 +16,6 @@ #include "dmdynamicjson.h" #include "dmdynamiclibrary.h" #include "dmdynamicvendor.h" -#include "dmoperate.h" #include "device.h" #include "dmbbfcommon.h" @@ -241,10 +240,10 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, break; case CMD_USP_OPERATE: ctx->in_value = arg1 ? arg1 : ""; - fault = operate_on_node(ctx, ctx->in_param, ctx->in_value); + fault = dm_entry_operate(ctx); break; case CMD_USP_LIST_OPERATE: - operate_list_cmds(ctx); + fault = dm_entry_list_operates(ctx); break; case CMD_GET_SCHEMA: fault = dm_entry_get_schema(ctx); @@ -261,11 +260,11 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, return usp_fault_map(fault); } -int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2) +int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1) { struct set_tmp *n = NULL, *p = NULL; int fault = 0; - + switch(cmd) { case CMD_SET_VALUE: ctx->setaction = VALUESET; diff --git a/dmentry.h b/dmentry.h index 8d702564..b4b2f7a4 100644 --- a/dmentry.h +++ b/dmentry.h @@ -27,7 +27,7 @@ enum ctx_init_enum { 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); -int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2); +int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1); int dm_entry_restart_services(void); int dm_entry_manage_services(struct blob_buf *bb, bool restart); int dm_entry_revert_changes(void); diff --git a/dmmemjson.c b/dmmemjson.c deleted file mode 100644 index 7c67031d..00000000 --- a/dmmemjson.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - * - */ - -#include "dmmemjson.h" - -LIST_HEAD(memheadjson); - -inline void *__dmmallocjson(size_t size) -{ - struct dmmemjson *m = malloc(sizeof(struct dmmemjson) + size); - if (m == NULL) return NULL; - list_add(&m->list, &memheadjson); - return (void *)m->mem; -} - -inline void *__dmcallocjson(int n, size_t size) -{ - struct dmmemjson *m = calloc(n, sizeof(struct dmmemjson) + size); - if (m == NULL) return NULL; - list_add(&m->list, &memheadjson); - return (void *)m->mem; -} - -inline void *__dmreallocjson(void *n, size_t size) -{ - struct dmmemjson *m = NULL; - if (n != NULL) { - m = container_of(n, struct dmmemjson, mem); - list_del(&m->list); - } - struct dmmemjson *new_m = realloc(m, sizeof(struct dmmemjson) + size); - if (new_m == NULL) { - dmfreejson(m); - return NULL; - } else - m = new_m; - list_add(&m->list, &memheadjson); - return (void *)m->mem; -} - -inline void dmfreejson(void *m) -{ - if (m == NULL) return; - struct dmmemjson *rm; - rm = container_of(m, struct dmmemjson, mem); - list_del(&rm->list); - free(rm); -} - -void dmcleanmemjson() -{ - struct dmmemjson *dmm; - while (memheadjson.next != &memheadjson) { - dmm = list_entry(memheadjson.next, struct dmmemjson, list); - list_del(&dmm->list); - free(dmm); - } -} - -char *__dmstrdupjson(const char *s) -{ - size_t len = strlen(s) + 1; - void *new = __dmmallocjson(len); - if (new == NULL) return NULL; - return (char *) memcpy(new, s, len); -} - -int __dmasprintfjson(char **s, const char *format, ...) -{ - int size; - char *str = NULL; - va_list arg; - - va_start(arg, format); - size = vasprintf(&str, format, arg); - va_end(arg); - - if (size < 0 || str == NULL) - return -1; - - *s = __dmstrdupjson(str); - - free(str); - if (*s == NULL) - return -1; - return 0; -} diff --git a/dmmemjson.h b/dmmemjson.h deleted file mode 100644 index 9129d6a9..00000000 --- a/dmmemjson.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Amin Ben Ramdhane - * - */ - -#ifndef __DMMEMJSON_H -#define __DMMEMJSON_H - -#include - -struct dmmemjson -{ - struct list_head list; - char mem[0]; -}; - -void *__dmmallocjson(size_t size); -void *__dmcallocjson(int n, size_t size); -void *__dmreallocjson(void *n, size_t size); -char *__dmstrdupjson(const char *s); -int __dmasprintfjson(char **s, const char *format, ...); -void dmfreejson(void *m); -void dmcleanmemjson(); - -#define dmmallocjson(x) __dmmallocjson(x) -#define dmcallocjson(n, x) __dmcallocjson(n, x) -#define dmreallocjson(x, n) __dmreallocjson(x, n) -#define dmstrdupjson(x) __dmstrdupjson(x) -#define dmasprintfjson(s, format, ...) __dmasprintfjson(s, format, ## __VA_ARGS__) - -#endif //__DMMEMJSON_H diff --git a/dmoperate.c b/dmoperate.c deleted file mode 100644 index 1e721520..00000000 --- a/dmoperate.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * dmoperate.c: Operate handler for uspd - * - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Vivek Dutta - * Author: Yashvardhan - * Author: Amin Ben Ramdhane - * - */ - -#include "dmoperate.h" - -#define GLOB_EXPR "[=><]+" - -static uint8_t wifi_neighbor_count = 0; -struct op_cmd *dynamic_operate = NULL; - -static const char *fw_image_activate_in[] = { - "TimeWindow.1.Start", - "TimeWindow.2.Start", - "TimeWindow.3.Start", - "TimeWindow.4.Start", - "TimeWindow.5.Start", -}; - -static void bbf_init(struct dmctx *dm_ctx, char *path) -{ - unsigned int instance = INSTANCE_MODE_NUMBER; - - if (match(path, "[[]+")) { - if (!match(path, GLOB_EXPR)) - instance = INSTANCE_MODE_ALIAS; - } - dm_ctx_init_sub(dm_ctx, instance); -} - -static void bbf_cleanup(struct dmctx *dm_ctx) -{ - dm_ctx_clean_sub(dm_ctx); -} - -static bool bbf_get(int operation, char *path, struct dmctx *dm_ctx) -{ - int fault = 0; - - switch(operation) { - case CMD_GET_NAME: - fault = dm_entry_param_method(dm_ctx, CMD_GET_NAME, path, "true", NULL); - break; - case CMD_GET_VALUE: - fault = dm_entry_param_method(dm_ctx, CMD_GET_VALUE, path, NULL, NULL); - break; - default: - return false; - } - - if (dm_ctx->list_fault_param.next != &dm_ctx->list_fault_param) { - return false; - } - if (fault) { - return false; - } - return true; -} - -static bool bbf_set_value(char *path, char *value) -{ - int fault = 0, res; - struct dmctx dm_ctx = {0}; - struct dmctx *p_dmctx = &dm_ctx; - - bbf_init(&dm_ctx, path); - - fault = dm_entry_param_method(&dm_ctx, CMD_SET_VALUE, path, value, NULL); - - if (!fault) { - fault = dm_entry_apply(&dm_ctx, CMD_SET_VALUE, "", NULL); - } - - if (p_dmctx->list_fault_param.next != &p_dmctx->list_fault_param) { - res = FAIL; - } - - if (fault) - res = FAIL; - else - res = SUCCESS; - - bbf_cleanup(&dm_ctx); - return res; -} - -static char *bbf_get_value_by_id(char *id) -{ - struct dmctx dm_ctx = {0}; - struct dm_parameter *n = NULL; - char *value = NULL; - - bbf_init(&dm_ctx, id); - if (bbf_get(CMD_GET_VALUE, id, &dm_ctx)) { - list_for_each_entry(n, &dm_ctx.list_parameter, list) { - value = dmstrdup(n->data); - break; - } - } - bbf_cleanup(&dm_ctx); - return value; -} - -char *get_param_val_from_op_cmd(char *op_cmd, const char *param) -{ - char node[256] = {'\0'}; - - // Trim action from operation command - // For eg: trim Reset from Device.IP.Interface.*.Reset - char *ret = strrchr(op_cmd, '.'); - strncpy(node, op_cmd, ret - op_cmd +1); - - // Append param name to the trimmed path - strncat(node, param, sizeof(node) - strlen(node)); - - // Get parameter value - return bbf_get_value_by_id(node); -} - -static opr_ret_t reboot_device(struct dmctx *dmctx, char *path, json_object *input) -{ - if (0 == dmubus_call_set(SYSTEM_UBUS_PATH, "reboot", UBUS_ARGS{}, 0)) - return SUCCESS; - else - return FAIL; -} - -static opr_ret_t factory_reset(struct dmctx *dmctx, char *path, json_object *input) -{ - if (0 == dmcmd_no_wait("/sbin/defaultreset", 0)) - return SUCCESS; - else - return FAIL; -} - -static opr_ret_t network_interface_reset(struct dmctx *dmctx, char *path, json_object *input) -{ - char cmd[NAME_MAX] = NETWORK_INTERFACE_UBUS_PATH; - bool status = false; - - snprintf(cmd + strlen(cmd), NAME_MAX - strlen(cmd), "%s", "."); - char *zone = get_param_val_from_op_cmd(path, "Name"); - if (zone) { - strncat(cmd, zone, NAME_MAX - strlen(cmd)); - dmfree(zone); - } else { - return FAIL; - } - if (0 == dmubus_call_set(cmd, "down", UBUS_ARGS{}, 0)) - status = true; - - if (0 == dmubus_call_set(cmd, "up", UBUS_ARGS{}, 0)) - status &= true; - - if (status) - return SUCCESS; - else - return FAIL; -} - -static opr_ret_t wireless_reset(struct dmctx *dmctx, char *path, json_object *input) -{ - if (0 == dmcmd_no_wait("/sbin/wifi", 2, "reload", "&")) - return SUCCESS; - else - return FAIL; -} - -struct wifi_security_params reset_params[] = { - {"", "ModeEnabled", ""}, - {"", "PreSharedKey", ""}, - {"", "KeyPassphrase", ""} -}; - -static opr_ret_t ap_security_reset(struct dmctx *dmctx, char *path, json_object *input) -{ - char *wpakey = NULL; - char node[255] = {'\0'}; - int i, len = 0; - - char *ret = strrchr(path, '.'); - strncpy(node, path, ret - path +1); - - len = ARRAY_SIZE(reset_params); - - for (i = 0; i < len; i++) { - DM_STRNCPY(reset_params[i].node, node, sizeof(reset_params[i].node)); - strncat(reset_params[i].node, reset_params[i].param, 255 - strlen(reset_params[i].node)); - } - const char *mode_enabled = "WPA2-Personal"; - - // Default mode - WPA2-Personal - DM_STRNCPY(reset_params[0].value, mode_enabled, sizeof(reset_params[0].value)); - - // Get Default wpakey - db_get_value_string("hw", "board", "wpa_key", &wpakey); - - // PreSharedKey and KeyPassphrase are kept same - DM_STRNCPY(reset_params[1].value, wpakey, sizeof(reset_params[1].value)); - DM_STRNCPY(reset_params[2].value, wpakey, sizeof(reset_params[2].value)); - - for (i = 0; i < len; i++) { - bbf_set_value(reset_params[i].node, reset_params[i].value); - } - return SUCCESS; -} - -static opr_ret_t dhcp_client_renew(struct dmctx *dmctx, char *path, json_object *input) -{ - if (SUCCESS == bbf_set_value(path, "true")) - return SUCCESS; - else - return FAIL; -} - -static opr_ret_t vendor_conf_backup(struct dmctx *dmctx, char *path, json_object *input) -{ - struct file_server fserver = {0}; - char obj_path[256] = {'\0'}; - char command[32] = {'\0'}; - - char *ret = strrchr(path, '.'); - strncpy(obj_path, path, ret - path +1); - DM_STRNCPY(command, ret+1, sizeof(command)); - - char *vcf_name = get_param_val_from_op_cmd(path, "Name"); - if (!vcf_name) - return FAIL; - - fserver.url = dmjson_get_value(input, 1, "URL"); - if (fserver.url[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - - fserver.user = dmjson_get_value(input, 1, "Username"); - fserver.pass = dmjson_get_value(input, 1, "Password"); - - int res = bbf_config_backup(fserver.url, fserver.user, fserver.pass, vcf_name, command, obj_path); - dmfree(vcf_name); - - return res ? FAIL : SUCCESS; -} - -static opr_ret_t vendor_conf_restore(struct dmctx *dmctx, char *path, json_object *input) -{ - struct file_server fserver = {0}; - char obj_path[256] = {'\0'}; - char command[32] = {'\0'}; - - char *ret = strrchr(path, '.'); - strncpy(obj_path, path, ret - path +1); - DM_STRNCPY(command, ret+1, sizeof(command)); - - fserver.url = dmjson_get_value(input, 1, "URL"); - if (fserver.url[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - - fserver.user = dmjson_get_value(input, 1, "Username"); - fserver.pass = dmjson_get_value(input, 1, "Password"); - fserver.file_size = dmjson_get_value(input, 1, "FileSize"); - fserver.checksum_algorithm = dmjson_get_value(input, 1, "CheckSumAlgorithm"); - fserver.checksum = dmjson_get_value(input, 1, "CheckSum"); - - int res = bbf_config_restore(fserver.url, fserver.user, fserver.pass, fserver.file_size, fserver.checksum_algorithm, fserver.checksum, command, obj_path); - - return res ? FAIL : SUCCESS; -} - -static void fill_wireless_scan_results(struct dmctx *dmctx, char *radio) -{ - json_object *res = NULL, *obj = NULL; - struct neighboring_wiFi_diagnostic neighboring = {0}; - char object[32], *ssid, *bssid, *channel, *frequency, *signal_stregth, *noise; - - snprintf(object, sizeof(object), "wifi.radio.%s", radio); - dmubus_call_set(object, "scan", UBUS_ARGS{}, 0); - sleep(2); // Wait for results to get populated in scanresults - dmubus_call(object, "scanresults", UBUS_ARGS{}, 0, &res); - - if (!res) - return; - - if (!json_object_object_get_ex(res,"accesspoints", &obj)) - return; - - uint8_t len = obj ? json_object_array_length(obj) : 0; - for (uint8_t j = 0; j < len; j++ ) { - wifi_neighbor_count++; - json_object *array_obj = json_object_array_get_idx(obj, j); - neighboring.ssid = dmjson_get_value(array_obj, 1, "ssid"); - neighboring.bssid = dmjson_get_value(array_obj, 1, "bssid"); - neighboring.channel = dmjson_get_value(array_obj, 1, "channel"); - neighboring.frequency = dmjson_get_value(array_obj, 1, "band"); - neighboring.signal_strength = dmjson_get_value(array_obj, 1, "rssi"); - neighboring.noise = dmjson_get_value(array_obj, 1, "noise"); - - dmasprintf(&ssid, "Result.%d.SSID", wifi_neighbor_count); - dmasprintf(&bssid, "Result.%d.BSSID", wifi_neighbor_count); - dmasprintf(&channel, "Result.%d.Channel", wifi_neighbor_count); - dmasprintf(&frequency, "Result.%d.OperatingFrequencyBand", wifi_neighbor_count); - dmasprintf(&signal_stregth, "Result.%d.SignalStrength", wifi_neighbor_count); - dmasprintf(&noise, "Result.%d.Noise", wifi_neighbor_count); - - add_list_parameter(dmctx, ssid, neighboring.ssid, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, bssid, neighboring.bssid, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, channel, neighboring.channel, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, frequency, neighboring.frequency, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, signal_stregth, neighboring.signal_strength, DMT_TYPE[DMT_INT], NULL); - add_list_parameter(dmctx, noise, neighboring.noise, DMT_TYPE[DMT_INT], NULL); - } -} - -static opr_ret_t fetch_neighboring_wifi_diagnostic(struct dmctx *dmctx, char *path, json_object *input) -{ - json_object *res = NULL, *radios = NULL, *arrobj = NULL; - - dmubus_call("wifi", "status", UBUS_ARGS{}, 0, &res); - if (res) { - int j = 0; - - dmjson_foreach_obj_in_array(res, arrobj, radios, j, 1, "radios") { - fill_wireless_scan_results(dmctx, dmjson_get_value(radios, 1, "name")); - } - } - wifi_neighbor_count = 0; - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_ipping(struct dmctx *dmctx, char *path, json_object *input) -{ - struct ipping_diagnostics ipping = {0}; - - init_diagnostics_operation("ipping", IPPING_PATH); - - ipping.host = dmjson_get_value(input, 1, "Host"); - if (ipping.host[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - ipping.interface = dmjson_get_value(input, 1, "Interface"); - ipping.proto = dmjson_get_value(input, 1, "ProtocolVersion"); - ipping.nbofrepetition = dmjson_get_value(input, 1, "NumberOfRepetitions"); - ipping.timeout = dmjson_get_value(input, 1, "Timeout"); - ipping.datablocksize = dmjson_get_value(input, 1, "DataBlockSize"); - ipping.dscp = dmjson_get_value(input, 1, "DSCP"); - - set_diagnostics_option("ipping", "Host", ipping.host); - set_diagnostics_interface_option(dmctx, "ipping", ipping.interface); - set_diagnostics_option("ipping", "ProtocolVersion", ipping.proto); - set_diagnostics_option("ipping", "NumberOfRepetitions", ipping.nbofrepetition); - set_diagnostics_option("ipping", "Timeout", ipping.timeout); - set_diagnostics_option("ipping", "DataBlockSize", ipping.datablocksize); - set_diagnostics_option("ipping", "DSCP", ipping.dscp); - - // Commit and Free uci_ctx_bbfdm - commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - - dmcmd("/bin/sh", 2, IPPING_PATH, "run"); - - // Allocate uci_ctx_bbfdm - dmuci_init_bbfdm(); - - ipping.success_count = get_diagnostics_option("ipping", "SuccessCount"); - ipping.failure_count = get_diagnostics_option("ipping", "FailureCount"); - ipping.average_response_time = get_diagnostics_option("ipping", "AverageResponseTime"); - ipping.minimum_response_time = get_diagnostics_option("ipping", "MinimumResponseTime"); - ipping.maximum_response_time = get_diagnostics_option("ipping", "MaximumResponseTime"); - ipping.average_response_time_detailed = get_diagnostics_option("ipping", "AverageResponseTimeDetailed"); - ipping.minimum_response_time_detailed = get_diagnostics_option("ipping", "MinimumResponseTimeDetailed"); - ipping.maximum_response_time_detailed = get_diagnostics_option("ipping", "MaximumResponseTimeDetailed"); - - add_list_parameter(dmctx, dmstrdup("SuccessCount"), ipping.success_count, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("FailureCount"), ipping.failure_count, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("AverageResponseTime"), ipping.average_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MinimumResponseTime"), ipping.minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MaximumResponseTime"), ipping.maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("AverageResponseTimeDetailed"), ipping.average_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MinimumResponseTimeDetailed"), ipping.minimum_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MaximumResponseTimeDetailed"), ipping.maximum_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_traceroute(struct dmctx *dmctx, char *path, json_object *input) -{ - struct traceroute_diagnostics traceroute = {0}; - struct uci_section *s = NULL; - char *host, *host_address, *errorcode, *rttimes; - int i = 1; - - init_diagnostics_operation("traceroute", TRACEROUTE_PATH); - - traceroute.host = dmjson_get_value(input, 1, "Host"); - if (traceroute.host[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - traceroute.interface = dmjson_get_value(input, 1, "Interface"); - traceroute.proto = dmjson_get_value(input, 1, "ProtocolVersion"); - traceroute.nboftries = dmjson_get_value(input, 1, "NumberOfTries"); - traceroute.timeout = dmjson_get_value(input, 1, "Timeout"); - traceroute.datablocksize = dmjson_get_value(input, 1, "DataBlockSize"); - traceroute.dscp = dmjson_get_value(input, 1, "DSCP"); - traceroute.maxhops = dmjson_get_value(input, 1, "MaxHopCount"); - - set_diagnostics_option("traceroute", "Host", traceroute.host); - set_diagnostics_interface_option(dmctx, "traceroute", traceroute.interface); - set_diagnostics_option("traceroute", "ProtocolVersion", traceroute.proto); - set_diagnostics_option("traceroute", "NumberOfTries", traceroute.nboftries); - set_diagnostics_option("traceroute", "Timeout", traceroute.timeout); - set_diagnostics_option("traceroute", "DataBlockSize", traceroute.datablocksize); - set_diagnostics_option("traceroute", "DSCP", traceroute.dscp); - set_diagnostics_option("traceroute", "MaxHops", traceroute.maxhops); - - // Commit and Free uci_ctx_bbfdm - commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - - dmcmd("/bin/sh", 2, TRACEROUTE_PATH, "run"); - - // Allocate uci_ctx_bbfdm - dmuci_init_bbfdm(); - - traceroute.response_time = get_diagnostics_option("traceroute", "ResponseTime"); - add_list_parameter(dmctx, dmstrdup("ResponseTime"), traceroute.response_time, DMT_TYPE[DMT_UNINT], NULL); - - uci_path_foreach_sections(bbfdm, DMMAP_DIAGNOSTIGS, "RouteHops", s) { - dmasprintf(&host, "RouteHops.%d.Host", i); - dmasprintf(&host_address, "RouteHops.%d.HostAddress", i); - dmasprintf(&errorcode, "RouteHops.%d.ErrorCode", i); - dmasprintf(&rttimes, "RouteHops.%d.RTTimes", i); - - dmuci_get_value_by_section_string(s, "host", &traceroute.host_name); - dmuci_get_value_by_section_string(s, "ip", &traceroute.host_address); - dmuci_get_value_by_section_string(s, "time", &traceroute.rttimes); - - add_list_parameter(dmctx, host, traceroute.host_name, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, host_address, traceroute.host_address, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, errorcode, "0", DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, rttimes, traceroute.rttimes, DMT_TYPE[DMT_STRING], NULL); - i++; - } - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_download(struct dmctx *dmctx, char *path, json_object *input) -{ - struct download_diagnostics download = {0}; - - init_diagnostics_operation("download", DOWNLOAD_DIAGNOSTIC_PATH); - - download.download_url = dmjson_get_value(input, 1, "DownloadURL"); - if (download.download_url[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - download.interface = dmjson_get_value(input, 1, "Interface"); - download.dscp = dmjson_get_value(input, 1, "DSCP"); - download.ethernet_priority = dmjson_get_value(input, 1, "EthernetPriority"); - download.proto = dmjson_get_value(input, 1, "ProtocolVersion"); - download.num_of_connections = dmjson_get_value(input, 1, "NumberOfConnections"); - download.enable_per_connection_results = dmjson_get_value(input, 1, "EnablePerConnectionResults"); - - set_diagnostics_option("download", "url", download.download_url); - set_diagnostics_interface_option(dmctx, "download", download.interface); - set_diagnostics_option("download", "DSCP", download.dscp); - set_diagnostics_option("download", "ethernetpriority", download.ethernet_priority); - set_diagnostics_option("download", "ProtocolVersion", download.proto); - set_diagnostics_option("download", "NumberOfConnections", download.num_of_connections); - set_diagnostics_option("download", "EnablePerConnection", download.enable_per_connection_results); - - if (start_upload_download_diagnostic(DOWNLOAD_DIAGNOSTIC) == -1) - return FAIL; - - download.romtime = get_diagnostics_option("download", "ROMtime"); - download.bomtime = get_diagnostics_option("download", "BOMtime"); - download.eomtime = get_diagnostics_option("download", "EOMtime"); - download.test_bytes_received = get_diagnostics_option("download", "TestBytesReceived"); - download.total_bytes_received = get_diagnostics_option("download", "TotalBytesReceived"); - download.total_bytes_sent = get_diagnostics_option("download", "TotalBytesSent"); - download.test_bytes_received_under_full_loading = get_diagnostics_option("download", "TestBytesReceived"); - download.total_bytes_received_under_full_loading = get_diagnostics_option("download", "TotalBytesReceived"); - download.total_bytes_sent_under_full_loading = get_diagnostics_option("download", "TotalBytesSent"); - download.period_of_full_loading = get_diagnostics_option("download", "PeriodOfFullLoading"); - download.tcp_open_request_time = get_diagnostics_option("download", "TCPOpenRequestTime"); - download.tcp_open_response_time = get_diagnostics_option("download", "TCPOpenResponseTime"); - - add_list_parameter(dmctx, dmstrdup("ROMTime"), download.romtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("BOMTime"), download.bomtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("EOMTime"), download.eomtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("TestBytesReceived"), download.test_bytes_received, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesReceived"), download.total_bytes_received, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesSent"), download.total_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TestBytesReceivedUnderFullLoading"), download.test_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesReceivedUnderFullLoading"), download.total_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesSentUnderFullLoading"), download.total_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("PeriodOfFullLoading"), download.period_of_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TCPOpenRequestTime"), download.tcp_open_request_time, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("TCPOpenResponseTime"), download.tcp_open_response_time, DMT_TYPE[DMT_TIME], NULL); - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_upload(struct dmctx *dmctx, char *path, json_object *input) -{ - struct upload_diagnostics upload = {0}; - - init_diagnostics_operation("upload", UPLOAD_DIAGNOSTIC_PATH); - - upload.upload_url = dmjson_get_value(input, 1, "UploadURL"); - if (upload.upload_url[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - upload.test_file_length = dmjson_get_value(input, 1, "TestFileLength"); - if (upload.test_file_length[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - upload.interface = dmjson_get_value(input, 1, "Interface"); - upload.dscp = dmjson_get_value(input, 1, "DSCP"); - upload.ethernet_priority = dmjson_get_value(input, 1, "EthernetPriority"); - upload.proto = dmjson_get_value(input, 1, "ProtocolVersion"); - upload.num_of_connections = dmjson_get_value(input, 1, "NumberOfConnections"); - upload.enable_per_connection_results = dmjson_get_value(input, 1, "EnablePerConnectionResults"); - - set_diagnostics_option("upload", "url", upload.upload_url); - set_diagnostics_option("upload", "TestFileLength", upload.test_file_length); - set_diagnostics_interface_option(dmctx, "upload", upload.interface); - set_diagnostics_option("upload", "DSCP", upload.dscp); - set_diagnostics_option("upload", "ethernetpriority", upload.ethernet_priority); - set_diagnostics_option("upload", "ProtocolVersion", upload.proto); - set_diagnostics_option("upload", "NumberOfConnections", upload.num_of_connections); - set_diagnostics_option("upload", "EnablePerConnection", upload.enable_per_connection_results); - - if (start_upload_download_diagnostic(UPLOAD_DIAGNOSTIC) == -1) - return FAIL; - - upload.romtime = get_diagnostics_option("upload", "ROMtime"); - upload.bomtime = get_diagnostics_option("upload", "BOMtime"); - upload.eomtime = get_diagnostics_option("upload", "EOMtime"); - upload.test_bytes_sent = get_diagnostics_option("upload", "TestBytesSent"); - upload.total_bytes_received = get_diagnostics_option("upload", "TotalBytesReceived"); - upload.total_bytes_sent = get_diagnostics_option("upload", "TotalBytesSent"); - upload.test_bytes_sent_under_full_loading = get_diagnostics_option("upload", "TestBytesSent"); - upload.total_bytes_received_under_full_loading = get_diagnostics_option("upload", "TotalBytesReceived"); - upload.total_bytes_sent_under_full_loading = get_diagnostics_option("upload", "TotalBytesSent"); - upload.period_of_full_loading = get_diagnostics_option("upload", "PeriodOfFullLoading"); - upload.tcp_open_request_time = get_diagnostics_option("upload", "TCPOpenRequestTime"); - upload.tcp_open_response_time = get_diagnostics_option("upload", "TCPOpenResponseTime"); - - add_list_parameter(dmctx, dmstrdup("ROMTime"), upload.romtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("BOMTime"), upload.bomtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("EOMTime"), upload.eomtime, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("TestBytesSent"), upload.test_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesReceived"), upload.total_bytes_received, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesSent"), upload.total_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TestBytesSentUnderFullLoading"), upload.test_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesReceivedUnderFullLoading"), upload.total_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TotalBytesSentUnderFullLoading"), upload.total_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("PeriodOfFullLoading"), upload.period_of_full_loading, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("TCPOpenRequestTime"), upload.tcp_open_request_time, DMT_TYPE[DMT_TIME], NULL); - add_list_parameter(dmctx, dmstrdup("TCPOpenResponseTime"), upload.tcp_open_response_time, DMT_TYPE[DMT_TIME], NULL); - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_udpecho(struct dmctx *dmctx, char *path, json_object *input) -{ - struct udpecho_diagnostics udpecho = {0}; - - init_diagnostics_operation("udpechodiag", UDPECHO_PATH); - - udpecho.host = dmjson_get_value(input, 1, "Host"); - if (udpecho.host[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - - udpecho.port = dmjson_get_value(input, 1, "Port"); - if (udpecho.port[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - - udpecho.interface = dmjson_get_value(input, 1, "Interface"); - udpecho.proto = dmjson_get_value(input, 1, "ProtocolVersion"); - udpecho.nbofrepetition = dmjson_get_value(input, 1, "NumberOfRepetitions"); - udpecho.timeout = dmjson_get_value(input, 1, "Timeout"); - udpecho.datablocksize = dmjson_get_value(input, 1, "DataBlockSize"); - udpecho.dscp = dmjson_get_value(input, 1, "DSCP"); - udpecho.inter_transmission_time = dmjson_get_value(input, 1, "InterTransmissionTime"); - - set_diagnostics_option("udpechodiag", "Host", udpecho.host); - set_diagnostics_option("udpechodiag", "port", udpecho.port); - set_diagnostics_interface_option(dmctx, "udpechodiag", udpecho.interface); - set_diagnostics_option("udpechodiag", "ProtocolVersion", udpecho.proto); - set_diagnostics_option("udpechodiag", "NumberOfRepetitions", udpecho.nbofrepetition); - set_diagnostics_option("udpechodiag", "Timeout", udpecho.timeout); - set_diagnostics_option("udpechodiag", "DataBlockSize", udpecho.datablocksize); - set_diagnostics_option("udpechodiag", "DSCP", udpecho.dscp); - set_diagnostics_option("udpechodiag", "InterTransmissionTime", udpecho.inter_transmission_time); - - // Commit and Free uci_ctx_bbfdm - commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - - dmcmd("/bin/sh", 2, UDPECHO_PATH, "run"); - - // Allocate uci_ctx_bbfdm - dmuci_init_bbfdm(); - - udpecho.success_count = get_diagnostics_option("udpechodiag", "SuccessCount"); - udpecho.failure_count = get_diagnostics_option("udpechodiag", "FailureCount"); - udpecho.average_response_time = get_diagnostics_option("udpechodiag", "AverageResponseTime"); - udpecho.minimum_response_time = get_diagnostics_option("udpechodiag", "MinimumResponseTime"); - udpecho.maximum_response_time = get_diagnostics_option("udpechodiag", "MaximumResponseTime"); - - add_list_parameter(dmctx, dmstrdup("SuccessCount"), udpecho.success_count, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("FailureCount"), udpecho.failure_count, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("AverageResponseTime"), udpecho.average_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MinimumResponseTime"), udpecho.minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MaximumResponseTime"), udpecho.maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_serverselection(struct dmctx *dmctx, char *path, json_object *input) -{ - struct serverselection_diagnostics serverselection = {0}; - - init_diagnostics_operation("serverselection", SERVERSELECTION_PATH); - - serverselection.hostlist = dmjson_get_value(input, 1, "HostList"); - if (serverselection.hostlist[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - serverselection.port = dmjson_get_value(input, 1, "Port"); - serverselection.proto = dmjson_get_value(input, 1, "Protocol"); - if (strcmp(serverselection.proto, "ICMP")) { - if (serverselection.port[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - } - serverselection.protocol_version = dmjson_get_value(input, 1, "ProtocolVersion"); - serverselection.interface = dmjson_get_value(input, 1, "Interface"); - serverselection.nbofrepetition = dmjson_get_value(input, 1, "NumberOfRepetitions"); - serverselection.timeout = dmjson_get_value(input, 1, "Timeout"); - - set_diagnostics_option("serverselection", "HostList", serverselection.hostlist); - set_diagnostics_interface_option(dmctx, "serverselection", serverselection.interface); - set_diagnostics_option("serverselection", "ProtocolVersion", serverselection.protocol_version); - set_diagnostics_option("serverselection", "NumberOfRepetitions", serverselection.nbofrepetition); - set_diagnostics_option("serverselection", "port", serverselection.port); - set_diagnostics_option("serverselection", "Protocol", serverselection.proto); - set_diagnostics_option("serverselection", "Timeout", serverselection.timeout); - - // Commit and Free uci_ctx_bbfdm - commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - - dmcmd("/bin/sh", 2, SERVERSELECTION_PATH, "run"); - - // Allocate uci_ctx_bbfdm - dmuci_init_bbfdm(); - - serverselection.fasthost = get_diagnostics_option("serverselection", "FastestHost"); - serverselection.average_response_time = get_diagnostics_option("serverselection", "AverageResponseTime"); - serverselection.minimum_response_time = get_diagnostics_option("serverselection", "MinimumResponseTime"); - serverselection.maximum_response_time = get_diagnostics_option("serverselection", "MaximumResponseTime"); - - add_list_parameter(dmctx, dmstrdup("FastestHost"), serverselection.fasthost, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, dmstrdup("AverageResponseTime"), serverselection.average_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MinimumResponseTime"), serverselection.minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); - add_list_parameter(dmctx, dmstrdup("MaximumResponseTime"), serverselection.maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); - - return SUCCESS; -} - -static opr_ret_t ip_diagnostics_nslookup(struct dmctx *dmctx, char *path, json_object *input) -{ - struct nslookup_diagnostics nslookup = {0}; - struct uci_section *s = NULL; - char *status, *answertype, *hostname, *ipaddress, *dnsserverip, *responsetime; - int i = 1; - - init_diagnostics_operation("nslookup", NSLOOKUP_PATH); - - nslookup.hostname = dmjson_get_value(input, 1, "HostName"); - if (nslookup.hostname[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - nslookup.interface = dmjson_get_value(input, 1, "Interface"); - nslookup.dnsserver = dmjson_get_value(input, 1, "DNSServer"); - nslookup.timeout = dmjson_get_value(input, 1, "Timeout"); - nslookup.nbofrepetition = dmjson_get_value(input, 1, "NumberOfRepetitions"); - - set_diagnostics_option("nslookup", "HostName", nslookup.hostname); - set_diagnostics_interface_option(dmctx, "nslookup", nslookup.interface); - set_diagnostics_option("nslookup", "DNSServer", nslookup.dnsserver); - set_diagnostics_option("nslookup", "Timeout", nslookup.timeout); - set_diagnostics_option("nslookup", "NumberOfRepetitions", nslookup.nbofrepetition); - - // Commit and Free uci_ctx_bbfdm - commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); - - dmcmd("/bin/sh", 2, NSLOOKUP_PATH, "run"); - - // Allocate uci_ctx_bbfdm - dmuci_init_bbfdm(); - - nslookup.success_count = get_diagnostics_option("nslookup", "SuccessCount"); - char *param_success_count = dmstrdup("SuccessCount"); - add_list_parameter(dmctx, param_success_count, nslookup.success_count, DMT_TYPE[DMT_UNINT], NULL); - - uci_path_foreach_sections(bbfdm, DMMAP_DIAGNOSTIGS, "NSLookupResult", s) { - dmasprintf(&status, "Result.%d.Status", i); - dmasprintf(&answertype, "Result.%d.AnswerType", i); - dmasprintf(&hostname, "Result.%d.HostNameReturned", i); - dmasprintf(&ipaddress, "Result.%d.IPAddresses", i); - dmasprintf(&dnsserverip, "Result.%d.DNSServerIP", i); - dmasprintf(&responsetime, "Result.%d.ResponseTime", i); - - dmuci_get_value_by_section_string(s, "Status", &nslookup.status); - dmuci_get_value_by_section_string(s, "AnswerType", &nslookup.answer_type); - dmuci_get_value_by_section_string(s, "HostNameReturned", &nslookup.hostname_returned); - dmuci_get_value_by_section_string(s, "IPAddresses", &nslookup.ip_addresses); - dmuci_get_value_by_section_string(s, "DNSServerIP", &nslookup.dns_server_ip); - dmuci_get_value_by_section_string(s, "ResponseTime", &nslookup.response_time); - - add_list_parameter(dmctx, status, nslookup.status, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, answertype, nslookup.answer_type, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, hostname, nslookup.hostname_returned, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, ipaddress, nslookup.ip_addresses, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, dnsserverip, nslookup.dns_server_ip, DMT_TYPE[DMT_STRING], NULL); - add_list_parameter(dmctx, responsetime, nslookup.response_time, DMT_TYPE[DMT_UNINT], NULL); - i++; - } - - return SUCCESS; -} - -static opr_ret_t firmware_image_download(struct dmctx *dmctx, char *path, json_object *input) -{ - char obj_path[256] = {'\0'}; - char command[32] = {'\0'}; - char *bank_id = NULL; - char *linker = NULL; - - char *ret = strrchr(path, '.'); - strncpy(obj_path, path, ret - path +1); - DM_STRNCPY(command, ret+1, sizeof(command)); - - adm_entry_get_linker_value(dmctx, obj_path, &linker); - if (linker && *linker) { - bank_id = strchr(linker, ':'); - if (!bank_id) - return FAIL; - } else { - return FAIL; - } - - char *url = dmjson_get_value(input, 1, "URL"); - char *auto_activate = dmjson_get_value(input, 1, "AutoActivate"); - if (url[0] == '\0' || auto_activate[0] == '\0') - return UBUS_INVALID_ARGUMENTS; - - char *username = dmjson_get_value(input, 1, "Username"); - char *password = dmjson_get_value(input, 1, "Password"); - char *file_size = dmjson_get_value(input, 1, "FileSize"); - char *checksum_algorithm = dmjson_get_value(input, 1, "CheckSumAlgorithm"); - char *checksum = dmjson_get_value(input, 1, "CheckSum"); - - int res = bbf_fw_image_download(url, auto_activate, username, password, file_size, checksum_algorithm, checksum, bank_id+1, command, obj_path); - - return res ? FAIL : SUCCESS; -} - -static opr_ret_t firmware_image_activate(struct dmctx *dmctx, char *path, json_object *input) -{ - struct activate_image active_images[MAX_TIME_WINDOW] = {0}; - char fwimage_path[256] = {'\0'}; - char *bank_id = NULL; - char *linker = NULL; - - char *ret = strrchr(path, '.'); - strncpy(fwimage_path, path, ret - path +1); - - adm_entry_get_linker_value(dmctx, fwimage_path, &linker); - if (linker && *linker) { - bank_id = strchr(linker, ':'); - if (!bank_id) - return FAIL; - } else { - return FAIL; - } - - for (int i = 0; i < ARRAY_SIZE(fw_image_activate_in); i++) - active_images[i].start_time = dmjson_get_value(input, 1, fw_image_activate_in[i]); - - int res = bbf_fw_image_activate(bank_id+1, active_images); - - return res ? FAIL : SUCCESS; -} - -static int get_index_of_available_dynamic_operate(struct op_cmd *operate) -{ - int idx = 0; - for (; (operate && operate->name); operate++) { - idx++; - } - return idx; -} - -int add_dynamic_operate(char *path, operation operate, char *type, operation_args args) -{ - if (dynamic_operate == NULL) { - dynamic_operate = calloc(2, sizeof(struct op_cmd)); - dynamic_operate[0].name = path; - dynamic_operate[0].opt = operate; - dynamic_operate[0].type = type; - dynamic_operate[0].args = args; - } else { - int idx = get_index_of_available_dynamic_operate(dynamic_operate); - struct op_cmd *new_dynamic_operate = realloc(dynamic_operate, (idx + 2) * sizeof(struct op_cmd)); - if (new_dynamic_operate == NULL) - FREE(dynamic_operate); - else - dynamic_operate = new_dynamic_operate; - memset(dynamic_operate + (idx + 1), 0, sizeof(struct op_cmd)); - dynamic_operate[idx].name = path; - dynamic_operate[idx].opt = operate; - dynamic_operate[idx].type = type; - dynamic_operate[idx].args = args; - } - return 0; -} - -static const struct op_cmd operate_helper[] = { - { - "Device.Reboot", reboot_device, "sync" - }, - { - "Device.FactoryReset", factory_reset, "sync" - }, - { - "Device.IP.Interface.*.Reset", network_interface_reset, "sync" - }, - { - "Device.PPP.Interface.*.Reset", network_interface_reset, "sync" - }, - { - "Device.WiFi.Reset", wireless_reset, "sync" - }, - { - "Device.WiFi.AccessPoint.*.Security.Reset", ap_security_reset, "sync" - }, - { - "Device.DHCPv4.Client.*.Renew", dhcp_client_renew, "sync" - }, - { - "Device.DHCPv6.Client.*.Renew", dhcp_client_renew, "sync" - }, - { - "Device.DeviceInfo.VendorConfigFile.*.Backup", vendor_conf_backup, "async", - { - .in = (const char *[]) { - "URL", - "Username", - "Password", - NULL - } - } - }, - { - "Device.DeviceInfo.VendorConfigFile.*.Restore", vendor_conf_restore, "async", - { - .in = (const char *[]) { - "URL", - "Username", - "Password", - "FileSize", - "TargetFileName", - "CheckSumAlgorithm", - "CheckSum", - NULL - } - } - }, - { - "Device.DeviceInfo.FirmwareImage.*.Download", firmware_image_download, "async", - { - .in = (const char *[]) { - "URL", - "AutoActivate", - "Username", - "Password", - "FileSize", - "CheckSumAlgorithm", - "CheckSum", - NULL - } - } - }, - { - "Device.DeviceInfo.FirmwareImage.*.Activate", firmware_image_activate, "async", - { - .in = (const char *[]) { - "TimeWindow.{i}.Start", - "TimeWindow.{i}.End", - "TimeWindow.{i}.Mode", - "TimeWindow.{i}.UserMessage", - "TimeWindow.{i}.MaxRetries", - NULL - } - } - }, - { - "Device.WiFi.NeighboringWiFiDiagnostic", fetch_neighboring_wifi_diagnostic, "async", - { - .out = (const char *[]) { - "Status", - NULL - } - } - }, - { - "Device.IP.Diagnostics.IPPing", ip_diagnostics_ipping, "async", - { - .in = (const char *[]) { - "Interface", - "ProtocolVersion", - "Host", - "NumberOfRepetitions", - "Timeout", - "DataBlockSize", - "DSCP", - NULL - }, - .out = (const char *[]) { - "Status", - "IPAddressUsed", - "SuccessCount", - "FailureCount", - "AverageResponseTime", - "MinimumResponseTime", - "MaximumResponseTime", - "AverageResponseTimeDetailed", - "MinimumResponseTimeDetailed", - "MaximumResponseTimeDetailed", - NULL - } - } - }, - { - "Device.IP.Diagnostics.TraceRoute", ip_diagnostics_traceroute, "async", - { - .in = (const char *[]) { - "Interface", - "ProtocolVersion", - "Host", - "NumberOfTries", - "Timeout", - "DataBlockSize", - "DSCP", - "MaxHopCount", - NULL - }, - .out = (const char *[]) { - "Status", - "IPAddressUsed", - "ResponseTime", - NULL - } - } - }, - { - "Device.IP.Diagnostics.DownloadDiagnostics", ip_diagnostics_download, "async", - { - .in = (const char *[]) { - "Interface", - "DownloadURL", - "DSCP", - "EthernetPriority", - "TimeBasedTestDuration", - "TimeBasedTestMeasurementInterval", - "TimeBasedTestMeasurementOffset", - "ProtocolVersion", - "NumberOfConnections", - "EnablePerConnectionResults", - NULL - }, - .out = (const char *[]) { - "Status", - "IPAddressUsed", - "ROMTime", - "BOMTime", - "EOMTime", - "TestBytesReceived", - "TotalBytesReceived", - "TotalBytesSent", - "TestBytesReceivedUnderFullLoading", - "TotalBytesReceivedUnderFullLoading", - "TotalBytesSentUnderFullLoading", - "PeriodOfFullLoading", - "TCPOpenRequestTime", - "TCPOpenResponseTime", - NULL - } - } - }, - { - "Device.IP.Diagnostics.UploadDiagnostics", ip_diagnostics_upload, "async", - { - .in = (const char *[]) { - "Interface", - "UploadURL", - "DSCP", - "EthernetPriority", - "TestFileLength", - "TimeBasedTestDuration", - "TimeBasedTestMeasurementInterval", - "TimeBasedTestMeasurementOffset", - "ProtocolVersion", - "NumberOfConnections", - "EnablePerConnectionResults", - NULL - }, - .out = (const char *[]) { - "Status", - "IPAddressUsed", - "ROMTime", - "BOMTime", - "EOMTime", - "TestBytesSent", - "TotalBytesReceived", - "TotalBytesSent", - "TestBytesSentUnderFullLoading", - "TotalBytesReceivedUnderFullLoading", - "TotalBytesSentUnderFullLoading", - "PeriodOfFullLoading", - "TCPOpenRequestTime", - "TCPOpenResponseTime", - NULL - } - } - }, - { - "Device.IP.Diagnostics.UDPEchoDiagnostics", ip_diagnostics_udpecho, "async", - { - .in = (const char *[]) { - "Interface", - "Host", - "Port", - "NumberOfRepetitions", - "Timeout", - "DataBlockSize", - "DSCP", - "InterTransmissionTime", - "ProtocolVersion", - "EnableIndividualPacketResults", - NULL - }, - .out = (const char *[]) { - "Status", - "IPAddressUsed", - "SuccessCount", - "FailureCount", - "AverageResponseTime", - "MinimumResponseTime", - "MaximumResponseTime", - NULL - } - } - }, - { - "Device.IP.Diagnostics.ServerSelectionDiagnostics", ip_diagnostics_serverselection, "async", - { - .in = (const char *[]) { - "Interface", - "ProtocolVersion", - "Protocol", - "HostList", - "NumberOfRepetitions", - "Timeout", - NULL - }, - .out = (const char *[]) { - "Status", - "FastestHost", - "MinimumResponseTime", - "AverageResponseTime", - "MaximumResponseTime", - "IPAddressUsed", - NULL - } - } - }, - { - "Device.DNS.Diagnostics.NSLookupDiagnostics", ip_diagnostics_nslookup, "async", - { - .in = (const char *[]) { - "HostName", - "Interface", - "DNSServer", - "Timeout", - "NumberOfRepetitions", - NULL - }, - .out = (const char *[]) { - "Status", - "AnswerType", - "HostNameReturned", - "IPAddresses", - "DNSServerIP", - "ResponseTime", - NULL - } - } - }, -}; - -void operate_list_cmds(struct dmctx *dmctx) -{ - char *param, *type; - const operation_args *args; - const size_t n = ARRAY_SIZE(operate_helper); - size_t i; - struct op_cmd *save_pointer = NULL; - - if (dynamic_operate) - save_pointer = dynamic_operate; - - for(i = 0; i < n; i++) { - param = dmstrdup(operate_helper[i].name); - type = (char *)operate_helper[i].type; - args = &operate_helper[i].args; - add_list_parameter(dmctx, param, (char *)args, type, NULL); - } - - for (; (dynamic_operate && dynamic_operate->name); dynamic_operate++) { - param = dmstrdup(dynamic_operate->name); - type = (char *)dynamic_operate->type; - args = &dynamic_operate->args; - add_list_parameter(dmctx, param, (char *)args, type, NULL); - } - - if (save_pointer) - dynamic_operate = save_pointer; -} - -static opr_ret_t do_operate(struct dmctx *dmctx, char *path, operation func, const char *input) -{ - json_object *j_input; - opr_ret_t rc; - - if (input) - j_input = json_tokener_parse(input); - else - j_input = NULL; - - rc = func(dmctx, path, j_input); - json_object_put(j_input); - return rc; -} - -opr_ret_t operate_on_node(struct dmctx *dmctx, char *path, char *input) -{ - struct op_cmd *save_pointer = NULL; - const struct op_cmd *op = NULL; - const size_t n = ARRAY_SIZE(operate_helper); - size_t i; - - if (dynamic_operate) - save_pointer = dynamic_operate; - - for (i = 0; i < n; i++) { - op = &operate_helper[i]; - - if (match(path, op->name)) - return do_operate(dmctx, path, op->opt, input); - } - - for (; (dynamic_operate && dynamic_operate->name); dynamic_operate++) { - if (match(path, dynamic_operate->name)) { - opr_ret_t res = do_operate(dmctx, path, dynamic_operate->opt, input); - if (save_pointer) dynamic_operate = save_pointer; - return res; - } - } - - if (save_pointer) - dynamic_operate = save_pointer; - - return CMD_NOT_FOUND; -} diff --git a/dmoperate.h b/dmoperate.h deleted file mode 100644 index 74259b90..00000000 --- a/dmoperate.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * dmoperate.c: Operate handler for uspd - * - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Vivek Dutta - * Author: Yashvardhan - * Author: Amin Ben Ramdhane - * - */ - -#ifndef __DMOPERATE_H__ -#define __DMOPERATE_H__ - -#include "dmentry.h" -#include "dmdiagnostics.h" - -#define SYSTEM_UBUS_PATH "system" -#define NETWORK_INTERFACE_UBUS_PATH "network.interface" - -extern struct op_cmd *dynamic_operate; - -struct wifi_security_params { - char node[256]; - char *param; - char value[256]; -}; - -struct file_server { - char *url; - char *user; - char *pass; - char *file_size; - char *checksum_algorithm; - char *checksum; -}; - -struct neighboring_wiFi_diagnostic { - char *radio; - char *ssid; - char *bssid; - char *channel; - char *frequency; - char *encryption_mode; - char *operating_frequency_band; - char *supported_standards; - char *operating_standards; - char *operating_channel_bandwidth; - char *signal_strength; - char *noise; -}; - -struct ipping_diagnostics { - char *host; - char *interface; - char *proto; - char *nbofrepetition; - char *timeout; - char *datablocksize; - char *dscp; - char *success_count; - char *failure_count; - char *average_response_time; - char *minimum_response_time; - char *maximum_response_time; - char *average_response_time_detailed; - char *minimum_response_time_detailed; - char *maximum_response_time_detailed; -}; - -struct traceroute_diagnostics { - char *host; - char *interface; - char *proto; - char *nboftries; - char *timeout; - char *datablocksize; - char *dscp; - char *maxhops; - char *response_time; - char *host_name; - char *host_address; - char *rttimes; -}; - -struct download_diagnostics { - char *interface; - char *download_url; - char *dscp; - char *ethernet_priority; - char *proto; - char *num_of_connections; - char *enable_per_connection_results; - char *romtime; - char *bomtime; - char *eomtime; - char *test_bytes_received; - char *total_bytes_received; - char *total_bytes_sent; - char *test_bytes_received_under_full_loading; - char *total_bytes_received_under_full_loading; - char *total_bytes_sent_under_full_loading; - char *period_of_full_loading; - char *tcp_open_request_time; - char *tcp_open_response_time; - char *per_conn_romtime; - char *per_conn_bomtime; - char *per_conn_eomtime; - char *per_conn_test_bytes_received; - char *per_conn_total_bytes_received; - char *per_conn_total_bytes_sent; - char *per_conn_period_of_full_loading; - char *per_conn_tcp_open_request_time; - char *per_conn_tcp_open_response_time; -}; - -struct upload_diagnostics { - char *interface; - char *upload_url; - char *dscp; - char *ethernet_priority; - char *test_file_length; - char *proto; - char *num_of_connections; - char *enable_per_connection_results; - char *romtime; - char *bomtime; - char *eomtime; - char *test_bytes_sent; - char *total_bytes_received; - char *total_bytes_sent; - char *test_bytes_sent_under_full_loading; - char *total_bytes_received_under_full_loading; - char *total_bytes_sent_under_full_loading; - char *period_of_full_loading; - char *tcp_open_request_time; - char *tcp_open_response_time; - char *per_conn_romtime; - char *per_conn_bomtime; - char *per_conn_eomtime; - char *per_conn_test_bytes_sent; - char *per_conn_total_bytes_received; - char *per_conn_total_bytes_sent; - char *per_conn_period_of_full_loading; - char *per_conn_tcp_open_request_time; - char *per_conn_tcp_open_response_time; -}; - -struct udpecho_diagnostics { - char *host; - char *interface; - char *port; - char *nbofrepetition; - char *timeout; - char *datablocksize; - char *dscp; - char *inter_transmission_time; - char *response_time; - char *proto; - char *success_count; - char *failure_count; - char *average_response_time; - char *minimum_response_time; - char *maximum_response_time; -}; - -struct serverselection_diagnostics { - char *interface; - char *protocol_version; - char *proto; - char *hostlist; - char *port; - char *nbofrepetition; - char *timeout; - char *fasthost; - char *average_response_time; - char *minimum_response_time; - char *maximum_response_time; -}; - -struct nslookup_diagnostics { - char *interface; - char *hostname; - char *dnsserver; - char *timeout; - char *nbofrepetition; - char *success_count; - char *status; - char *answer_type; - char *hostname_returned; - char *ip_addresses; - char *dns_server_ip; - char *response_time; -}; - -struct op_cmd { - const char *name; - operation opt; - const char *type; - operation_args args; -}; - -int add_dynamic_operate(char *path, operation operate, char *type, operation_args args); -void operate_list_cmds(struct dmctx *dmctx); -opr_ret_t operate_on_node(struct dmctx *dmctx, char *path, char *input); - -#endif diff --git a/dmtree/tr143/diagnostics.c b/dmtree/tr143/diagnostics.c index 48b95f45..9918803c 100644 --- a/dmtree/tr143/diagnostics.c +++ b/dmtree/tr143/diagnostics.c @@ -14,12 +14,18 @@ #include "dmbbfcommon.h" #include "diagnostics.h" +/************************************************************* +* COMMON FUNCTIONS +**************************************************************/ static int get_diag_enable_true(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = "1"; return 0; } +/************************************************************* +* GET & SET PARAM +**************************************************************/ /* * *** Device.IP.Diagnostics.IPPing. *** */ @@ -1565,6 +1571,9 @@ static int get_IPDiagnosticsServerSelectionDiagnostics_MaximumResponseTime(char return 0; } +/************************************************************* +* ENTRY METHOD +**************************************************************/ static int browseIPDiagnosticsTraceRouteRouteHopsInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { struct uci_section *s = NULL; @@ -1613,6 +1622,544 @@ static int browseIPDiagnosticsUploadDiagnosticsPerConnectionResultInst(struct dm return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static operation_args ip_diagnostics_ipping_args = { + .in = (const char *[]) { + "Interface", + "ProtocolVersion", + "Host", + "NumberOfRepetitions", + "Timeout", + "DataBlockSize", + "DSCP", + NULL + }, + .out = (const char *[]) { + "Status", + "IPAddressUsed", + "SuccessCount", + "FailureCount", + "AverageResponseTime", + "MinimumResponseTime", + "MaximumResponseTime", + "AverageResponseTimeDetailed", + "MinimumResponseTimeDetailed", + "MaximumResponseTimeDetailed", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_IPPing(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_ipping_args; + return 0; +} + +static int operate_IPDiagnostics_IPPing(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + init_diagnostics_operation("ipping", IPPING_PATH); + + char *ipping_host = dmjson_get_value((json_object *)value, 1, "Host"); + if (ipping_host[0] == '\0') + return CMD_INVALID_ARGUMENTS; + char *ipping_interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *ipping_proto = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *ipping_nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions"); + char *ipping_timeout = dmjson_get_value((json_object *)value, 1, "Timeout"); + char *ipping_datablocksize = dmjson_get_value((json_object *)value, 1, "DataBlockSize"); + char *ipping_dscp = dmjson_get_value((json_object *)value, 1, "DSCP"); + + set_diagnostics_option("ipping", "Host", ipping_host); + set_diagnostics_interface_option(ctx, "ipping", ipping_interface); + set_diagnostics_option("ipping", "ProtocolVersion", ipping_proto); + set_diagnostics_option("ipping", "NumberOfRepetitions", ipping_nbofrepetition); + set_diagnostics_option("ipping", "Timeout", ipping_timeout); + set_diagnostics_option("ipping", "DataBlockSize", ipping_datablocksize); + set_diagnostics_option("ipping", "DSCP", ipping_dscp); + + // Commit and Free uci_ctx_bbfdm + commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); + + dmcmd("/bin/sh", 2, IPPING_PATH, "run"); + + // Allocate uci_ctx_bbfdm + dmuci_init_bbfdm(); + + char *ipping_success_count = get_diagnostics_option("ipping", "SuccessCount"); + char *ipping_failure_count = get_diagnostics_option("ipping", "FailureCount"); + char *ipping_average_response_time = get_diagnostics_option("ipping", "AverageResponseTime"); + char *ipping_minimum_response_time = get_diagnostics_option("ipping", "MinimumResponseTime"); + char *ipping_maximum_response_time = get_diagnostics_option("ipping", "MaximumResponseTime"); + char *ipping_average_response_time_detailed = get_diagnostics_option("ipping", "AverageResponseTimeDetailed"); + char *ipping_minimum_response_time_detailed = get_diagnostics_option("ipping", "MinimumResponseTimeDetailed"); + char *ipping_maximum_response_time_detailed = get_diagnostics_option("ipping", "MaximumResponseTimeDetailed"); + + add_list_parameter(ctx, dmstrdup("SuccessCount"), ipping_success_count, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("FailureCount"), ipping_failure_count, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("AverageResponseTime"), ipping_average_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MinimumResponseTime"), ipping_minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MaximumResponseTime"), ipping_maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("AverageResponseTimeDetailed"), ipping_average_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MinimumResponseTimeDetailed"), ipping_minimum_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MaximumResponseTimeDetailed"), ipping_maximum_response_time_detailed, DMT_TYPE[DMT_UNINT], NULL); + + return CMD_SUCCESS; +} + +static operation_args ip_diagnostics_trace_route_args = { + .in = (const char *[]) { + "Interface", + "ProtocolVersion", + "Host", + "NumberOfTries", + "Timeout", + "DataBlockSize", + "DSCP", + "MaxHopCount", + NULL + }, + .out = (const char *[]) { + "Status", + "IPAddressUsed", + "ResponseTime", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_TraceRoute(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_trace_route_args; + return 0; +} + +static int operate_IPDiagnostics_TraceRoute(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct uci_section *s = NULL; + char *route_hops_host[2] = {0}; + char *route_hops_host_address[2] = {0}; + char *route_hops_rttimes[2] = {0}; + char *route_hops_errorcode = NULL; + int i = 1; + + init_diagnostics_operation("traceroute", TRACEROUTE_PATH); + + char *host = dmjson_get_value((json_object *)value, 1, "Host"); + if (host[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *proto = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *nboftries = dmjson_get_value((json_object *)value, 1, "NumberOfTries"); + char *timeout = dmjson_get_value((json_object *)value, 1, "Timeout"); + char *datablocksize = dmjson_get_value((json_object *)value, 1, "DataBlockSize"); + char *dscp = dmjson_get_value((json_object *)value, 1, "DSCP"); + char *maxhops = dmjson_get_value((json_object *)value, 1, "MaxHopCount"); + + set_diagnostics_option("traceroute", "Host", host); + set_diagnostics_interface_option(ctx, "traceroute", interface); + set_diagnostics_option("traceroute", "ProtocolVersion", proto); + set_diagnostics_option("traceroute", "NumberOfTries", nboftries); + set_diagnostics_option("traceroute", "Timeout", timeout); + set_diagnostics_option("traceroute", "DataBlockSize", datablocksize); + set_diagnostics_option("traceroute", "DSCP", dscp); + set_diagnostics_option("traceroute", "MaxHops", maxhops); + + // Commit and Free uci_ctx_bbfdm + commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); + + dmcmd("/bin/sh", 2, TRACEROUTE_PATH, "run"); + + // Allocate uci_ctx_bbfdm + dmuci_init_bbfdm(); + + char *response_time = get_diagnostics_option("traceroute", "ResponseTime"); + add_list_parameter(ctx, dmstrdup("ResponseTime"), response_time, DMT_TYPE[DMT_UNINT], NULL); + + uci_path_foreach_sections(bbfdm, DMMAP_DIAGNOSTIGS, "RouteHops", s) { + dmasprintf(&route_hops_host[0], "RouteHops.%d.Host", i); + dmasprintf(&route_hops_host_address[0], "RouteHops.%d.HostAddress", i); + dmasprintf(&route_hops_rttimes[0], "RouteHops.%d.RTTimes", i); + dmasprintf(&route_hops_errorcode, "RouteHops.%d.ErrorCode", i); + + dmuci_get_value_by_section_string(s, "host", &route_hops_host[1]); + dmuci_get_value_by_section_string(s, "ip", &route_hops_host_address[1]); + dmuci_get_value_by_section_string(s, "time", &route_hops_rttimes[1]); + + add_list_parameter(ctx, route_hops_host[0], route_hops_host[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, route_hops_host_address[0], route_hops_host_address[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, route_hops_rttimes[0], route_hops_rttimes[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, route_hops_errorcode, "0", DMT_TYPE[DMT_UNINT], NULL); + i++; + } + + return CMD_SUCCESS; +} + +static operation_args ip_diagnostics_download_args = { + .in = (const char *[]) { + "Interface", + "DownloadURL", + "DSCP", + "EthernetPriority", + "TimeBasedTestDuration", + "TimeBasedTestMeasurementInterval", + "TimeBasedTestMeasurementOffset", + "ProtocolVersion", + "NumberOfConnections", + "EnablePerConnectionResults", + NULL + }, + .out = (const char *[]) { + "Status", + "IPAddressUsed", + "ROMTime", + "BOMTime", + "EOMTime", + "TestBytesReceived", + "TotalBytesReceived", + "TotalBytesSent", + "TestBytesReceivedUnderFullLoading", + "TotalBytesReceivedUnderFullLoading", + "TotalBytesSentUnderFullLoading", + "PeriodOfFullLoading", + "TCPOpenRequestTime", + "TCPOpenResponseTime", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_DownloadDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_download_args; + return 0; +} + +static int operate_IPDiagnostics_DownloadDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + init_diagnostics_operation("download", DOWNLOAD_DIAGNOSTIC_PATH); + + char *download_url = dmjson_get_value((json_object *)value, 1, "DownloadURL"); + if (download_url[0] == '\0') + return CMD_INVALID_ARGUMENTS; + char *download_interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *download_dscp = dmjson_get_value((json_object *)value, 1, "DSCP"); + char *download_ethernet_priority = dmjson_get_value((json_object *)value, 1, "EthernetPriority"); + char *download_proto = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *download_num_of_connections = dmjson_get_value((json_object *)value, 1, "NumberOfConnections"); + char *download_enable_per_connection_results = dmjson_get_value((json_object *)value, 1, "EnablePerConnectionResults"); + + set_diagnostics_option("download", "url", download_url); + set_diagnostics_interface_option(ctx, "download", download_interface); + set_diagnostics_option("download", "DSCP", download_dscp); + set_diagnostics_option("download", "ethernetpriority", download_ethernet_priority); + set_diagnostics_option("download", "ProtocolVersion", download_proto); + set_diagnostics_option("download", "NumberOfConnections", download_num_of_connections); + set_diagnostics_option("download", "EnablePerConnection", download_enable_per_connection_results); + + if (start_upload_download_diagnostic(DOWNLOAD_DIAGNOSTIC) == -1) + return CMD_FAIL; + + char *romtime = get_diagnostics_option("download", "ROMtime"); + char *bomtime = get_diagnostics_option("download", "BOMtime"); + char *eomtime = get_diagnostics_option("download", "EOMtime"); + char *test_bytes_received = get_diagnostics_option("download", "TestBytesReceived"); + char *total_bytes_received = get_diagnostics_option("download", "TotalBytesReceived"); + char *total_bytes_sent = get_diagnostics_option("download", "TotalBytesSent"); + char *test_bytes_received_under_full_loading = get_diagnostics_option("download", "TestBytesReceived"); + char *total_bytes_received_under_full_loading = get_diagnostics_option("download", "TotalBytesReceived"); + char *total_bytes_sent_under_full_loading = get_diagnostics_option("download", "TotalBytesSent"); + char *period_of_full_loading = get_diagnostics_option("download", "PeriodOfFullLoading"); + char *tcp_open_request_time = get_diagnostics_option("download", "TCPOpenRequestTime"); + char *tcp_open_response_time = get_diagnostics_option("download", "TCPOpenResponseTime"); + + add_list_parameter(ctx, dmstrdup("ROMTime"), romtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("BOMTime"), bomtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("EOMTime"), eomtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("TestBytesReceived"), test_bytes_received, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesReceived"), total_bytes_received, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesSent"), total_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TestBytesReceivedUnderFullLoading"), test_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesReceivedUnderFullLoading"), total_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesSentUnderFullLoading"), total_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("PeriodOfFullLoading"), period_of_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TCPOpenRequestTime"), tcp_open_request_time, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("TCPOpenResponseTime"), tcp_open_response_time, DMT_TYPE[DMT_TIME], NULL); + + return CMD_SUCCESS; +} + +static operation_args ip_diagnostics_upload_args = { + .in = (const char *[]) { + "Interface", + "UploadURL", + "DSCP", + "EthernetPriority", + "TestFileLength", + "TimeBasedTestDuration", + "TimeBasedTestMeasurementInterval", + "TimeBasedTestMeasurementOffset", + "ProtocolVersion", + "NumberOfConnections", + "EnablePerConnectionResults", + NULL + }, + .out = (const char *[]) { + "Status", + "IPAddressUsed", + "ROMTime", + "BOMTime", + "EOMTime", + "TestBytesSent", + "TotalBytesReceived", + "TotalBytesSent", + "TestBytesSentUnderFullLoading", + "TotalBytesReceivedUnderFullLoading", + "TotalBytesSentUnderFullLoading", + "PeriodOfFullLoading", + "TCPOpenRequestTime", + "TCPOpenResponseTime", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_UploadDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_upload_args; + return 0; +} + +static int operate_IPDiagnostics_UploadDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + init_diagnostics_operation("upload", UPLOAD_DIAGNOSTIC_PATH); + + char *upload_url = dmjson_get_value((json_object *)value, 1, "UploadURL"); + if (upload_url[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *upload_test_file_length = dmjson_get_value((json_object *)value, 1, "TestFileLength"); + if (upload_test_file_length[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *upload_interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *upload_dscp = dmjson_get_value((json_object *)value, 1, "DSCP"); + char *upload_ethernet_priority = dmjson_get_value((json_object *)value, 1, "EthernetPriority"); + char *upload_proto = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *upload_num_of_connections = dmjson_get_value((json_object *)value, 1, "NumberOfConnections"); + char *upload_enable_per_connection_results = dmjson_get_value((json_object *)value, 1, "EnablePerConnectionResults"); + + set_diagnostics_option("upload", "url", upload_url); + set_diagnostics_option("upload", "TestFileLength", upload_test_file_length); + set_diagnostics_interface_option(ctx, "upload", upload_interface); + set_diagnostics_option("upload", "DSCP", upload_dscp); + set_diagnostics_option("upload", "ethernetpriority", upload_ethernet_priority); + set_diagnostics_option("upload", "ProtocolVersion", upload_proto); + set_diagnostics_option("upload", "NumberOfConnections", upload_num_of_connections); + set_diagnostics_option("upload", "EnablePerConnection", upload_enable_per_connection_results); + + if (start_upload_download_diagnostic(UPLOAD_DIAGNOSTIC) == -1) + return CMD_FAIL; + + char *upload_romtime = get_diagnostics_option("upload", "ROMtime"); + char *upload_bomtime = get_diagnostics_option("upload", "BOMtime"); + char *upload_eomtime = get_diagnostics_option("upload", "EOMtime"); + char *upload_test_bytes_sent = get_diagnostics_option("upload", "TestBytesSent"); + char *upload_total_bytes_received = get_diagnostics_option("upload", "TotalBytesReceived"); + char *upload_total_bytes_sent = get_diagnostics_option("upload", "TotalBytesSent"); + char *upload_test_bytes_sent_under_full_loading = get_diagnostics_option("upload", "TestBytesSent"); + char *upload_total_bytes_received_under_full_loading = get_diagnostics_option("upload", "TotalBytesReceived"); + char *upload_total_bytes_sent_under_full_loading = get_diagnostics_option("upload", "TotalBytesSent"); + char *upload_period_of_full_loading = get_diagnostics_option("upload", "PeriodOfFullLoading"); + char *upload_tcp_open_request_time = get_diagnostics_option("upload", "TCPOpenRequestTime"); + char *upload_tcp_open_response_time = get_diagnostics_option("upload", "TCPOpenResponseTime"); + + add_list_parameter(ctx, dmstrdup("ROMTime"), upload_romtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("BOMTime"), upload_bomtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("EOMTime"), upload_eomtime, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("TestBytesSent"), upload_test_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesReceived"), upload_total_bytes_received, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesSent"), upload_total_bytes_sent, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TestBytesSentUnderFullLoading"), upload_test_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesReceivedUnderFullLoading"), upload_total_bytes_received_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TotalBytesSentUnderFullLoading"), upload_total_bytes_sent_under_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("PeriodOfFullLoading"), upload_period_of_full_loading, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("TCPOpenRequestTime"), upload_tcp_open_request_time, DMT_TYPE[DMT_TIME], NULL); + add_list_parameter(ctx, dmstrdup("TCPOpenResponseTime"), upload_tcp_open_response_time, DMT_TYPE[DMT_TIME], NULL); + + return CMD_SUCCESS; +} + +static operation_args ip_diagnostics_udpecho_args = { + .in = (const char *[]) { + "Interface", + "UploadURL", + "DSCP", + "EthernetPriority", + "TestFileLength", + "TimeBasedTestDuration", + "TimeBasedTestMeasurementInterval", + "TimeBasedTestMeasurementOffset", + "ProtocolVersion", + "NumberOfConnections", + "EnablePerConnectionResults", + NULL + }, + .out = (const char *[]) { + "Status", + "IPAddressUsed", + "ROMTime", + "BOMTime", + "EOMTime", + "TestBytesSent", + "TotalBytesReceived", + "TotalBytesSent", + "TestBytesSentUnderFullLoading", + "TotalBytesReceivedUnderFullLoading", + "TotalBytesSentUnderFullLoading", + "PeriodOfFullLoading", + "TCPOpenRequestTime", + "TCPOpenResponseTime", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_UDPEchoDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_udpecho_args; + return 0; +} + +static int operate_IPDiagnostics_UDPEchoDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + init_diagnostics_operation("udpechodiag", UDPECHO_PATH); + + char *udpecho_host = dmjson_get_value((json_object *)value, 1, "Host"); + if (udpecho_host[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *udpecho_port = dmjson_get_value((json_object *)value, 1, "Port"); + if (udpecho_port[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *udpecho_interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *udpecho_proto = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *udpecho_nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions"); + char *udpecho_timeout = dmjson_get_value((json_object *)value, 1, "Timeout"); + char *udpecho_datablocksize = dmjson_get_value((json_object *)value, 1, "DataBlockSize"); + char *udpecho_dscp = dmjson_get_value((json_object *)value, 1, "DSCP"); + char *udpecho_inter_transmission_time = dmjson_get_value((json_object *)value, 1, "InterTransmissionTime"); + + set_diagnostics_option("udpechodiag", "Host", udpecho_host); + set_diagnostics_option("udpechodiag", "port", udpecho_port); + set_diagnostics_interface_option(ctx, "udpechodiag", udpecho_interface); + set_diagnostics_option("udpechodiag", "ProtocolVersion", udpecho_proto); + set_diagnostics_option("udpechodiag", "NumberOfRepetitions", udpecho_nbofrepetition); + set_diagnostics_option("udpechodiag", "Timeout", udpecho_timeout); + set_diagnostics_option("udpechodiag", "DataBlockSize", udpecho_datablocksize); + set_diagnostics_option("udpechodiag", "DSCP", udpecho_dscp); + set_diagnostics_option("udpechodiag", "InterTransmissionTime", udpecho_inter_transmission_time); + + // Commit and Free uci_ctx_bbfdm + commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); + + dmcmd("/bin/sh", 2, UDPECHO_PATH, "run"); + + // Allocate uci_ctx_bbfdm + dmuci_init_bbfdm(); + + char *udpecho_success_count = get_diagnostics_option("udpechodiag", "SuccessCount"); + char *udpecho_failure_count = get_diagnostics_option("udpechodiag", "FailureCount"); + char *udpecho_average_response_time = get_diagnostics_option("udpechodiag", "AverageResponseTime"); + char *udpecho_minimum_response_time = get_diagnostics_option("udpechodiag", "MinimumResponseTime"); + char *udpecho_maximum_response_time = get_diagnostics_option("udpechodiag", "MaximumResponseTime"); + + add_list_parameter(ctx, dmstrdup("SuccessCount"), udpecho_success_count, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("FailureCount"), udpecho_failure_count, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("AverageResponseTime"), udpecho_average_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MinimumResponseTime"), udpecho_minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MaximumResponseTime"), udpecho_maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); + + return CMD_SUCCESS; +} + +static operation_args ip_diagnostics_server_selection_args = { + .in = (const char *[]) { + "Interface", + "ProtocolVersion", + "Protocol", + "HostList", + "NumberOfRepetitions", + "Timeout", + NULL + }, + .out = (const char *[]) { + "Status", + "FastestHost", + "MinimumResponseTime", + "AverageResponseTime", + "MaximumResponseTime", + "IPAddressUsed", + NULL + } +}; + +static int get_operate_args_IPDiagnostics_ServerSelectionDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&ip_diagnostics_server_selection_args; + return 0; +} + +static int operate_IPDiagnostics_ServerSelectionDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + init_diagnostics_operation("serverselection", SERVERSELECTION_PATH); + + char *hostlist = dmjson_get_value((json_object *)value, 1, "HostList"); + if (hostlist[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *port = dmjson_get_value((json_object *)value, 1, "Port"); + char *proto = dmjson_get_value((json_object *)value, 1, "Protocol"); + if (strcmp(proto, "ICMP") && port[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *protocol_version = dmjson_get_value((json_object *)value, 1, "ProtocolVersion"); + char *interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions"); + char *timeout = dmjson_get_value((json_object *)value, 1, "Timeout"); + + set_diagnostics_option("serverselection", "HostList", hostlist); + set_diagnostics_interface_option(ctx, "serverselection", interface); + set_diagnostics_option("serverselection", "ProtocolVersion", protocol_version); + set_diagnostics_option("serverselection", "NumberOfRepetitions", nbofrepetition); + set_diagnostics_option("serverselection", "port", port); + set_diagnostics_option("serverselection", "Protocol", proto); + set_diagnostics_option("serverselection", "Timeout", timeout); + + // Commit and Free uci_ctx_bbfdm + commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); + + dmcmd("/bin/sh", 2, SERVERSELECTION_PATH, "run"); + + // Allocate uci_ctx_bbfdm + dmuci_init_bbfdm(); + + char *fasthost = get_diagnostics_option("serverselection", "FastestHost"); + char *average_response_time = get_diagnostics_option("serverselection", "AverageResponseTime"); + char *minimum_response_time = get_diagnostics_option("serverselection", "MinimumResponseTime"); + char *maximum_response_time = get_diagnostics_option("serverselection", "MaximumResponseTime"); + + add_list_parameter(ctx, dmstrdup("FastestHost"), fasthost, DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, dmstrdup("AverageResponseTime"), average_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MinimumResponseTime"), minimum_response_time, DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, dmstrdup("MaximumResponseTime"), maximum_response_time, DMT_TYPE[DMT_UNINT], NULL); + + return CMD_SUCCESS; +} + +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ /* *** Device.IP.Diagnostics. *** */ DMOBJ tIPDiagnosticsObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -1639,6 +2186,12 @@ DMLEAF tIPDiagnosticsParams[] = { {"IPv6UDPEchoDiagnosticsSupported", &DMREAD, DMT_BOOL, get_diag_enable_true, NULL, BBFDM_BOTH}, {"IPv4ServerSelectionDiagnosticsSupported", &DMREAD, DMT_BOOL, get_diag_enable_true, NULL, BBFDM_BOTH}, {"IPv6ServerSelectionDiagnosticsSupported", &DMREAD, DMT_BOOL, get_diag_enable_true, NULL, BBFDM_BOTH}, +{"IPPing()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_IPPing, operate_IPDiagnostics_IPPing, BBFDM_USP}, +{"TraceRoute()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_TraceRoute, operate_IPDiagnostics_TraceRoute, BBFDM_USP}, +{"DownloadDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_DownloadDiagnostics, operate_IPDiagnostics_DownloadDiagnostics, BBFDM_USP}, +{"UploadDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_UploadDiagnostics, operate_IPDiagnostics_UploadDiagnostics, BBFDM_USP}, +{"UDPEchoDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_UDPEchoDiagnostics, operate_IPDiagnostics_UDPEchoDiagnostics, BBFDM_USP}, +{"ServerSelectionDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_IPDiagnostics_ServerSelectionDiagnostics, operate_IPDiagnostics_ServerSelectionDiagnostics, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/datamodelversion.c b/dmtree/tr181/datamodelversion.c deleted file mode 100644 index 0057a7b9..00000000 --- a/dmtree/tr181/datamodelversion.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Omar Kallel - */ - -#include "datamodelversion.h" - -int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - *value = "2.14"; - return 0; -} diff --git a/dmtree/tr181/datamodelversion.h b/dmtree/tr181/datamodelversion.h deleted file mode 100644 index b9ecc8a3..00000000 --- a/dmtree/tr181/datamodelversion.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2019 iopsys Software Solutions AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * Author: Omar Kallel - */ - -#ifndef __DATAMODELVERSION_H -#define __DATAMODELVERSION_H - -#include - -int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); - -#endif diff --git a/dmtree/tr181/device.c b/dmtree/tr181/device.c index 15f3775f..e404b496 100644 --- a/dmtree/tr181/device.c +++ b/dmtree/tr181/device.c @@ -35,7 +35,6 @@ #include "interfacestack.h" #include "qos.h" #include "usb.h" -#include "datamodelversion.h" #include "gre.h" #include "dynamicdns.h" #include "lanconfigsecurity.h" @@ -46,6 +45,43 @@ #include "servicesvoiceservice.h" #endif +/************************************************************* +* GET & SET PARAM +**************************************************************/ +static int get_Device_InterfaceStackNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + struct uci_section *s = NULL; + int cnt = 0; + + uci_path_foreach_sections(bbfdm, "dmmap_interface_stack", "interface_stack", s) { + cnt++; + } + dmasprintf(value, "%d", cnt); + return 0; +} + +static int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = "2.14"; + return 0; +} + +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static int operate_Device_Reboot(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + return !dmubus_call_set("system", "reboot", UBUS_ARGS{}, 0) ? CMD_SUCCESS : CMD_FAIL; +} + +static int operate_Device_FactoryReset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + return !dmcmd_no_wait("/sbin/defaultreset", 0) ? CMD_SUCCESS : CMD_FAIL; +} + +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ /* *** BBFDM *** */ DMOBJ tEntry181Obj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -53,13 +89,7 @@ DMOBJ tEntry181Obj[] = { {0} }; -DMLEAF tDeviceParams[] = { -/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ -{"InterfaceStackNumberOfEntries", &DMREAD, DMT_UNINT, get_Device_InterfaceStackNumberOfEntries, NULL, BBFDM_BOTH}, -{"RootDataModelVersion", &DMREAD, DMT_STRING, get_Device_RootDataModelVersion, NULL, BBFDM_BOTH}, -{0} -}; - +/* *** Device. *** */ DMOBJ tDeviceObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ {"DeviceInfo", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceInfoObj, tDeviceInfoParams, NULL, BBFDM_BOTH}, @@ -97,3 +127,12 @@ DMOBJ tDeviceObj[] = { {"RouterAdvertisement", &DMREAD, NULL, NULL, "file:/etc/config/dhcp", NULL, NULL, NULL, tRouterAdvertisementObj, tRouterAdvertisementParams, NULL, BBFDM_BOTH}, {0} }; + +DMLEAF tDeviceParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"InterfaceStackNumberOfEntries", &DMREAD, DMT_UNINT, get_Device_InterfaceStackNumberOfEntries, NULL, BBFDM_BOTH}, +{"RootDataModelVersion", &DMREAD, DMT_STRING, get_Device_RootDataModelVersion, NULL, BBFDM_BOTH}, +{"Reboot()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_Reboot, BBFDM_USP}, +{"FactoryReset()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_FactoryReset, BBFDM_USP}, +{0} +}; diff --git a/dmtree/tr181/deviceinfo.c b/dmtree/tr181/deviceinfo.c index c66581ad..52516064 100644 --- a/dmtree/tr181/deviceinfo.c +++ b/dmtree/tr181/deviceinfo.c @@ -9,6 +9,7 @@ * Author: Feten Besbes */ +#include "dmdiagnostics.h" #include "deviceinfo.h" struct Supported_Data_Models @@ -792,6 +793,180 @@ static int get_process_state(char* refparam, struct dmctx *ctx, void *data, char return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static operation_args vendor_config_file_backup_args = { + .in = (const char *[]) { + "URL", + "Username", + "Password", + NULL + } +}; + +static int get_operate_args_DeviceInfoVendorConfigFile_Backup(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&vendor_config_file_backup_args; + return 0; +} + +static int operate_DeviceInfoVendorConfigFile_Backup(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char backup_path[256] = {'\0'}; + char backup_command[32] = {'\0'}; + char *vcf_name = NULL; + + char *ret = strrchr(refparam, '.'); + strncpy(backup_path, refparam, ret - refparam +1); + DM_STRNCPY(backup_command, ret+1, sizeof(backup_command)); + + char *url = dmjson_get_value((json_object *)value, 1, "URL"); + if (url[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *user = dmjson_get_value((json_object *)value, 1, "Username"); + char *pass = dmjson_get_value((json_object *)value, 1, "Password"); + + dmuci_get_value_by_section_string((struct uci_section *)data, "name", &vcf_name); + + int res = bbf_config_backup(url, user, pass, vcf_name, backup_command, backup_path); + + return res ? CMD_FAIL : CMD_SUCCESS; +} + +static operation_args vendor_config_file_restore_args = { + .in = (const char *[]) { + "URL", + "Username", + "Password", + "FileSize", + "TargetFileName", + "CheckSumAlgorithm", + "CheckSum", + NULL + } +}; + +static int get_operate_args_DeviceInfoVendorConfigFile_Restore(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&vendor_config_file_restore_args; + return 0; +} + +static int operate_DeviceInfoVendorConfigFile_Restore(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char restore_path[256] = {'\0'}; + char restore_command[32] = {'\0'}; + + char *ret = strrchr(refparam, '.'); + strncpy(restore_path, refparam, ret - refparam +1); + DM_STRNCPY(restore_command, ret+1, sizeof(restore_command)); + + char *url = dmjson_get_value((json_object *)value, 1, "URL"); + if (url[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *user = dmjson_get_value((json_object *)value, 1, "Username"); + char *pass = dmjson_get_value((json_object *)value, 1, "Password"); + char *file_size = dmjson_get_value((json_object *)value, 1, "FileSize"); + char *checksum_algorithm = dmjson_get_value((json_object *)value, 1, "CheckSumAlgorithm"); + char *checksum = dmjson_get_value((json_object *)value, 1, "CheckSum"); + + int res = bbf_config_restore(url, user, pass, file_size, checksum_algorithm, checksum, restore_command, restore_path); + + return res ? CMD_FAIL : CMD_SUCCESS; +} + +static operation_args firmware_image_download_args = { + .in = (const char *[]) { + "URL", + "AutoActivate", + "Username", + "Password", + "FileSize", + "CheckSumAlgorithm", + "CheckSum", + NULL + } +}; + +static int get_operate_args_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&firmware_image_download_args; + return 0; +} + +static int operate_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char obj_path[256] = {'\0'}; + char command[32] = {'\0'}; + + char *ret = strrchr(refparam, '.'); + strncpy(obj_path, refparam, ret - refparam +1); + DM_STRNCPY(command, ret+1, sizeof(command)); + + char *url = dmjson_get_value((json_object *)value, 1, "URL"); + char *auto_activate = dmjson_get_value((json_object *)value, 1, "AutoActivate"); + if (url[0] == '\0' || auto_activate[0] == '\0') + return CMD_INVALID_ARGUMENTS; + + char *username = dmjson_get_value((json_object *)value, 1, "Username"); + char *password = dmjson_get_value((json_object *)value, 1, "Password"); + char *file_size = dmjson_get_value((json_object *)value, 1, "FileSize"); + char *checksum_algorithm = dmjson_get_value((json_object *)value, 1, "CheckSumAlgorithm"); + char *checksum = dmjson_get_value((json_object *)value, 1, "CheckSum"); + + char *bank_id = dmjson_get_value((json_object *)data, 1, "id"); + + int res = bbf_fw_image_download(url, auto_activate, username, password, file_size, checksum_algorithm, checksum, bank_id, command, obj_path); + + return res ? CMD_FAIL : CMD_SUCCESS; +} + +static operation_args firmware_image_activate_args = { + .in = (const char *[]) { + "TimeWindow.{i}.Start", + "TimeWindow.{i}.End", + "TimeWindow.{i}.Mode", + "TimeWindow.{i}.UserMessage", + "TimeWindow.{i}.MaxRetries", + NULL + } +}; + + +static const char *firmware_image_activate_in[] = { + "TimeWindow.1.Start", + "TimeWindow.2.Start", + "TimeWindow.3.Start", + "TimeWindow.4.Start", + "TimeWindow.5.Start", +}; + +static int get_operate_args_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&firmware_image_activate_args; + return 0; +} + +static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct activate_image active_images[MAX_TIME_WINDOW] = {0}; + + for (int i = 0; i < ARRAY_SIZE(firmware_image_activate_in); i++) + active_images[i].start_time = dmjson_get_value((json_object *)value, 1, firmware_image_activate_in[i]); + + char *bank_id = dmjson_get_value((json_object *)data, 1, "id"); + + int res = bbf_fw_image_activate(bank_id, active_images); + + return res ? CMD_FAIL : CMD_SUCCESS; +} + +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ /* *** Device.DeviceInfo. *** */ DMOBJ tDeviceInfoObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -837,6 +1012,8 @@ DMLEAF tDeviceInfoVendorConfigFileParams[] = { {"Date", &DMREAD, DMT_TIME, get_vcf_date, NULL, BBFDM_BOTH}, {"Description", &DMREAD, DMT_STRING, get_vcf_desc, NULL, BBFDM_BOTH}, {"UseForBackupRestore", &DMREAD, DMT_BOOL, get_vcf_backup_restore, NULL, BBFDM_BOTH}, +{"Backup()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoVendorConfigFile_Backup, operate_DeviceInfoVendorConfigFile_Backup, BBFDM_USP}, +{"Restore()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoVendorConfigFile_Restore, operate_DeviceInfoVendorConfigFile_Restore, BBFDM_USP}, {0} }; @@ -910,6 +1087,8 @@ DMLEAF tDeviceInfoFirmwareImageParams[] = { {"Available", &DMREAD, DMT_BOOL, get_DeviceInfoFirmwareImage_Available, NULL, BBFDM_BOTH}, {"Status", &DMREAD, DMT_STRING, get_DeviceInfoFirmwareImage_Status, NULL, BBFDM_BOTH}, {"BootFailureLog", &DMREAD, DMT_STRING, get_empty, NULL, BBFDM_BOTH}, +{"Download()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoFirmwareImage_Download, operate_DeviceInfoFirmwareImage_Download, BBFDM_USP}, +{"Activate()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoFirmwareImage_Activate, operate_DeviceInfoFirmwareImage_Activate, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/dhcpv4.c b/dmtree/tr181/dhcpv4.c index c9c56588..139f6280 100644 --- a/dmtree/tr181/dhcpv4.c +++ b/dmtree/tr181/dhcpv4.c @@ -3112,6 +3112,18 @@ static int browseDHCPv4RelayForwardingInst(struct dmctx *dmctx, DMNODE *parent_n return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static int operate_DHCPv4Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct uci_section *dhcp_s = ((struct dhcp_client_args *)data)->dhcp_client_conf; + + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", section_name(dhcp_s), String}}, 1); + + return CMD_SUCCESS; +} + /********************************************************************************************************************************** * OBJ & PARAM DEFINITION ***********************************************************************************************************************************/ @@ -3156,6 +3168,7 @@ DMLEAF tDHCPv4ClientParams[] = { //{"PassthroughDHCPPool", &DMWRITE, DMT_STRING, get_DHCPv4Client_PassthroughDHCPPool, set_DHCPv4Client_PassthroughDHCPPool, BBFDM_BOTH}, {"SentOptionNumberOfEntries", &DMREAD, DMT_UNINT, get_DHCPv4Client_SentOptionNumberOfEntries, NULL, BBFDM_BOTH}, {"ReqOptionNumberOfEntries", &DMREAD, DMT_UNINT, get_DHCPv4Client_ReqOptionNumberOfEntries, NULL, BBFDM_BOTH}, +{"Renew()", &DMSYNC, DMT_COMMAND, NULL, operate_DHCPv4Client_Renew, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/dhcpv6.c b/dmtree/tr181/dhcpv6.c index fb0aa502..9828ad6c 100644 --- a/dmtree/tr181/dhcpv6.c +++ b/dmtree/tr181/dhcpv6.c @@ -1300,6 +1300,21 @@ static int set_DHCPv6ServerPoolOption_Value(char *refparam, struct dmctx *ctx, v return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static int operate_DHCPv6Client_Renew(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct uci_section *dhcpv6_s = ((struct dhcpv6_client_args *)data)->dhcp_client_conf; + + dmubus_call_set("network.interface", "renew", UBUS_ARGS{{"interface", section_name(dhcpv6_s), String}}, 1); + + return CMD_SUCCESS; +} + +/********************************************************************************************************************************** +* OBJ & PARAM DEFINITION +***********************************************************************************************************************************/ /* *** Device.DHCPv6. *** */ DMOBJ tDHCPv6Obj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -1332,6 +1347,7 @@ DMLEAF tDHCPv6ClientParams[] = { //{"ServerNumberOfEntries", &DMREAD, DMT_UNINT, get_DHCPv6Client_ServerNumberOfEntries, NULL, BBFDM_BOTH}, //{"SentOptionNumberOfEntries", &DMREAD, DMT_UNINT, get_DHCPv6Client_SentOptionNumberOfEntries, NULL, BBFDM_BOTH}, //{"ReceivedOptionNumberOfEntries", &DMREAD, DMT_UNINT, get_DHCPv6Client_ReceivedOptionNumberOfEntries, NULL, BBFDM_BOTH}, +{"Renew()", &DMSYNC, DMT_COMMAND, NULL, operate_DHCPv6Client_Renew, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/dns.c b/dmtree/tr181/dns.c index 2d0393e6..5dfac963 100644 --- a/dmtree/tr181/dns.c +++ b/dmtree/tr181/dns.c @@ -13,6 +13,9 @@ #include "dmbbfcommon.h" #include "dns.h" +/************************************************************* +* COMMON FUNCTIONS +**************************************************************/ static unsigned char is_dns_server_in_dmmap(char *chk_ip, char *chk_interface) { struct uci_section *s = NULL; @@ -100,7 +103,9 @@ static int dmmap_synchronizeDNSClientRelayServer(struct dmctx *dmctx, DMNODE *pa return 0; } -/******************************** Browse Functions ****************************************/ +/************************************************************* +* ENTRY METHOD +**************************************************************/ static int browseDNSServerInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { struct uci_section *s = NULL; @@ -134,7 +139,9 @@ static int browseResultInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev return 0; } -/*********************************** Add/Delet Object functions *************************/ +/************************************************************* +* ADD & DEL OBJ +**************************************************************/ static int add_dns_server(char *refparam, struct dmctx *ctx, void *data, char **instance) { struct uci_section *s = NULL; @@ -188,7 +195,9 @@ static int delete_dns_server(char *refparam, struct dmctx *ctx, void *data, char return 0; } -/***************************************** Get/Set Parameter functions ***********************/ +/************************************************************* +* GET & SET PARAM +**************************************************************/ static int get_dns_supported_record_types(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = "A,AAAA,PTR"; @@ -686,12 +695,109 @@ static int set_nslookupdiagnostics_number_of_repetitions(char *refparam, struct return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static operation_args dns_diagnostics_nslookup_args = { + .in = (const char *[]) { + "HostName", + "Interface", + "DNSServer", + "Timeout", + "NumberOfRepetitions", + NULL + }, + .out = (const char *[]) { + "Status", + "AnswerType", + "HostNameReturned", + "IPAddresses", + "DNSServerIP", + "ResponseTime", + NULL + } +}; + +static int get_operate_args_DNSDiagnostics_NSLookupDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&dns_diagnostics_nslookup_args; + return 0; +} + +static int operate_DNSDiagnostics_NSLookupDiagnostics(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct uci_section *s = NULL; + char *nslookup_status[2] = {0}; + char *nslookup_answer_type[2] = {0}; + char *nslookup_hostname_returned[2] = {0}; + char *nslookup_ip_addresses[2] = {0}; + char *nslookup_dns_server_ip[2] = {0}; + char *nslookup_response_time[2] = {0}; + int i = 1; + + init_diagnostics_operation("nslookup", NSLOOKUP_PATH); + + char *hostname = dmjson_get_value((json_object *)value, 1, "HostName"); + if (hostname[0] == '\0') + return CMD_INVALID_ARGUMENTS; + char *interface = dmjson_get_value((json_object *)value, 1, "Interface"); + char *dnsserver = dmjson_get_value((json_object *)value, 1, "DNSServer"); + char *timeout = dmjson_get_value((json_object *)value, 1, "Timeout"); + char *nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions"); + + set_diagnostics_option("nslookup", "HostName", hostname); + set_diagnostics_interface_option(ctx, "nslookup", interface); + set_diagnostics_option("nslookup", "DNSServer", dnsserver); + set_diagnostics_option("nslookup", "Timeout", timeout); + set_diagnostics_option("nslookup", "NumberOfRepetitions", nbofrepetition); + + // Commit and Free uci_ctx_bbfdm + commit_and_free_uci_ctx_bbfdm(DMMAP_DIAGNOSTIGS); + + dmcmd("/bin/sh", 2, NSLOOKUP_PATH, "run"); + + // Allocate uci_ctx_bbfdm + dmuci_init_bbfdm(); + + char *success_count = get_diagnostics_option("nslookup", "SuccessCount"); + add_list_parameter(ctx, dmstrdup("SuccessCount"), success_count, DMT_TYPE[DMT_UNINT], NULL); + + uci_path_foreach_sections(bbfdm, DMMAP_DIAGNOSTIGS, "NSLookupResult", s) { + dmasprintf(&nslookup_status[0], "Result.%d.Status", i); + dmasprintf(&nslookup_answer_type[0], "Result.%d.AnswerType", i); + dmasprintf(&nslookup_hostname_returned[0], "Result.%d.HostNameReturned", i); + dmasprintf(&nslookup_ip_addresses[0], "Result.%d.IPAddresses", i); + dmasprintf(&nslookup_dns_server_ip[0], "Result.%d.DNSServerIP", i); + dmasprintf(&nslookup_response_time[0], "Result.%d.ResponseTime", i); + + dmuci_get_value_by_section_string(s, "Status", &nslookup_status[1]); + dmuci_get_value_by_section_string(s, "AnswerType", &nslookup_answer_type[1]); + dmuci_get_value_by_section_string(s, "HostNameReturned", &nslookup_hostname_returned[1]); + dmuci_get_value_by_section_string(s, "IPAddresses", &nslookup_ip_addresses[1]); + dmuci_get_value_by_section_string(s, "DNSServerIP", &nslookup_dns_server_ip[1]); + dmuci_get_value_by_section_string(s, "ResponseTime", &nslookup_response_time[1]); + + add_list_parameter(ctx, nslookup_status[0], nslookup_status[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, nslookup_answer_type[0], nslookup_answer_type[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, nslookup_hostname_returned[0], nslookup_hostname_returned[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, nslookup_ip_addresses[0], nslookup_ip_addresses[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, nslookup_dns_server_ip[0], nslookup_dns_server_ip[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, nslookup_response_time[0], nslookup_response_time[1], DMT_TYPE[DMT_UNINT], NULL); + i++; + } + + return CMD_SUCCESS; +} + +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ /* *** Device.DNS. *** */ DMOBJ tDNSObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ {"Client", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDNSClientObj, tDNSClientParams, NULL, BBFDM_BOTH}, {"Relay", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDNSRelayObj, tDNSRelayParams, NULL, BBFDM_BOTH}, -{"Diagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDNSDiagnosticsObj, NULL, NULL, BBFDM_BOTH}, +{"Diagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDNSDiagnosticsObj, tDNSDiagnosticsParams, NULL, BBFDM_BOTH}, {0} }; @@ -762,6 +868,12 @@ DMOBJ tDNSDiagnosticsObj[] = { {0} }; +DMLEAF tDNSDiagnosticsParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"NSLookupDiagnostics()", &DMASYNC, DMT_COMMAND, get_operate_args_DNSDiagnostics_NSLookupDiagnostics, operate_DNSDiagnostics_NSLookupDiagnostics, BBFDM_USP}, +{0} +}; + /* *** Device.DNS.Diagnostics.NSLookupDiagnostics. *** */ DMOBJ tDNSDiagnosticsNSLookupDiagnosticsObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ diff --git a/dmtree/tr181/dns.h b/dmtree/tr181/dns.h index e118e8a4..254d4ea6 100644 --- a/dmtree/tr181/dns.h +++ b/dmtree/tr181/dns.h @@ -22,6 +22,7 @@ extern DMLEAF tDNSRelayParams[]; extern DMOBJ tDNSRelayObj[]; extern DMLEAF tDNSRelayForwardingParams[]; extern DMOBJ tDNSDiagnosticsObj[]; +extern DMLEAF tDNSDiagnosticsParams[]; extern DMLEAF tDNSDiagnosticsNSLookupDiagnosticsParams[]; extern DMOBJ tDNSDiagnosticsNSLookupDiagnosticsObj[]; extern DMLEAF tDNSDiagnosticsNSLookupDiagnosticsResultParams[]; diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index 52cba21c..cca540b7 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -1080,7 +1080,7 @@ static int get_EthernetLink_MACAddress(char *refparam, struct dmctx *ctx, void * int i; dmuci_get_value_by_section_string((struct uci_section *)data, "mac", &mac_addr); - strncpy(address, mac_addr, sizeof(address)); + DM_STRNCPY(address, mac_addr, sizeof(address)); for (i = 0; address[i] != '\0'; i++) { if(address[i] >= 'a' && address[i] <= 'z') { address[i] = address[i] - 32; diff --git a/dmtree/tr181/interfacestack.c b/dmtree/tr181/interfacestack.c index 5432ede4..643908d0 100644 --- a/dmtree/tr181/interfacestack.c +++ b/dmtree/tr181/interfacestack.c @@ -601,18 +601,6 @@ end: /************************************************************* * GET & SET PARAM **************************************************************/ -int get_Device_InterfaceStackNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) -{ - struct uci_section *s = NULL; - int cnt = 0; - - uci_path_foreach_sections(bbfdm, "dmmap_interface_stack", "interface_stack", s) { - cnt++; - } - dmasprintf(value, "%d", cnt); - return 0; -} - static int get_InterfaceStack_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { struct uci_section *s = NULL; diff --git a/dmtree/tr181/interfacestack.h b/dmtree/tr181/interfacestack.h index 4535555a..ea26e428 100644 --- a/dmtree/tr181/interfacestack.h +++ b/dmtree/tr181/interfacestack.h @@ -15,7 +15,6 @@ extern DMLEAF tInterfaceStackParams[]; -int get_Device_InterfaceStackNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); int browseInterfaceStackInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance); #endif //__INTERFACESTACK_H diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index d6bd5aa8..07ccbb56 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -2368,6 +2368,20 @@ static int get_IPInterfaceStats_MulticastPacketsReceived(char *refparam, struct return get_ip_iface_sysfs(data, "statistics/multicast", value); } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static int operate_IPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char interface_obj[64] = {0}; + + snprintf(interface_obj, sizeof(interface_obj), "network.interface.%s", section_name(((struct uci_section *)data))); + dmubus_call_set(interface_obj, "down", UBUS_ARGS{}, 0); + dmubus_call_set(interface_obj, "up", UBUS_ARGS{}, 0); + + return CMD_SUCCESS; +} + /********************************************************************************************************************************** * OBJ & PARAM DEFINITION ***********************************************************************************************************************************/ @@ -2425,6 +2439,7 @@ DMLEAF tIPInterfaceParams[] = { {"IPv6PrefixNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_IPv6PrefixNumberOfEntries, NULL, BBFDM_BOTH}, //{"AutoIPEnable", &DMWRITE, DMT_BOOL, get_IPInterface_AutoIPEnable, set_IPInterface_AutoIPEnable, BBFDM_BOTH}, {"TWAMPReflectorNumberOfEntries", &DMREAD, DMT_UNINT, get_IPInterface_TWAMPReflectorNumberOfEntries, NULL, BBFDM_BOTH}, +{"Reset()", &DMSYNC, DMT_COMMAND, NULL, operate_IPInterface_Reset, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/ppp.c b/dmtree/tr181/ppp.c index eb0d7c38..58ffb342 100644 --- a/dmtree/tr181/ppp.c +++ b/dmtree/tr181/ppp.c @@ -558,6 +558,23 @@ static int browseInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void *p return 0; } +/************************************************************* + * OPERATE COMMANDS + *************************************************************/ +static int operate_PPPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char interface_obj[64] = {0}; + + snprintf(interface_obj, sizeof(interface_obj), "network.interface.%s", section_name(((struct uci_section *)data))); + dmubus_call_set(interface_obj, "down", UBUS_ARGS{}, 0); + dmubus_call_set(interface_obj, "up", UBUS_ARGS{}, 0); + + return CMD_SUCCESS; +} + +/********************************************************************************************************************************** +* OBJ & PARAM DEFINITION +***********************************************************************************************************************************/ /* *** Device.PPP. *** */ DMOBJ tPPPObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -593,6 +610,7 @@ DMLEAF tPPPInterfaceParams[] = { {"ConnectionStatus", &DMREAD, DMT_STRING, get_ppp_status, NULL, BBFDM_BOTH}, {"Username", &DMWRITE, DMT_STRING, get_ppp_username, set_ppp_username, BBFDM_BOTH}, {"Password", &DMWRITE, DMT_STRING, get_empty, set_ppp_password, BBFDM_BOTH}, +{"Reset()", &DMSYNC, DMT_COMMAND, NULL, operate_PPPInterface_Reset, BBFDM_USP}, {0} }; diff --git a/dmtree/tr181/wifi.c b/dmtree/tr181/wifi.c index e02a288e..17f77e88 100644 --- a/dmtree/tr181/wifi.c +++ b/dmtree/tr181/wifi.c @@ -466,6 +466,200 @@ static int browseWiFiEndPointProfileInst(struct dmctx *dmctx, DMNODE *parent_nod return 0; } +static int browseWiFiDataElementsNetworkDeviceInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + int i = 0, j = 0, id = 0; + char *inst = NULL, *max_inst = NULL; + json_object *res = NULL, *data_arr = NULL, *data_obj = NULL, *net_obj = NULL; + json_object *dev_arr = NULL, *dev_obj = NULL; + + dmubus_call("wifi.dataelements.collector", "dump", UBUS_ARGS{}, 0, &res); + dmjson_foreach_obj_in_array(res, data_arr, data_obj, i, 1, "data") { + json_object_object_get_ex(data_obj, "wfa-dataelements:Network", &net_obj); + dmjson_foreach_obj_in_array(net_obj, dev_arr, dev_obj, j, 1, "DeviceList") { + inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)dev_obj, inst) == DM_STOP) + break; + } + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *radio_arr = NULL, *radio_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, radio_arr, radio_obj, i, 1, "RadioList") { + inst = handle_update_instance(2, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)radio_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioCurrentOperatingClassProfileInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *opclass_arr = NULL, *opclass_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, opclass_arr, opclass_obj, i, 1, "CurrentOperatingClasses") { + inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioBSSInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *bss_arr = NULL, *bss_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, bss_arr, bss_obj, i, 1, "BSSList") { + inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)bss_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioScanResultInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *scanres_arr = NULL, *scanres_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, scanres_arr, scanres_obj, i, 1, "ScanResultList") { + inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)scanres_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioUnassociatedSTAInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *unassoc_arr = NULL, *unassoc_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, unassoc_arr, unassoc_obj, i, 1, "UnassociatedStaList") { + inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)unassoc_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioCapabilitiesCapableOperatingClassProfileInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *caps_obj = NULL, *opclass_arr = NULL, *opclass_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + json_object_object_get_ex((json_object *)prev_data, "Capabilites", &caps_obj); + dmjson_foreach_obj_in_array(caps_obj, opclass_arr, opclass_obj, i, 1, "OperatingClasses") { + inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioBSSSTAInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *sta_arr = NULL, *sta_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, sta_arr, sta_obj, i, 1, "STAList") { + inst = handle_update_instance(4, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)sta_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *opclass_scan_arr = NULL, *opclass_scan_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, opclass_scan_arr, opclass_scan_obj, i, 1, "OpClassScanList") { + inst = handle_update_instance(4, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_scan_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanChannelScanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *chscan_arr = NULL, *chscan_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, chscan_arr, chscan_obj, i, 1, "ChannelScanList") { + inst = handle_update_instance(5, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)chscan_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanChannelScanNeighborBSSInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *neigh_arr = NULL, *neigh_obj = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmjson_foreach_obj_in_array((json_object *)prev_data, neigh_arr, neigh_obj, i, 1, "NeighborList") { + inst = handle_update_instance(6, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)neigh_obj, inst) == DM_STOP) + break; + } + return 0; +} + +static int browseWiFiDataElementsAssociationEventAssociationEventDataInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *res = NULL, *notify_arr = NULL, *notify_obj = NULL, *assoc_ev = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmubus_call("wifi.dataelements.collector", "event", UBUS_ARGS{}, 0, &res); + dmjson_foreach_obj_in_array(res, notify_arr, notify_obj, i, 1, "notification") { + if (json_object_object_get_ex(notify_obj, "wfa-dataelements:AssociationEvent", &assoc_ev)) { + inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)notify_obj, inst) == DM_STOP) + break; + } + } + return 0; +} + +static int browseWiFiDataElementsDisassociationEventDisassociationEventDataInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + json_object *res = NULL, *notify_arr = NULL, *notify_obj = NULL, *disassoc_ev = NULL; + char *inst = NULL, *max_inst = NULL; + int id = 0, i = 0; + + dmubus_call("wifi.dataelements.collector", "event", UBUS_ARGS{}, 0, &res); + dmjson_foreach_obj_in_array(res, notify_arr, notify_obj, i, 1, "notification") { + if (json_object_object_get_ex(notify_obj, "wfa-dataelements:DisassociationEvent", &disassoc_ev)) { + inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)notify_obj, inst) == DM_STOP) + break; + } + } + return 0; +} + /************************************************************************** * SET & GET VALUE ***************************************************************************/ @@ -3908,202 +4102,117 @@ static int get_WiFiDataElementsDisassociationEventDisassociationEventData_TimeSt } /************************************************************* - * ENTRY METHOD - **************************************************************/ -static int browseWiFiDataElementsNetworkDeviceInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) + * OPERATE COMMANDS + *************************************************************/ +static int operate_WiFi_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - int i = 0, j = 0, id = 0; - char *inst = NULL, *max_inst = NULL; - json_object *res = NULL, *data_arr = NULL, *data_obj = NULL, *net_obj = NULL; - json_object *dev_arr = NULL, *dev_obj = NULL; + return !dmcmd_no_wait("/sbin/wifi", 2, "reload", "&") ? CMD_SUCCESS : CMD_FAIL; +} - dmubus_call("wifi.dataelements.collector", "dump", UBUS_ARGS{}, 0, &res); - dmjson_foreach_obj_in_array(res, data_arr, data_obj, i, 1, "data") { - json_object_object_get_ex(data_obj, "wfa-dataelements:Network", &net_obj); - dmjson_foreach_obj_in_array(net_obj, dev_arr, dev_obj, j, 1, "DeviceList") { - inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)dev_obj, inst) == DM_STOP) - break; +static operation_args neighboring_wifi_diagnostic_args = { + .out = (const char *[]) { + "Status", + "Result.{i}.Radio", + "Result.{i}.SSID", + "Result.{i}.BSSID", + "Result.{i}.Mode", + "Result.{i}.Channel", + "Result.{i}.SignalStrength", + "Result.{i}.SecurityModeEnabled", + "Result.{i}.EncryptionMode", + "Result.{i}.OperatingFrequencyBand", + "Result.{i}.SupportedStandards", + "Result.{i}.OperatingStandards", + "Result.{i}.OperatingChannelBandwidth", + "Result.{i}.BeaconPeriod", + "Result.{i}.Noise", + "Result.{i}.BasicDataTransferRates", + "Result.{i}.SupportedDataTransferRates", + "Result.{i}.DTIMPeriod", + NULL + } +}; + +static int get_operate_args_WiFi_NeighboringWiFiDiagnostic(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&neighboring_wifi_diagnostic_args; + return 0; +} + +static int operate_WiFi_NeighboringWiFiDiagnostic(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + json_object *res = NULL; + + dmubus_call("wifi", "status", UBUS_ARGS{}, 0, &res); + if (res) { + json_object *radios = NULL, *arrobj = NULL; + int i = 0; + + dmjson_foreach_obj_in_array(res, arrobj, radios, i, 1, "radios") { + json_object *scan_res = NULL, *obj = NULL; + char object[32] = {0}; + char *ssid[2] = {0}; + char *bssid[2] = {0}; + char *noise[2] = {0}; + char *channel[2] = {0}; + char *frequency[2] = {0}; + char *signal_strength[2] = {0}; + + char *radio_name = dmjson_get_value(radios, 1, "name"); + snprintf(object, sizeof(object), "wifi.radio.%s", radio_name); + dmubus_call_set(object, "scan", UBUS_ARGS{}, 0); + sleep(2); // Wait for results to get populated in scanresults + dmubus_call(object, "scanresults", UBUS_ARGS{}, 0, &scan_res); + + if (!scan_res) + continue; + + if (!json_object_object_get_ex(scan_res,"accesspoints", &obj)) + continue; + + uint8_t len = obj ? json_object_array_length(obj) : 0; + for (uint8_t j = 0; j < len; j++ ) { + json_object *array_obj = json_object_array_get_idx(obj, j); + ssid[1] = dmjson_get_value(array_obj, 1, "ssid"); + bssid[1] = dmjson_get_value(array_obj, 1, "bssid"); + channel[1] = dmjson_get_value(array_obj, 1, "channel"); + frequency[1] = dmjson_get_value(array_obj, 1, "band"); + signal_strength[1] = dmjson_get_value(array_obj, 1, "rssi"); + noise[1] = dmjson_get_value(array_obj, 1, "noise"); + + dmasprintf(&ssid[0], "Result.%d.SSID", j); + dmasprintf(&bssid[0], "Result.%d.BSSID", j); + dmasprintf(&channel[0], "Result.%d.Channel", j); + dmasprintf(&frequency[0], "Result.%d.OperatingFrequencyBand", j); + dmasprintf(&signal_strength[0], "Result.%d.SignalStrength", j); + dmasprintf(&noise[0], "Result.%d.Noise", j); + + add_list_parameter(ctx, ssid[0], ssid[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, bssid[0], bssid[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, channel[0], channel[1], DMT_TYPE[DMT_UNINT], NULL); + add_list_parameter(ctx, frequency[0], frequency[1], DMT_TYPE[DMT_STRING], NULL); + add_list_parameter(ctx, signal_strength[0], signal_strength[1], DMT_TYPE[DMT_INT], NULL); + add_list_parameter(ctx, noise[0], noise[1], DMT_TYPE[DMT_INT], NULL); + } } } - return 0; + + return CMD_SUCCESS; } -static int browseWiFiDataElementsNetworkDeviceRadioInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +static int operate_WiFiAccessPointSecurity_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { - json_object *radio_arr = NULL, *radio_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; + dmuci_set_value_by_section(((struct wifi_acp_args *)data)->wifi_acp_sec, "encryption", "psk"); + dmuci_set_value_by_section(((struct wifi_acp_args *)data)->wifi_acp_sec, "key", get_default_wpa_key()); + dmuci_set_value_by_section(((struct wifi_acp_args *)data)->wifi_acp_sec, "wps", "1"); + dmuci_set_value_by_section(((struct wifi_acp_args *)data)->wifi_acp_sec, "wps_pushbutton", "1"); - dmjson_foreach_obj_in_array((json_object *)prev_data, radio_arr, radio_obj, i, 1, "RadioList") { - inst = handle_update_instance(2, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)radio_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioCurrentOperatingClassProfileInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *opclass_arr = NULL, *opclass_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, opclass_arr, opclass_obj, i, 1, "CurrentOperatingClasses") { - inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioBSSInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *bss_arr = NULL, *bss_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, bss_arr, bss_obj, i, 1, "BSSList") { - inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)bss_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioScanResultInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *scanres_arr = NULL, *scanres_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, scanres_arr, scanres_obj, i, 1, "ScanResultList") { - inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)scanres_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioUnassociatedSTAInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *unassoc_arr = NULL, *unassoc_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, unassoc_arr, unassoc_obj, i, 1, "UnassociatedStaList") { - inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)unassoc_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioCapabilitiesCapableOperatingClassProfileInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *caps_obj = NULL, *opclass_arr = NULL, *opclass_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - json_object_object_get_ex((json_object *)prev_data, "Capabilites", &caps_obj); - dmjson_foreach_obj_in_array(caps_obj, opclass_arr, opclass_obj, i, 1, "OperatingClasses") { - inst = handle_update_instance(3, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioBSSSTAInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *sta_arr = NULL, *sta_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, sta_arr, sta_obj, i, 1, "STAList") { - inst = handle_update_instance(4, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)sta_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *opclass_scan_arr = NULL, *opclass_scan_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, opclass_scan_arr, opclass_scan_obj, i, 1, "OpClassScanList") { - inst = handle_update_instance(4, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)opclass_scan_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanChannelScanInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *chscan_arr = NULL, *chscan_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, chscan_arr, chscan_obj, i, 1, "ChannelScanList") { - inst = handle_update_instance(5, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)chscan_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsNetworkDeviceRadioScanResultOpClassScanChannelScanNeighborBSSInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *neigh_arr = NULL, *neigh_obj = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmjson_foreach_obj_in_array((json_object *)prev_data, neigh_arr, neigh_obj, i, 1, "NeighborList") { - inst = handle_update_instance(6, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)neigh_obj, inst) == DM_STOP) - break; - } - return 0; -} - -static int browseWiFiDataElementsAssociationEventAssociationEventDataInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *res = NULL, *notify_arr = NULL, *notify_obj = NULL, *assoc_ev = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmubus_call("wifi.dataelements.collector", "event", UBUS_ARGS{}, 0, &res); - dmjson_foreach_obj_in_array(res, notify_arr, notify_obj, i, 1, "notification") { - if (json_object_object_get_ex(notify_obj, "wfa-dataelements:AssociationEvent", &assoc_ev)) { - inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)notify_obj, inst) == DM_STOP) - break; - } - } - return 0; -} - -static int browseWiFiDataElementsDisassociationEventDisassociationEventDataInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) -{ - json_object *res = NULL, *notify_arr = NULL, *notify_obj = NULL, *disassoc_ev = NULL; - char *inst = NULL, *max_inst = NULL; - int id = 0, i = 0; - - dmubus_call("wifi.dataelements.collector", "event", UBUS_ARGS{}, 0, &res); - dmjson_foreach_obj_in_array(res, notify_arr, notify_obj, i, 1, "notification") { - if (json_object_object_get_ex(notify_obj, "wfa-dataelements:DisassociationEvent", &disassoc_ev)) { - inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)notify_obj, inst) == DM_STOP) - break; - } - } - return 0; + return CMD_SUCCESS; } +/********************************************************************************************************************************** +* OBJ & LEAF DEFINITION +***********************************************************************************************************************************/ /* *** Device.WiFi. *** */ DMOBJ tWiFiObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ @@ -4122,6 +4231,8 @@ DMLEAF tWiFiParams[] = { {"SSIDNumberOfEntries", &DMREAD, DMT_UNINT, get_WiFi_SSIDNumberOfEntries, NULL, BBFDM_BOTH}, {"AccessPointNumberOfEntries", &DMREAD, DMT_UNINT, get_WiFi_AccessPointNumberOfEntries, NULL, BBFDM_BOTH}, {"EndPointNumberOfEntries", &DMREAD, DMT_UNINT, get_WiFi_EndPointNumberOfEntries, NULL, BBFDM_BOTH}, +{"Reset()", &DMSYNC, DMT_COMMAND, NULL, operate_WiFi_Reset, BBFDM_USP}, +{"NeighboringWiFiDiagnostic()", &DMASYNC, DMT_COMMAND, get_operate_args_WiFi_NeighboringWiFiDiagnostic, operate_WiFi_NeighboringWiFiDiagnostic, BBFDM_USP}, {0} }; @@ -4297,6 +4408,7 @@ DMLEAF tWiFiAccessPointSecurityParams[] = { {"RadiusServerPort", &DMWRITE, DMT_UNINT, get_access_point_security_radius_server_port, set_access_point_security_radius_server_port, BBFDM_BOTH}, {"RadiusSecret", &DMWRITE, DMT_STRING, get_empty, set_access_point_security_radius_secret, BBFDM_BOTH}, {"MFPConfig", &DMWRITE, DMT_STRING, get_WiFiAccessPointSecurity_MFPConfig, set_WiFiAccessPointSecurity_MFPConfig, BBFDM_BOTH}, +{"Reset()", &DMSYNC, DMT_COMMAND, NULL, operate_WiFiAccessPointSecurity_Reset, BBFDM_USP}, {0} }; diff --git a/libbbf_api/dmbbf.c b/libbbf_api/dmbbf.c index 90fb7c6e..e633a699 100644 --- a/libbbf_api/dmbbf.c +++ b/libbbf_api/dmbbf.c @@ -104,6 +104,8 @@ char *array_notifcation_char[__MAX_notification] = { struct dm_permession_s DMREAD = {"0", NULL}; struct dm_permession_s DMWRITE = {"1", NULL}; +struct dm_permession_s DMSYNC = {"sync", NULL}; +struct dm_permession_s DMASYNC = {"async", NULL}; static int plugin_obj_match(DMOBJECT_ARGS) { @@ -227,9 +229,15 @@ static bool check_dependency(const char *conf_obj) static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf, void *data, char *instance) { int err = 0; + for (; (leaf && leaf->parameter); leaf++) { + if (!bbfdatamodel_matches(leaf->bbfdm_type)) continue; + + if (dmctx->iscommand != (leaf->type == DMT_COMMAND)) + 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) @@ -244,8 +252,13 @@ static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf for (int j = 0; next_dyn_array->nextleaf[j]; j++) { DMLEAF *jleaf = next_dyn_array->nextleaf[j]; for (; (jleaf && jleaf->parameter); jleaf++) { + if (!bbfdatamodel_matches(jleaf->bbfdm_type)) continue; + + if (dmctx->iscommand != (jleaf->type == DMT_COMMAND)) + 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) @@ -427,30 +440,55 @@ void dm_exclude_obj(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, c } } +static void dm_check_dynamic_obj_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, char *parent_obj, char *full_obj, char *obj, DMOBJ **root_entry, int *obj_found) +{ + DMNODE node = {0}; + node.obj = entryobj; + node.parent = parent_node; + node.instance_level = parent_node->instance_level; + node.matched = parent_node->matched; + + dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj); + if (strcmp(node.current_object, obj) == 0) { + *root_entry = entryobj; + *obj_found = 1; + return; + } + + int err = plugin_dynamic_obj_match(dmctx, &node, entryobj->obj, full_obj); + if (err) + return; + + if (entryobj->nextobj || entryobj->nextdynamicobj) + dm_check_dynamic_obj(dmctx, &node, entryobj->nextobj, full_obj, obj, root_entry, obj_found); +} + void dm_check_dynamic_obj(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, char *obj, DMOBJ **root_entry, int *obj_found) { char *parent_obj = parent_node->current_object; for (; (entryobj && entryobj->obj); entryobj++) { - DMNODE node = {0}; - node.obj = entryobj; - node.parent = parent_node; - node.instance_level = parent_node->instance_level; - node.matched = parent_node->matched; - - dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj); - if (strcmp(node.current_object, obj) == 0) { - *root_entry = entryobj; - *obj_found = 1; + dm_check_dynamic_obj_entry(dmctx, parent_node, entryobj, parent_obj, full_obj, obj, root_entry, obj_found); + if (*obj_found == 1) return; + } + + if (parent_node->obj) { + if (parent_node->obj->nextdynamicobj) { + for (int i = 0; i < __INDX_DYNAMIC_MAX; i++) { + struct dm_dynamic_obj *next_dyn_array = parent_node->obj->nextdynamicobj + i; + if (next_dyn_array->nextobj) { + for (int j = 0; next_dyn_array->nextobj[j]; j++) { + DMOBJ *jentryobj = next_dyn_array->nextobj[j]; + for (; (jentryobj && jentryobj->obj); jentryobj++) { + dm_check_dynamic_obj_entry(dmctx, parent_node, jentryobj, parent_obj, full_obj, obj, root_entry, obj_found); + if (*obj_found == 1) + return; + } + } + } + } } - - int err = plugin_dynamic_obj_match(dmctx, &node, entryobj->obj, full_obj); - if (err) - continue; - - if (entryobj->nextobj) - dm_check_dynamic_obj(dmctx, &node, entryobj->nextobj, full_obj, obj, root_entry, obj_found); } } @@ -743,7 +781,7 @@ void add_list_parameter(struct dmctx *ctx, char *param_name, char *param_data, c dm_parameter = dmcalloc(1, sizeof(struct dm_parameter)); _list_add(&dm_parameter->list, ilist->prev, ilist); dm_parameter->name = param_name; - dm_parameter->data = param_data ? param_data : ""; + dm_parameter->data = param_data; dm_parameter->type = param_type; dm_parameter->notification = param_notification; } @@ -1954,6 +1992,100 @@ static int get_linker_value_check_param(DMPARAM_ARGS) return FAULT_9005; } +/* ************ + * list operate + * ************/ +static int mobj_list_operates_name(DMOBJECT_ARGS) +{ + return 0; +} + +static int mparam_list_operates_name(DMPARAM_ARGS) +{ + char *full_param; + char *value = NULL; + + dmastrcat(&full_param, node->current_object, lastname); + if (get_cmd) + (get_cmd)(full_param, dmctx, data, instance, &value); + + add_list_parameter(dmctx, full_param, value, permission->val, NULL); + return 0; +} + +int dm_entry_list_operates(struct dmctx *dmctx) +{ + DMOBJ *root = dmctx->dm_entryobj; + DMNODE node = {.current_object = ""}; + int err; + + dmctx->inparam_isparam = 0; + dmctx->isgetschema = 1; + dmctx->iscommand = 1; + dmctx->findparam = 0; + dmctx->stop = 0; + dmctx->checkobj = NULL; + dmctx->checkleaf = NULL; + dmctx->method_obj = mobj_list_operates_name; + dmctx->method_param = mparam_list_operates_name; + err = dm_browse(dmctx, &node, root, NULL, NULL); + return err; +} + +/* ************** + * Operate + * **************/ +static int mobj_operate(DMOBJECT_ARGS) +{ + return CMD_NOT_FOUND; +} + +static int mparam_operate(DMPARAM_ARGS) +{ + char *full_param = NULL; + + dmastrcat(&full_param, node->current_object, lastname); + if (full_param && strcmp(full_param, dmctx->in_param) != 0) { + dmfree(full_param); + return CMD_NOT_FOUND; + } + dmctx->stop = 1; + + if (!set_cmd) { + dmfree(full_param); + return CMD_FAIL; + } + + json_object *j_input = (dmctx->in_value) ? json_tokener_parse(dmctx->in_value) : NULL; + int fault = (set_cmd)(full_param, dmctx, data, instance, (char *)j_input, VALUESET); + json_object_put(j_input); + dmfree(full_param); + return fault; +} + +int dm_entry_operate(struct dmctx *dmctx) +{ + DMOBJ *root = dmctx->dm_entryobj; + DMNODE node = { .current_object = "" }; + int err; + + if (dmctx->in_param == NULL || dmctx->in_param[0] == '\0' || (*(dmctx->in_param + strlen(dmctx->in_param) - 1) != ')')) + return CMD_NOT_FOUND; + + dmctx->iscommand = 1; + dmctx->inparam_isparam = 1; + dmctx->stop = 0; + dmctx->checkobj = plugin_obj_match; + dmctx->checkleaf = plugin_leaf_match; + dmctx->method_obj = mobj_operate; + dmctx->method_param = mparam_operate; + err = dm_browse(dmctx, &node, root, NULL, NULL); + if (dmctx->stop) + return err; + else + return CMD_NOT_FOUND; +} + int dm_browse_last_access_path(char *path, size_t len) { snprintf(path, len, "%s", dm_browse_path); diff --git a/libbbf_api/dmbbf.h b/libbbf_api/dmbbf.h index cb0e6119..8933dadb 100644 --- a/libbbf_api/dmbbf.h +++ b/libbbf_api/dmbbf.h @@ -46,6 +46,8 @@ do { \ extern struct dm_permession_s DMREAD; extern struct dm_permession_s DMWRITE; +extern struct dm_permession_s DMSYNC; +extern struct dm_permession_s DMASYNC; extern char *DMT_TYPE[]; extern int bbfdatamodel_type; @@ -184,6 +186,7 @@ struct dmctx char *inst_buf[16]; unsigned int end_session_flag; bool isgetschema; + bool iscommand; }; typedef struct dmnode { @@ -216,12 +219,18 @@ typedef struct dm_map_vendor_exclude { char **vendor_obj; } DM_MAP_VENDOR_EXCLUDE; -enum operate_ret_status{ +enum operate_ret_status { + CMD_INVALID_ARGUMENTS, + CMD_SUCCESS, + CMD_FAIL, + CMD_NOT_FOUND, + __STATUS_MAX, +}; + +enum deprecated_operate_ret_status { UBUS_INVALID_ARGUMENTS, SUCCESS, FAIL, - CMD_NOT_FOUND, - __STATUS_MAX, }; typedef struct { @@ -385,6 +394,7 @@ enum dmt_type_enum { DMT_TIME, DMT_HEXBIN, DMT_BASE64, + DMT_COMMAND, }; enum amd_version_enum { @@ -445,6 +455,8 @@ int dm_entry_set_notification(struct dmctx *dmctx); int dm_entry_enabled_notify(struct dmctx *dmctx); int dm_entry_get_linker(struct dmctx *dmctx); int dm_entry_get_linker_value(struct dmctx *dmctx); +int dm_entry_list_operates(struct dmctx *ctx); +int dm_entry_operate(struct dmctx *dmctx); int dm_browse_last_access_path(char *path, size_t len); char *get_last_instance(char *package, char *section, char *opt_inst); char *get_last_instance_bbfdm(char *package, char *section, char *opt_inst); diff --git a/test/bbf_test/libbbf_test.c b/test/bbf_test/libbbf_test.c index b1d5b39d..3e237dbb 100644 --- a/test/bbf_test/libbbf_test.c +++ b/test/bbf_test/libbbf_test.c @@ -20,31 +20,7 @@ DM_MAP_OBJ tDynamicObj[] = { /* parentobj, nextobject, parameter */ {"Device.ManagementServer.", tDynamicManagementServerObj, tDynamicManagementServerParams}, -{"Device.", tDynamicDeviceObj, NULL}, -{0} -}; - -/* ********** DynamicOperate ********** */ -DM_MAP_OPERATE tDynamicOperate[] = { -/* pathname, operation, type, args */ -{ - "Device.X_IOPSYS_EU_PingTEST.Run", DynamicDevicePingOperate, "async", - { - .in = (const char *[]) { - "Host", - NULL - }, - .out = (const char *[]) { - "AverageResponseTime", - "MinimumResponseTime", - "MaximumResponseTime", - NULL - } - } -}, -{ - "Device.X_IOPSYS_EU_Reboot", DynamicDeviceRebootOperate, "sync" -}, +{"Device.", tDynamicDeviceObj, tDynamicDeviceParams}, {0} }; @@ -283,16 +259,40 @@ static int set_X_IOPSYS_EU_Syslog_ConsoleLogLevel(char *refparam, struct dmctx * } /************************************************************* - * OPERATE + * OPERATE COMMANDS *************************************************************/ -opr_ret_t DynamicDevicePingOperate(struct dmctx *dmctx, char *path, json_object *input) +static int operate_Device_X_IOPSYS_EU_Reboot(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + return !dmubus_call_set("system", "reboot", UBUS_ARGS{}, 0) ? CMD_SUCCESS : CMD_FAIL; +} + +static operation_args x_iopsys_eu_ping_test_run_args = { + .in = (const char *[]) { + "Host", + NULL + }, + .out = (const char *[]) { + "AverageResponseTime", + "MinimumResponseTime", + "MaximumResponseTime", + NULL + } +}; + +static int get_operate_args_XIOPSYSEUPingTEST_Run(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&x_iopsys_eu_ping_test_run_args; + return 0; +} + +static int operate_DeviceXIOPSYSEUPingTEST_Run(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) { char *p, *min = NULL, *avg = NULL, *max = NULL, line[512], command[512]; FILE *log = NULL; - char *host = dmjson_get_value(input, 1, "Host"); + char *host = dmjson_get_value((json_object *)value, 1, "Host"); if(host[0] == '\0') - return UBUS_INVALID_ARGUMENTS; + return CMD_INVALID_ARGUMENTS; snprintf(command, sizeof(command), "ping -c 1 -W 1 %s", host); @@ -301,25 +301,17 @@ opr_ret_t DynamicDevicePingOperate(struct dmctx *dmctx, char *path, json_object if (strstr(line, "rtt")) { strtok_r(line, "=", &min); strtok_r(min+1, "/", &avg); - add_list_parameter(dmctx, dmstrdup("MinimumResponseTime"), dmstrdup(min ? min+1 : ""), "xsd:unsignedInt", NULL); + add_list_parameter(ctx, dmstrdup("MinimumResponseTime"), dmstrdup(min ? min+1 : ""), "xsd:unsignedInt", NULL); strtok_r(avg, "/", &max); - add_list_parameter(dmctx, dmstrdup("AverageResponseTime"), dmstrdup(avg ? avg : ""), "xsd:unsignedInt", NULL); + add_list_parameter(ctx, dmstrdup("AverageResponseTime"), dmstrdup(avg ? avg : ""), "xsd:unsignedInt", NULL); strtok_r(max, "/", &p); - add_list_parameter(dmctx, dmstrdup("MaximumResponseTime"), dmstrdup(max ? max : ""), "xsd:unsignedInt", NULL); + add_list_parameter(ctx, dmstrdup("MaximumResponseTime"), dmstrdup(max ? max : ""), "xsd:unsignedInt", NULL); break; } } pclose(log); } - return SUCCESS; -} - -opr_ret_t DynamicDeviceRebootOperate(struct dmctx *dmctx, char *path, json_object *input) -{ - if (0 == dmubus_call_set("system", "reboot", UBUS_ARGS{}, 0)) - return SUCCESS; - else - return FAIL; + return CMD_SUCCESS; } /********************************************************************************************************************************** @@ -352,6 +344,13 @@ DMLEAF tManagementServerInformParameterParams[] = { DMOBJ tDynamicDeviceObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ {"X_IOPSYS_EU_Syslog", &DMREAD, NULL, NULL, "file:/etc/config/system", NULL, NULL, NULL, NULL, tX_IOPSYS_EU_SyslogParam, NULL, BBFDM_BOTH}, +{"X_IOPSYS_EU_PingTEST", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tX_IOPSYS_EU_PingTESTParam, NULL, BBFDM_BOTH}, +{0} +}; + +DMLEAF tDynamicDeviceParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"X_IOPSYS_EU_Reboot()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_X_IOPSYS_EU_Reboot, BBFDM_USP}, {0} }; @@ -363,3 +362,10 @@ DMLEAF tX_IOPSYS_EU_SyslogParam[] = { {"ConsoleLogLevel", &DMWRITE, DMT_UNINT, get_X_IOPSYS_EU_Syslog_ConsoleLogLevel, set_X_IOPSYS_EU_Syslog_ConsoleLogLevel, BBFDM_BOTH}, {0} }; + +/*** Device.X_IOPSYS_EU_PingTEST. ***/ +DMLEAF tX_IOPSYS_EU_PingTESTParam[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"Run()", &DMASYNC, DMT_COMMAND, get_operate_args_XIOPSYSEUPingTEST_Run, operate_DeviceXIOPSYSEUPingTEST_Run, BBFDM_USP}, +{0} +}; diff --git a/test/bbf_test/libbbf_test.h b/test/bbf_test/libbbf_test.h index 8861adb4..407a0f80 100644 --- a/test/bbf_test/libbbf_test.h +++ b/test/bbf_test/libbbf_test.h @@ -15,10 +15,9 @@ extern DMOBJ tDynamicManagementServerObj[]; extern DMLEAF tDynamicManagementServerParams[]; extern DMLEAF tManagementServerInformParameterParams[]; extern DMOBJ tDynamicDeviceObj[]; +extern DMLEAF tDynamicDeviceParams[]; extern DMLEAF tX_IOPSYS_EU_SyslogParam[]; - -opr_ret_t DynamicDevicePingOperate(struct dmctx *dmctx, char *path, json_object *input); -opr_ret_t DynamicDeviceRebootOperate(struct dmctx *dmctx, char *path, json_object *input); +extern DMLEAF tX_IOPSYS_EU_PingTESTParam[]; #endif //__LIBBBFD_TEST_H diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c index 837d40b7..dfe47b68 100644 --- a/test/cmocka/functional_test_bbfd.c +++ b/test/cmocka/functional_test_bbfd.c @@ -77,7 +77,7 @@ static void test_api_bbfdm_get_set_standard_parameter(void **state) assert_int_equal(fault, 0); // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); // get value ==> expected "0" error @@ -105,7 +105,7 @@ static void test_api_bbfdm_get_set_json_parameter(void **state) assert_int_equal(fault, 0); // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); // get value ==> expected "0" error @@ -137,7 +137,7 @@ static void test_api_bbfdm_get_set_library_parameter(void **state) assert_int_equal(fault, 0); // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); // get value ==> expected "0" error @@ -362,8 +362,8 @@ static void test_api_bbfdm_valid_standard_operate(void **state) struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPPing", input, NULL); - assert_int_equal(fault, SUCCESS); + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPPing()", input, NULL); + assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { if (strcmp(n->name, "SuccessCount") == 0) { @@ -384,8 +384,8 @@ static void test_api_bbfdm_valid_library_operate(void **state) struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.X_IOPSYS_EU_PingTEST.Run", input, NULL); - assert_int_equal(fault, SUCCESS); + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.X_IOPSYS_EU_PingTEST.Run()", input, NULL); + assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { assert_string_not_equal(n->data, "0"); diff --git a/test/cmocka/unit_test_bbfd.c b/test/cmocka/unit_test_bbfd.c index a6c9f76d..7565543e 100644 --- a/test/cmocka/unit_test_bbfd.c +++ b/test/cmocka/unit_test_bbfd.c @@ -284,7 +284,7 @@ static void test_api_bbfdm_set_value_parameter(void **state) first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); assert_true(&first_fault->list == &ctx->list_fault_param); - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); } @@ -538,8 +538,8 @@ static void test_api_bbfdm_valid_operate(void **state) struct dmctx *ctx = (struct dmctx *) *state; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.DHCPv4.Client.1.Renew", NULL, NULL); - assert_int_equal(fault, SUCCESS); + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.WiFi.AccessPoint.1.Security.Reset()", NULL, NULL); + assert_int_equal(fault, CMD_SUCCESS); } static void test_api_bbfdm_wrong_operate(void **state) @@ -547,7 +547,7 @@ static void test_api_bbfdm_wrong_operate(void **state) struct dmctx *ctx = (struct dmctx *) *state; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPing", NULL, NULL); + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPing()", NULL, NULL); assert_int_equal(fault, CMD_NOT_FOUND); } @@ -682,7 +682,7 @@ static void test_api_bbfdm_json_set_value(void **state) first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); assert_true(&first_fault->list == &ctx->list_fault_param); - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Dropbear.1.Port", "9856", NULL); @@ -691,7 +691,7 @@ static void test_api_bbfdm_json_set_value(void **state) first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); assert_true(&first_fault->list == &ctx->list_fault_param); - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); } @@ -766,7 +766,7 @@ static void test_api_bbfdm_library_set_value(void **state) first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); assert_true(&first_fault->list == &ctx->list_fault_param); - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Syslog.ServerPort", "9856", NULL); @@ -775,7 +775,7 @@ static void test_api_bbfdm_library_set_value(void **state) first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); assert_true(&first_fault->list == &ctx->list_fault_param); - fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key"); assert_int_equal(fault, 0); } diff --git a/tools/bbf_common.py b/tools/bbf_common.py index 93a63e13..16fc434c 100755 --- a/tools/bbf_common.py +++ b/tools/bbf_common.py @@ -38,7 +38,8 @@ Array_Types = {"string": "DMT_STRING", "boolean": "DMT_BOOL", "dateTime": "DMT_TIME", "hexBinary": "DMT_HEXBIN", - "base64": "DMT_BASE64"} + "base64": "DMT_BASE64", + "command": "DMT_COMMAND"} def rename_file(old_file_name, new_file_name): diff --git a/tools/convert_dm_json_to_c.py b/tools/convert_dm_json_to_c.py index a12a6a25..f140df51 100755 --- a/tools/convert_dm_json_to_c.py +++ b/tools/convert_dm_json_to_c.py @@ -798,6 +798,52 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par fp.close() +def cprinOperateCommands(getoperateargs, operate, in_args, out_args, struct_name): + # Open file + fp = open('./.operatecommands.c', 'a') + + if in_args != None or out_args != None: + ############################## OPERATE ARGUMENTS ######################################## + print("static operation_args %s = {" % struct_name, file=fp) + + if in_args != None: + if isinstance(in_args, dict): + print(" .in = (const char *[]) {", file=fp) + for obj, _val in in_args.items(): + print(" \"%s\"," % obj, file=fp) + print(" NULL", file=fp) + print(" %s" % ("}," if out_args != None else "}"), file=fp) + + if out_args != None: + if isinstance(out_args, dict): + print(" .out = (const char *[]) {", file=fp) + for obj, _val in out_args.items(): + print(" \"%s\"," % obj, file=fp) + print(" NULL", file=fp) + print(" }", file=fp) + + print("};", file=fp) + print("", file=fp) + + print("static int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)" % getoperateargs, file=fp) + print("{", file=fp) + print(" *value = (char *)&%s;" % struct_name, file=fp) + print(" return 0;", file=fp) + print("}", file=fp) + print("", file=fp) + + ############################## OPERATE ######################################## + print("static int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % operate, file=fp) + print("{", file=fp) + print(" //TODO", file=fp) + print(" return CMD_SUCCESS;", file=fp) + print("}", file=fp) + print("", file=fp) + + # Close file + fp.close() + + def cprintheaderPARAMS(objname): fp = open('./.objparamarray.c', 'a') print("DMLEAF %s[] = {" % ("t" + getname(objname) + "Params"), file=fp) @@ -841,6 +887,32 @@ def printPARAMline(parentname, dmparam, value): fp.close() +def printCOMMANDline( parentname, dmparam, value ): + commonname = getname(parentname) + "_" + dmparam + ptype = bbf.get_param_type(value) + operate = "operate_" + commonname.replace("()", "") + bbfdm = getprotocolsparam(value, "protocols") + asyncparam = bbf.get_option_value(value, "async") + in_args = bbf.get_option_value(value, "input") + out_args = bbf.get_option_value(value, "output") + + if asyncparam: + c_type = "&DMASYNC" + else: + c_type = "&DMSYNC" + + if in_args != None or out_args != None: + getoperateargs = "get_operate_args_" + commonname.replace("()", "") + else: + getoperateargs = "NULL" + + cprinOperateCommands(getoperateargs, operate, in_args, out_args, commonname.replace("()", "").lower()+"_args") + + fp = open('./.objparamarray.c', 'a') + print("{\"%s\", %s, %s, %s, %s, %s}," % (dmparam, c_type, ptype, getoperateargs, operate, bbfdm), file=fp) + fp.close() + + def printtailArray(): fp = open('./.objparamarray.c', 'a') print("{0}", file=fp) @@ -943,9 +1015,15 @@ def object_parse_childs(dmobject, value, nextlevel): continue if isinstance(v, dict): for k1, v1 in v.items(): - if k1 == "type" and v1 != "object" and "()" not in k: + + if k1 == "type" and v1 == "command": + printCOMMANDline(dmobject, k, v) + break + + if k1 == "type" and v1 != "object": printPARAMline(dmobject, k, v) break + printtailArray() if hasobj and nextlevel == 0: @@ -1012,6 +1090,19 @@ def generatecfromobj(pobj, pvalue, pdir, nextlevel): except IOError: pass + try: + exists = os.path.isfile("./.operatecommands.c") + if exists: + print("/*************************************************************", file=dmfpc) + print("* OPERATE COMMANDS", file=dmfpc) + print("**************************************************************/", file=dmfpc) + tmpf = open("./.operatecommands.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except IOError: + pass + try: print("/**********************************************************************************************************************************", file=dmfpc) print("* OBJ & PARAM DEFINITION", file=dmfpc) @@ -1042,6 +1133,7 @@ def removetmpfiles(): bbf.remove_file("./.objadddel.c") bbf.remove_file("./.objbrowse.c") bbf.remove_file("./.getstevalue.c") + bbf.remove_file("./.operatecommands.c") ### main ### diff --git a/tools/generate_dm_excel.py b/tools/generate_dm_excel.py index b7825568..7fd1e1b6 100755 --- a/tools/generate_dm_excel.py +++ b/tools/generate_dm_excel.py @@ -27,7 +27,7 @@ def getprotocols(value): return "CWMP+USP" -def check_param_obj(dmobject): +def check_param_obj_command(dmobject): for value in bbf.LIST_SUPPORTED_DM: obj = value.split(",") if obj[0] == dmobject: @@ -36,16 +36,6 @@ def check_param_obj(dmobject): return "No" -def check_commands(param): - cmd = 'awk \'/static const struct op_cmd operate_helper/,/^};$/\' ../dmoperate.c' - param = param.replace(".{i}.", ".*.").replace("()", "") - - res = os.popen(cmd).read() - string = "\n\t{\n\t\t\"%s\"," % param - - return "Yes" if string in res else "No" - - def add_data_to_list_dm(obj, supported, protocols, types): LIST_DM.append(obj + "," + protocols + "," + supported + "," + types) @@ -54,7 +44,7 @@ def parse_standard_object(dmobject, value): hasobj = bbf.obj_has_child(value) hasparam = bbf.obj_has_param(value) - supported = check_param_obj(dmobject) + supported = check_param_obj_command(dmobject) add_data_to_list_dm(dmobject, supported, getprotocols(value), "object") if hasparam: @@ -65,14 +55,8 @@ def parse_standard_object(dmobject, value): if isinstance(v, dict): for k1, v1 in v.items(): if k1 == "type" and v1 != "object": - if "()" in k: - supported = check_commands(dmobject + k) - add_data_to_list_dm( - dmobject + k, supported, getprotocols(v), "operate") - else: - supported = check_param_obj(dmobject + k) - add_data_to_list_dm( - dmobject + k, supported, getprotocols(v), "parameter") + supported = check_param_obj_command(dmobject + k) + add_data_to_list_dm(dmobject + k, supported, getprotocols(v), "operate" if "()" in k else "parameter") break if hasobj: diff --git a/tools/generate_dm_xml.py b/tools/generate_dm_xml.py index 89a7209a..d2721ff6 100755 --- a/tools/generate_dm_xml.py +++ b/tools/generate_dm_xml.py @@ -53,6 +53,9 @@ def generate_bbf_xml_file(output_file): for value in bbf.LIST_SUPPORTED_DM: + if "()" in value: + continue + obj = value.strip().split(",") access = "readOnly" if obj[1] == "DMREAD" else "readWrite" @@ -146,6 +149,9 @@ def generate_hdm_xml_file(output_file): for value in bbf.LIST_SUPPORTED_DM: + if "()" in value: + continue + obj = value.strip().split(",") if obj[2] == "DMT_OBJ":