Feature #13148: Replace vendor implementation with DotSo plugin

This commit is contained in:
Amin Ben Romdhane 2024-01-23 20:52:37 +00:00
parent 36a805cac4
commit b3945f8b0e
75 changed files with 1253 additions and 1944 deletions

View file

@ -1650,13 +1650,13 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
if (strcasecmp(tmp, "JSON") == 0) {
err = load_json_plugin(&loaded_json_files, &json_list, &json_memhead, file_path, &DEAMON_DM_ROOT_OBJ);
} else if (strcasecmp(tmp, "DotSo") == 0) {
err = load_dotso_plugin(&deamon_lib_handle, file_path, &DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, &DEAMON_DM_VENDOR_EXTENSION_EXCLUDE);
err = load_dotso_plugin(&deamon_lib_handle, file_path, &DEAMON_DM_ROOT_OBJ);
} else {
ERR("Input type %s not supported", tmp);
}
if (!err) {
bbf_global_init(DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE, daemon_ctx->config.in_plugin_dir);
bbf_global_init(DEAMON_DM_ROOT_OBJ, daemon_ctx->config.in_plugin_dir);
} else {
ERR("Failed loading %s", file_path);
}

View file

@ -21,8 +21,6 @@ extern struct list_head json_memhead;
#define UNUSED __attribute__((unused))
static DMOBJ *CLI_DM_ROOT_OBJ = NULL;
static DM_MAP_VENDOR *CLI_DM_VENDOR_EXTENSION[2] = {0};
static DM_MAP_VENDOR_EXCLUDE *CLI_DM_VENDOR_EXTENSION_EXCLUDE = NULL;
static void *cli_lib_handle = NULL;
@ -516,16 +514,12 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0) {
if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
if (load_dotso_plugin(&cli_lib_handle, cli_data->in_name,
&CLI_DM_ROOT_OBJ,
CLI_DM_VENDOR_EXTENSION,
&CLI_DM_VENDOR_EXTENSION_EXCLUDE) != 0) {
if (load_dotso_plugin(&cli_lib_handle, cli_data->in_name, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE;
goto end;
}
} else {
if (load_json_plugin(&loaded_json_files, &json_list, &json_memhead, cli_data->in_name,
&CLI_DM_ROOT_OBJ) != 0) {
if (load_json_plugin(&loaded_json_files, &json_list, &json_memhead, cli_data->in_name, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE;
goto end;
}
@ -536,9 +530,9 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
goto end;
}
bbf_global_init(CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE, cli_data->in_plugin_dir);
bbf_global_init(CLI_DM_ROOT_OBJ, cli_data->in_plugin_dir);
bbf_ctx_init(&cli_data->bbf_ctx, CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(&cli_data->bbf_ctx, CLI_DM_ROOT_OBJ);
cli_data->bbf_ctx.dm_type = cli_data->proto;
cli_data->bbf_ctx.instance_mode = cli_data->instance_mode;

View file

@ -12,10 +12,6 @@
#include "common.h"
#include "get_helper.h"
#define DEFAULT_LOG_LEVEL (2)
static unsigned char gLogLevel = DEFAULT_LOG_LEVEL;
// Logging utilities
void set_debug_level(unsigned char level)
{

View file

@ -43,8 +43,6 @@
#define GLOB_EXPR "[=><]+"
extern DMOBJ *DEAMON_DM_ROOT_OBJ;
extern DM_MAP_VENDOR *DEAMON_DM_VENDOR_EXTENSION[2];
extern DM_MAP_VENDOR_EXCLUDE *DEAMON_DM_VENDOR_EXTENSION_EXCLUDE;
bool is_str_eq(const char *s1, const char *s2);
bool is_node_instance(char *path);

View file

@ -21,8 +21,6 @@
extern struct list_head head_registered_service;
DMOBJ *DEAMON_DM_ROOT_OBJ = NULL;
DM_MAP_VENDOR *DEAMON_DM_VENDOR_EXTENSION[2] = {0};
DM_MAP_VENDOR_EXCLUDE *DEAMON_DM_VENDOR_EXTENSION_EXCLUDE = NULL;
static struct {
int trans_id;
@ -74,7 +72,7 @@ void bb_add_string(struct blob_buf *bb, const char *name, const char *value)
void bbf_init(struct dmctx *dm_ctx)
{
bbf_ctx_init(dm_ctx, DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(dm_ctx, DEAMON_DM_ROOT_OBJ);
}
void bbf_cleanup(struct dmctx *dm_ctx)
@ -84,7 +82,7 @@ void bbf_cleanup(struct dmctx *dm_ctx)
void bbf_sub_init(struct dmctx *dm_ctx)
{
bbf_ctx_init_sub(dm_ctx, DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init_sub(dm_ctx, DEAMON_DM_ROOT_OBJ);
}
void bbf_sub_cleanup(struct dmctx *dm_ctx)

View file

@ -18,12 +18,9 @@
extern struct list_head global_memhead;
int load_dotso_plugin(void **lib_handle, const char *file_path,
DMOBJ **main_entry,
DM_MAP_VENDOR *main_Extension[],
DM_MAP_VENDOR_EXCLUDE **main_Extension_exclude)
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry)
{
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry || !main_Extension || !main_Extension_exclude)
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry)
return -1;
void *handle = dlopen(file_path, RTLD_NOW|RTLD_LOCAL);
@ -66,21 +63,6 @@ int load_dotso_plugin(void **lib_handle, const char *file_path,
return -1;
}
//Vendor Extension
DM_MAP_VENDOR *vendor_extension = NULL;
*(void **) (&vendor_extension) = dlsym(handle, "tVendorExtension");
if (vendor_extension) main_Extension[0] = vendor_extension;
//Vendor Extension Overwrite
DM_MAP_VENDOR *vendor_extension_overwrite = NULL;
*(void **) (&vendor_extension_overwrite) = dlsym(handle, "tVendorExtensionOverwrite");
if (vendor_extension_overwrite) main_Extension[1] = vendor_extension_overwrite;
//Vendor Extension Exclude
DM_MAP_VENDOR_EXCLUDE *vendor_extension_exclude = NULL;
*(void **) (&vendor_extension_exclude) = dlsym(handle, "tVendorExtensionExclude");
if (vendor_extension_exclude) *main_Extension_exclude = vendor_extension_exclude;
return 0;
}
@ -92,8 +74,7 @@ int free_dotso_plugin(void *lib_handle)
return 0;
}
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path,
DMOBJ **main_entry)
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry)
{
int json_plugin_version = 0;
@ -114,16 +95,22 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
}
char *node_obj = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
unsigned int len = strlen(node_obj);
if (node_obj == NULL) {
ERR("ERROR: Can't get the node object\n");
return -1;
}
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[strlen(node_obj) - 1] != '.') {
ERR("ERROR: Object (%s) not valid\n", node_obj);
return -1;
}
char obj_prefix[512] = {0};
find_prefix_obj(node_obj, obj_prefix, sizeof(obj_prefix));
obj_prefix[strlen(obj_prefix)-1] = 0;
char obj_prefix[1024] = {0};
json_plugin_find_prefix_obj(node_obj, obj_prefix, sizeof(obj_prefix));
if (strlen(obj_prefix) == 0) {
ERR("ERROR: Obj prefix is empty for (%s) Object\n", node_obj);
return -1;
}
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ));
if (dm_entryobj == NULL) {

View file

@ -10,14 +10,10 @@
#ifndef PLUGIN_H
int load_dotso_plugin(void **lib_handle, const char *file_path,
DMOBJ **main_entry,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE **tVendorExtensionExclude);
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry);
int free_dotso_plugin(void *lib_handle);
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path,
DMOBJ **main_entry);
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry);
int free_json_plugin(void);
#endif /* PLUGIN_H */

View file

@ -67,7 +67,7 @@ return
This method is used to initialize the dmctx structure object to read the data model.
```
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude);
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj);
inputs
struct dmctx *ctx
pointer to struct dmctx strunture to be initialized.
@ -81,7 +81,7 @@ return
This method is an extension of bbf_ctx_init method. only difference it only intializes dmctx structure object and does not intializes other resources used in reading data model
```
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude)
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj)
inputs
struct dmctx *ctx
pointer to struct dmctx strunture to be initialized.

View file

