From 4ab526b9f2aea6b48079d215dfd63bd63f075579 Mon Sep 17 00:00:00 2001 From: Amin Ben Ramdhane Date: Tue, 21 Jan 2020 22:43:37 +0100 Subject: [PATCH] Ticket refs#1598: libbbfdm: plug-in based with support for dynamic loading of libraries + separate libbbfdm into two libraries: libbbf_api (API) and libbbfdm (data model) --- README.md | 85 +++- bin/Makefile.am | 53 ++- dmbbfcommon.c | 106 +++++ dmbbfcommon.h | 36 ++ dmdiagnostics.c | 3 +- dmentry.c | 55 ++- dmentry.h | 5 +- dmentryjson.c | 162 +++---- dmentryjson.h | 6 +- dmentrylibrary.c | 183 ++++++++ dmentrylibrary.h | 21 + dmoperate.c | 66 ++- dmoperate.h | 30 +- dmtree/tr104/voice_services.c | 24 +- dmtree/tr143/diagnostics.c | 18 +- dmtree/tr157/bulkdata.c | 18 +- dmtree/tr157/softwaremodules.c | 14 +- dmtree/tr181/atm.c | 16 +- dmtree/tr181/bridging.c | 18 +- dmtree/tr181/datamodelversion.h | 4 +- dmtree/tr181/device.c | 8 +- dmtree/tr181/deviceinfo.c | 14 +- dmtree/tr181/deviceinfo.h | 2 +- dmtree/tr181/dhcpv4.c | 25 +- dmtree/tr181/dhcpv6.c | 21 +- dmtree/tr181/dns.c | 20 +- dmtree/tr181/dsl.c | 20 +- dmtree/tr181/dynamicdns.c | 14 +- dmtree/tr181/ethernet.c | 20 +- dmtree/tr181/firewall.c | 12 +- dmtree/tr181/gre.c | 11 +- dmtree/tr181/hosts.c | 14 +- dmtree/tr181/interfacestack.c | 8 +- dmtree/tr181/ip.c | 14 +- dmtree/tr181/managementserver.c | 12 +- dmtree/tr181/managementserver.h | 2 +- dmtree/tr181/nat.c | 10 +- dmtree/tr181/ppp.c | 14 +- dmtree/tr181/ptm.c | 16 +- dmtree/tr181/qos.c | 12 +- dmtree/tr181/routing.c | 16 +- dmtree/tr181/times.c | 8 +- dmtree/tr181/times.h | 2 +- dmtree/tr181/upnp.c | 10 +- dmtree/tr181/usb.c | 18 +- dmtree/tr181/userinterface.c | 12 +- dmtree/tr181/users.c | 6 +- dmtree/tr181/users.h | 2 +- dmtree/tr181/wifi.c | 31 +- dmtree/tr181/x_iopsys_eu_buttons.c | 8 +- dmtree/tr181/x_iopsys_eu_dropbear.c | 8 +- dmtree/tr181/x_iopsys_eu_ice.c | 8 +- dmtree/tr181/x_iopsys_eu_igmp.c | 8 +- dmtree/tr181/x_iopsys_eu_ipacccfg.c | 10 +- dmtree/tr181/x_iopsys_eu_logincfg.c | 8 +- dmtree/tr181/x_iopsys_eu_owsd.c | 10 +- dmtree/tr181/x_iopsys_eu_power_mgmt.c | 6 +- dmtree/tr181/x_iopsys_eu_syslog.c | 8 +- dmtree/tr181/x_iopsys_eu_wifilife.c | 10 +- dmtree/tr181/xmpp.c | 12 +- json/convertor_json_to_c.py | 2 +- dmbbf.c => libbbf_api/dmbbf.c | 147 ++++-- dmbbf.h => libbbf_api/dmbbf.h | 43 +- dmcommon.c => libbbf_api/dmcommon.c | 3 +- dmcommon.h => libbbf_api/dmcommon.h | 3 + dmjson.c => libbbf_api/dmjson.c | 0 dmjson.h => libbbf_api/dmjson.h | 0 dmmem.c => libbbf_api/dmmem.c | 0 dmmem.h => libbbf_api/dmmem.h | 0 dmubus.c => libbbf_api/dmubus.c | 0 dmubus.h => libbbf_api/dmubus.h | 0 dmuci.c => libbbf_api/dmuci.c | 0 dmuci.h => libbbf_api/dmuci.h | 0 library/example.json | 53 +++ library/example/Makefile | 23 + library/example/example.c | 151 ++++++ library/example/example.h | 25 + library/generate_library.py | 641 ++++++++++++++++++++++++++ pictures/rootdynamicobj.png | Bin 0 -> 18115 bytes pictures/rootdynamincoperate.png | Bin 0 -> 17682 bytes 80 files changed, 1959 insertions(+), 525 deletions(-) create mode 100644 dmbbfcommon.c create mode 100644 dmbbfcommon.h create mode 100644 dmentrylibrary.c create mode 100644 dmentrylibrary.h rename dmbbf.c => libbbf_api/dmbbf.c (96%) rename dmbbf.h => libbbf_api/dmbbf.h (94%) rename dmcommon.c => libbbf_api/dmcommon.c (99%) rename dmcommon.h => libbbf_api/dmcommon.h (99%) rename dmjson.c => libbbf_api/dmjson.c (100%) rename dmjson.h => libbbf_api/dmjson.h (100%) rename dmmem.c => libbbf_api/dmmem.c (100%) rename dmmem.h => libbbf_api/dmmem.h (100%) rename dmubus.c => libbbf_api/dmubus.c (100%) rename dmubus.h => libbbf_api/dmubus.h (100%) rename dmuci.c => libbbf_api/dmuci.c (100%) rename dmuci.h => libbbf_api/dmuci.h (100%) create mode 100644 library/example.json create mode 100644 library/example/Makefile create mode 100644 library/example/example.c create mode 100644 library/example/example.h create mode 100755 library/generate_library.py create mode 100644 pictures/rootdynamicobj.png create mode 100644 pictures/rootdynamincoperate.png diff --git a/README.md b/README.md index 9701854f..2024f507 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ The root directory of bbfdm library is **“src”** which is structred as follo The bbfdm library offers a tool to generate templates of the source code from json files. ```plain -$ ./convertor_json_to_c.py -Usage: ./convertor_json_to_c.py +$ python convertor_json_to_c.py +Usage: convertor_json_to_c.py Examples: - - ./convertor_json_to_c.py tr181.json + - convertor_json_to_c.py tr181.json ==> Generate the C code of all data model in tr181/ folder - - ./convertor_json_to_c.py tr104.json + - convertor_json_to_c.py tr104.json ==> Generate the C code of all data model in tr104/ folder ``` **Note:** Any developer can full the json file (**tr181.json** or **tr104.json**) with mapping field according to UCI, UBUS or CLI commands before generating the source code in C. @@ -95,7 +95,7 @@ Each object in the **DMOBJ** table contains the following arguments: | `browseinstobj` | This function allow to browse all instances under this object | | `forced_inform` | If it's set to `&DMFINFRM` that mean the object contains a force inform parameter in its subtree. The forced inform parameters are the parameter included in the inform message | | `notification` | The notification of the object. Could be **&DMACTIVE**, **&DMACTIVE** or **&DMNONE** | -| `nextjsonobj` | Pointer to a **DMOBJ** array which contains a list of the child objects using json file | +| `nextdynamicobj` | Pointer to the next of **DMOBJ** which contains a list of the child objects using json files and plugins(libraries) | | `nextobj` | Pointer to a **DMOBJ** array which contains a list of the child objects | | `leaf` | Pointer to a **DMLEAF** array which contains a list of the child objects | | `linker` | This argument is used for LowerLayer parameters or to make reference to other instance object in the tree | @@ -116,7 +116,10 @@ Each parameter in the **DMLEAF** table contains the following arguments: | `notification` | The notification of the parameter. Could be **&DMACTIVE**, **&DMACTIVE** or **&DMNONE** | | `bbfdm_type` | The bbfdm type of the parameter. Could be **BBFDM_CWMP**, **BBFDM_USP** or **BBFDM_NONE**.If it's `BBFDM_NONE` then we can see this parameter in all protocols (CWMP, USP,...) | -## BBFDM API used for GET/SET/ADD/Delete calls ## +## BBFDM API ## + +The bbfdm API is used for GET/SET/ADD/Delete/Operate calls. + It includes list of `UCI` functions. The most used one are as follow: **1. dmuci_get_option_value_string:** execute the uci get value @@ -202,21 +205,25 @@ End of BBF Data Models Generation #### JSON generator: #### It is a generator of json file from C source code. ```plain -$ ./generator_json_with_backend.py -Usage: ./generator_json_with_backend.py [Object path] +$ python generator_json_with_backend.py +Usage: generator_json_with_backend.py [Object path] Examples: - - ./generator_json_with_backend.py tr-181-2-12-0-cwmp-full.xml tr-181-2-12-0-usp-full.xml Device. + - generator_json_with_backend.py tr-181-2-12-0-cwmp-full.xml tr-181-2-12-0-usp-full.xml Device. ==> Generate the json file of the sub tree Device. in tr181.json - - ./generator_json_with_backend.py tr-104-1-1-0-full.xml VoiceService. + - generator_json_with_backend.py tr-104-1-1-0-full.xml VoiceService. ==> Generate the json file of the sub tree VoiceService. in tr104.json - - ./generator_json_with_backend.py tr-106-1-2-0-full.xml Device. + - generator_json_with_backend.py tr-106-1-2-0-full.xml Device. ==> Generate the json file of the sub tree Device. in tr106.json Example of xml data model file: https://www.broadband-forum.org/cwmp/tr-181-2-12-0-cwmp-full.xml ``` -#### Additional dynamic parameters at run time #### -The bbfdm library allows all applications installed on the box to import its own tr-181 data model parameters at run time.
+#### Load additional parameters at run time #### + +The bbfdm library allows all applications installed on the box to import its own tr-181 data model parameters at run time in two formats: **JSON files** and **Plugin(library) files**. + +#### `JSON Files:` #### + The application should bring its JSON file under **'/etc/bbfdm/json/'** path with **UCI** and **UBUS** mappings. The new added parameters will be automatically shown by icwmp and uspd/obuspa. **1. Object without instance:** @@ -394,4 +401,56 @@ The application should bring its JSON file under **'/etc/bbfdm/json/'** path wit } } ``` +#### +#### `Plugin(library) Files:` #### + +The application should bring its plugin(library) file 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 icwmp and uspd/obuspa. + +To build a new library, you can use **example source code** under **library** folder to help you build it. + +Each library should contains two Root table named **“tRootDynamicObj”** and **“tRootDynamicOperate”** to define the parant path for each new object and operate. + +#### RootDynamicObject definition #### +![object](/pictures/rootdynamicobj.png) + +Each object in the **LIB_MAP_OBJ** table contains two arguments: + +| Argument | Description | +| ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `parentobj` | A string of the parent object name. Example “Device.IP.Diagnostics.”, “Device.DeviceInfo”, “Device.WiFi.Radio.” | +| `nextobject` | Pointer to a **DMOBJ** array which contains a list of the child objects. | + +#### RootDynamicOperate definition #### +![object](/pictures/rootdynamincoperate.png) + +Each operate in the **LIB_MAP_OPERATE** table 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 which return the status of this operate. | + +For the other tables, they are defined in the same way as the [Object and Parameter](#object-definition) definition described above. + +**Below are the steps for building of a new library using JSON file** + +**1. Create the json file:** + +Any developer should create a json file containing object requested as defined in the above section of **JSON Files**. You can find an example of json file **example.json** under **library** folder. + +**2. Generate the source code:** + +The bbfdm library offers a tool to generate templates of the library source code from json file. You can find the tool **generate_library.py** under **library** folder. + +```plain +$ python generate_library.py +Usage: generate_library.py +Examples: + - generate_library.py example.json + ==> Generate the C code in example/ folder +``` + +**3. Fill the functions of object/parameter:** + +After building the templates of source code, a **test.c, test.h and Makefile** files will be generated under **test** folder that contains the functions related to each object, parameter and operate. Then, you have to fill each function with the necessary [bbfdm API](#bbfdm-api) defined above. You can find an example of source code **(example folder)** under **library** folder. diff --git a/bin/Makefile.am b/bin/Makefile.am index c1d66dea..1d405820 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,20 +1,47 @@ LIB_BBFDM_VERSION = 3:0:0 -lib_LTLIBRARIES = libbbfdm.la +lib_LTLIBRARIES = libbbf_api.la + +libbbf_api_la_SOURCES = \ + ../libbbf_api/dmbbf.c \ + ../libbbf_api/dmubus.c \ + ../libbbf_api/dmjson.c \ + ../libbbf_api/dmuci.c \ + ../libbbf_api/dmcommon.c \ + ../libbbf_api/dmmem.c + +libbbf_api_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBUCI_CFLAGS) \ + $(LIBUBOX_CFLAGS) \ + $(LIBUBUS_CFLAGS) + +libbbf_api_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + $(LIBUCI_LDFLAGS) \ + $(LIBUBOX_LDFLAGS) \ + $(LIBUBUS_LDFLAGS) + +libbbf_api_la_LIBADD = \ + $(AM_LIBS) \ + $(LIBUCI_LIBS) \ + $(LIBUBOX_LIBS) \ + $(LIBUBUS_LIBS) \ + $(LIBJSON_LIBS) \ + $(LBLOBMSG_LIBS) + + +lib_LTLIBRARIES += libbbfdm.la libbbfdm_la_SOURCES = \ - ../md5.c \ - ../dmbbf.c \ - ../dmentry.c \ - ../dmmem.c \ - ../dmubus.c \ - ../dmjson.c \ - ../dmuci.c \ - ../dmcommon.c \ - ../dmoperate.c \ - ../dmdiagnostics.c \ + ../dmentry.c \ + ../dmentrylibrary.c \ ../dmentryjson.c \ ../dmmemjson.c \ + ../dmoperate.c \ + ../dmdiagnostics.c \ + ../dmbbfcommon.c \ + ../md5.c \ ../wepkey.c if BBF_TR181 @@ -106,10 +133,10 @@ libbbfdm_la_LIBADD = \ $(LIBUBUS_LIBS) \ $(LIBJSON_LIBS) \ $(LIBTRACE_LIBS) \ - $(LBLOBMSG_LIBS) + $(LBLOBMSG_LIBS) \ + -lbbf_api libbbfdm_la_CFLAGS+=-I../ -libbbfdm_la_CFLAGS+=-I../dmtree/ libbbfdm_la_CFLAGS+=-I../dmtree/tr181 libbbfdm_la_CFLAGS+=-I../dmtree/tr104 libbbfdm_la_CFLAGS+=-I../dmtree/tr143 diff --git a/dmbbfcommon.c b/dmbbfcommon.c new file mode 100644 index 00000000..c365310d --- /dev/null +++ b/dmbbfcommon.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 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 "dmbbfcommon.h" + +int bbfdmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value) +{ + return dmuci_lookup_ptr(ctx, ptr, package, section, option, value); +} + +void bbf_apply_end_session(void) +{ + apply_end_session(); +} + +int set_bbfdatamodel_type(int bbf_type) +{ + bbfdatamodel_type = bbf_type; + return 0; +} + +int set_upnp_in_user_mask(unsigned int upnp_user_mask) +{ + upnp_in_user_mask = upnp_user_mask; + return 0; +} + +int bbf_set_ip_version(int ipversion) +{ + ip_version = ipversion; + return 0; +} + +int set_bbf_end_session_flag(int flag) +{ + return (end_session_flag &= flag); +} + +int reset_bbf_end_session_flag(void) +{ + end_session_flag = 0; + return 0; +} + +void bbf_del_list_parameter(struct dm_parameter *dm_parameter) +{ + del_list_parameter(dm_parameter); +} + +void bbf_cwmp_set_end_session (unsigned int flag) +{ + cwmp_set_end_session (flag); +} + +int bbfdm_update_file_enabled_notify(char *param, char *new_value) +{ + return dm_update_file_enabled_notify(param, new_value); +} + +void bbfdmjson_parse_init(char *msg) +{ + dmjson_parse_init(msg); +} + +void bbfdmjson_parse_fini(void) +{ + dmjson_parse_fini(); +} + +json_object *bbfdmjson_select_obj(json_object * jobj, char *argv[]) +{ + return (dmjson_select_obj(jobj, argv)); +} + +void bbf_del_list_fault_param(struct param_fault *param_fault) +{ + del_list_fault_param(param_fault); +} + +int dm_copy_temporary_file_to_original_file(char *f1, char *f2) +{ + return copy_temporary_file_to_original_file(f1, f2); +} + +void bbfdmjson_get_var(char *jkey, char **jval) +{ + dmjson_get_var(jkey, jval); +} + +void bbfdm_update_enabled_notify(struct dm_enabled_notify *p, char *new_value) +{ + dm_update_enabled_notify(p, new_value); +} + +struct list_head get_bbf_list_enabled_lw_notify(void) +{ + return list_enabled_lw_notify; +} diff --git a/dmbbfcommon.h b/dmbbfcommon.h new file mode 100644 index 00000000..fec7df5b --- /dev/null +++ b/dmbbfcommon.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 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 +#include +#include +#include +#include + +int bbfdmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value); +void bbf_apply_end_session(void); +int set_bbfdatamodel_type(int bbf_type); +int set_upnp_in_user_mask(unsigned int upnp_user_mask); +int bbf_set_ip_version(int ipversion); +int set_bbf_end_session_flag(int flag); +int reset_bbf_end_session_flag(void); +void bbf_del_list_parameter(struct dm_parameter *dm_parameter); +void bbf_cwmp_set_end_session (unsigned int flag); +int bbfdm_update_file_enabled_notify(char *param, char *new_value); +void bbfdmjson_parse_init(char *msg); +void bbfdmjson_parse_fini(void); +json_object *bbfdmjson_select_obj(json_object * jobj, char *argv[]); +void bbf_del_list_fault_param(struct param_fault *param_fault); +int dm_copy_temporary_file_to_original_file(char *f1, char *f2); +void bbfdmjson_get_var(char *jkey, char **jval); +void bbfdm_update_enabled_notify(struct dm_enabled_notify *p, char *new_value); +struct list_head get_bbf_list_enabled_lw_notify(void); + diff --git a/dmdiagnostics.c b/dmdiagnostics.c index a23d950e..22ab080e 100644 --- a/dmdiagnostics.c +++ b/dmdiagnostics.c @@ -23,8 +23,7 @@ #include #include #include -#include "dmentry.h" -#include "dmcommon.h" +#include #include "dmdiagnostics.h" int read_next; diff --git a/dmentry.c b/dmentry.c index f7b4f0b7..8107b828 100644 --- a/dmentry.c +++ b/dmentry.c @@ -8,21 +8,23 @@ * Author MOHAMED Kallel * Author Imen Bhiri * Author Feten Besbes + * Author Amin Ben Ramdhane * */ #include #include #include -#include "dmbbf.h" -#include "dmubus.h" -#include "dmuci.h" +#include +#include +#include +#include #include "dmentry.h" +#include "dmentryjson.h" +#include "dmentrylibrary.h" +#include "dmoperate.h" #include "device.h" #include "wepkey.h" -#include "dmcommon.h" -#include "dmoperate.h" -#include "dmentryjson.h" LIST_HEAD(head_package_change); unsigned char dmcli_timetrack = 0; @@ -155,33 +157,21 @@ int dm_ctx_clean_sub(struct dmctx *ctx) return 0; } -void dmentry_instance_lookup_inparam(struct dmctx *ctx) -{ - char *pch, *spch, *in_param; - in_param = dmstrdup(ctx->in_param); - int i = 0; - char pat[2] = {0}; - *pat = dm_delim; - for (pch = strtok_r(in_param, pat, &spch); pch != NULL; pch = strtok_r(NULL, pat, &spch)) { - if (pch[0]== '[') { - ctx->alias_register |= (1 << i); - i++; - } else if (isdigit(pch[0])) { - i++; - } - } - dmfree(in_param); - ctx->nbrof_instance = i; -} - int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2) { int fault = 0; bool setnotif = true, alarm = false, event = false; int err, err2; - - if (check_stats_folder(JSON_FOLDER_PATH)) + + if (check_stats_json_folder(JSON_FOLDER_PATH)) { + free_json_dynamic_arrays(tEntry181Obj); load_json_dynamic_arrays(ctx); + } + + if (check_stats_library_folder(LIBRARY_FOLDER_PATH)) { + free_library_dynamic_arrays(tEntry181Obj); + load_library_dynamic_arrays(ctx); + } if (!inparam) inparam = ""; ctx->in_param = inparam; @@ -254,7 +244,7 @@ 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 = dm_entry_operate(ctx); + fault = operate_on_node(ctx, ctx->in_param, ctx->in_value); break; #ifdef BBF_TR064 case CMD_UPNP_GET_SUPPORTED_PARAMETERS: @@ -1965,3 +1955,12 @@ invalid_arguments: fprintf(stdout, "Invalid arguments!\n");; } +int free_dynamic_arrays(void) +{ + DMOBJ *root = tEntry181Obj; + DMNODE node = {.current_object = ""}; + free_dm_browse_node_dynamic_object_tree(&node, root); + free_json_dynamic_arrays(tEntry181Obj); + free_library_dynamic_arrays(tEntry181Obj); + return 0; +} diff --git a/dmentry.h b/dmentry.h index 5c59cc11..1f94dc1a 100644 --- a/dmentry.h +++ b/dmentry.h @@ -8,13 +8,14 @@ * Author MOHAMED Kallel * Author Imen Bhiri * Author Feten Besbes + * Author Amin Ben Ramdhane * */ #ifndef __DMENTRY_H__ #define __DMENTRY_H__ -#include "dmbbf.h" +#include extern struct list_head head_package_change; extern unsigned char dmcli_timetrack; extern unsigned char dmcli_evaluatetest; @@ -52,7 +53,7 @@ int dm_ctx_clean_sub(struct dmctx *ctx); void dm_execute_cli_shell(int argc, char** argv, unsigned int dmtype, unsigned int amd_version, unsigned int instance_mode); void dm_execute_cli_command(char *file, unsigned int dmtype, unsigned int amd_version, unsigned int instance_mode); void wepkey_cli(int argc, char** argv); -void dmentry_instance_lookup_inparam(struct dmctx *ctx); +int free_dynamic_arrays(void); #ifdef BBF_TR064 #define DM_ENTRY_UPNP_CHECK_CHANGES(ALARM, EVENT, VERSION) \ diff --git a/dmentryjson.c b/dmentryjson.c index d1f8251f..20547e81 100644 --- a/dmentryjson.c +++ b/dmentryjson.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 iopsys Software Solutions AB + * Copyright (C) 2020 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 @@ -14,18 +14,17 @@ #include #include #include -#include "dmcommon.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmjson.h" +#include +#include +#include +#include #include "dmentryjson.h" #include "dmmemjson.h" -#include "device.h" LIST_HEAD(json_list); static char json_hash[64] = ""; -static int get_stats_folder(char *folder_path, int *file_count, unsigned long *size, unsigned long *date) +static int get_stats_json_folder(char *folder_path, int *file_count, unsigned long *size, unsigned long *date) { struct stat stats; struct dirent *entry; @@ -56,7 +55,7 @@ static int get_stats_folder(char *folder_path, int *file_count, unsigned long *s return 0; } -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) +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) { struct dm_json_parameter *dm_json_parameter; dm_json_parameter = dmcallocjson(1, sizeof(struct dm_json_parameter)); @@ -70,7 +69,7 @@ void add_json_data_to_list(struct list_head *dup_list, char *name, char *arg1, c if (arg6) dm_json_parameter->arg6 = dmstrdupjson(arg6); } -void delete_json_data_from_list(struct dm_json_parameter *dm_json_parameter) +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); @@ -83,7 +82,7 @@ void delete_json_data_from_list(struct dm_json_parameter *dm_json_parameter) if (dm_json_parameter) dmfreejson(dm_json_parameter); } -void free_json_data_from_list(struct list_head *dup_list) +static void free_json_data_from_list(struct list_head *dup_list) { struct dm_json_parameter *dm_json_parameter; while (dup_list->next != dup_list) { @@ -92,13 +91,17 @@ void free_json_data_from_list(struct list_head *dup_list) } } -int dm_browse_node_object_tree(DMNODE *parent_node, DMOBJ *entryobj) +static int dm_browse_node_json_object_tree(DMNODE *parent_node, DMOBJ *entryobj) { if (!entryobj) return 0; for (; entryobj->obj; entryobj++) { - entryobj->nextjsonobj = NULL; + if (entryobj->nextdynamicobj) { + struct dm_dynamic_obj *next_dyn_array = entryobj->nextdynamicobj + INDX_JSON_OBJ_MOUNT; + if (next_dyn_array->nextobj) FREE(next_dyn_array->nextobj); + } + DMNODE node = {0}; node.obj = entryobj; node.parent = parent_node; @@ -106,41 +109,38 @@ int dm_browse_node_object_tree(DMNODE *parent_node, DMOBJ *entryobj) node.matched = parent_node->matched; if (entryobj->nextobj) - dm_browse_node_object_tree(&node, entryobj->nextobj); + dm_browse_node_json_object_tree(&node, entryobj->nextobj); } return 0; } -static int free_node_object_tree(void) +static int free_node_object_tree_dynamic_array(DMOBJ *dm_entryobj) { - DMOBJ *root = tEntry181Obj; + DMOBJ *root = dm_entryobj; DMNODE node = {.current_object = ""}; - dm_browse_node_object_tree(&node, root); + dm_browse_node_json_object_tree(&node, root); return 0; } - -int free_json_dynamic_arrays(void) +int free_json_dynamic_arrays(DMOBJ *dm_entryobj) { free_json_data_from_list(&json_list); dmcleanmemjson(); - free_node_object_tree(); + free_node_object_tree_dynamic_array(dm_entryobj); return 0; } -int check_stats_folder(char *folder_path) +int check_stats_json_folder(char *json_folder_path) { int file_count = 0; unsigned long size = 0, date = 0; char str[64] = ""; - if (!get_stats_folder(folder_path, &file_count, &size, &date)) + if (!get_stats_json_folder(json_folder_path, &file_count, &size, &date)) return 0; sprintf(str, "count:%d,sizes:%lu,date:%lu", file_count, size, date); - if (strcmp(str, json_hash)) { - free_json_dynamic_arrays(); strcpy(json_hash, str); return 1; } @@ -236,53 +236,7 @@ int get_index_of_available_entry(DMOBJ *jentryobj) return idx; } -int plugin_json_obj_match(struct dmctx *dmctx, struct dmnode *node, char *entry_obj, char *full_obj) -{ - if (node->matched) - return 0; - - if (!dmctx->inparam_isparam && strstr(node->current_object, full_obj) == node->current_object) { - node->matched++; - dmctx->findparam = 1; - return 0; - } - - if (strstr(full_obj, node->current_object) == full_obj) - return 0; - - return FAULT_9005; -} - - -void dm_check_obj(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, char *obj, DMOBJ **root_entry, int *obj_found) -{ - int err = 0; - if (!entryobj) - return; - char *parent_obj = parent_node->current_object; - for (; 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; - dmasprintfjson(&(node.current_object), "%s%s%c", parent_obj, entryobj->obj, dm_delim); - if (strcmp(node.current_object, obj) == 0) { - *root_entry = entryobj; - *obj_found = 1; - return; - } - - err = plugin_json_obj_match(dmctx, &node, entryobj->obj, full_obj); - if (err) - continue; - - if (entryobj->nextobj) - dm_check_obj(dmctx, &node, entryobj->nextobj, full_obj, obj, root_entry, obj_found); - } -} - -int check_root_obj(struct dmctx *ctx, char *in_param_json, DMOBJ **root_entry) +static int check_json_root_obj(struct dmctx *ctx, char *in_param_json, DMOBJ **root_entry) { char *prefix_obj = NULL, *obj = NULL, *full_obj; int prefix_obj_found = 0, obj_found = 0; @@ -296,9 +250,9 @@ int check_root_obj(struct dmctx *ctx, char *in_param_json, DMOBJ **root_entry) else generate_prefixobj_and_obj_full_obj(full_obj, &prefix_obj, &obj); - dm_check_obj(ctx, &node, root, full_obj, prefix_obj, root_entry, &prefix_obj_found); + dm_check_dynamic_obj(ctx, &node, root, full_obj, prefix_obj, root_entry, &prefix_obj_found); if(prefix_obj_found && *root_entry) { - dm_check_obj(ctx, &node, root, full_obj, full_obj, root_entry, &obj_found); + dm_check_dynamic_obj(ctx, &node, root, full_obj, full_obj, root_entry, &obj_found); dmfreejson(full_obj); if(obj_found) return 1; @@ -718,7 +672,7 @@ static void count_obj_param_under_jsonobj(json_object *jsonobj, int *obj_number, static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, struct list_head *list) { - /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type(13)*/ + /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ char *full_obj = NULL, *prfix_obj = NULL, *obj_str = NULL; int obj_number = 0, param_number = 0, i = 0, j = 0; @@ -788,8 +742,8 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s //notification pobj[index].notification = NULL; - //nextjsonobj - pobj[index].nextjsonobj = NULL; + //nextdynamicobj + pobj[index].nextdynamicobj = NULL; //linker pobj[index].get_linker = NULL; @@ -813,28 +767,39 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s static void parse_next_obj(struct dmctx *ctx, json_object *jobj) { + int instance = 0, indx = 0; + json_object_object_foreach(jobj, key, json_obj) { DMOBJ *dm_entryobj = NULL; if (json_object_get_type(json_obj) == json_type_object && is_obj(key, json_obj)) { - int check_obj = check_root_obj(ctx, key, &dm_entryobj); + int check_obj = check_json_root_obj(ctx, key, &dm_entryobj); if (check_obj == 0) continue; if (check_obj == 1) { parse_next_obj(ctx, json_obj); } else { if (!dm_entryobj) continue; - if (dm_entryobj->nextjsonobj == NULL) { - dm_entryobj->nextjsonobj = dmcallocjson(2, sizeof(struct dm_obj_s)); - parse_obj(key, json_obj, dm_entryobj->nextjsonobj, 0, &json_list); + + if (dm_entryobj->nextdynamicobj == NULL) { + dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj)); + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].isstatic = 0; + } + + if (dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj == NULL) { + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj = calloc(2, sizeof(struct dm_obj_s *)); + } + + if (dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] == NULL) { + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] = dmcallocjson(2, sizeof(struct dm_obj_s)); + parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], 0, &json_list); } else { - int idx = get_index_of_available_entry(dm_entryobj->nextjsonobj); - dm_entryobj->nextjsonobj = dmreallocjson(dm_entryobj->nextjsonobj, (idx + 2) * sizeof(struct dm_obj_s)); - memset(dm_entryobj->nextjsonobj + (idx + 1), 0, sizeof(struct dm_obj_s)); - parse_obj(key, json_obj, dm_entryobj->nextjsonobj, idx, &json_list); + int idx = get_index_of_available_entry(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0]); + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] = dmreallocjson(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s)); + memset(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s)); + parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], idx, &json_list); } } } } - } int load_json_dynamic_arrays(struct dmctx *ctx) @@ -848,28 +813,39 @@ int load_json_dynamic_arrays(struct dmctx *ctx) DMOBJ *dm_entryobj = NULL; json_object *json; char buf[32] = ""; + int instance = 0, indx = 0; sprintf(buf, "%s/%s", JSON_FOLDER_PATH, ent->d_name); json = json_object_from_file(buf); if (!json) continue; json_object_object_foreach(json, key, jobj) { if (!key) break; - int check_obj = check_root_obj(ctx, key, &dm_entryobj); + int check_obj = check_json_root_obj(ctx, key, &dm_entryobj); if (check_obj == 0) continue; if (check_obj == 1) { parse_next_obj(ctx, jobj); continue; } if (!dm_entryobj) continue; - if (dm_entryobj->nextjsonobj == NULL) { - dm_entryobj->nextjsonobj = dmcallocjson(2, sizeof(struct dm_obj_s)); - parse_obj(key, jobj, dm_entryobj->nextjsonobj, 0, &json_list); - } else { - int idx = get_index_of_available_entry(dm_entryobj->nextjsonobj); - dm_entryobj->nextjsonobj = dmreallocjson(dm_entryobj->nextjsonobj, (idx + 2) * sizeof(struct dm_obj_s)); - memset(dm_entryobj->nextjsonobj + (idx + 1), 0, sizeof(struct dm_obj_s)); - parse_obj(key, jobj, dm_entryobj->nextjsonobj, idx, &json_list); + if (dm_entryobj->nextdynamicobj == NULL) { + dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj)); + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].isstatic = 0; + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].isstatic = 1; + } + + if (dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj == NULL) { + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj = calloc(2, sizeof(struct dm_obj_s *)); + } + + if (dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] == NULL) { + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] = dmcallocjson(2, sizeof(struct dm_obj_s)); + parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], 0, &json_list); + } else { + int idx = get_index_of_available_entry(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0]); + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] = dmreallocjson(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s)); + memset(dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s)); + parse_obj(key, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].nextobj[0], idx, &json_list); } } if (json) json_object_put(json); diff --git a/dmentryjson.h b/dmentryjson.h index 7caf48dd..732a1274 100644 --- a/dmentryjson.h +++ b/dmentryjson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 iopsys Software Solutions AB + * Copyright (C) 2020 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 @@ -14,8 +14,8 @@ #define JSON_FOLDER_PATH "/etc/bbfdm/json" -int check_stats_folder(char *folder_path); +int check_stats_json_folder(char *json_folder_path); int load_json_dynamic_arrays(struct dmctx *ctx); -int free_json_dynamic_arrays(void); +int free_json_dynamic_arrays(DMOBJ *dm_entryobj); #endif //__DMENTRYJSON_H__ diff --git a/dmentrylibrary.c b/dmentrylibrary.c new file mode 100644 index 00000000..20597051 --- /dev/null +++ b/dmentrylibrary.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2020 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 +#include +#include +#include +#include +#include +#include +#include "dmentrylibrary.h" +#include "dmoperate.h" + +static char library_hash[64] = ""; + +static int get_stats_library_folder(char *folder_path, int *file_count, unsigned long *size, unsigned long *date) +{ + struct stat stats; + struct dirent *entry; + DIR *dirp = NULL; + char buf[256] = {0}; + int filecount = 0; + unsigned long filesize = 0, filedate = 0; + + if (isfolderexist(folder_path)) { + dirp = opendir(folder_path); + while ((entry = readdir(dirp)) != NULL) { + if ((entry->d_type == DT_REG) && (strstr(entry->d_name, ".so"))) { + filecount++; + sprintf(buf, "%s/%s", folder_path, entry->d_name); + if (!stat(buf, &stats)) { + filesize = (filesize + stats.st_size) / 2; + filedate = (filedate + stats.st_mtime) / 2; + } + } + } + if (dirp) closedir(dirp); + + *file_count = filecount; + *size = filesize; + *date = filedate; + return 1; + } + return 0; +} + +int check_stats_library_folder(char *library_folder_path) +{ + int file_count = 0; + unsigned long size = 0, date = 0; + char str[64] = ""; + + if (!get_stats_library_folder(library_folder_path, &file_count, &size, &date)) + return 0; + + sprintf(str, "count:%d,sizes:%lu,date:%lu", file_count, size, date); + if (strcmp(str, library_hash)) { + strcpy(library_hash, str); + return 1; + } + return 0; +} + +static int dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryobj) +{ + if (!entryobj) + return 0; + + for (; entryobj->obj; entryobj++) { + if (entryobj->nextdynamicobj) { + struct dm_dynamic_obj *next_dyn_array = entryobj->nextdynamicobj + INDX_LIBRARY_OBJ_MOUNT; + if (next_dyn_array->nextobj) FREE(next_dyn_array->nextobj); + } + + DMNODE node = {0}; + node.obj = entryobj; + node.parent = parent_node; + node.instance_level = parent_node->instance_level; + node.matched = parent_node->matched; + + if (entryobj->nextobj) + dm_browse_node_dynamic_object_tree(&node, entryobj->nextobj); + } + return 0; +} + +int free_library_dynamic_arrays(DMOBJ *dm_entryobj) +{ + DMOBJ *root = dm_entryobj; + DMNODE node = {.current_object = ""}; + dm_browse_node_dynamic_object_tree(&node, root); + FREE(dynamic_operate); + return 0; +} + +static int check_library_root_obj(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); + if(obj_found && *root_entry) return 1; + return 0; +} + +static int get_index_of_available_dynamic_array(struct dm_obj_s **jentryobj) +{ + int i, idx = 0; + for (i = 0; jentryobj[i]; i++) { + idx++; + } + return idx; +} + +int load_library_dynamic_arrays(struct dmctx *ctx) +{ + struct dirent *ent; + DIR *dir = NULL; + + if (isfolderexist(LIBRARY_FOLDER_PATH)) { + sysfs_foreach_file(LIBRARY_FOLDER_PATH, dir, ent) { + if (strstr(ent->d_name, ".so")) { + void *handle; + LIB_MAP_OBJ *root_dynamic_obj = NULL; + LIB_MAP_OPERATE *root_dynamic_operate = NULL; + DMOBJ *dm_entryobj = NULL; + char buf[32] = ""; + int i; + + sprintf(buf, "%s/%s", LIBRARY_FOLDER_PATH, ent->d_name); + handle = dlopen(buf, RTLD_LAZY); + if (!handle) continue; + + //Dynamic Object + *(void **) (&root_dynamic_obj) = dlsym(handle, "tRootDynamicObj"); + if(root_dynamic_obj) { + for (i = 0; root_dynamic_obj[i].path; i++) { + if (!root_dynamic_obj[i].root_obj) continue; + int check_obj = check_library_root_obj(ctx, root_dynamic_obj[i].path, &dm_entryobj); + if ((check_obj == 0) || (!dm_entryobj)) continue; + + if (dm_entryobj->nextdynamicobj == NULL) { + dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj)); + dm_entryobj->nextdynamicobj[INDX_JSON_OBJ_MOUNT].isstatic = 0; + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].isstatic = 1; + } + + if (dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj == NULL) { + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj = calloc(2, sizeof(struct dm_obj_s *)); + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj[0] = root_dynamic_obj[i].root_obj; + } else { + int idx = get_index_of_available_dynamic_array(dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj); + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj = realloc(dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj, (idx + 2) * sizeof(struct dm_obj_s *)); + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj[idx] = root_dynamic_obj[i].root_obj; + dm_entryobj->nextdynamicobj[INDX_LIBRARY_OBJ_MOUNT].nextobj[idx+1] = NULL; + } + } + } + + //Dynamic Operate + *(void **) (&root_dynamic_operate) = dlsym(handle, "tRootDynamicOperate"); + if(root_dynamic_operate) { + for (i = 0; root_dynamic_operate[i].path; i++) { + if (root_dynamic_operate[i].operate) + add_dynamic_operate(root_dynamic_operate[i].path, root_dynamic_operate[i].operate); + } + } + + if (handle) dlclose(handle); + } + } + if (dir) closedir(dir); + } + return 0; +} diff --git a/dmentrylibrary.h b/dmentrylibrary.h new file mode 100644 index 00000000..0ae16322 --- /dev/null +++ b/dmentrylibrary.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2020 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 __DMENTRYLIBRARY_H__ +#define __DMENTRYLIBRARY_H__ + +#define LIBRARY_FOLDER_PATH "/usr/lib/bbfdm" + +int check_stats_library_folder(char *library_folder_path); +int load_library_dynamic_arrays(struct dmctx *ctx); +int free_library_dynamic_arrays(DMOBJ *dm_entryobj); + +#endif //__DMENTRYLIBRARY_H__ diff --git a/dmoperate.c b/dmoperate.c index 92bf787d..bbd6693e 100644 --- a/dmoperate.c +++ b/dmoperate.c @@ -13,22 +13,12 @@ * */ -#include -#include -#include -#include -#include "dmbbf.h" -#include "dmubus.h" -#include "dmuci.h" -#include "dmjson.h" -#include "dmentry.h" -#include "dmcommon.h" #include "dmoperate.h" -#include "dmdiagnostics.h" #define GLOB_EXPR "[=><]+" static uint8_t wifi_neighbor_count = 0; +struct op_cmd *dynamic_operate = NULL; bool match(const char *string, const char *pattern) { @@ -224,7 +214,7 @@ struct wifi_security_params reset_params[] = { static opr_ret_t ap_security_reset(struct dmctx *dmctx, char *path, char *input) { char *wpakey = NULL; - char node[MAXNAMLEN] = {'\0'}; + char node[255] = {'\0'}; int i, len = 0; char *ret = strrchr(path, '.'); @@ -233,20 +223,20 @@ static opr_ret_t ap_security_reset(struct dmctx *dmctx, char *path, char *input) len = ARRAY_SIZE(reset_params); for (i = 0; i < len; i++) { - strncpy(reset_params[i].node, node, MAXNAMLEN); + strncpy(reset_params[i].node, node, 255); strcat(reset_params[i].node, reset_params[i].param); } const char *mode_enabled = "WPA2-Personal"; // Default mode - WPA2-Personal - strncpy(reset_params[0].value, mode_enabled, MAXNAMLEN); + strncpy(reset_params[0].value, mode_enabled, 255); // Get Default wpakey db_get_value_string("hw", "board", "wpaKey", &wpakey); // PreSharedKey and KeyPassphrase are kept same - strncpy(reset_params[1].value, wpakey, MAXNAMLEN); - strncpy(reset_params[2].value, wpakey, MAXNAMLEN); + strncpy(reset_params[1].value, wpakey, 255); + strncpy(reset_params[2].value, wpakey, 255); for (i = 0; i < len; i++) { bbf_set_value(reset_params[i].node, reset_params[i].value); @@ -807,6 +797,31 @@ static opr_ret_t ip_diagnostics_nslookup(struct dmctx *dmctx, char *path, char * return 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) +{ + if (dynamic_operate == NULL) { + dynamic_operate = calloc(2, sizeof(struct op_cmd)); + dynamic_operate[0].name = path; + dynamic_operate[0].opt = operate; + } else { + int idx = get_index_of_available_dynamic_operate(dynamic_operate); + dynamic_operate = realloc(dynamic_operate, (idx + 2) * sizeof(struct op_cmd)); + memset(dynamic_operate + (idx + 1), 0, sizeof(struct op_cmd)); + dynamic_operate[idx].name = path; + dynamic_operate[idx].opt = operate; + } + return 0; +} + static struct op_cmd operate_helper[] = { {"Device.Reboot", reboot_device}, {"Device.FactoryReset", factory_reset}, @@ -829,15 +844,26 @@ static struct op_cmd operate_helper[] = { {"Device.DNS.Diagnostics.NSLookupDiagnostics", ip_diagnostics_nslookup} }; -int operate_on_node(struct dmctx *dmctx, char *path, char *input) +opr_ret_t operate_on_node(struct dmctx *dmctx, char *path, char *input) { - uint8_t len = 0; + uint8_t len = 0, i; + struct op_cmd *save_pointer = NULL; + if (dynamic_operate) save_pointer = dynamic_operate; len = ARRAY_SIZE(operate_helper); - for(uint8_t i=0; iname); dynamic_operate++) { + if (match(path, dynamic_operate->name)) { + opr_ret_t res = dynamic_operate->opt(dmctx, path, 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 index 28f542eb..7f33955b 100644 --- a/dmoperate.h +++ b/dmoperate.h @@ -16,7 +16,18 @@ #ifndef __DMOPERATE_H__ #define __DMOPERATE_H__ +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include "dmentry.h" +#include "dmdiagnostics.h" #define SYSTEM_UBUS_PATH "system" #define NETWORK_INTERFACE_UBUS_PATH "network.interface" @@ -25,22 +36,12 @@ #define ICWMP_SCRIPT "/usr/sbin/icwmp" #define VCF_FILE_TYPE "3" -enum operate_ret_status{ - UBUS_INVALID_ARGUMENTS, - SUCCESS, - FAIL, - CMD_NOT_FOUND, - __STATUS_MAX, -}; - -typedef enum operate_ret_status opr_ret_t; - -typedef opr_ret_t (*operation) (struct dmctx *dmctx, char *p, char *input); +extern struct op_cmd *dynamic_operate; struct wifi_security_params { - char node[MAXNAMLEN]; + char node[255]; char *param; - char value[MAXNAMLEN]; + char value[255]; }; struct file_server { @@ -216,6 +217,7 @@ struct op_cmd { operation opt; }; -int operate_on_node(struct dmctx *dmctx, char *path, char *input); +int add_dynamic_operate(char *path, operation operate); +opr_ret_t operate_on_node(struct dmctx *dmctx, char *path, char *input); #endif diff --git a/dmtree/tr104/voice_services.c b/dmtree/tr104/voice_services.c index 054d2dda..25bbd2cb 100644 --- a/dmtree/tr104/voice_services.c +++ b/dmtree/tr104/voice_services.c @@ -13,23 +13,23 @@ #include #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "voice_services.h" -#include "dmjson.h" /* *** Device.Services. *** */ DMOBJ tServicesObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"VoiceService", &DMREAD, NULL, NULL, NULL, browseVoiceServiceInst, NULL, NULL, NULL, tServicesVoiceServiceObj, tServicesVoiceServiceParams, NULL, BBFDM_BOTH}, {0} }; /* *** Device.Services.VoiceService.{i}. *** */ DMOBJ tServicesVoiceServiceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Capabilities", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesObj, tServicesVoiceServiceCapabilitiesParams, NULL, BBFDM_BOTH}, {"VoiceProfile", &DMWRITE, add_profile_object, delete_profile_object, NULL, browseProfileInst, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileObj, tServicesVoiceServiceVoiceProfileParams, NULL, BBFDM_BOTH}, {0} @@ -43,7 +43,7 @@ DMLEAF tServicesVoiceServiceParams[] = { /* *** Device.Services.VoiceService.{i}.Capabilities. *** */ DMOBJ tServicesVoiceServiceCapabilitiesObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"SIP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesSIPParams, NULL, BBFDM_BOTH}, {"Codecs", &DMREAD, NULL, NULL, NULL, browseCodecsInst, NULL, NULL, NULL, NULL, tServicesVoiceServiceCapabilitiesCodecsParams, NULL, BBFDM_BOTH}, {0} @@ -111,7 +111,7 @@ DMLEAF tServicesVoiceServiceCapabilitiesCodecsParams[] = { /* *** Device.Services.VoiceService.{i}.VoiceProfile.{i}. *** */ DMOBJ tServicesVoiceServiceVoiceProfileObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"SIP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileSIPParams, NULL, BBFDM_BOTH}, {"ServiceProviderInfo", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileServiceProviderInfoParams, NULL, BBFDM_BOTH}, {"FaxT38", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileFaxT38Params, NULL, BBFDM_BOTH}, @@ -172,7 +172,7 @@ DMLEAF tServicesVoiceServiceVoiceProfileFaxT38Params[] = { /* *** Device.Services.VoiceService.{i}.VoiceProfile.{i}.RTP. *** */ DMOBJ tServicesVoiceServiceVoiceProfileRTPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"RTCP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileRTPRTCPParams, NULL, BBFDM_BOTH}, {"SRTP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileRTPSRTPParams, NULL, BBFDM_BOTH}, {0} @@ -203,7 +203,7 @@ DMLEAF tServicesVoiceServiceVoiceProfileRTPSRTPParams[] = { /* *** Device.Services.VoiceService.{i}.VoiceProfile.{i}.Line.{i}. *** */ DMOBJ tServicesVoiceServiceVoiceProfileLineObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"VoiceProcessing", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileLineVoiceProcessingParams, NULL, BBFDM_BOTH}, {"CallingFeatures", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileLineCallingFeaturesParams, NULL, BBFDM_BOTH}, {"SIP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileLineSIPParams, NULL, BBFDM_BOTH}, @@ -250,7 +250,7 @@ DMLEAF tServicesVoiceServiceVoiceProfileLineSIPParams[] = { /* *** Device.Services.VoiceService.{i}.VoiceProfile.{i}.Line.{i}.Codec. *** */ DMOBJ tServicesVoiceServiceVoiceProfileLineCodecObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"List", &DMREAD, NULL, NULL, NULL, browseLineCodecListInst, NULL, NULL, NULL, NULL, tServicesVoiceServiceVoiceProfileLineCodecListParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr143/diagnostics.c b/dmtree/tr143/diagnostics.c index 28fee0ac..a938d3e1 100644 --- a/dmtree/tr143/diagnostics.c +++ b/dmtree/tr143/diagnostics.c @@ -12,17 +12,17 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "diagnostics.h" /* *** Device.IP.Diagnostics. *** */ DMOBJ tIPDiagnosticsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"IPPing", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPDiagnosticsIPPingParams, NULL, BBFDM_CWMP}, {"TraceRoute", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPDiagnosticsTraceRouteObj, tIPDiagnosticsTraceRouteParams, NULL, BBFDM_CWMP}, {"DownloadDiagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPDiagnosticsDownloadDiagnosticsObj, tIPDiagnosticsDownloadDiagnosticsParams, NULL, BBFDM_CWMP}, @@ -74,7 +74,7 @@ DMLEAF tIPDiagnosticsIPPingParams[] = { /* *** Device.IP.Diagnostics.TraceRoute. *** */ DMOBJ tIPDiagnosticsTraceRouteObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"RouteHops", &DMREAD, NULL, NULL, NULL, browseIPDiagnosticsTraceRouteRouteHopsInst, NULL, NULL, NULL, NULL, tIPDiagnosticsTraceRouteRouteHopsParams, NULL, BBFDM_CWMP}, {0} }; @@ -107,7 +107,7 @@ DMLEAF tIPDiagnosticsTraceRouteRouteHopsParams[] = { /* *** Device.IP.Diagnostics.DownloadDiagnostics. *** */ DMOBJ tIPDiagnosticsDownloadDiagnosticsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"PerConnectionResult", &DMREAD, NULL, NULL, NULL, browseIPDiagnosticsDownloadDiagnosticsPerConnectionResultInst, NULL, NULL, NULL, NULL, tIPDiagnosticsDownloadDiagnosticsPerConnectionResultParams, NULL, BBFDM_CWMP}, {0} }; @@ -156,7 +156,7 @@ DMLEAF tIPDiagnosticsDownloadDiagnosticsPerConnectionResultParams[] = { /* *** Device.IP.Diagnostics.UploadDiagnostics. *** */ DMOBJ tIPDiagnosticsUploadDiagnosticsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"PerConnectionResult", &DMREAD, NULL, NULL, NULL, browseIPDiagnosticsUploadDiagnosticsPerConnectionResultInst, NULL, NULL, NULL, NULL, tIPDiagnosticsUploadDiagnosticsPerConnectionResultParams, NULL, BBFDM_CWMP}, {0} }; diff --git a/dmtree/tr157/bulkdata.c b/dmtree/tr157/bulkdata.c index 7f570ebc..1d922002 100644 --- a/dmtree/tr157/bulkdata.c +++ b/dmtree/tr157/bulkdata.c @@ -8,17 +8,17 @@ * Author: Amin Ben Ramdhane */ -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmjson.h" -#include "dmentry.h" +#include +#include +#include +#include +#include +//#include "dmentry.h" #include "bulkdata.h" /* *** Device.BulkData. *** */ DMOBJ tBulkDataObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Profile", &DMWRITE, addObjBulkDataProfile, delObjBulkDataProfile, NULL, browseBulkDataProfileInst, NULL, NULL, NULL, tBulkDataProfileObj, tBulkDataProfileParams, NULL, BBFDM_BOTH}, {0} }; @@ -39,7 +39,7 @@ DMLEAF tBulkDataParams[] = { /* *** Device.BulkData.Profile.{i}. *** */ DMOBJ tBulkDataProfileObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Parameter", &DMWRITE, addObjBulkDataProfileParameter, delObjBulkDataProfileParameter, NULL, browseBulkDataProfileParameterInst, NULL, NULL, NULL, NULL, tBulkDataProfileParameterParams, NULL, BBFDM_BOTH}, {"CSVEncoding", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataProfileCSVEncodingParams, NULL, BBFDM_BOTH}, {"JSONEncoding", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataProfileJSONEncodingParams, NULL, BBFDM_BOTH}, @@ -98,7 +98,7 @@ DMLEAF tBulkDataProfileJSONEncodingParams[] = { /* *** Device.BulkData.Profile.{i}.HTTP. *** */ DMOBJ tBulkDataProfileHTTPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"RequestURIParameter", &DMWRITE, addObjBulkDataProfileHTTPRequestURIParameter, delObjBulkDataProfileHTTPRequestURIParameter, NULL, browseBulkDataProfileHTTPRequestURIParameterInst, NULL, NULL, NULL, NULL, tBulkDataProfileHTTPRequestURIParameterParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr157/softwaremodules.c b/dmtree/tr157/softwaremodules.c index 65bfa4a1..a2029eae 100644 --- a/dmtree/tr157/softwaremodules.c +++ b/dmtree/tr157/softwaremodules.c @@ -8,17 +8,17 @@ * Author: Amin Ben Ramdhane */ -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "softwaremodules.h" /* *** Device.SoftwareModules. *** */ DMOBJ tSoftwareModulesObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"ExecEnv", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecEnvInst, NULL, NULL, NULL, NULL, tSoftwareModulesExecEnvParams, get_exe_cenv_linker, BBFDM_BOTH}, {"DeploymentUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesDeploymentUnitInst, NULL, NULL, NULL, NULL, tSoftwareModulesDeploymentUnitParams, get_du_linker, BBFDM_BOTH}, {"ExecutionUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecutionUnitInst, NULL, NULL, NULL, tSoftwareModulesExecutionUnitObj, tSoftwareModulesExecutionUnitParams, NULL, BBFDM_BOTH}, @@ -80,7 +80,7 @@ DMLEAF tSoftwareModulesDeploymentUnitParams[] = { /* *** Device.SoftwareModules.ExecutionUnit.{i}. *** */ DMOBJ tSoftwareModulesExecutionUnitObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Extensions", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/atm.c b/dmtree/tr181/atm.c index 8f780fb2..a66a8b43 100644 --- a/dmtree/tr181/atm.c +++ b/dmtree/tr181/atm.c @@ -11,24 +11,24 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" -#include "atm.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "atm.h" /*** ATM. ***/ DMOBJ tATMObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Link", &DMWRITE, add_atm_link, delete_atm_link, NULL, browseAtmLinkInst, NULL, NULL, NULL, tATMLinkObj, tATMLinkParams, get_atm_linker, BBFDM_BOTH}, {0} }; /*** ATM.Link. ***/ DMOBJ tATMLinkObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tATMLinkStatsParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/bridging.c b/dmtree/tr181/bridging.c index 30ccb78e..3ef81dbe 100644 --- a/dmtree/tr181/bridging.c +++ b/dmtree/tr181/bridging.c @@ -12,19 +12,19 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" -#include "bridging.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "bridging.h" static char *wan_baseifname = NULL; /*** Bridging. ***/ DMOBJ tBridgingObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Bridge", &DMWRITE, add_bridge, delete_bridge, NULL, browseBridgeInst, NULL, NULL, NULL, tBridgingBridgeObj, tBridgingBridgeParams, NULL, BBFDM_BOTH}, {0} }; @@ -43,7 +43,7 @@ DMLEAF tBridgingParams[] = { /*** Bridging.Bridge.{i}. ***/ DMOBJ tBridgingBridgeObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Port", &DMWRITE, add_br_port, delete_br_port, NULL, browseBridgePortInst, NULL, NULL, NULL, tBridgingBridgePortObj, tBridgingBridgePortParams, get_linker_br_port, BBFDM_BOTH}, {"VLAN", &DMWRITE, add_br_vlan, delete_br_vlan, NULL, browseBridgeVlanInst, NULL, NULL, NULL, NULL, tBridgingBridgeVLANParams, get_linker_br_vlan, BBFDM_BOTH}, {"VLANPort", &DMREAD, NULL, NULL, NULL, browseBridgeVlanPortInst, NULL, NULL, NULL, NULL, tBridgingBridgeVLANPortParams, NULL, BBFDM_BOTH}, @@ -65,7 +65,7 @@ DMLEAF tBridgingBridgeParams[] = { /*** Bridging.Bridge.{i}.Port.{i}. ***/ DMOBJ tBridgingBridgePortObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBridgingBridgePortStatsParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/datamodelversion.h b/dmtree/tr181/datamodelversion.h index 04f2ceb5..063efe1e 100644 --- a/dmtree/tr181/datamodelversion.h +++ b/dmtree/tr181/datamodelversion.h @@ -11,8 +11,8 @@ #ifndef __DATAMODELVERSION_H #define __DATAMODELVERSION_H -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); diff --git a/dmtree/tr181/device.c b/dmtree/tr181/device.c index 35fd33c0..b1c62ff8 100644 --- a/dmtree/tr181/device.c +++ b/dmtree/tr181/device.c @@ -10,8 +10,8 @@ * Author: Amin Ben Ramdhane */ -#include "dmuci.h" -#include "dmbbf.h" +#include +#include #include "device.h" #include "deviceinfo.h" #include "managementserver.h" @@ -61,7 +61,7 @@ /* *** BBFDM *** */ DMOBJ tEntry181Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Device", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, tRoot_181_Obj, tRoot_181_Params, NULL, BBFDM_BOTH}, {0} }; @@ -74,7 +74,7 @@ DMLEAF tRoot_181_Params[] = { }; DMOBJ tRoot_181_Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"DeviceInfo", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, tDeviceInfoObj, tDeviceInfoParams, NULL, BBFDM_BOTH}, {"ManagementServer", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, NULL, tManagementServerParams, NULL, BBFDM_BOTH}, {"Time", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, NULL, tTimeParams, NULL, BBFDM_BOTH}, diff --git a/dmtree/tr181/deviceinfo.c b/dmtree/tr181/deviceinfo.c index 8284770c..3da3b373 100644 --- a/dmtree/tr181/deviceinfo.c +++ b/dmtree/tr181/deviceinfo.c @@ -16,16 +16,16 @@ #include #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmcommon.h" +#include +#include +#include #include "deviceinfo.h" -#include "dmjson.h" -#include "dmubus.h" +#include +#include /* *** Device.DeviceInfo. *** */ DMOBJ tDeviceInfoObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {CUSTOM_PREFIX"CATV", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tCatTvParams, NULL, BBFDM_BOTH}, {"VendorConfigFile", &DMREAD, NULL, NULL, NULL, browseVcfInst, NULL, NULL, NULL, NULL, tDeviceInfoVendorConfigFileParams, NULL, BBFDM_BOTH}, {"VendorLogFile", &DMREAD, NULL, NULL, NULL, browseVlfInst, NULL, NULL, NULL, NULL, tDeviceInfoVendorLogFileParams, NULL, BBFDM_BOTH}, @@ -75,7 +75,7 @@ DMLEAF tDeviceInfoMemoryStatusParams[] = { /* *** Device.DeviceInfo.ProcessStatus. *** */ DMOBJ tDeviceInfoProcessStatusObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Process", &DMREAD, NULL, NULL, NULL, browsePocessEntriesInst, NULL, NULL, NULL, NULL, tDeviceInfoProcessStatusProcessParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/deviceinfo.h b/dmtree/tr181/deviceinfo.h index 91bc3cbe..93d9c8b7 100644 --- a/dmtree/tr181/deviceinfo.h +++ b/dmtree/tr181/deviceinfo.h @@ -12,7 +12,7 @@ #ifndef __DEVICE_INFO_H #define __DEVICE_INFO_H -#include "dmbbf.h" +#include #define UPTIME "/proc/uptime" #define DEFAULT_CONFIG_DIR "/etc/config/" diff --git a/dmtree/tr181/dhcpv4.c b/dmtree/tr181/dhcpv4.c index e977074e..ed82754c 100644 --- a/dmtree/tr181/dhcpv4.c +++ b/dmtree/tr181/dhcpv4.c @@ -14,18 +14,19 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "dhcpv4.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "dhcpv4.h" + #define DELIMITOR "," /*** DHCPv4. ***/ DMOBJ tDHCPv4Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Client", &DMWRITE, addObjDHCPv4Client, delObjDHCPv4Client, NULL, browseDHCPv4ClientInst, NULL, NULL, NULL, tDHCPv4ClientObj, tDHCPv4ClientParams, NULL, BBFDM_BOTH}, {"Server", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv4ServerObj, tDHCPv4ServerParams, NULL, BBFDM_BOTH}, {"Relay", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv4RelayObj, tDHCPv4RelayParams, NULL, BBFDM_BOTH}, @@ -40,7 +41,7 @@ DMLEAF tDHCPv4Params[] = { /* *** Device.DHCPv4.Client.{i}. *** */ DMOBJ tDHCPv4ClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"SentOption", &DMWRITE, addObjDHCPv4ClientSentOption, delObjDHCPv4ClientSentOption, NULL, browseDHCPv4ClientSentOptionInst, NULL, NULL, NULL, NULL, tDHCPv4ClientSentOptionParams, NULL, BBFDM_BOTH}, {"ReqOption", &DMWRITE, addObjDHCPv4ClientReqOption, delObjDHCPv4ClientReqOption, NULL, browseDHCPv4ClientReqOptionInst, NULL, NULL, NULL, NULL, tDHCPv4ClientReqOptionParams, NULL, BBFDM_BOTH}, {0} @@ -97,14 +98,14 @@ DMLEAF tDHCPv4ServerParams[] = { /*** DHCPv4.Server. ***/ DMOBJ tDHCPv4ServerObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Pool", &DMWRITE, add_dhcp_server, delete_dhcp_server, NULL, browseDhcpInst, NULL, NULL, NULL, tDHCPv4ServerPoolObj, tDHCPv4ServerPoolParams, NULL, BBFDM_BOTH}, {0} }; /*** DHCPv4.Server.Pool.{i}. ***/ DMOBJ tDHCPv4ServerPoolObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"StaticAddress", &DMWRITE, add_dhcp_staticaddress, delete_dhcp_staticaddress, NULL, browseDhcpStaticInst, NULL, NULL, NULL, NULL, tDHCPv4ServerPoolAddressParams, NULL, BBFDM_BOTH}, {"Option", &DMWRITE, addObjDHCPv4ServerPoolOption, delObjDHCPv4ServerPoolOption, NULL, browseDHCPv4ServerPoolOptionInst, NULL, NULL, NULL, NULL, tDHCPv4ServerPoolOptionParams, NULL, BBFDM_BOTH}, {"Client", &DMREAD, NULL, NULL, NULL, browseDhcpClientInst, NULL, NULL, NULL, tDHCPv4ServerPoolClientObj, tDHCPv4ServerPoolClientParams, get_dhcp_client_linker}, @@ -113,7 +114,7 @@ DMOBJ tDHCPv4ServerPoolObj[] = { /*** DHCPv4.Server.Pool.{i}.Client.{i}. ***/ DMOBJ tDHCPv4ServerPoolClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"IPv4Address", &DMREAD, NULL, NULL, NULL, browseDhcpClientIPv4Inst, NULL, NULL, NULL, NULL, tDHCPv4ServerPoolClientIPv4AddressParams, NULL, BBFDM_BOTH}, {"Option", &DMREAD, NULL, NULL, NULL, browseDHCPv4ServerPoolClientOptionInst, NULL, NULL, NULL, NULL, tDHCPv4ServerPoolClientOptionParams, NULL, BBFDM_BOTH}, {0} @@ -186,7 +187,7 @@ DMLEAF tDHCPv4ServerPoolClientOptionParams[] = { /* *** Device.DHCPv4.Relay. *** */ DMOBJ tDHCPv4RelayObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Forwarding", &DMWRITE, addObjDHCPv4RelayForwarding, delObjDHCPv4RelayForwarding, NULL, browseDHCPv4RelayForwardingInst, NULL, NULL, NULL, NULL, tDHCPv4RelayForwardingParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/dhcpv6.c b/dmtree/tr181/dhcpv6.c index 9a26c64b..f5fb38a2 100644 --- a/dmtree/tr181/dhcpv6.c +++ b/dmtree/tr181/dhcpv6.c @@ -11,18 +11,19 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "dhcpv4.h" #include "dhcpv6.h" -#include "dmjson.h" + /* *** Device.DHCPv6. *** */ DMOBJ tDHCPv6Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Client", &DMWRITE, addObjDHCPv6Client, delObjDHCPv6Client, NULL, browseDHCPv6ClientInst, NULL, NULL, NULL, tDHCPv6ClientObj, tDHCPv6ClientParams, NULL, BBFDM_BOTH}, {"Server", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv6ServerObj, tDHCPv6ServerParams, NULL, BBFDM_BOTH}, {0} @@ -36,7 +37,7 @@ DMLEAF tDHCPv6Params[] = { /* *** Device.DHCPv6.Client.{i}. *** */ DMOBJ tDHCPv6ClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Server", &DMREAD, NULL, NULL, NULL, browseDHCPv6ClientServerInst, NULL, NULL, NULL, NULL, tDHCPv6ClientServerParams, NULL, BBFDM_BOTH}, {"SentOption", &DMWRITE, addObjDHCPv6ClientSentOption, delObjDHCPv6ClientSentOption, NULL, browseDHCPv6ClientSentOptionInst, NULL, NULL, NULL, NULL, tDHCPv6ClientSentOptionParams, NULL, BBFDM_BOTH}, {"ReceivedOption", &DMREAD, NULL, NULL, NULL, browseDHCPv6ClientReceivedOptionInst, NULL, NULL, NULL, NULL, tDHCPv6ClientReceivedOptionParams, NULL, BBFDM_BOTH}, @@ -94,7 +95,7 @@ DMLEAF tDHCPv6ClientReceivedOptionParams[] = { /* *** Device.DHCPv6.Server. *** */ DMOBJ tDHCPv6ServerObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Pool", &DMWRITE, addObjDHCPv6ServerPool, delObjDHCPv6ServerPool, NULL, browseDHCPv6ServerPoolInst, NULL, NULL, NULL, tDHCPv6ServerPoolObj, tDHCPv6ServerPoolParams, NULL, BBFDM_BOTH}, {0} }; @@ -108,7 +109,7 @@ DMLEAF tDHCPv6ServerParams[] = { /* *** Device.DHCPv6.Server.Pool.{i}. *** */ DMOBJ tDHCPv6ServerPoolObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Client", &DMREAD, NULL, NULL, NULL, browseDHCPv6ServerPoolClientInst, NULL, NULL, NULL, tDHCPv6ServerPoolClientObj, tDHCPv6ServerPoolClientParams, NULL, BBFDM_BOTH}, {"Option", &DMWRITE, addObjDHCPv6ServerPoolOption, delObjDHCPv6ServerPoolOption, NULL, browseDHCPv6ServerPoolOptionInst, NULL, NULL, NULL, NULL, tDHCPv6ServerPoolOptionParams, NULL, BBFDM_BOTH}, {0} @@ -144,7 +145,7 @@ DMLEAF tDHCPv6ServerPoolParams[] = { /* *** Device.DHCPv6.Server.Pool.{i}.Client.{i}. *** */ DMOBJ tDHCPv6ServerPoolClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"IPv6Address", &DMREAD, NULL, NULL, NULL, browseDHCPv6ServerPoolClientIPv6AddressInst, NULL, NULL, NULL, NULL, tDHCPv6ServerPoolClientIPv6AddressParams, NULL, BBFDM_BOTH}, {"IPv6Prefix", &DMREAD, NULL, NULL, NULL, browseDHCPv6ServerPoolClientIPv6PrefixInst, NULL, NULL, NULL, NULL, tDHCPv6ServerPoolClientIPv6PrefixParams, NULL, BBFDM_BOTH}, {"Option", &DMREAD, NULL, NULL, NULL, browseDHCPv6ServerPoolClientOptionInst, NULL, NULL, NULL, NULL, tDHCPv6ServerPoolClientOptionParams, NULL, BBFDM_BOTH}, diff --git a/dmtree/tr181/dns.c b/dmtree/tr181/dns.c index d631695f..e4070ef2 100644 --- a/dmtree/tr181/dns.c +++ b/dmtree/tr181/dns.c @@ -8,17 +8,17 @@ * Author: Amin Ben Ramdhane */ -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "dns.h" /* *** Device.DNS. *** */ DMOBJ tDNSObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Client", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDNSClientObj, tDNSClientParams, NULL, BBFDM_BOTH}, {"Relay", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDNSRelayObj, tDNSRelayParams, NULL, BBFDM_BOTH}, {"Diagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDNSDiagnosticsObj, NULL, NULL, BBFDM_BOTH}, @@ -33,7 +33,7 @@ DMLEAF tDNSParams[] = { /* *** Device.DNS.Client. *** */ DMOBJ tDNSClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Server", &DMWRITE, add_client_server, delete_client_server, NULL, browseServerInst, NULL, NULL, NULL, NULL, tDNSClientServerParams, NULL, BBFDM_BOTH}, {0} }; @@ -60,7 +60,7 @@ DMLEAF tDNSClientServerParams[] = { /* *** Device.DNS.Relay. *** */ DMOBJ tDNSRelayObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Forwarding", &DMWRITE, add_relay_forwarding, delete_relay_forwarding, NULL, browseRelayForwardingInst, NULL, NULL, NULL, NULL, tDNSRelayForwardingParams, NULL, BBFDM_BOTH}, {0} }; @@ -87,14 +87,14 @@ DMLEAF tDNSRelayForwardingParams[] = { /* *** Device.DNS.Diagnostics. *** */ DMOBJ tDNSDiagnosticsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"NSLookupDiagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDNSDiagnosticsNSLookupDiagnosticsObj, tDNSDiagnosticsNSLookupDiagnosticsParams, NULL, BBFDM_BOTH}, {0} }; /* *** Device.DNS.Diagnostics.NSLookupDiagnostics. *** */ DMOBJ tDNSDiagnosticsNSLookupDiagnosticsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Result", &DMREAD, NULL, NULL, NULL, browseResultInst, NULL, NULL, NULL, NULL, tDNSDiagnosticsNSLookupDiagnosticsResultParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/dsl.c b/dmtree/tr181/dsl.c index aa6a60d3..f29e2231 100644 --- a/dmtree/tr181/dsl.c +++ b/dmtree/tr181/dsl.c @@ -11,11 +11,11 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "dsl.h" @@ -23,7 +23,7 @@ /* *** Device.DSL. *** */ DMOBJ tDSLObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Line", &DMREAD, NULL, NULL, NULL, browseDSLLineInst, NULL, NULL, NULL, tDSLLineObj, tDSLLineParams, get_dsl_line_linker, BBFDM_BOTH}, {"Channel", &DMREAD, NULL, NULL, NULL, browseDSLChannelInst, NULL, NULL, NULL, tDSLChannelObj, tDSLChannelParams, get_dsl_channel_linker, BBFDM_BOTH}, {0} @@ -38,7 +38,7 @@ DMLEAF tDSLParams[] = { /* *** Device.DSL.Line.{i}. *** */ DMOBJ tDSLLineObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLLineStatsObj, tDSLLineStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -98,7 +98,7 @@ DMLEAF tDSLLineParams[] = { /* *** Device.DSL.Line.{i}.Stats. *** */ DMOBJ tDSLLineStatsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Total", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLLineStatsTotalParams, NULL, BBFDM_BOTH}, {"Showtime", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLLineStatsShowtimeParams, NULL, BBFDM_BOTH}, {"LastShowtime", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLLineStatsLastShowtimeParams, NULL, BBFDM_BOTH}, @@ -159,7 +159,7 @@ DMLEAF tDSLLineStatsQuarterHourParams[] = { /* *** Device.DSL.Channel.{i}. *** */ DMOBJ tDSLChannelObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLChannelStatsObj, tDSLChannelStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -191,7 +191,7 @@ DMLEAF tDSLChannelParams[] = { /* *** Device.DSL.Channel.{i}.Stats. *** */ DMOBJ tDSLChannelStatsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Total", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLChannelStatsTotalParams, NULL, BBFDM_BOTH}, {"Showtime", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLChannelStatsShowtimeParams, NULL, BBFDM_BOTH}, {"LastShowtime", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLChannelStatsLastShowtimeParams, NULL, BBFDM_BOTH}, diff --git a/dmtree/tr181/dynamicdns.c b/dmtree/tr181/dynamicdns.c index e9ff9387..6f722e97 100644 --- a/dmtree/tr181/dynamicdns.c +++ b/dmtree/tr181/dynamicdns.c @@ -9,17 +9,17 @@ */ #include -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "dynamicdns.h" /* *** Device.DynamicDNS. *** */ DMOBJ tDynamicDNSObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Client", &DMWRITE, addObjDynamicDNSClient, delObjDynamicDNSClient, NULL, browseDynamicDNSClientInst, NULL, NULL, NULL, tDynamicDNSClientObj, tDynamicDNSClientParams, NULL, BBFDM_BOTH}, {"Server", &DMWRITE, addObjDynamicDNSServer, delObjDynamicDNSServer, NULL, browseDynamicDNSServerInst, NULL, NULL, NULL, NULL, tDynamicDNSServerParams, get_linker_dynamicdns_server, BBFDM_BOTH}, {0} @@ -35,7 +35,7 @@ DMLEAF tDynamicDNSParams[] = { /* *** Device.DynamicDNS.Client.{i}. *** */ DMOBJ tDynamicDNSClientObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Hostname", &DMWRITE, NULL, NULL, NULL, browseDynamicDNSClientHostnameInst, NULL, NULL, NULL, NULL, tDynamicDNSClientHostnameParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index c518a164..87182c27 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -13,19 +13,19 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "ethernet.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "ethernet.h" char *wan_ifname = NULL; /* *** Device.Ethernet. *** */ DMOBJ tEthernetObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Interface", &DMREAD, NULL, NULL, NULL, browseEthernetInterfaceInst, NULL, NULL, NULL, tEthernetInterfaceObj, tEthernetInterfaceParams, get_linker_interface, BBFDM_BOTH}, {"Link", &DMWRITE, addObjEthernetLink, delObjEthernetLink, NULL, browseEthernetLinkInst, NULL, NULL, NULL, tEthernetLinkObj, tEthernetLinkParams, get_linker_link, BBFDM_BOTH}, {"VLANTermination", &DMWRITE, addObjEthernetVLANTermination, delObjEthernetVLANTermination, NULL, browseEthernetVLANTerminationInst, NULL, NULL, NULL, tEthernetVLANTerminationObj, tEthernetVLANTerminationParams, get_linker_vlan_term, BBFDM_BOTH}, @@ -42,7 +42,7 @@ DMLEAF tEthernetParams[] = { /* *** Device.Ethernet.Interface.{i}. *** */ DMOBJ tEthernetInterfaceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tEthernetInterfaceStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -87,7 +87,7 @@ DMLEAF tEthernetInterfaceStatsParams[] = { /* *** Device.Ethernet.Link.{i}. *** */ DMOBJ tEthernetLinkObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tEthernetLinkStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -127,7 +127,7 @@ DMLEAF tEthernetLinkStatsParams[] = { /* *** Device.Ethernet.VLANTermination.{i}. *** */ DMOBJ tEthernetVLANTerminationObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tEthernetVLANTerminationStatsParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/firewall.c b/dmtree/tr181/firewall.c index efd52172..14508865 100644 --- a/dmtree/tr181/firewall.c +++ b/dmtree/tr181/firewall.c @@ -8,14 +8,14 @@ * Author: Omar Kallel */ -#include "dmbbf.h" -#include "firewall.h" -#include "dmcommon.h" +#include +#include #include "dmentry.h" +#include "firewall.h" /* *** Device.Firewall. *** */ DMOBJ tFirewallObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Level", &DMREAD, NULL, NULL, NULL, browseLevelInst, NULL, NULL, NULL, NULL, tFirewallLevelParams, NULL, BBFDM_BOTH}, {"Chain", &DMREAD, NULL, NULL, NULL, browseChainInst, NULL, NULL, NULL, tFirewallChainObj, tFirewallChainParams, NULL, BBFDM_BOTH}, {0} @@ -44,7 +44,7 @@ DMLEAF tFirewallLevelParams[] = { /* *** Device.Firewall.Chain.{i}. *** */ DMOBJ tFirewallChainObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Rule", &DMWRITE, add_firewall_rule, delete_firewall_rule, NULL, browseRuleInst, NULL, NULL, NULL, tFirewallChainRuleObj, tFirewallChainRuleParams, NULL, BBFDM_BOTH}, {0} }; @@ -60,7 +60,7 @@ DMLEAF tFirewallChainParams[] = { /* *** Device.Firewall.Chain.{i}.Rule.{i}. *** */ DMOBJ tFirewallChainRuleObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {CUSTOM_PREFIX"TimeSpan", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tTimeSpanParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/gre.c b/dmtree/tr181/gre.c index 993cb0e4..c88c088e 100644 --- a/dmtree/tr181/gre.c +++ b/dmtree/tr181/gre.c @@ -10,12 +10,11 @@ #include #include -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmjson.h" -#include "dmentry.h" +#include +#include +#include +#include +#include #include "gre.h" /* *** Device.GRE. *** */ diff --git a/dmtree/tr181/hosts.c b/dmtree/tr181/hosts.c index 381e9ebb..aa7fdf9e 100644 --- a/dmtree/tr181/hosts.c +++ b/dmtree/tr181/hosts.c @@ -12,17 +12,17 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "hosts.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "hosts.h" /* *** Device.Hosts. *** */ DMOBJ tHostsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Host", &DMREAD, NULL, NULL, NULL, browsehostInst, NULL, NULL, NULL, NULL, tHostsHostParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/interfacestack.c b/dmtree/tr181/interfacestack.c index 83bd71df..376eea41 100644 --- a/dmtree/tr181/interfacestack.c +++ b/dmtree/tr181/interfacestack.c @@ -8,10 +8,10 @@ * Author: Amin Ben Ramdhane */ -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmubus.h" -#include "dmjson.h" +#include +#include +#include +#include #include "dmentry.h" #include "interfacestack.h" diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index 2a01a350..66fd18b1 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -13,12 +13,12 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "ip.h" -#include "dmjson.h" #include "dmentry.h" #ifdef BBF_TR143 #include "diagnostics.h" @@ -29,7 +29,7 @@ struct dm_forced_inform_s IPv6INFRM = {0, get_ipv6_finform}; /* *** Device.IP. *** */ DMOBJ tIPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Interface", &DMWRITE, add_ip_interface, delete_ip_interface, NULL, browseIPIfaceInst, NULL, NULL, NULL, tIPInterfaceObj, tIPInterfaceParams, get_linker_ip_interface, BBFDM_BOTH}, #ifdef BBF_TR143 {"Diagnostics", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPDiagnosticsObj, tIPDiagnosticsParams, NULL, BBFDM_BOTH}, @@ -52,7 +52,7 @@ DMLEAF tIPParams[] = { /* *** Device.IP.Interface. *** */ DMOBJ tIPInterfaceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"IPv4Address", &DMWRITE, add_ipv4, delete_ipv4, NULL, browseIfaceIPv4Inst, NULL, NULL, NULL, NULL, tIPInterfaceIPv4AddressParams, NULL, BBFDM_BOTH}, {"IPv6Address", &DMWRITE, add_ipv6, delete_ipv6, NULL, browseIfaceIPv6Inst, NULL, NULL, NULL, NULL, tIPInterfaceIPv6AddressParams, NULL, BBFDM_BOTH}, {"IPv6Prefix", &DMWRITE, add_ipv6_prefix, delete_ipv6_prefix, NULL, browseIfaceIPv6PrefixInst, NULL, NULL, NULL, NULL, tIPInterfaceIPv6PrefixParams, get_linker_ipv6_prefix, BBFDM_BOTH}, diff --git a/dmtree/tr181/managementserver.c b/dmtree/tr181/managementserver.c index 40f12dc6..f0aed4b9 100644 --- a/dmtree/tr181/managementserver.c +++ b/dmtree/tr181/managementserver.c @@ -14,13 +14,13 @@ #include #include #include -#include "dmmem.h" -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include +#include #include "managementserver.h" -#include "dmjson.h" #define DEFAULT_ACSURL "http://192.168.1.1:8080/openacs/acs" diff --git a/dmtree/tr181/managementserver.h b/dmtree/tr181/managementserver.h index 382d6c30..164b4158 100644 --- a/dmtree/tr181/managementserver.h +++ b/dmtree/tr181/managementserver.h @@ -11,7 +11,7 @@ #ifndef __MANAGEMENT_SERVER_H #define __MANAGEMENT_SERVER_H -#include "dmbbf.h" +#include extern DMLEAF tManagementServerParams[]; int get_management_server_url(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); diff --git a/dmtree/tr181/nat.c b/dmtree/tr181/nat.c index 9c676926..803f676f 100644 --- a/dmtree/tr181/nat.c +++ b/dmtree/tr181/nat.c @@ -13,16 +13,16 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "dmentry.h" #include "nat.h" /* *** Device.NAT. *** */ DMOBJ tNATObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"InterfaceSetting", &DMWRITE, add_NAT_InterfaceSetting, delete_NAT_InterfaceSetting, NULL, browseInterfaceSettingInst, NULL, NULL, NULL, NULL, tNATInterfaceSettingParams, NULL, BBFDM_BOTH}, {"PortMapping", &DMWRITE, add_NAT_PortMapping, delete_NAT_PortMapping, NULL, browsePortMappingInst, NULL, NULL, NULL, NULL, tNATPortMappingParams, NULL, BBFDM_BOTH}, {0} diff --git a/dmtree/tr181/ppp.c b/dmtree/tr181/ppp.c index fa2fe8b5..2a8f3bfd 100644 --- a/dmtree/tr181/ppp.c +++ b/dmtree/tr181/ppp.c @@ -12,17 +12,17 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmjson.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "ppp.h" /* *** Device.PPP. *** */ DMOBJ tPPPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Interface", &DMWRITE, add_ppp_interface, delete_ppp_interface, NULL, browseInterfaceInst, NULL, NULL, NULL, tPPPInterfaceObj, tPPPInterfaceParams, get_linker_ppp_interface, BBFDM_BOTH}, {0} }; @@ -35,7 +35,7 @@ DMLEAF tPPPParams[] = { /* *** Device.PPP.Interface.{i}. *** */ DMOBJ tPPPInterfaceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"PPPoE", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tPPPInterfacePPPoEParams, NULL, BBFDM_BOTH}, {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tPPPInterfaceStatsParams, NULL, BBFDM_BOTH}, {0} diff --git a/dmtree/tr181/ptm.c b/dmtree/tr181/ptm.c index d0c9c81c..76c24d2f 100644 --- a/dmtree/tr181/ptm.c +++ b/dmtree/tr181/ptm.c @@ -11,24 +11,24 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" -#include "ptm.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" +#include "ptm.h" /* *** Device.PTM. *** */ DMOBJ tPTMObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Link", &DMWRITE, add_ptm_link, delete_ptm_link, NULL, browsePtmLinkInst, NULL, NULL, NULL, tPTMLinkObj, tPTMLinkParams, get_ptm_linker, BBFDM_BOTH}, {0} }; /* *** Device.PTM.Link.{i}. *** */ DMOBJ tPTMLinkObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tPTMLinkStatsParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/qos.c b/dmtree/tr181/qos.c index c1feaab2..b8ab2449 100644 --- a/dmtree/tr181/qos.c +++ b/dmtree/tr181/qos.c @@ -8,16 +8,16 @@ * Author: Omar Kallel */ -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmentry.h" -#include "dmuci.h" -#include "qos.h" #include +#include +#include +#include +#include "dmentry.h" +#include "qos.h" /* *** Device.QoS. *** */ DMOBJ tQoSObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Classification", &DMWRITE, addObjQoSClassification, delObjQoSClassification, NULL, browseQoSClassificationInst, NULL, NULL, NULL, NULL, tQoSClassificationParams, NULL, BBFDM_BOTH}, {"App", &DMWRITE, addObjQoSApp, delObjQoSApp, NULL, browseQoSAppInst, NULL, NULL, NULL, NULL, tQoSAppParams, NULL, BBFDM_BOTH}, {"Flow", &DMWRITE, addObjQoSFlow, delObjQoSFlow, NULL, browseQoSFlowInst, NULL, NULL, NULL, NULL, tQoSFlowParams, NULL, BBFDM_BOTH}, diff --git a/dmtree/tr181/routing.c b/dmtree/tr181/routing.c index bb12245d..86beb187 100644 --- a/dmtree/tr181/routing.c +++ b/dmtree/tr181/routing.c @@ -14,12 +14,12 @@ #include #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "routing.h" -#include "dmjson.h" #include "dmentry.h" enum enum_route_type { @@ -30,7 +30,7 @@ enum enum_route_type { /* *** Device.Routing. *** */ DMOBJ tRoutingObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Router", &DMREAD, NULL, NULL, NULL, browseRouterInst, NULL, NULL, NULL, tRoutingRouterObj, tRoutingRouterParams, NULL, BBFDM_BOTH}, {"RouteInformation", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tRoutingRouteInformationObj, tRoutingRouteInformationParams, NULL, BBFDM_BOTH}, {0} @@ -44,7 +44,7 @@ DMLEAF tRoutingParams[] = { /* *** Device.Routing.Router.{i}. *** */ DMOBJ tRoutingRouterObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"IPv4Forwarding", &DMWRITE, add_ipv4forwarding, delete_ipv4forwarding, NULL, browseIPv4ForwardingInst, NULL, NULL, NULL, NULL, tRoutingRouterIPv4ForwardingParams, NULL, BBFDM_BOTH}, {"IPv6Forwarding", &DMWRITE, add_ipv6Forwarding, delete_ipv6Forwarding, NULL, browseIPv6ForwardingInst, NULL, NULL, NULL, NULL, tRoutingRouterIPv6ForwardingParams, NULL, BBFDM_BOTH}, {0} @@ -95,7 +95,7 @@ DMLEAF tRoutingRouterIPv6ForwardingParams[] = { /* *** Device.Routing.RouteInformation. *** */ DMOBJ tRoutingRouteInformationObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"InterfaceSetting", &DMREAD, NULL, NULL, NULL, browseRoutingRouteInformationInterfaceSettingInst, NULL, NULL, NULL, NULL, tRoutingRouteInformationInterfaceSettingParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/times.c b/dmtree/tr181/times.c index f876f5f2..f575db9b 100644 --- a/dmtree/tr181/times.c +++ b/dmtree/tr181/times.c @@ -11,10 +11,10 @@ #include #include -#include "dmuci.h" -#include "dmbbf.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "dmentry.h" #include "times.h" diff --git a/dmtree/tr181/times.h b/dmtree/tr181/times.h index 2ffa7352..d7132732 100644 --- a/dmtree/tr181/times.h +++ b/dmtree/tr181/times.h @@ -11,7 +11,7 @@ #ifndef __TIMES_H #define __TIMES_H -#include "dmbbf.h" +#include extern DMLEAF tTimeParams[]; diff --git a/dmtree/tr181/upnp.c b/dmtree/tr181/upnp.c index 4af7f77c..25500814 100644 --- a/dmtree/tr181/upnp.c +++ b/dmtree/tr181/upnp.c @@ -12,15 +12,15 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "upnp.h" /* *** Device.UPnP. *** */ DMOBJ tUPnPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDeviceParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/usb.c b/dmtree/tr181/usb.c index 3d4c0501..3bd4f7ea 100644 --- a/dmtree/tr181/usb.c +++ b/dmtree/tr181/usb.c @@ -9,15 +9,15 @@ */ #include -#include "dmbbf.h" -#include "dmcommon.h" -#include "dmuci.h" +#include +#include +#include #include "dmentry.h" #include "usb.h" /* *** Device.USB. *** */ DMOBJ tUSBObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Interface", &DMREAD, NULL, NULL, NULL, browseUSBInterfaceInst, NULL, NULL, NULL, tUSBInterfaceObj, tUSBInterfaceParams, NULL, BBFDM_BOTH}, {"Port", &DMREAD, NULL, NULL, NULL, browseUSBPortInst, NULL, NULL, NULL, NULL, tUSBPortParams, get_linker_usb_port, BBFDM_BOTH}, {"USBHosts", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSBUSBHostsObj, tUSBUSBHostsParams, NULL, BBFDM_BOTH}, @@ -33,7 +33,7 @@ DMLEAF tUSBParams[] = { /* *** Device.USB.Interface.{i}. *** */ DMOBJ tUSBInterfaceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSBInterfaceStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -89,7 +89,7 @@ DMLEAF tUSBPortParams[] = { /* *** Device.USB.USBHosts. *** */ DMOBJ tUSBUSBHostsObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Host", &DMREAD, NULL, NULL, NULL, browseUSBUSBHostsHostInst, NULL, NULL, NULL, tUSBUSBHostsHostObj, tUSBUSBHostsHostParams, NULL, BBFDM_BOTH}, {0} }; @@ -102,7 +102,7 @@ DMLEAF tUSBUSBHostsParams[] = { /* *** Device.USB.USBHosts.Host.{i}. *** */ DMOBJ tUSBUSBHostsHostObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Device", &DMREAD, NULL, NULL, NULL, browseUSBUSBHostsHostDeviceInst, NULL, NULL, NULL, tUSBUSBHostsHostDeviceObj, tUSBUSBHostsHostDeviceParams, get_linker_usb_host_device, BBFDM_BOTH}, {0} }; @@ -122,7 +122,7 @@ DMLEAF tUSBUSBHostsHostParams[] = { /* *** Device.USB.USBHosts.Host.{i}.Device.{i}. *** */ DMOBJ tUSBUSBHostsHostDeviceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Configuration", &DMREAD, NULL, NULL, NULL, browseUSBUSBHostsHostDeviceConfigurationInst, NULL, NULL, NULL, tUSBUSBHostsHostDeviceConfigurationObj, tUSBUSBHostsHostDeviceConfigurationParams, NULL, BBFDM_BOTH}, {0} }; @@ -153,7 +153,7 @@ DMLEAF tUSBUSBHostsHostDeviceParams[] = { /* *** Device.USB.USBHosts.Host.{i}.Device.{i}.Configuration.{i}. *** */ DMOBJ tUSBUSBHostsHostDeviceConfigurationObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Interface", &DMREAD, NULL, NULL, NULL, browseUSBUSBHostsHostDeviceConfigurationInterfaceInst, NULL, NULL, NULL, NULL, tUSBUSBHostsHostDeviceConfigurationInterfaceParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/userinterface.c b/dmtree/tr181/userinterface.c index 3710e95e..9521515c 100644 --- a/dmtree/tr181/userinterface.c +++ b/dmtree/tr181/userinterface.c @@ -13,16 +13,16 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmjson.h" -#include "dmcommon.h" +#include +#include +#include +#include +#include #include "userinterface.h" /* *** Device.UserInterface. *** */ DMOBJ tUserInterfaceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"RemoteAccess", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUserInterfaceRemoteAccessParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/users.c b/dmtree/tr181/users.c index dba80907..fb33ddc9 100644 --- a/dmtree/tr181/users.c +++ b/dmtree/tr181/users.c @@ -9,13 +9,13 @@ * Author: Omar Kallel */ -#include "dmbbf.h" +#include +#include #include "users.h" -#include "dmcommon.h" /* *** Device.Users. *** */ DMOBJ tUsersObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"User", &DMWRITE, add_users_user, delete_users_user, NULL, browseUserInst, NULL, NULL, NULL, NULL, tUsersUserParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/users.h b/dmtree/tr181/users.h index 86428ea6..06db9a0f 100644 --- a/dmtree/tr181/users.h +++ b/dmtree/tr181/users.h @@ -11,7 +11,7 @@ #ifndef _USERS_H #define _USERS_H -#include "dmbbf.h" +#include extern DMOBJ tUsersObj[]; extern DMLEAF tUsersParams[]; diff --git a/dmtree/tr181/wifi.c b/dmtree/tr181/wifi.c index 709386e1..f6c2ba8a 100644 --- a/dmtree/tr181/wifi.c +++ b/dmtree/tr181/wifi.c @@ -13,19 +13,20 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" -#include "wifi.h" -#include "dmjson.h" +#include +#include +#include +#include +#include #include "dmentry.h" #include "wepkey.h" +#include "wifi.h" + #define DELIMITOR "," /* *** Device.WiFi. *** */ DMOBJ tWiFiObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Radio", &DMREAD, NULL, NULL, NULL, browseWifiRadioInst, NULL, NULL, NULL, tWiFiRadioObj, tWiFiRadioParams, get_linker_Wifi_Radio, BBFDM_BOTH}, {"SSID", &DMWRITE, add_wifi_ssid, delete_wifi_ssid, NULL, browseWifiSsidInst, NULL, NULL, NULL, tWiFiSSIDObj, tWiFiSSIDParams, get_linker_Wifi_Ssid, BBFDM_BOTH}, {"AccessPoint", &DMREAD, NULL, NULL, NULL, browseWifiAccessPointInst, NULL, NULL, NULL, tWiFiAccessPointObj, tWiFiAccessPointParams, NULL, BBFDM_BOTH}, @@ -46,7 +47,7 @@ DMLEAF tWiFiParams[] = { /* *** Device.WiFi.Radio.{i}. *** */ DMOBJ tWiFiRadioObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiRadioStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -104,7 +105,7 @@ DMLEAF tWiFiRadioStatsParams[] = { /* *** Device.WiFi.NeighboringWiFiDiagnostic. *** */ DMOBJ tWiFiNeighboringWiFiDiagnosticObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Result", &DMREAD, NULL, NULL, NULL, browseWifiNeighboringWiFiDiagnosticResultInst, NULL, NULL, NULL, NULL, tWiFiNeighboringWiFiDiagnosticResultParams, NULL, BBFDM_CWMP}, {0} }; @@ -130,7 +131,7 @@ DMLEAF tWiFiNeighboringWiFiDiagnosticResultParams[] = { /* *** Device.WiFi.SSID.{i}. *** */ DMOBJ tWiFiSSIDObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiSSIDStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -170,7 +171,7 @@ DMLEAF tWiFiSSIDStatsParams[] = { /* *** Device.WiFi.AccessPoint.{i}. *** */ DMOBJ tWiFiAccessPointObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Security", &DMWRITE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiAccessPointSecurityParams, NULL, BBFDM_BOTH}, {"AssociatedDevice", &DMREAD, NULL, NULL, NULL, browse_wifi_associated_device, NULL, NULL, NULL, tWiFiAccessPointAssociatedDeviceObj, tWiFiAccessPointAssociatedDeviceParams, get_linker_associated_device, BBFDM_BOTH}, {"WPS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiAccessPointWPSParams, NULL, BBFDM_BOTH}, @@ -230,7 +231,7 @@ DMLEAF tWiFiAccessPointWPSParams[] = { /* *** Device.WiFi.AccessPoint.{i}.AssociatedDevice.{i}. *** */ DMOBJ tWiFiAccessPointAssociatedDeviceObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiAccessPointAssociatedDeviceStatsParams, NULL, BBFDM_BOTH}, {0} }; @@ -286,7 +287,7 @@ DMLEAF tWiFiAcessPointIEEE80211rParams[] = { /* *** Device.WiFi.EndPoint.{i}. *** */ DMOBJ tWiFiEndPointObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointStatsParams, NULL, BBFDM_BOTH}, {"Security", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointSecurityParams, NULL, BBFDM_BOTH}, {"Profile", &DMREAD, NULL, NULL, NULL, browseWiFiEndPointProfileInst, NULL, NULL, NULL, tWiFiEndPointProfileObj, tWiFiEndPointProfileParams, NULL, BBFDM_BOTH}, @@ -324,7 +325,7 @@ DMLEAF tWiFiEndPointSecurityParams[] = { /* *** Device.WiFi.EndPoint.{i}.Profile.{i}. *** */ DMOBJ tWiFiEndPointProfileObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Security", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointProfileSecurityParams, NULL, BBFDM_BOTH}, {0} }; @@ -700,7 +701,7 @@ int get_radio_operating_channel_bandwidth(char *refparam, struct dmctx *ctx, voi json_object *res; char *wlan_name; dmuci_get_value_by_section_string(((struct wifi_radio_args *)data)->wifi_radio_sec, "bandwidth", value); - if (value[0] == '\0') + if ((*value)[0] == '\0') { wlan_name = section_name(((struct wifi_radio_args *)data)->wifi_radio_sec); dmubus_call("router.wireless", "status", UBUS_ARGS{{"vif", wlan_name, String}}, 1, &res); diff --git a/dmtree/tr181/x_iopsys_eu_buttons.c b/dmtree/tr181/x_iopsys_eu_buttons.c index 9442c187..ca50f811 100644 --- a/dmtree/tr181/x_iopsys_eu_buttons.c +++ b/dmtree/tr181/x_iopsys_eu_buttons.c @@ -12,10 +12,10 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_buttons.h" /*** DMROOT.X_IOPSYS_EU_Buttons.{i}. ****/ diff --git a/dmtree/tr181/x_iopsys_eu_dropbear.c b/dmtree/tr181/x_iopsys_eu_dropbear.c index bf05261d..ae02c9d8 100644 --- a/dmtree/tr181/x_iopsys_eu_dropbear.c +++ b/dmtree/tr181/x_iopsys_eu_dropbear.c @@ -11,10 +11,10 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_dropbear.h" /*** DMROOT.X_IOPSYS_EU_Dropbear.{i}. ****/ diff --git a/dmtree/tr181/x_iopsys_eu_ice.c b/dmtree/tr181/x_iopsys_eu_ice.c index 2a17affd..cb4b24e8 100644 --- a/dmtree/tr181/x_iopsys_eu_ice.c +++ b/dmtree/tr181/x_iopsys_eu_ice.c @@ -12,10 +12,10 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_ice.h" /*** DMROOT.X_IOPSYS_EU_ICE. ***/ diff --git a/dmtree/tr181/x_iopsys_eu_igmp.c b/dmtree/tr181/x_iopsys_eu_igmp.c index 9555f88c..42888d8d 100644 --- a/dmtree/tr181/x_iopsys_eu_igmp.c +++ b/dmtree/tr181/x_iopsys_eu_igmp.c @@ -12,10 +12,10 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_igmp.h" DMLEAF tSe_IgmpParam[] = { diff --git a/dmtree/tr181/x_iopsys_eu_ipacccfg.c b/dmtree/tr181/x_iopsys_eu_ipacccfg.c index b3b5e4f1..a3035133 100644 --- a/dmtree/tr181/x_iopsys_eu_ipacccfg.c +++ b/dmtree/tr181/x_iopsys_eu_ipacccfg.c @@ -12,15 +12,15 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_ipacccfg.h" /*** DMROOT.X_IOPSYS_EU_IpAccCfg. ***/ DMOBJ tSe_IpAccObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {CUSTOM_PREFIX"IpAccListCfgObj", &DMWRITE, add_ipacccfg_rule, delete_ipacccfg_rule, NULL, browseAccListInst, NULL, NULL, NULL, NULL, tSe_IpAccCfgParam, NULL, BBFDM_BOTH}, {CUSTOM_PREFIX"PortForwarding", &DMWRITE, add_ipacccfg_port_forwarding, delete_ipacccfg_port_forwarding, NULL, browseport_forwardingInst, NULL, NULL, NULL, NULL, tSe_PortForwardingParam, NULL, BBFDM_BOTH}, {0} diff --git a/dmtree/tr181/x_iopsys_eu_logincfg.c b/dmtree/tr181/x_iopsys_eu_logincfg.c index 97b27fbd..6e0bb630 100644 --- a/dmtree/tr181/x_iopsys_eu_logincfg.c +++ b/dmtree/tr181/x_iopsys_eu_logincfg.c @@ -10,10 +10,10 @@ */ #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_logincfg.h" /*** DMROOT.X_IOPSYS_EU_LoginCfg. ***/ diff --git a/dmtree/tr181/x_iopsys_eu_owsd.c b/dmtree/tr181/x_iopsys_eu_owsd.c index 07d8b710..052756ff 100644 --- a/dmtree/tr181/x_iopsys_eu_owsd.c +++ b/dmtree/tr181/x_iopsys_eu_owsd.c @@ -12,10 +12,10 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "dmentry.h" #include "x_iopsys_eu_owsd.h" @@ -28,7 +28,7 @@ DMLEAF XIopsysEuOwsdParams[] = { }; DMOBJ XIopsysEuOwsdObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {CUSTOM_PREFIX"UbusProxy", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, UbusProxyParams, NULL, BBFDM_BOTH}, {CUSTOM_PREFIX"ListenObj", &DMWRITE, add_owsd_listen, delete_owsd_listen_instance, NULL, browseXIopsysEuOwsdListenObj, NULL, NULL, NULL, NULL, X_IOPSYS_EU_ListenObjParams, NULL, BBFDM_BOTH}, {0} diff --git a/dmtree/tr181/x_iopsys_eu_power_mgmt.c b/dmtree/tr181/x_iopsys_eu_power_mgmt.c index d121a5dc..6fffc26a 100644 --- a/dmtree/tr181/x_iopsys_eu_power_mgmt.c +++ b/dmtree/tr181/x_iopsys_eu_power_mgmt.c @@ -12,9 +12,9 @@ */ #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmcommon.h" +#include +#include +#include #include "x_iopsys_eu_power_mgmt.h" /*** DMROOT.X_IOPSYS_EU_PowerManagement. ***/ diff --git a/dmtree/tr181/x_iopsys_eu_syslog.c b/dmtree/tr181/x_iopsys_eu_syslog.c index 0edac3a0..0e380bda 100644 --- a/dmtree/tr181/x_iopsys_eu_syslog.c +++ b/dmtree/tr181/x_iopsys_eu_syslog.c @@ -12,10 +12,10 @@ #include #include #include -#include "dmuci.h" -#include "dmubus.h" -#include "dmbbf.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_syslog.h" /*** DMROOT.X_IOPSYS_EU_SyslogCfg. ***/ diff --git a/dmtree/tr181/x_iopsys_eu_wifilife.c b/dmtree/tr181/x_iopsys_eu_wifilife.c index c146cb41..10b2baec 100644 --- a/dmtree/tr181/x_iopsys_eu_wifilife.c +++ b/dmtree/tr181/x_iopsys_eu_wifilife.c @@ -10,15 +10,15 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "x_iopsys_eu_wifilife.h" /*** DMROOT.X_IOPSYS_EU_WiFiLife. ****/ DMOBJ X_IOPSYS_EU_WiFiLifeObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Steering", &DMREAD, NULL, NULL, NULL, browseWifiLifeSteeringObj, NULL, NULL, NULL, NULL, WiFiLifeSteeringParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/dmtree/tr181/xmpp.c b/dmtree/tr181/xmpp.c index 3a34d7b7..551f5f48 100644 --- a/dmtree/tr181/xmpp.c +++ b/dmtree/tr181/xmpp.c @@ -12,15 +12,15 @@ #include #include -#include "dmbbf.h" -#include "dmuci.h" -#include "dmubus.h" -#include "dmcommon.h" +#include +#include +#include +#include #include "xmpp.h" /* *** Device.XMPP. *** */ DMOBJ tXMPPObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Connection", &DMWRITE, add_xmpp_connection, delete_xmpp_connection, NULL, browsexmpp_connectionInst, NULL, NULL, NULL, tXMPPConnectionObj, tXMPPConnectionParams, get_xmpp_connection_linker, BBFDM_BOTH}, {0} }; @@ -34,7 +34,7 @@ DMLEAF tXMPPParams[] = { /* *** Device.XMPP.Connection.{i}. *** */ DMOBJ tXMPPConnectionObj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Server", &DMREAD, NULL, NULL, NULL, browsexmpp_connection_serverInst, NULL, NULL, NULL, NULL, tXMPPConnectionServerParams, NULL, BBFDM_BOTH}, {0} }; diff --git a/json/convertor_json_to_c.py b/json/convertor_json_to_c.py index 35d96b01..399a6f41 100755 --- a/json/convertor_json_to_c.py +++ b/json/convertor_json_to_c.py @@ -169,7 +169,7 @@ def printheaderObjCommon( objname ): def cprintheaderOBJS( objname ): fp = open('./.objparamarray.c', 'a') print >> fp, "DMOBJ %s[] = {" % ("t" + getname(objname) + "Obj") - print >> fp, "/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/" + print >> fp, "/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/" fp.close() def hprintheaderOBJS( objname ): diff --git a/dmbbf.c b/libbbf_api/dmbbf.c similarity index 96% rename from dmbbf.c rename to libbbf_api/dmbbf.c index f8290004..086f587d 100644 --- a/dmbbf.c +++ b/libbbf_api/dmbbf.c @@ -9,6 +9,7 @@ * Author Imen Bhiri * Author Feten Besbes * Author Omar Kallel + * Author Amin Ben Ramdhane * */ @@ -19,37 +20,8 @@ #include "dmuci.h" #include "dmbbf.h" #include "dmmem.h" -#include "device.h" -#include "times.h" -#include "upnp.h" -#include "deviceinfo.h" -#include "managementserver.h" -#include "x_iopsys_eu_igmp.h" -#include "x_iopsys_eu_ice.h" -#include "x_iopsys_eu_power_mgmt.h" -#include "x_iopsys_eu_ipacccfg.h" -#include "x_iopsys_eu_logincfg.h" -#include "x_iopsys_eu_syslog.h" #include "dmcommon.h" -#include "wifi.h" -#include "ethernet.h" -#include "atm.h" -#include "ptm.h" -#include "bridging.h" -#include "hosts.h" -#include "dhcpv4.h" -#include "ip.h" -#include "ppp.h" -#include "softwaremodules.h" -#include "routing.h" -#include "nat.h" -#include "xmpp.h" #include "dmjson.h" -#include "dmentry.h" -#include "dmoperate.h" -#ifdef BBF_TR104 -#include "voice_services.h" -#endif static char *get_parameter_notification(struct dmctx *ctx, char *param); static int remove_parameter_notification(char *param); @@ -340,7 +312,7 @@ void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, } } - if (entryobj->nextobj || entryobj->nextjsonobj) { + if (entryobj->nextobj || entryobj->nextdynamicobj) { *err = dm_browse(dmctx, &node, entryobj->nextobj, data, instance); } } @@ -348,7 +320,8 @@ void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, int dm_browse(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, void *data, char *instance) { DMOBJ *jentryobj; - int err = 0; + struct dm_dynamic_obj *next_dyn_array; + int i, j, err = 0; char *parent_obj = parent_node->current_object; @@ -361,11 +334,20 @@ int dm_browse(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, void *d } if (parent_node->obj) { - jentryobj = parent_node->obj->nextjsonobj; - for (; (jentryobj && jentryobj->obj); jentryobj++) { - dm_browse_entry(dmctx, parent_node, jentryobj, data, instance, parent_obj, &err); - if (dmctx->stop) - return err; + if (parent_node->obj->nextdynamicobj) { + for (i = 0; i < __INDX_DYNAMIC_MAX; i++) { + next_dyn_array = parent_node->obj->nextdynamicobj + i; + if (next_dyn_array->nextobj) { + for (j = 0; next_dyn_array->nextobj[j]; j++) { + jentryobj = next_dyn_array->nextobj[j]; + for (; (jentryobj && jentryobj->obj); jentryobj++) { + dm_browse_entry(dmctx, parent_node, jentryobj, data, instance, parent_obj, &err); + if (dmctx->stop) + return err; + } + } + } + } } } @@ -421,6 +403,77 @@ int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char return err; } +static int plugin_dynamic_obj_match(struct dmctx *dmctx, struct dmnode *node, char *entry_obj, char *full_obj) +{ + if (node->matched) + return 0; + + if (!dmctx->inparam_isparam && strstr(node->current_object, full_obj) == node->current_object) { + node->matched++; + dmctx->findparam = 1; + return 0; + } + + if (strstr(full_obj, node->current_object) == full_obj) + return 0; + + return FAULT_9005; +} + +void dm_check_dynamic_obj(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, char *obj, DMOBJ **root_entry, int *obj_found) +{ + int err = 0; + if (!entryobj) + return; + char *parent_obj = parent_node->current_object; + for (; 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%c", parent_obj, entryobj->obj, dm_delim); + if (strcmp(node.current_object, obj) == 0) { + *root_entry = entryobj; + *obj_found = 1; + return; + } + + 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); + } +} + +int free_dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryobj) +{ + if (!entryobj) + return 0; + + for (; entryobj->obj; entryobj++) { + if (entryobj->nextdynamicobj) { + for (int i = 0; i < __INDX_DYNAMIC_MAX; i++) { + struct dm_dynamic_obj *next_dyn_array = entryobj->nextdynamicobj + i; + if (next_dyn_array->nextobj) FREE(next_dyn_array->nextobj); + } + FREE(entryobj->nextdynamicobj); + } + + DMNODE node = {0}; + node.obj = entryobj; + node.parent = parent_node; + node.instance_level = parent_node->instance_level; + node.matched = parent_node->matched; + + if (entryobj->nextobj) + free_dm_browse_node_dynamic_object_tree(&node, entryobj->nextobj); + } + return 0; +} + int rootcmp(char *inparam, char *rootobj) { int cmp = -1; @@ -1060,13 +1113,23 @@ int string_to_bool(char *v, bool *b) return -1; } -/****************** - * operate commands - *****************/ -int dm_entry_operate(struct dmctx *dmctx) +void dmentry_instance_lookup_inparam(struct dmctx *ctx) { - int res = operate_on_node(dmctx, dmctx->in_param, dmctx->in_value); - return res; + char *pch, *spch, *in_param; + in_param = dmstrdup(ctx->in_param); + int i = 0; + char pat[2] = {0}; + *pat = dm_delim; + for (pch = strtok_r(in_param, pat, &spch); pch != NULL; pch = strtok_r(NULL, pat, &spch)) { + if (pch[0]== '[') { + ctx->alias_register |= (1 << i); + i++; + } else if (isdigit(pch[0])) { + i++; + } + } + dmfree(in_param); + ctx->nbrof_instance = i; } /* ********** diff --git a/dmbbf.h b/libbbf_api/dmbbf.h similarity index 94% rename from dmbbf.h rename to libbbf_api/dmbbf.h index 026cd5cd..6e7c20b9 100644 --- a/dmbbf.h +++ b/libbbf_api/dmbbf.h @@ -8,6 +8,7 @@ * Author MOHAMED Kallel * Author Imen Bhiri * Author Feten Besbes + * Author Amin Ben Ramdhane * */ @@ -94,6 +95,11 @@ struct dmnode; struct dmctx; struct dm_notif_s; +struct dm_dynamic_obj { + struct dm_obj_s **nextobj; + int isstatic; +}; + struct dm_permession_s { char *val; char *(*get_permission)(char *refparam, struct dmctx *dmctx, void *data, char *instance); @@ -122,7 +128,7 @@ typedef struct dm_leaf_s { } DMLEAF; typedef struct dm_obj_s { - /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type(13)*/ + /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ char *obj; struct dm_permession_s *permission; int (*addobj)(char *refparam, struct dmctx *ctx, void *data, char **instance); @@ -131,7 +137,7 @@ typedef struct dm_obj_s { int (*browseinstobj)(struct dmctx *dmctx, struct dmnode *node, void *data, char *instance); struct dm_forced_inform_s *forced_inform; struct dm_notif_s *notification; - struct dm_obj_s *nextjsonobj; + struct dm_dynamic_obj *nextdynamicobj; struct dm_obj_s *nextobj; struct dm_leaf_s *leaf; int (*get_linker)(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker); @@ -274,6 +280,28 @@ typedef struct execute_end_session { void (*function)(struct execute_end_session *); } execute_end_session; +typedef struct lib_map_obj { + char *path; + struct dm_obj_s *root_obj; +} LIB_MAP_OBJ; + +enum operate_ret_status{ + UBUS_INVALID_ARGUMENTS, + SUCCESS, + FAIL, + CMD_NOT_FOUND, + __STATUS_MAX, +}; + +typedef enum operate_ret_status opr_ret_t; + +typedef opr_ret_t (*operation) (struct dmctx *dmctx, char *p, char *input); + +typedef struct lib_map_operate { + char *path; + operation operate; +} LIB_MAP_OPERATE; + enum set_value_action { VALUECHECK, VALUESET @@ -283,6 +311,7 @@ enum del_action_enum { DEL_INST, DEL_ALL }; + enum { CMD_GET_VALUE, CMD_GET_NAME, @@ -469,6 +498,12 @@ enum dm_param_flags_enum{ DM_FACTORIZED = 1 << 31 }; +enum { + INDX_JSON_OBJ_MOUNT, + INDX_LIBRARY_OBJ_MOUNT, + __INDX_DYNAMIC_MAX +}; + extern struct list_head list_enabled_notify; extern struct list_head list_enabled_lw_notify; extern struct list_head list_execute_end_session; @@ -505,7 +540,7 @@ void add_list_fault_param(struct dmctx *ctx, char *param, int fault); void del_list_fault_param(struct param_fault *param_fault); void free_all_list_fault_param(struct dmctx *ctx); int string_to_bool(char *v, bool *b); -int dm_entry_operate(struct dmctx *dmctx); +void dmentry_instance_lookup_inparam(struct dmctx *ctx); int dm_entry_get_value(struct dmctx *ctx); int dm_entry_get_name(struct dmctx *ctx); int dm_entry_get_notification(struct dmctx *ctx); @@ -548,6 +583,8 @@ void cwmp_set_end_session (unsigned int flag); char *dm_print_path(char *fpath, ...); void free_all_list_enabled_lwnotify(); int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char *instance); +void dm_check_dynamic_obj(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, char *obj, DMOBJ **root_entry, int *obj_found); +int free_dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryobj); #ifdef BBF_TR064 void dm_upnp_apply_config(void); void add_list_upnp_param_track(struct dmctx *dmctx, struct list_head *pchead, char *param, char *key, char *value, unsigned int isobj); diff --git a/dmcommon.c b/libbbf_api/dmcommon.c similarity index 99% rename from dmcommon.c rename to libbbf_api/dmcommon.c index 3085608c..bd6b1e8d 100644 --- a/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -8,6 +8,7 @@ * Author: Imen Bhiri * Author: Feten Besbes * Author: Omar Kallel + * Author Amin Ben Ramdhane */ #include @@ -687,7 +688,7 @@ void update_section_list(char *config, char *section, char *option, int number, struct uci_section *s = NULL; int i = 0; - if (config == DMMAP) + if (strcmp(config, DMMAP) == 0) { if (option) { uci_path_foreach_option_eq(bbfdm, config, section, option, filter, s) { diff --git a/dmcommon.h b/libbbf_api/dmcommon.h similarity index 99% rename from dmcommon.h rename to libbbf_api/dmcommon.h index 286570c5..c21e259f 100644 --- a/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -7,15 +7,18 @@ * * Author: Imen Bhiri * Author: Feten Besbes + * Author Amin Ben Ramdhane */ #ifndef __DM_COMMON_H #define __DM_COMMON_H + #include #include #include #include #include "dmbbf.h" + #define NVRAM_FILE "/proc/nvram/WpaKey" #define MAX_DHCP_LEASES 256 #define MAX_PROC_ROUTING 256 diff --git a/dmjson.c b/libbbf_api/dmjson.c similarity index 100% rename from dmjson.c rename to libbbf_api/dmjson.c diff --git a/dmjson.h b/libbbf_api/dmjson.h similarity index 100% rename from dmjson.h rename to libbbf_api/dmjson.h diff --git a/dmmem.c b/libbbf_api/dmmem.c similarity index 100% rename from dmmem.c rename to libbbf_api/dmmem.c diff --git a/dmmem.h b/libbbf_api/dmmem.h similarity index 100% rename from dmmem.h rename to libbbf_api/dmmem.h diff --git a/dmubus.c b/libbbf_api/dmubus.c similarity index 100% rename from dmubus.c rename to libbbf_api/dmubus.c diff --git a/dmubus.h b/libbbf_api/dmubus.h similarity index 100% rename from dmubus.h rename to libbbf_api/dmubus.h diff --git a/dmuci.c b/libbbf_api/dmuci.c similarity index 100% rename from dmuci.c rename to libbbf_api/dmuci.c diff --git a/dmuci.h b/libbbf_api/dmuci.h similarity index 100% rename from dmuci.h rename to libbbf_api/dmuci.h diff --git a/library/example.json b/library/example.json new file mode 100644 index 00000000..5481c926 --- /dev/null +++ b/library/example.json @@ -0,0 +1,53 @@ +{ + "Device.IP.Diagnostics.X_IOPSYS_EU_BBKSpeedTest.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": false, + "DiagnosticsState": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true + }, + "Latency": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + + ], + "read": true, + "write": false + }, + "Download": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + + ], + "read": true, + "write": false + }, + "Upload": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + + ], + "read": true, + "write": false + } + }, + "Device.BBKSpeedTest": { + "type": "operate" + } +} + diff --git a/library/example/Makefile b/library/example/Makefile new file mode 100644 index 00000000..e61c1eec --- /dev/null +++ b/library/example/Makefile @@ -0,0 +1,23 @@ +LIB_EXAMPLE := lib/libexample.so + +OBJS := example.o + +PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing +PROG_LDFLAGS = $(LDFLAGS) -lbbfdm +FPIC := -fPIC + +.PHONY: all + +%.o: %.c + $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $< + +all: $(LIB_EXAMPLE) + +$(LIB_EXAMPLE): $(OBJS) + $(shell mkdir -p lib) + $(CC) -shared -Wl,-soname,libexample.so $^ -o $@ + +clean: + rm -f *.o + rm -f $(LIB_EXAMPLE) + diff --git a/library/example/example.c b/library/example/example.c new file mode 100644 index 00000000..59d96324 --- /dev/null +++ b/library/example/example.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2020 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 +#include +#include +#include +#include +#include +#include +#include "example.h" + +/* ********** RootDynamicObj ********** */ +LIB_MAP_OBJ tRootDynamicObj[] = { +/* parentobj, nextobject */ +{"Device.IP.Diagnostics.", tdynamicIPDiagnosticsObj}, +{0} +}; + +/* ********** RootDynamicOperate ********** */ +LIB_MAP_OPERATE tRootDynamicOperate[] = { +/* pathname, operation */ +{"Device.BBKSpeedTest", dynamicDeviceOperate}, +{0} +}; + +/* *** Device.IP.Diagnostics. *** */ +DMOBJ tdynamicIPDiagnosticsObj[] = { +/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/ +{"X_IOPSYS_EU_BBKSpeedTest", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tdynamicIPDiagnosticsX_IOPSYS_EU_BBKSpeedTestParams, NULL, BBFDM_BOTH}, +{0} +}; + +/* *** Device.IP.Diagnostics.X_IOPSYS_EU_BBKSpeedTest. *** */ +DMLEAF tdynamicIPDiagnosticsX_IOPSYS_EU_BBKSpeedTestParams[] = { +/* PARAM, permission, type, getvalue, setvalue, forced_inform, notification, bbfdm_type*/ +{"DiagnosticsState", &DMWRITE, DMT_STRING, getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState, setdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState, NULL, NULL, BBFDM_BOTH}, +{"Latency", &DMREAD, DMT_STRING, getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Latency, NULL, NULL, NULL, BBFDM_BOTH}, +{"Download", &DMREAD, DMT_STRING, getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Download, NULL, NULL, NULL, BBFDM_BOTH}, +{"Upload", &DMREAD, DMT_STRING, getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Upload, NULL, NULL, NULL, BBFDM_BOTH}, +{0} +}; + +/************************************************************* + * GET & SET PARAM +/*************************************************************/ +static int execute_bbk_speedtest() +{ + json_object *res; + char *latency, *download, *upload = NULL; + + dmubus_call("bbk", "start", UBUS_ARGS{}, 0, &res); + if (res) { + dmuci_set_varstate_value("cwmp", "@bbkspeedtest[0]", "DiagnosticState", "Complete"); + latency=dmjson_get_value(res, 1, "latency"); + if(latency!=NULL && strlen(latency)>0) + dmuci_set_varstate_value("cwmp", "@bbkspeedtest[0]", "Latency", latency); + download=dmjson_get_value(res, 1, "download"); + if(download!=NULL && strlen(latency)>0) + dmuci_set_varstate_value("cwmp", "@bbkspeedtest[0]", "Download", download); + upload=dmjson_get_value(res, 1, "upload"); + if(upload!=NULL && strlen(upload)>0) + dmuci_set_varstate_value("cwmp", "@bbkspeedtest[0]", "Upload", upload); + } + return 0; +} + +static inline char *bbk_speedtest_get(char *option, char *def) +{ + char *tmp; + dmuci_get_varstate_string("cwmp", "@bbkspeedtest[0]", option, &tmp); + if(tmp && tmp[0] == '\0') + return dmstrdup(def); + else + return tmp; +} + + +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbk_speedtest_get("DiagnosticState", "None"); + return 0; +} + +int setdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *tmp; + struct uci_section *curr_section = NULL; + + switch (action) { + case VALUECHECK: + break; + case VALUESET: + if (strcmp(value, "Requested") == 0) { + curr_section = dmuci_walk_state_section("cwmp", "bbkspeedtest", NULL, NULL, CMP_SECTION, NULL, NULL, GET_FIRST_SECTION); + if(!curr_section) + { + dmuci_add_state_section("cwmp", "bbkspeedtest", &curr_section, &tmp); + } + dmuci_set_varstate_value("cwmp", "@bbkspeedtest[0]", "DiagnosticState", value); + execute_bbk_speedtest(); + } + break; + } + return 0; +} + +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Latency(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbk_speedtest_get("Latency", "0"); + return 0; +} + +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Download(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbk_speedtest_get("Download", "0"); + return 0; +} + +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Upload(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = bbk_speedtest_get("Upload", "0"); + return 0; +} + +/************************************************************* + * OPERATE +/*************************************************************/ +opr_ret_t dynamicDeviceOperate(struct dmctx *dmctx, char *path, char *input) +{ + json_object *ubus_res = NULL; + + dmubus_call("bbk", "start", UBUS_ARGS{}, 0, &ubus_res); + + char *param_latency = (char *) dmjson_get_value(ubus_res, 1, "latency"); + char *param_download = (char *) dmjson_get_value(ubus_res, 1, "download"); + char *param_upload = (char *) dmjson_get_value(ubus_res, 1, "upload"); + + add_list_paramameter(dmctx, dmstrdup("Latency"), param_latency, "string", NULL, 0); + add_list_paramameter(dmctx, dmstrdup("Download"), param_download, "string", NULL, 0); + add_list_paramameter(dmctx, dmstrdup("Upload"), param_upload, "string", NULL, 0); + + return SUCCESS; +} diff --git a/library/example/example.h b/library/example/example.h new file mode 100644 index 00000000..74c13480 --- /dev/null +++ b/library/example/example.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 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 __EXAMPLE_H +#define __EXAMPLE_H + +DMOBJ tdynamicIPDiagnosticsObj[]; +DMLEAF tdynamicIPDiagnosticsX_IOPSYS_EU_BBKSpeedTestParams[]; + +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +int setdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_DiagnosticsState(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action); +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Latency(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Download(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +int getdynamic_IPDiagnosticsX_IOPSYS_EU_BBKSpeedTest_Upload(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); +opr_ret_t dynamicDeviceOperate(struct dmctx *dmctx, char *path, char *input); + +#endif //__EXAMPLE_H + diff --git a/library/generate_library.py b/library/generate_library.py new file mode 100755 index 00000000..252b3661 --- /dev/null +++ b/library/generate_library.py @@ -0,0 +1,641 @@ +#!/usr/bin/python + +# Copyright (C) 2020 iopsys Software Solutions AB +# Author: Amin Ben Ramdhane + +import os +import sys +import time +import json +from collections import OrderedDict + +arrtype = { +"string": "DMT_STRING", +"unsignedInt": "DMT_UNINT", +"unsignedLong": "DMT_UNLONG", +"int": "DMT_INT", +"long": "DMT_LONG", +"boolean": "DMT_BOOL", +"dateTime": "DMT_TIME", +"hexBinary": "DMT_HEXBIN", +"base64": "DMT_BASE64", +} + +def removefile( filename ): + try: + os.remove(filename) + except OSError: + pass + +def securemkdir( folder ): + try: + os.mkdir(folder) + except: + pass + +def getlastname( name ): + lastname = name + lastname = lastname.replace(".{i}", "") + namelist = lastname.split('.') + lastname = namelist[-1] + if lastname == "": + lastname = namelist[-2] + return lastname; + +def getname( objname ): + OBJSname = objname + if (objname.count('.') > 1 and (objname.count('.') != 2 or objname.count('{i}') != 1)): + OBJSname = objname.replace("Device", "", 1) + OBJSname = OBJSname.replace("{i}", "") + OBJSname = OBJSname.replace(".", "") + if (objname.count('.') == 1): + OBJSname = "Device" + return OBJSname + return OBJSname; + +def getoptionparam( value, option ): + val = "false" + if isinstance(value,dict): + for k,v in value.items(): + if k == option: + return v + return val + +def getprotocolsparam( value, option ): + if isinstance(value,dict): + for k,v in value.items(): + if k == option and isinstance(v, list): + if len(v) == 2: + return "BBFDM_BOTH" + elif v[0] == "usp": + return "BBFDM_USP" + else: + return "BBFDM_CWMP" + return "BBFDM_BOTH" + +def getparamtype( value ): + ptype = None + paramtype = getoptionparam(value, "type") + ptype = arrtype.get(paramtype, None) + if ptype == None: + ptype = "__NA__" + return ptype + +def objhaschild( value ): + if isinstance(value,dict): + for k,v in value.items(): + if isinstance(v,dict): + for k1,v1 in v.items(): + if k1 == "type" and v1 == "object": + return 1 + return 0 + +def objhasparam( value ): + if isinstance(value,dict): + for k,v in value.items(): + if isinstance(v,dict): + for k1,v1 in v.items(): + if k1 == "type" and v1 != "object": + return 1 + return 0 + +def printheaderObjCommon( objname ): + fp = open('./.objparamarray.c', 'a') + print >> fp, "/* *** %s *** */" % objname + fp.close() + +def cprintheaderOBJS( objname ): + fp = open('./.objparamarray.c', 'a') + print >> fp, "DMOBJ %s[] = {" % ("tdynamic" + getname(objname) + "Obj") + print >> fp, "/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextjsonobj, nextobj, leaf, linker, bbfdm_type*/" + fp.close() + +def cprintheaderRootDynamicObj( ): + fp = open('./.objroot.c', 'a') + print >> fp, "/* ********** RootDynamicObj ********** */" + print >> fp, "LIB_MAP_OBJ tRootDynamicObj[] = {" + print >> fp, "/* parentobj, nextobject */" + fp.close() + +def cprintheaderRootDynamicOperate( ): + fp = open('./.objroot.c', 'a') + print >> fp, "/* ********** RootDynamicOperate ********** */" + print >> fp, "LIB_MAP_OPERATE tRootDynamicOperate[] = {" + print >> fp, "/* pathname, operation */" + fp.close() + +def printObjRootDynamic( dmobject ): + commonname = getname(dmobject) + fp = open('./.objroot.c', 'a') + print >> fp, "{\"%s\", %s}," % (dmobject, "tdynamic" + commonname + "Obj") + fp.close() + +def printOperateRootDynamic( dmobject, commonname ): + fp = open('./.objroot.c', 'a') + print >> fp, "{\"%s\", %s}," % (dmobject, "dynamic" + commonname + "Operate") + fp.close() + +def printtailArrayRootDynamic( ): + fp = open('./.objroot.c', 'a') + print >> fp, "{0}" + print >> fp, "};" + print >> fp, "" + fp.close() + +def hprintheaderOBJS( objname ): + fp = open('./.objparamarray.h', 'a') + print >> fp, "DMOBJ %s[];" % ("tdynamic" + getname(objname) + "Obj") + fp.close() + +def cprinttopfile ( fp ): + print >> fp, "/*" + print >> fp, " * Copyright (C) 2020 iopsys Software Solutions AB" + print >> fp, " *" + print >> fp, " * This program is free software; you can redistribute it and/or modify" + print >> fp, " * it under the terms of the GNU Lesser General Public License version 2.1" + print >> fp, " * as published by the Free Software Foundation" + print >> fp, " *" + print >> fp, " * Author: Amin Ben Ramdhane " + print >> fp, " */" + print >> fp, "" + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include " + print >> fp, "#include \"example.h\"" + print >> fp, "" + +def hprinttopfile ( fp ): + print >> fp, "/*" + print >> fp, " * Copyright (C) 2020 iopsys Software Solutions AB" + print >> fp, " *" + print >> fp, " * This program is free software; you can redistribute it and/or modify" + print >> fp, " * it under the terms of the GNU Lesser General Public License version 2.1" + print >> fp, " * as published by the Free Software Foundation" + print >> fp, " *" + print >> fp, " * Author: Amin Ben Ramdhane " + print >> fp, " */" + print >> fp, "" + print >> fp, "#ifndef __EXAMPLE_H" + print >> fp, "#define __EXAMPLE_H" + print >> fp, "" + +def printmakefile ( fp ): + print >> fp, "LIB_EXAMPLE := lib/libexample.so" + print >> fp, "" + print >> fp, "OBJS := example.o" + print >> fp, "" + print >> fp, "PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing" + print >> fp, "PROG_LDFLAGS = $(LDFLAGS) -lbbfdm" + print >> fp, "FPIC := -fPIC" + print >> fp, "" + print >> fp, ".PHONY: all" + print >> fp, "" + print >> fp, "%.o: %.c" + print >> fp, " $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<" + print >> fp, "" + print >> fp, "all: $(LIB_EXAMPLE)" + print >> fp, "" + print >> fp, "$(LIB_EXAMPLE): $(OBJS)" + print >> fp, " $(shell mkdir -p lib)" + print >> fp, " $(CC) -shared -Wl,-soname,libexample.so $^ -o $@" + print >> fp, "" + print >> fp, "clean:" + print >> fp, " rm -f *.o" + print >> fp, " rm -f $(LIB_EXAMPLE)" + print >> fp, "" + +def hprintfootfile ( fp ): + print >> fp, "" + print >> fp, "#endif //__EXAMPLE_H" + print >> fp, "" + +def cprintAddDelObj( faddobj, fdelobj, name, mappingobj, dmobject ): + fp = open('./.objadddel.c', 'a') + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char **instance)" % faddobj + print >> fp, "{" + print >> fp, " //TODO" + print >> fp, " return 0;" + print >> fp, "}" + print >> fp, "" + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)" % fdelobj + print >> fp, "{" + print >> fp, " switch (del_action) {" + print >> fp, " case DEL_INST:" + print >> fp, " //TODO" + print >> fp, " break;" + print >> fp, " case DEL_ALL:" + print >> fp, " //TODO" + print >> fp, " break;" + print >> fp, " }" + print >> fp, " return 0;" + print >> fp, "}" + print >> fp, "" + fp.close() + +def hprintAddDelObj( faddobj, fdelobj ): + fp = open('./.objadddel.h', 'a') + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char **instance);" % faddobj + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action);" % fdelobj + fp.close() + +def cprintBrowseObj( fbrowse, name, mappingobj, dmobject ): + fp = open('./.objbrowse.c', 'a') + print >> fp, "int %s(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)" % fbrowse + print >> fp, "{" + print >> fp, " //TODO" + print >> fp, " return 0;" + print >> fp, "}" + print >> fp, "" + fp.close() + +def hprintBrowseObj( fbrowse ): + fp = open('./.objbrowse.h', 'a') + print >> fp, "int %s(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance);" % fbrowse + fp.close() + +def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, parentname, dmparam): + fp = open('./.getstevalue.c', 'a') + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)" % getvalue + print >> fp, "{" + print >> fp, " //TODO" + print >> fp, " return 0;" + print >> fp, "}" + print >> fp, "" + if setvalue != "NULL": + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue + print >> fp, "{" + print >> fp, " switch (action) {" + print >> fp, " case VALUECHECK:" + print >> fp, " break;" + print >> fp, " case VALUESET:" + print >> fp, " //TODO" + print >> fp, " break;" + print >> fp, " }" + print >> fp, " return 0;" + print >> fp, "}" + print >> fp, "" + fp.close() + +def hprintGetSetValue( getvalue, setvalue ): + fp = open('./.getstevalue.h', 'a') + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);" % getvalue + if setvalue != "NULL": + print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action);" % setvalue + fp.close() + +def cprintOperate( get_operate ): + fp = open('./.operate.c', 'a') + print >> fp, "opr_ret_t %s(struct dmctx *dmctx, char *path, char *input)" % ("dynamic" + get_operate + "Operate") + print >> fp, "{" + print >> fp, " return SUCCESS;" + print >> fp, "}" + fp.close() + +def cprintheaderPARAMS( objname ): + fp = open('./.objparamarray.c', 'a') + print >> fp, "DMLEAF %s[] = {" % ("tdynamic" + getname(objname) + "Params") + print >> fp, "/* PARAM, permission, type, getvalue, setvalue, forced_inform, notification, bbfdm_type*/" + fp.close() + +def hprintOperate( get_operate ): + fp = open('./.operate.h', 'a') + print >> fp, "opr_ret_t %s(struct dmctx *dmctx, char *path, char *input);" % ("dynamic" + get_operate + "Operate") + fp.close() + +def hprintheaderPARAMS( objname ): + fp = open('./.objparamarray.h', 'a') + print >> fp, "DMLEAF %s[];" % ("tdynamic" + getname(objname) + "Params") + fp.close() + +def printPARAMline( parentname, dmparam, value ): + commonname = getname(parentname) + "_" + dmparam + ptype = getparamtype(value) + getvalue = "getdynamic_" + commonname + mappingparam = getoptionparam(value, "mapping") + typeparam = getoptionparam(value, "type") + bbfdm = getprotocolsparam(value, "protocols") + accessparam = getoptionparam(value, "write") + + if accessparam: + access = "&DMWRITE" + setvalue = "setdynamic_" + commonname + else: + access = "&DMREAD" + setvalue = "NULL" + + if parentname.endswith(".{i}."): + instance = "TRUE" + else: + instance = "FALSE" + + cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, parentname, dmparam) + hprintGetSetValue(getvalue, setvalue) + + fp = open('./.objparamarray.c', 'a') + print >> fp, "{\"%s\", %s, %s, %s, %s, NULL, NULL, %s}," % (dmparam, access, ptype, getvalue, setvalue, bbfdm) + fp.close() + +def printtailArray( ): + fp = open('./.objparamarray.c', 'a') + print >> fp, "{0}" + print >> fp, "};" + print >> fp, "" + fp.close() + +def printOBJline( dmobject, value ): + commonname = getname(dmobject) + hasobj = objhaschild(value) + hasparam = objhasparam(value) + accessobj = getoptionparam(value, "access") + mappingobj = getoptionparam(value, "mapping") + bbfdm = getprotocolsparam(value, "protocols") + + if accessobj: + access = "&DMWRITE" + faddobj = "adddynamicObj" + commonname + fdelobj = "deldynamicObj" + commonname + cprintAddDelObj(faddobj, fdelobj, (getlastname(dmobject)).lower(), mappingobj, dmobject) + hprintAddDelObj(faddobj, fdelobj) + else: + access = "&DMREAD" + faddobj = "NULL" + fdelobj = "NULL" + + if dmobject.endswith(".{i}."): + fbrowse = "browse" + commonname + "Inst" + cprintBrowseObj(fbrowse, (getlastname(dmobject)).lower(), mappingobj, dmobject) + hprintBrowseObj(fbrowse) + else: + fbrowse = "NULL" + + if hasobj: + objchildarray = "tdynamic" + commonname + "Obj" + else: + objchildarray = "NULL" + + if hasparam: + paramarray = "tdynamic" + commonname + "Params" + else: + paramarray = "NULL" + + fp = open('./.objparamarray.c', 'a') + print >> fp, "{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, NULL, %s, %s, NULL, %s}," % (getlastname(dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm) + fp.close() + +def printusage(): + print "Usage: " + sys.argv[0] + " " + print "Examples:" + print " - " + sys.argv[0] + " example.json" + print " ==> Generate the C code in example/ folder" + +def object_parse_childs( dmobject , value, nextlevel ): + hasobj = objhaschild(value) + hasparam = objhasparam(value) + + if hasobj or hasparam: + printheaderObjCommon(dmobject) + + if hasobj: + cprintheaderOBJS(dmobject) + hprintheaderOBJS(dmobject) + + if isinstance(value,dict): + for k,v in value.items(): + if isinstance(v,dict): + for k1,v1 in v.items(): + if k1 == "type" and v1 == "object": + printOBJline(k, v) + break + printtailArray() + + if hasparam: + cprintheaderPARAMS(dmobject) + hprintheaderPARAMS(dmobject) + if isinstance(value,dict): + for k,v in value.items(): + if k == "mapping": + continue + if isinstance(v,dict): + for k1,v1 in v.items(): + if k1 == "type" and v1 != "object": + printPARAMline(dmobject, k, v) + break + printtailArray() + + if hasobj and nextlevel == 0: + if isinstance(value,dict): + for k,v in value.items(): + if isinstance(v,dict): + for k1,v1 in v.items(): + if k1 == "type" and v1 == "object": + object_parse_childs(k , v, 0) + +def generatecfiles( pdir ): + securemkdir(pdir) + dmfpc = open(pdir + "/example" + ".c", "w") + dmfph = open(pdir + "/example" + ".h", "w") + makefile = open(pdir + "/Makefile", "w") + + cprinttopfile(dmfpc) + hprinttopfile(dmfph) + printmakefile(makefile) + + try: + tmpf = open("./.objroot.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.objparamarray.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.objparamarray.h", "r") + tmpd = tmpf.read() + tmpf.close() + dmfph.write(tmpd) + print >> dmfph, "" + except: + pass + try: + exists = os.path.isfile("./.objbrowse.c") + if exists: + print >> dmfpc, "/*************************************************************" + print >> dmfpc, " * ENTRY METHOD" + print >> dmfpc, "/*************************************************************/" + tmpf = open("./.objbrowse.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.objbrowse.h", "r") + tmpd = tmpf.read() + tmpf.close() + dmfph.write(tmpd) + print >> dmfph, "" + except: + pass + try: + exists = os.path.isfile("./.objadddel.c") + if exists: + print >> dmfpc, "/*************************************************************" + print >> dmfpc, " * ADD & DEL OBJ" + print >> dmfpc, "/*************************************************************/" + tmpf = open("./.objadddel.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.objadddel.h", "r") + tmpd = tmpf.read() + tmpf.close() + dmfph.write(tmpd) + print >> dmfph, "" + except: + pass + try: + exists = os.path.isfile("./.getstevalue.c") + if exists: + print >> dmfpc, "/*************************************************************" + print >> dmfpc, " * GET & SET PARAM" + print >> dmfpc, "/*************************************************************/" + tmpf = open("./.getstevalue.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.getstevalue.h", "r") + tmpd = tmpf.read() + tmpf.close() + dmfph.write(tmpd) + except: + pass + try: + exists = os.path.isfile("./.operate.c") + if exists: + print >> dmfpc, "/*************************************************************" + print >> dmfpc, " * OPERATE" + print >> dmfpc, "/*************************************************************/" + tmpf = open("./.operate.c", "r") + tmpd = tmpf.read() + tmpf.close() + dmfpc.write(tmpd) + except: + pass + try: + tmpf = open("./.operate.h", "r") + tmpd = tmpf.read() + tmpf.close() + dmfph.write(tmpd) + except: + pass + hprintfootfile(dmfph) + removetmpfiles() + +def generatestartedobject( key , value ): + obj_type = getoptionparam(value, "type") + if obj_type == "operate": + key = key.replace(".{i}.", ".*.") + if key not in ListOperate: + ListOperate.append(key) + else: + key = key.replace(".{i}", "") + obj = '.'.join(key.split(".")[0:key.count('.')-1]) + '.' + if obj not in ListObjects: + ListObjects.append(obj) + +def generateRootDynamicarray( ): + cprintheaderRootDynamicObj() + for x in ListObjects: + printObjRootDynamic(x) + printtailArrayRootDynamic() + + cprintheaderRootDynamicOperate() + for x in ListOperate: + commonname = getname(x) + printOperateRootDynamic(x, commonname) + cprintOperate(commonname) + hprintOperate(commonname) + printtailArrayRootDynamic() + +def removetmpfiles( ): + removefile("./.objparamarray.c") + removefile("./.objparamarray.h") + removefile("./.objadddel.c") + removefile("./.objadddel.h") + removefile("./.objbrowse.c") + removefile("./.objbrowse.h") + removefile("./.getstevalue.c") + removefile("./.getstevalue.h") + removefile("./.operate.c") + removefile("./.operate.h") + removefile("./.objroot.c") + +### main ### +if len(sys.argv) < 2: + printusage() + exit(1) + +if (sys.argv[1]).lower() == "-h" or (sys.argv[1]).lower() == "--help": + printusage() + exit(1) + +json_file = sys.argv[1] +gendir = "example" +removetmpfiles() + +with open(json_file) as file: + data = json.loads(file.read(), object_pairs_hook=OrderedDict) + +ListObjects = [] +ListOperate = [] +for i,(key,value) in enumerate(data.items()): + generatestartedobject(key, value) + +generateRootDynamicarray() + +for x in ListObjects: + printheaderObjCommon(x) + cprintheaderOBJS(x) + hprintheaderOBJS(x) + for i,(key,value) in enumerate(data.items()): + obj_type = getoptionparam(value, "type") + if obj_type == "operate": + continue + objstart = key + key = key.replace(".{i}", "") + obj = '.'.join(key.split(".")[0:key.count('.')-1]) + '.' + if x == obj: + printOBJline(objstart, value) + printtailArray() + +for i,(key,value) in enumerate(data.items()): + objstart = key + device = key.split(".") + if device[0] == None: + print "Wrong JSON Data model format!" + exit(1) + object_parse_childs(objstart, value, 0) + +generatecfiles(gendir) + +if (os.path.isdir(gendir)): + print "Source code generated under \"./%s\" folder" % gendir +else: + print "No source code generated!" + diff --git a/pictures/rootdynamicobj.png b/pictures/rootdynamicobj.png new file mode 100644 index 0000000000000000000000000000000000000000..62ab003cc3cd71bb60d4771760be42b7de3d5e2c GIT binary patch literal 18115 zcma&ObyOYA*S6VsaDux92<{e~;O_3h9fAe70KwgZ`@!Aa-QC^YeR!Vt`@QqY%$n&x z&Z*O@`>c|#U3>5At`3%$6+?u>g#!QpQ9@i;5dgr&Kgxcez&}2jqcR~rz91aFODKQ( z^l5ohZsX%8j-!aWqmr$Oql>{$W5CqL*4miP!SJWCv5kY7t>ZaFJ0AcL0}{f5%D?`e zrkSc^h++ARujw`fthr<4Qv1QdQH#v{VM{Ozqocr;$qr`fee1pR8+@g`DtMHSSQ%8#jvGQ&ecD zJ?yaO)JZ(sD-^P$k2AbBzCP^sq+SMdY@^w(dBy1kU(@!T9x8&)5Fk}r9vt)M#`gx~4OnB|hP; zy4h5cH8-w@ts)CTonhsq`(r~%C;+H^Ft^Z*7GAaU*VK-S(WIo<8qIxepp0uE0|Nx+ zX{=5LTu6mrnh)dhbe~<`OBJCe3zy_o^2o{8=;CTpu>9M)`+o;PH{(cTXg|B$5ANWq zsF5#gh$HCec=910|M5~&AtPFM;T1AqBPQi>%nZ2MoE7RPRCcKl#}2p5>^F@G{<^}e zrE`y9oe|Mvy_ibkhD3l@IS9W!zEa|Z&om+v=?4aET%~01gfi8KN;r02OET~1w7rO% z|FD!YYMAiSMwe8Nu`n1*t3i!WJ3#r0CM3iHBj#YBsVU2};J)NC>QV@zKD7y)=^8G0 z{3NWB>Ppk9U2glUA}6^qJ~jxAhX2t^GCnJ@ny<7NIy4Q)!MVG-nqqFS@O@d_WeFyK z5;6%pvotibGB%YOZcO}JTz6lw9RoJA)iM)DnoyjP5ESF;obIU;hSL);@o!5`!^l$A zoQKyCCLKDsHfR*-el>XSLj}KwCBNRJIwx5iUUQp9_UsMgunSQj-!o^q^ju8ad^AHi zFl0ZG{XMk{`Q0o99v%XSGQxj4eqbrKCz7$th5&pdqnv2i>B$SULky*bzLpDSwXt&{ za)D0eHO?y6W%oc@xu)n<`Y|v;kROi}e}qX=OSOJT8U>E|+#y|%gY=hu>4RQy`@Kv4 zoME1?qX=w8&xES*L}%+>f*ahPV}MWyh}3Jm405dEQ_j~*s>fML=J6%l89VP`F6&It zka$B(OtP9LodQ_0^~nK~ow}YD5)Poe8{Ax%f8lm1HJw2t6A~rOduvbr)PMH@zFM!79Xc)oeGiJXtm;Gi%s}`PR-^#ys2d#zF@TN?u#VS)=i83 zMNY3WR4~No=_VnXih`F`CoTBP>t~!ObvevB_grNC-5Z}^;W1P<>kQ}+1DZ~Ce2>Ign?$U{E zcVbZe^^Z({V@7kC3E=O0akZZ2R>*p zi~C4jDaBq(h6?ZbMt282XbPGrZb1Z;MvA)nR=pTVGL0|xPdAqb6%)v%*k4i^ft}xMW39HU{n*;g7wZKE@U`yO(mnBU8YAI~BHHNo z7VON|dS8QV$LaUDza1$G+`Zi0e*La={?>XNXhasn%6%w-Gg?=k zN-x6lW0=PE>F=VuS(Kjb7m>MDt$Pq6FaEJ;Az71eY;kj>i*5JR3~inY5%QLU)oS&u z)A+=gc$KfJJBx6n?*%>{{aCmh#s$yQa%D;lgmLd`gHhx305Ykk%mM|(mvua2hBmZB zO$j5#?EkhzrE$Z%KZ^>P_jON3smuB|_(ahGKs&|zOJ2$u59v>zRR8!^(~d%gyP1&Z zdN`vcAtt!c{_W$Ri^>QCjz}5(^ShUiR+@OFfx@QKfYEmxBtU@Ucv(s;#))4q1Og}o z5#=T5@A0*!q=mS}S}fQgYNDQ1tc#caaOCTs zRn;~2&dAu@Br_>UK!YN6x9?CUYeJ-Oo{|7vd=c&`E^GhiZkU_8TKhX#g5}7s!_q^A zr9{&)2l#|~iT%@uW_pYNF*3*ItsFu(_rUDLU(rj`arH3W_UTMEvalGd*)-7bSfV0J;CR4L#l#pdn+rWcwD96oq z=5OKd@wD?OSh9G$!0Z6SpRD_zyapc&E+x~A$2x3%_8=70ec9K%bZ*njH%>WvSYYO7 zFgT^OTQ?_c&IFE8VFIOHX%>Mn9oit+!QUq;#HzC5a{I1;of6HjYMb3PxPjB3hE4Q7 zs^tKo(EYpoMPnt)us+@ytkdx1c9As(^fFetoh%b5<743T-dWM~4qiqPWm>BpD<(>F zO^qEO*e^h$!mgoI5JlzNlgY6cD{Wh25nV`2O-UY-P#wh}cW>pi%2MOG6jA&!crCXm z7OY1pVR+`uIa!`Eht{j#e`qaK=rJRo_KRfo=pUtOX;d**)J^u+6E$GCd|9U&2@D1c z?#uQ2POG#Dq`)HNNrS+tV?)5qU{8rdK&EUy$?A5;S{T9GCx#A(E3ab4D z?0E9mF!2R>vr{_#qL7;Aqyr)rc?q15B$ErQK(GJ^d<;H3V~AKt^HmCz!lR?p9~w7YyFo~VckbQ@sCsSrzPfUU!p$rFal!L)$Ddc z3z#iDmlsPR+kW!L#Q>rjG5d@t2R+J?kHEDRZ*ma|MHBEt<|eopQ3D{U13<4}(IBpE zld>4AUE|e;PoE7no;fFJPz|@Ia+`EpgEhVEYQH1Shz5`_$S_2q(Rn}XOFOuG7P{VK zwhXfK*GjVNWgjeQO=q19PB&?=s94{{O6qGYU#E!Y@KhJdst+Bte22wea5NJG+Zy$A ztA2-E(vzqqeijW8pI;vb?Pi+`-$NQMJ>Acax7cqxNB1+*K(B(@VK|PxZtQI;%Athf zyuY%GW$hoEO27aeONgcZBlSDov10W~rB9kwRAitC`ufTCKL;Alf!}qs((f6+<@~lH zz&z=&nUZA;3@C@^=FNjc@LzEZb|zQm6{E3u>gLALC9!ckstQsYF9?AhhuM~_6d>!i z*QQhekLszNWn%`Ig~Wm+`hWqqv(B|5v6u+Lg!_B@nF1P1cp@J3hp_O99Egb#=o=P^ zX0J#2u$A=`s)1I|(l8^OlVvN2a-QRp#^3r34w@=Y@mg#M1;j>^ZteoDi{6l>X#rI) zHb3}G2sU#f`J~oyDc#cjPi={$LcM2fV~`_FK3|;uvar$~3i#pzU_;Bk847uZA3s@? ztjZ%ArJIV&Pxkh}_cH^y_m$?9?G9(0farX!-KW0`>-zz`o616_S|&q6o^oFaH{Xa1 z7ma`BX3$B~=EpW%RtXX%u@MTH=y5}~hh zGof+~4lGY?-~+S}-1T74PNk_O=e#CxUXN3&4+oBadzhW^SebfSlhr6fZleTOYK9A9 z$grn-*o>^Acs14U=X^ef7*3PjY3y@i_vvN27t1tG*#%~_b25ue2}Y}i{E zVxw!uyI#0hXix5HBfCMg`dFF?Eoc`z!}LK-8S-3h4e;RmTB0zQdncoR2V^YnImeZS#I`I;$V2n<|z&p5w*LqMDpPNxZNnJ^t|)rmBS)- zGX^HF--HLN+%mz&iO07u77P-MSx#|pF$*O$+KyiFmnGImMRS_BnQya5csvWTcsJ|L z1&FECN0(g;DSLT>9CLJqOkW)pw(r{AGe@4M@w&m0RUEBS8cv^}7Q1(m=$6!rXM}^4 zDs_(u+turjVt8MV$@-EPS~R|&J}QJYRS1evbI0w|3%r;ekG!dJVF%)jG|;=P7JWe} zkCiQ3A;lAUaU95$rfO?8xf_ps_NaBLgo(9a_E{I!s|xgJe~s03jBmKqj1 z9E2Bhj2*mVk8`qgD_Z*Q%CSel>Bj6ltSy~xijI%HT&!kif-mKSUZ3Drt=I&MLmS{B zoieESfgWbCGKk0&M<@oE?@Kjeg;JO~CN@ME2$0}i-mpiM=619f>-NgWp;wC}WHmPj zPxRp!qRW=m+*REM;1wB8AGbp*x+~wwGExlZ>FU4?lzH8;I4~mzm~;@$%JsmbzOmbk zv39ek3E#cxbzKf(@+hU5sD1OV=N~H?TxPSlI6}&uW!o?|#T;EvX5ZOQn*KsCTB=db z3-PJv7;;|pHklF5ZY><6#(nw_g}I`?cZR*SkbZHQsKZXyukg(8;jRD^NXK(P*F@v} z1__aRnL``4)+!&q4T|v=dbryb!-inF`Ywcb;t&HIFe*Kyka^=D}>hIU#O@-NDS>Ou3y za3i7ouO}nbWp?J6vT;TjpRF6zQWL?$Sfxsg4L3D+ujA0yGf58d8mqW{#)E{kVEN0gR4hgm(<HU`ubemNWGHiJQRGlHV$A8MI; zWm-4u36`=P&5@K6L@UU#*!7A!z-ElaL@O9W1L}JaISNCZ5%cwt)_J4Ae0V&=SwxW+ ztDc8Z+}Q&S5SBMB%hcG_Uw6L2B*@|)m<{wWA{eIJr#0MlRX1%75S2QU;snUxn*A|Y z@d~{^PdXm!V_fweww;?BY}_-l^Ea+jQOd2lS+Zq;S+tkH4y+t)>G$yD(E}5x@FGuk z-+#o5WeWST!)+)Pl6iR^&!kq0$jRX44F*@dD$F!ru-h4qvip{y2OsMmGISp!?59W0*6derirKjU>g&jNdzsx@{Xi)pnL!4+=hT`FM^%Zv z#_|95Sj($96F})@aK8s+}r=yEZ+jCY*iIx*Er@k^?BD}RX<0Fo2 zIV7T&k(<8A;vY0@l7VPHi8;8R2Wv4(3Hgi4T52lRH^w7CU*22}JWhIBX}%21%km@u zD8+h%0V2g$-@W-9E*IoB*%Yq*OwuSz)%ul}U6~p`nmVWjp_>sXKkHXf63-tEOb{wV zX0z$Gy8ON>MA~s=84gCE{{dBI3>E`PCQP*`+eu$kBaA?e{<^MW@CmlF)AE2!e6-p zMos-%K$>$C!H)UD*1k;PCD!4Y?EW&~P3d{1X{(`ST*|0f0s}oF<1xb@l!>vL(moVrJby56w8E$3IMeb?GSW-m zcx-?Lc^E{!M9{xE}VTf*=(wY3wppNPZ< z*&XGAkJI5ufHxBK3{w`zu66%lq(bD06jWe)%CVi{w{~vJU)|MgsjBG+5>DHg!*?eP z8s@Nv)k^K9oyzG5*rm;RfQ^vjxk|mzz#Z9D_M!1|U9JMa77^p@TFtY1c*xOoP zX`4JB^gYGf}Sae^spdb;UEDZLF+H+{A2s`geJz+mQp>Q?+ABO4= zkVu3b;65aq2CbF^(B--w9%H-a`8~?i-PU`iXo}}ZX(s~yLE(wBd209T5OV|3cVtD% zlJ+>KV(Z?n=eJk)>ueV4B&K{c7W1r@xB+>lhdV!dzbGrBDn&{`+s8N9he%L?5&)S* zx&F+ttLZFMrz|1&#PY~jj4q5_oyX(Q+T{Z2^9(PW1U4u@x$Ea=#@k24R{Xw+**qcD zM)5qh8h=X5P$+<>+Rc0lzku$f-s7zg4GOIQ%QkdqHlxDxkKi<^(m}W(Bto}<4nH21 z^b0lPi`rpfd}{U=x6}%%D=~hg47-LwBXUtvFd#S#Oq9X^AY%?Jj<-0~L!lP5rvug% z>*ICxq+TsDubuF`qMQ(%1hlD6vag%<-~tJflIwpG7^0Z#bkR&(`Q57mNir*FY_s@j zWx*d7*^QvKir{IvWA5um24q?qHXS6y%C3xfHu0c%tZAEAAo!)pj%I15K!5L%F`v#MbK@ zeODSU!;reY>Bh}f7=S=M&d#9nI`?1YJPBzeRSeq2K)r#i?ay_!ed%cI;gLo6i@4o&v7ewHk*0rY`#&NP zw@((>5@UJYFp{{Z*JO3u6Q4a12O2oJ*`HLC6+PFKGZs&eNM1L3sxmYe1peNnMB}8B8YMu9HtgzgFhj#-^8sqZUcZj$ADM;PPDS5gg;W^!G20 z2wliAdA#O|;p(QJ0E;+XtDrHm_o4FdVt1*qIsF1mBWqMP%x~@<&-IS4V2(@^T;1|4 zgSE>h>t7!ibUu+Y@q2nH9<-bk3lIXpoDHR~<7_X7ED;73+&_M_;XAM9z@AKWpG;d2 zqt`}uQ9jJO2f|vrj1wuBfJsvX;?~Jx^;^fu>2w-;kvpHaw-^(kP)bQh^NU`73zW@F z1vKuM+sGp7v$i!h5+Xumej9sqTHA|46cYMfj1~TKTjFQ=>00``{m7a;eb!UJ5?b|F z?`AIp;^)COW6SE>wO8Z6y&uj)Wot*#G;-F3bR%(50*X_+zd*~Z+3KOHCq+qonacUA z<@Xk^dUN;}XI{0M>ahfKoDtg%J7+(nM)wwfH;MwD z?`}(u$R#}2rY^v>NPQ23&BPh;&=d`S+p)DcGyt++FKVYyp7}as6RgZOs37(AVfknh z0L=3F&db_0=jPZ~>*VKG9-aJ}z0$S{*Y}ry`m;xDgQg6lxde{h)yly8?X?rUkCqk6 z+{ggp!{$g0*RsMx-J3h1Wmz>8jy%Cvg`2<7?eE=-1uFWv}%Oj`4@9kgKBMqv2x+8pzvkek@3O{!falq>E0U$8A|DZf_p98(| z^r>_?li+QB{rUw#0x-&HW2wvigqx=;_fL$|;E{2;75IMEB&g-#9{mVUkNy!=!*N9- zPHObj^Eur;_g{;z71;;AhtKXD?KeXwd1kJ}WU$Ux^{UJ2RGDTDI_}PO^(>Y$%*gYt z&dfWL+}rimUb>ZkDR&Y-_dYzic0aE+p6m`D^&>^GWqJ>f_;e{L5C8K_o4@|{8V3)4 zlusRVZo4)`Gs^RLX_h8&{H4{(36(Saz;-4f;A#vX9?pdMRnlR6(=Q43347MrV5oTf z2!0~WJ=vex?!4q%g?lAKc>zN`+E*{5`S){F zVB(PN^7(Zc^OwCYZIz^a(zA96bO$95yq2L!EceXTeq#XmN5XAk&w1};{)r^BEKG}? z=c-?;7NDpuH?=-pQDz07EOj*uISs-=JFji~4!`~6U47_~J$$^D;Q09uN2I3eZApdn zP+bj&!QIU`N{=_rN2UISq}c^>p&tdvEq>_#q$?biD>q|G4rGq&bm=WB>m(E09p{q^ zY{xH^HRV-#r6n7bggbU^s?~Sro!?qEZ1P7`ZcnErlHY=j_i#~| z8tM(wxII)1I7<;W6Ix^1sqw3NF|LXX=<2g3eCY@xEUDy%Eg(MgY-~*O-`tlz$u` zhj%>srCq|jM#&!lGBL5%f+O2wHI#DzxZ#PpQtvFjcSvTdS%#fW!}bMN&4=-CqK zsVO1pD3Q7<;Slz$KOEK-&f3#K=^3>O-zYVySn*SeLq3mz9t${ z(p-P0g6GD0WXa`#y4o=~yV~DeZ(webFa?SXf-073yIZFFEZ{yx%oJ|@jXd~r@cZ=| z5>FN9SCjW!xaJC2!99c%8OfYgT*!_*SFC%YHibTWJZ#p&$mSf9MxN%R^PNJe$rMw% zY_hp@Ezgh1CCuSlL4}I7-&X+lD?R5_U1rVbzu4RI0CI_?9Fh1j8qUy|%%50X$>^1RoO|*1oDub}4vS6BfKv16id zEgXrEz|#}O8~`*>KL7l|G`pEL*p0u4?Ngh_ROI1s65jtdw}$BaCBnV1-5(6fXO^Sm zXsoiOfQ?!Sf>|FOGqN9CgB$~bIjwvDGBunu_mM*pbU0@C1!jSn36N4Uxvk5&x5c=@ zF`lUA9`k1VyHD<{l0-N0?@j{c&)TFlh84e1E@i1%^1yP%OrfiXh<{pW^oPngBaSy$WdQzsB z##*z3lZbAt28_46OjnxsWr+-=&fax*m*wZOi*Q_(98h9m8pGD#H#8N6l7%Oyy>(!=!&~P!W5(_`zc1_1j|a0I$0bn zq`&`Neg1_@YONvrudt1cHYxjTVS*I8fWZ_VI~ zzTd2B@E>sq!z5QOhx7H)+0)tOxDE8f;<&&Bp5k57Z$Mi2FQ;lP>w44Ef9&(GZWKk4 z|C^sJ^8}^$)K$3Rl!GLLl~vkz5E4U;1dJ6K0r|N9kgqv{8(OTQ_|l&K3an-W)HE3= z)$-4VuPOJ^%Cf18UqAg9T(cahQlwA;i(eFO1Q~^sE7J6QXcf$Ct6<285w-7L_KKRn z>nPc%DBd787y0)6rijq}r)QIe4W|Jz@FFFP-dHD;m0o%^z^03HmfG?8B@1B9eQ2Zh9;E;!DGvGfshU%T%D8tJB7y z-}IZaN&*m=b*RbC=WmJK#MsI&pm+au>j6qC+(b8AM!sZObKTw$jBbw%=hGoCqh}cM zqQ1rDoeI{+8Ss$e<8gK5o&}YYr+&{qI{0}=287wnuKTAt@jr2LEX@0n47H=B=1g4Q zR$D#Y(vNew(~~R=|5c6m+EqpDrYiixPNS`me9c%LCvgwwJbfC|rWDFL(-pSBLIwBi z^4>Um>HcgwEqaeuITQ z+kR3K&-Dzy{6Xgf#OU~|s$|i&rzS;eh&>#%qvjybI-3z68=MT1!S*pbz=waTnk>=o zP`~RIgZUdCzFhZ6D&L@L^Y(?;HeLG5ld|DDEQ^zkc3bQ(YLO6#kA#H9{?4p#{Nn!% z(o#G&dW-!$_g;Dkr=9e4o?zxQ z@FGD-*Q#1bZF92fgn`Ft3Tp54?wOm7U~R%Gzxuc1f)nKA!i@RdE(^-P((n>!>#8VH z%NH8Qn_u>3?wdYsompvL(N?Fd9TSYFpO5ekt4~MLa);uIPEstpSj^|G+Z_C@w*~e<@nXna#W4KaOd((0}mRfAcg)fy!Va z>$JsnNtkX%f1G&{#Kg;#6Q<5(ik@M-HwB{XhDP=w=3lAC7wp3u1nJW`i7#3YVTJc7 zeueOnMAZmhJaO~;uhi{4H&s&p8 z)#vhDVNl3JM!^kR)(87zyiRRnsswEs$MR~Q`Be64qno)3%Q$jk9M_)NSI<$l@B{}L zV9!%rY5bNRcH{>3Hgy{=`ynWavWb ze~b07h|sA<^kaxE<_N7@@`fUh;a}vW{v{E!?QU5ggvZN$-R%?$P|$%Wc?S|!~MZRaO`#!w3;c~Eqe0Csd#GLTui zT|SKa@hFkDSDGY>*xiWu?iDcaKbU_6tJCFwRD{t^>jr*c+E#yxY^1PoR!PsmN3U_Z zSOal=F6=RFUo-#g_)rdBN`6*Z1!{F2qd1s2cOBwLixyq7snijWxv`_>ESH(T8%c5a za=6hzT}m_U#iE>nL;~TiEp1(0{2vgP^QJ@j-y9Aft4C%N%-qb=lyvyT0R=JX3sPds zX=$3-sSAN$G0P2@2gfd@9e%(4V{8Twm^5Eo(P45fa$7Zw$xgu19bs0$(6*5HMjeUL z8dRgFCkngBmShq50sh{w+)%W2kSl^gVOhF|t_nYjS|~Nrn-{y?&d2Prj)=`s(=99F zwo@eMYS2&Jg`xTuPWY-4=|WJ2kLg*Wh^FDSISrkoR~$&|3+WnE?&iTGWj5)QLCjZavDrm8Lf2B`Ck{`cQ35l2B$p0^oe}K z3FTk0Bxo6RJ1Mdq<4HknqGJR}8ahYqui~M%7+w{PywknSGkwhNgHH42(Bc$qBn;!n zb`SR%&x4N&pQcwcyn2bP+{8hNXuOTD6W(IijegjIRqmiZ+h2dR5-WJliU|@rm$efy zsIyGEpSjtRi9XYT5=9CuDo!2O(QEfbCzuen!#N9l`q%HWEfK8SmP3w)L*ZlI(>E=p zI~hal-y`o#CGfIA!x3Tn2AJ@+!FcpV|DR-UCYoozV=5Se05KUm&_MdS4Q*ccm#Q9Y zq$+oGSQiB%YY(GMd+)Q$h?A*d(pkqYhvo5(jstT;r|tqMSX#sFv_9GYq=5{fd%qid{ql!S`bu2s_g5Yj#9A4`Y-m4O~ve^N6; zi!H~L0H=f-FAHwBCY|bz3NgSIop-_Kad$V-F|V2PD%e?Z zZkqa9@PnqqQ&M=9G0B4EN(YOw4P|x4nR0N2dwe}9%mDq%I*yhiWOy(Qv$vz=fU1;| z5rGkxKX^#KsX{BFqu1r9K33fqor{98xIph3R~r9)OK{N3mPh!DQM@<9x65Ah;PtSq zXD_(NIkh(T(PUd&iCI9v1S*`Bgm;wZy`^n(&~mJ2Mv+$s{4qs=$7$lqW&2)+^UA9j zlfLEXY&1H9BE6TcT^q;CPUvF)O*X51_3WDK z746ktiuZQ@)Je3Y_Fl*8*1g@Nrl^zFepCG*#AY(A8hHM+z~gPYb(_E&%jIRs#ZJNc zw(xs(+g!~>_l-Q~%_$+S?EPk|oNDC0?bGVJXNPcFc19cLv!#h=p`@L@@rW(5qX|7c z|BK~9-y#xw_7bQ`0Q5cu3;Rr=tNr6Uc-l9-zW(!6?Dq3j0->Z^_7vF}efL9)0tmV~ z2s=M#zQMsU*+uq02<#bpBLidq9K39U!b-X-gO|yjL?S9dZ;mHjMTnhpZCZ{+S;r(e zfnI#F{s@f&sWliIa(x1b;?H_Y7>W^nLTPUg0 za4#+cS0@wcGa@y&lH0g=4wktQB~cmN1=1=l$NK~8y_2894`RDv_*q&nw?PX{$ilJ% zzAGmuU*}b8+;}RQuBN)Y{Q0>-5fAHG*OgfJWnsj6+?Nk|ZQ#b^(^5b~{>ohLs54vz zlyTqfN)wz7huUd^nvS!H&BaREu8$6%IWK4g zyhP}CXk|kVDQ5H)1}oayovv&Z*DU^w#$P7|7b%6Vg4MEdbN5dF6MA)9V*Z{j#JyRI zTq; zshPhbtm3wmOR|6`?5*Hn*LWUbR5od#g8U4{==@~UKsH_)y0`sdrI@j{dE&U`R2V6a zHMvq@chb?m+{4tpS4+5^tq$`rP}a3cf8(fUpE~Z0^GaLjqR_pW+=|cjj8SFc(E928 zkV=MU7N}?9VVTARwIG~TEJnzy3S1!k>+Xu1an$B_WO16<7$wm_Wnt|bDClhb5+DgV zoma=Zi_$R~I15(TV7UF?wx`WS$}7&gHOZtOd=NJ8Ip3@sJ8xj|08zi0RzrzUgHBFa&vNykC){5y436jCf+d3rD1;E}DILe_k`nWiN z4>Zea{#(*D6l67yeps_*6Cfb36rEUOS;hh^c)F^Ewd;rU*gFlby#XioSgE|Z;s01N z?aLbmJz&}R{#aPW%YwEb`0sLjZqwEdCB?~+JIBbwC#ku^E@XYEms_nT<{iAmir5GnT4xdlI>lIuT7QIFsXgMV692QD+Sk!8gF}i%SEivS=KVGf4v40zh@@2#V~8X3{AC- z8rZy5VZdH0(sr{tcRR}ZTw2a&3{hk3Y60~uc`%?5PKhR$?DbP(lTs~HnZj@0Kg^+_ ztlQ!#5#{9QV(aP-l-ztu@6-lzm~exJgCXUTniEUBfaD( zXMFSGru5b1MQP&s_0&}L7t3;6Y9U&#^AOEo!vzXLV3-{UEnc^MV2v)Po?K#a+Hw%J zYP`X#$*EMQ{rwj*%1U#3`5_KAJ49NR-SO8@?{C=d{N+u@((9T#D~FD}eGhXO!8SyE z>O@lv#?JZ^qmKAXsmgW-8SrwjtjRY1&NN{cL#(MAtr&m_+P$z0+xdthLwt)gLWha{ z0FVhPQuMnyoQYmeS?@tHTN6iR(T}6DR+(!wJ%g79$@Rivd%nIl{#HdR>Omy|=KriM zbrD-1I^)Lv>1_XfAU}xS_IbQB=`O~(%%p0{?_l!OUW#bw>A6JL^e|hDgr=B-A)Gfy z{v$VPVNeREE}iC<=QDYz&8*Ds4g}Bb2ooVd)Ha;6Lo@BL$ zJAZu-kf>XE=b*M3Hv#k!J!~(CSVp+p2`g4{JpvBfn9=<#%$2zDgRKk20ziFuW)ahv zcUpYj+rfUp)1mbuyGL>hd_9@wmIV`d^Cbq@&__=!$^pT8P=W8%1hqev9EEMs*hStB z`Zv*#hVdfRd&NKCQ8ZJ>02zXhaGzbRVyRAOA!KhY;32h|$T!mAp*mA$KF10tH9j@i z8#2GwoLNGL30#aUwdF)R57U&F#sU2eo28vePaf299PR>IG0L#RA{{gP9C4V22S-yR z#Vt0PNk@$DI~tc$wcM&QYc1HoNT3&9t@kct&RG53-R_EP6IniCBElB6{We*fqB0#= z3Vp`f#IFO7)j%R60wDqvH8}2xd4&@Gh34BXAC2fbtq!BR+mceSQbM}*(TTOFh1a>S zE2*9??^r}HHFk$Ln=qmW?Kg@l=BH^th`-@!O#wbV(|JB+s|mMfNHWK!o>`ha`(eZ6x!y zhcno+*EQdUUq;n|$?% zSDu?|32#E_IvM_pksnXs-am?qdy$<_$9Ls|7n^@1QTSB|uZc)y4dA2E3ut)7gOBKq z9d!Jw4bX5$!!)MY0bg{<40raIf8NcrzfFo#pf*#l{8B{5(?fEMT_LEgOJ{3#IyFR% zQ-Qc}3ko%1dP(){ZU_4iW7n<@^FJ7!?v!_@+Z;QJm8*02hvrd=0(BiH`a*7J&uh~;H%RE>hu1xyYN^&E*;>0w&lVO5?=i1Tz!Md8+=m`MrAgWe+nwn9Tp~I zV68VM)2N0_otvD6lxE)HG;j%2i=wdLPMj+hpdDkS(WK4M3 z%4i<^bC8qfD}k|~M#8Eg4~+oH$4ms6 zWX3m1XQ(uz9g}YzzblBBfBkH(vS@EXFA&T>Nh)dok>(AzO;ug3TI#M1C;xsb#f-PZ z>*hX^k8$}##N9|KRcA|&4u*|7MALVF={COevAd@d^V%JGL$d5W)lp$6mA^OFhLMCi z>HSg2Cezy6J%aC3Iic)W4}u!kWJ;Z9Q&BJ?53d`e!-TNm7u;auj@k(lr?L+pZ8`mK ztzRf%#+t)J8;N%(G7CNz`<=-G6jw*(DxPxyEfS-#{K6j691k4OYthAl)<*EWYP$SV zH)e;~Q}(yL8o_7%`;u>HehT5sHPf$m_Ss;wD(U%3!N0ujb3{q4o=vf&PUHLM=akUI zAdEa?sBtJsZ53q-DB?t((a|EXus#ls`5Xg)wf|fD*fM^Vf!QCs+iV3J9*MKs)#Ypc zh()|1sE*#n%E|hnxUJ>@>L{LYUXRQ$2{s%?=7p36o|dMEzQY_+5y7K8Uhk83G5Ez6 zs;Q)0UbWN2#2??zng`e0uG{S$5WJIj>E#|g2cf`xV6zYmnuOZYO}RJbsnD#vURl-K z$@U7y<>1m1Ju%elt?KVycCy;9`ooZ~YFK)%>ED{pJ{PUq@{O8^Efv1X4mQ3zIziKF z&DpMF!HbQcdVDrfcQko*8LScXrafF%c9>01;(c7cg@;&_yQ9-eExkWu*rw&W_+FUD zhPshl+muqvVmnkE@DO!lj2JcR?MVdhb4eE#G!Co9vo@98sogV?@h+7+IHu)&+E`VM z2?ITymH1dV*;GO?&CBDGNNlpE0c$-Xo|B(|GwJ_(gIo@;ZBK24y9OM%(UCjH+Yo^P zr0d6hSlX}J*3<8%Qyf1>A)bz`zxs?5r`V(xg5c*$nv!+zi(kqS?SYM2$Du(xNj2I; zYbDjw1gzco4N7x7Vt)QiQCjxdZ~I@0QuuVUCQjnl@R zoLghA;(5pD_K^aZgreMqLW_uh8*J^T0g0xkPZ(ru4auBzF2Y8-hf%`0et*>H# zVg~cc<*=GArID3tU#;<&G67?h=IJsiJIb3R1x-~;QP4{lg}U7bX($05w)59`=cy>g z!8Jtr;V_v8-w^SiyBAeL1GVN|!cO-jrCcQfzq~iTaCq+3XN0dwG2?K)KO=VYy&QZC zl`O11zIop~qPlx2e@l5Cb7PZO_q-W$@b*|O&=s2~g>m2Xw$-gFtx$z!Ma!799Jl?u zZpD`~x^y1)w>DSG;qgS8_HED5a%|n za`zx#A<$Yy{#dbV8R@7e^(us<$wTqyIXq3K$lp@ecuUsL<%F&VLs6Lo)u`)UiCErb(E=%9fa!6A{IUcNlK<$-86FMc*4sZ`>t{Z z9Engl5n=tF>rQwpl_trHfjG;VG1Aoz8tixwBFAZ+!_6O6c`4fyIT?25Q`6yWSQ@$W zhUcCMbDet~)5|`E#8u9;yyvrE*H+zBYZ1DE#>AJ0x3=DYR54uGb9-29-)WA98i>4F ztiN$)*5kBt-L9Xj=4yCdxO8ak?p-)#VH&MB>QSn~5uWO%LCTU~&vpO+G~Yk(1sHyA zZ|Fcv#L(q^6A-y}v^f3q%yE&A5?BGJtfKu^m67k6G}5-_>$&uYBTUonI-|NXnw!?I zP7_iD@rm?OI{LdiZI7ieHvcdHVBeivHO#*4x&OwTQBg|_Xu@Rz0~p&J9s*{Mct1*{f;l^QFe^Uh^-K=u-M@fML9eKu&k0LnziDB>5R3{#j zTFwoeAMZRMUis~Nz`8~0Q zc_%0Ax}2l&?Vnp!K(*!SpO%mEpFeyA3V;gfmv`9&VlcDs{B)Lp zN$PLY_RSLns`(h-xFIRnJ4?kO`SPs(8&g7q6pU9c`SizC{us~wfC#^(MvOPcq1|7YfH;Xl|$-lWPrFmN@ z^R(LRbDiRhpwJUo&+)da_ildep}pF_r~Q~FAGPC4lIvzx1(CMJb`Gw&hpXHxQ++iX zHkvM;x&8UE!$;TO-@j|u`RF2O;JaUr4O}S5UY*43a=u7I`bKx#6L<`2Y7*`-k>|X(l}%Ce=Qin#rcp_VmTvu7mg2 zNUiF2gPK(GfhBkAnpcsDGpFQc<~yYnK8~)11&-B<8zApCzPPtQcnioI7Z*EpLAS~= z?NieCe*~QD+RFK-B7WN&(-clnd~{5A{|($vu6z2t{wa%nDSyH}6Q6hYwG_ttp933J z!O8KXD@7v8y0Z0b?1g@nGZg{14#tAr;;<)-eckr3^YwQ! z`o;fdDuVQXy!Ap#cgYF+Eh*pHH&2^ex9-iP=MafW0%184Q(c)ods$=~dqFOF$McZ) z)~P-Fncv!J%_@F$OMh`r#ECl{U@6W-Ue}HP65e0)xH-)u+HB^A^&UWfIw-^$w}|(z z@IJ5e^Gi#{hw}DoeP6efr|muE1F>Y2fZWE;%Y8>VdzSzGaJ7X&U;VO}+yq32L8o&1 za{+KL@Hs?mTnTQW6h_NFdbsHL^6xTs1s~irqeMGFE-?3E4{HRT$+A}7P8n7~r<8cE zg9MT%FbTx03}Bq;mgl?q{J1l85&2#`X6jMwEDRGii~-FY-?Qt z5M_Qw>>O*bU#vR5)#kt!roZ5i6Rmw^ZLep=1)in7E6#N9@6q#{xm9(Pxr6O^Uz&jQ xloWGR%Yo-^ALTOWegis`w8L0%p5OB5f17-BS8az*6Yv-s22WQ%mvv4FO#q#=b8P?s literal 0 HcmV?d00001 diff --git a/pictures/rootdynamincoperate.png b/pictures/rootdynamincoperate.png new file mode 100644 index 0000000000000000000000000000000000000000..75fe6b3a69d77d3b73eaa7b34a46b0c7a02aed44 GIT binary patch literal 17682 zcmagG19T)&yQp2UoryIuCbpBw#7-u*ZB3ksZQHh;iEVpg+x|1(J@>40*RNi^x~r;p z7k2HJ&$}x`PDT^~76%pp00eQd9|`~fO8B|#2Mzl9nG1fN^!Wwm@Ll{TG&J<;mh9ip zRcuFLRYye|V@DS~dn3Ta+Q!O=*1^Eu$jI8k)W-1wtcwo-hyd{)fk zGr6v7jnNola+*&R_n=CA|4t|_p2<jtsqCtn5Cj07z*Qv23$>#m`MUoxP8kD0(&{8g1yD8Z4z&n(Zo%?|cs z!yg^TLeuGKsj=E*$Bc9sf(8^(A(59gsF+%BE(cd*$^kij_g_$Z=jPV@1MdoHm064l z)*UJY_Bp;eOWoQ+*-a#XiCQ=Dpo!0@!A1?$sjX&7tE}G+T=-QS!bx5X(9M+gDK4(^ z3`E>B=IH`JbA1EX&1*m!E2-Pd8#&Wjha;7&_0IP9{GIYudV8|;I0-K`b!%D*BCeU) zfti_!_1?^^G!11i>v!wGBW$WvhgrBjL=Z51)zl6YVU4SZSID|-Mic_)`^ZeM%<|B& z@N(l(fZkz+d1`skH1Q1-v|Wm_;qGh3oEXh~PxxLS!XfeXT~yo&-DpV$tT{ zoC2)p_J8`-LdU)q7pWna{+lYjOwG^6gVS|q8FVJ^Ze53Q8)>S}EazuAkAV0sJWdNs zAA}C}8)U9GVijUn$~Nz-D(^a}fp+G_v;Ytw7#8vM;*fW+h zl(;OT&eA~$=ie{-5nlF?)k3sVm={#I`+0KqmAt<;a`h6?g$=eV&&1QGYm|jU)V|Q# zGcB48`PY2q38Wql-S^G+FW+u+q9uliUS1&Z>J^1*u^j@kO~sZwslrw#^XWc1*PL~K zX0zOR$dD|v84l#@Av(eXeFY!yZnY9*b6@Y*7kN^UcJmZe6B3h?l{MF?!C*&c`b|uK z216ymU$^>4xX)sfV9;Tieg_5QST>fPWNY=8EN(>AB55k5rD0_yx-<#Hq8o^AR@d})jJMXOwcoESRH!W|7B$5)k(~UeauUYYOj1pv zXV0<*M#(p2)&j275YNIw5i&&}AopjAIScjWN5gS^UEK+G~U0S z%Wku?p1kbOwES1FbW^7$>wJtYYcC!Wrb9b2hjb6mSEwh|h5dMau%b>rV^!O~fBwEV z;&EXsMrnn&L%yVzsx!eq1{}GpE)#%Qix`%olwCO+$ILNKWk`Yma*g|1!Ck#L1g!pp zL?CpfLlf;9Dzw!|X)J6^ODLg=iq@l=kk0kR*MaHfIF*Y6AAg9t-YYfjy6{Yxe zNSOZil#Xe*JT3_7f9Fs-O5uEv64Jr8RLHO^TOj{47#<1|%}Lh@_6p_7Fmh8`Owf%~ z-u8F9?cjkxs`B6w9*K}~Xt6hTO-|il`$$g$WcV#@G4!$Vw-A(L_%AV1J2P{6-f^;_ z!FW&!L04mEBcX&oGUJ85X`zha0`VjTb*r~^sS+$;=y(Rvx=lgC2`&r<;krgSzKFcA zVfDE+wX~lG;tMwRJnh3di^Ci7fPVmZYwET_qF)Ci#B7WPsRtlNTAf@0l?Ny*j^cK-C`|YkMBIv`aK7YyjdQX+4`r%ZJRziMv{fT z`Bu%!|PKW@m*hiO(VihaX_RC?kUdSicR<0Y(XM}LP)vRSr)hS99cf(eMTj#rL zJ7&<0xn>1J|rJY(5)7vb5nQS7s|=#p7|P#!JU3GL1t#X?c; zX%HYOjEqALJHGNZrq~gdvL97=5jty+pS*88T<~BCDV#u`ZcLUI<1gR?CqZ8@C$~;9 zhQm9wIy^kvUjtIvxWCUP<3$q0!N9-S^)so_zbsxA-mx8Kh?I)2?GER z^wv*%xyLGKT~~Djtu9iYR4b+CUy>u*qz7-22kIZH{byE2oLguza#tHLw^`-b`+i#J zc-M`cuwOv0cPxh%u8on0zWh=lk)Aiy-((c~L-~yahXtBc0$>7se04HYlVi2CSHH=7 zXaDSMuItWcD#nVYgvXIf`3Z!NWcx@FFY=Fug_TO;{>EkcqnSq>H`J%X#NZ%WhgfA8 zS%H8iao#xe7G7LCuuTmyKff5WK5ZQxeyS<;wV_;%z*K4$`p?Q_z)dyBXJ;VlweVh9 zF5H{UDzW>&nwtshs0OnVH8&GKDWjEn$GaeHe%esEia>wnVA;F-o==MusCG$XfM+&y zKccayP&b)w_sg@iixCEhSBQb9lyW-=2FaVkHZ(;Uw(Y3w_(6pt26BjZ=g7QV?_KRQ z(=ryzHu?UVzNQ>_z@gp5ha0lyxsmOFBIkB-{hNe+uQCTEZhdT-B{ui#+0e9p1PHjU z>L5SX!WI2r2~ay_2_-wjTZV%Oc`QeGL;aS(y(lSSC{(|VFS1M#635p9MLtrLil9E< ziKBm)UmgZtv_g%aiTQ@;D`_dQ2h<^{h1N1YkTpOu+%nZqmZmaWGkWjdgr3I!5{ zjJhMstuFAKaV_a3ca@_ZS+2rY#C7Ti#G-W*HQ-};sw*A1vi(xJhxA8yUieO+VcU+< zO^f@F7&k77~?#(+J}p}37yNLM-y8v>Sq<99%1BwoPCsq#YX zm&$-8u zW3jC9>v6ssf#dbfc!Gz>uFm%Y7;Rt&2 zzyMt?EpDQ;OQ~$i3*$xu4u9 zW3O6>`-RfI?%XjPx+6mofnzFbHr5e8J#ia(ts4gb25rKKH5-ZT-d#k7*>#*+UoFjw z={iUdlR4hMh8>DZR3$1LhH3W2ZSPqM-+9$s2j0fRj!`*hKao^k5ohwCGk?Tbvq$Zc z?;~V#MoT(CdphB;zS}Rf2$=!!aFfwg)7=aB2;_ycN)Rb0gkQ8h`S#XgKz+`+X#t#> z2|S2DhlPmeddz`{9;RRv^E0CXDG3JW7sF(0DFdq31{8srkzMUiRW|~R&bKhw7v68b z=olw!kL$RRzBtQ#BRkzl27psRX3SFO4PE%6LpA0x)VP_-L8Bp`v0B?ZY~yM9w&DHX zaV9%SbcGZHdpo3w4U@sx@}295ciFAsum*d5gtA}szHw(AF4>ygDWJ}C{dxw?+m$q< zqNwfTkW)2otjq-Y0WS+vpkhJA)2i8rwoPUwe0N&d7f?X)&ZV~VaO_)*`8EgIw+7RbXUyhfQtuza-@lTR8ozj!K$-_rgtYTL9d<42*M^(~m-L?9p0$5QRP)h^+i|`@(9Dv#o(a*@se@k!$;$OQ!(Jp7R2wb85 za1-tAhh5698&Tk%=qtB*JOKP!&(uqujL_=Ec+H#>+kMPiK+6-u3dEk|Sj~0IE`MQ9 zjnu=kxPH2?TvVTs+SA1{=A!7-nr$jS40^}0FTr>l{I(e*y*sA*slr*v-+8!)0t5B1 zdaZ}rHx*O4J&zHeKo$|(7xpAU1d?0(8c)6s_gVG%ZdT6oCu8##987+n*QR0(emogNp4=^Smu?7@$RVYWO`Hg`}I8QHx`C-c8!Z< zBG>W!tgs{%@^`g13sX^XJ7dQW_?)v-aFL+ZU?J(i5E?sw*E9@xCzc+DG5vSe?zqHA zAHLP_mxfdh51nF7i~kkwAaikQpeF(aANJ6eNHa^WFqb1i|~SBVn4F_bX#>CaKw2 z)QjiY#Z3^#Hbl|>%`LgA`t6HswJ4 z`Kr^%*E9$YM;Ira#+fE>{MrlJ%0ET^Age@8^MQD?1%ZFaxS5Ek?>dlKTHGexy{5T|AFnxC+Y>0?QpAv82r-k zA(GN8jcbB1CVs$W1RcBC2w6MHAqxaO*ub`VNWyhpK>dBQ`u*dsDfj%6#uCUP49kB8 z-#Js+PXh!0m_`vbo0feC*em^7TtFH#)ehJ411Vq9QH(5ZJh&tWFUs)0fyFom40#`)NC#UV?HZ(n_qOwhx1&w zqDR0!i>LMEKcmj{;AWCv<)gHC85h$G1 z4?^Z)D_qD(J}70rzYGSH?rj=t|KW8buGQy28fQNH2bb;`{+muPW$$&hVW+w zk9Mx-vA-dgZ9TVuv{%JO39;RD$fL+*2L37|dJb2V_dKroM1R6PmIwWJFXRayN?D)4 z*yqYw^pK(<-TDk{(LsiA?(=YXSpEx9m2m@bo62*$#N929(NdYJlwAwKZiaC4FAQfV zaIC2&FXk?137V-dr%E-J(=A=7ICg;1TaMkgF}-C3y#u(=<1-SfZa#V z-uvQ}VtB;^by(Ju*-{ER(3&$UJE^Ia`?#g!SEgEaJ$ zul{~nRPK*>G=%g zUey5u4TBCv;oQ(M_dmAx%30hHKP?Ceu&J3#-K>w@q1C=xTA7{a7f8?DI5w8ow8Q-Q zT7A+!w2@y71wC?xNa3L&uV!Ypu#aMB`+n&mX!h^*6q3TmD-*+mW#V;gg0j=uYJRhj z*bGPUk!fSE=j6Dnf_<#4lVowR3%bfY2eAvWIMNT0jvgWvr7B&#F*j87Drws}_9_Yg znR(jKa&^6$jmR&ckTegQ^w70`4@=S6_&F${o{=hx;OX)<(HxdEajtrl)#WVpcwm;1 z3R~4BozdmF*p|rdopM9i?GE+et(*3`qjDu(nwW{!P}N>ve|Vh4yFpc8+1hM*IfR5r zW6;HE%l7_y&RVluHV7*W^c^Q$ZmUqNc}dxrSG3;dOm_yvNKTYF*=9k?N!61lh8)8$L=$3P=W2+#laEAy*zP$ zM5zZ`Nqg|PS~3}6$$6pW^pd@($J$_I-hZBBMD3bk+<&P&A{BppSZomE7*C^pgGg93|Dv+l_j$C0^ik_RW1GzbgLZe{X8%eTRGeASvO*kmhOv>gedBPeau5+z37tDk z#hxWjLgq3VsP9)>{^bFRCS{yqrXZb8brL1L512f+V7yhf?(s1&7gkD~mK-Pr(6`sD zfrOK1nf~17h?IowJVS~{S>+-(A^nsV5ImK_FfM&p(p1PD0@_1Ig!v!VITQ z%f19}@NSVt{u!3Q=M44kM@s!A6d_T7b(Qj8j>_U?!d_s9Drg?f@4D>+p2R?iZR4z* zJ2yNk11R3opstseyNlOmRhJNKTN~tNP9*g62IYPA;Dfm>;w4Lp!+2 z0`J9s8SGZ-bPOoY`MW(p@0EEUI)67>28E5Hfoyb}#hP+;Ltm1qW95_=#)^mjKz}|7 zGRm%Vr3=)3#6!pNKb%PxyPI@sE$WsZmI?0bIK58bTs|j)=|JKbQ>n`iIo~u{r_8nt z$m(Bvu;ST#v)`dpcsuUAG@aRuvz*Ux0;QUXkZJK0)JP|DsWc890xLpfJ8NcL_BdqW z=Wshw4&t85tzcQxkn0{&Ctd-O~Reevdtv`*?71dc;SUtq;wXroe>(Q z=c{3?4B5uq8ep*9Meg`}Wq}#k`=>glR~10!BsUgFdl_n=iKJ^~Sxi*T8@^P#?7ls{ zm9JYfi=MqxRdX@Apw*2aybwVR>qox`5ju3IKkHn$d@fVYFdy~Wiac}3Fhx(qo}68c zk)$jjElgp=_8;%5R3mH276xZgL~~2xo5QcIIjA0*)>faGzkWX*`p6B3a6x;2m|oN{ zp2SV{HqJo{Fb#FgQ?%BZ!Z3m85(K0i;wEGX43bl4a`FYUr%qNRcdb~@08MTu?OC3E zI^5U(*v%-ViDZ>JSJ9TITiO_m)TbXgE?SuZdRUb67M`#1vONQ@)S1=$QO!#rY?h%c z7lSpkNao)l^hrOh(h!!eAu6N*u|czf%wGi~VRvaISS&Au6)NRy0^$dBlcFb)|c z&g`H|<4X+&GDs^JSAD-~i&SgZgSdJNb8!=5TN=T+7vQsy5H&xsOhgXcMtnWD63h%* zoF(gX$gsPDhOrcb(xO1*YBUOo`|1jl>$@|ucT=_?pGZSIaoKp80zf|{nAi3u_O*=R zjGu>R4c1RS1`HiUaI-?)(`+QtR54sNG!u1YTZ*k#*RMK9c*PZ^y17IR)Dn&jTOi7U z9tE8u0gUrkb6qQq#Fq3E!*g$n_xYsb@TSY8-o^~F!FLcC8=FlHYo?c;b9&J-o=b}Y zNcAFe2g`7fW13VW-OsFWxL5}&D@&-|-%m~u+W2Dihs_`c@G&>H0%v1J%+Q{eW!8*E ziCUEol%RJmqCc9abD1ps=Bvj8+s~{!*g}x0NZx%QD!5sl#QPYOuVGVo@pc%Il~|F= z?!3w2;K=bXyFHxxGnj_Cl%*{@O2Xnela$Kr(xs@1thCu}8;&1YYdvkFa0rBS>DHSzNvR{=Vl!NDJcy8n* zg6@16J`5Fb_nAlhU;xW3Dxo7*_RvG?H`XiX-NVJ%|D+P?N6&;Sc|hAQwj!7rKDM%| zg2%!?W6P>PF?C&!&ZtG4@20=yx{&&Ie07=WsoQ?p>R2t}k%ycynrlWwU}Gi@46YX^ z!OfPT6Sbmw+v@PfnKN5@_$wZ?`OeT#M9xotiA`)kQTS8`YjJ@^jML=+9TGA24W-tN6*)EF1$F;;Q!?EFV79pnrFbUy*V}8{TK3PAoT^1bNz6 zryNj?Zrp91XjlNjrQ~*=dvDI1mBp2qV9^#A@ktG!BFr^S?0I?sOO$X|=bOshv%LIk z!zjh0t?-_Ti*?Dbhn{m&1O2ysvXhCb+}Pv@VpuCWKsb;{cI43NOjv z*Yi1tKrk%UPS4i4vf)$)7qJ*F-p^5$QO;P&gj$l zWPhwrvna-3e4N7RcD)8xPqxABIl=IE;+Tp<0;Nt<={j*ZZKth{fopkZi7WBv-5DVq zku=AVQcR#TQy&RB({aSC9o5+GL;kW9BMbF9MK7r?^&94BL>YF8Tc1t@wTuT}P8T)| zAhzEbx0qhCuvT5Vs?@f2KU&A_gxo*ouzRwZ)k)Gr=$q9%1uB-KLEW}YBYwT$21)RuYw%5;%xfi|);?R8?FO}#&}r36ua#58 zN$s9P8mJenJ2yd^88Z-naBm>P))Si=9}GS~l)rB>5VbVZZSJUjUuxr7Q`EF_0NXbF zziR;?FcbRTuGR}B=aE$P#YT{9_??OtlhSVyTpeW071Zy9DB!7a(3(D8duy&u4r|vi zv8)QRMV1q5_L{O>zJz4n5~YY`%qeG~K>yG=DsYznZvbAlVpWB{F+5SRu!LNOu54nY z0+S^rlxsR6EiGQhsw;|k% zxg&gD9cIwbW#W9i8o?Hms&8J+gl^Ni9uI3Phpz?sHxc$-+O->!2@DTg@ZxaL3G-*A z0eXkpyvqN9i*Ih?w_nVPkor}`uqR^b1|XNFLZ~oYtzPffo1}t}at=1XnZ?GcI==}S zh$2?!m$uWS!o{N2hF&Z*1fvTWYq&om5aRFVay82;c>7`1{Dfsjy~JYb2n5;B&;+0T|>r7Ibi4woHmTP21Ft;w@lTH4w$hFt!cZ%W^S z;>}rBE*NegB{}JXGTl8PLQ2e8!mfP1VxiGwtR|bXt>AX%HsRR`YM}bm$wU!5cqmB) z1WSIr-5Dkv*9e`qRk=Dh!Oq7J^BUz75<4kq{Oj#NpLXMM9N(%Da|K!Lii3y{m{apc zAgM9FfK+n=BTbGhnX{uYTVkN5k*P1tLgS~QiW=iy?4hJXjgu()btc#{7=lf0qW>3Kgw^F|a1%S{4=L&I&3FrE0C4C%n5u4A zGr@{V998rLcjRz!VRb+G=_sf;+7~dU41*rlBSD;Xr?F%?3ND|ri0ktKMVE_uYD-$K z&7DV)pk@s@Kvgg&(oD2f(`gt2(EZ0m8yZ{PIk^{?o3h%Z9TKi8eBFNcWQb$LYfF^m zw01FB)I;Hd*>0=F;k<{+(!txop03Wp(N&5~nCG}lr?89#gn(RHrqHG#nXDD#v2-`w zfVUN5v@mjtwX8uzw3+ z!RM|BPygaB`Ei7dtGjIV6sOPVc>NOq#Bl*Yr0zB{`Dh*PDY+$2O*Hs_62*Vj0iSr= zFlmuZa*q93{>jZ6bh>Y?Ut(THkA*G?gcdXeHM`D}v4&l~06(uf+;nPcuT+#SL9pNF zhu)OWXOd0#CnSU+Dkmb5#kWcYIW158W&E=*!$TAO=nA8$d%p)fTbUK6m6gi=Sgy_E zMlu$51d+urC^wF39pMWX(^9|;j{FB*BA!}M-F_A38WF?vKh95l4*#rSf@D1N4Wo&* zVXb)ddYX)e${)fr)dw4D zUCkuM{V)(Vt|81MI(DGCCHw68V4{_i{P%xn`3(EjGux6@Y$8E50=9PEO^_ty?C&e( zVBfH?zVN|(v%+uiVkuZipf+%Ajm_4%Bp?|GZG_^<0} zEYw9+59+a|Qq)8Kv6bbql6|n*Osu!R8`DW~Xv(3&wgy#Te<;kEV6PmL{{CObj;Tz$ z^*SEMX&toHIX9>-FQG5RC~M8H4XkxnU~pk70D#JPs^25IB|8)qqg5WJI(Q4pp%G3;N8pza%V~IYk(AlW zJIV9PRs6z32*@F$2-ym(I3!@=(E5F8Mo!C36pz8KJ&=};&VqWBs?uNv zjMzg8hRp_R-L5#xPF!S7ekWKLDlnUvwo}R&gU7#U`C%b8u1|kHXl+UvwpnwDF8VLW z1m-Y^SWjc3G7ONSXV^z-;IDA2`fKc;G&yEBt;e(H7yZeuv&9 zgF7DbPxU2y3M#&3MGJ8S?Prfmge`T(`<6eSP6!2Lpqat6v6BOU`_x##G}}*NDz|Su z`~Swo+~Klx2%Mzst5fa3#XN*OBtMPNzX~Onz_a>?0nUyevzws=b6odhTYX7_q_FKol42i3KUoQAlirdlu=DPRO-g;F%=B;nZg8j@w38sKdCHPgV zE7Dm-|KPb&^U1q{2N7C%|3kw^0Zogdf2GUzhAH zJ@tfTLz{tD8@^-S9Vp zEd)%NV#WFt%$jBQh2bwj7ISImPHiKV-W`6JuFs%d%;(z{xQN%p&Rq^UT9BXiuXLpI z?KXO|c)UG$Tw4*T<9WT}@tKbhb6EpC;UO3^?oba zlWg1*dH2}b{e|RCfuRROe&NMdoE4sxrCsZ}v#fZObI^I`%#>b$)4#Mdp3?KxHY0qC z2+7@{4_C&pK=o&I`ps%!v%bg5mYF8?R~6P~7Keux*B}VJQSx`x{v1$BoRJOpmut?# z-dva0*On1?7xNu@^o*7Z?vd*w1p4*257jgBZV-XYwu6-c`#KlC>kC;ZKzAh-$Iv9A zzI3;%ZACn*F)&IWao{7)RX?Vzo9&jz zzPz4<_Sy4$-^kCX#m)_;f#Z#m3l(~#s{FkS?^W9vFGJFP_k{`?l5uUkg)#)QQ$24( zOfLmn$Gv*l4Q*Dto*b;5L5$u5$ey$I{AcBma3;s$p6T}vb7%(TDY+y{l4SH%@4|}| z`Hzlw;n>;67%4E;6w);LJTwt(@^3wI8Lt@w@Y#TXWwP+<*^b79@_N>o6DgXV(pP#u zjF00+$gC%{_e{ePa6nGE&mnWD@h8%@H``lX+m@Vm2CG$O(I zk!sV^L5tv3bgi*~4&4WvB>5?mrt6v0b0h0(-%G_L23GIP@a&A))l7F*KjvCxTt61S zr|?t#SIrOG7F9?`8NxZxWutl>QX#v&$2a3UXbmdUwU5nNy&d)&Vm9}&Pz{F?rF?ri z=zIG0F?W)(@{=Fh!dv%X?bCLmsXsFd4mK{*i;wJ#rIw=;>hzbrE`mQL!OCx={ql{q zvwT)MZEeFh1`8bs$UPvzb9Yu!)@kQ@doVwtV&pzhx0_oOVp9tFJ>tC3J{cypHN}+ijm$Pt!l+6<>%-}j{Q$$PlW9at5o`Rv%5Q415J14KdUq< z%R9FZCXrquHpar1PM=49o1MUoa*qhOJ;hag?&6KVB39_+d9kS^)Lt_^yDI6+A(YMJ z8VCPUs;?gUNzTP7Es6_S;rkQ^#(wo_VD(K*uG@LnXnC#$VU#(G0tHdbkDY%3AVnCDmjMn#zC z@+V+_4Lh;I4_I>J`Oe!le}fm_etv8NC(?`)#{h4z3L*1;Y8r5wlLVNa*QxZ^3Lm^n z9Ks7NC$=~pnaZM}2I^TZ4k6tq6?fH^R`d=p`4EP+g2wK9?S;sbJj_wP5YSZE3u-zN zccOTh3|{~2&?vomRO!gs*GxB;5cjYsAQ^~!ejY7(YrzVfwhW@%NTr!7KT{V{hRA9e z!8VZPi>-IHql^mC!|LbJ75`qA$>iI}ymN>ZXg8P=sWejXva_J)OU{jgB2-{cl@I;VgtdiH8>{f+aOJZt?*qYtq(V2LY?D(?_SRU&{(9&Qk2W3J_qzF)FeWn@vQvGgX>InA+$(zG_#w`Q_dp`Ubl=*Z=r%++7Q~ zLlG`Z(mDNE^grp|PDuOqVPILPPr*$GHw9<`CjYvax?632N3qj+Gmc~`kNuCxCtdb!d4Mz}=&@u=h>Y7_E5 z@LosJ{|nx8KS!Ny*{EnFy-B*Zz>z-rlTSC2Y@ZGqdG|HAwpKl%EiZv9@tycyL*w$+@;wC!(0Lrp_F zzQW@RKS7vDPf7dl#m_h!xQ5#TjbQ70SvA29HtVYL_=ERvGmGoGb5L;e&Dk-O#MYJz zJ7;){?Puz$xt8v|UgPmzSj8VUp{(6=GIkvCVpnO{4sY;FME|U)Rp`>}xBkzyej~Hq z-lj2eWa_pMxt|1_r^sI0KO`RpXZ8_p*g3~qW5|x($dgKT4`a&EjNYDh5Vz7;yc)yb z&txLfgUkMN^h@dXOX<(;9t-h{yhJiH?FXZt)KS*6kz+5MCmsd$%u2aE@qaI+!Mw}9 zl)fi6ymES@*_ds425g`oIV-L4dh~tu*mUV~V zWkdBG5Q&pzq5ix?GKkH4sF7eRe3;nXiaT&y&6LXPa!VdmX^2l}BbESstC`3whU`)~ zKg<>{Y1eBHL^&)Dy!mq9-kl*M?ayF;N>*$1TGtqgg~-K3AmB6QjoZ3tBHr!72UKR| z!?b1&7nF)M=wyyV%oL;1nnM|#o#z0bJap9-Pi5{jO3&vizPI6+sr6-&fr-s9k9zdW zgNvwK_J<1uzRvR5ytP0Sr|P2CD@mV3k*4rnqAtKZK9K*m?MULI=YA5;5gGQGV+1Ud zG%ui4)gS$kqQ5t((A*Y5587$QU)7)itR9j9oo)qcBIfEl0}9FKI9SFtF>oYG+|vQSuTqjSMNqU`*(8v)@ERWTfG+V1Cy zxXq;0rJyRf;rKey!HwEMHM66hy6_o`#N6Ynz^5VFe)X_x=uFSYhPcTlr*mEZJ=3>+ zzd&L4l&0+;fO*}`!?U2J#4NVoTZlO2X!6{3m&nfl4}T^Av9I`P*Qzyy;Z3uu@5HYD zt))B$j&R(F_3IZ>DfQ25E)GJxW7wZo3(Nhn(9N{OT)r*#lX)^ls~KB{e?m}@5Tg-L zy*fGXO_k+jdmhX+oit_v19@Mm`4;j;JMbWe1KZdo%4e%PUGO2c9E0_%)dRQy03a=! z4(l~@<&H`m1_TstFESPO51V>up*@XS^$SGlK!*78I=Da!SCDWmE5|y15+6$s3EK3n z@TUv6j*3Bn?=kU;AP^}LJRYp!gF?LI=6SdN&SF^P)OR8ASr6CZ-oKU8?vocg2>>iH zg5ZJB1!Ksr!o43J+$5BweaX@Dq2DRD!LT%@ z-PKiQDOC6kHIUMBz$gI*kLr%3zkhBss7wZ<(#&Q0=AU0C-zb>Ru2E%QJNS%dd@fDV z#?fQO)-v{6xyLi2!l=VGTwhieA_{EYtN5!(CdEaxTE7@z#R!sOP~R1bHI*s+Q31k+ znipKSI8zfU~64DM-pg8&wf79{LrP3%k4Q&GO<9m4PfjRVJS zvicgS@;NOh5UGP}Mt)tY*Dp0A*f-{E7nJN-on*Bd29lrTwC(eTQO=i{|G$t^i8hRN z2GmbpUCE6a-5Z;QomRal6)xzQ-LF5OeMzN|Mwx3bHraT<@Dqo(VJz?ZVxUY( zNgrlh%yOPi421Nt=z(@+RuM%Lvr5re+zWY{bQtC1``S~<*qm-SS}*m8(|P-ir!7jb z1$6cqGdwrIxnClQH*H95zD(ot(`vBVoOasv9c#-5ug;kJ>>7>dfdC;E5+I6;UEY^Y zi{+W5rCOqPy2igZdP}Z?sv0H<6`WuB$XqsL}UaxRYmxSmR-hdrli{%GELpM60&v z{&Puw_{^4#2P&M|sqpb+xtSGC%f12+!3X7#p0sPd+aTtTwXCDqu8Yjx_JXf{Qj!5p zO&7H6DV}-{NqL{+ykSPP{);Oz)8GJBc4w{{3H$=bqo&X}j`4|9{mNcL&jd3`- z3G+*5k&t9h0%xQ^^Bo3T!su-i+xF=I}S4pXqJB}J%zn&4jTMPPmgiB10 zn%|V7|ABKnbW@v~q8t!3y2~|f+k~`a#t0D$<&rzPKEEvphaOQ{$WVWJXY3xDhw9AS zzSzHOSO0?z`L+UKu^F7(jPWVLcWr!2MFBZ=}EUK z=!mdJI-R$$hheWyzz}!2Rg~2X+IzPMf8)` zSa_#i$jp9xPPm+%I`+0Y-byLrAB5-Li{ zA^AuKDClZ9pIdI55J;KM9{Dkl-b9Oo{f%4au2Xr#Dt~`QSAa-a=pBb%$i4=;8h z{>A|4zDQw9@c+sSK4)w2o(zRyCT!sdWi>n4XnywG8!-4_PtUfW#-~}g$NmS>y_Oq3 zEazujGN^#swxW-5sFNmx_12AkW~2g^4z6xIFy#F#Df3uq{jIu1%oUTXx#1p0-&D}KMH1{7Cq(&#M4p#>JDy+Utkr2 zQ49bulCMYcEs+5h$%P>!Ja|CF*K)rx*Zgmj#833>uqBO)4GE`RQ3P?G&Z8s#(?s8iPCF{4=(C_cr31o$b4d z9|HRRw1^qWzqT%;O3<1jg8yzisce(D#25@T`@7-T8T#Hnu4;_b{57(kz`^(IZm_tp zj_EuSrQ>opaNsozS2N3hcS+_X0nVAgjrkcz`Gz`&=WBBu7rx{t6_0tp|HndqGzr-G4#$D z9zFPXDTVIben@?Ij2t7eAuWI6K3=c!SgSiEQ_Me7J&BVw>mMdx!Qa^i<4j5Zobr>U z*I6tgy=<&8O)4gKob)a>Eda<$(%a7?FK70e@>=weM2j0#^cE1|#`-okBE5hqL7124 zOI7h*UhbnslI-PH=t$N1n!?q2!1^>kSwXotpQ|cS*;r?@Mel}2eR0=&vY|96K(yRm z`yQ5^Jt@++rt@~6{7xR5I`&nVE-~5z|8+~^u}PkaUbPXQJ?Fz>77f`KP(5wWm$-P5>yC7OpGs*fR=_7zWX%)=< zIDl;%0}NkT;nShU>tRRwb+-HBPEFm0t55le0QJs+|2|?I^yzLJI0t##J{|ZgOXK1g zx%Y3^e71IJPudtaabJOmvR+X8_is)q>5;?h^5V&%cikhts()U(1{h}g%e#78e6^l+ul7{x~J zl3EMvwIYgRb*?eRpKJ!J+We_)_E$2WrxY0%<>^=|o~_rD$1TjIm2lSYI*NI*9bjXR z<#JhJb)+bQQja~0S(|Tm5LJ{{SfWr*W;@;gv4K8Ba9I^^h~LifoDhi@#@l}paF@(r z6haG_j7)O{yeF~#Xf%3dwTUK!0h;+{7d^g+%vWQd`208U7Z#0eT0k?cDbkp?(Q@y_ zE61R4NoE_yt@Pj?P6Gq}IKz0`+`Jb={z>)dL{M1{kJ0>yqa7f7(s9>o|8hjEseXL} zjP0+ZgGBCFVHVyqkmx>aM9{f&t6BBX-w0`O002C0S4b9qMfCQspm9|wbmqyJDsS&+ z85ch?VT*~Yn1m+& z&b|Tg=^WtjDgIYM!Ib0-G>=8_XDso@^toUA)-VfOUFJtj&gMhF48arYmW+ zziss0zc8B?>U~xrc$kS^KLq)LvP6v856n%=RnZ$Z_;Rj=Y z6kOYd&rR%ng?QwDH`s}9oWBVMn&bQF?)vuqm0lyqeafm5xiiGM`nN}EdK*4viPQ_F z`LJakcHDi*IML5(`8l{TFc9JZ03Px0xd58Ky6PqRYVE68b8-shh3OmqGeI92TmWtK z|D3{)^>^Pu&uH(ticYxGnd>%URMO?=W`d)1L(ZxI3N-lkp8sVloVGX7%KQA>P*&6{ z!$$AM@bq`5Z(+3!&S#~!VUB72vsSdnr5}6>MeuMNbwdhHa2RxzRmH`09If^%6eWx% zWz$yKpGUol75H_UYj;yq6c_N^M{hLWkQ?T)pZ@T65U?^J1M|ohIPFn!=^-@e%J?ru z$xLMYnW7~1>OSMzUR3z{`M`ngmO>kLLYjhQ_SNn&^4c9;uTYKP1nhb(>Laf!idKYw zRT0`u&yA(@n3(LK$+#Nwf^>=E@dC^T>L7C)UnCLG`Tv0do+#u6ItlqQXj4n|hnlc< zHF!hvggLpI*9tg;MHN=L5-C70Eq7IZ1S>%pOx~huQson_L-#p^>RIy*3>lJ;+b+dt zM$rm2{U-k0EE(u^)+3v2A-Ml*VnZ^c=Bzs{N*rAglJW;rK*<{tu0a%i17pna58#`D zeUt5fykHjb>jzRyHtY=fz<-l{K>oK6jCx-VZ_QC{IsY_ZO>=`D7{n=Hpi#t{Twl_F z_-7?#`V4)la#f(pNK=jbaIf=!T`uIU1!lO>!50qu|7+jG@B2M6IWDg&Q1;pPGq+jO zvRU3&SIriGy7c<%SqCgG&As(jW;;;7GqX+Z#gEfL5pwAAaiC-Q65|&8Eqnh{_jE?v z+SI#yd!HXsOWYSIc6aKubKpe4^zo77o`dfzk2pSxTKntH^u1d%UdNjnX&tWL^8ff| zogMtW9R+U{fnmh*=xFnXvV$i~iu$dU48{7tf1JLjzx2n^r$($3GEi|G_Dxu|lwNkGcF}XcA<(TLYY90-ZDQZkY>^ zM(lcOKVX^s;#(3ZR=)`SeXR#$i!nX#S$Mk}n1GosdUNC#T&b+yxJdKwi;G{(Hcwb7 z{8!G7jSaMfMqj!ukabfRv-bU(?1#(M-=F3ck^`EhFfX4YTfC&&5X9zit}tKv=iM=b z>*cG&Wq1EN&5|xQ>#q~Y9eftP1m$3CKf-SHIS^$)K+;nL2ZoYT7=f||?90LXq(?#v>6xr?K-tV7ZV<;Kc;-&ZJ`I8MrZJJ^>bP0l+XkKYQMdh literal 0 HcmV?d00001