@ -1,77 +1,81 @@
# BBFDM Vendor
`bbfdm` library can be used to **Extend** the Data Model with new objects/parameters, to **Overwrite** existing objects/parameters with new ones and **Exclude** some objects/parameters from Data Model tree.
The `bbfdm` library offers functionality for vendors to define their vendor extensions. This allows them to **extend** the core Data Model by introducing new objects/parameters/operates/events, **overwrite** and **exclude** existing ones.
## How to add new vendor
## How to Add a New Vendor
### 1. Create a vendor folder
### 1. Create a Vendor Folder
Create a new folder under **'dmtree/vendor/'** which contains all files related to the vendor
To add a new vendor, simply create a new folder under **'dmtree/vendor/'** which contains all files related to the vendor. Ensure that the folder name matches the vendor name specified in **BBF_VENDOR_LIST** macro.
### 2. Fill Extend, Overwrite and Exclude tables with objects/parameters
### 2. Populate the `tDynamicObj` Table
Create the first vendor C file which contains new **Extend**, **Overwrite** and **Exclude** tables of objects/parameters.
#### Extend and Overwrite table
The Extend and Overwrite tables contain entries of **DM_MAP_OBJ** structure.
The **DM_MAP_OBJ** structure contains three arguments:
For extending, overwriting, and excluding objects/parameters/operates/events from the core tree, it's mandatory to have a `tDynamicObj` table. This table should be defined using **DM_MAP_OBJ** structure, which has three 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 |
| `parameter` | Pointer to a **DMLEAF** array which contains a list of the child parameters |
| `parentobj` | A string representing the parent object name from which to extend/exclude/overwrite the required items. Example: "Device.IP.Diagnostics.", "Device.WiFi.Radio." |
| `nextobject` | Pointer to a **DMOBJ** array containing a list of child objects to extend/exclude/overwrite |
| `parameter` | Pointer to a **DMLEAF** array containing a list of child parameters to extend/exclude/overwrite |
#### Exclude table
Each entry in the exclude table is a string which could be a path of object or parameter that need to be excluded from the tree
- The `parentobj` must be a string path of an **object** available in the core tree. If it doesn't exist, it will be skipped during parsing of the `tDynamicObj` table.
The following [link](../../libbbfdm/dmtree/vendor/test/tr181/vendor.c) contains example of Extend, Overwrite and Exclude table.
- To extend the Data Model tree, fill the `nextobject` and `parameter` arguments with the required objects/parameters/operates/events not supported by the core tree.
### 3. Adding vendor and standard objects/Parameters
- To overwrite existing objects/parameters/operates/events in the core tree, fill the `nextobject` and `parameter` arguments with the same items defined in the core tree, along with new **add/del/get/set/browse** APIs needed by the vendor.
Implement the new vendor/standard objects and parameters as defined above in the first section.
- To exclude existing objects/parameters/operates/events in the core tree, fill the `nextobject` and `parameter` arguments with the same items defined in the core tree, and setting **bbfdm_type** to **BBFDM_NONE**.
Example: [Custom Vendor Object Dropbear](../../libbbfdm/dmtree/vendor/test/tr181/x_test_com_dropbear.c)
### 3. Enable vendor
### 4. link vendor tables to the main tree
To enable the new vendor:
To register the new vendor tables, you need to link them in the main three tables:
- Add the vendor to the list in **BBF_VENDOR_LIST** macro.
- **tVendorExtension**
- Define the vendor prefix using **BBF_VENDOR_PREFIX** macro.
- **tVendorExtensionOverwrite**
- **tVendorExtensionExclude**
These tables are defined in the file **'dmtree/vendor/vendor.c'**.
Example: [Link vendor tables to the main tree](../../libbbfdm/dmtree/vendor/vendor.c)
### 5. Enable vendor
To enable the new vendor
- Define **BBF_VENDOR_EXTENSION** macro
- Add the new vendor in the list **BBF_VENDOR_LIST** macro
- Define the vendor prefix using **BBF_VENDOR_PREFIX** macro
Example of Config Options:
Example Configuration Options:
```bash
BBF_VENDOR_EXTENSION=y
BBF_VENDOR_LIST="iopsys,test"
BBF_VENDOR_PREFIX="X_TEST_COM_"
BBF_VENDOR_LIST="iopsys,xxxx"
BBF_VENDOR_PREFIX="X_IOPSYS_EU_"
```
> Note1: The `libbbfdm` vendor list can support multi-vendor with comma seperated.
## Example how to Extend, Overwrite and Exclude the Data Model tree
> Note2: If multi vendors are supported and there is a object/parameter that is implmented by multi customers in different way, the implemented object/parameter of the first vendor name in the **BBF_VENDOR_LIST** will be considered.
In the [test/vendor_test/](../../test/vendor_test) directory, you'll find an example implementation for **test** vendor. This implementation demonstrates how to extend, overwrite, and exclude objects/parameters/operates/events from the core tree.
> Note3: Overwrite and Exclude are only considered in `dmtree/vendor/<vendor>/`
### 1. Extend Data Model
- The directory **'dmtree/vendor/test/'** contains an example of **test** vendor implementation
- using DotSo Plugin:
- Add support for [Device.Firewall.Chain.{i}.Rule.{i}.X_TEST_COM_TimeSpan.](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/firewall.c#L172) object
- Add support for [Device.Firewall.Chain.{i}.Rule.{i}.X_TEST_COM_ICMPType](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/firewall.c#L178) parameter
- using JSON Plugin:
- Add support for [Device.PD2.{i}.](../../test/vendor_test/test_extend.json) object
### 2. Overwrite Data Model
- using DotSo Plugin:
- Overwrite [Device.X_IOPSYS_EU_Dropbear.{i}.](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/device.c#L18) object in the core tree
- Overwrite [Device.DeviceInfo.Manufacturer](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/deviceinfo.c#L29) parameter in the core tree
- using JSON Plugin:
- Overwrite [Device.DeviceInfo.Processor.](../../test/vendor_test/test_overwrite.json) object in the core tree
### 3. Exclude Data Model
- using DotSo Plugin:
- Exclude [Device.USB.](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/device.c#L17) object from the core tree
- Exclude [Device.Ethernet.RMONStats.{i}.Packets1024to1518Bytes](https://dev.iopsys.eu/bbf/bbfdm/-/blob/ticket_13148/test/vendor_test/extension.c#L37) parameter from the core tree
- using JSON Plugin:
- Exclude [Device.X_IOPSYS_EU_IGMP.](../../test/vendor_test/test_exclude.json) object from the core tree
> Note1: The `libbbfdm` vendor list can support multiple vendors, separated by commas.
> Note2: If multi vendors are supported and there is an objects/parameters/operates/events implemented differently by different vendors, the implementation of the **last vendor name** in **BBF_VENDOR_LIST** will be considered.
> Note3: In the JSON plugin, there is no way to extend, overwrite and exclude parameters/operates/events that have an existing object in the core tree.

View file

@ -62,7 +62,7 @@ function install_libbbf()
mkdir -p build
cd build
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS -lm" -DWITH_OPENSSL=ON -DBBF_VENDOR_EXTENSION=ON -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFDMD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS -lm" -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFDMD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
exec_cmd_verbose make
echo "installing libbbf"

View file

@ -34,14 +34,6 @@ echo "Validate X_IOPSYS_EU_WiFi JSON Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_WiFi.json
check_ret $?
echo "Validate X_IOPSYS_EU_URLFilter JSON Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/urlfilter.json
check_ret $?
echo "Validate CWMPManagementServer JSON Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/CWMPManagementServer.json
check_ret $?
echo "Validate TR-181 JSON Plugin after generating from XML"
json_path=$(./tools/convert_dm_xml_to_json.py test/tools/tr-181-2-*-cwmp-full.xml test/tools/tr-181-2-*-usp-full.xml Device.)
./tools/validate_json_plugin.py $json_path

View file

@ -2,34 +2,22 @@ cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm-api)
ADD_DEFINITIONS(-Wall -Werror)
ADD_DEFINITIONS(-D_GNU_SOURCE)
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
IF(${BBF_MAX_OBJECT_INSTANCES})
ADD_DEFINITIONS(-DBBF_MAX_OBJECT_INSTANCES=${BBF_MAX_OBJECT_INSTANCES})
ENDIF()
OPTION(BBF_VENDOR_EXTENSION "build with vendor extension enabled" ON)
OPTION(BBF_SCHEMA_FULL_TREE "build with schema full tree" OFF)
SET(BBF_PLUGIN_SOURCES plugin/dotso_plugin.c plugin/json_plugin.c)
IF(BBF_VENDOR_EXTENSION)
SET(BBF_VENDOR_EXTENSION_SOURCES plugin/vendor_plugin.c)
ADD_DEFINITIONS(-DBBF_VENDOR_LIST="${BBF_VENDOR_LIST}")
add_compile_definitions(BBF_VENDOR_EXTENSION)
SET(BBF_VENDOR_LIST "iopsys" CACHE STRING "vendor list to be used")
STRING(REPLACE "," ";" VENDOR_LIST ${BBF_VENDOR_LIST})
ENDIF(BBF_VENDOR_EXTENSION)
IF(BBF_SCHEMA_FULL_TREE)
add_compile_definitions(BBF_SCHEMA_FULL_TREE)
ENDIF(BBF_SCHEMA_FULL_TREE)
FILE(GLOB BBF_API_SOURCES *.c)
FILE(GLOB BBF_API_SOURCES *.c plugin/*.c)
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES} ${BBF_PLUGIN_SOURCES} ${BBF_VENDOR_EXTENSION_SOURCES})
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm-api uci ubus ubox json-c blobmsg_json dl)

View file

@ -32,6 +32,7 @@ extern struct dm_permession_s DMASYNC;
extern char *DMT_TYPE[];
extern unsigned char gLogLevel;
extern bool is_micro_service;
#ifndef BBF_MAX_OBJECT_INSTANCES
@ -157,15 +158,6 @@ typedef struct dm_map_obj {
struct dm_leaf_s *root_leaf;
} DM_MAP_OBJ;
typedef struct dm_map_vendor {
char *vendor;
struct dm_map_obj *vendor_obj;
} DM_MAP_VENDOR;
typedef struct dm_map_vendor_exclude {
char *vendor;
char **vendor_obj;
} DM_MAP_VENDOR_EXCLUDE;
struct dm_reference {
char *path;
@ -181,8 +173,6 @@ struct dmctx {
int (*checkleaf)(DMOBJECT_ARGS);
struct list_head list_parameter;
DMOBJ *dm_entryobj;
DM_MAP_VENDOR *dm_vendor_extension[2];
DM_MAP_VENDOR_EXCLUDE *dm_vendor_extension_exclude;
bool nextlevel;
bool iswildcard;
int faultcode;
@ -389,7 +379,6 @@ enum bbfdm_type_enum {
enum {
INDX_JSON_MOUNT,
INDX_LIBRARY_MOUNT,
INDX_VENDOR_MOUNT,
INDX_SERVICE_MOUNT,
__INDX_DYNAMIC_MAX
};

View file

@ -18,8 +18,10 @@
#include "dmbbf.h"
#define MAX_DM_PATH (1024)
#define DEFAULT_LOG_LEVEL (2)
static int dm_browse(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, void *data, char *instance);
unsigned char gLogLevel = DEFAULT_LOG_LEVEL;
bool is_micro_service = false;
char *DMT_TYPE[] = {
[DMT_STRING] = "xsd:string",
@ -40,7 +42,7 @@ struct dm_permession_s DMWRITE = {"1", NULL};
struct dm_permession_s DMSYNC = {"sync", NULL};
struct dm_permession_s DMASYNC = {"async", NULL};
bool is_micro_service = false;
static int dm_browse(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, void *data, char *instance);
static bool is_instance_number_alias(char **str)
{
@ -430,7 +432,7 @@ static void dm_browse_service(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *e
if (dmctx->checkobj) {
*err = dmctx->checkobj(dmctx, &node, NULL, NULL, NULL, NULL, data, instance);
if (*err)
if (*err && !dmctx->inparam_isparam && DM_STRSTR(dmctx->in_param, parent_obj) != dmctx->in_param)
return;
}
@ -2272,12 +2274,12 @@ static int mparam_set_value(DMPARAM_ARGS)
res = string_to_bool(dmctx->in_value, &val);
if (res == 0 && dmuci_string_to_boolean(value) == val) {
TRACE("Requested value (%s) is same as current value (%s)", dmctx->in_value, value);
BBF_DEBUG("Requested value (%s) is same as current value (%s)", dmctx->in_value, value);
return 0;
}
} else {
if (DM_STRCMP(value, dmctx->in_value) == 0) {
TRACE("Requested value (%s) is same as current value (%s)", dmctx->in_value, value);
BBF_DEBUG("Requested value (%s) is same as current value (%s)", dmctx->in_value, value);
return 0;
}
}

View file

@ -64,22 +64,28 @@ static inline int DM_LINK_INST_OBJ(struct dmctx *dmctx, DMNODE *parent_node, voi
#ifndef TRACE
#define TRACE(MESSAGE, ...) do { \
syslog(LOG_INFO, "[%s:%d] " MESSAGE, __FUNCTION__,__LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
syslog(LOG_INFO, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#endif
#define ENABLE_BBF_DEBUG 0
#if ENABLE_BBF_DEBUG
#define BBF_DEBUG(fmt, ...) do { \
FILE *fp = fopen("/tmp/bbfdm.log", "a"); \
if (fp) { \
fprintf(fp, "%s@%s:%d: " fmt, __func__, __FILE__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
fclose(fp); \
} \
// Macros for different log levels
#define BBF_ERR(MESSAGE, ...) do { \
if (gLogLevel >= 1) { \
syslog(LOG_ERR, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} \
} while(0)
#else
#define BBF_DEBUG(fmt, ...)
#endif
#define BBF_INFO(MESSAGE, ...) do { \
if (gLogLevel >= 3) { \
syslog(LOG_INFO, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} \
} while(0)
#define BBF_DEBUG(MESSAGE, ...) do { \
if (gLogLevel >= 4) { \
syslog(LOG_DEBUG, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} \
} while(0)
#endif //__DMBBF_H__

View file

@ -750,7 +750,7 @@ struct uci_section *is_dmmap_section_exist_eq(char* package, char* section, char
return NULL;
}
unsigned int count_occurrences(char *str, char c)
unsigned int count_occurrences(const char *str, char c)
{
int count = 0;
@ -2062,21 +2062,31 @@ char *replace_char(char *str, char find, char replace)
char *replace_str(const char *str, const char *substr, const char *replacement)
{
int replacement_len = DM_STRLEN(replacement);
int substr_len = DM_STRLEN(substr);
int i, cnt = 0;
if (!str || !substr || !replacement)
return NULL;
for (i = 0; str[i] != '\0'; i++) {
int str_len = strlen(str);
int substr_len = strlen(substr);
int replacement_len = strlen(replacement);
int cnt = 0;
if (str_len == 0)
return strdup("");
if (substr_len == 0)
return strdup(str);
for (int i = 0; str[i] != '\0'; i++) {
if (DM_STRSTR(&str[i], substr) == &str[i]) {
cnt++;
i += substr_len - 1;
}
}
size_t new_str_len = i + cnt * (replacement_len - substr_len) + 1;
size_t new_str_len = str_len + cnt * (replacement_len - substr_len) + 1;
char *value = (char *)malloc(new_str_len * sizeof(char));
i = 0;
int i = 0;
while (*str) {
if (strstr(str, substr) == str) {
i += snprintf(&value[i], new_str_len - i, "%s", replacement);

View file

@ -185,7 +185,7 @@ enum option_type_enum {
#define sysfs_foreach_file_sorted(path,max_num_files) \
struct dirent *ent = NULL; \
DIR *dir = NULL; \
if ((dir = opendir(path)) == NULL) return 0; \
if ((dir = opendir(path)) == NULL) return; \
int num_files = 0; \
char *files[max_num_files]; \
while ((ent = readdir(dir)) != NULL && num_files < max_num_files) \
@ -251,7 +251,7 @@ int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *obje
int dm_entry_validate_external_linker_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
int dm_validate_allowed_objects(struct dmctx *ctx, struct dm_reference *reference, char *objects[]);
char *check_create_dmmap_package(const char *dmmap_package);
unsigned int count_occurrences(char *str, char c);
unsigned int count_occurrences(const char *str, char c);
bool isdigit_str(const char *str);
bool ishex_str(const char *str);
bool special_char(char c);

View file

@ -42,15 +42,10 @@ static struct dm_fault DM_FAULT_ARRAY[] = {
{ USP_FAULT_INVALID_PATH, "Path is not present in the data model schema"},
};
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude)
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
{
INIT_LIST_HEAD(&ctx->list_parameter);
ctx->dm_entryobj = tEntryObj;
ctx->dm_vendor_extension[0] = tVendorExtension ? tVendorExtension[0] : NULL;
ctx->dm_vendor_extension[1] = tVendorExtension ? tVendorExtension[1] : NULL;
ctx->dm_vendor_extension_exclude = tVendorExtensionExclude;
dm_uci_init();
}
@ -63,15 +58,10 @@ void bbf_ctx_clean(struct dmctx *ctx)
dmcleanmem();
}
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude)
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj)
{
INIT_LIST_HEAD(&ctx->list_parameter);
ctx->dm_entryobj = tEntryObj;
ctx->dm_vendor_extension[0] = tVendorExtension ? tVendorExtension[0] : NULL;
ctx->dm_vendor_extension[1] = tVendorExtension ? tVendorExtension[1] : NULL;
ctx->dm_vendor_extension_exclude = tVendorExtensionExclude;
}
void bbf_ctx_clean_sub(struct dmctx *ctx)
@ -252,9 +242,9 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
return bbf_fault_map(ctx, fault);
}
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
void bbf_global_init(DMOBJ *dm_entryobj, const char *plugin_path)
{
load_plugins(dm_entryobj, dm_VendorExtension,dm_VendorExtensionExclude, plugin_path);
load_plugins(dm_entryobj, plugin_path);
}
void bbf_global_clean(DMOBJ *dm_entryobj)
@ -338,7 +328,7 @@ int adm_entry_get_reference_param(struct dmctx *ctx, char *param, char *linker,
if (!param || !linker || *linker == 0)
return 0;
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj);
dmctx.iswildcard = 1;
dmctx.inparam_isparam = 1;
@ -364,7 +354,7 @@ int adm_entry_get_reference_value(struct dmctx *ctx, char *param, char **value)
snprintf(linker, sizeof(linker), "%s%c", param, (param[DM_STRLEN(param) - 1] != '.') ? '.' : '\0');
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj);
dmctx.in_param = linker;
@ -384,7 +374,7 @@ int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, cha
if (!param || !linker || *linker == 0)
return 0;
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj);
dmctx.in_param = param;
dmctx.linker = linker;
@ -407,7 +397,7 @@ int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value) //
snprintf(linker, sizeof(linker), "%s%c", param, (param[DM_STRLEN(param) - 1] != '.') ? '.' : '\0');
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj);
dmctx.in_param = linker;
@ -428,7 +418,7 @@ bool adm_entry_object_exists(struct dmctx *ctx, char *param)
snprintf(linker, sizeof(linker), "%s%c", param, (param[DM_STRLEN(param) - 1] != '.') ? '.' : '\0');
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj);
dmctx.in_param = linker;

View file

@ -15,21 +15,17 @@
#ifndef __DMENTRY_H__
#define __DMENTRY_H__
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude);
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj);
void bbf_ctx_clean(struct dmctx *ctx);
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude);
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj);
void bbf_ctx_clean_sub(struct dmctx *ctx);
int bbf_fault_map(struct dmctx *ctx, int fault);
int bbf_entry_method(struct dmctx *ctx, int cmd);
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
void bbf_global_init(DMOBJ *dm_entryobj, const char *plugin_path);
void bbf_global_clean(DMOBJ *dm_entryobj);
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);

View file

@ -14,10 +14,6 @@
#include "plugin/json_plugin.h"
#include "plugin/dotso_plugin.h"
#ifdef BBF_VENDOR_EXTENSION
#include "plugin/vendor_plugin.h"
#endif
extern struct list_head global_memhead;
struct service
@ -35,13 +31,12 @@ static bool add_service_to_main_tree(DMOBJ *main_dm, char *srv_name, char *srv_p
return false;
// Disable service object if it already exists in the main tree
disable_entry_obj(dm_entryobj, srv_obj);
disable_entry_obj(dm_entryobj, srv_obj, srv_parent_dm, srv_name);
if (dm_entryobj->nextdynamicobj == NULL) {
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
dm_entryobj->nextdynamicobj[INDX_SERVICE_MOUNT].idx_type = INDX_SERVICE_MOUNT;
}
@ -326,15 +321,18 @@ DMOBJ *find_entry_obj(DMOBJ *entryobj, char *obj_path)
DMOBJ *obj = NULL;
char *in_obj = replace_str(obj_path, ".{i}.", ".");
if (in_obj == NULL)
return NULL;
dm_check_dynamic_obj(&node, entryobj, in_obj, &obj);
FREE(in_obj);
return obj;
}
void disable_entry_obj(DMOBJ *entryobj, char *obj_path)
void disable_entry_obj(DMOBJ *entryobj, char *obj_path, const char *parent_obj, const char *plugin_path)
{
if (!entryobj || DM_STRLEN(obj_path) == 0)
if (!entryobj || !plugin_path || DM_STRLEN(obj_path) == 0)
return;
DMOBJ *nextobj = entryobj->nextobj;
@ -342,35 +340,65 @@ void disable_entry_obj(DMOBJ *entryobj, char *obj_path)
for (; (nextobj && nextobj->obj); nextobj++) {
if (DM_STRCMP(nextobj->obj, obj_path) == 0) {
BBF_INFO("## Excluding [%s%s.] from the core tree and the same object will be exposed again using (%s) ##", parent_obj, obj_path, plugin_path);
nextobj->bbfdm_type = BBFDM_NONE;
return;
}
}
if (entryobj->nextdynamicobj) {
for (int i = 0; i < 2; i++) {
struct dm_dynamic_obj *next_dyn_array = entryobj->nextdynamicobj + i;
if (next_dyn_array->nextobj) {
for (int j = 0; next_dyn_array->nextobj[j]; j++) {
DMOBJ *jentryobj = next_dyn_array->nextobj[j];
for (; (jentryobj && jentryobj->obj); jentryobj++) {
if (DM_STRCMP(jentryobj->obj, obj_path) == 0) {
TRACE("## Excluding [%s%s.] from the core tree and the same object will be exposed again using (%s) ##", parent_obj, obj_path, plugin_path);
jentryobj->bbfdm_type = BBFDM_NONE;
return;
}
}
}
}
}
}
}
void dm_exclude_obj(DMOBJ *entryobj, DMNODE *parent_node, char *obj_path)
void disable_entry_leaf(DMOBJ *entryobj, char *leaf_path, const char *parent_obj, const char *plugin_path)
{
char *parent_obj = parent_node->current_object;
if (!entryobj || !plugin_path || DM_STRLEN(leaf_path) == 0)
return;
for (; (entryobj && entryobj->obj); entryobj++) {
DMNODE node = {0};
node.obj = entryobj;
node.parent = parent_node;
node.instance_level = parent_node->instance_level;
node.matched = parent_node->matched;
DMLEAF *leaf = entryobj->leaf;
dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj);
if (DM_STRCMP(node.current_object, obj_path) == 0) {
entryobj->bbfdm_type = BBFDM_NONE;
for (; (leaf && leaf->parameter); leaf++) {
if (DM_STRCMP(leaf->parameter, leaf_path) == 0) {
BBF_INFO("## Excluding [%s%s] from the core tree and the same parameter will be exposed again using (%s) ##", parent_obj, leaf_path, plugin_path);
leaf->bbfdm_type = BBFDM_NONE;
return;
}
}
int err = plugin_obj_match(obj_path, &node);
if (err)
continue;
if (entryobj->dynamicleaf) {
for (int i = 0; i < 2; i++) {
struct dm_dynamic_leaf *next_dyn_array = entryobj->dynamicleaf + i;
if (next_dyn_array->nextleaf) {
for (int j = 0; next_dyn_array->nextleaf[j]; j++) {
DMLEAF *jleaf = next_dyn_array->nextleaf[j];
for (; (jleaf && jleaf->parameter); jleaf++) {
if (entryobj->nextobj)
dm_exclude_obj(entryobj->nextobj, &node, obj_path);
if (DM_STRCMP(jleaf->parameter, leaf_path) == 0) {
TRACE("## Excluding [%s%s] from the core tree and the same parameter will be exposed again using (%s) ##", parent_obj, leaf_path, plugin_path);
jleaf->bbfdm_type = BBFDM_NONE;
return;
}
}
}
}
}
}
}
@ -404,22 +432,15 @@ int get_leaf_idx(DMLEAF **entryleaf)
return idx;
}
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
void load_plugins(DMOBJ *dm_entryobj, const char *plugin_path)
{
int max_num_files = 256;
#ifdef BBF_VENDOR_EXTENSION
// Load objects and parameters exposed via vendor extension plugin
free_specific_dynamic_node(dm_entryobj, INDX_VENDOR_MOUNT);
load_vendor_dynamic_arrays(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude);
#endif /* BBF_VENDOR_EXTENSION */
if (DM_STRLEN(plugin_path) == 0)
return 0;
return;
if (!folder_exists(plugin_path)) {
return 0;
}
if (!folder_exists(plugin_path))
return;
free_json_plugins();
free_specific_dynamic_node(dm_entryobj, INDX_JSON_MOUNT);
@ -439,8 +460,6 @@ int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP
dmfree(files[i]);
}
return 0;
}
void free_plugins(DMOBJ *dm_entryobj)

View file

@ -12,15 +12,15 @@
#define __DMPLUGIN_H__
DMOBJ *find_entry_obj(DMOBJ *entryobj, char *obj_path);
void disable_entry_obj(DMOBJ *entryobj, char *obj_path);
void dm_exclude_obj(DMOBJ *entryobj, DMNODE *parent_node, char *obj_path);
void disable_entry_obj(DMOBJ *entryobj, char *obj_path, const char *parent_obj, const char *plugin_path);
void disable_entry_leaf(DMOBJ *entryobj, char *leaf_path, const char *parent_obj, const char *plugin_path);
int get_entry_idx(DMOBJ *entryobj);
int get_obj_idx(DMOBJ **entryobj);
int get_leaf_idx(DMLEAF **entryleaf);
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
void load_plugins(DMOBJ *dm_entryobj, const char *plugin_path);
void free_plugins(DMOBJ *dm_entryobj);
#endif //__DMPLUGIN_H__

View file

@ -42,6 +42,18 @@ static void free_all_list_open_library(struct list_head *library_list)
}
}
static void dotso_plugin_disable_requested_entries(DMOBJ *entryobj, DMOBJ *requested_obj, DMLEAF *requested_leaf, const char *parent_obj, const char *plugin_path)
{
if (!entryobj)
return;
for (; (requested_obj && requested_obj->obj); requested_obj++)
disable_entry_obj(entryobj, requested_obj->obj, parent_obj, plugin_path);
for (; (requested_leaf && requested_leaf->parameter); requested_leaf++)
disable_entry_leaf(entryobj, requested_leaf->parameter, parent_obj, plugin_path);
}
int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
{
#ifndef BBF_SCHEMA_FULL_TREE
@ -50,7 +62,7 @@ int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
void *handle = dlopen(plugin_path, RTLD_LAZY);
#endif
if (!handle) {
TRACE("Plugin failed [%s]\n", dlerror());
BBF_DEBUG("Plugin failed [%s]\n", dlerror());
return 0;
}
@ -60,7 +72,7 @@ int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
if (dynamic_obj == NULL) {
dlclose(handle);
TRACE("Plugin %s missing init symbol ...", plugin_path);
BBF_DEBUG("Plugin %s missing init symbol ...", plugin_path);
return 0;
}
@ -70,16 +82,14 @@ int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
if (!dm_entryobj)
continue;
if (dynamic_obj[i].root_obj) {
dotso_plugin_disable_requested_entries(dm_entryobj, dynamic_obj[i].root_obj, dynamic_obj[i].root_leaf, dynamic_obj[i].path, plugin_path);
// Disable object if it already exists in the main tree
disable_entry_obj(dm_entryobj, dynamic_obj[i].root_obj->obj);
if (dynamic_obj[i].root_obj) {
if (dm_entryobj->nextdynamicobj == NULL) {
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
}
if (dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj == NULL) {
@ -100,7 +110,6 @@ int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf));
dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
}
if (dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf == NULL) {

View file

@ -111,11 +111,23 @@ static void free_loaded_json_files(struct list_head *json_list)
}
}
void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len)
void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t len)
{
int last_occurent = 0, occur = 0;
if (!full_obj || !prefix_obj || len == 0)
return;
*prefix_obj = 0;
char *full_object = replace_str(full_obj, ".{i}.", ".");
if (full_object == NULL)
return;
unsigned int full_object_dot_num = count_occurrences(full_object, '.');
if (full_object_dot_num < 2)
return;
for (int i = 0; full_object[i] != 0; i++) {
if (full_object[i] == '.') {
@ -129,11 +141,23 @@ void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len)
FREE(full_object);
}
static void find_current_obj(char *full_obj, char *curr_obj, size_t len)
static void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, size_t len)
{
int last_occurent = 0, occur = 0;
if (!full_obj || !curr_obj || len == 0)
return;
*curr_obj = 0;
char *full_object = replace_str(full_obj, ".{i}.", ".");
if (full_object == NULL)
return;
unsigned int full_object_dot_num = count_occurrences(full_object, '.');
if (full_object_dot_num < 2)
return;
for (int i = 0; full_object[i] != 0; i++) {
if (full_object[i] == '.') {
@ -218,6 +242,42 @@ static int get_number_of_instances(char *refparam)
return nbr_inst;
}
static int get_bbfdm_type(struct json_object *protocols)
{
if (!protocols || json_object_get_type(protocols) != json_type_array)
return BBFDM_NONE;
size_t n_proto = json_object_array_length(protocols);
if (n_proto == 0)
return BBFDM_NONE;
if (n_proto == 1) {
struct json_object *proto = json_object_array_get_idx(protocols, 0);
const char *proto_str = json_object_get_string(proto);
if (strcmp(proto_str, "cwmp") == 0)
return BBFDM_CWMP;
else if (strcmp(proto_str, "usp") == 0)
return BBFDM_USP;
else
return BBFDM_NONE;
} else if (n_proto == 2) {
struct json_object *proto1 = json_object_array_get_idx(protocols, 0);
struct json_object *proto2 = json_object_array_get_idx(protocols, 1);
const char *proto_str1 = json_object_get_string(proto1);
const char *proto_str2 = json_object_get_string(proto2);
if ((strcmp(proto_str1, "cwmp") == 0 && strcmp(proto_str2, "usp") == 0) ||
(strcmp(proto_str1, "usp") == 0 && strcmp(proto_str2, "cwmp") == 0))
return BBFDM_BOTH;
else
return BBFDM_NONE;
} else {
return BBFDM_NONE;
}
}
static void replace_indexes(struct dmctx *ctx, char *old_key, char *new_key, size_t key_len)
{
char buf_key[256] = {0};
@ -1541,7 +1601,7 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type(6)*/
struct json_object *type = NULL, *protocols = NULL, *write = NULL, *async = NULL, *flags = NULL;
char full_param[512] = {0};
size_t n_proto, n_flags;
size_t n_flags;
// cppcheck-suppress nullPointerRedundantCheck
char **in_p = NULL, **out_p = NULL, **ev_arg = NULL, **tmp = NULL;
@ -1549,6 +1609,9 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
return;
char *param_ext = replace_str(param, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
if (!param_ext)
return;
//PARAM
pleaf[i].parameter = dm_dynamic_strdup(&json_memhead, param_ext);
@ -1658,19 +1721,7 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
//bbfdm_type
json_object_object_get_ex(jobj, "protocols", &protocols);
n_proto = protocols ? json_object_array_length(protocols) : 0;
if (n_proto == 2)
pleaf[i].bbfdm_type = BBFDM_BOTH;
else if (n_proto == 1) {
struct json_object *proto = protocols ? json_object_array_get_idx(protocols, 0) : NULL;
if (proto && strcmp(json_object_get_string(proto), "cwmp") == 0)
pleaf[i].bbfdm_type = BBFDM_CWMP;
else if (proto && strcmp(json_object_get_string(proto), "usp") == 0)
pleaf[i].bbfdm_type = BBFDM_USP;
else
pleaf[i].bbfdm_type = BBFDM_BOTH;
} else
pleaf[i].bbfdm_type = BBFDM_BOTH;
pleaf[i].bbfdm_type = get_bbfdm_type(protocols);
//dm_falgs
json_object_object_get_ex(jobj, "flags", &flags);
@ -1720,12 +1771,21 @@ void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json
char curr_obj[128] = {0};
count_obj_param_under_jsonobj(jobj, &obj_number, &param_number);
char *obj_path = replace_str(object, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
if (!obj_path)
return;
char *full_obj = replace_str(obj_path, ".{i}.", ".");
find_current_obj(full_obj, curr_obj, sizeof(curr_obj));
if (!full_obj) {
FREE(obj_path);
return;
}
json_plugin_find_current_obj(full_obj, curr_obj, sizeof(curr_obj));
FREE(obj_path);
if (!pobj)
if (!pobj || strlen(curr_obj) == 0)
return;
//OBJ
@ -1753,21 +1813,10 @@ void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json
pobj[index].checkdep = NULL;
json_object_object_foreach(jobj, key, json_obj) {
//bbfdm_type
if (strcmp(key, "protocols") == 0) {
size_t n_proto = json_obj ? json_object_array_length(json_obj) : 0;
if (n_proto == 2)
pobj[index].bbfdm_type = BBFDM_BOTH;
else if (n_proto == 1) {
struct json_object *proto = json_obj ? json_object_array_get_idx(json_obj, 0) : NULL;
if (proto && strcmp(json_object_get_string(proto), "cwmp") == 0)
pobj[index].bbfdm_type = BBFDM_CWMP;
else if (proto && strcmp(json_object_get_string(proto), "usp") == 0)
pobj[index].bbfdm_type = BBFDM_USP;
else
pobj[index].bbfdm_type = BBFDM_BOTH;
} else
pobj[index].bbfdm_type = BBFDM_BOTH;
pobj[index].bbfdm_type = get_bbfdm_type(json_obj);
}
//linker
@ -1823,40 +1872,58 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
json_object *json = json_object_from_file(plugin_path);
if (!json) {
TRACE("Plugin failed [%s]\n", plugin_path);
BBF_DEBUG("Plugin failed [%s]\n", plugin_path);
return 0;
}
json_object_object_foreach(json, key, jobj) {
if (!key)
break;
if (strcmp(key, "json_plugin_version") == 0) {
json_plugin_version = json_object_get_int(jobj);
continue;
}
char obj_prefix[MAX_DM_LENGTH] = {0};
char obj_name[64] = {0};
char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
find_current_obj(obj_path, obj_name, sizeof(obj_name));
if (obj_path == NULL) {
BBF_DEBUG("ERROR: Can't get the node object");
continue;
}
DMOBJ *dm_entryobj = find_entry_obj(entryobj, obj_prefix);
if (!dm_entryobj) {
if (strncmp(obj_path, "Device.", strlen("Device.")) != 0 || obj_path[strlen(obj_path) - 1] != '.') {
BBF_DEBUG("ERROR: Object (%s) not valid", obj_path);
FREE(obj_path);
continue;
}
// Disable object if it already exists in the main tree
disable_entry_obj(dm_entryobj, obj_name);
char obj_prefix[MAX_DM_LENGTH] = {0};
json_plugin_find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
if (strlen(obj_prefix) == 0) {
BBF_DEBUG("ERROR: Obj prefix is empty for (%s) Object", obj_path);
FREE(obj_path);
continue;
}
char curr_obj[128] = {0};
json_plugin_find_current_obj(obj_path, curr_obj, sizeof(curr_obj));
if (strlen(curr_obj) == 0) {
BBF_DEBUG("ERROR: Can't get the current object from (%s) parent object", obj_path);
FREE(obj_path);
continue;
}
DMOBJ *dm_entryobj = find_entry_obj(entryobj, obj_prefix);
if (!dm_entryobj) {
BBF_DEBUG("ERROR: entry obj doesn't exist for (%s) Object", obj_prefix);
FREE(obj_path);
continue;
}
disable_entry_obj(dm_entryobj, curr_obj, obj_prefix, plugin_path);
if (dm_entryobj->nextdynamicobj == NULL) {
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
dm_entryobj->nextdynamicobj[INDX_SERVICE_MOUNT].idx_type = INDX_SERVICE_MOUNT;
}
@ -1876,6 +1943,7 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
FREE(obj_path);
}
save_loaded_json_files(&loaded_json_files, json);
return 0;
}

View file

@ -16,7 +16,7 @@
void save_loaded_json_files(struct list_head *json_list, json_object *data);
void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json_version, struct list_head *list);
void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len);
void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t len);
int load_json_plugins(DMOBJ *entryobj, const char *path);
int free_json_plugins(void);

View file

@ -1,265 +0,0 @@
/*
* Copyright (C) 2023 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 Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "vendor_plugin.h"
#include "../dmplugin.h"
#ifndef BBF_VENDOR_LIST
#define BBF_VENDOR_LIST ""
#endif
static void overwrite_param(DMOBJ *entryobj, DMLEAF *leaf)
{
if (entryobj->leaf) {
DMLEAF *entryleaf = entryobj->leaf;
for (; (entryleaf && entryleaf->parameter); entryleaf++) {
if (DM_STRCMP(entryleaf->parameter, leaf->parameter) == 0) {
entryleaf->getvalue = leaf->getvalue;
entryleaf->setvalue = leaf->setvalue;
return;
}
}
}
}
static void overwrite_obj(DMOBJ *entryobj, DMOBJ *dmobj)
{
if (entryobj->nextobj) {
DMOBJ *entrynextobj = entryobj->nextobj;
for (; (entrynextobj && entrynextobj->obj); entrynextobj++) {
if (DM_STRCMP(entrynextobj->obj, dmobj->obj) == 0) {
entrynextobj->addobj = dmobj->addobj;
entrynextobj->delobj = dmobj->delobj;
entrynextobj->checkdep = dmobj->checkdep;
entrynextobj->browseinstobj = dmobj->browseinstobj;
entrynextobj->get_linker = dmobj->get_linker;
if (dmobj->leaf) {
DMLEAF *leaf = dmobj->leaf;
for (; (leaf && leaf->parameter); leaf++) {
overwrite_param(entrynextobj, leaf);
}
}
if (dmobj->nextobj) {
DMOBJ *dmnextobj = dmobj->nextobj;
for (; (dmnextobj && dmnextobj->obj); dmnextobj++) {
overwrite_obj(entrynextobj, dmnextobj);
}
}
return;
}
}
}
}
static void load_vendor_extension_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *vendor_map_obj)
{
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (int j = 0; vendor_map_obj && vendor_map_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_obj[j].vendor, tokens[idx]) != 0)
continue;
DM_MAP_OBJ *vendor_obj = vendor_map_obj[j].vendor_obj;
for (int i = 0; vendor_obj[i].path; i++) {
DMOBJ *dm_entryobj = find_entry_obj(entryobj, vendor_obj[i].path);
if (!dm_entryobj)
continue;
if (vendor_obj[i].root_obj) {
if (dm_entryobj->nextdynamicobj == NULL) {
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
dm_entryobj->nextdynamicobj[INDX_SERVICE_MOUNT].idx_type = INDX_SERVICE_MOUNT;
}
if (dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj == NULL) {
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj = calloc(2, sizeof(DMOBJ *));
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj[0] = vendor_obj[i].root_obj;
} else {
int obj_idx = get_obj_idx(dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj);
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj = realloc(dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj, (obj_idx + 2) * sizeof(DMOBJ *));
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj[obj_idx] = vendor_obj[i].root_obj;
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].nextobj[obj_idx+1] = NULL;
}
}
if (vendor_obj[i].root_leaf) {
if (dm_entryobj->dynamicleaf == NULL) {
dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf));
dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
}
if (dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf == NULL) {
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf = calloc(2, sizeof(DMLEAF *));
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf[0] = vendor_obj[i].root_leaf;
} else {
int leaf_idx = get_leaf_idx(dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf);
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf = realloc(dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf, (leaf_idx + 2) * sizeof(DMLEAF *));
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf[leaf_idx] = vendor_obj[i].root_leaf;
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].nextleaf[leaf_idx+1] = NULL;
}
}
}
break;
}
}
}
static void load_vendor_extension_overwrite_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *vendor_map_obj)
{
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (int j = 0; vendor_map_obj && vendor_map_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_obj[j].vendor, tokens[idx]) != 0)
continue;
DM_MAP_OBJ *dynamic_overwrite_obj = vendor_map_obj[j].vendor_obj;
for (int i = 0; dynamic_overwrite_obj[i].path; i++) {
DMOBJ *dm_entryobj = find_entry_obj(entryobj, dynamic_overwrite_obj[i].path);
if (!dm_entryobj)
continue;
if (dynamic_overwrite_obj[i].root_obj) {
DMOBJ *dmobj = dynamic_overwrite_obj[i].root_obj;
for (; (dmobj && dmobj->obj); dmobj++) {
overwrite_obj(dm_entryobj, dmobj);
}
}
if (dynamic_overwrite_obj[i].root_leaf) {
DMLEAF *leaf = dynamic_overwrite_obj[i].root_leaf;
for (; (leaf && leaf->parameter); leaf++) {
overwrite_param(dm_entryobj, leaf);
}
}
}
break;
}
}
}
static void exclude_obj(DMOBJ *dm_entryobj, char *in_obj)
{
DMNODE node = {.current_object = ""};
char *obj_path = replace_str(in_obj, ".{i}.", ".");
dm_exclude_obj(dm_entryobj, &node, obj_path);
FREE(obj_path);
}
static void exclude_param(DMOBJ *dm_entryobj, char *in_param)
{
char obj_prefix[256] = {'\0'};
if (in_param == NULL)
return;
char *ret = strrchr(in_param, '.');
if (ret)
DM_STRNCPY(obj_prefix, in_param, ret - in_param + 2);
DMOBJ *entryobj = find_entry_obj(dm_entryobj, obj_prefix);
if (entryobj) {
DMLEAF *leaf = entryobj->leaf;
for (; (leaf && leaf->parameter); leaf++) {
char param[1024];
snprintf(param, sizeof(param), obj_prefix, leaf->parameter);
if (strcmp(param, in_param) == 0) {
leaf->bbfdm_type = BBFDM_NONE;
return;
}
}
}
}
static void load_vendor_extension_exclude_arrays(DMOBJ *entryobj, DM_MAP_VENDOR_EXCLUDE *vendor_map_exclude_obj)
{
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (int j = 0; vendor_map_exclude_obj && vendor_map_exclude_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_exclude_obj[j].vendor, tokens[idx]) != 0)
continue;
char **dynamic_exclude_obj = vendor_map_exclude_obj[j].vendor_obj;
for (; *dynamic_exclude_obj; dynamic_exclude_obj++) {
if ((*dynamic_exclude_obj)[DM_STRLEN(*dynamic_exclude_obj) - 1] == '.')
exclude_obj(entryobj, *dynamic_exclude_obj);
else
exclude_param(entryobj, *dynamic_exclude_obj);
}
break;
}
}
}
void load_vendor_dynamic_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *VendorExtension[], DM_MAP_VENDOR_EXCLUDE *VendorExtensionExclude)
{
load_vendor_extension_arrays(entryobj, VendorExtension[0]);
load_vendor_extension_overwrite_arrays(entryobj, VendorExtension[1]);
load_vendor_extension_exclude_arrays(entryobj, VendorExtensionExclude);
}

View file

@ -1,19 +0,0 @@
/*
* Copyright (C) 2023 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 Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __VENDOR_PLUGIN_H__
#define __VENDOR_PLUGIN_H__
#include "../dmcommon.h"
void load_vendor_dynamic_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *VendorExtension[], DM_MAP_VENDOR_EXCLUDE *VendorExtensionExclude);
#endif //__VENDOR_PLUGIN_H__

View file

@ -2,8 +2,7 @@ cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm)
ADD_DEFINITIONS(-Wall -Werror)
ADD_DEFINITIONS(-D_GNU_SOURCE)
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/dmtree")
@ -11,10 +10,9 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOUR
OPTION(BBF_TR181 "build with tr181 datamodel" ON)
OPTION(BBF_TR143 "build with tr143 datamodel" ON)
OPTION(BBF_TR471 "build with tr471 datamodel" ON)
OPTION(BBF_VENDOR_EXTENSION "build with vendor extension enabled" ON)
OPTION(BBF_WIFI_DATAELEMENTS "build with wifi dataelements datamodel" ON)
SET(BBF_DM_SOURCES dmcommon.c)
SET(BBF_DM_SOURCES dmcommon.c dmlayer.c)
IF(BBF_TR181)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/dmtree/tr181")
@ -41,25 +39,7 @@ IF(BBF_TR471)
add_compile_definitions(BBF_TR471)
ENDIF(BBF_TR471)
IF(BBF_VENDOR_EXTENSION)
SET(BBF_VENDOR_EXTENSION_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/dmtree/vendor/vendor.c)
ADD_DEFINITIONS(-DBBF_VENDOR_LIST="${BBF_VENDOR_LIST}")
add_compile_definitions(BBF_VENDOR_EXTENSION)
SET(BBF_VENDOR_LIST "iopsys" CACHE STRING "vendor list to be used")
STRING(REPLACE "," ";" VENDOR_LIST ${BBF_VENDOR_LIST})
foreach(VENDOR IN LISTS VENDOR_LIST)
FILE(GLOB_RECURSE BBF_VENDOR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/dmtree/vendor/${VENDOR}/*.c)
LIST(APPEND BBF_VENDOR_EXTENSION_SOURCES ${BBF_VENDOR_SOURCES})
STRING(TOUPPER ${VENDOR} VENDOR)
add_compile_definitions(BBF_VENDOR_${VENDOR})
endforeach()
ENDIF(BBF_VENDOR_EXTENSION)
ADD_LIBRARY(bbfdm SHARED ${BBF_DM_SOURCES} ${BBF_TR181_SOURCES} ${BBF_TR143_SOURCES} ${BBF_TR471_SOURCES} ${BBF_VENDOR_EXTENSION_SOURCES})
ADD_LIBRARY(bbfdm SHARED ${BBF_DM_SOURCES} ${BBF_TR181_SOURCES} ${BBF_TR143_SOURCES} ${BBF_TR471_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm uci ubus ubox json-c blobmsg_json curl m bbfdm-api ssl crypto)
@ -70,11 +50,6 @@ INSTALL(DIRECTORY DESTINATION etc/bbfdm)
INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap)
INSTALL(DIRECTORY DESTINATION etc/bbfdm/plugins)
FILE(GLOB root_device dmtree/tr181/device.h dmtree/vendor/vendor.h)
INSTALL(FILES ${root_device}
DESTINATION usr/include/libbbfdm
)
IF(BBF_TR143)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm)
INSTALL(DIRECTORY DESTINATION usr/libexec/rpcd)
@ -88,3 +63,9 @@ IF(BBF_TR143)
DESTINATION usr/libexec/rpcd
)
ENDIF(BBF_TR143)
string(REPLACE "," ";" VENDOR_LIST ${BBF_VENDOR_LIST})
foreach(VENDOR ${VENDOR_LIST})
add_subdirectory(dmtree/vendor/${VENDOR})
endforeach()

View file

@ -546,449 +546,3 @@ end:
return res;
}
void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to)
{
char *proto = NULL;
char *device = NULL;
char *username = NULL;
char *password = NULL;
char *pppd_options = NULL;
char *service = NULL;
char *ac = NULL;
dmuci_get_value_by_section_string(s_from, "proto", &proto);
dmuci_get_value_by_section_string(s_from, "device", &device);
dmuci_get_value_by_section_string(s_from, "username", &username);
dmuci_get_value_by_section_string(s_from, "password", &password);
dmuci_get_value_by_section_string(s_from, "pppd_options", &pppd_options);
dmuci_get_value_by_section_string(s_from, "service", &service);
dmuci_get_value_by_section_string(s_from, "ac", &ac);
dmuci_set_value_by_section(s_to, "proto", proto);
dmuci_set_value_by_section(s_to, "device", DM_STRLEN(device) ? device : section_name(s_to));
dmuci_set_value_by_section(s_to, "username", username);
dmuci_set_value_by_section(s_to, "password", password);
dmuci_set_value_by_section(s_to, "pppd_options", pppd_options);
dmuci_set_value_by_section(s_to, "service", service);
dmuci_set_value_by_section(s_to, "ac", ac);
}
void ppp___reset_options(struct uci_section *ppp_s)
{
dmuci_set_value_by_section(ppp_s, "device", section_name(ppp_s));
dmuci_set_value_by_section(ppp_s, "username", "");
dmuci_set_value_by_section(ppp_s, "password", "");
dmuci_set_value_by_section(ppp_s, "pppd_options", "");
dmuci_set_value_by_section(ppp_s, "service", "");
dmuci_set_value_by_section(ppp_s, "ac", "");
}
void firewall__create_zone_section(char *s_name)
{
struct uci_section *s = NULL;
char *input = NULL;
char *output = NULL;
char *forward = NULL;
dmuci_get_option_value_string("firewall", "@defaults[0]", "input", &input);
dmuci_get_option_value_string("firewall", "@defaults[0]", "output", &output);
dmuci_get_option_value_string("firewall", "@defaults[0]", "forward", &forward);
dmuci_add_section("firewall", "zone", &s);
dmuci_rename_section_by_section(s, s_name);
dmuci_set_value_by_section(s, "name", s_name);
dmuci_set_value_by_section(s, "input", input);
dmuci_set_value_by_section(s, "output", output);
dmuci_set_value_by_section(s, "forward", forward);
dmuci_add_list_value_by_section(s, "network", s_name);
}
bool ip___is_ip_interface_instance_exists(const char *sec_name, const char *device)
{
struct uci_section *s = NULL;
char *curr_dev = NULL;
if (DM_STRLEN(sec_name) == 0 ||
DM_STRLEN(device) == 0)
return false;
uci_foreach_sections("network", "interface", s) {
dmuci_get_value_by_section_string(s, "device", &curr_dev);
if (DM_STRLEN(curr_dev) == 0 ||
DM_STRCMP(curr_dev, device) != 0)
continue;
struct uci_section *dmmap_s = NULL;
char *ip_inst = NULL;
if ((dmmap_s = get_dup_section_in_dmmap("dmmap_network", "interface", section_name(s))) != NULL) {
dmuci_get_value_by_section_string(dmmap_s, "ip_int_instance", &ip_inst);
if (strcmp(sec_name, section_name(s)) != 0 &&
DM_STRLEN(ip_inst) != 0)
return true;
}
}
return false;
}
void ip___update_child_interfaces(char *device, char *option_name, char *option_value)
{
struct uci_section *s = NULL;
if (DM_STRLEN(device) == 0)
return;
uci_foreach_option_eq("network", "interface", "device", device, s) {
dmuci_set_value_by_section(s, option_name, option_value);
}
}
static void ip___Update_IP_Interface_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "LowerLayers", path, dmmap_s) {
struct uci_section *iface_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char *curr_device = NULL;
dmuci_get_value_by_section_string(dmmap_s, "ip_int_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
iface_s = get_origin_section_from_config("network", "interface", sec_name);
if (!iface_s)
continue;
dmuci_get_value_by_section_string(iface_s, "device", &curr_device);
ip___update_child_interfaces(curr_device, "device", DM_STRLEN(linker) ? linker : section_name(iface_s));
}
}
static void ppp___Update_PPP_Interface_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_ppp", "interface", "LowerLayers", path, dmmap_s) {
struct uci_section *iface_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char proto[8] = {0};
dmuci_get_value_by_section_string(dmmap_s, "ppp_int_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "iface_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
iface_s = get_origin_section_from_config("network", "interface", sec_name);
snprintf(proto, sizeof(proto), "ppp%s", (DM_STRLEN(linker)) ? (!DM_LSTRNCMP(linker, "atm", 3) || !DM_LSTRNCMP(linker, "ptm", 3)) ? "oa" : "oe" : "");
// Update proto option
dmuci_set_value_by_section(dmmap_s, "proto", proto);
if (iface_s) dmuci_set_value_by_section(iface_s, "proto", proto);
// Update device option
dmuci_set_value_by_section(dmmap_s, "device", linker);
if (iface_s) dmuci_set_value_by_section(iface_s, "device", linker);
snprintf(curr_path, sizeof(curr_path), "Device.PPP.Interface.%s", instance);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, linker);
}
}
void ppp___Update_PPP_Interface_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
static void ethernet___Update_MAC_VLAN_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "LowerLayers", path, dmmap_s) {
struct uci_section *dev_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char name[32] = {0};
dmuci_get_value_by_section_string(dmmap_s, "mac_vlan_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
dev_s = get_origin_section_from_config("network", "device", sec_name);
if (!dev_s)
continue;
if (DM_STRLEN(linker)) {
char *dev_name = ethernet___get_ethernet_interface_name(linker);
snprintf(name, sizeof(name), "%s_%s", dev_name, instance);
}
dmuci_set_value_by_section(dev_s, "ifname", linker);
dmuci_set_value_by_section(dev_s, "name", name);
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet."BBF_VENDOR_PREFIX"MACVLAN.%s", instance);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(curr_path, name);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, name);
}
}
void ethernet___Update_MAC_VLAN_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
static void ethernet___Update_VLAN_Termination_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "LowerLayers", path, dmmap_s) {
struct uci_section *dev_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char name[32] = {0};
dmuci_get_value_by_section_string(dmmap_s, "vlan_term_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
dev_s = get_origin_section_from_config("network", "device", sec_name);
if (!dev_s)
continue;
if (DM_STRLEN(linker)) {
char *vid = NULL;
dmuci_get_value_by_section_string(dev_s, "vid", &vid);
snprintf(name, sizeof(name), "%s%s%s", linker, DM_STRLEN(vid) ? "." : "", DM_STRLEN(vid) ? vid : "");
}
dmuci_set_value_by_section(dev_s, "ifname", linker);
dmuci_set_value_by_section(dev_s, "name", name);
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet.VLANTermination.%s", instance);
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(curr_path, name);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(curr_path, name);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(curr_path, name);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, name);
}
}
void ethernet___Update_VLAN_Termination_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(path, linker);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(path, linker);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
void ethernet___Update_Link_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
uci_path_foreach_option_eq(bbfdm, "dmmap_ethernet", "link", "LowerLayers", path, dmmap_s) {
char *instance = NULL;
char curr_path[128] = {0};
dmuci_get_value_by_section_string(dmmap_s, "link_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_set_value_by_section(dmmap_s, "device", linker);
if (match(path, "Device.Bridging.Bridge.*.Port.", 0, NULL)) {
// Remove unused Interface section created by Bridge Object if it exists
struct uci_section *s = get_dup_section_in_config_opt("network", "interface", "device", linker);
dmuci_delete_by_section(s, NULL, NULL);
}
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet.Link.%s", instance);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, linker);
}
}
void ethernet___Update_Link_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(path, linker);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(path, linker);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
void bridging___get_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char **value)
{
struct uci_list *uci_opt_list = NULL;
struct uci_element *e = NULL;
char uci_value[256] = {0};
unsigned pos = 0;
if (!data || !uci_opt_name)
return;
dmuci_get_value_by_section_list(device_sec, uci_opt_name, &uci_opt_list);
if (uci_opt_list == NULL)
return;
uci_value[0] = '\0';
/* traverse each list value and create comma separated output */
uci_foreach_element(uci_opt_list, e) {
//delimiting priority which is in the form of x:y where y is the priority
char *priority = strchr(e->name, ':');
if (priority)
pos += snprintf(&uci_value[pos], sizeof(uci_value) - pos, "%s,", priority + 1);
}
if (pos)
uci_value[pos - 1] = 0;
dmasprintf(value, "%s", uci_value);
}
void bridging___set_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char *value)
{
char *pch = NULL, *pchr = NULL;
int idx = 0;
if (!data || !uci_opt_name || !value)
return;
/* delete current list values */
dmuci_set_value_by_section(device_sec, uci_opt_name, "");
/* tokenize each value from received comma separated string and add it to uci file in the format x:y
x being priority and y being priority to be mapped to */
for (pch = strtok_r(value, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr), idx++) {
char buf[16] = {0};
/* convert values to uci format (x:y) and add */
snprintf(buf, sizeof(buf), "%d%c%s", idx, ':', pch);
dmuci_add_list_value_by_section(device_sec, uci_opt_name, buf);
}
}
struct uci_section *ethernet___get_ethernet_interface_section(const char *device_name)
{
struct uci_section *s = NULL;
uci_foreach_sections("network", "device", s) {
char *name = NULL;
if (!dmuci_is_option_value_empty(s, "type"))
continue;
dmuci_get_value_by_section_string(s, "name", &name);
if (DM_STRCMP(name, device_name) == 0)
return s;
}
return NULL;
}
char *ethernet___get_ethernet_interface_name(char *device_name)
{
char *dev_name = dmstrdup(device_name);
if (!ethernet___get_ethernet_interface_section(dev_name)) {
struct uci_section *dev_s = NULL;
dev_s = get_dup_section_in_config_opt("network", "device", "name", dev_name);
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
if (dev_s) { // Verify if the device has dual tags
char *type = NULL;
dmuci_get_value_by_section_string(dev_s, "type", &type);
if (DM_STRCMP(type, "8021ad") == 0) {
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
}
}
}
return dev_name;
}

View file

@ -15,6 +15,8 @@
#include "libbbfdm-api/dmcommon.h"
#include <libubox/uloop.h>
#include "dmlayer.h"
#define HTTP_URI "http"
#define FTP_URI "ftp"
#define FILE_URI "file://"
@ -57,24 +59,4 @@ int bbf_fw_image_download(const char *url, const char *auto_activate, const char
const char *file_size, const char *checksum_algorithm, const char *checksum,
const char *bank_id, const char *command, const char *obj_path, const char *commandKey);
bool ip___is_ip_interface_instance_exists(const char *sec_name, const char *device);
void ip___update_child_interfaces(char *device, char *option_name, char *option_value);
void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to);
void ppp___reset_options(struct uci_section *ppp_s);
void ppp___Update_PPP_Interface_Top_Layers(char *path, char *linker);
void ethernet___Update_MAC_VLAN_Top_Layers(char *path, char *linker);
void ethernet___Update_VLAN_Termination_Top_Layers(char *path, char *linker);
void ethernet___Update_Link_Layer(char *path, char *linker);
void ethernet___Update_Link_Top_Layers(char *path, char *linker);
void bridging___get_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char **value);
void bridging___set_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char *value);
void firewall__create_zone_section(char *s_name);
struct uci_section *ethernet___get_ethernet_interface_section(const char *device_name);
char *ethernet___get_ethernet_interface_name(char *device_name);
#endif //__DMCOMMON_H__

457
libbbfdm/dmlayer.c Normal file
View file

@ -0,0 +1,457 @@
/*
* Copyright (C) 2023 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 Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "dmlayer.h"
void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to)
{
char *proto = NULL;
char *device = NULL;
char *username = NULL;
char *password = NULL;
char *pppd_options = NULL;
char *service = NULL;
char *ac = NULL;
dmuci_get_value_by_section_string(s_from, "proto", &proto);
dmuci_get_value_by_section_string(s_from, "device", &device);
dmuci_get_value_by_section_string(s_from, "username", &username);
dmuci_get_value_by_section_string(s_from, "password", &password);
dmuci_get_value_by_section_string(s_from, "pppd_options", &pppd_options);
dmuci_get_value_by_section_string(s_from, "service", &service);
dmuci_get_value_by_section_string(s_from, "ac", &ac);
dmuci_set_value_by_section(s_to, "proto", proto);
dmuci_set_value_by_section(s_to, "device", DM_STRLEN(device) ? device : section_name(s_to));
dmuci_set_value_by_section(s_to, "username", username);
dmuci_set_value_by_section(s_to, "password", password);
dmuci_set_value_by_section(s_to, "pppd_options", pppd_options);
dmuci_set_value_by_section(s_to, "service", service);
dmuci_set_value_by_section(s_to, "ac", ac);
}
void ppp___reset_options(struct uci_section *ppp_s)
{
dmuci_set_value_by_section(ppp_s, "device", section_name(ppp_s));
dmuci_set_value_by_section(ppp_s, "username", "");
dmuci_set_value_by_section(ppp_s, "password", "");
dmuci_set_value_by_section(ppp_s, "pppd_options", "");
dmuci_set_value_by_section(ppp_s, "service", "");
dmuci_set_value_by_section(ppp_s, "ac", "");
}
void firewall__create_zone_section(char *s_name)
{
struct uci_section *s = NULL;
char *input = NULL;
char *output = NULL;
char *forward = NULL;
dmuci_get_option_value_string("firewall", "@defaults[0]", "input", &input);
dmuci_get_option_value_string("firewall", "@defaults[0]", "output", &output);
dmuci_get_option_value_string("firewall", "@defaults[0]", "forward", &forward);
dmuci_add_section("firewall", "zone", &s);
dmuci_rename_section_by_section(s, s_name);
dmuci_set_value_by_section(s, "name", s_name);
dmuci_set_value_by_section(s, "input", input);
dmuci_set_value_by_section(s, "output", output);
dmuci_set_value_by_section(s, "forward", forward);
dmuci_add_list_value_by_section(s, "network", s_name);
}
bool ip___is_ip_interface_instance_exists(const char *sec_name, const char *device)
{
struct uci_section *s = NULL;
char *curr_dev = NULL;
if (DM_STRLEN(sec_name) == 0 ||
DM_STRLEN(device) == 0)
return false;
uci_foreach_sections("network", "interface", s) {
dmuci_get_value_by_section_string(s, "device", &curr_dev);
if (DM_STRLEN(curr_dev) == 0 ||
DM_STRCMP(curr_dev, device) != 0)
continue;
struct uci_section *dmmap_s = NULL;
char *ip_inst = NULL;
if ((dmmap_s = get_dup_section_in_dmmap("dmmap_network", "interface", section_name(s))) != NULL) {
dmuci_get_value_by_section_string(dmmap_s, "ip_int_instance", &ip_inst);
if (strcmp(sec_name, section_name(s)) != 0 &&
DM_STRLEN(ip_inst) != 0)
return true;
}
}
return false;
}
void ip___update_child_interfaces(char *device, char *option_name, char *option_value)
{
struct uci_section *s = NULL;
if (DM_STRLEN(device) == 0)
return;
uci_foreach_option_eq("network", "interface", "device", device, s) {
dmuci_set_value_by_section(s, option_name, option_value);
}
}
static void ip___Update_IP_Interface_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "interface", "LowerLayers", path, dmmap_s) {
struct uci_section *iface_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char *curr_device = NULL;
dmuci_get_value_by_section_string(dmmap_s, "ip_int_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
iface_s = get_origin_section_from_config("network", "interface", sec_name);
if (!iface_s)
continue;
dmuci_get_value_by_section_string(iface_s, "device", &curr_device);
ip___update_child_interfaces(curr_device, "device", DM_STRLEN(linker) ? linker : section_name(iface_s));
}
}
static void ppp___Update_PPP_Interface_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_ppp", "interface", "LowerLayers", path, dmmap_s) {
struct uci_section *iface_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char proto[8] = {0};
dmuci_get_value_by_section_string(dmmap_s, "ppp_int_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "iface_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
iface_s = get_origin_section_from_config("network", "interface", sec_name);
snprintf(proto, sizeof(proto), "ppp%s", (DM_STRLEN(linker)) ? (!DM_LSTRNCMP(linker, "atm", 3) || !DM_LSTRNCMP(linker, "ptm", 3)) ? "oa" : "oe" : "");
// Update proto option
dmuci_set_value_by_section(dmmap_s, "proto", proto);
if (iface_s) dmuci_set_value_by_section(iface_s, "proto", proto);
// Update device option
dmuci_set_value_by_section(dmmap_s, "device", linker);
if (iface_s) dmuci_set_value_by_section(iface_s, "device", linker);
snprintf(curr_path, sizeof(curr_path), "Device.PPP.Interface.%s", instance);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, linker);
}
}
void ppp___Update_PPP_Interface_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
static void ethernet___Update_MAC_VLAN_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "LowerLayers", path, dmmap_s) {
struct uci_section *dev_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char name[32] = {0};
dmuci_get_value_by_section_string(dmmap_s, "mac_vlan_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
dev_s = get_origin_section_from_config("network", "device", sec_name);
if (!dev_s)
continue;
if (DM_STRLEN(linker)) {
char *dev_name = ethernet___get_ethernet_interface_name(linker);
snprintf(name, sizeof(name), "%s_%s", dev_name, instance);
}
dmuci_set_value_by_section(dev_s, "ifname", linker);
dmuci_set_value_by_section(dev_s, "name", name);
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet."BBF_VENDOR_PREFIX"MACVLAN.%s", instance);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(curr_path, name);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, name);
}
}
void ethernet___Update_MAC_VLAN_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
static void ethernet___Update_VLAN_Termination_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
uci_path_foreach_option_eq(bbfdm, "dmmap_network", "device", "LowerLayers", path, dmmap_s) {
struct uci_section *dev_s = NULL;
char *sec_name = NULL;
char *instance = NULL;
char curr_path[128] = {0};
char name[32] = {0};
dmuci_get_value_by_section_string(dmmap_s, "vlan_term_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_get_value_by_section_string(dmmap_s, "section_name", &sec_name);
if (!DM_STRLEN(sec_name))
continue;
dev_s = get_origin_section_from_config("network", "device", sec_name);
if (!dev_s)
continue;
if (DM_STRLEN(linker)) {
char *vid = NULL;
dmuci_get_value_by_section_string(dev_s, "vid", &vid);
snprintf(name, sizeof(name), "%s%s%s", linker, DM_STRLEN(vid) ? "." : "", DM_STRLEN(vid) ? vid : "");
}
dmuci_set_value_by_section(dev_s, "ifname", linker);
dmuci_set_value_by_section(dev_s, "name", name);
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet.VLANTermination.%s", instance);
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(curr_path, name);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(curr_path, name);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(curr_path, name);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, name);
}
}
void ethernet___Update_VLAN_Termination_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(path, linker);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(path, linker);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
void ethernet___Update_Link_Layer(char *path, char *linker)
{
struct uci_section *dmmap_s = NULL;
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
uci_path_foreach_option_eq(bbfdm, "dmmap_ethernet", "link", "LowerLayers", path, dmmap_s) {
char *instance = NULL;
char curr_path[128] = {0};
dmuci_get_value_by_section_string(dmmap_s, "link_instance", &instance);
if (!DM_STRLEN(instance))
continue;
dmuci_set_value_by_section(dmmap_s, "device", linker);
if (match(path, "Device.Bridging.Bridge.*.Port.", 0, NULL)) {
// Remove unused Interface section created by Bridge Object if it exists
struct uci_section *s = get_dup_section_in_config_opt("network", "interface", "device", linker);
dmuci_delete_by_section(s, NULL, NULL);
}
snprintf(curr_path, sizeof(curr_path), "Device.Ethernet.Link.%s", instance);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(curr_path, linker);
}
}
void ethernet___Update_Link_Top_Layers(char *path, char *linker)
{
char *p = DM_STRRCHR(path, '.');
if (p) *p = 0;
// Update VLAN Termination instance if exists
ethernet___Update_VLAN_Termination_Layer(path, linker);
// Update MACVLAN instance if exists
ethernet___Update_MAC_VLAN_Layer(path, linker);
// Update PPP Interface instance if exists
ppp___Update_PPP_Interface_Layer(path, linker);
// Update IP Interface instance if exists
ip___Update_IP_Interface_Layer(path, linker);
}
void bridging___get_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char **value)
{
struct uci_list *uci_opt_list = NULL;
struct uci_element *e = NULL;
char uci_value[256] = {0};
unsigned pos = 0;
if (!data || !uci_opt_name)
return;
dmuci_get_value_by_section_list(device_sec, uci_opt_name, &uci_opt_list);
if (uci_opt_list == NULL)
return;
uci_value[0] = '\0';
/* traverse each list value and create comma separated output */
uci_foreach_element(uci_opt_list, e) {
//delimiting priority which is in the form of x:y where y is the priority
char *priority = strchr(e->name, ':');
if (priority)
pos += snprintf(&uci_value[pos], sizeof(uci_value) - pos, "%s,", priority + 1);
}
if (pos)
uci_value[pos - 1] = 0;
dmasprintf(value, "%s", uci_value);
}
void bridging___set_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char *value)
{
char *pch = NULL, *pchr = NULL;
int idx = 0;
if (!data || !uci_opt_name || !value)
return;
/* delete current list values */
dmuci_set_value_by_section(device_sec, uci_opt_name, "");
/* tokenize each value from received comma separated string and add it to uci file in the format x:y
x being priority and y being priority to be mapped to */
for (pch = strtok_r(value, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr), idx++) {
char buf[16] = {0};
/* convert values to uci format (x:y) and add */
snprintf(buf, sizeof(buf), "%d%c%s", idx, ':', pch);
dmuci_add_list_value_by_section(device_sec, uci_opt_name, buf);
}
}
struct uci_section *ethernet___get_ethernet_interface_section(const char *device_name)
{
struct uci_section *s = NULL;
uci_foreach_sections("network", "device", s) {
char *name = NULL;
if (!dmuci_is_option_value_empty(s, "type"))
continue;
dmuci_get_value_by_section_string(s, "name", &name);
if (DM_STRCMP(name, device_name) == 0)
return s;
}
return NULL;
}
char *ethernet___get_ethernet_interface_name(char *device_name)
{
char *dev_name = dmstrdup(device_name);
if (!ethernet___get_ethernet_interface_section(dev_name)) {
struct uci_section *dev_s = NULL;
dev_s = get_dup_section_in_config_opt("network", "device", "name", dev_name);
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
if (dev_s) { // Verify if the device has dual tags
char *type = NULL;
dmuci_get_value_by_section_string(dev_s, "type", &type);
if (DM_STRCMP(type, "8021ad") == 0) {
char *has_vid = DM_STRRCHR(dev_name, '.');
if (has_vid)
*has_vid = '\0';
}
}
}
return dev_name;
}

37
libbbfdm/dmlayer.h Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 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 Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __DMLAYER_H__
#define __DMLAYER_H__
#include "libbbfdm-api/dmcommon.h"
bool ip___is_ip_interface_instance_exists(const char *sec_name, const char *device);
void ip___update_child_interfaces(char *device, char *option_name, char *option_value);
void ppp___update_sections(struct uci_section *s_from, struct uci_section *s_to);
void ppp___reset_options(struct uci_section *ppp_s);
void ppp___Update_PPP_Interface_Top_Layers(char *path, char *linker);
void ethernet___Update_MAC_VLAN_Top_Layers(char *path, char *linker);
void ethernet___Update_VLAN_Termination_Top_Layers(char *path, char *linker);
void ethernet___Update_Link_Layer(char *path, char *linker);
void ethernet___Update_Link_Top_Layers(char *path, char *linker);
void bridging___get_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char **value);
void bridging___set_priority_list(struct uci_section *device_sec, char *uci_opt_name, void *data, char *value);
void firewall__create_zone_section(char *s_name);
struct uci_section *ethernet___get_ethernet_interface_section(const char *device_name);
char *ethernet___get_ethernet_interface_name(char *device_name);
#endif //__DMLAYER_H__

View file

@ -88,12 +88,6 @@ DM_MAP_OBJ tDynamicObj[] = {
{0}
};
DMOBJ tEntryRoot[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceObj, tDeviceParams, NULL, BBFDM_BOTH},
{0}
};
/* *** Device. *** */
DMOBJ tDeviceObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/

View file

@ -17,7 +17,7 @@
extern DM_MAP_OBJ tDynamicObj[];
extern DMOBJ tEntryRoot[];
extern DMOBJ tDeviceObj[];
extern DMLEAF tDeviceParams[];
#endif

View file

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm_iopsys_ext)
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
FILE(GLOB BBF_IOPSYS_VENDOR_EXTENSION_SOURCES ../../../dmlayer.c *.c)
ADD_LIBRARY(bbfdm_iopsys_ext SHARED ${BBF_IOPSYS_VENDOR_EXTENSION_SOURCES})
INSTALL(TARGETS bbfdm_iopsys_ext
LIBRARY DESTINATION etc/bbfdm/plugins)

View file

@ -12,7 +12,7 @@
#ifndef __IOPSYS_ETHERNET_H
#define __IOPSYS_ETHERNET_H
#include "dmcommon.h"
#include "dmlayer.h"
extern DMOBJ tIOPSYS_EthernetObj[];
extern DMLEAF tEthernetMACVLANParams[];

View file

@ -16,20 +16,15 @@
#include "ip.h"
#include "times.h"
#include "wifi.h"
#include "vendor.h"
#include "extension.h"
DM_MAP_OBJ tVendorExtensionIOPSYS[] = {
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.", tIOPSYS_DeviceObj, NULL},
{"Device.DeviceInfo.", NULL, tIOPSYS_DeviceInfoParams},
{"Device.Ethernet.", tIOPSYS_EthernetObj, NULL},
{"Device.Time.", NULL, tIOPSYS_TimeParams},
{"Device.Bridging.Bridge.{i}.Port.{i}.", NULL, tIOPSYS_BridgingBridgePortParams},
//{"Device.Services.VoiceService.{i}.CallLog.{i}.", NULL, tIOPSYS_VoiceServiceCallLogParams},
//{"Device.Services.VoiceService.{i}.CallLog.{i}.Session.{i}.Source.RTP.", NULL, tIOPSYS_VoiceServiceCallLogSessionSourceRTPParams},
//{"Device.Services.VoiceService.{i}.CallLog.{i}.Session.{i}.Destination.RTP.", NULL, tIOPSYS_VoiceServiceCallLogSessionDestinationRTPParams},
//{"Device.Services.VoiceService.{i}.DECT.Portable.{i}.", NULL, tIOPSYS_VoiceServiceDECTPortableParams},
//{"Device.Services.VoiceService.{i}.CallControl.Extension.{i}.", NULL, tIOPSYS_VoiceServiceCallControlExtensionParams},
{"Device.WiFi.AccessPoint.{i}.", NULL, tIOPSYS_WiFiAccessPointParams},
{0}
};

View file

@ -1,41 +0,0 @@
/*
* Copyright (C) 2021 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 <amin.benramdhane@pivasoftware.com>
*
*/
#include "device.h"
#include "deviceinfo.h"
#include "firewall.h"
#include "vendor.h"
DM_MAP_OBJ tVendorExtensionOverwriteTEST[] = {
/* parentobj, nextobject, parameter */
{"Device.DeviceInfo.", NULL, tTEST_DeviceInfoParams},
{"Device.Firewall.Chain.{i}.Rule.{i}.", NULL, tTEST_FirewallRuleParams},
{0}
};
DM_MAP_OBJ tVendorExtensionTEST[] = {
/* parentobj, nextobject, parameter */
{"Device.", tTEST_DeviceObj, NULL},
{"Device.Firewall.Chain.{i}.Rule.{i}.", tTEST_FirewallChainRuleObj, tTEST_FirewallChainRuleParams},
{0}
};
char *VendorExtensionExcludeTEST[] = {
"Device.USB.", //Object
"Device.DeviceInfo.VendorConfigFile.{i}.", //Object
"Device.DSL.Channel.{i}.Stats.", //Object
"Device.QoS.Queue.{i}.SchedulerAlgorithm", //Parameter
"Device.FAST.Line.{i}.Stats.CurrentDay.ErroredSecs", //Parameter
"Device.Ethernet.RMONStats.{i}.Packets1024to1518Bytes", //Parameter
NULL
};

View file

@ -1,58 +0,0 @@
/*
* Copyright (C) 2021 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 <amin.benramdhane@pivasoftware.com>
*
*/
#include "vendor.h"
#ifdef BBF_VENDOR_IOPSYS
#include "iopsys/tr181/vendor.h"
#endif
#ifdef BBF_VENDOR_TEST
#include "test/tr181/vendor.h"
#endif
/** This table is defined to add a new custom obj/param in the tree **/
DM_MAP_VENDOR tVendorExtension[] = {
/* customer, tableobject */
#ifdef BBF_VENDOR_IOPSYS
{"iopsys", tVendorExtensionIOPSYS},
#endif
#ifdef BBF_VENDOR_TEST
{"test", tVendorExtensionTEST},
#endif
{0}
};
/** This table is defined to overwrite an existing obj/param in the tree **/
DM_MAP_VENDOR tVendorExtensionOverwrite[] = {
/* customer, tableobject */
#ifdef BBF_VENDOR_TEST
{"test", tVendorExtensionOverwriteTEST},
#endif
{0}
};
/** This table is defined to exclude some obj/param from the tree **/
DM_MAP_VENDOR_EXCLUDE tVendorExtensionExclude[] = {
/* customer, tableobject */
#ifdef BBF_VENDOR_TEST
{"test", VendorExtensionExcludeTEST},
#endif
{0}
};

View file

@ -1,21 +0,0 @@
/*
* Copyright (C) 2021 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 <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __VENDOR_EXTENSION_H
#define __VENDOR_EXTENSION_H
#include "libbbfdm-api/dmcommon.h"
extern DM_MAP_VENDOR tVendorExtension[];
extern DM_MAP_VENDOR tVendorExtensionOverwrite[];
extern DM_MAP_VENDOR_EXCLUDE tVendorExtensionExclude[];
#endif //__VENDOR_EXTENSION_H

View file

@ -7,15 +7,13 @@
#include <libbbfdm-api/dmapi.h>
#include <libbbfdm-api/dmentry.h>
#include <libbbfdm/device.h>
#include <libbbfdm/vendor.h>
#include "../../libbbfdm/dmtree/tr181/device.h"
static DMOBJ *TR181_ROOT_TREE = tEntryRoot;
static DM_MAP_VENDOR *TR181_VENDOR_EXTENSION[2] = {
tVendorExtension,
tVendorExtensionOverwrite
static DMOBJ TR181_ROOT_TREE[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceObj, tDeviceParams, NULL, BBFDM_BOTH},
{0}
};
static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
static int setup(void **state)
{
@ -23,7 +21,7 @@ static int setup(void **state)
if (!ctx)
return -1;
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
*state = ctx;
@ -43,7 +41,7 @@ static int teardown_commit(void **state)
static int group_init(void **state)
{
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, "/etc/bbfdm/plugins");
bbf_global_init(TR181_ROOT_TREE, "/etc/bbfdm/plugins");
return 0;
}
@ -71,7 +69,7 @@ static void validate_parameter(struct dmctx *ctx, const char *name, const char *
}
bbf_ctx_clean_sub(ctx);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE);
}
static void test_api_bbfdm_get_set_standard_parameter(void **state)
@ -176,12 +174,22 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state)
// get value ==> expected "0" error
ctx->in_param = "Device.UCI_TEST_V1.Password";
ctx->dm_type = BBFDM_CWMP;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter : name, type, value
validate_parameter(ctx, "Device.UCI_TEST_V1.Password", "", "xsd:string");
// get value ==> expected "0" error
ctx->in_param = "Device.UCI_TEST_V1.Password";
ctx->dm_type = BBFDM_USP;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter : name, type, value
validate_parameter(ctx, "Device.UCI_TEST_V1.Password", "iopsys_test", "xsd:string");
// validate uci config
fault = dmuci_get_option_value_string("users", "user", "password_required", &value);
assert_int_equal(fault, 0);
@ -189,6 +197,7 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state)
// get value ==> expected "0" error
ctx->in_param = "Device.UCI_TEST_V1.OWSDNumberOfEntries";
ctx->dm_type = BBFDM_BOTH;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
@ -267,12 +276,22 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state)
// get value ==> expected "0" error
ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password";
ctx->dm_type = BBFDM_CWMP;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter : name, type, value
validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.3.Password", "", "xsd:string");
// get value ==> expected "0" error
ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password";
ctx->dm_type = BBFDM_USP;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter : name, type, value
validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.3.Password", "owsd_pwd", "xsd:string");
// validate uci config
fault = dmuci_get_option_value_string("owsd", "@owsd_listen[2]", "password", &value);
assert_int_equal(fault, 0);
@ -280,6 +299,7 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state)
// get value ==> expected "0" error
ctx->in_param = "Device.UBUS_TEST_V1.Uptime";
ctx->dm_type = BBFDM_BOTH;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
@ -483,7 +503,6 @@ static void test_api_bbfdm_get_set_standard_parameter_alias(void **state)
validate_parameter(ctx, "Device.WiFi.Radio.[iopsys_test].Channel", "116", "xsd:unsignedInt");
}
#if 0
static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
@ -494,19 +513,26 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "64t", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Enable";
ctx->in_value = "64t";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "truee", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Enable";
ctx->in_value = "truee";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "true", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Enable";
ctx->in_value = "true";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Enable";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -517,41 +543,54 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Mapping without range: Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "64t", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries";
ctx->in_value = "64t";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "15600", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries";
ctx->in_value = "15600";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "15600", "xsd:unsignedInt");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1050", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Port";
ctx->in_value = "1050";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [0-1000] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1000", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Port";
ctx->in_value = "1000";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Port";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Port", "1000", "xsd:unsignedInt");
// Mapping with range: set value in the second range [15000-65535] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "20546", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Port";
ctx->in_value = "20546";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Port";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -562,56 +601,74 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Mapping with range (only min): Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-300", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Min_value";
ctx->in_value = "-300";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-273", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Min_value";
ctx->in_value = "-273";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Min_value";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-273", "xsd:int");
// Mapping with range (only max): Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "280", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Max_value";
ctx->in_value = "280";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [0-1000] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "274", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Max_value";
ctx->in_value = "274";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Max_value";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Max_value", "274", "xsd:int");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-3", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Value";
ctx->in_value = "-3";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [-10:-5] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-7", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Value";
ctx->in_value = "-7";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Value";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.value", "-7", "xsd:int");
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Value", "-7", "xsd:int");
// Mapping with range: set value in the second range [-1:10] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "1", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Value";
ctx->in_value = "1";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Value";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -622,41 +679,54 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Mapping without range: Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "64t", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes";
ctx->in_value = "64t";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "15600", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes";
ctx->in_value = "15600";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "15600", "xsd:unsignedLong");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "499", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_packets";
ctx->in_value = "499";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [0-100] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "99", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_packets";
ctx->in_value = "99";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_packets";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "99", "xsd:unsignedLong");
// Mapping with range: set value in the second range [500-3010] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "1024", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_packets";
ctx->in_value = "1024";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Nbr_packets";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -667,45 +737,60 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Mapping without range: Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-300t", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.MaxTxPower";
ctx->in_value = "-300t";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-273", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.MaxTxPower";
ctx->in_value = "-273";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.MaxTxPower";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-273", "xsd:long");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "-91", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
ctx->in_value = "-91";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [-90:36] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "274", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
ctx->in_value = "274";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "274", "xsd:long");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "37", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
ctx->in_value = "37";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [70:360] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "70", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
ctx->in_value = "70";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -716,19 +801,26 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2030-01-01T11:22:33.2Z", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.AssociationTime";
ctx->in_value = "2030-01-01T11:22:33.2Z";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22.2222Z", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.AssociationTime";
ctx->in_value = "2022-01-01T12:20:22.2222Z";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22Z", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.AssociationTime";
ctx->in_value = "2022-01-01T12:20:22Z";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.AssociationTime";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -739,56 +831,74 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Mapping without range: Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64t", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.ButtonColor";
ctx->in_value = "64t";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64ab78cef12", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.ButtonColor";
ctx->in_value = "64ab78cef12";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.ButtonColor";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64ab78cef12", "xsd:hexBinary");
// Mapping with range: Set Wrong Value out of range ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "am123", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TextColor";
ctx->in_value = "am123";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Mapping with range: set value in the first range [3-3] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "123abc", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TextColor";
ctx->in_value = "123abc";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TextColor";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TextColor", "123abc", "xsd:hexBinary");
// Mapping with range: set value in the second range [5-5] ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "12345abcde", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TextColor";
ctx->in_value = "12345abcde";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TextColor";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TextColor", "12345abcde", "xsd:hexBinary");
// Mapping without range: Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "12345abce", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.BackgroundColor";
ctx->in_value = "12345abce";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "45a1bd", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.BackgroundColor";
ctx->in_value = "45a1bd";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.BackgroundColor";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -799,56 +909,74 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "64", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Interface";
ctx->in_value = "64";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "wan", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Interface";
ctx->in_value = "wan";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Interface";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Interface", "wan", "xsd:string");
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.1.789", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.IPAddr";
ctx->in_value = "192.168.1.789";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.117.45", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.IPAddr";
ctx->in_value = "192.168.117.45";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.IPAddr";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.117.45", "xsd:string");
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-D", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Protocol";
ctx->in_value = "OMA-D";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-DM", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Protocol";
ctx->in_value = "OMA-DM";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Protocol";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-DM", "xsd:string");
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", "bbf validate test", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Description";
ctx->in_value = "bbf validate test";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Description";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -859,41 +987,57 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "te,be,re,yu", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.FailureReasons";
ctx->in_value = "te,be,re,yu";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "ExcessiveDelay,InsufficientBuffers", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.FailureReasons";
ctx->in_value = "ExcessiveDelay,InsufficientBuffers";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "LowRate,Other", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.FailureReasons";
ctx->in_value = "LowRate,Other";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.FailureReasons";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "LowRate,Other", "xsd:string");
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "200MHz,10MHz", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths";
ctx->in_value = "200MHz,10MHz";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "ExcessiveDelay,InsufficientBuffers", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths";
ctx->in_value = "ExcessiveDelay,InsufficientBuffers";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "40MHz,80+80MHz", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths";
ctx->in_value = "40MHz,80+80MHz";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths";
ctx->in_value = "";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
ctx->in_param = "";
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "40MHz,80+80MHz", "xsd:string");
/*
@ -901,19 +1045,26 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-5,-3,99,120", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported";
ctx->in_value = "-5,-3,99,120";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,990", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported";
ctx->in_value = "-1,9,990";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,100", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported";
ctx->in_value = "-1,9,100";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
@ -924,25 +1075,32 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state)
*/
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "8,1,2,3", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration";
ctx->in_value = "8,1,2,3";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// Set Wrong Value ==> expected "9007" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "1,2,3,4,5,6,7,8", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration";
ctx->in_value = "1,2,3,4,5,6,7,8";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
// set value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "0,1,2,3,4,5,6,7", NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration";
ctx->in_value = "0,1,2,3,4,5,6,7";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
// get value ==> expected "0" error
fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
// validate parameter after setting to true: name, type, value
validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "0,1,2,3,4,5,6,7", "xsd:string");
}
#endif
static void test_api_bbfdm_add_del_standard_object(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
@ -1617,9 +1775,8 @@ int main(void)
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_json_v1_parameter, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_library_parameter, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_standard_parameter_alias, setup, teardown_commit),
#if 0
cmocka_unit_test_setup_teardown(test_api_bbfdm_input_value_validation_json_parameter, setup, teardown_commit),
#endif
// Add/Delete Object method test cases
cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_standard_object, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_json_object, setup, teardown_commit),

View file

@ -7,15 +7,13 @@
#include <libbbfdm-api/dmapi.h>
#include <libbbfdm-api/dmentry.h>
#include <libbbfdm/device.h>
#include <libbbfdm/vendor.h>
#include "../../libbbfdm/dmtree/tr181/device.h"
static DMOBJ *TR181_ROOT_TREE = tEntryRoot;
static DM_MAP_VENDOR *TR181_VENDOR_EXTENSION[2] = {
tVendorExtension,
tVendorExtensionOverwrite
static DMOBJ TR181_ROOT_TREE[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceObj, tDeviceParams, NULL, BBFDM_BOTH},
{0}
};
static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
static int setup(void **state)
{
@ -23,7 +21,7 @@ static int setup(void **state)
if (!ctx)
return -1;
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
*state = ctx;
@ -54,7 +52,7 @@ static int teardown_revert(void **state)
static int group_init(void **state)
{
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, "/etc/bbfdm/plugins");
bbf_global_init(TR181_ROOT_TREE, "/etc/bbfdm/plugins");
return 0;
}
@ -592,7 +590,7 @@ static void test_api_bbfdm_json_get_value(void **state)
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
/*
* Test of JSON Parameter Path
@ -605,7 +603,7 @@ static void test_api_bbfdm_json_get_value(void **state)
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
}
static void test_api_bbfdm_json_add_object(void **state)
@ -653,7 +651,7 @@ static void test_api_bbfdm_library_get_value(void **state)
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
ctx->in_param = "Device.WiFi.SSID.1.Enable";

View file

@ -1,36 +0,0 @@
{
"json_plugin_version": 1,
"Device.CWMPManagementServer.": {
"type": "object",
"version": "2.15",
"protocols": [
"usp"
],
"access": false,
"array": false,
"dependency": "file:/etc/config/cwmp",
"EnableCWMP": {
"type": "boolean",
"version": "2.15",
"read": true,
"write": true,
"protocols": [
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "cwmp",
"section": {
"name": "cpe"
},
"option": {
"name": "enable"
}
}
}
]
}
}
}

View file

@ -18,12 +18,11 @@
"cwmp",
"usp"
],
"flags": [
"Secure"
],
"mapping": [
{
"rpc": "get"
},
{
"rpc": "set",
"type": "uci",
"uci": {
"file": "users",
@ -138,12 +137,11 @@
"cwmp",
"usp"
],
"flags": [
"Secure"
],
"mapping": [
{
"rpc": "get"
},
{
"rpc": "set",
"type": "uci",
"uci": {
"file": "owsd",

View file

@ -1,426 +0,0 @@
{
"json_plugin_version": 1,
"Device.{BBF_VENDOR_PREFIX}URLFilter.": {
"type": "object",
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"Enable": {
"type": "boolean",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"name": "globals"
},
"option": {
"name": "enable"
}
}
}
]
},
"GlobalBlacklist": {
"type": "boolean",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"name": "globals"
},
"option": {
"name": "global_blacklist"
}
}
}
]
},
"BlacklistURL": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"list": {
"datatype": "string"
},
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"name": "globals"
},
"list": {
"name": "blacklist_url"
}
}
}
]
},
"ProfileNumberOfEntries": {
"type": "unsignedInt",
"read": true,
"write": false,
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "profile"
},
"option": {
"name": "@Count"
}
}
}
]
},
"Device.{BBF_VENDOR_PREFIX}URLFilter.Profile.{i}.": {
"type": "object",
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"uniqueKeys": [
"Name"
],
"access": true,
"array": true,
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "profile"
},
"dmmapfile": "dmmap_urlfilter"
}
}
],
"Name": {
"type": "string",
"read": true,
"write": true,
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
"range": [
{
"max": 64
}
],
"flags": [
"Unique",
"Linker"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "profile"
},
"option": {
"name": "name"
}
}
}
]
},
"WhitelistURL": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"list": {
"datatype": "string"
},
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "profile"
},
"list": {
"name": "whitelist_url"
}
}
}
]
},
"BlacklistURL": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"list": {
"datatype": "string"
},
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "profile"
},
"list": {
"name": "blacklist_url"
}
}
}
]
}
},
"FilterNumberOfEntries": {
"type": "unsignedInt",
"read": true,
"write": false,
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"option": {
"name": "@Count"
}
}
}
]
},
"Device.{BBF_VENDOR_PREFIX}URLFilter.Filter.{i}.": {
"type": "object",
"version": "2.14",
"protocols": [
"cwmp",
"usp"
],
"access": true,
"array": true,
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"dmmapfile": "dmmap_urlfilter"
}
}
],
"Enable": {
"type": "boolean",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"option": {
"name": "enable"
}
}
}
]
},
"Profile": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"flags": [
"Reference"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"option": {
"name": "profile"
}
},
"linker_obj": "Device.{BBF_VENDOR_PREFIX}URLFilter.Profile.*.Name"
}
]
},
"MACAddress": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"list": {
"datatype": "string"
},
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"list": {
"name": "macaddr"
}
}
}
]
},
"Day": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"list": {
"datatype": "string"
},
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"list": {
"name": "day"
}
}
}
]
},
"StartTime": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"option": {
"name": "start_time"
}
}
}
]
},
"Duration": {
"type": "string",
"version": "2.14",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "urlfilter",
"section": {
"type": "filter"
},
"option": {
"name": "duration"
}
}
}
]
}
}
}
}

20
test/vendor_test/Makefile Normal file
View file

@ -0,0 +1,20 @@
LIB = libbbfdm_test_ext.so
LIB_OBJS = device.o deviceinfo.o extension.o firewall.o x_test_com_dropbear.o
LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -I /usr/local/include/
LIB_LDFLAGS = $(LDFLAGS) -lbbfdm-api
%.o: %.c
$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<
all: $(LIB)
$(LIB): $(LIB_OBJS)
$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
install:
cp -f $(LIB) /etc/bbfdm/plugins
cp -f *.json /etc/bbfdm/plugins
clean:
rm -fv *.o $(LIB)

View file

@ -14,6 +14,7 @@
DMOBJ tTEST_DeviceObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{BBF_VENDOR_PREFIX"Dropbear", &DMWRITE, add_dropbear_instance, delete_dropbear_instance, "file:/etc/config/dropbear", browse_dropbear_instance, NULL, NULL, NULL, X_TEST_COM_DropbearParams, NULL, BBFDM_BOTH},
{"USB", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BBFDM_NONE},
{"X_IOPSYS_EU_Dropbear", &DMWRITE, add_dropbear_instance, delete_dropbear_instance, "file:/etc/config/dropbear", browse_dropbear_instance, NULL, NULL, NULL, X_TEST_COM_DropbearParams, NULL, BBFDM_BOTH},
{0}
};

View file

@ -18,6 +18,12 @@ static int test__get_device_manufacturer(char *refparam, struct dmctx *ctx, void
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/* *** Device.DeviceInfo. *** */
DMOBJ tTEST_DeviceInfoObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"VendorConfigFile", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BBFDM_NONE},
{0}
};
DMLEAF tTEST_DeviceInfoParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Manufacturer", &DMREAD, DMT_STRING, test__get_device_manufacturer, NULL, BBFDM_BOTH},

View file

@ -3,6 +3,7 @@
#include "libbbfdm-api/dmcommon.h"
extern DMOBJ tTEST_DeviceInfoObj[];
extern DMLEAF tTEST_DeviceInfoParams[];
#endif //__TEST_DEVICEINFO_H

View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2021 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 <amin.benramdhane@pivasoftware.com>
*
*/
#include "device.h"
#include "deviceinfo.h"
#include "firewall.h"
#include "extension.h"
DMOBJ tTEST_DSLChannelObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BBFDM_NONE},
{0}
};
DMLEAF tTEST_QoSQueueParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"SchedulerAlgorithm", &DMREAD, DMT_STRING, NULL, NULL, BBFDM_NONE},
{0}
};
DMLEAF tFASTLineStatsParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"ErroredSecs", &DMREAD, DMT_UNINT, NULL, NULL, BBFDM_NONE},
{0}
};
DMLEAF tTEST_EthernetRMONStatsParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Packets1024to1518Bytes", &DMREAD, DMT_UNLONG, NULL, NULL, BBFDM_NONE},
{0}
};
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.", tTEST_DeviceObj, NULL}, // Overwrite 'X_IOPSYS_EU_Dropbear' && Exclude 'USB'
{"Device.Firewall.Chain.{i}.Rule.{i}.", tTEST_FirewallChainRuleObj, tTEST_FirewallChainRuleParams}, // Extend 'X_TEST_COM_TimeSpan', etc.. && Overwrite 'ExpiryDate'
{"Device.DeviceInfo.", tTEST_DeviceInfoObj, tTEST_DeviceInfoParams}, // Overwrite 'Manufacturer' && Exclude 'VendorConfigFile' from the tree
{"Device.DSL.Channel.{i}.", tTEST_DSLChannelObj, NULL}, // Exclude 'Stats' from the tree
{"Device.QoS.Queue.{i}.", NULL, tTEST_QoSQueueParams}, // Exclude 'SchedulerAlgorithm' from the tree
{"Device.FAST.Line.{i}.Stats.CurrentDay.", NULL, tFASTLineStatsParams}, // Exclude 'ErroredSecs' from the tree
{"Device.Ethernet.RMONStats.{i}.", NULL, tTEST_EthernetRMONStatsParams}, // Exclude 'Packets1024to1518Bytes' from the tree
{0}
};

View file

@ -167,22 +167,17 @@ static int test__get_firewall_expriydate(char *refparam, struct dmctx *ctx, void
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/* *** Device.Firewall.Chain.{i}.Rule.{i}. *** */
DMLEAF tTEST_FirewallRuleParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"ExpiryDate", &DMWRITE, DMT_TIME, test__get_firewall_expriydate, NULL, BBFDM_BOTH},
{0}
};
DMOBJ tTEST_FirewallChainRuleObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{BBF_VENDOR_PREFIX"TimeSpan", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tTEST_FirewallChainRuleTimeSpanParams, NULL, BBFDM_BOTH},
{"X_TEST_COM_TimeSpan", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tTEST_FirewallChainRuleTimeSpanParams, NULL, BBFDM_BOTH},
{0}
};
DMLEAF tTEST_FirewallChainRuleParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{BBF_VENDOR_PREFIX"ICMPType", &DMWRITE, DMT_STRING, get_rule_icmp_type, set_rule_icmp_type, BBFDM_BOTH},
{BBF_VENDOR_PREFIX"SourceMACAddress", &DMWRITE, DMT_STRING, get_rule_source_mac, set_rule_source_mac, BBFDM_BOTH},
{"X_TEST_COM_ICMPType", &DMWRITE, DMT_STRING, get_rule_icmp_type, set_rule_icmp_type, BBFDM_BOTH},
{"X_TEST_COM_SourceMACAddress", &DMWRITE, DMT_STRING, get_rule_source_mac, set_rule_source_mac, BBFDM_BOTH},
{"ExpiryDate", &DMWRITE, DMT_TIME, test__get_firewall_expriydate, NULL, BBFDM_BOTH},
{0}
};

View file

@ -14,7 +14,6 @@
#include "libbbfdm-api/dmcommon.h"
extern DMLEAF tTEST_FirewallRuleParams[];
extern DMOBJ tTEST_FirewallChainRuleObj[];
extern DMLEAF tTEST_FirewallChainRuleParams[];
extern DMLEAF tTEST_FirewallChainRuleTimeSpanParams[];

View file

@ -0,0 +1,26 @@
{
"Device.DeviceInfo.ProcessStatus.": {
"type": "object",
"protocols": [
"none"
],
"access": false,
"array": false
},
"Device.X_IOPSYS_EU_IGMP.": {
"type": "object",
"protocols": [
"none"
],
"access": false,
"array": false
},
"Device.X_IOPSYS_EU_MLD.": {
"type": "object",
"protocols": [
"none"
],
"access": false,
"array": false
}
}

View file

@ -0,0 +1,21 @@
{
"Device.DeviceInfo.Processor.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": false,
"Architecture": {
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"default": "x86_64"
}
}
}

View file

@ -78,16 +78,6 @@ int delete_dropbear_instance(char *refparam, struct dmctx *ctx, void *data, char
/*************************************************************
* GET & SET PARAM
**************************************************************/
static int get_x_test_com_dropbear_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
return bbf_get_alias(ctx, ((struct dmmap_dup *)data)->dmmap_section, "dropbearalias", instance, value);
}
static int set_x_test_com_dropbear_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
return bbf_set_alias(ctx, ((struct dmmap_dup *)data)->dmmap_section, "dropbearalias", instance, value);
}
static int get_x_test_com_dropbear_password_auth(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *res = dmuci_get_value_by_section_fallback_def(((struct dmmap_dup *)data)->config_section, "PasswordAuth", "1");
@ -182,29 +172,6 @@ static int set_x_test_com_dropbear_root_login(char *refparam, struct dmctx *ctx,
return 0;
}
static int get_x_test_com_dropbear_verbose(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_dup *)data)->config_section, "verbose", "0");
return 0;
}
static int set_x_test_com_dropbear_verbose(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
bool b;
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
return 0;
case VALUESET:
string_to_bool(value, &b);
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "verbose", b ? "1" : "0");
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_gateway_ports(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_dup *)data)->config_section, "GatewayPorts", "0");
@ -228,134 +195,16 @@ static int set_x_test_com_dropbear_gateway_ports(char *refparam, struct dmctx *c
return 0;
}
static int get_x_test_com_dropbear_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "Interface", value);
return 0;
}
static int set_x_test_com_dropbear_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "Interface", value);
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_rsakeyfile(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "rsakeyfile", value);
return 0;
}
static int set_x_test_com_dropbear_rsakeyfile(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "rsakeyfile", value);
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_dsskeyfile(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "dsskeyfile", value);
return 0;
}
static int set_x_test_com_dropbear_dsskeyfile(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "dsskeyfile", value);
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_ssh_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_dup *)data)->config_section, "SSHKeepAlive", "300");
return 0;
}
static int set_x_test_com_dropbear_ssh_keepalive(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "SSHKeepAlive", (DM_STRCMP(value, "300") == 0) ? "" : value);
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_idle_timeout(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_value_by_section_fallback_def(((struct dmmap_dup *)data)->config_section, "IdleTimeout", "300");
return 0;
}
static int set_x_test_com_dropbear_idle_timeout(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "IdleTimeout", (value[0] == '0') ? "" : value);
return 0;
}
return 0;
}
static int get_x_test_com_dropbear_banner_file(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dmmap_dup *)data)->config_section, "BannerFile", value);
return 0;
}
static int set_x_test_com_dropbear_banner_file(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
return 0;
case VALUESET:
dmuci_set_value_by_section(((struct dmmap_dup *)data)->config_section, "BannerFile", value);
return 0;
}
return 0;
}
/**********************************************************************************************************************************
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/*** Device.X_TEST_COM_Dropbear.{i}. ****/
DMLEAF X_TEST_COM_DropbearParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Alias", &DMWRITE, DMT_STRING, get_x_test_com_dropbear_alias, set_x_test_com_dropbear_alias, BBFDM_BOTH},
{"PasswordAuth", &DMWRITE, DMT_BOOL, get_x_test_com_dropbear_password_auth, set_x_test_com_dropbear_password_auth, BBFDM_BOTH},
{"RootPasswordAuth", &DMWRITE, DMT_BOOL, get_x_test_com_dropbear_root_password_auth, set_x_test_com_dropbear_root_password_auth, BBFDM_BOTH},
{"Port", &DMWRITE, DMT_UNINT, get_x_test_com_dropbear_port, set_x_test_com_dropbear_port, BBFDM_BOTH},
{"RootLogin", &DMWRITE, DMT_BOOL, get_x_test_com_dropbear_root_login, set_x_test_com_dropbear_root_login, BBFDM_BOTH},
{"GatewayPorts", &DMWRITE, DMT_BOOL, get_x_test_com_dropbear_gateway_ports, set_x_test_com_dropbear_gateway_ports, BBFDM_BOTH},
{"Interface", &DMWRITE, DMT_STRING, get_x_test_com_dropbear_interface, set_x_test_com_dropbear_interface, BBFDM_BOTH},
{"RSAKeyFile", &DMWRITE, DMT_STRING, get_x_test_com_dropbear_rsakeyfile, set_x_test_com_dropbear_rsakeyfile, BBFDM_BOTH},
{"DSSKeyFile", &DMWRITE, DMT_STRING, get_x_test_com_dropbear_dsskeyfile, set_x_test_com_dropbear_dsskeyfile, BBFDM_BOTH},
{"SSHKeepAlive", &DMWRITE, DMT_UNINT, get_x_test_com_dropbear_ssh_keepalive, set_x_test_com_dropbear_ssh_keepalive, BBFDM_BOTH},
{"IdleTimeout", &DMWRITE, DMT_UNINT, get_x_test_com_dropbear_idle_timeout, set_x_test_com_dropbear_idle_timeout, BBFDM_BOTH},
{"Verbose", &DMWRITE, DMT_BOOL, get_x_test_com_dropbear_verbose, set_x_test_com_dropbear_verbose, BBFDM_BOTH},
{"BannerFile", &DMWRITE, DMT_STRING, get_x_test_com_dropbear_banner_file, set_x_test_com_dropbear_banner_file, BBFDM_BOTH},
{0}
};

View file

@ -199,8 +199,6 @@ def build_and_install_bbfdm(vendor_prefix, vendor_list):
cmake_command = [
"cmake",
"../",
"-DWITH_OPENSSL=ON",
"-DBBF_VENDOR_EXTENSION=ON",
"-DBBF_SCHEMA_FULL_TREE=ON",
f"-DBBF_VENDOR_LIST={VENDOR_LIST}",
f"-DBBF_VENDOR_PREFIX={VENDOR_PREFIX}",