Add bbfdm daemon(bbfdmd)

This commit is contained in:
Amin Ben Romdhane 2023-04-14 10:05:08 +00:00 committed by Vivek Kumar Dutta
parent c7be1ab765
commit 0a4105c931
101 changed files with 7587 additions and 8598 deletions

54
.gitignore vendored
View file

@ -1,53 +1,9 @@
*.swp
*.swo
*.o
*.lo
bin/*
!bin/Makefile.am
.prepared*
.built*
.configured*
.dep_files
ABOUT-NLS
INSTALL
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
compile
config.log
config.rpath
config.status
config.guess
config.sub
configure
depcomp
install-sh
ipkg-*/
missing
.deps/
.dirstamp
.git_update
.pkgdir/
libtool
ltmain.sh
COPYING
tools/*.xls
tools/*.xml
tools/*.pyc
tools/__pycache__
*.gcov
*.gcno
*\.log
.libs
m4/
bbf_ubus
memory-report.xml
*.la
CMakeFiles
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
install_manifest.txt
*.cmake
*.o
*.so
bbfdmd/src/bbfdmd
docs/index.md

View file

@ -15,9 +15,7 @@ variables:
stages:
- static_code_analysis
- unit_test
- memory_test
- functional_test
- uspd
- deploy
run_unit_test:
@ -25,6 +23,7 @@ run_unit_test:
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/unit-test.sh"
artifacts:
@ -33,34 +32,6 @@ run_unit_test:
- timestamp.log
- unit-test-coverage.xml
run_functional_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-test.sh"
artifacts:
when: always
paths:
- timestamp.log
- functional-test-coverage.xml
run_functional_api_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-api-test.sh"
artifacts:
when: always
paths:
- timestamp.log
- functional-api-test-coverage.xml
run_tools_test:
stage: unit_test
image: iopsys/code-analysis:latest
@ -76,53 +47,66 @@ run_tools_test:
- tools/out/datamodel_hdm.xml
- tools/out/datamodel.xls
run_memory_test:
stage: memory_test
run_libbbf_api_functional_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-api-test.sh"
artifacts:
when: always
paths:
- timestamp.log
- functional-api-test-coverage.xml
run_libbbf_dm_functional_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-test.sh"
artifacts:
when: always
paths:
- timestamp.log
- functional-test-coverage.xml
run_libbbf_dm_memory_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/memory-test.sh"
- echo "BBF_TAR_URL=${CI_JOB_URL}/artifacts/raw/build/libbbf-1.0.0-Linux.sh" >build.env
artifacts:
reports:
dotenv: build.env
when: always
paths:
- timestamp.log
- output-report-device-get.txt
- build/libbbf-1.0.0-Linux.sh
doxygen:
stage: unit_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
before_script:
- apt update
- apt --assume-yes install doxygen graphviz
run_bbfd_functional_test:
stage: functional_test
image: dev.iopsys.eu:5050/iopsys/gitlab-ci-pipeline/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/bbfdmd-functional-test.sh"
artifacts:
when: always
reports:
junit: ./report/*.xml
paths:
- funl-result.log
- funl-test-coverage.xml
- memory-report.xml
- timestamp.log
- report/
script:
- doxygen Doxyfile
- mv doxygen/html/ public/
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
run_uspd:
stage: uspd
inherit:
variables: false
variables:
UPSTREAM_BBF_SHA: $CI_COMMIT_SHA
BBF_TAR_URL: $BBF_TAR_URL
allow_failure: false
trigger:
project: iopsys/uspd
branch: bbf_pipeline
strategy: depend
needs:
job: run_memory_test
artifacts: true

View file

@ -2,16 +2,11 @@ cmake_minimum_required(VERSION 3.0)
PROJECT(bbf C)
OPTION(BBFD_ENABLED "build bbfd daemon with their dependencies" OFF)
OPTION(BBFDMD_ENABLED "build bbfdmd daemon with their dependencies" OFF)
add_subdirectory(libbbf_api)
add_subdirectory(libbbf_dm)
# add CPack to project
SET(CPACK_PACKAGE_NAME "libbbf")
SET(CPACK_PACKAGE_VENDOR "iopsys.io")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "libbbf - Datamodel library")
SET(CPACK_PACKAGE_VERSION "1.0.0")
SET(CPACK_GENERATOR STGZ)
include(CPack)
IF(BBFDMD_ENABLED)
add_subdirectory(bbfdmd/src)
ENDIF(BBFDMD_ENABLED)

View file

@ -1,71 +0,0 @@
include:
- project: 'iopsys/gitlab-ci-pipeline'
file: '/static-code-analysis.yml'
variables:
COMMON_IMAGE: iopsys/code-analysis:0.26
DEBUG: 'TRUE'
SOURCE_FOLDER: "./src"
RUN_CPPCHECK: "cppcheck --enable=all --error-exitcode=1 --inline-suppr --suppress=missingInclude --include=/usr/include/libubox/list.h -DUSPD_MAX_MSG_LEN=1048576"
stages:
- static_code_analysis
- test
run_unit_test:
stage: test
image: iopsys/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/unit-test.sh"
artifacts:
untracked: true
when: always
paths:
- timestamp.log
- unit-test-coverage.xml
run_functional_test:
stage: test
image: iopsys/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-test.sh"
artifacts:
untracked: true
when: always
reports:
junit: ./report/*.xml
paths:
- funl-result.log
- funl-test-coverage.xml
- memory-report.xml
- timestamp.log
- report/
run_api_test:
stage: test
image: iopsys/code-analysis:latest
allow_failure: false
script:
- "./gitlab-ci/install-dependencies.sh"
- "./gitlab-ci/setup.sh"
- "./gitlab-ci/functional-api-test.sh"
artifacts:
untracked: true
when: always
reports:
junit: ./report/*.xml
paths:
- timestamp.log
- api-test-coverage.xml
- memory-report.xml
- api-result.log
- report/

View file

@ -1,58 +0,0 @@
PROG = uspd
OBJS =common.o get.o get_helper.o set.o operate.o add_delete.o pretty_print.o usp.o events.o
CP=cp -f
PROG_CFLAGS = $(CFLAGS) \
-fstrict-aliasing \
-Wall -Wextra -Werror \
-Wformat \
-Wformat-signedness -fPIC
PROG_LDFLAGS = $(LDFLAGS)
PROG_LDFLAGS += -luci -lubus -lubox -ljson-c -lblobmsg_json -lbbfdm
ifeq ($(USE_MBEDTLS),yes)
PROG_LDFLAGS += -lmbedcrypto -lmbedtls
endif
ifeq ($(USE_OPENSSL),yes)
PROG_LDFLAGS += -lssl -lcrypto
endif
ifeq ($(USE_WOLFSSL),yes)
PROG_LDFLAGS += -lwolfssl
endif
%.o: %.c
$(CC) $(PROG_CFLAGS) -c -o $@ $<
all: ${PROG}
${PROG}: $(OBJS)
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
$(CP) ${PROG} ../${PROG}
test: PROG_CFLAGS += -fPIC
test: ${OBJS}
${CC} $(PROG_CFLAGS) -shared -o libuspd.so ${OBJS} $(PROG_LDFLAGS)
$(CP) libuspd.so ../libuspd.so
unit-test: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage
unit-test: LDFLAGS += --coverage
unit-test: clean_objs
unit-test: test
make -C ../test/cmocka unit-test USPD_LIB_DIR=$(PWD)
func-test: CFLAGS += -g -O0 -fprofile-arcs -ftest-coverage
func-test: LDFLAGS += --coverage
func-test: clean_objs
func-test: ${PROG}
clean_objs:
rm -f *.o
clean:
rm -f *.o libuspd.so $(PROG)
rm -f *.xml *.html
find -name '*.gcda' -exec rm {} -fv \;
find -name '*.gcno' -exec rm {} -fv \;
find -name '*.gcov' -exec rm {} -fv \;

View file

@ -1,77 +0,0 @@
/*
* add_delete.c: Add/Delete handler for uspd
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "common.h"
#include "add_delete.h"
#include "get_helper.h"
#include <libbbfdm/dmbbfcommon.h>
typedef int (*ADD_DEL_CB_T)(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
static int handle_add_del_req(usp_data_t *data, struct blob_buf *bb, ADD_DEL_CB_T req_cb)
{
int fault = 0;
struct dmctx bbf_ctx;
LIST_HEAD(resolved_paths);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_paths);
if (fault) {
fill_resolve_err(bb, data->qpath, fault);
} else {
struct pathNode *p;
void *array;
array = blobmsg_open_array(bb, "parameters");
list_for_each_entry(p, &resolved_paths, list) {
void *table = blobmsg_open_table(bb, NULL);
int op_fault;
op_fault = req_cb(&bbf_ctx, bb, p->path, data->set_key);
blobmsg_close_table(bb, table);
// Preserve the first error
if (fault == USP_ERR_OK && op_fault != USP_ERR_OK)
fault = op_fault;
}
blobmsg_close_array(bb, array);
}
// Free
bbf_cleanup(&bbf_ctx);
free_path_list(&resolved_paths);
return fault;
}
int create_add_response(usp_data_t *data, struct blob_buf *bb)
{
return handle_add_del_req(data, bb, &usp_add_object);
}
int create_del_response(usp_data_t *data, struct blob_buf *bb)
{
return handle_add_del_req(data, bb, &usp_del_object);
}

View file

@ -1,23 +0,0 @@
#ifndef ADD_DEL_H
#define ADD_DEL_H
#include "usp.h"
enum {
DM_ADD_PATH,
DM_ADD_PROTO,
DM_ADD_INSTANCE,
__DM_ADD_MAX
};
enum {
DM_RAW_ADD_PATH,
DM_RAW_ADD_PROTO,
DM_RAW_ADD_INSTANCE,
DM_RAW_ADD_TRANS_ID,
__DM_RAW_ADD_MAX
};
int create_add_response(usp_data_t *data, struct blob_buf *bb);
int create_del_response(usp_data_t *data, struct blob_buf *bb);
#endif /* ADD_DEL_H */

View file

@ -1,306 +0,0 @@
/*
* get.c: Get handler for uspd
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "get.h"
#include "get_helper.h"
#include "pretty_print.h"
#include "ipc.h"
#include <libubus.h>
#include <libbbfdm/dmbbfcommon.h>
void init_dmmap(void)
{
struct dmctx bbf_ctx;
LIST_HEAD(resolved_list);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER);
get_resolved_paths(&bbf_ctx, ROOT_NODE, &resolved_list);
// Commit dmmap
bbf_uci_commit_bbfdm();
free_path_list(&resolved_list);
bbf_cleanup(&bbf_ctx);
}
void usp_get_value_async(usp_data_t *data, void *output)
{
struct blob_buf bb;
int fault = USP_ERR_OK;
struct dmctx bbf_ctx;
LIST_HEAD(resolved_list);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
// Fill the blob_buf for sharing the result
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
INFO("Preparing result for(%s)", data->qpath);
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_list);
if (fault) {
fill_err_code(&bb, fault);
} else {
if (data->is_raw)
prepare_result_raw(&bb, &bbf_ctx, &resolved_list);
else
prepare_pretty_result(data->depth, data->qpath, &bb, &bbf_ctx, &resolved_list);
}
if (!validate_msglen(&bb)) {
ERR("IPC failed for path(%s)", data->qpath);
}
memcpy(output, bb.head, blob_pad_len(bb.head));
// free
blob_buf_free(&bb);
free_path_list(&resolved_list);
bbf_cleanup(&bbf_ctx);
}
void usp_get_value(usp_data_t *data)
{
struct ubus_context *ctx;
struct ubus_request_data *req;
struct blob_buf bb;
int fault = USP_ERR_OK;
char *qpath;
bool raw;
uint8_t depth;
struct dmctx bbf_ctx;
ctx = data->ctx;
req = data->req;
qpath = data->qpath;
raw = data->is_raw;
depth = data->depth;
LIST_HEAD(resolved_list);
// Fill the blob_buf for sharing the result
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
fault = get_resolved_paths(&bbf_ctx, qpath, &resolved_list);
INFO("Preparing result for(%s), fault(%d)", qpath, fault);
if (fault) {
fill_err_code(&bb, fault);
} else {
if (raw)
prepare_result_raw(&bb, &bbf_ctx, &resolved_list);
else
prepare_pretty_result(depth, qpath, &bb, &bbf_ctx, &resolved_list);
}
if (!validate_msglen(&bb)) {
ERR("IPC failed for path(%s)", data->qpath);
}
ubus_send_reply(ctx, req, bb.head);
// Apply all bbfdm changes
if (is_transaction_running() == false)
bbf_uci_commit_bbfdm();
// free
blob_buf_free(&bb);
free_path_list(&resolved_list);
bbf_cleanup(&bbf_ctx);
}
void usp_validate_path(usp_data_t *data)
{
struct ubus_context *ctx;
struct ubus_request_data *req;
struct blob_buf bb;
int fault = USP_ERR_OK;
char *qpath;
struct dmctx bbf_ctx;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
ctx = data->ctx;
req = data->req;
qpath = data->qpath;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
fault = bbf_dm_get_names(&bbf_ctx, qpath, data->next_level);
if (!list_empty(&bbf_ctx.list_parameter)) {
size_t len = DM_STRLEN(qpath);
if (len > 0) {
if (qpath[len - 1] == '.')
qpath[len - 1] = '\0';
blobmsg_add_string(&bb, "parameter", qpath);
}
}
if (fault)
fill_err_code(&bb, fault);
ubus_send_reply(ctx, req, bb.head);
// Apply all bbfdm changes
if (is_transaction_running() == false)
bbf_uci_commit_bbfdm();
// free
blob_buf_free(&bb);
bbf_cleanup(&bbf_ctx);
}
void usp_get_instance(usp_data_t *data)
{
struct ubus_context *ctx;
struct ubus_request_data *req;
struct blob_buf bb;
int fault = USP_ERR_OK;
char *qpath;
struct dmctx bbf_ctx;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
ctx = data->ctx;
req = data->req;
qpath = data->qpath;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
fault = bbf_dm_get_instances(&bbf_ctx, qpath, data->next_level);
if (fault) {
fill_err_code(&bb, fault);
} else {
struct dm_parameter *n;
void *array;
array = blobmsg_open_array(&bb, "parameters");
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
void *table = blobmsg_open_table(&bb, NULL);
blobmsg_add_string(&bb, "parameter", n->name);
blobmsg_close_table(&bb, table);
}
blobmsg_close_array(&bb, array);
}
ubus_send_reply(ctx, req, bb.head);
// Apply all bbfdm changes
if (is_transaction_running() == false)
bbf_uci_commit_bbfdm();
// free
blob_buf_free(&bb);
bbf_cleanup(&bbf_ctx);
}
void usp_get_name(usp_data_t *data)
{
struct ubus_context *ctx;
struct ubus_request_data *req;
struct blob_buf bb;
int fault;
char *qpath;
struct dmctx bbf_ctx;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
ctx = data->ctx;
req = data->req;
qpath = data->qpath;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
fault = bbf_dm_get_names(&bbf_ctx, qpath, data->next_level);
if (fault) {
fill_err_code(&bb, fault);
} else {
void *array;
struct dm_parameter *n;
array = blobmsg_open_array(&bb, "parameters");
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
void *table = blobmsg_open_table(&bb, NULL);
blobmsg_add_string(&bb, "parameter", n->name);
blobmsg_add_string(&bb, "writable", n->data);
blobmsg_add_string(&bb, "type", n->type);
blobmsg_close_table(&bb, table);
}
blobmsg_close_array(&bb, array);
}
ubus_send_reply(ctx, req, bb.head);
// Commit all bbfdm changes if transaction is not in progress
if (is_transaction_running() == false)
bbf_uci_commit_bbfdm();
// free
blob_buf_free(&bb);
bbf_cleanup(&bbf_ctx);
}
void get_mpath(usp_data_t *data)
{
struct blob_buf bb;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (data->is_raw) {
void *array = blobmsg_open_array(&bb, "parameters");
bbf_get_raw(data, &bb);
blobmsg_close_array(&bb, array);
} else {
bbf_get_blob(data, &bb);
}
ubus_send_reply(data->ctx, data->req, bb.head);
blob_buf_free(&bb);
}

View file

@ -1,31 +0,0 @@
#ifndef GET_H
#define GET_H
#include "usp.h"
#include "common.h"
enum {
DM_GET_PATH,
DM_GET_PROTO,
DM_GET_MAXDEPTH,
DM_GET_NXT_LVL,
DM_GET_INSTANCE,
__DM_GET_MAX
};
enum {
DM_GET_SAFE_PATHS,
DM_GET_SAFE_PROTO,
DM_GET_SAFE_NXT_LVL,
DM_GET_SAFE_INSTANCE,
__DM_GET_SAFE_MAX
};
void init_dmmap(void);
void usp_validate_path(usp_data_t *data);
void usp_get_value(usp_data_t *data);
void usp_get_instance(usp_data_t *data);
void usp_get_name(usp_data_t *data);
void get_mpath(usp_data_t *data);
void usp_get_value_async(usp_data_t *data, void *output);
#endif /* GET_H */

File diff suppressed because it is too large Load diff

View file

@ -1,89 +0,0 @@
#ifndef GET_HELPER_H
#define GET_HELPER_H
#include "usp.h"
#include "common.h"
#include <libbbf_api/dmbbf.h>
#include <libubus.h>
enum operation {
OPER_EQUAL_EQUAL,
OPER_NOT_EQUAL,
OPER_LESS_THAN_EQUAL,
OPER_GREATER_THAN_EQUAL,
OPER_LESS_THAN,
OPER_GREATER_THAN,
};
struct pvNode {
char *param;
char *val;
char *type;
struct list_head list;
};
struct pathNode {
struct list_head list;
char path[MAX_DM_PATH];
};
int resolve_path(struct dmctx *bbf_ctx, char *qPath, size_t pos,
struct list_head *resolved_plist);
void add_path_node(char *para, struct list_head *plist);
void fill_err_code(struct blob_buf *bb, int fault);
void fill_resolve_err(struct blob_buf *bb, char *spath, int fault);
void add_pv_node(char *para, char *val, char *type,
struct list_head *pv_list);
bool path_present_in_pvlist(struct list_head *pvlist, char *entry);
void free_pv_list(struct list_head *head);
void free_pv_node(struct pvNode *pv);
void free_path_list(struct list_head *head);
bool get_granural_object_paths(struct list_head *path_list,
uint8_t maxdepth);
int bbf_dm_get_supported_dm(struct blob_buf *bb, char *path, bool first_level, int schema_type);
int bbf_dm_get_values(struct dmctx *bbf_ctx, char *path);
int bbf_dm_get_schema(struct blob_buf *bb);
int bbf_dm_get_names(struct dmctx *bbf_ctx, char *path, char *next);
int bbf_dm_list_operate(struct dmctx *bbf_ctx);
int usp_dm_set(struct dmctx *dm_ctx, char *path, char *value);
int get_resolved_paths(struct dmctx *bbf_ctx, char *qpath,
struct list_head *resolved_paths);
int usp_dm_operate(struct blob_buf *bb, char *path, char *input_params, bool raw, int instance);
int usp_del_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
int usp_add_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey);
int bbf_get_blob(usp_data_t *data, struct blob_buf *bb);
int bbf_get_raw(usp_data_t *data, struct blob_buf *bb);
bool get_next_param(char *qPath, size_t *pos, char *param);
int bbf_dm_get_instances(struct dmctx *bbf_ctx, char *path, char *next);
void bbf_init(struct dmctx *dm_ctx, int instance);
void bbf_configure_ubus(struct ubus_context *ctx);
void bbf_cleanup(struct dmctx *dm_ctx);
void bb_add_string(struct blob_buf *bb, const char *name, const char *value);
bool bbf_dm_event_registered(char *ename);
void set_datamodel_version(char * version);
bool present_in_path_list(struct list_head *plist, char *entry);
// Transaction related
bool is_transaction_running(void);
bool is_transaction_valid(int trans_id);
int transaction_start(const char *app, uint32_t max_timeout);
int fill_transaction_status(struct blob_buf *bb, int trans_id);
int transaction_commit(int trans_id, struct blob_buf *bp_service_list, bool is_service_restart);
int transaction_abort(int trans_id);
int configure_transaction_timeout(int timeout);
void handle_pending_signal(int);
void print_last_dm_object(void);
int usp_dm_exec_apply(struct dmctx *bbf_ctx, int cmd);
#endif /* GET_HELPER_H */

View file

@ -1,156 +0,0 @@
/*
* operate.c: Operate handler for uspd
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "common.h"
#include "operate.h"
#include "get_helper.h"
#include "pretty_print.h"
#include "ipc.h"
#include <libbbfdm/dmbbfcommon.h>
#include <libubus.h>
static void usp_operate_cmd(usp_data_t *data, struct blob_buf *bb)
{
struct dmctx bbf_ctx;
int fault;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
LIST_HEAD(resolved_paths);
fault = get_resolved_paths(&bbf_ctx, data->qpath, &resolved_paths);
bbf_cleanup(&bbf_ctx);
if (fault) {
fill_err_code(bb, fault);
} else {
void *array;
struct pathNode *rv;
array = blobmsg_open_array(bb, "Results");
list_for_each_entry(rv, &resolved_paths, list) {
char path[MAX_DM_PATH] = {0};
snprintf(path, MAX_DM_PATH, "%s%s", rv->path, data->op_action);
void *table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", path);
usp_dm_operate(bb, path, data->op_input, data->is_raw, data->instance);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
}
free_path_list(&resolved_paths);
}
void list_operate_schema(struct blob_buf *bb)
{
struct dm_parameter *n;
void *array;
struct dmctx bbf_ctx;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(BBFDM_USP);
bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER);
bbf_dm_list_operate(&bbf_ctx);
array = blobmsg_open_array(bb, "parameters");
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
void *table = blobmsg_open_table(bb, NULL);
bb_add_string(bb, "parameter", n->name);
bb_add_string(bb, "type", n->additional_data);
DEBUG("Operate node|%s|, type(%s)", n->name, n->type);
// filling in and out parameter
if (n->data) {
int i;
void *array_arg;
operation_args *args = (operation_args *) n->data;
const char **ap = args->in;
if (ap) {
array_arg = blobmsg_open_array(bb, "in");
for (i = 0; ap[i] != NULL; i++)
blobmsg_add_string(bb, NULL, ap[i]);
blobmsg_close_array(bb, array_arg);
}
ap = args->out;
if (ap) {
array_arg = blobmsg_open_array(bb, "out");
for (i = 0; ap[i] != NULL; i++)
blobmsg_add_string(bb, NULL, ap[i]);
blobmsg_close_array(bb, array_arg);
}
}
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
bbf_cleanup(&bbf_ctx);
}
void usp_operate_cmd_async(usp_data_t *data, void *output)
{
struct blob_buf bb;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
usp_operate_cmd(data, &bb);
if (!validate_msglen(&bb)) {
ERR("IPC failed for path(%s)", data->qpath);
}
memcpy(output, bb.head, blob_pad_len(bb.head));
// free
blob_buf_free(&bb);
}
void usp_operate_cmd_sync(usp_data_t *data)
{
struct blob_buf bb;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
usp_operate_cmd(data, &bb);
if (!validate_msglen(&bb)) {
ERR("IPC failed for path(%s)", data->qpath);
}
ubus_send_reply(data->ctx, data->req, bb.head);
// free
blob_buf_free(&bb);
}

View file

@ -1,225 +0,0 @@
/*
* set.c: Set handler for uspd
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "set.h"
#include "get_helper.h"
#include <libubus.h>
#include <libbbfdm/dmbbfcommon.h>
static const struct blobmsg_policy dm_setm_value_policy[] = {
[DM_SET_V_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[DM_SET_V_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING },
};
int usp_set_value(usp_data_t *data)
{
struct blob_buf bb;
struct ubus_context *ctx;
struct ubus_request_data *req;
void *array = NULL;
struct pvNode *pv = NULL;
struct dmctx bbf_ctx;
int fault = USP_ERR_OK;
struct param_fault *p = NULL;
void *table;
bool fault_occured = false;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(data->proto);
bbf_init(&bbf_ctx, data->instance);
ctx = data->ctx;
req = data->req;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
list_for_each_entry(pv, data->pv_list, list) {
fault = usp_dm_set(&bbf_ctx, pv->param, pv->val);
if (fault == 0)
fault = usp_dm_exec_apply(&bbf_ctx, CMD_SET_VALUE);
if (fault) {
if (fault_occured == false) {
fault_occured = true;
if (!array)
array = blobmsg_open_array(&bb, "parameters");
}
while (bbf_ctx.list_fault_param.next != &bbf_ctx.list_fault_param) {
p = list_entry(bbf_ctx.list_fault_param.next, struct param_fault, list);
table = blobmsg_open_table(&bb, NULL);
bb_add_string(&bb, "path", p->name);
blobmsg_add_u8(&bb, "status", false);
blobmsg_add_u32(&bb, "fault", (uint32_t)p->fault);
blobmsg_close_table(&bb, table);
del_list_fault_param(p);
}
}
}
if (fault_occured == false)
blobmsg_add_u8(&bb, "status", true);
if (array)
blobmsg_close_array(&bb, array);
ubus_send_reply(ctx, req, bb.head);
// free
blob_buf_free(&bb);
bbf_cleanup(&bbf_ctx);
return fault;
}
int fill_pvlist_from_table(char *bpath, struct blob_attr *blob_value, struct list_head *pv_list, int instance)
{
struct blob_attr *attr;
char path[MAX_DM_PATH], value[MAX_DM_VALUE];
struct dmctx bbf_ctx;
int fault = USP_ERR_OK;
struct pathNode *p;
size_t tlen;
LIST_HEAD(resolved_paths);
if (!blob_value)
return 0;
tlen = (size_t)blobmsg_data_len(blob_value);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
bbf_init(&bbf_ctx, instance);
fault = get_resolved_paths(&bbf_ctx, bpath, &resolved_paths);
if (fault) {
bbf_cleanup(&bbf_ctx);
free_path_list(&resolved_paths);
return fault;
}
__blob_for_each_attr(attr, blobmsg_data(blob_value), tlen) {
struct blobmsg_hdr *hdr = blob_data(attr);
switch (blob_id(attr)) {
case BLOBMSG_TYPE_STRING:
snprintf(value, MAX_DM_VALUE, "%s", blobmsg_get_string(attr));
break;
case BLOBMSG_TYPE_INT8:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u8(attr));
break;
case BLOBMSG_TYPE_INT16:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u16(attr));
break;
case BLOBMSG_TYPE_INT32:
snprintf(value, MAX_DM_VALUE, "%u", blobmsg_get_u32(attr));
break;
case BLOBMSG_TYPE_INT64:
snprintf(value, MAX_DM_VALUE, "%"PRIu64"", blobmsg_get_u64(attr));
break;
default:
INFO("Unhandled set request type|%x|", blob_id(attr));
bbf_cleanup(&bbf_ctx);
free_path_list(&resolved_paths);
return USP_FAULT_INVALID_ARGUMENT;
}
list_for_each_entry(p, &resolved_paths, list) {
snprintf(path, MAX_DM_PATH, "%s%s", p->path, (char *)hdr->name);
add_pv_node(path, value, NULL, pv_list);
}
}
bbf_cleanup(&bbf_ctx);
free_path_list(&resolved_paths);
return fault;
}
int fill_pvlist_from_tuple(struct blob_attr *blob, struct list_head *pv_list)
{
size_t rem;
struct blob_attr *cur;
blobmsg_for_each_attr(cur, blob, rem) {
struct blob_attr *tb[__DM_SET_V_MAX];
char *path, *value, *key;
key = NULL;
blobmsg_parse(dm_setm_value_policy, __DM_SET_V_MAX, tb,
blobmsg_data(cur), blobmsg_len(cur));
// ignore the tuples which does not have path and values
if (!tb[DM_SET_V_PATH] || !tb[DM_SET_V_VALUE])
continue;
path = blobmsg_get_string(tb[DM_SET_V_PATH]);
value = blobmsg_get_string(tb[DM_SET_V_VALUE]);
add_pv_node(path, value, key, pv_list);
}
return 0;
}
int fill_pvlist_from_path(char *path, struct blob_attr *val_blob, struct list_head *pv_list, int instance)
{
int fault = USP_ERR_OK;
size_t plen;
char *val = NULL;
struct dmctx bbf_ctx;
LIST_HEAD(resolved_paths);
if (!val_blob)
return 0;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
bbf_init(&bbf_ctx, instance);
plen = DM_STRLEN(path);
if (plen == 0)
fault = USP_FAULT_INVALID_PATH;
if (fault == USP_ERR_OK) {
if (path[plen - 1] == '.')
fault = USP_FAULT_INVALID_PATH;
}
if (fault == USP_ERR_OK)
fault = get_resolved_paths(&bbf_ctx, path, &resolved_paths);
if (fault == USP_ERR_OK) {
struct pathNode *p;
list_for_each_entry(p, &resolved_paths, list) {
val = blobmsg_get_string(val_blob);
add_pv_node(p->path, val, NULL, pv_list);
}
}
free_path_list(&resolved_paths);
bbf_cleanup(&bbf_ctx);
return fault;
}

View file

@ -1,60 +0,0 @@
#ifndef SET_H
#define SET_H
#include "usp.h"
#include "common.h"
enum {
DM_SETS_PATHS,
DM_SETS_PROTO,
DM_SETS_INSTANCE,
DM_SETS_TRANS_ID,
__DM_SETS_MAX
};
enum {
DM_SETS_A_NOTIF_PATH,
DM_SETS_A_NOTIF_VALUE,
DM_SETS_A_NOTIF_CHANGE,
__DM_SETS_A_NOTIF_MAX
};
enum {
DM_SET_PATH,
DM_SET_VALUE,
DM_SET_VALUE_TABLE,
DM_SET_PROTO,
DM_SET_INSTANCE,
__DM_SET_MAX,
};
enum {
DM_RAW_SET_PATH,
DM_RAW_SET_VALUE,
DM_RAW_SET_VALUE_TABLE,
DM_RAW_SET_PROTO,
DM_RAW_SET_INSTANCE,
DM_RAW_SET_TRANS_ID,
__DM_RAW_SET_MAX,
};
enum {
DM_SET_V_PATH,
DM_SET_V_VALUE,
__DM_SET_V_MAX
};
enum {
DM_SET_MULTI_TUPLE,
DM_SET_MULTI_PROTO,
DM_SET_MULTI_INSTANCE,
DM_SET_MULTI_TRANS_ID,
__DM_SET_MULTI_MAX
};
int fill_pvlist_from_table(char *bpath, struct blob_attr *blob_value, struct list_head *pv_list, int instance);
int fill_pvlist_from_tuple(struct blob_attr *blob, struct list_head *pv_list);
int fill_pvlist_from_path(char *path, struct blob_attr *val_blob, struct list_head *pv_list, int instance);
int usp_set_value(usp_data_t *data);
#endif /* SET_H */

1686
bbfd/usp.c

File diff suppressed because it is too large Load diff

View file

@ -1,137 +0,0 @@
#ifndef USP_H
#define USP_H
#include <libubus.h>
#include <libubox/blobmsg.h>
#include <libubox/list.h>
#define USP_ATTR_UNUSED __attribute__((unused))
#define USP_EXT_LEN (4) // length of usp.
#define MAX_GRANURALITY_DEPTH (3)
#define USP_SUBPROCESS_DEPTH (2)
#define SCHEMA_UPDATE_TIMEOUT (30 * 1000)
struct uspd_async_req {
struct ubus_context *ctx;
struct ubus_request_data req;
struct uloop_process process;
void *result;
};
struct usp_context {
struct ubus_context ubus_ctx;
size_t dm_schema_len;
struct uloop_timeout schema_timer;
struct uloop_timeout instance_timer;
struct ubus_object *notify_object;
struct list_head obj_list;
struct list_head event_handlers;
struct list_head instances;
struct list_head old_instances;
};
struct ev_handler_node {
struct ubus_event_handler *ev_handler;
struct list_head list;
};
typedef struct usp_data {
struct ubus_context *ctx;
struct ubus_request_data *req;
bool is_raw;
int proto;
char *qpath;
uint8_t depth;
char *next_level;
int dm_cmd;
struct list_head *plist;
struct list_head *pv_list;
char *set_key;
char *op_action;
char *op_input;
int instance;
int trans_id;
} usp_data_t;
enum {
DM_LIST_NOTIFY_INSTANCE,
__DM_LIST_NOTIFY_MAX,
};
enum {
DM_SUPPORTED_PATH,
DM_SUPPORTED_NXT_LEVEL,
DM_SUPPORTED_SCHEMA_TYPE,
__DM_SUPPORTED_MAX
};
enum {
DM_NOTIFY_NAME,
DM_NOTIFY_PRAMS,
__DM_NOTIFY_MAX,
};
struct obNode {
struct ubus_object *obj;
struct list_head list;
};
int get_multi(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, struct blob_attr *msg,
int bbf_cmd);
int usp_getm_values(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req,
USP_ATTR_UNUSED const char *method,
struct blob_attr *msg);
int usp_getm_names(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req,
USP_ATTR_UNUSED const char *method,
struct blob_attr *msg);
int usp_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
int usp_raw_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
struct blob_attr *msg);
int usp_set(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
int usp_raw_set(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
int usp_operate(struct ubus_context *ctx, struct ubus_object *obj USP_ATTR_UNUSED,
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
struct blob_attr *msg);
int usp_list_schema(struct ubus_context *actx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg USP_ATTR_UNUSED);
int usp_list_operate(struct ubus_context *actx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg USP_ATTR_UNUSED);
int handle_set_multi_value(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method USP_ATTR_UNUSED,
struct blob_attr *msg);
int usp_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
bool usp_pre_init(struct usp_context *u);
bool usp_post_init(struct usp_context *u);
bool usp_cleanup(struct usp_context *u);
#endif /* COMMON_H */

16
bbfdmd/src/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(bbfdmd)
ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -fPIC -D_GNU_SOURCE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR}")
IF(${BBFDMD_MAX_MSG_LEN})
ADD_DEFINITIONS(-DUSPD_MAX_MSG_LEN=${BBFDMD_MAX_MSG_LEN})
ENDIF()
FILE(GLOB BBF_SOURCES *.c)
ADD_EXECUTABLE(bbfdmd ${BBF_SOURCES})
TARGET_LINK_LIBRARIES(bbfdmd uci ubus ubox blobmsg_json bbf_api bbf_dm)
INSTALL(TARGETS bbfdmd DESTINATION usr/sbin)

102
bbfdmd/src/add_delete.c Normal file
View file

@ -0,0 +1,102 @@
/*
* add_delete.c: Add/Delete handler for uspd
*
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "common.h"
#include "add_delete.h"
#include "get_helper.h"
typedef int (*ADD_DEL_CB_T)(usp_data_t *data);
static int usp_add_object(usp_data_t *data)
{
int fault = 0;
INFO("Req to add object |%s|", data->bbf_ctx.in_param);
void *array = blobmsg_open_array(&data->bb, "results");
fault = usp_dm_exec(&data->bbf_ctx, BBF_ADD_OBJECT);
if (fault) {
fill_err_code_table(data, fault);
} else {
void *table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", data->bbf_ctx.in_param);
bb_add_string(&data->bb, "data", data->bbf_ctx.addobj_instance);
blobmsg_close_table(&data->bb, table);
}
blobmsg_close_array(&data->bb, array);
return fault;
}
static int usp_del_object(usp_data_t *data)
{
struct pathNode *pn;
int fault = 0;
void *array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
INFO("Req to delete object |%s|", data->bbf_ctx.in_param);
fault = usp_dm_exec(&data->bbf_ctx, BBF_DEL_OBJECT);
if (fault) {
fill_err_code_table(data, fault);
} else {
void *table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", data->bbf_ctx.in_param);
bb_add_string(&data->bb, "data", "1");
blobmsg_close_table(&data->bb, table);
}
bbf_sub_cleanup(&data->bbf_ctx);
}
blobmsg_close_array(&data->bb, array);
return fault;
}
static int handle_add_del_req(usp_data_t *data, ADD_DEL_CB_T req_cb)
{
int fault = 0;
fault = req_cb(data);
return fault;
}
int create_add_response(usp_data_t *data)
{
return handle_add_del_req(data, &usp_add_object);
}
int create_del_response(usp_data_t *data)
{
return handle_add_del_req(data, &usp_del_object);
}

23
bbfdmd/src/add_delete.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef ADD_DEL_H
#define ADD_DEL_H
#include "bbfdmd.h"
enum {
DM_ADD_PATH,
DM_ADD_OBJ_PATH,
DM_ADD_OPTIONAL,
__DM_ADD_MAX
};
enum {
DM_DEL_PATH,
DM_DEL_PATHS,
DM_DEL_OPTIONAL,
__DM_DEL_MAX
};
int create_add_response(usp_data_t *data);
int create_del_response(usp_data_t *data);
#endif /* ADD_DEL_H */

1321
bbfdmd/src/bbfdmd.c Normal file

File diff suppressed because it is too large Load diff

43
bbfdmd/src/bbfdmd.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef BBFDMD_H
#define BBFDMD_H
#include <libubus.h>
#include <libubox/blobmsg.h>
#include <libubox/list.h>
#include "libbbf_api/dmbbf.h"
struct uspd_async_req {
struct ubus_context *ctx;
struct ubus_request_data req;
struct uloop_process process;
void *result;
};
struct usp_context {
struct ubus_context ubus_ctx;
size_t dm_schema_len;
struct uloop_timeout schema_timer;
struct uloop_timeout instance_timer;
struct list_head event_handlers;
struct list_head instances;
struct list_head old_instances;
};
struct ev_handler_node {
struct ubus_event_handler *ev_handler;
struct list_head list;
};
typedef struct usp_data {
struct ubus_context *ctx;
struct ubus_request_data *req;
struct list_head *plist;
struct dmctx bbf_ctx;
struct blob_buf bb;
uint8_t depth;
bool is_raw;
int trans_id;
} usp_data_t;
#endif /* BBFDMD_H */

View file

@ -1,9 +1,10 @@
/*
* common.c: Common utils of Get/Set/Operate handlers
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,7 +22,6 @@
*/
#include "common.h"
#include <libbbfdm/dmbbfcommon.h>
#include "ipc.h"
#include "get_helper.h"
@ -132,34 +132,6 @@ bool is_node_instance(char *path)
return ret;
}
bool get_uci_option_string(char *package, char *section,
char *option, char **value)
{
struct uci_context *uci_ctx;
struct uci_ptr ptr = {0};
bool ret = true;
*value = NULL;
uci_ctx = uci_alloc_context();
if (!uci_ctx)
return false;
if (bbfdmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, NULL)) {
*value = NULL;
ret = false;
} else if (ptr.o && ptr.o->v.string) {
*value = strdup(ptr.o->v.string);
} else {
*value = NULL;
ret = false;
}
uci_free_context(uci_ctx);
return ret;
}
// RE utilities
bool match(const char *string, const char *pattern)
{
@ -194,17 +166,50 @@ int count_delim(const char *path)
return (count - 1);
}
bool validate_msglen(struct blob_buf *bb)
bool validate_msglen(usp_data_t *data)
{
size_t data_len = blob_pad_len(bb->head);
size_t data_len = blob_pad_len(data->bb.head);
if (data_len >= DEF_IPC_DATA_LEN) {
ERR("Blob exceed max len(%zd), data len(%zd)", DEF_IPC_DATA_LEN, data_len);
blob_buf_free(bb);
blob_buf_init(bb, 0);
fill_err_code(bb, FAULT_9002);
blob_buf_free(&data->bb);
blob_buf_init(&data->bb, 0);
fill_err_code_table(data, FAULT_9002);
return false;
}
return true;
}
int bbf_get_dm_type(char *dm_type)
{
if (dm_type == NULL)
return DMT_STRING;
if (DM_STRCMP(dm_type, DMT_TYPE[DMT_STRING]) == 0)
return DMT_STRING;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_UNINT]) == 0)
return DMT_UNINT;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_INT]) == 0)
return DMT_INT;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_UNLONG]) == 0)
return DMT_UNLONG;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_LONG]) == 0)
return DMT_LONG;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_BOOL]) == 0)
return DMT_BOOL;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_TIME]) == 0)
return DMT_TIME;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_HEXBIN]) == 0)
return DMT_HEXBIN;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_BASE64]) == 0)
return DMT_BASE64;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_COMMAND]) == 0)
return DMT_COMMAND;
else if (DM_STRCMP(dm_type, DMT_TYPE[DMT_EVENT]) == 0)
return DMT_EVENT;
else
return DMT_STRING;
return DMT_STRING;
}

View file

@ -1,5 +1,6 @@
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@ -13,12 +14,13 @@
#include <libubox/utils.h>
#include <libubox/list.h>
#include "bbfdmd.h"
#define ROOT_NODE "Device."
#define USP "usp"
#define USPRAW "usp.raw"
#define USPEXT "usp.Device."
#define USP_ADD_EVENT "usp.AddObj"
#define USP_DEL_EVENT "usp.DelObj"
#define METHOD_NAME "bbfdm"
#define BBF_ADD_EVENT METHOD_NAME".AddObj"
#define BBF_DEL_EVENT METHOD_NAME".DelObj"
#define BBF_EVENT METHOD_NAME".event"
#define MAX_DM_KEY_LEN 256
#define MAX_DM_PATH 1024
@ -30,14 +32,12 @@
#define GLOB_EXPR "[=><]+"
#define GLOB_USP_PATH "[+#=><]+"
#define USP_ERR_OK 0
#define USP_ERR_OK 0
bool match(const char *string, const char *pattern);
bool is_str_eq(const char *s1, const char *s2);
bool is_node_instance(char *path);
int count_delim(const char *path);
bool get_uci_option_string(char *package, char *section,
char *option, char **value);
void set_debug_level(unsigned char level);
void print_error(const char *format, ...);
@ -45,8 +45,8 @@ void print_warning(const char *format, ...);
void print_info(const char *format, ...);
void print_debug(const char *format, ...);
bool get_boolean_string(char *value);
bool validate_msglen(struct blob_buf *bb);
bool validate_msglen(usp_data_t *data);
int bbf_get_dm_type(char *dm_type);
#define DEBUG(fmt, args...) \
print_debug("[%s:%d]"fmt, __func__, __LINE__, ##args)

View file

@ -1,9 +1,10 @@
/*
* events.c: Handler to generate usp events on ubus
*
* Copyright (C) 2021 iopsys Software Solutions AB. All rights reserved.
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +24,6 @@
#include "common.h"
#include "events.h"
#include "get_helper.h"
#include <libbbfdm/dmentry.h>
#include <libubus.h>
static struct event_map_list ev_map_list[] = {
@ -106,23 +106,23 @@ static void serialize_blob_msg(struct blob_attr *msg, char *node, struct list_he
switch (blobmsg_type(attr)) {
case BLOBMSG_TYPE_STRING:
snprintf(value, MAX_DM_VALUE, "%s", blobmsg_get_string(attr));
add_pv_node(path, value, NULL, pv_list);
add_pv_list(path, value, NULL, pv_list);
break;
case BLOBMSG_TYPE_INT8:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u8(attr));
add_pv_node(path, value, NULL, pv_list);
add_pv_list(path, value, NULL, pv_list);
break;
case BLOBMSG_TYPE_INT16:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u16(attr));
add_pv_node(path, value, NULL, pv_list);
add_pv_list(path, value, NULL, pv_list);
break;
case BLOBMSG_TYPE_INT32:
snprintf(value, MAX_DM_VALUE, "%u", blobmsg_get_u32(attr));
add_pv_node(path, value, NULL, pv_list);
add_pv_list(path, value, NULL, pv_list);
break;
case BLOBMSG_TYPE_INT64:
snprintf(value, MAX_DM_VALUE, "%"PRIu64"", blobmsg_get_u64(attr));
add_pv_node(path, value, NULL, pv_list);
add_pv_list(path, value, NULL, pv_list);
break;
case BLOBMSG_TYPE_TABLE:
serialize_blob_msg(attr, path, pv_list);
@ -181,7 +181,7 @@ static void uspd_event_handler(struct ubus_context *ctx, struct ubus_event_handl
blobmsg_add_string(&b, "name", dm_path);
generate_blob_input(&bb, type, &pv_list);
blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, "input", blob_data(bb.head), blob_len(bb.head));
ubus_send_event(ctx, "usp.event", b.head);
ubus_send_event(ctx, BBF_EVENT, b.head);
blob_buf_free(&bb);
blob_buf_free(&b);
@ -206,16 +206,6 @@ static void add_ubus_event_handler(struct ubus_event_handler *ev, struct list_he
list_add_tail(&node->list, ev_list);
}
void list_event_schema(struct blob_buf *bb)
{
bbf_dm_get_supported_dm(bb, ROOT_NODE, false, EVENT_ONLY);
}
bool is_registered_event(char *name)
{
return bbf_dm_event_registered(name);
}
void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list)
{
struct ev_handler_node *iter = NULL, *node = NULL;
@ -265,3 +255,38 @@ int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list)
return 0;
}
bool is_registered_event(char *name)
{
bool ret = false;
if (!name)
return false;
struct dmctx bbf_ctx = {
.in_param = ROOT_NODE,
.nextlevel = false,
.iscommand = false,
.isevent = true,
.isinfo = false,
.instance_mode = INSTANCE_MODE_NUMBER,
.dm_type = BBFDM_USP
};
bbf_init(&bbf_ctx);
if (0 == usp_dm_exec(&bbf_ctx, BBF_SCHEMA)) {
struct dm_parameter *param;
list_for_each_entry(param, &bbf_ctx.list_parameter, list) {
if (strcmp(param->name, name) == 0) {
ret = true;
break;
}
}
}
bbf_cleanup(&bbf_ctx);
return ret;
}

View file

@ -1,7 +1,7 @@
#ifndef EVENT_H
#define EVENT_H
#include "usp.h"
#include "bbfdmd.h"
#include "common.h"
struct event_args_list {
@ -15,9 +15,8 @@ struct event_map_list {
struct event_args_list args[16];
};
void list_event_schema(struct blob_buf *bb);
bool is_registered_event(char *name);
void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list);
int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list);
bool is_registered_event(char *name);
#endif /* EVENT_H */

366
bbfdmd/src/get.c Normal file
View file

@ -0,0 +1,366 @@
/*
* get.c: Get handler for uspd
*
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "get.h"
#include "get_helper.h"
#include "pretty_print.h"
#include "ipc.h"
#include "libbbf_api/dmentry.h"
#include <libubus.h>
void usp_get_value_async(usp_data_t *data, void *output)
{
int fault = USP_ERR_OK;
struct pathNode *pn;
void *array = NULL;
bbf_init(&data->bbf_ctx);
blob_buf_init(&data->bb, 0);
if (data->is_raw)
array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
fault = usp_dm_exec(&data->bbf_ctx, BBF_GET_VALUE);
if (fault) {
fill_err_code_table(data, fault);
} else {
INFO("Preparing result for(%s)", data->bbf_ctx.in_param);
if (data->is_raw) {
struct dm_parameter *n = NULL;
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
void *table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", n->name);
bb_add_string(&data->bb, "data", n->data);
bb_add_string(&data->bb, "type", n->type);
blobmsg_close_table(&data->bb, table);
}
} else {
prepare_pretty_result(data->depth, &data->bb, &data->bbf_ctx);
}
}
bbf_sub_cleanup(&data->bbf_ctx);
}
if (data->is_raw)
blobmsg_close_array(&data->bb, array);
if (!validate_msglen(data)) {
ERR("IPC failed for path(%s)", data->bbf_ctx.in_param);
}
// Apply all bbfdm changes
if (is_transaction_running() == false)
dmuci_commit_bbfdm();
memcpy(output, data->bb.head, blob_pad_len(data->bb.head));
// free
blob_buf_free(&data->bb);
bbf_cleanup(&data->bbf_ctx);
}
void usp_get_value(usp_data_t *data)
{
int fault = USP_ERR_OK;
struct pathNode *pn;
void *array = NULL;
memset(&data->bb, 0, sizeof(struct blob_buf));
bbf_init(&data->bbf_ctx);
blob_buf_init(&data->bb, 0);
if (data->is_raw)
array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
fault = usp_dm_exec(&data->bbf_ctx, BBF_GET_VALUE);
if (fault) {
fill_err_code_table(data, fault);
} else {
INFO("Preparing result for(%s)", data->bbf_ctx.in_param);
if (data->is_raw) {
struct dm_parameter *n = NULL;
void *table = NULL;
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", n->name);
bb_add_string(&data->bb, "data", n->data);
bb_add_string(&data->bb, "type", n->type);
blobmsg_close_table(&data->bb, table);
}
} else {
prepare_pretty_result(data->depth, &data->bb, &data->bbf_ctx);
}
}
bbf_sub_cleanup(&data->bbf_ctx);
}
if (data->is_raw)
blobmsg_close_array(&data->bb, array);
if (!validate_msglen(data)) {
ERR("IPC failed");
}
// Apply all bbfdm changes
if (is_transaction_running() == false)
dmuci_commit_bbfdm();
ubus_send_reply(data->ctx, data->req, data->bb.head);
// free
blob_buf_free(&data->bb);
bbf_cleanup(&data->bbf_ctx);
}
void usp_get_names(usp_data_t *data)
{
int fault = USP_ERR_OK;
struct pathNode *pn;
bbf_init(&data->bbf_ctx);
void *array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
fault = usp_dm_exec(&data->bbf_ctx, BBF_GET_NAME);
if (fault) {
fill_err_code_table(data, fault);
} else {
struct dm_parameter *n = NULL;
void *table = NULL;
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", n->name);
blobmsg_add_string(&data->bb, "data", n->data);
blobmsg_add_string(&data->bb, "type", n->type);
blobmsg_close_table(&data->bb, table);
}
}
bbf_sub_cleanup(&data->bbf_ctx);
}
blobmsg_close_array(&data->bb, array);
// Apply all bbfdm changes
if (is_transaction_running() == false)
dmuci_commit_bbfdm();
bbf_cleanup(&data->bbf_ctx);
}
void usp_get_instances(usp_data_t *data)
{
int fault = USP_ERR_OK;
struct pathNode *pn;
bbf_init(&data->bbf_ctx);
void *array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
fault = usp_dm_exec(&data->bbf_ctx, BBF_INSTANCES);
if (fault) {
fill_err_code_table(data, fault);
} else {
struct dm_parameter *n;
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
void *table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", n->name);
blobmsg_close_table(&data->bb, table);
}
}
bbf_sub_cleanup(&data->bbf_ctx);
}
blobmsg_close_array(&data->bb, array);
// Apply all bbfdm changes
if (is_transaction_running() == false)
dmuci_commit_bbfdm();
bbf_cleanup(&data->bbf_ctx);
}
static void fill_operate_schema(struct blob_buf *bb, struct dm_parameter *param)
{
blobmsg_add_string(bb, "path", param->name);
blobmsg_add_string(bb, "type", param->type);
blobmsg_add_string(bb, "data", param->additional_data);
if (param->data) {
void *array, *table;
const char **in, **out;
operation_args *args;
int i;
args = (operation_args *) param->data;
in = args->in;
if (in) {
array = blobmsg_open_array(bb, "input");
for (i = 0; in[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", in[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
}
out = args->out;
if (out) {
array = blobmsg_open_array(bb, "output");
for (i = 0; out[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", out[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
}
}
}
static void fill_event_schema(struct blob_buf *bb, struct dm_parameter *param)
{
blobmsg_add_string(bb, "path", param->name);
blobmsg_add_string(bb, "type", param->type);
if (param->data) {
event_args *ev;
void *table;
ev = (event_args *)param->data;
if (ev->param) {
const char **in = ev->param;
void *key = blobmsg_open_array(bb, "input");
for (int i = 0; in[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", in[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, key);
}
}
}
static void fill_param_schema(struct blob_buf *bb, struct dm_parameter *param)
{
blobmsg_add_string(bb, "path", param->name);
blobmsg_add_string(bb, "data", param->data ? param->data : "0");
blobmsg_add_string(bb, "type", param->type);
if (param->additional_data) {
const char **uniq_keys = (const char **)param->additional_data;
void *key = blobmsg_open_array(bb, "input");
void *table = NULL;
for (int i = 0; uniq_keys[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", uniq_keys[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, key);
}
}
int bbf_dm_get_supported_dm(usp_data_t *data)
{
struct dm_parameter *param;
struct pathNode *pn;
int fault = USP_ERR_OK;
bbf_init(&data->bbf_ctx);
void *array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pn, data->plist, list) {
bbf_sub_init(&data->bbf_ctx);
data->bbf_ctx.in_param = pn->path;
fault = usp_dm_exec(&data->bbf_ctx, BBF_SCHEMA);
if (fault) {
fill_err_code_table(data, fault);
} else {
INFO("Preparing result for(%s)", data->bbf_ctx.in_param);
list_for_each_entry(param, &data->bbf_ctx.list_parameter, list) {
int cmd = bbf_get_dm_type(param->type);
void *table = blobmsg_open_table(&data->bb, NULL);
if (cmd == DMT_COMMAND) {
fill_operate_schema(&data->bb, param);
} else if (cmd == DMT_EVENT) {
fill_event_schema(&data->bb, param);
} else {
fill_param_schema(&data->bb, param);
}
blobmsg_close_table(&data->bb, table);
}
}
bbf_sub_cleanup(&data->bbf_ctx);
}
blobmsg_close_array(&data->bb, array);
bbf_cleanup(&data->bbf_ctx);
return fault;
}

43
bbfdmd/src/get.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef GET_H
#define GET_H
#include "bbfdmd.h"
#include "common.h"
enum {
DM_GET_PATH,
DM_GET_PATHS,
DM_GET_MAXDEPTH,
DM_GET_OPTIONAL,
__DM_GET_MAX
};
enum {
DM_INSTANCES_PATH,
DM_INSTANCES_PATHS,
DM_INSTANCES_FIRST_LEVEL,
DM_INSTANCES_OPTIONAL,
__DM_INSTANCES_MAX
};
enum {
DM_SCHEMA_PATH,
DM_SCHEMA_PATHS,
DM_SCHEMA_FIRST_LEVEL,
DM_SCHEMA_COMMANDS,
DM_SCHEMA_EVENTS,
DM_SCHEMA_PARAMS,
DM_SCHEMA_OPTIONAL,
__DM_SCHEMA_MAX
};
void usp_get_value(usp_data_t *data);
void usp_get_value_async(usp_data_t *data, void *output);
void usp_get_names(usp_data_t *data);
void usp_get_instances(usp_data_t *data);
int bbf_dm_get_supported_dm(usp_data_t *data);
#endif /* GET_H */

333
bbfdmd/src/get_helper.c Normal file
View file

@ -0,0 +1,333 @@
/*
* get_helper.c: Get Fast handler for uspd
*
* Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
*
* Author: Shubham Sharma <shubham.sharma@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#define _XOPEN_SOURCE
#define _DEFAULT_SOURCE
#include <time.h>
#include <setjmp.h>
#include "get_helper.h"
#include "common.h"
#include "pretty_print.h"
#include "libbbf_api/dmentry.h"
#include "libbbf_dm/dmtree/tr181/device.h"
#include "libbbf_dm/dmtree/vendor/vendor.h"
DMOBJ *DM_ROOT_OBJ = tEntry181Obj;
DM_MAP_VENDOR *DM_VENDOR_EXTENSION[2] = {
tVendorExtension,
tVendorExtensionOverwrite
};
DM_MAP_VENDOR_EXCLUDE *DM_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
// uloop.h does not have versions, below line is to use
// deprecated uloop_timeout_remaining for the time being
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
static struct {
int trans_id;
struct uloop_timeout trans_timeout;
int timeout_ms;
} g_current_trans = {.trans_id=0, .timeout_ms=10000};
static jmp_buf gs_jump_location;
static bool gs_jump_called_by_bbf = false;
void print_last_dm_object(void)
{
char buff[MAX_DM_PATH];
bbf_debug_browse_path(buff, MAX_DM_PATH);
ERR("# PID[%ld] Last DM path [%s] #", getpid(), buff);
}
void handle_pending_signal(int sig)
{
if (gs_jump_called_by_bbf) {
siglongjmp(gs_jump_location, 1);
}
ERR("Exception [%d] not cause by bbf dm, exit with error", sig);
exit(1);
}
void bb_add_string(struct blob_buf *bb, const char *name, const char *value)
{
blobmsg_add_string(bb, name, value ? value : "");
}
void bbf_init(struct dmctx *dm_ctx)
{
bbf_ctx_init(dm_ctx, DM_ROOT_OBJ, DM_VENDOR_EXTENSION, DM_VENDOR_EXTENSION_EXCLUDE);
}
void bbf_cleanup(struct dmctx *dm_ctx)
{
bbf_ctx_clean(dm_ctx);
}
void bbf_sub_init(struct dmctx *dm_ctx)
{
bbf_ctx_init_sub(dm_ctx, DM_ROOT_OBJ, DM_VENDOR_EXTENSION, DM_VENDOR_EXTENSION_EXCLUDE);
}
void bbf_sub_cleanup(struct dmctx *dm_ctx)
{
bbf_ctx_clean_sub(dm_ctx);
}
bool present_in_path_list(struct list_head *plist, char *entry)
{
struct pathNode *pos;
list_for_each_entry(pos, plist, list) {
if (!strcmp(pos->path, entry))
return true;
}
return false;
}
void add_pv_list(char *para, char *val, char *type, struct list_head *pv_list)
{
struct pvNode *node = NULL;
node = (struct pvNode *) malloc(sizeof(*node));
if (!node) {
ERR("Out of memory!");
return;
}
node->param = (para) ? strdup(para) : strdup("");
node->val = (val) ? strdup(val) : strdup("");
node->type = (type) ? strdup(type) : strdup("");
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, pv_list);
}
void free_pv_list(struct list_head *pv_list)
{
struct pvNode *iter, *node;
list_for_each_entry_safe(iter, node, pv_list, list) {
free(iter->param);
free(iter->val);
free(iter->type);
list_del(&iter->list);
free(iter);
}
}
void add_path_list(char *param, struct list_head *plist)
{
struct pathNode *node = NULL;
size_t len;
node = (struct pathNode *)calloc(1, sizeof(*node));
if (!node) {
ERR("Out of memory!");
return;
}
len = DM_STRLEN(param);
strncpyt(node->path, param, len + 1);
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, plist);
}
void free_path_list(struct list_head *plist)
{
struct pathNode *iter, *node;
list_for_each_entry_safe(iter, node, plist, list) {
list_del(&iter->list);
free(iter);
}
}
int usp_dm_exec(struct dmctx *bbf_ctx, int cmd)
{
int fault = 0;
if (bbf_ctx->in_param == NULL)
return USP_FAULT_INTERNAL_ERROR;
if (sigsetjmp(gs_jump_location, 1) == 0) {
gs_jump_called_by_bbf = true;
fault = bbf_entry_method(bbf_ctx, cmd);
} else {
ERR("PID [%ld]::Exception on [%d => %s]", getpid(), cmd, bbf_ctx->in_param);
print_last_dm_object();
fault = USP_FAULT_INTERNAL_ERROR;
}
gs_jump_called_by_bbf = false;
if (fault)
WARNING("Fault [%d => %d => %s]", fault, cmd, bbf_ctx->in_param);
return fault;
}
void fill_err_code_table(usp_data_t *data, int fault)
{
void *table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", data->bbf_ctx.in_param);
blobmsg_add_u32(&data->bb, "fault", bbf_fault_map(data->bbf_ctx.dm_type, fault));
bb_add_string(&data->bb, "fault_msg", "");
blobmsg_close_table(&data->bb, table);
}
void fill_err_code_array(usp_data_t *data, int fault)
{
void *array = blobmsg_open_array(&data->bb, "results");
void *table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", data->bbf_ctx.in_param);
blobmsg_add_u32(&data->bb, "fault", bbf_fault_map(data->bbf_ctx.dm_type, fault));
bb_add_string(&data->bb, "fault_msg", "");
blobmsg_close_table(&data->bb, table);
blobmsg_close_array(&data->bb, array);
}
static void transaction_timeout_handler(struct uloop_timeout *t __attribute__((unused)))
{
INFO("Transaction timeout called");
transaction_abort(g_current_trans.trans_id, NULL);
}
static int get_random_id(void)
{
int ret;
srand(time(0));
ret = rand();
if (!ret)
ret = 1;
return ret;
}
// Returns transaction id if successful, otherwise 0
int transaction_start(uint32_t max_timeout)
{
int ret = 0;
uint32_t timeout;
if (g_current_trans.trans_id) {
WARNING("Transaction already in-process");
return 0;
}
if (max_timeout > 0) {
timeout = max_timeout * 1000;
} else {
timeout = g_current_trans.timeout_ms;
}
ret = get_random_id();
g_current_trans.trans_id = ret;
g_current_trans.trans_timeout.cb = transaction_timeout_handler;
uloop_timeout_set(&g_current_trans.trans_timeout, timeout);
INFO("Transaction started with id %d, timeout %zd", g_current_trans.trans_id, timeout);
return ret;
}
int transaction_status(struct blob_buf *bb, int trans_id)
{
if (g_current_trans.trans_id == trans_id) {
int rem = uloop_timeout_remaining(&g_current_trans.trans_timeout);
blobmsg_add_string(bb, "status", "on-going");
blobmsg_add_u32(bb, "remaining_time", rem / 1000);
} else {
blobmsg_add_string(bb, "status", "not-exists");
}
return 0;
}
bool is_transaction_running(void)
{
return (g_current_trans.trans_id == 0 ? false : true);
}
bool is_transaction_valid(int trans_id)
{
if (trans_id == 0)
return false;
return (trans_id == g_current_trans.trans_id);
}
int transaction_commit(int trans_id, struct blob_buf *bb, bool is_service_restart)
{
int ret = -1;
if (is_transaction_valid(trans_id)) {
INFO("Commit on-going transaction");
uloop_timeout_cancel(&g_current_trans.trans_timeout);
g_current_trans.trans_id = 0;
bbf_entry_restart_services(bb, is_service_restart);
ret = 0;
} else {
WARNING("Transaction id mismatch(%d)", trans_id);
}
return ret;
}
int transaction_abort(int trans_id, struct blob_buf *bb)
{
int ret = -1;
if (is_transaction_valid(trans_id)) {
INFO("Abort on-going transaction");
uloop_timeout_cancel(&g_current_trans.trans_timeout);
g_current_trans.trans_id = 0;
bbf_entry_revert_changes(bb);
ret = 0;
} else {
WARNING("Transaction id mismatch(%d)", trans_id);
}
return ret;
}
int configure_transaction_timeout(int timeout)
{
if (timeout <= 0)
return -1;
g_current_trans.timeout_ms = timeout * 1000;
return 0;
}

55
bbfdmd/src/get_helper.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef GET_HELPER_H
#define GET_HELPER_H
#include "bbfdmd.h"
#include "common.h"
#include "libbbf_api/dmbbf.h"
#include <libubus.h>
struct pvNode {
char *param;
char *val;
char *type;
struct list_head list;
};
struct pathNode {
struct list_head list;
char path[MAX_DM_PATH];
};
extern DMOBJ *DM_ROOT_OBJ;
void handle_pending_signal(int sig);
void print_last_dm_object(void);
void bbf_init(struct dmctx *dm_ctx);
void bbf_cleanup(struct dmctx *dm_ctx);
void bbf_sub_init(struct dmctx *dm_ctx);
void bbf_sub_cleanup(struct dmctx *dm_ctx);
bool present_in_path_list(struct list_head *plist, char *entry);
int usp_dm_exec(struct dmctx *bbf_ctx, int cmd);
void add_pv_list(char *para, char *val, char *type, struct list_head *pv_list);
void free_pv_list(struct list_head *pv_list);
void add_path_list(char *param, struct list_head *plist);
void free_path_list(struct list_head *plist);
void fill_err_code_table(usp_data_t *data, int fault);
void fill_err_code_array(usp_data_t *data, int fault);
void bb_add_string(struct blob_buf *bb, const char *name, const char *value);
int transaction_start(uint32_t max_timeout);
int transaction_commit(int trans_id, struct blob_buf *bb, bool is_service_restart);
int transaction_abort(int trans_id, struct blob_buf *bb);
int transaction_status(struct blob_buf *bb, int trans_id);
bool is_transaction_running(void);
bool is_transaction_valid(int trans_id);
int configure_transaction_timeout(int timeout);
#endif /* GET_HELPER_H */

View file

@ -31,4 +31,4 @@
#define DEF_IPC_DATA_LEN (10 * 1024 * 1024 - 128) // 10M - 128 bytes
#endif
#endif // end IPC_H
#endif /* IPC_H */

135
bbfdmd/src/operate.c Normal file
View file

@ -0,0 +1,135 @@
/*
* operate.c: Operate handler for uspd
*
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "common.h"
#include "operate.h"
#include "get_helper.h"
#include "pretty_print.h"
#include "ipc.h"
#include <libubus.h>
static int usp_dm_operate(usp_data_t *data)
{
int fault = 0, ret = 0;
void *table, *array;
bbf_init(&data->bbf_ctx);
ret = usp_dm_exec(&data->bbf_ctx, BBF_OPERATE);
// This switch should be removed in the future and will be treated internally
switch (ret) {
case CMD_NOT_FOUND:
fault = USP_FAULT_INVALID_PATH;
break;
case CMD_INVALID_ARGUMENTS:
fault = USP_FAULT_INVALID_ARGUMENT;
break;
case CMD_FAIL:
fault = USP_FAULT_COMMAND_FAILURE;
break;
case CMD_SUCCESS:
fault = USP_ERR_OK;
DEBUG("command executed successfully");
break;
default:
WARNING("Case(%d) not defined", fault);
fault = USP_FAULT_INVALID_PATH;
break;
}
void *global_table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", data->bbf_ctx.in_param);
blobmsg_add_string(&data->bb, "data", data->bbf_ctx.linker);
if (ret == CMD_SUCCESS) {
struct dm_parameter *n;
if (data->is_raw) {
array = blobmsg_open_array(&data->bb, "output");
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", n->name);
bb_add_string(&data->bb, "data", n->data);
bb_add_string(&data->bb, "type", n->type);
blobmsg_close_table(&data->bb, table);
}
blobmsg_close_array(&data->bb, array);
} else {
LIST_HEAD(pv_local);
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
add_pv_list(n->name, n->data, n->type, &pv_local);
}
array = blobmsg_open_array(&data->bb, "output");
table = blobmsg_open_table(&data->bb, NULL);
prepare_result_blob(&data->bb, &pv_local);
blobmsg_close_table(&data->bb, table);
blobmsg_close_array(&data->bb, array);
free_pv_list(&pv_local);
}
} else {
blobmsg_add_u32(&data->bb, "fault", fault);
bb_add_string(&data->bb, "fault_msg", "");
}
blobmsg_close_table(&data->bb, global_table);
bbf_cleanup(&data->bbf_ctx);
if (fault != USP_ERR_OK) {
WARNING("Fault(%d) path(%s) input(%s)", fault, data->bbf_ctx.in_param, data->bbf_ctx.in_value);
return fault;
}
return USP_ERR_OK;
}
static void usp_operate_cmd(usp_data_t *data)
{
void *array = blobmsg_open_array(&data->bb, "results");
usp_dm_operate(data);
blobmsg_close_array(&data->bb, array);
}
void usp_operate_cmd_async(usp_data_t *data, void *output)
{
blob_buf_init(&data->bb, 0);
usp_operate_cmd(data);
memcpy(output, data->bb.head, blob_pad_len(data->bb.head));
blob_buf_free(&data->bb);
}
void usp_operate_cmd_sync(usp_data_t *data)
{
blob_buf_init(&data->bb, 0);
usp_operate_cmd(data);
ubus_send_reply(data->ctx, data->req, data->bb.head);
blob_buf_free(&data->bb);
}

View file

@ -1,19 +1,20 @@
#ifndef OPERATE_H
#define OPERATE_H
#include "usp.h"
#include "bbfdmd.h"
#include "common.h"
#include "libbbf_api/dmbbf.h"
enum {
DM_OPERATE_PATH,
DM_OPERATE_ACTION,
DM_OPERATE_COMMAND,
DM_OPERATE_COMMAND_KEY,
DM_OPERATE_INPUT,
DM_OPERATE_PROTO,
DM_OPERATE_INSTANCE,
DM_OPERATE_OPTIONAL,
__DM_OPERATE_MAX,
};
void list_operate_schema(struct blob_buf *bb);
void usp_operate_cmd_async(usp_data_t *data, void *output);
void usp_operate_cmd_sync(usp_data_t *data);
#endif /* OPERATE_H */

View file

@ -23,8 +23,6 @@
#include "common.h"
#include "get_helper.h"
#include "pretty_print.h"
#include <libbbfdm/dmbbfcommon.h>
// private function and structures
struct resultstack {
@ -159,13 +157,12 @@ static size_t get_glob_len(char *path)
return(ret);
}
static void resulting(uint8_t maxdepth, char *path, char *qPath, struct dmctx *bbf_ctx, struct list_head *pv_local)
static void resulting(uint8_t maxdepth, char *path, struct dmctx *bbf_ctx, struct list_head *pv_local)
{
struct dm_parameter *n;
uint8_t count;
size_t plen = get_glob_len(qPath);
//size_t plen = 0;
size_t plen = get_glob_len(bbf_ctx->in_param);
size_t path_len = DM_STRLEN(path);
list_for_each_entry(n, &bbf_ctx->list_parameter, list) {
@ -174,28 +171,28 @@ static void resulting(uint8_t maxdepth, char *path, char *qPath, struct dmctx *b
if (path[path_len - 1] == DELIM) {
if (!strncmp(n->name, path, path_len)) {
if (is_search_by_reference(qPath))
if (is_search_by_reference(bbf_ctx->in_param))
plen = 0;
if (maxdepth > 4 || maxdepth == 0) {
add_pv_node(n->name + plen, n->data, n->type, pv_local);
add_pv_list(n->name + plen, n->data, n->type, pv_local);
} else {
count = count_delim(n->name + path_len);
if (count < maxdepth)
add_pv_node(n->name + plen, n->data, n->type, pv_local);
add_pv_list(n->name + plen, n->data, n->type, pv_local);
}
}
} else {
if (!strcmp(n->name, path)) {
if (is_search_by_reference(qPath))
if (is_search_by_reference(bbf_ctx->in_param))
plen = 0;
if (maxdepth > 4 || maxdepth == 0) {
add_pv_node(n->name + plen, n->data, n->type, pv_local);
add_pv_list(n->name + plen, n->data, n->type, pv_local);
} else {
count = count_delim(n->name + path_len);
if (count < maxdepth)
add_pv_node(n->name + plen, n->data, n->type, pv_local);
add_pv_list(n->name + plen, n->data, n->type, pv_local);
}
}
}
@ -208,7 +205,7 @@ static void add_data_blob(struct blob_buf *bb, char *param, char *value, char *t
return;
DEBUG("# Adding BLOB (%s)::(%s)", param, value);
switch (get_dm_type(type)) {
switch (bbf_get_dm_type(type)) {
case DMT_UNINT:
blobmsg_add_u64(bb, param, (uint32_t)strtoul(value, NULL, 10));
break;
@ -404,87 +401,13 @@ void prepare_result_blob(struct blob_buf *bb, struct list_head *pv_list)
free_result_list(&result_stack);
}
void prepare_pretty_result(uint8_t maxdepth, char *qPath, struct blob_buf *bb,
struct dmctx *bbf_ctx, struct list_head *rslvd)
void prepare_pretty_result(uint8_t maxdepth, struct blob_buf *bb, struct dmctx *bbf_ctx)
{
struct pathNode *iter = NULL;
LIST_HEAD(pv_local);
list_for_each_entry(iter, rslvd, list) {
resulting(maxdepth, iter->path, qPath, bbf_ctx, &pv_local);
}
struct pvNode *pv;
DEBUG("################### DATA to PROCESS ##################");
list_for_each_entry(pv, &pv_local, list) {
DEBUG("## %s ##", pv->param);
}
DEBUG("######################################################");
resulting(maxdepth, bbf_ctx->in_param, bbf_ctx, &pv_local);
prepare_result_blob(bb, &pv_local);
free_pv_list(&pv_local);
}
/* This function is not used anywhere but kept for debugging purpose hence suppressed */
// cppcheck-suppress unusedFunction
void dump_pv_list(struct list_head *pv_list)
{
struct pvNode *pv = NULL;
INFO("############### PV list Dump #########");
list_for_each_entry(pv, pv_list, list) {
INFO("## (%s)::(%s)::(%s) ##", pv->param, pv->val, pv->type);
}
INFO("############# dump done ###############");
}
/* This function is not used anywhere but kept for debugging purpose hence suppressed */
// cppcheck-suppress unusedFunction
void dump_resolved_list(struct list_head *resolved_list)
{
struct pathNode *iter;
INFO("********************Resolved List Dump***********************");
list_for_each_entry(iter, resolved_list, list) {
INFO("## %s ##", iter->path);
}
INFO("**************************DONE*******************************");
}
void prepare_result_raw(struct blob_buf *bb, struct dmctx *bbf_ctx, struct list_head *rslvd)
{
struct pathNode *iter = NULL;
struct dm_parameter *n;
void *array, *table;
array = blobmsg_open_array(bb, "parameters");
list_for_each_entry(iter, rslvd, list) {
size_t ilen = DM_STRLEN(iter->path);
if (ilen == 0)
continue;
list_for_each_entry(n, &bbf_ctx->list_parameter, list) {
if (iter->path[ilen - 1] == DELIM) {
if (!strncmp(n->name, iter->path, ilen)) {
table = blobmsg_open_table(bb, NULL);
bb_add_string(bb, "parameter", n->name);
bb_add_string(bb, "value", n->data);
bb_add_string(bb, "type", n->type);
blobmsg_close_table(bb, table);
}
} else {
if (!strcmp(n->name, iter->path)) {
table = blobmsg_open_table(bb, NULL);
bb_add_string(bb, "parameter", n->name);
bb_add_string(bb, "value", n->data);
bb_add_string(bb, "type", n->type);
blobmsg_close_table(bb, table);
}
}
}
}
blobmsg_close_array(bb, array);
}

View file

@ -24,10 +24,6 @@
#define PRETTY_PRINT_H
void prepare_result_blob(struct blob_buf *bb, struct list_head *pv_list);
void prepare_pretty_result(uint8_t maxdepth, char *qPath, struct blob_buf *bb,
struct dmctx *bbf_ctx, struct list_head *rslvd);
void prepare_result_raw(struct blob_buf *bb, struct dmctx *bbf_ctx, struct list_head *rslvd);
void dump_pv_list(struct list_head *pv_list);
void dump_resolved_list(struct list_head *resolved_list);
void prepare_pretty_result(uint8_t maxdepth, struct blob_buf *bb, struct dmctx *bbf_ctx);
#endif
#endif /* PRETTY_PRINT_H */

111
bbfdmd/src/set.c Normal file
View file

@ -0,0 +1,111 @@
/*
* set.c: Set handler for uspd
*
* Copyright (C) 2023 iopsys Software Solutions AB. All rights reserved.
*
* Author: Vivek Dutta <vivek.dutta@iopsys.eu>
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "set.h"
#include "get_helper.h"
#include <libubus.h>
int usp_set_value(usp_data_t *data)
{
struct pvNode *pv = NULL;
void *array = NULL;
int fault = USP_ERR_OK;
array = blobmsg_open_array(&data->bb, "results");
list_for_each_entry(pv, data->plist, list) {
data->bbf_ctx.in_param = pv->param;
data->bbf_ctx.in_value = pv->val;
fault = usp_dm_exec(&data->bbf_ctx, BBF_SET_VALUE);
if (fault) {
fill_err_code_table(data, fault);
} else {
void *table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", data->bbf_ctx.in_param);
bb_add_string(&data->bb, "data", "1");
blobmsg_close_table(&data->bb, table);
}
}
blobmsg_close_array(&data->bb, array);
return fault;
}
int fill_pvlist_set(char *param_name, char *param_value, struct blob_attr *blob_table, struct list_head *pv_list)
{
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
char path[MAX_DM_PATH], value[MAX_DM_VALUE];
size_t plen = DM_STRLEN(param_name);
if (plen == 0)
return USP_FAULT_INVALID_PATH;
if (!param_value)
goto blob__table;
if (param_name[plen - 1] == '.')
return USP_FAULT_INVALID_PATH;
add_pv_list(param_name, param_value, NULL, pv_list);
blob__table:
if (!blob_table)
return USP_ERR_OK;
size_t tlen = (size_t)blobmsg_data_len(blob_table);
__blob_for_each_attr(attr, blobmsg_data(blob_table), tlen) {
hdr = blob_data(attr);
switch (blob_id(attr)) {
case BLOBMSG_TYPE_STRING:
snprintf(value, MAX_DM_VALUE, "%s", blobmsg_get_string(attr));
break;
case BLOBMSG_TYPE_INT8:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u8(attr));
break;
case BLOBMSG_TYPE_INT16:
snprintf(value, MAX_DM_VALUE, "%d", blobmsg_get_u16(attr));
break;
case BLOBMSG_TYPE_INT32:
snprintf(value, MAX_DM_VALUE, "%u", blobmsg_get_u32(attr));
break;
case BLOBMSG_TYPE_INT64:
snprintf(value, MAX_DM_VALUE, "%"PRIu64"", blobmsg_get_u64(attr));
break;
default:
INFO("Unhandled set request type|%x|", blob_id(attr));
return USP_FAULT_INVALID_ARGUMENT;
}
snprintf(path, MAX_DM_PATH, "%s%s", param_name, (char *)hdr->name);
add_pv_list(path, value, NULL, pv_list);
}
return USP_ERR_OK;
}

21
bbfdmd/src/set.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef SET_H
#define SET_H
#include "bbfdmd.h"
#include "common.h"
#include "libbbf_api/dmbbf.h"
enum {
DM_SET_PATH,
DM_SET_VALUE,
DM_SET_OBJ_PATH,
DM_SET_OPTIONAL,
__DM_SET_MAX,
};
int fill_pvlist_set(char *param_name, char *param_value, struct blob_attr *blob_table, struct list_head *pv_list);
int usp_set_value(usp_data_t *data);
#endif /* SET_H */

2313
docs/apis/ubus/bbf.md Normal file

File diff suppressed because it is too large Load diff

181
docs/apis/uci/bbfd.md Normal file
View file

@ -0,0 +1,181 @@
# UCI Config
<tbody>
<tr>
<td colspan="2">
<div style="font-weight: bold">bbfdmd</div>
<table style="width:100%">
<tbody>
<tr>
<td>
<div style="font-weight: bold; font-size: 14px">section</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">description</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">multi</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">options</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">globals</div>
</td>
<td class="td_row_even">
<div class="td_row_even">BBF daemon Settings</div>
</td>
<td class="td_row_even">
<div class="td_row_even">false</div>
</td>
<td class="td_row_even">
<table style="width:100%">
<tbody>
<tr>
<td>
<div style="font-weight: bold; font-size: 14px">name</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">type</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">required</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">default</div>
</td>
<td>
<div style="font-weight: bold; font-size: 14px">description</div>
</td>
</tr>
<tr>
<td class="td_row_odd">
<div class="td_row_odd">debug</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">boolean</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">no</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd"></div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">Enabled debug logging</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">sock</div>
</td>
<td class="td_row_even">
<div class="td_row_even">string</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even"></div>
</td>
<td class="td_row_even">
<div class="td_row_even">Path for ubus socket to register bbfdmd services</div>
</td>
</tr>
<tr>
<td class="td_row_odd">
<div class="td_row_odd">transaction_timeout</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">integer</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">no</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">10</div>
</td>
<td class="td_row_odd">
<div class="td_row_odd">Transaction timeout value in seconds</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">loglevel</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">1</div>
</td>
<td class="td_row_even">
<div class="td_row_even">Internal loglevel for debugging {0: No Logs; 1: Errors only; 2: Errors
and warnings; 3: Error, warning and info; 4: Everything}</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">subprocess_level</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">2</div>
</td>
<td class="td_row_even">
<div class="td_row_even">This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess.</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">bbf_caching_time</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">0</div>
</td>
<td class="td_row_even">
<div class="td_row_even">Max caching time in seconds for ubus output used in datamodel parameters. If not configured, output shall be cleared end the end of call.</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">refresh_time</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">5</div>
</td>
<td class="td_row_even">
<div class="td_row_even">The time period in seconds after which bbfdmd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed.</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>

View file

@ -416,60 +416,6 @@ The application should bring its JSON file under **'/etc/bbfdm/json/'** path wit
}
```
- **UBUS command:** ubus call usp operate '{"path":"Device.X_IOPSYS_Test.", "action":"Status()", "input":{"Option":"Last"}}'
```bash
{
"Results": [
{
"path": "Device.X_IOPSYS_Test.Status()",
"result": [
{
"Result": "Success"
}
]
}
]
}
```
- **UBUS command:** ubus call usp get_supported_dm
```bash
{
"parameters": [
{
"parameter": "Device.X_IOPSYS_Test.Push!",
"type": "xsd:event",
"in": [
"data"
]
},
...
]
}
```
- **UBUS command:** ubus call usp list_operate
```bash
{
"parameters": [
{
"parameter": "Device.X_IOPSYS_Test.Status()",
"type": "async",
"in": [
"Option"
],
"out": [
"Result"
]
},
...
]
}
```
> Note1: JSON File can only add vendor or standard objects that are not implemented by `libbbf_dm`
> Note2: JSON File is not allowed to overwrite objects/parameters

View file

@ -0,0 +1,73 @@
#!/bin/bash
echo "$0 preparation script"
pwd
source ./gitlab-ci/shared.sh
echo "Starting supervisor"
supervisorctl shutdown
sleep 1
supervisord -c /etc/supervisor/supervisord.conf
sleep 3
supervisorctl status all
exec_cmd ubus wait_for bbfdm
supervisorctl status all
# debug logging
echo "Checking ubus status [$(date '+%d/%m/%Y %H:%M:%S')]"
ubus list
ubus -v list bbf
echo "Checking system resources"
free -h
df -h
echo "## Running python based verification of functionalities ##"
echo > ./funl-result.log
num=0
for test in `ls -1 ./test/python/*.py`
do
num=$(( num + 1 ))
sleep 1
$test
if [ $? -eq 0 ]; then
echo "ok ${num} - $test" >> ./funl-result.log
else
echo "not ok ${num} - $test" >> ./funl-result.log
fi
done
echo "1..${num}" >> ./funl-result.log
generate_report python_test ./funl-result.log
# run functional on bbf object validation
rm /usr/share/rpcd/schemas/bbf.json
fault=0
# run functional on bbf object validation
cp -r ./schemas/ubus/bbf.json /usr/share/rpcd/schemas/bbf.json
ubus-api-validator -t 5 -f ./test/funl/validation/bbf.validation.json > ./funl-result.log
fault=$(( $fault + $? ))
generate_report bbf_positive ./funl-result.log
supervisorctl stop all
supervisorctl status
#report part
gcovr -r . --xml -o ./funl-test-coverage.xml
gcovr -r .
date +%s > timestamp.log
echo "Checking memory leaks..."
grep -q "Leak" memory-report.xml
error_on_zero $?
if [ "${fault}" -ne 0 ]; then
echo "Failed running ubus-api-validator fault[$fault]"
exit $fault
fi
echo "Functional Test :: PASS"

View file

@ -4,17 +4,12 @@ echo "Functional API Tests"
pwd
source ./gitlab-ci/shared.sh
echo "Starting supervisor in current directory"
echo "Starting supervisor"
supervisorctl shutdown
sleep 1
supervisord -c supervisord.conf
# compile and install libbbf
install_libbbf
supervisorctl status all
supervisorctl update
supervisord -c /etc/supervisor/supervisord.conf
sleep 3
supervisorctl status all
echo "Running the functional API test cases"

View file

@ -4,21 +4,12 @@ echo "Functional Tests"
pwd
source ./gitlab-ci/shared.sh
echo "Starting supervisor in current directory"
echo "Starting supervisor"
supervisorctl shutdown
sleep 1
supervisord -c supervisord.conf
# compile and install libbbf
install_libbbf
#compile and install libbbf_test dynamic extension library
install_libbbf_test
supervisorctl status all
supervisorctl update
supervisorctl restart all
supervisord -c /etc/supervisor/supervisord.conf
sleep 3
supervisorctl status all
echo "Running the functional test cases"

View file

@ -0,0 +1,39 @@
#!/bin/bash
echo "install dependencies of bbf"
pwd
source ./gitlab-ci/shared.sh
# install required packages
apt update
apt install -y python3-pip iproute2 libmxml-dev uuid-dev zip
pip3 install pexpect ubus
# compile and install libbbf
install_libbbf
#compile and install libbbf_test dynamic extension library
install_libbbf_test
git clone -b devel --depth 1 https://dev.iopsys.eu/feed/iopsys.git /opt/dev/iopsys
git clone -b devel --depth 1 https://dev.iopsys.eu/bbf/bulkdata.git /opt/dev/bulkdata
cp -f /opt/dev/iopsys/urlfilter/files/etc/bbfdm/json/urlfilter.json /etc/bbfdm/json
cp -f /opt/dev/iopsys/obuspa/files/etc/bbfdm/json/USPAgent.json /etc/bbfdm/json
cp -f /opt/dev/iopsys/obuspa/files/etc/bbfdm/json/TransferComplete.json /etc/bbfdm/json
cp -f /opt/dev/iopsys/icwmp/files/etc/bbfdm/json/CWMPManagementServer.json /etc/bbfdm/json
cp -f /opt/dev/iopsys/ponmngr/files/etc/bbfdm/json/xpon.json /etc/bbfdm/json
cp -f /opt/dev/bulkdata/bbf_plugin/bulkdata.json /etc/bbfdm/json
# install usermngr plugin
install_libusermngr
# install periodicstats plugin
install_libperiodicstats
# install cwmpdm plugin
install_libcwmpdm
ls /usr/lib/bbfdm/
ls /etc/bbfdm/json/

View file

@ -11,3 +11,10 @@ numprocs_start=1
startretries=0
priority=2
command=/bin/bash -c "/usr/sbin/rpcd"
[program:bbfdmd]
autorestart=false
numprocs_start=2
startretries=0
priority=3
command=/bin/bash -c "/usr/bin/valgrind --xml=yes --xml-file=/builds/bbf/bbfdm/memory-report.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes --leak-resolution=high --show-error-list=yes --child-silent-after-fork=yes /usr/sbin/bbfdmd"

View file

@ -4,27 +4,14 @@ echo "Functional API Tests"
pwd
. ./gitlab-ci/shared.sh
echo "Starting supervisor in current directory"
supervisorctl shutdown
sleep 1
supervisord -c supervisord.conf
# install required packages
exec_cmd apt update
exec_cmd apt install -y zip
date +%s > timestamp.log
# compile and install libbbf
install_libbbf
echo "Starting supervisor"
supervisorctl shutdown
sleep 1
supervisord -c /etc/supervisor/supervisord.conf
sleep 3
install_libbbf_test
install_libperiodicstats
supervisorctl update
supervisorctl status all
supervisorctl restart all
sleep 5
supervisorctl status all
function run_valgrind()
@ -50,28 +37,18 @@ echo "Running memory check on datamodel"
run_valgrind_verbose -u get Device.RootDataModelVersion
run_valgrind_verbose -c get Device.RootDataModelVersion
run_valgrind_verbose -u list_operate
run_valgrind -u get_schema
run_valgrind -u instances Device.
run_valgrind -c get Device.
run_valgrind -c list_operate
run_valgrind -c get_schema
run_valgrind_verbose -c instances Device.
run_valgrind -u get_info Device. 0
run_valgrind -u get_info Device. 1
run_valgrind -u get_info Device. 2
run_valgrind -u get_info Device. 3
run_valgrind -u get Device.
run_valgrind -c get Device.
run_valgrind -u instances Device.
run_valgrind -c instances Device.
run_valgrind -u schema Device.
run_valgrind -c schema Device.
run_valgrind_verbose -u get Device.IP.Interface.*.IPv4Address.
run_valgrind_verbose -c get Device.IP.Interface.*.IPv6Address.*.IPAddress
run_valgrind_verbose -u get_name Device.IP.Interface.*.IPv4Address. 1
run_valgrind_verbose -c get_name Device.DeviceInfo.VendorConfigFile.*.Name 0
run_valgrind_redirect -u get Device.
run_valgrind_redirect -c get Device.
@ -84,7 +61,4 @@ gcovr -r . 2> /dev/null #throw away stderr
# Artefact
gcovr -r . 2> /dev/null --xml -o ./memory-test-coverage.xml
echo "Generating release"
generate_release
echo "Memory Test :: PASS"

View file

@ -12,6 +12,6 @@ cp -r ./test/files/var/* /var/
cp -r ./test/files/tmp/* /tmp/
cp -r ./test/files/lib/* /lib/
apt update && apt install -y iproute2
ls /etc/config/
cp ./gitlab-ci/iopsys-supervisord.conf /etc/supervisor/conf.d/
ls /etc/config/

View file

@ -36,43 +36,15 @@ function exec_cmd_verbose()
fi
}
function install_wolfssl()
{
CUR="${PWD}"
echo "Installing wolfssl-4.8.1"
cd /opt/dev/
rm -rf wolfssl*
wget -q https://github.com/wolfSSL/wolfssl/archive/refs/tags/v4.8.1-stable.tar.gz -O wolfssl.tgz
tar xf wolfssl.tgz
cd wolfssl-4.8.1-stable
autoreconf -i -f
exec_cmd ./configure --program-prefix="" --program-suffix="" --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --sysconfdir=/etc --datadir=/usr/share --localstatedir=/var --mandir=/usr/man --infodir=/usr/info --disable-nls --enable-reproducible-build --enable-lighty --enable-opensslall --enable-opensslextra --enable-sni --enable-stunnel --disable-crypttests --disable-examples --disable-jobserver --enable-ipv6 --enable-aesccm --enable-certgen --enable-chacha --enable-poly1305 --enable-dh --enable-arc4 --enable-tlsv10 --enable-tls13 --enable-session-ticket --disable-dtls --disable-curve25519 --disable-afalg --enable-devcrypto=no --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 --enable-wpas --enable-fortress --enable-fastmath
exec_cmd make
exec_cmd make install
cd ${CUR}
}
function generate_release()
{
cd build
cpack
cd ..
}
function install_libusermngr()
{
# clone and compile libusermngr
rm -rf /opt/dev/usermngr
exec_cmd git clone -b devel https://dev.iopsys.eu/iopsys/usermngr.git /opt/dev/usermngr
exec_cmd git clone -b devel https://dev.iopsys.eu/bbf/usermngr.git /opt/dev/usermngr
echo "Compiling libusermngr"
make clean -C /opt/dev/usermngr/src/
make -C /opt/dev/usermngr/src/
exec_cmd_verbose make clean -C /opt/dev/usermngr/src/
exec_cmd_verbose make -C /opt/dev/usermngr/src/
echo "installing libusermngr"
cp -f /opt/dev/usermngr/src/libusermngr.so /usr/lib/bbfdm
@ -92,44 +64,57 @@ function install_libbbf()
mkdir -p build
cd build
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS" -DBBF_TR181=ON -DBBF_TR104=ON -DBBF_TR143=ON -DWITH_OPENSSL=ON -DBBF_JSON_PLUGIN=ON -DBBF_DOTSO_PLUGIN=ON -DBBF_VENDOR_EXTENSION=ON -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DCMAKE_INSTALL_PREFIX=/
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS" -DBBFDMD_ENABLED=ON -DBBF_TR181=ON -DBBF_TR104=ON -DBBF_TR143=ON -DWITH_OPENSSL=ON -DBBF_JSON_PLUGIN=ON -DBBF_DOTSO_PLUGIN=ON -DBBF_VENDOR_EXTENSION=ON -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
exec_cmd_verbose make
echo "installing libbbf"
exec_cmd_verbose make install
ln -sf /usr/share/bbfdm/bbf.diag /usr/libexec/rpcd/bbf.diag
cd ..
echo "installing libusermngr"
install_libusermngr
}
function install_libbbf_test()
{
# compile and install libbbf_test
echo "Compiling libbbf_test"
make clean -C test/bbf_test/
make -C test/bbf_test/
exec_cmd_verbose make clean -C test/bbf_test/
exec_cmd_verbose make -C test/bbf_test/
echo "installing libbbf_test"
cp -f test/bbf_test/libbbf_test.so /usr/lib/bbfdm
ldconfig
}
function install_libperiodicstats()
{
# clone and compile libperiodicstats
rm -rf /opt/dev/periodicstats
exec_cmd git clone -b devel https://dev.iopsys.eu/iopsys/periodicstats.git /opt/dev/periodicstats
exec_cmd git clone -b devel https://dev.iopsys.eu/bbf/periodicstats.git /opt/dev/periodicstats
echo "Compiling libperiodicstats"
make clean -C /opt/dev/periodicstats/
make -C /opt/dev/periodicstats/
exec_cmd_verbose make clean -C /opt/dev/periodicstats/
exec_cmd_verbose make -C /opt/dev/periodicstats/
echo "installing libperiodicstats"
cp -f /opt/dev/periodicstats/bbf_plugin/libperiodicstats.so /usr/lib/bbfdm
}
function install_libcwmpdm()
{
# clone and compile libcwmpdm
rm -rf /opt/dev/icwmp
exec_cmd git clone -b ticket_8966 --depth 1 https://dev.iopsys.eu/bbf/icwmp.git /opt/dev/icwmp
echo "Compiling libcwmpdm"
cd /opt/dev/icwmp
cmake -DWITH_OPENSSL=ON -DCMAKE_INSTALL_PREFIX=/
exec_cmd_verbose make
echo "installing libcwmpdm"
cp -f /opt/dev/icwmp/libcwmpdm.so /usr/lib/bbfdm
cd /builds/bbf/bbfdm
}
function error_on_zero()
{
ret=$1
@ -140,3 +125,9 @@ function error_on_zero()
}
function generate_report()
{
exec_cmd tap-junit --name "${1}" --input "${2}" --output report
sync
}

View file

@ -42,7 +42,7 @@ echo "Validate X_IOPSYS_EU_URLFilter JSON Plugin"
check_ret $?
echo "Validate CWMPManagementServer JSON Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/cwmp_management_server.json
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/CWMPManagementServer.json
check_ret $?
echo "Validate TR-181 JSON Plugin after generating from XML"

View file

@ -4,20 +4,12 @@ echo "Unit Tests"
pwd
. ./gitlab-ci/shared.sh
echo "Starting supervisor in current directory"
echo "Starting supervisor"
supervisorctl shutdown
sleep 1
supervisord -c supervisord.conf
# compile and install libbbf
install_libbbf
#compile and install libbbf_test dynamic extension library
install_libbbf_test
supervisorctl status all
supervisorctl update
supervisord -c /etc/supervisor/supervisord.conf
sleep 3
supervisorctl status all
echo "Running the unit test cases"

View file

@ -1637,7 +1637,7 @@ static char** fill_unique_keys(size_t count, struct json_object *obj)
static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pleaf, int i, int json_version, struct list_head *list)
{
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type(6)*/
struct json_object *type = NULL, *protocols = NULL, *write = NULL, *async = NULL, *version = NULL, *def_value = NULL;
struct json_object *type = NULL, *protocols = NULL, *write = NULL, *async = NULL, *def_value = NULL;
char full_param[512] = {0};
size_t n_proto;
char **in_p = NULL, **out_p = NULL, **ev_arg = NULL, **tmp = NULL;
@ -1776,10 +1776,6 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
pleaf[i].bbfdm_type = BBFDM_BOTH;
} else
pleaf[i].bbfdm_type = BBFDM_BOTH;
//Version
json_object_object_get_ex(jobj, "version", &version);
DM_STRNCPY(pleaf[i].version, version ? json_object_get_string(version) : "", 10);
snprintf(full_param, sizeof(full_param), "%s%s", object, param_ext);
save_json_data(list, full_param, jobj, json_version, (const char**)in_p, (const char**)out_p, (const char**)ev_arg);
@ -1897,10 +1893,6 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, i
pobj[index].checkdep = dm_dynamic_strdup(&json_memhead, json_object_get_string(json_obj));
}
//Version
if (strcmp(key,"version") == 0)
DM_STRNCPY(pobj[index].version, json_object_get_string(json_obj), 10);
if (strcmp(key, "mapping") == 0 &&
((json_object_get_type(json_obj) == json_type_object && json_version == JSON_VERSION_0) ||
(json_object_get_type(json_obj) == json_type_array && json_version == JSON_VERSION_1))) {

View file

@ -12,7 +12,6 @@
#include "dmdynamiclibrary.h"
LIST_HEAD(loaded_library_list);
LIST_HEAD(dynamic_operate_list);
LIST_HEAD(library_memhead);
struct loaded_library
@ -49,28 +48,6 @@ static void free_all_list_open_library(struct list_head *library_list)
}
}
static void add_list_dynamic_operates(struct list_head *operate_list, char *operate_path, void *operate, void *operate_args)
{
struct dynamic_operate *dyn_operate = calloc(1, sizeof(struct dynamic_operate));
list_add_tail(&dyn_operate->list, operate_list);
dyn_operate->operate_path = strdup(operate_path);
dyn_operate->operate = operate;
dyn_operate->operate_args = operate_args;
}
static void free_list_dynamic_operates(struct list_head *operate_list)
{
struct dynamic_operate *dyn_operate;
while (operate_list->next != operate_list) {
dyn_operate = list_entry(operate_list->next, struct dynamic_operate, list);
list_del(&dyn_operate->list);
if (dyn_operate->operate_path) {
free(dyn_operate->operate_path);
}
FREE(dyn_operate);
}
}
static void dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryobj)
{
for (; (entryobj && entryobj->obj); entryobj++) {
@ -102,73 +79,10 @@ void free_library_dynamic_arrays(DMOBJ *dm_entryobj)
DMNODE node = {.current_object = ""};
free_all_list_open_library(&loaded_library_list);
free_list_dynamic_operates(&dynamic_operate_list);
dm_dynamic_cleanmem(&library_memhead);
dm_browse_node_dynamic_object_tree(&node, root);
}
static bool operate_find_root_entry(struct dmctx *ctx, char *in_param, DMOBJ **root_entry)
{
int obj_found = 0;
DMOBJ *root = ctx->dm_entryobj;
DMNODE node = {.current_object = ""};
dm_check_dynamic_obj(ctx, &node, root, in_param, in_param, root_entry, &obj_found);
return (obj_found && *root_entry) ? true : false;
}
static void get_path_without_instance(char *path, char *operate_path, size_t len)
{
char *pch = NULL, *pchr = NULL;
char str[1024] = {0};
unsigned pos = 0;
snprintf(str, sizeof(str), "%s", path);
operate_path[0] = 0;
for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) {
if (DM_STRTOL(pch) == 0 && strcmp(pch, "{i}") != 0)
pos += snprintf(&operate_path[pos], len - pos, "%s%s", pch, (pchr != NULL && *pchr != '\0') ? "." : "");
}
}
static int get_dynamic_operate_args(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct dynamic_operate *dyn_operate = NULL;
operation_args *operate_args = NULL;
char operate_path[1024] = {0};
get_path_without_instance(refparam, operate_path, sizeof(operate_path));
list_for_each_entry(dyn_operate, &dynamic_operate_list, list) {
if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) {
operate_args = (operation_args *)dyn_operate->operate_args;
break;
}
}
*value = (char *)operate_args;
return 0;
}
static int dynamic_operate_leaf(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
struct dynamic_operate *dyn_operate = NULL;
operation operate_func = NULL;
char operate_path[1024] = {0};
get_path_without_instance(refparam, operate_path, sizeof(operate_path));
list_for_each_entry(dyn_operate, &dynamic_operate_list, list) {
if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) {
operate_func = (operation)dyn_operate->operate;
break;
}
}
return operate_func ? operate_func(ctx, refparam, (json_object *)value) : CMD_FAIL;
}
int load_library_dynamic_arrays(struct dmctx *ctx)
{
struct dirent *ent = NULL;
@ -246,61 +160,6 @@ int load_library_dynamic_arrays(struct dmctx *ctx)
}
}
//Dynamic Operate is deprecated now. It will be removed later.
struct dm_map_operate *dynamic_operate = NULL;
*(void **) (&dynamic_operate) = dlsym(handle, "tDynamicOperate");
if (dynamic_operate) {
for (int i = 0; dynamic_operate[i].path; i++) {
if (dynamic_operate[i].operate && dynamic_operate[i].type) {
char parent_path[256] = {'\0'};
char operate_path[256] = {'\0'};
DMOBJ *dm_entryobj = NULL;
char *object_path = replace_str(dynamic_operate[i].path, ".*.", ".");
snprintf(operate_path, sizeof(operate_path), "%s%s", object_path, !strstr(object_path, "()") ? "()" : "");
dmfree(object_path);
char *ret = strrchr(operate_path, '.');
DM_STRNCPY(parent_path, operate_path, ret - operate_path + 2);
bool obj_exists = operate_find_root_entry(ctx, parent_path, &dm_entryobj);
if (obj_exists == false || !dm_entryobj)
continue;
add_list_dynamic_operates(&dynamic_operate_list, operate_path, dynamic_operate[i].operate, &dynamic_operate[i].args);
if (dm_entryobj->dynamicleaf == NULL) {
dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf));
dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
}
operation_args *args = &dynamic_operate[i].args;
DMLEAF *new_leaf = dm_dynamic_calloc(&library_memhead, 2, sizeof(struct dm_leaf_s));
new_leaf[0].parameter = dm_dynamic_strdup(&library_memhead, ret+1);
new_leaf[0].permission = !strcmp(dynamic_operate[i].type, "sync") ? &DMSYNC : &DMASYNC;
new_leaf[0].type = DMT_COMMAND;
new_leaf[0].getvalue = (args->in || args->out) ? get_dynamic_operate_args : NULL;
new_leaf[0].setvalue = dynamic_operate_leaf;
new_leaf[0].bbfdm_type = BBFDM_USP;
if (dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf == NULL) {
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = calloc(2, sizeof(DMLEAF *));
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[0] = new_leaf;
} else {
int idx = get_leaf_idx_dynamic_array(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf);
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = realloc(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf, (idx + 2) * sizeof(DMLEAF *));
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx] = new_leaf;
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx+1] = NULL;
}
}
}
}
add_list_loaded_libraries(&loaded_library_list, handle);
}

View file

@ -31,12 +31,6 @@ extern struct dm_permession_s DMSYNC;
extern struct dm_permession_s DMASYNC;
extern char *DMT_TYPE[];
extern int bbfdatamodel_type;
#ifdef UNDEF
#undef UNDEF
#endif
#define UNDEF -1
#ifndef BBF_MAX_OBJECT_INSTANCES
#define BBF_MAX_OBJECT_INSTANCES (255)
@ -50,10 +44,6 @@ extern int bbfdatamodel_type;
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
#endif
#ifndef BBF_ATTR_UNUSED
#define BBF_ATTR_UNUSED(x) (void)(x)
#endif
#define DM_STRNCPY(DST, SRC, SIZE) \
do { \
strncpy(DST, SRC, SIZE - 1); \
@ -122,25 +112,20 @@ struct dm_permession_s {
char *(*get_permission)(char *refparam, struct dmctx *dmctx, void *data, char *instance);
};
struct dm_notif_s {
char *val;
char *(*get_notif)(char *refparam, struct dmctx *dmctx, void *data, char *instance);
};
typedef struct dm_leaf_s {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version(7)*/
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type(6)*/
char *parameter;
struct dm_permession_s *permission;
int type;
int (*getvalue)(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
int (*setvalue)(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action);
int bbfdm_type;
char version[10];
char version[10]; //To be removed
char *default_value;
} DMLEAF;
typedef struct dm_obj_s {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version(14)*/
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys (13)*/
char *obj;
struct dm_permession_s *permission;
int (*addobj)(char *refparam, struct dmctx *ctx, void *data, char **instance);
@ -154,21 +139,9 @@ typedef struct dm_obj_s {
int (*get_linker)(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker);
int bbfdm_type;
const char **unique_keys;
char version[10];
char version[10]; //To be removed later
} DMOBJ;
struct set_tmp {
struct list_head list;
char *name;
char *value;
};
struct param_fault {
struct list_head list;
char *name;
int fault;
};
struct dm_parameter {
struct list_head list;
char *name;
@ -177,6 +150,12 @@ struct dm_parameter {
char *additional_data;
};
typedef struct dm_map_obj {
char *path;
struct dm_obj_s *root_obj;
struct dm_leaf_s *root_leaf;
} DM_MAP_OBJ;
typedef struct dm_map_vendor {
char *vendor;
struct dm_map_obj *vendor_obj;
@ -187,8 +166,7 @@ typedef struct dm_map_vendor_exclude {
char **vendor_obj;
} DM_MAP_VENDOR_EXCLUDE;
struct dmctx
{
struct dmctx {
bool stop;
bool match;
int (*method_param)(DMPARAM_ARGS);
@ -196,9 +174,6 @@ struct dmctx
int (*checkobj)(DMOBJECT_ARGS);
int (*checkleaf)(DMOBJECT_ARGS);
struct list_head list_parameter;
struct list_head set_list_tmp;
struct list_head list_fault_param;
struct list_head list_json_parameter;
DMOBJ *dm_entryobj;
DM_MAP_VENDOR *dm_vendor_extension[2];
DM_MAP_VENDOR_EXCLUDE *dm_vendor_extension_exclude;
@ -211,10 +186,10 @@ struct dmctx
char *addobj_instance;
char *linker;
char *linker_param;
char *dm_version;
unsigned int alias_register;
unsigned int nbrof_instance;
unsigned int instance_mode;
unsigned int dm_type;
unsigned char inparam_isparam;
unsigned char findparam;
char *inst_buf[16];
@ -238,12 +213,6 @@ typedef struct dmnode {
int num_of_entries;
} DMNODE;
typedef struct dm_map_obj {
char *path;
struct dm_obj_s *root_obj;
struct dm_leaf_s *root_leaf;
} DM_MAP_OBJ;
enum operate_ret_status {
CMD_SUCCESS,
CMD_INVALID_ARGUMENTS,
@ -252,12 +221,6 @@ enum operate_ret_status {
__STATUS_MAX,
};
enum deprecated_operate_ret_status {
SUCCESS,
UBUS_INVALID_ARGUMENTS,
FAIL,
};
typedef struct {
const char **in;
const char **out;
@ -267,17 +230,6 @@ typedef struct {
const char **param;
} event_args;
typedef enum operate_ret_status opr_ret_t;
typedef opr_ret_t (*operation) (struct dmctx *dmctx, char *p, json_object *input);
typedef struct dm_map_operate {
char *path;
operation operate;
char *type; // sync or async
operation_args args;
} DM_MAP_OPERATE __attribute__ ((deprecated));
enum set_value_action {
VALUECHECK,
VALUESET
@ -295,17 +247,14 @@ enum browse_type_enum {
};
enum {
CMD_GET_VALUE,
CMD_GET_NAME,
CMD_SET_VALUE,
CMD_ADD_OBJECT,
CMD_DEL_OBJECT,
CMD_USP_OPERATE,
CMD_USP_LIST_OPERATE,
CMD_USP_LIST_EVENT,
CMD_GET_SCHEMA,
CMD_GET_INSTANCES,
CMD_EXTERNAL_COMMAND
BBF_GET_VALUE,
BBF_SCHEMA,
BBF_INSTANCES,
BBF_GET_NAME,
BBF_SET_VALUE,
BBF_ADD_OBJECT,
BBF_DEL_OBJECT,
BBF_OPERATE,
};
enum usp_fault_code_enum {
@ -386,11 +335,6 @@ enum fault_code_enum {
__FAULT_MAX
};
enum {
INSTANCE_UPDATE_NUMBER,
INSTANCE_UPDATE_ALIAS
};
enum instance_mode {
INSTANCE_MODE_NUMBER,
INSTANCE_MODE_ALIAS
@ -416,14 +360,6 @@ enum dmt_type_enum {
DMT_EVENT,
};
enum amd_version_enum {
AMD_1 = 1,
AMD_2,
AMD_3,
AMD_4,
AMD_5,
};
enum bbfdm_type_enum {
BBFDM_BOTH,
BBFDM_CWMP,

View file

@ -49,8 +49,6 @@ static int get_linker_value_check_param(DMPARAM_ARGS);
static int mobj_get_supported_dm(DMOBJECT_ARGS);
static int mparam_get_supported_dm(DMPARAM_ARGS);
int bbfdatamodel_type = BBFDM_BOTH;
char *DMT_TYPE[] = {
[DMT_STRING] = "xsd:string",
[DMT_UNINT] = "xsd:unsignedInt",
@ -341,38 +339,9 @@ static int plugin_leaf_wildcard_nextlevel_match(DMOBJECT_ARGS)
return FAULT_9005;
}
static int bbfdatamodel_matches(const enum bbfdm_type_enum type)
static int bbfdatamodel_matches(unsigned int dm_type, const enum bbfdm_type_enum type)
{
return (bbfdatamodel_type == BBFDM_BOTH || type == BBFDM_BOTH || bbfdatamodel_type == type) && type != BBFDM_NONE;
}
static bool check_version(const char *obj_version, struct dmctx *ctx)
{
char *config_version = ctx->dm_version;
int config_major = 0, config_minor = 0;
int obj_major = 0, obj_minor = 0;
if (!config_version || !obj_version)
return true;
if (*config_version) {
config_major = DM_STRTOL(config_version);
char *temp = DM_STRCHR(config_version, '.');
if (temp)
config_minor = DM_STRTOL(temp + 1);
}
if (*obj_version) {
obj_major = DM_STRTOL(obj_version);
char *temp = DM_STRCHR(obj_version, '.');
if (temp)
obj_minor = DM_STRTOL(temp + 1);
}
if (obj_major > config_major || obj_minor > config_minor)
return false;
return true;
return (dm_type == BBFDM_BOTH || type == BBFDM_BOTH || dm_type == type) && type != BBFDM_NONE;
}
static bool check_dependency(const char *conf_obj)
@ -427,10 +396,7 @@ static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf
for (; (leaf && leaf->parameter); leaf++) {
if (!bbfdatamodel_matches(leaf->bbfdm_type))
continue;
if (!check_version(leaf->version, dmctx))
if (!bbfdatamodel_matches(dmctx->dm_type, leaf->bbfdm_type))
continue;
if (!dmctx->isinfo) {
@ -453,10 +419,7 @@ static int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf
DMLEAF *jleaf = next_dyn_array->nextleaf[j];
for (; (jleaf && jleaf->parameter); jleaf++) {
if (!bbfdatamodel_matches(jleaf->bbfdm_type))
continue;
if (!check_version(jleaf->version, dmctx))
if (!bbfdatamodel_matches(dmctx->dm_type, jleaf->bbfdm_type))
continue;
if (!dmctx->isinfo) {
@ -489,15 +452,12 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent
node.prev_data = data;
node.prev_instance = instance;
if (!bbfdatamodel_matches(entryobj->bbfdm_type))
if (!bbfdatamodel_matches(dmctx->dm_type, entryobj->bbfdm_type))
return;
if (entryobj->checkdep && (check_dependency(entryobj->checkdep) == false))
return;
if (!check_version(entryobj->version, dmctx))
return;
if (entryobj->browseinstobj && dmctx->isgetschema)
dmasprintf(&(node.current_object), "%s%s.{i}.", parent_obj, entryobj->obj);
else
@ -723,7 +683,9 @@ bool find_root_entry(struct dmctx *ctx, char *in_param, DMOBJ **root_entry)
DMNODE node = {.current_object = ""};
char *obj_path = replace_str(in_param, ".{i}.", ".");
char *old_in_param = ctx->in_param;
dm_check_dynamic_obj(ctx, &node, root, obj_path, obj_path, root_entry, &obj_found);
ctx->in_param = old_in_param;
dmfree(obj_path);
return (obj_found && *root_entry) ? true : false;
@ -883,33 +845,6 @@ char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node,
return instance;
}
__attribute__ ((deprecated)) char *handle_update_instance(int instance_ranck, struct dmctx *ctx, char **max_inst, char * (*up_instance)(int action, char **last_inst, char **max_inst, void *argv[]), int argc, ...)
{
va_list arg;
char *instance, *last_inst = NULL;
int i = 0;
unsigned int action, pos = instance_ranck - 1;
void *argv[argc+1];
va_start(arg, argc);
for (i = 0; i < argc; i++) {
argv[i] = va_arg(arg, void*);
}
argv[argc] = NULL;
va_end(arg);
if (pos < ctx->nbrof_instance)
action = (ctx->alias_register & (1 << pos)) ? INSTANCE_UPDATE_ALIAS : INSTANCE_UPDATE_NUMBER;
else
action = (ctx->instance_mode == INSTANCE_MODE_ALIAS) ? INSTANCE_UPDATE_ALIAS : INSTANCE_UPDATE_NUMBER;
instance = up_instance(action, &last_inst, max_inst, argv);
if (last_inst)
ctx->inst_buf[pos] = dmstrdup(last_inst);
return instance;
}
char *update_instance(char *max_inst, int argc, ...)
{
va_list arg;
@ -990,95 +925,6 @@ char *update_instance_alias(int action, char **last_inst, char **max_inst, void
return instance;
}
__attribute__ ((deprecated)) char *update_instance_without_section(int action, char **last_inst, char **max_inst, void *argv[])
{
char *instance, buf[64] = {0};
int instnbr = (int)(long)argv[0];
snprintf(buf, sizeof(buf), "%d", instnbr);
instance = dmstrdup(buf);
*last_inst = instance;
if (action == INSTANCE_MODE_ALIAS) {
snprintf(buf, sizeof(buf), "[cpe-%d]", instnbr);
instance = dmstrdup(buf);
}
return instance;
}
__attribute__ ((deprecated)) char *get_last_instance_bbfdm(char *package, char *section, char *opt_inst)
{
struct uci_section *s;
char *inst = NULL, *last_inst = NULL;
uci_path_foreach_sections(bbfdm, package, section, s) {
inst = update_instance(last_inst, 2, s, opt_inst);
if(last_inst)
dmfree(last_inst);
last_inst = dmstrdup(inst);
}
return inst;
}
__attribute__ ((deprecated)) char *get_last_instance(char *package, char *section, char *opt_inst)
{
struct uci_section *s;
char *inst = NULL, *last_inst = NULL;
if (strcmp(package, DMMAP) == 0) {
uci_path_foreach_sections(bbfdm, "dmmap", section, s) {
inst = update_instance(last_inst, 2, s, opt_inst);
if(last_inst)
dmfree(last_inst);
last_inst = dmstrdup(inst);
}
} else {
uci_foreach_sections(package, section, s) {
inst = update_instance(inst, 2, s, opt_inst);
}
}
return inst;
}
__attribute__ ((deprecated)) char *get_last_instance_lev2_bbfdm_dmmap_opt(char *dmmap_package, char *section, char *opt_inst, char *opt_check, char *value_check)
{
struct uci_section *s;
char *instance = NULL, *last_inst = NULL;
struct browse_args browse_args = {0};
browse_args.option = opt_check;
browse_args.value = value_check;
uci_path_foreach_option_eq(bbfdm, dmmap_package, section, opt_check, value_check, s) {
instance = update_instance(last_inst, 5, s, opt_inst, 0, check_browse_section, (void *)&browse_args);
if(last_inst)
dmfree(last_inst);
last_inst = dmstrdup(instance);
}
return instance;
}
__attribute__ ((deprecated)) char *get_last_instance_lev2_bbfdm(char *package, char *section, char* dmmap_package, char *opt_inst, char *opt_check, char *value_check)
{
struct uci_section *s = NULL, *dmmap_section = NULL;
char *instance = NULL, *last_inst = NULL;
uci_foreach_option_cont(package, section, opt_check, value_check, s) {
get_dmmap_section_of_config_section(dmmap_package, section, section_name(s), &dmmap_section);
if (dmmap_section == NULL) {
dmuci_add_section_bbfdm(dmmap_package, section, &dmmap_section);
dmuci_set_value_by_section(dmmap_section, "section_name", section_name(s));
}
instance = update_instance(last_inst, 2, dmmap_section, opt_inst);
if(last_inst)
dmfree(last_inst);
last_inst = dmstrdup(instance);
}
return instance;
}
int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "";
@ -1113,59 +959,6 @@ void free_all_list_parameter(struct dmctx *ctx)
}
}
static void add_set_list_tmp(struct dmctx *ctx, char *param, char *value)
{
struct set_tmp *set_tmp;
set_tmp = dmcalloc(1, sizeof(struct set_tmp));
list_add_tail(&set_tmp->list, &ctx->set_list_tmp);
set_tmp->name = dmstrdup(param);
set_tmp->value = value ? dmstrdup(value) : NULL;
}
static void del_set_list_tmp(struct set_tmp *set_tmp)
{
list_del(&set_tmp->list);
dmfree(set_tmp->name);
dmfree(set_tmp->value);
dmfree(set_tmp);
}
void free_all_set_list_tmp(struct dmctx *ctx)
{
struct set_tmp *set_tmp = NULL;
while (ctx->set_list_tmp.next != &ctx->set_list_tmp) {
set_tmp = list_entry(ctx->set_list_tmp.next, struct set_tmp, list);
del_set_list_tmp(set_tmp);
}
}
void add_list_fault_param(struct dmctx *ctx, char *param, int fault)
{
struct param_fault *param_fault;
if (param == NULL) param = "";
param_fault = dmcalloc(1, sizeof(struct param_fault));
list_add_tail(&param_fault->list, &ctx->list_fault_param);
param_fault->name = dmstrdup(param);
param_fault->fault = fault;
}
void bbf_api_del_list_fault_param(struct param_fault *param_fault)
{
list_del(&param_fault->list);
dmfree(param_fault->name);
dmfree(param_fault);
}
void free_all_list_fault_param(struct dmctx *ctx)
{
struct param_fault *param_fault = NULL;
while (ctx->list_fault_param.next != &ctx->list_fault_param) {
param_fault = list_entry(ctx->list_fault_param.next, struct param_fault, list);
bbf_api_del_list_fault_param(param_fault);
}
}
int string_to_bool(char *v, bool *b)
{
if (v[0] == '1' && v[1] == '\0') {
@ -1667,6 +1460,10 @@ int dm_entry_get_supported_dm(struct dmctx *ctx)
{
DMOBJ *root = ctx->dm_entryobj;
DMNODE node = {.current_object = ""};
size_t plen = DM_STRLEN(ctx->in_param);
if (plen == 0 || ctx->in_param[plen - 1] != '.')
return FAULT_9005;
ctx->inparam_isparam = 0;
ctx->isgetschema = 1;
@ -1898,15 +1695,9 @@ static int mparam_set_value(DMPARAM_ARGS)
if (perm[0] == '0' || !leaf->setvalue)
return FAULT_9008;
int fault = (leaf->setvalue)(refparam, dmctx, data, instance, dmctx->in_value, VALUECHECK);
if (fault)
return fault;
add_set_list_tmp(dmctx, dmctx->in_param, dmctx->in_value);
return (leaf->setvalue)(refparam, dmctx, data, instance, dmctx->in_value, VALUECHECK);
} else if (dmctx->setaction == VALUESET) {
int fault = (leaf->setvalue)(refparam, dmctx, data, instance, dmctx->in_value, VALUESET);
if (fault)
return fault;
return (leaf->setvalue)(refparam, dmctx, data, instance, dmctx->in_value, VALUESET);
}
return 0;
}

View file

@ -27,18 +27,12 @@
#include "dmmem.h"
#include "dmapi.h"
#define DEFAULT_DMVERSION "2.16"
int get_number_of_entries(struct dmctx *ctx, void *data, char *instance, int (*browseinstobj)(struct dmctx *ctx, struct dmnode *node, void *data, char *instance));
char *handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct uci_section *s, char *inst_opt, char *alias_opt);
char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node, int inst_nbr);
int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
void add_list_parameter(struct dmctx *ctx, char *param_name, char *param_data, char *param_type, char *additional_data);
void free_all_list_parameter(struct dmctx *ctx);
void free_all_set_list_tmp(struct dmctx *ctx);
void add_list_fault_param(struct dmctx *ctx, char *param, int fault);
void bbf_api_del_list_fault_param(struct param_fault *param_fault);
void free_all_list_fault_param(struct dmctx *ctx);
int string_to_bool(char *v, bool *b);
void dmentry_instance_lookup_inparam(struct dmctx *ctx);
int dm_entry_get_value(struct dmctx *dmctx);
@ -65,12 +59,6 @@ void free_dm_browse_node_dynamic_object_tree(DMNODE *parent_node, DMOBJ *entryob
char *update_instance_alias(int action, char **last_inst, char **max_inst, void *argv[]);
char *update_instance(char *max_inst, int argc, ...);
__attribute__ ((deprecated)) char *update_instance_without_section(int action, char **last_inst, char **max_inst, void *argv[]);
__attribute__ ((deprecated)) char *get_last_instance(char *package, char *section, char *opt_inst);
__attribute__ ((deprecated)) char *get_last_instance_bbfdm(char *package, char *section, char *opt_inst);
__attribute__ ((deprecated)) char *get_last_instance_lev2_bbfdm_dmmap_opt(char* dmmap_package, char *section, char *opt_inst, char *opt_check, char *value_check);
__attribute__ ((deprecated)) char *get_last_instance_lev2_bbfdm(char *package, char *section, char* dmmap_package, char *opt_inst, char *opt_check, char *value_check);
__attribute__ ((deprecated)) char *handle_update_instance(int instance_ranck, struct dmctx *ctx, char **max_inst, char * (*up_instance)(int action, char **last_inst, char **max_inst, void *argv[]), int argc, ...);
static inline int DM_LINK_INST_OBJ(struct dmctx *dmctx, DMNODE *parent_node, void *data, char *instance)
{

View file

@ -633,81 +633,6 @@ char *check_create_dmmap_package(const char *dmmap_package)
return path;
}
__attribute__ ((deprecated)) int is_section_unnamed(char *section_name)
{
int i;
if (section_name == NULL)
return 0;
if (strlen(section_name) != 9)
return 0;
if(strstr(section_name, "cfg") != section_name)
return 0;
for (i = 3; i < 9; i++) {
if (!isxdigit(section_name[i]))
return 0;
}
return 1;
}
static void add_dmmap_list_section(struct list_head *dup_list, char* section_name, char* instance)
{
struct dmmap_sect *dmsect;
dmsect = dmcalloc(1, sizeof(struct dmmap_sect));
list_add_tail(&dmsect->list, dup_list);
dmasprintf(&dmsect->section_name, "%s", section_name);
dmasprintf(&dmsect->instance, "%s", instance);
}
__attribute__ ((deprecated)) void delete_sections_save_next_sections(char* dmmap_package, char *section_type, char *instancename, char *section_name, int instance, struct list_head *dup_list)
{
struct uci_section *s, *stmp;
char *v = NULL, *lsectname = NULL, *tmp = NULL;
int inst;
dmasprintf(&lsectname, "%s", section_name);
uci_path_foreach_sections(bbfdm, dmmap_package, section_type, s) {
dmuci_get_value_by_section_string(s, instancename, &v);
inst = DM_STRTOL(v);
if (inst > instance){
dmuci_get_value_by_section_string(s, "section_name", &tmp);
add_dmmap_list_section(dup_list, lsectname, v);
dmfree(lsectname);
lsectname = NULL;
dmasprintf(&lsectname, "%s", tmp);
dmfree(tmp);
tmp = NULL;
}
}
if(lsectname != NULL) dmfree(lsectname);
uci_path_foreach_sections_safe(bbfdm, dmmap_package, section_type, stmp, s) {
dmuci_get_value_by_section_string(s, instancename, &v);
inst = DM_STRTOL(v);
if (inst >= instance)
dmuci_delete_by_section_unnamed_bbfdm(s, NULL, NULL);
}
}
__attribute__ ((deprecated)) void update_dmmap_sections(struct list_head *dup_list, char *instancename, char* dmmap_package, char *section_type)
{
struct uci_section *dm_sect = NULL;
struct dmmap_sect *p = NULL;
list_for_each_entry(p, dup_list, list) {
dmuci_add_section_bbfdm(dmmap_package, section_type, &dm_sect);
dmuci_set_value_by_section(dm_sect, "section_name", p->section_name);
dmuci_set_value_by_section(dm_sect, instancename, p->instance);
}
}
struct uci_section *is_dmmap_section_exist(char* package, char* section)
{
struct uci_section *s;

View file

@ -226,9 +226,6 @@ int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, cha
int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value);
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
char *check_create_dmmap_package(const char *dmmap_package);
__attribute__ ((deprecated)) int is_section_unnamed(char *section_name);
__attribute__ ((deprecated)) void delete_sections_save_next_sections(char* dmmap_package, char *section_type, char *instancename, char *section_name, int instance, struct list_head *dup_list);
__attribute__ ((deprecated)) void update_dmmap_sections(struct list_head *dup_list, char *instancename, char* dmmap_package, char *section_type);
unsigned char isdigit_str(char *str);
bool special_char(char c);
bool special_char_exits(const char *str);

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 iopsys Software Solutions AB
* 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
@ -8,48 +8,77 @@
* Author MOHAMED Kallel <mohamed.kallel@pivasoftware.com>
* Author Imen Bhiri <imen.bhiri@pivasoftware.com>
* Author Feten Besbes <feten.besbes@pivasoftware.com>
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Author Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include "dmapi.h"
#include "dmuci.h"
#include "dmbbf.h"
#include "dmmem.h"
#include "dmubus.h"
#include "dmentry.h"
#include "dm_plugin/dmdynamicjson.h"
#include "dm_plugin/dmdynamiclibrary.h"
#include "dm_plugin/dmdynamicvendor.h"
LIST_HEAD(head_package_change);
LIST_HEAD(main_memhead);
#ifdef BBFDM_ENABLE_JSON_PLUGIN
#include "dm_plugin/dmdynamicjson.h"
static char json_hash[64] = {0};
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
#include "dm_plugin/dmdynamiclibrary.h"
static char library_hash[64] = {0};
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
#ifdef BBF_VENDOR_EXTENSION
#include "dm_plugin/dmdynamicvendor.h"
static bool first_boot = false;
#endif
static void load_dynamic_arrays(struct dmctx *ctx);
LIST_HEAD(head_package_change);
LIST_HEAD(global_memhead);
int dm_debug_browse_path(char *buff, size_t len)
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude)
{
if (!buff)
return -1;
// initialise with default value
buff[0] = '\0';
return dm_browse_last_access_path(buff, len);
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();
}
int usp_fault_map(int fault)
void bbf_ctx_clean(struct dmctx *ctx)
{
free_all_list_parameter(ctx);
dm_uci_exit();
dmubus_free();
dmcleanmem();
}
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude)
{
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)
{
free_all_list_parameter(ctx);
}
int bbf_fault_map(unsigned int dm_type, int fault)
{
int out_fault;
if (bbfdatamodel_type == BBFDM_USP) {
if (dm_type == BBFDM_USP) {
switch(fault) {
case FAULT_9000:
out_fault = USP_FAULT_MESSAGE_NOT_UNDERSTOOD;
@ -85,7 +114,7 @@ int usp_fault_map(int fault)
else
out_fault = fault;
}
} else if (bbfdatamodel_type == BBFDM_CWMP) {
} else if (dm_type == BBFDM_CWMP) {
switch(fault) {
case USP_FAULT_GENERAL_FAILURE:
out_fault = FAULT_9002;
@ -127,357 +156,6 @@ int usp_fault_map(int fault)
return out_fault;
}
static int dm_ctx_init_custom(struct dmctx *ctx, unsigned int instance_mode, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, int custom)
{
if (custom == CTX_INIT_ALL)
bbf_uci_init();
INIT_LIST_HEAD(&ctx->list_parameter);
INIT_LIST_HEAD(&ctx->set_list_tmp);
INIT_LIST_HEAD(&ctx->list_fault_param);
ctx->instance_mode = instance_mode;
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;
ctx->dm_version = DEFAULT_DMVERSION;
return 0;
}
static int dm_ctx_clean_custom(struct dmctx *ctx, int custom)
{
free_all_list_parameter(ctx);
free_all_set_list_tmp(ctx);
free_all_list_fault_param(ctx);
DMFREE(ctx->addobj_instance);
if (custom == CTX_INIT_ALL) {
bbf_uci_exit();
dmcleanmem();
}
return 0;
}
void dm_config_ubus(struct ubus_context *ctx)
{
dmubus_configure(ctx);
}
int dm_ctx_init_entry(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode)
{
return dm_ctx_init_custom(ctx, instance_mode, tEntryObj, tVendorExtension, tVendorExtensionExclude, CTX_INIT_ALL);
}
int dm_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode)
{
dmubus_clean_endlife_entries();
return dm_ctx_init_custom(ctx, instance_mode, tEntryObj, tVendorExtension, tVendorExtensionExclude, CTX_INIT_ALL);
}
int dm_ctx_clean(struct dmctx *ctx)
{
dmubus_update_cached_entries();
return dm_ctx_clean_custom(ctx, CTX_INIT_ALL);
}
int dm_ctx_init_cache(int time)
{
dmubus_set_caching_time(time);
return 0;
}
int dm_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode)
{
return dm_ctx_init_custom(ctx, instance_mode, tEntryObj, tVendorExtension, tVendorExtensionExclude, CTX_INIT_SUB);
}
int dm_ctx_clean_sub(struct dmctx *ctx)
{
return dm_ctx_clean_custom(ctx, CTX_INIT_SUB);
}
int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type)
{
int fault = 0;
int len = DM_STRLEN(path);
// Load dynamic objects and parameters
load_dynamic_arrays(ctx);
if (len == 0) {
path = "";
} else {
if (path[len - 1] != '.')
return usp_fault_map(USP_FAULT_INVALID_PATH);
}
ctx->in_param = path;
dmentry_instance_lookup_inparam(ctx);
ctx->stop = false;
ctx->nextlevel = first_level;
switch(schema_type) {
case ALL_SCHEMA:
ctx->isinfo = 1;
ctx->isevent = 1;
ctx->iscommand = 1;
break;
case PARAM_ONLY:
ctx->isinfo = 1;
break;
case EVENT_ONLY:
ctx->isevent = 1;
break;
case COMMAND_ONLY:
ctx->iscommand = 1;
break;
}
fault = dm_entry_get_supported_dm(ctx);
return usp_fault_map(fault);
}
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2)
{
int fault = 0;
#ifdef DM_DEBUG
time_t s; // Seconds
long ms; // Milliseconds
struct timespec tstart, tend;
clock_gettime(CLOCK_REALTIME, &tstart); // START TIME
#endif //DM_DEBUG
// Load dynamic objects and parameters
load_dynamic_arrays(ctx);
if (!inparam) inparam = "";
ctx->in_param = inparam;
ctx->iswildcard = DM_STRCHR(inparam, '*') ? 1 : 0;
dmentry_instance_lookup_inparam(ctx);
ctx->stop = false;
switch(cmd) {
case CMD_GET_VALUE:
fault = dm_entry_get_value(ctx);
break;
case CMD_GET_NAME:
if (arg1 && string_to_bool(arg1, &ctx->nextlevel) == 0)
fault = dm_entry_get_name(ctx);
else
fault = FAULT_9003;
break;
case CMD_SET_VALUE:
ctx->in_value = arg1 ? arg1 : "";
ctx->setaction = VALUECHECK;
fault = dm_entry_set_value(ctx);
if (fault)
add_list_fault_param(ctx, ctx->in_param, usp_fault_map(fault));
break;
case CMD_ADD_OBJECT:
fault = dm_entry_add_object(ctx);
if (!fault)
dmuci_change_packages(&head_package_change);
break;
case CMD_DEL_OBJECT:
fault = dm_entry_delete_object(ctx);
if (!fault)
dmuci_change_packages(&head_package_change);
break;
case CMD_USP_OPERATE:
ctx->in_value = arg1 ? arg1 : "";
fault = dm_entry_operate(ctx);
break;
case CMD_USP_LIST_OPERATE:
fault = dm_entry_list_operates(ctx);
break;
case CMD_USP_LIST_EVENT:
fault = dm_entry_list_events(ctx);
break;
case CMD_GET_SCHEMA:
fault = dm_entry_get_schema(ctx);
break;
case CMD_GET_INSTANCES:
if (!arg1 || string_to_bool(arg1, &ctx->nextlevel) == 0)
fault = dm_entry_get_instances(ctx);
else
fault = FAULT_9003;
break;
}
dmuci_save();
#ifdef DM_DEBUG
clock_gettime(CLOCK_REALTIME, &tend); // END TIME
s = tend.tv_sec - tstart.tv_sec;
ms = (tend.tv_nsec - tstart.tv_nsec) / 1.0e6; // Convert nanoseconds to milliseconds
if (ms < 0) {
ms = 1000 + ms;
s--;
}
TRACE("-----------------------------\n");
TRACE("CMD: %d : PATH: %s :: End: %ld s : %ld ms\n", cmd, inparam, (long)s, ms);
TRACE("-----------------------------\n");
#endif //DM_DEBUG
return usp_fault_map(fault);
}
int dm_entry_apply(struct dmctx *ctx, int cmd)
{
struct set_tmp *n = NULL, *p = NULL;
int fault = 0;
bool set_success = false;
switch(cmd) {
case CMD_SET_VALUE:
ctx->setaction = VALUESET;
set_success = false;
list_for_each_entry_safe(n, p, &ctx->set_list_tmp, list) {
ctx->in_param = n->name;
ctx->in_value = n->value ? n->value : "";
ctx->stop = false;
fault = dm_entry_set_value(ctx);
if (fault) {
add_list_fault_param(ctx, ctx->in_param, usp_fault_map(fault));
break;
}
set_success = true;
}
if (!fault && set_success == true) {
dmuci_change_packages(&head_package_change);
dmuci_save();
}
break;
}
free_all_set_list_tmp(ctx);
return usp_fault_map(fault);
}
int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, char **value)
{
struct dmctx dmctx = {0};
*value = "";
if (!param || !linker || *linker == 0)
return 0;
dm_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude, ctx->instance_mode);
dmctx.in_param = param;
dmctx.linker = linker;
dm_entry_get_linker(&dmctx);
*value = dmctx.linker_param;
dm_ctx_clean_sub(&dmctx);
return 0;
}
int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value)
{
struct dmctx dmctx = {0};
char linker[256] = {0};
*value = NULL;
if (!param || param[0] == '\0')
return 0;
snprintf(linker, sizeof(linker), "%s%c", param, (param[DM_STRLEN(param) - 1] != '.') ? '.' : '\0');
dm_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude, ctx->instance_mode);
dmctx.in_param = linker;
dm_entry_get_linker_value(&dmctx);
*value = dmctx.linker;
dm_ctx_clean_sub(&dmctx);
return 0;
}
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[])
{
if (!value || !objects)
return -1;
if (*value == '\0')
return 0;
for (; *objects; objects++) {
if (match(value, *objects)) {
char *linker = NULL;
adm_entry_get_linker_value(ctx, value, &linker);
if (linker && *linker)
return 0;
}
}
return -1;
}
int dm_entry_manage_services(struct blob_buf *bb, bool restart)
{
struct package_change *pc = NULL;
void *arr;
if (!bb)
return 0;
arr = blobmsg_open_array(bb, "updated_services");
list_for_each_entry(pc, &head_package_change, list) {
blobmsg_add_string(bb, NULL, pc->package);
if (restart) {
dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", pc->package, String}}, 1);
} else {
dmuci_commit_package(pc->package);
}
}
blobmsg_close_array(bb, arr);
dmuci_commit_bbfdm();
free_all_list_package_change(&head_package_change);
return 0;
}
int dm_entry_restart_services(void)
{
struct package_change *pc = NULL;
dmuci_commit_bbfdm();
list_for_each_entry(pc, &head_package_change, list) {
dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", pc->package, String}}, 1);
}
free_all_list_package_change(&head_package_change);
return 0;
}
int dm_entry_revert_changes(void)
{
struct package_change *pc = NULL;
dmuci_revert_bbfdm();
list_for_each_entry(pc, &head_package_change, list) {
dmubus_call_set("uci", "revert", UBUS_ARGS{{"config", pc->package, String}}, 1);
}
free_all_list_package_change(&head_package_change);
return 0;
}
#if defined(BBFDM_ENABLE_JSON_PLUGIN) || defined(BBFDM_ENABLE_DOTSO_PLUGIN)
static char* get_folder_path(bool json_path)
{
@ -587,42 +265,211 @@ static void load_dynamic_arrays(struct dmctx *ctx)
#endif
}
static void free_dynamic_arrays(DMOBJ *tEntryObj)
static void free_dynamic_arrays(DMOBJ *dm_entryobj)
{
DMNODE node = {.current_object = ""};
#ifdef BBFDM_ENABLE_JSON_PLUGIN
free_json_dynamic_arrays(tEntryObj);
free_json_dynamic_arrays(dm_entryobj);
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
free_library_dynamic_arrays(tEntryObj);
free_library_dynamic_arrays(dm_entryobj);
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
#ifdef BBF_VENDOR_EXTENSION
free_vendor_dynamic_arrays(tEntryObj);
free_vendor_dynamic_arrays(dm_entryobj);
#endif
free_dm_browse_node_dynamic_object_tree(&node, tEntryObj);
free_dm_browse_node_dynamic_object_tree(&node, dm_entryobj);
}
void bbf_dm_cleanup(DMOBJ *tEntryObj)
int bbf_entry_method(struct dmctx *ctx, int cmd)
{
dmubus_free();
dm_dynamic_cleanmem(&main_memhead);
free_dynamic_arrays(tEntryObj);
int fault = 0;
if (!ctx->dm_entryobj)
return bbf_fault_map(ctx->dm_type, USP_FAULT_INVALID_CONFIGURATION);
if (!ctx->in_param)
return bbf_fault_map(ctx->dm_type, USP_FAULT_INVALID_PATH);
// Load dynamic objects and parameters
load_dynamic_arrays(ctx);
dmentry_instance_lookup_inparam(ctx);
ctx->iswildcard = DM_STRCHR(ctx->in_param, '*') ? 1 : 0;
ctx->stop = false;
switch(cmd) {
case BBF_GET_VALUE:
fault = dm_entry_get_value(ctx);
break;
case BBF_SCHEMA:
fault = dm_entry_get_supported_dm(ctx);
break;
case BBF_INSTANCES:
fault = dm_entry_get_instances(ctx);
break;
case BBF_GET_NAME:
fault = dm_entry_get_name(ctx);
break;
case BBF_SET_VALUE:
ctx->setaction = VALUECHECK;
fault = dm_entry_set_value(ctx);
if (fault)
break;
ctx->setaction = VALUESET;
ctx->stop = false;
fault = dm_entry_set_value(ctx);
if (!fault)
dmuci_change_packages(&head_package_change);
break;
break;
case BBF_ADD_OBJECT:
fault = dm_entry_add_object(ctx);
if (!fault)
dmuci_change_packages(&head_package_change);
break;
case BBF_DEL_OBJECT:
fault = dm_entry_delete_object(ctx);
if (!fault)
dmuci_change_packages(&head_package_change);
break;
case BBF_OPERATE:
fault = dm_entry_operate(ctx);
break;
}
dmuci_save();
return bbf_fault_map(ctx->dm_type, fault);
}
void dm_cleanup_dynamic_entry(DMOBJ *root)
void bbf_global_clean(DMOBJ *dm_entryobj)
{
DMNODE node = {.current_object = ""};
dm_dynamic_cleanmem(&main_memhead);
free_dm_browse_node_dynamic_object_tree(&node, root);
dm_dynamic_cleanmem(&global_memhead);
free_dynamic_arrays(dm_entryobj);
}
int set_bbfdatamodel_type(int bbf_type)
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[])
{
bbfdatamodel_type = bbf_type;
if (!value || !objects)
return -1;
if (*value == '\0')
return 0;
for (; *objects; objects++) {
if (DM_STRNCMP(value, *objects, DM_STRLEN(*objects)) == 0) {
char *linker = NULL;
adm_entry_get_linker_value(ctx, value, &linker);
if (linker && *linker)
return 0;
}
}
return -1;
}
int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, char **value)
{
struct dmctx dmctx = {0};
*value = "";
if (!param || !linker || *linker == 0)
return 0;
bbf_ctx_init_sub(&dmctx, ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude);
dmctx.in_param = param;
dmctx.linker = linker;
dm_entry_get_linker(&dmctx);
*value = dmctx.linker_param;
bbf_ctx_clean_sub(&dmctx);
return 0;
}
int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value)
{
struct dmctx dmctx = {0};
char linker[256] = {0};
*value = NULL;
if (!param || param[0] == '\0')
return 0;
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);
dmctx.in_param = linker;
dm_entry_get_linker_value(&dmctx);
*value = dmctx.linker;
bbf_ctx_clean_sub(&dmctx);
return 0;
}
void bbf_entry_restart_services(struct blob_buf *bb, bool restart_services)
{
struct package_change *pc = NULL;
void *arr = NULL;
if (bb) arr = blobmsg_open_array(bb, "updated_services");
list_for_each_entry(pc, &head_package_change, list) {
if (bb) blobmsg_add_string(bb, NULL, pc->package);
if (restart_services) {
dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", pc->package, String}}, 1);
} else {
dmuci_commit_package(pc->package);
}
}
if (bb) blobmsg_close_array(bb, arr);
dmuci_commit_bbfdm();
free_all_list_package_change(&head_package_change);
}
void bbf_entry_revert_changes(struct blob_buf *bb)
{
struct package_change *pc = NULL;
void *arr = NULL;
if (bb) arr = blobmsg_open_array(bb, "reverted_configs");
list_for_each_entry(pc, &head_package_change, list) {
if (bb) blobmsg_add_string(bb, NULL, pc->package);
dmubus_call_set("uci", "revert", UBUS_ARGS{{"config", pc->package, String}}, 1);
}
if (bb) blobmsg_close_array(bb, arr);
dmuci_revert_bbfdm();
free_all_list_package_change(&head_package_change);
}
int bbf_debug_browse_path(char *buff, size_t len)
{
if (!buff)
return -1;
// initialise with default value
buff[0] = '\0';
return dm_browse_last_access_path(buff, len);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 iopsys Software Solutions AB
* 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
@ -8,47 +8,41 @@
* Author MOHAMED Kallel <mohamed.kallel@pivasoftware.com>
* Author Imen Bhiri <imen.bhiri@pivasoftware.com>
* Author Feten Besbes <feten.besbes@pivasoftware.com>
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Author Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
*/
#ifndef __DMENTRY_H__
#define __DMENTRY_H__
#include "dmcommon.h"
extern struct list_head global_memhead;
extern struct list_head head_package_change;
extern struct list_head main_memhead;
enum ctx_init_enum {
CTX_INIT_ALL,
CTX_INIT_SUB
};
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude);
void bbf_ctx_clean(struct dmctx *ctx);
typedef enum {
ALL_SCHEMA,
PARAM_ONLY,
EVENT_ONLY,
COMMAND_ONLY
} schema_type_t;
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj,
DM_MAP_VENDOR *tVendorExtension[],
DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude);
void bbf_ctx_clean_sub(struct dmctx *ctx);
int bbf_fault_map(unsigned int dm_type, int fault);
int bbf_entry_method(struct dmctx *ctx, int cmd);
void bbf_global_clean(DMOBJ *dm_entryobj);
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, char **value);
int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value);
void bbf_entry_restart_services(struct blob_buf *bb, bool restart_services);
void bbf_entry_revert_changes(struct blob_buf *bb);
int dm_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode);
int dm_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode);
int dm_ctx_init_entry(struct dmctx *ctx, DMOBJ *tEntryObj, DM_MAP_VENDOR *tVendorExtension[], DM_MAP_VENDOR_EXCLUDE *tVendorExtensionExclude, unsigned int instance_mode);
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2);
int dm_entry_apply(struct dmctx *ctx, int cmd);
int dm_entry_restart_services(void);
int dm_entry_manage_services(struct blob_buf *bb, bool restart);
int dm_entry_revert_changes(void);
int usp_fault_map(int fault);
int dm_ctx_clean(struct dmctx *ctx);
int dm_ctx_clean_sub(struct dmctx *ctx);
int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type);
void dm_config_ubus(struct ubus_context *ctx);
int dm_ctx_init_cache(int time);
void bbf_dm_cleanup(DMOBJ *tEntryObj);
/**
* @brief dm_debug_browse_path
* @brief bbf_debug_browse_path
*
* Debug API to get the last datamodel access object by datamodel browse
* function.
@ -62,8 +56,6 @@ void bbf_dm_cleanup(DMOBJ *tEntryObj);
* @note This is debug API, mostly be useful in debugging in last datamodel
* object illegal access.
*/
int dm_debug_browse_path(char *buff, size_t len);
void dm_cleanup_dynamic_entry(DMOBJ *root);
int set_bbfdatamodel_type(int bbf_type);
int bbf_debug_browse_path(char *buff, size_t len);
#endif
#endif //__DMENTRY_H__

View file

@ -11,72 +11,41 @@
#include "dmmem.h"
#ifdef WITH_MEMLEACKSEC
LIST_HEAD(memhead);
inline void *__dmmalloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, size_t size
)
inline void *__dmmalloc(struct list_head *mem_list, size_t size)
{
struct dmmem *m = malloc(sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, mem_list);
#ifdef WITH_MEMTRACK
m->file = (char *)file;
m->func = (char *)func;
m->line = line;
#endif /*WITH_MEMTRACK*/
return (void *)m->mem;
}
inline void *__dmcalloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, int n, size_t size
)
inline void *__dmcalloc(struct list_head *mem_list, int n, size_t size)
{
struct dmmem *m = calloc(n, sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, mem_list);
#ifdef WITH_MEMTRACK
m->file = (char *)file;
m->func = (char *)func;
m->line = line;
#endif /*WITH_MEMTRACK*/
return (void *)m->mem;
}
inline void *__dmrealloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, void *n, size_t size
)
inline void *__dmrealloc(struct list_head *mem_list, void *n, size_t size)
{
struct dmmem *m = NULL;
if (n != NULL) {
m = container_of(n, struct dmmem, mem);
list_del(&m->list);
}
struct dmmem *new_m = realloc(m, sizeof(struct dmmem) + size);
if (new_m == NULL) {
dmfree(m);
return NULL;
} else
} else {
m = new_m;
}
list_add(&m->list, mem_list);
#ifdef WITH_MEMTRACK
m->file = (char *)file;
m->func = (char *)func;
m->line = line;
#endif /*WITH_MEMTRACK*/
return (void *)m->mem;
}
@ -94,46 +63,26 @@ inline void __dmcleanmem(struct list_head *mem_list)
struct dmmem *dmm;
while (mem_list->next != mem_list) {
dmm = list_entry(mem_list->next, struct dmmem, list);
#ifdef WITH_MEMTRACK
fprintf(stderr, "Allocated memory in {%s, %s(), line %d} is not freed\n", dmm->file, dmm->func, dmm->line);
#endif /*WITH_MEMTRACK*/
list_del(&dmm->list);
free(dmm);
}
}
char *__dmstrdup
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, const char *s
)
char *__dmstrdup(struct list_head *mem_list, const char *s)
{
if (s == NULL)
return NULL;
size_t len = strlen(s) + 1;
#ifdef WITH_MEMTRACK
void *new = __dmmalloc(file, func, line, mem_list, len);
#else
void *new = __dmmalloc(mem_list, len);
#endif /*WITH_MEMTRACK*/
if (new == NULL)
return NULL;
return (char *) memcpy(new, s, len);
}
#endif /*WITH_MEMLEACKSEC*/
int __dmasprintf
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, char **s, const char *format, ...
)
int __dmasprintf(struct list_head *mem_list, char **s, const char *format, ...)
{
int size;
char *str = NULL;
@ -146,36 +95,26 @@ struct list_head *mem_list, char **s, const char *format, ...
if (size < 0 || str == NULL)
return -1;
#ifdef WITH_MEMTRACK
*s = __dmstrdup(file, func, line, mem_list, str);
#else
*s = __dmstrdup(mem_list, str);
#endif /*WITH_MEMTRACK*/
free(str);
if (*s == NULL)
return -1;
return 0;
}
int __dmastrcat
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, char **s, char *obj, char *lastname
)
int __dmastrcat(struct list_head *mem_list, char **s, char *obj, char *lastname)
{
char buf[2048];
int olen = strlen(obj);
memcpy(buf, obj, olen);
int llen = strlen(lastname) + 1;
memcpy(buf + olen, lastname, llen);
#ifdef WITH_MEMTRACK
*s = __dmstrdup(file, func, line, mem_list, buf);
#else
*s = __dmstrdup(mem_list, buf);
#endif /*WITH_MEMTRACK*/
if (*s == NULL) return -1;
if (*s == NULL)
return -1;
return 0;
}

View file

@ -21,89 +21,20 @@
extern struct list_head memhead;
void dmfree(void *m);
static inline void dm_empty_func()
{
}
#define WITH_MEMLEACKSEC 1
//#define WITH_MEMTRACK 1
#ifndef WITH_MEMLEACKSEC
#undef WITH_MEMTRACK
#endif
#ifdef WITH_MEMLEACKSEC
struct dmmem {
struct list_head list;
#ifdef WITH_MEMTRACK
char *file;
char *func;
int line;
#endif /*WITH_MEMTRACK*/
char mem[0];
};
void *__dmmalloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, size_t size
);
void *__dmcalloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, int n, size_t size
);
void *__dmrealloc
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, void *n, size_t size
);
char *__dmstrdup
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, const char *s
);
void *__dmmalloc(struct list_head *mem_list, size_t size);
void *__dmcalloc(struct list_head *mem_list, int n, size_t size);
void *__dmrealloc(struct list_head *mem_list, void *n, size_t size);
char *__dmstrdup(struct list_head *mem_list, const char *s);
int __dmasprintf(struct list_head *mem_list, char **s, const char *format, ...);
int __dmastrcat(struct list_head *mem_list, char **s, char *obj, char *lastname);
void __dmcleanmem(struct list_head *mem_list);
#endif /*WITH_MEMLEACKSEC*/
int __dmasprintf
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, char **s, const char *format, ...
);
int __dmastrcat
(
#ifdef WITH_MEMTRACK
const char *file, const char *func, int line,
#endif /*WITH_MEMTRACK*/
struct list_head *mem_list, char **s, char *obj, char *lastname
);
#ifdef WITH_MEMLEACKSEC
#ifdef WITH_MEMTRACK
#define dmmalloc(x) __dmmalloc(__FILE__, __func__, __LINE__, &memhead, x)
#define dmcalloc(n, x) __dmcalloc(__FILE__, __func__, __LINE__, &memhead, n, x)
#define dmrealloc(x, n) __dmrealloc(__FILE__, __func__, __LINE__, &memhead, x, n)
#define dmstrdup(x) __dmstrdup(__FILE__, __func__, __LINE__, &memhead, x)
#define dmasprintf(s, format, ...) __dmasprintf(__FILE__, __func__, __LINE__, &memhead, s, format, ## __VA_ARGS__)
#define dmastrcat(s, b, m) __dmastrcat(__FILE__, __func__, __LINE__, &memhead, s, b, m)
#define dmcleanmem() __dmcleanmem(&memhead)
#else
#define dmmalloc(x) __dmmalloc(&memhead, x)
#define dmcalloc(n, x) __dmcalloc(&memhead, n, x)
#define dmrealloc(x, n) __dmrealloc(&memhead, x, n)
@ -111,7 +42,6 @@ struct list_head *mem_list, char **s, char *obj, char *lastname
#define dmasprintf(s, format, ...) __dmasprintf(&memhead, s, format, ## __VA_ARGS__)
#define dmastrcat(s, b, m) __dmastrcat(&memhead, s, b, m)
#define dmcleanmem() __dmcleanmem(&memhead)
#endif /*WITH_MEMTRACK*/
#define dm_dynamic_malloc(m, x) __dmmalloc(m, x)
#define dm_dynamic_calloc(m, n, x) __dmcalloc(m, n, x)
@ -120,16 +50,4 @@ struct list_head *mem_list, char **s, char *obj, char *lastname
#define dm_dynamic_asprintf(m, s, format, ...) __dmasprintf(m, s, format, ## __VA_ARGS__)
#define dm_dynamic_cleanmem(m) __dmcleanmem(m)
#else
#define dmmalloc(x) malloc(x)
#define dmcalloc(n, x) calloc(n, x)
#define __dmstrdup(x) strdup(x)
#define dmstrdup(x) strdup(x)
#define dmasprintf(s, format, ...) __dmasprintf(s, format, ## __VA_ARGS__)
#define dmastrcat(s, b, m) __dmastrcat(s, b, m)
#define dmfree(x) free(x)
#define dmcleanmem() dm_empty_func()
#endif /*WITH_MEMLEACKSEC*/
#define DMFREE(x) do { dmfree(x); x = NULL; } while (0);
#endif
#endif /* __DMMEM_H */

View file

@ -666,7 +666,6 @@ void dmubus_update_cached_entries()
{
if (hard_limit_g == 0 || local_ctx_g == true) {
dmubus_free();
dm_libubus_free();
} else {
struct dm_ubus_cache_entry *entry;
time_t curr_time = time(NULL);
@ -695,6 +694,8 @@ void dmubus_free()
list_for_each_entry_safe(entry, tmp, &dmubus_cache, list)
dm_ubus_cache_entry_free(entry);
dm_libubus_free();
}
void dmubus_set_caching_time(int seconds)

View file

@ -40,7 +40,7 @@ void dmuci_exit(void)
uci_ctx = NULL;
}
int bbf_uci_init(void)
int dm_uci_init(void)
{
dmuci_init();
@ -53,7 +53,7 @@ int bbf_uci_init(void)
return 0;
}
int bbf_uci_exit(void)
int dm_uci_exit(void)
{
dmuci_exit();
@ -108,9 +108,9 @@ static void add_list_package_change(struct list_head *clist, char *package)
if (DM_STRCMP(pc->package, package) == 0)
return;
}
pc = calloc(1, sizeof(struct package_change));//TODO !!!!! Do not use dmcalloc here
pc = calloc(1, sizeof(struct package_change));
list_add_tail(&pc->list, clist);
pc->package = strdup(package); //TODO !!!!! Do not use dmstrdup here
pc->package = strdup(package);
}
void free_all_list_package_change(struct list_head *clist)
@ -119,8 +119,8 @@ void free_all_list_package_change(struct list_head *clist)
while (clist->next != clist) {
pc = list_entry(clist->next, struct package_change, list);
list_del(&pc->list);
free(pc->package);//TODO !!!!! Do not use dmfree here
free(pc);//TODO !!!!! Do not use dmfree here
free(pc->package);
free(pc);
}
}

View file

@ -324,8 +324,8 @@ int dmuci_delete_by_section_unnamed_##UCI_PATH(struct uci_section *s, char *opti
int dmuci_init(void);
void dmuci_exit(void);
int bbf_uci_init(void);
int bbf_uci_exit(void);
int dm_uci_init(void);
int dm_uci_exit(void);
char *dmuci_list_to_string(struct uci_list *list, const char *delimitor);
void free_all_list_package_change(struct list_head *clist);
int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value);

View file

@ -31,7 +31,7 @@
#include <libubox/list.h>
#include <json-c/json.h>
#include "libbbf_api/dmapi.h"
#include <libbbf_api/dmapi.h>
/*******************
*

View file

@ -103,9 +103,14 @@ INSTALL(FILES ${root_device}
IF(BBF_TR143)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm)
INSTALL(DIRECTORY DESTINATION usr/libexec/rpcd)
FILE(GLOB scripts scripts/*)
INSTALL(FILES ${scripts}
PERMISSIONS OWNER_EXECUTE
DESTINATION usr/share/bbfdm
)
INSTALL(FILES scripts/bbf.diag
PERMISSIONS OWNER_EXECUTE
DESTINATION usr/libexec/rpcd
)
ENDIF(BBF_TR143)

View file

@ -134,7 +134,7 @@ static void send_transfer_complete_event(const char *command, const char *obj_pa
json_object_object_add(obj, "FaultCode", json_object_new_uint64(fault_code));
json_object_object_add(obj, "FaultString", json_object_new_string(fault_string));
dmubus_call_set("usp.raw", "notify_event", UBUS_ARGS{{"name", "Device.LocalAgent.TransferComplete!", String}, {"input", json_object_to_json_string(obj), Table}}, 2);
dmubus_call_set("bbfdm", "notify_event", UBUS_ARGS{{"name", "Device.LocalAgent.TransferComplete!", String}, {"input", json_object_to_json_string(obj), Table}}, 2);
json_object_put(obj);
}

View file

@ -19,7 +19,7 @@ char *KeyingMethods[] = {"Null", "Static", "SDP", "IKE", NULL};
char *FacilityAction[] = {"AA_REGISTER", "AA_ERASE", "AA_INTERROGATE", "CA_ACTIVATE", "CCBS_ACTIVATE", "CCBS_DEACTIVATE", "CCBS_INTERROGATE", "CCNR_ACTIVATE", "CCNR_DEACTIVATE", "CCNR_INTERROGATE", "CFB_REGISTER", "CFB_ACTIVATE", "CFB_DEACTIVATE", "CFB_ERASE", "CFB_INTERROGATE", "CFNR_REGISTER", "CFNR_ACTIVATE", "CFNR_DEACTIVATE", "CFNR_ERASE", "CFNR_INTERROGATE", "CFNR_TIMER", "CFT_ACTIVATE", "CFT_DEACTIVATE", "CFT_INTERROGATE", "CFU_REGISTER", "CFU_ACTIVATE", "CFU_DEACTIVATE", "CFU_ERASE", "CFU_INTERROGATE", "CLIR_ACTIVATE", "CLIR_DEACTIVATE", "CLIR_INTERROGATE", "CP_INVOKE", "CW_ACTIVATE", "CW_DEACTIVATE", "CW_INVOKE", "DND_ACTIVATE", "DND_DEACTIVATE", "DND_INTERROGATE", "EXT_INVOKE", "LINE_INVOKE", "MAILBOX_INVOKE", "OCB_ACTIVATE", "OCB_DEACTIVATE", "OCB_INTERROGATE", "PSO_ACTIVATE", "PW_SET", "SCF_ACTIVATE", "SCF_DEACTIVATE", "SCF_INTERROGATE", "SCREJ_ACTIVATE", "SCREJ_DEACTIVATE", "SCREJ_INTERROGATE", "SR_ACTIVATE", "SR_DEACTIVATE", "SR_INTERROGATE", NULL};
struct codec_info supported_codecs[MAX_SUPPORTED_CODECS];
int codecs_num;
extern struct list_head main_memhead;
extern struct list_head global_memhead;
LIST_HEAD(call_log_list);
static struct stat prev_stat = { 0 };
static int call_log_list_size = 0;
@ -634,7 +634,7 @@ int init_call_log(void)
pos = &entry->list;
}
} else {
entry = dm_dynamic_malloc(&main_memhead, sizeof(struct call_log_entry));
entry = dm_dynamic_malloc(&global_memhead, sizeof(struct call_log_entry));
if (!entry)
return -1;

View file

@ -1713,7 +1713,7 @@ static int operate_IPDiagnostics_IPPing(char *refparam, struct dmctx *ctx, void
char *ipping_timeout = dmjson_get_value((json_object *)value, 1, "Timeout");
char *ipping_datablocksize = dmjson_get_value((json_object *)value, 1, "DataBlockSize");
char *ipping_dscp = dmjson_get_value((json_object *)value, 1, "DSCP");
char *proto = (bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto";
char *proto = (ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto";
dmubus_call_blocking("bbf.diag", "ipping",
UBUS_ARGS{
@ -1823,7 +1823,7 @@ static int operate_IPDiagnostics_TraceRoute(char *refparam, struct dmctx *ctx, v
datablocksize,
dscp,
maxhops,
(bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto");
(ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto");
snprintf(cmd, sizeof(cmd), "sh %s %s", TRACEROUTE_DIAGNOSTIC_PATH, input);
@ -1954,7 +1954,7 @@ static int operate_IPDiagnostics_DownloadDiagnostics(char *refparam, struct dmct
download_proto,
download_num_of_connections,
download_enable_per_connection_results,
(bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto");
(ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto");
snprintf(cmd, sizeof(cmd), "sh %s %s", DOWNLOAD_DIAGNOSTIC_PATH, input);
@ -2093,7 +2093,7 @@ static int operate_IPDiagnostics_UploadDiagnostics(char *refparam, struct dmctx
upload_proto,
upload_num_of_connections,
upload_enable_per_connection_results,
(bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto");
(ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto");
snprintf(cmd, sizeof(cmd), "sh %s %s", UPLOAD_DIAGNOSTIC_PATH, input);
@ -2200,7 +2200,7 @@ static int operate_IPDiagnostics_UDPEchoDiagnostics(char *refparam, struct dmctx
char *udpecho_datablocksize = dmjson_get_value((json_object *)value, 1, "DataBlockSize");
char *udpecho_dscp = dmjson_get_value((json_object *)value, 1, "DSCP");
char *udpecho_inter_transmission_time = dmjson_get_value((json_object *)value, 1, "InterTransmissionTime");
char *proto = (bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto";
char *proto = (ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto";
dmubus_call_blocking("bbf.diag", "udpecho",
UBUS_ARGS{
@ -2284,7 +2284,7 @@ static int operate_IPDiagnostics_ServerSelectionDiagnostics(char *refparam, stru
char *interface = get_diagnostics_interface_option(ctx, ip_interface);
char *nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions");
char *timeout = dmjson_get_value((json_object *)value, 1, "Timeout");
char *proto = (bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto";
char *proto = (ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto";
dmubus_call_blocking("bbf.diag", "serverselection",
UBUS_ARGS{

View file

@ -59,7 +59,7 @@ static int get_Device_InterfaceStackNumberOfEntries(char *refparam, struct dmctx
static int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = DEFAULT_DMVERSION;
*value = "2.16";
return 0;
}

View file

@ -14,7 +14,7 @@
#include "deviceinfo.h"
#include "sys/statvfs.h"
extern struct list_head main_memhead;
extern struct list_head global_memhead;
LIST_HEAD(process_list);
static int process_count = 0;
@ -343,7 +343,7 @@ static void init_processes(void)
if (process_count == 0 || !(pentry_exits = check_entry_exists(entry->d_name))) {
pentry = dm_dynamic_malloc(&main_memhead, sizeof(struct process_entry));
pentry = dm_dynamic_malloc(&global_memhead, sizeof(struct process_entry));
if (!pentry)
return;

View file

@ -760,7 +760,7 @@ static int operate_DNSDiagnostics_NSLookupDiagnostics(char *refparam, struct dmc
char *dnsserver = dmjson_get_value((json_object *)value, 1, "DNSServer");
char *timeout = dmjson_get_value((json_object *)value, 1, "Timeout");
char *nbofrepetition = dmjson_get_value((json_object *)value, 1, "NumberOfRepetitions");
char *proto = (bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto";
char *proto = (ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto";
dmubus_call_blocking("bbf.diag", "nslookup",
UBUS_ARGS{

View file

@ -93,7 +93,7 @@ static void free_firewall_config_dup_list(struct list_head *dup_list)
list_for_each_entry_safe(rule_args, tmp, dup_list, list) {
list_del(&rule_args->list);
DMFREE(rule_args);
dmfree(rule_args);
}
}

View file

@ -144,7 +144,7 @@ static void free_ssh_config_dup_list(struct list_head *dup_list)
list_for_each_entry_safe(dmmap_config, tmp, dup_list, list) {
list_del(&dmmap_config->list);
DMFREE(dmmap_config);
dmfree(dmmap_config);
}
}
@ -235,7 +235,7 @@ static void free_ssh_session_list(struct list_head *sess_list)
struct ssh_session_args *session = NULL, *tmp = NULL;
list_for_each_entry_safe(session, tmp, sess_list, list) {
list_del(&session->list);
DMFREE(session);
dmfree(session);
}
}

View file

@ -100,7 +100,7 @@ static void free_http_config_dup_list(struct list_head *dup_list)
struct dmmap_http *dmmap_config = NULL, *tmp = NULL;
list_for_each_entry_safe(dmmap_config, tmp, dup_list, list) {
list_del(&dmmap_config->list);
DMFREE(dmmap_config);
dmfree(dmmap_config);
}
}
@ -109,7 +109,7 @@ static void free_http_session_list(struct list_head *sess_list)
struct http_session_args *session = NULL, *tmp = NULL;
list_for_each_entry_safe(session, tmp, sess_list, list) {
list_del(&session->list);
DMFREE(session);
dmfree(session);
}
}

View file

@ -5904,7 +5904,7 @@ static int operate_WiFi_NeighboringWiFiDiagnostic(char *refparam, struct dmctx *
signal_strength[1] = dmjson_get_value(array_obj, 1, "rssi");
noise[1] = dmjson_get_value(array_obj, 1, "noise");
if (bbfdatamodel_type != BBFDM_USP) {
if (ctx->dm_type != BBFDM_USP) {
struct uci_section *dmmap_s = NULL;
dmuci_add_section_bbfdm("dmmap_wifi_neighboring", "result", &dmmap_s);
dmuci_set_value_by_section(dmmap_s, "ssid", ssid[1]);
@ -5932,7 +5932,7 @@ static int operate_WiFi_NeighboringWiFiDiagnostic(char *refparam, struct dmctx *
}
}
if (bbfdatamodel_type != BBFDM_USP) {
if (ctx->dm_type != BBFDM_USP) {
dmuci_set_value_bbfdm("dmmap_wifi_neighboring", "@diagnostic_status[0]", "DiagnosticsState", "Complete");
dmuci_commit_package_bbfdm("dmmap_wifi_neighboring");
}

View file

@ -1066,7 +1066,7 @@ int operate_IPDiagnostics_IPLayerCapacity(char *refparam, struct dmctx *ctx, voi
ip_proto, content, test_type, DM_STRLEN(ipdv) > 0 ? (ipdv_en ? "1" : "0") : "\0",
dscp, start_rate, mode_test, sub_interval, feed_interval, seq_err,
DM_STRLEN(dup_ignore) > 0 ? (dup_ignore_en ? "1" : "0") : "\0", low_thresh, up_thresh,
speed_delta, rate_adj, slow_adj, num_interval, (bbfdatamodel_type == BBFDM_USP) ? "usp" : "both_proto");
speed_delta, rate_adj, slow_adj, num_interval, (ctx->dm_type == BBFDM_USP) ? "usp" : "both_proto");
snprintf(cmd, sizeof(cmd), "sh %s %s", IPLAYER_CAP_DIAGNOSTIC_PATH, input);

View file

@ -14,7 +14,7 @@ START_TIME=$(date +%s)
MODE="${1}"
log() {
echo "${@}"|logger -t usp.activate_firmware -p info
echo "${@}"|logger -t bbf.activate_firmware -p info
}
activate_and_reboot_device() {

808
schemas/ubus/bbf.json Normal file
View file

@ -0,0 +1,808 @@
{
"definitions": {
"path_t": {
"description": "Complete object element path as per TR181",
"type": "string",
"minLength": 6,
"maxLength": 1024,
"examples": [
"Device.",
"Device.DeviceInfo.Manufacturer",
"Device.WiFi.SSID.1.",
"Device.WiFi."
]
},
"schema_path_t": {
"description": "Datamodel object schema path",
"type": "string",
"minLength": 6,
"maxLength": 1024,
"examples": [
"Device.Bridging.Bridge.{i}.",
"Device.DeviceInfo.Manufacturer",
"Device.WiFi.SSID.{i}.SSID"
]
},
"boolean_t": {
"type": "string",
"enum": [
"0",
"1"
]
},
"operate_path_t": {
"description": "Datamodel object schema path",
"type": "string",
"minLength": 6,
"maxLength": 1024,
"examples": [
"Device.IP.Diagnostics.IPPing()",
"Device.DHCPv4.Client.{i}.Renew()",
"Device.FactoryReset()"
]
},
"query_path_t": {
"description": "DM object path with search queries",
"type": "string",
"minLength": 6,
"maxLength": 1024,
"examples": [
"Device.",
"Device.DeviceInfo.Manufacturer",
"Device.WiFi.SSID.1.BSSID",
"Device.WiFi.SSID.*.BSSID",
"Device.WiFi."
]
},
"instance_t": {
"description": "Multi object instances",
"type": "string",
"minLength": 6,
"maxLength": 256
},
"proto_t": {
"type": "string",
"default": "both",
"enum": [
"usp",
"cwmp",
"both"
]
},
"type_t": {
"type": "string",
"enum": [
"xsd:string",
"xsd:unsignedInt",
"xsd:int",
"xsd:unsignedLong",
"xsd:long",
"xsd:boolean",
"xsd:dateTime",
"xsd:hexBinary",
"xsd:object",
"xsd:command",
"xsd:event"
]
},
"fault_t": {
"type": "integer",
"minimum": 7000,
"maximum": 9050
},
"trans_type_t": {
"type": "string",
"enum": [
"start",
"commit",
"abort",
"status"
]
},
"format_t": {
"type": "string",
"default": "pretty",
"enum": [
"raw",
"pretty"
]
},
"instance_mode_t": {
"type": "integer",
"default": 0,
"minimum": 0,
"maximum": 1
},
"trans_id_t": {
"type": "integer",
"minimum": 1
}
},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/docs/api/bbfdm.md",
"type": "object",
"title": "bbf",
"object": "bbf",
"additionalProperties": false,
"properties": {
"schema": {
"title": "Get list of supported datamodel parameters",
"description": "Schema will have all the nodes/objects supported by libbbf",
"type": "object",
"required": [
"output"
],
"properties": {
"input": {
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/query_path_t"
},
"paths": {
"type": "array",
"uniqueItems": true,
"items": [
{
"$ref": "#/definitions/query_path_t"
}
]
},
"first_level": {
"type": "boolean",
"description": "gets only first level objects if true"
},
"commands": {
"type": "boolean",
"description": "includes commands in the list if true"
},
"events": {
"type": "boolean",
"description": "includes events in the list if true"
},
"params": {
"type": "boolean",
"description": "includes objs/params in the list if true"
},
"optional": {
"type": "object",
"properties": {
"proto": {
"$ref": "#/definitions/proto_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/schema_path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"type": {
"$ref": "#/definitions/type_t"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"input": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/schema_path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"type": {
"$ref": "#/definitions/type_t"
}
}
}
]
},
"output": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/schema_path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"type": {
"$ref": "#/definitions/type_t"
}
}
}
]
}
},
"required": [
"path"
]
}
]
}
}
}
}
},
"get": {
"title": "Get handler",
"description": "Query the datamodel object",
"type": "object",
"required": [
"input",
"output"
],
"properties": {
"input": {
"type": "object",
"required": [
"path"
],
"properties": {
"path": {
"$ref": "#/definitions/query_path_t"
},
"paths": {
"type": "array",
"uniqueItems": true,
"items": [
{
"$ref": "#/definitions/query_path_t"
}
]
},
"maxdepth": {
"type": "integer",
"description": "Integer to decide the depth of data model to be parsed"
},
"optional": {
"type": "object",
"properties": {
"format": {
"$ref": "#/definitions/format_t"
},
"proto": {
"$ref": "#/definitions/proto_t"
},
"instance_mode": {
"$ref": "#/definitions/instance_mode_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"type": "string"
},
"type": {
"$ref": "#/definitions/type_t"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
}
},
"required": [
"path"
]
}
]
}
}
}
}
},
"instances": {
"title": "Instance query handler",
"description": "Get the instances of multi object",
"type": "object",
"required": [
"input"
],
"properties": {
"input": {
"type": "object",
"required": [
"path"
],
"properties": {
"path": {
"$ref": "#/definitions/query_path_t"
},
"first_level": {
"type": "boolean",
"description": "gets only first level objects if true"
},
"optional": {
"type": "object",
"properties": {
"proto": {
"$ref": "#/definitions/proto_t"
},
"instance_mode": {
"$ref": "#/definitions/instance_mode_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
}
},
"required": [
"path"
]
}
]
}
}
}
}
},
"add": {
"title": "Add a new object instance",
"description": "Add a new object in multi instance object",
"type": "object",
"required": [
"input",
"output"
],
"properties": {
"input": {
"type": "object",
"required": [
"path",
"optional"
],
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"obj_path": {
"type": "object",
"properties": {}
},
"optional": {
"type": "object",
"properties": {
"transaction_id": {
"$ref": "#/definitions/trans_id_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"type": "string"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
}
},
"required": [
"path"
]
}
]
}
}
}
}
},
"del": {
"title": "Delete object instance",
"description": "Delete a object instance from multi instance object",
"type": "object",
"required": [
"input",
"output"
],
"properties": {
"input": {
"type": "object",
"required": [
"path",
"transaction_id"
],
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"paths": {
"type": "array",
"uniqueItems": true,
"items": [
{
"$ref": "#/definitions/query_path_t"
}
]
},
"optional": {
"type": "object",
"properties": {
"transaction_id": {
"$ref": "#/definitions/trans_id_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"type": "string"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
}
},
"required": [
"parameter",
"type"
]
}
]
}
}
}
}
},
"set": {
"title": "Set handler",
"description": "Set values of datamodel object element",
"type": "object",
"required": [
"input",
"output"
],
"properties": {
"input": {
"type": "object",
"required": [
"path",
"value",
"optional"
],
"properties": {
"path": {
"$ref": "#/definitions/query_path_t"
},
"value": {
"description": "value of the object element provided in path, path should contains valid writable object element",
"type": "string",
"examples": [
"{\"path\":\"Device.WiFi.SSID.1.SSID\", \"value\":\"test_ssid\"}",
"{\"path\":\"Device.WiFi.SSID.2.Enable\", \"value\":\"true\"}",
"{\"path\":\"Device.WiFi.SSID.1.Enable\", \"value\":\"0\"}"
]
},
"obj_path": {
"description": "To set multiple values at once, path should be relative to object elements",
"examples": [
"{\"path\":\"Device.WiFi.SSID.1\", \"values\":{\".SSID\":\"test_ssid\",\".Name\":\"test_name\"}}",
"{\"path\":\"Device.WiFi.SSID.2\", \"values\":{\".SSID\":\"test_ssid\"}}"
],
"type": "object",
"properties": {}
},
"optional": {
"type": "object",
"properties": {
"proto": {
"$ref": "#/definitions/proto_t"
},
"instance_mode": {
"$ref": "#/definitions/instance_mode_t"
},
"transaction_id": {
"$ref": "#/definitions/trans_id_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
}
},
"required": [
"path"
]
}
]
}
}
}
}
},
"operate": {
"title": "Operate handler",
"description": "Operate on object element provided in path",
"type": "object",
"required": [
"input",
"output"
],
"properties": {
"input": {
"type": "object",
"required": [
"command"
],
"properties": {
"command": {
"$ref": "#/definitions/operate_path_t"
},
"command_key": {
"type": "string"
},
"input": {
"description": "Input arguments for the operate command as defined in TR-181-2.13",
"examples": [
"{\"path\":\"Device.IP.Diagnostics.IPPing\\(\\)\", \"input\":{\"Host\":\"iopsys.eu\"}}"
],
"type": "object",
"properties": {}
},
"optional": {
"type": "object",
"properties": {
"format": {
"$ref": "#/definitions/format_t"
},
"proto": {
"$ref": "#/definitions/proto_t"
},
"instance_mode": {
"$ref": "#/definitions/instance_mode_t"
}
}
}
}
},
"output": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"fault": {
"$ref": "#/definitions/fault_t",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"fault_msg": {
"type": "string",
"Description": "Any discrepancy in input will result in fault. The type of fault can be identified by fault code"
},
"output": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"path": {
"$ref": "#/definitions/path_t"
},
"data": {
"$ref": "#/definitions/boolean_t"
},
"type": {
"$ref": "#/definitions/type_t"
}
}
}
]
}
},
"required": [
"path",
"data"
]
}
]
}
}
}
}
},
"transaction": {
"title": "Start/commit/abort/status a transaction before set/add/del operations",
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"cmd": {
"$ref": "#/definitions/trans_type_t"
},
"timeout": {
"type": "integer",
"minimum":0
},
"restart_services": {
"type": "boolean"
},
"optional": {
"type": "object",
"properties": {
"transaction_id": {
"$ref": "#/definitions/trans_id_t"
}
}
}
},
"required": [
"cmd"
]
},
"output": {
"type": "object",
"properties": {
"status": {
"type": "boolean"
},
"transaction_id": {
"type": "integer",
"minimum": 1
},
"error": {
"type": "string"
}
},
"required": [
"status"
]
}
},
"required": [
"input",
"output"
]
},
"notify_event": {
"title": "notify occurance of an event on ubus",
"type": "object",
"required": [
"input"
],
"properties": {
"input": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"input": {
"type": "object",
"properties": {}
}
}
},
"output": {}
}
}
}
}

60
schemas/uci/bbfd.json Normal file
View file

@ -0,0 +1,60 @@
{
"bbfdmd": [
{
"section": "globals",
"description": "BBF daemon Settings",
"multi": false,
"options": [
{
"name": "debug",
"type": "boolean",
"required": "no",
"default": "",
"description": "Enabled debug logging"
},
{
"name": "sock",
"type": "string",
"required": "no",
"default": "",
"description": "Path for ubus socket to register bbfdmd services"
},
{
"name": "transaction_timeout",
"type": "integer",
"required": "no",
"default": "10",
"description": "Transaction timeout value in seconds"
},
{
"name": "loglevel",
"type": "integer",
"required": "no",
"default": "1",
"description": "Internal loglevel for debugging {0: No Logs; 1: Errors only; 2: Errors and warnings; 3: Error, warning and info; 4: Everything}"
},
{
"name": "subprocess_level",
"type": "integer",
"required": "no",
"default": "2",
"description": "This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess."
},
{
"name": "bbf_caching_time",
"type": "integer",
"required": "no",
"default": "0",
"description": "Max caching time in seconds for ubus output used in datamodel parameters. If not configured, output shall be cleared end the end of call."
},
{
"name": "refresh_time",
"type": "integer",
"required": "no",
"default": "5",
"description": "The time period in seconds after which bbfdmd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed."
}
]
}
]
}

View file

@ -1,18 +0,0 @@
[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; true to run in foreground
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = ./gitlab-ci/iopsys-supervisord.conf

View file

@ -1,104 +0,0 @@
{
"object": "dmtest",
"methods": [
{
"method": "get",
"args": {
"path": "Device.",
"proto": "usp"
},
"rc": 0
},
{
"method": "transaction_start",
"args": {},
"rc": 0
},
{
"method": "set",
"args": {
"path": "Device..X_IOPSYS_EU_Syslog.ConsoleLogLevel",
"value": "1"
},
"rc": 0
},
{
"method": "transaction_abort",
"args": {},
"rc": 0
},
{
"method": "add_object",
"args": {
"path": "Device.ManagementServer..InformParameter.",
"proto": "cwmp"
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {
"path":"Device.",
"next-level":false,
"schema_type":1
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {
"path":"Device."
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {
"path":"Device.",
"next-level":false,
"schema_type":2
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {
"path":"Device.",
"next-level":false,
"schema_type":3
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {
"path":"Device.",
"schema_type":1
},
"rc": 0
},
{
"method": "get_supported_dm",
"args": {},
"rc": 0
},
{
"method": "transaction_start",
"args": {},
"rc": 0
},
{
"method": "transaction_commit",
"args": {},
"rc": 0
},
{
"method": "del_object",
"args": {
"path": "Device.ManagementServer..InformParameter.2",
"proto": "cwmp"
},
"rc": 0
}
]
}

View file

@ -4,8 +4,8 @@ BIN = bbf_dm
BIN_OBJ = bbf_dm.o
LIB_OBJS = libbbf_test.o
LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -I /usr/local/include/
LIB_LDFLAGS = $(LDFLAGS) -lubus
BIN_LDFLAGS = $(LDFLAGS) -lbbf_api -lbbf_dm -lubus
LIB_LDFLAGS = $(LDFLAGS) -lbbf_api
BIN_LDFLAGS = $(LDFLAGS) -lbbf_api -lbbf_dm
%.o: %.c
$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<

View file

@ -1,6 +1,6 @@
#include <stdio.h>
#include <libubus.h>
#include <libbbf_api/dmapi.h>
#include <libbbf_api/dmentry.h>
#include <libbbf_dm/device.h>
#include <libbbf_dm/vendor.h>
@ -12,12 +12,6 @@ static DM_MAP_VENDOR *TR181_VENDOR_EXTENSION[2] = {
};
static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
#ifndef CMD_GET_INFO
#define CMD_GET_INFO (CMD_EXTERNAL_COMMAND + 1)
#endif
static struct ubus_context *ubus_ctx = NULL;
static int g_proto = BBFDM_USP;
typedef struct {
int id;
char *str;
@ -25,22 +19,18 @@ typedef struct {
cmd_t CMD[] = {
{ CMD_GET_VALUE, "get"},
{ CMD_GET_NAME, "get_name"},
//{ CMD_SET_VALUE, "set"},
//{ CMD_ADD_OBJECT, "add"},
//{ CMD_DEL_OBJECT, "del"},
//{ CMD_USP_OPERATE, "operate"},
{ CMD_USP_LIST_OPERATE, "list_operate"},
{ CMD_USP_LIST_EVENT, "list_event"},
{ CMD_GET_SCHEMA, "get_schema"},
{ CMD_GET_INSTANCES, "instances"},
{ CMD_GET_INFO, "get_info"}
{ BBF_GET_VALUE, "get"},
{ BBF_SCHEMA, "schema"},
{ BBF_INSTANCES, "instances"},
//{ BBF_SET_VALUE, "set"},
//{ BBF_ADD_OBJECT, "add"},
//{ BBF_DEL_OBJECT, "del"},
//{ BBF_USP_OPERATE, "operate"},
};
int get_cmd_from_str(char *str)
static int get_cmd_from_str(char *str)
{
int i, cmd = CMD_GET_VALUE;
int i, cmd = BBF_GET_VALUE;
for (i = 0; i < ARRAY_SIZE(CMD); i++) {
if (DM_STRCMP(CMD[i].str, str) == 0) {
@ -52,7 +42,7 @@ int get_cmd_from_str(char *str)
return cmd;
}
void print_help(char *prog)
static void print_help(char *prog)
{
printf("Valid commands:\n");
printf("%s -c => Run with cwmp proto\n", prog);
@ -60,29 +50,43 @@ void print_help(char *prog)
exit(0);
}
int usp_dm_exec(int cmd, char *path, char *arg1, char *arg2)
int bbf_dm_exec(int argc, char *argv[])
{
int fault = 0;
struct dmctx bbf_ctx;
int fault = 0;
int cmd = 0;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
printf("cmd[%d], path[%s]\n", cmd, path);
set_bbfdatamodel_type(g_proto);
cmd = get_cmd_from_str(argv[2]);
dm_ctx_init(&bbf_ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, 0);
bbf_ctx.instance_mode = INSTANCE_MODE_NUMBER;
if (arg2 && *arg2) {
bbf_ctx.dm_version = arg2;
printf("config version %s\n", bbf_ctx.dm_version);
if (DM_STRCMP(argv[1], "-c") == 0)
bbf_ctx.dm_type = BBFDM_CWMP;
else
bbf_ctx.dm_type = BBFDM_USP;
if (argc > 3 && DM_STRLEN(argv[3]))
bbf_ctx.in_param = argv[3];
if (cmd == 1) {
bbf_ctx.nextlevel = false;
bbf_ctx.iscommand = true;
bbf_ctx.isevent = true;
bbf_ctx.isinfo = true;
}
if (cmd == CMD_GET_INFO) {
fault = dm_get_supported_dm(&bbf_ctx, path, false, DM_STRTOL(arg1));
} else {
fault = dm_entry_param_method(&bbf_ctx, cmd, path, arg1, arg2);
if (cmd == 2) {
bbf_ctx.nextlevel = false;
}
if (cmd == 3 && argc > 4 && DM_STRLEN(argv[4]))
bbf_ctx.in_value = argv[4];
bbf_ctx_init(&bbf_ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
fault = bbf_entry_method(&bbf_ctx, cmd);
if (!fault) {
struct dm_parameter *n;
@ -93,42 +97,16 @@ int usp_dm_exec(int cmd, char *path, char *arg1, char *arg2)
printf("Fault %d\n", fault);
}
dm_ctx_clean(&bbf_ctx);
bbf_ctx_clean(&bbf_ctx);
return fault;
}
int main(int argc, char *argv[])
{
char *param = "", *value = "", *version = "";
int cmd;
if (argc < 3) {
if (argc < 3)
print_help(argv[0]);
}
ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL) {
fprintf(stderr, "Failed to connect with ubus\n");
return -1;
}
bbf_dm_exec(argc, argv);
dm_config_ubus(ubus_ctx);
if (DM_STRCMP(argv[1], "-c") == 0)
g_proto = BBFDM_CWMP;
cmd = get_cmd_from_str(argv[2]);
if (argc > 3 && DM_STRLEN(argv[3]))
param = argv[3];
if (argc > 4 && DM_STRLEN(argv[4]))
value = argv[4];
if (argc > 5 && DM_STRLEN(argv[5]))
version = argv[5];
usp_dm_exec(cmd, param, value, version);
bbf_dm_cleanup(TR181_ROOT_TREE);
ubus_free(ubus_ctx);
bbf_global_clean(TR181_ROOT_TREE);
}

View file

@ -19,7 +19,6 @@
/* ********** DynamicObj ********** */
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.ManagementServer.", NULL, tDynamicManagementServerParams},
{"Device.", tDynamicDeviceObj, tDynamicDeviceParams},
{0}
};
@ -27,29 +26,6 @@ DM_MAP_OBJ tDynamicObj[] = {
/*************************************************************
* GET & SET PARAM
**************************************************************/
static int get_ManagementServer_EnableCWMP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_option_value_fallback_def("cwmp", "acs", "enabled", "1");
return 0;
}
static int set_ManagementServer_EnableCWMP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
bool b;
switch (action) {
case VALUECHECK:
if (dm_validate_boolean(value))
return FAULT_9007;
break;
case VALUESET:
string_to_bool(value, &b);
dmuci_set_value("cwmp", "acs", "enabled", b ? "1" : "0");
break;
}
return 0;
}
static int get_X_IOPSYS_EU_Syslog_ServerIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_option_value_string("system", "@system[0]", "log_ip", value);
@ -184,12 +160,6 @@ static int get_event_args_XIOPSYSEU_Boot(char *refparam, struct dmctx *ctx, void
/**********************************************************************************************************************************
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
DMLEAF tDynamicManagementServerParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"EnableCWMP", &DMWRITE, DMT_BOOL, get_ManagementServer_EnableCWMP, set_ManagementServer_EnableCWMP, BBFDM_CWMP},
{0}
};
/* *** Device. *** */
DMOBJ tDynamicDeviceObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/

View file

@ -11,7 +11,6 @@
#ifndef __LIBBBFD_TEST_H
#define __LIBBBFD_TEST_H
extern DMLEAF tDynamicManagementServerParams[];
extern DMOBJ tDynamicDeviceObj[];
extern DMLEAF tDynamicDeviceParams[];
extern DMLEAF tX_IOPSYS_EU_SyslogParam[];

View file

@ -1,6 +1,6 @@
CC = gcc
CFLAGS = -g -Wall -Werror
LDFLAGS = -lcmocka -lbbf_api -lbbf_dm -lubus
LDFLAGS = -lcmocka -lbbf_api -lbbf_dm
UNIT_TESTS = unit_test_bbfd
FUNCTIONAL_TESTS = functional_test_bbfd
FUNCTIONAL_API_TESTS = functional_api_test_bbfd

View file

@ -3,31 +3,19 @@
#include <setjmp.h>
#include <cmocka.h>
#include <libubus.h>
#include <libbbf_api/dmcommon.h>
#include <libbbf_api/dmmem.h>
static struct ubus_context *ubus_ctx = NULL;
static int setup_teardown(void **state)
{
ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL)
return -1;
dmubus_configure(ubus_ctx);
bbf_uci_init();
dm_uci_init();
return 0;
}
static int group_teardown(void **state)
{
bbf_uci_exit();
dm_uci_exit();
dmubus_free();
if (ubus_ctx != NULL) {
ubus_free(ubus_ctx);
ubus_ctx = NULL;
}
dmcleanmem();
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,8 @@
#include <setjmp.h>
#include <cmocka.h>
#include <libubus.h>
#include <libbbf_api/dmuci.h>
#include <libbbf_api/dmapi.h>
#include <libbbf_api/dmentry.h>
#include <libbbf_dm/device.h>
#include <libbbf_dm/vendor.h>
@ -21,37 +21,14 @@ static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionE
#define LIBBBF_TEST_PATH "../bbf_test/libbbf_test.so"
#define LIBBBF_TEST_BBFDM_PATH "/usr/lib/bbfdm/libbbf_test.so"
static struct ubus_context *ubus_ctx = NULL;
static int group_setup(void **state)
{
ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL)
return -1;
dm_config_ubus(ubus_ctx);
return 0;
}
static int setup(void **state)
{
struct dmctx *ctx = calloc(1, sizeof(struct dmctx));
if (!ctx)
return -1;
dm_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_NUMBER);
*state = ctx;
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
return 0;
}
static int setup_alias(void **state)
{
struct dmctx *ctx = calloc(1, sizeof(struct dmctx));
if (!ctx)
return -1;
dm_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_ALIAS);
*state = ctx;
return 0;
@ -61,8 +38,8 @@ static int teardown_commit(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
dm_entry_restart_services();
dm_ctx_clean(ctx);
bbf_entry_restart_services(NULL, true);
bbf_ctx_clean(ctx);
free(ctx);
return 0;
@ -72,8 +49,8 @@ static int teardown_revert(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
dm_entry_revert_changes();
dm_ctx_clean(ctx);
bbf_entry_revert_changes(NULL);
bbf_ctx_clean(ctx);
free(ctx);
return 0;
@ -81,12 +58,7 @@ static int teardown_revert(void **state)
static int group_teardown(void **state)
{
bbf_dm_cleanup(TR181_ROOT_TREE);
if (ubus_ctx != NULL) {
ubus_free(ubus_ctx);
ubus_ctx = NULL;
}
bbf_global_clean(TR181_ROOT_TREE);
return 0;
}
@ -96,7 +68,9 @@ static void test_api_bbfdm_get_value_object(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.", NULL, NULL);
ctx->in_param = "Device.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -109,7 +83,9 @@ static void test_api_bbfdm_get_value_parameter(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Alias", NULL, NULL);
ctx->in_param = "Device.WiFi.Radio.1.Alias";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -122,7 +98,9 @@ static void test_api_bbfdm_get_value_empty(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "", NULL, NULL);
ctx->in_param = "";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -135,7 +113,9 @@ static void test_api_bbfdm_get_value_wrong_object_path(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.DSLL.", NULL, NULL);
ctx->in_param = "Device.DSLL.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -148,7 +128,9 @@ static void test_api_bbfdm_get_value_wrong_parameter_path(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.Users.User.1.Enabl", NULL, NULL);
ctx->in_param = "Device.Users.User.1.Enabl";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -161,7 +143,10 @@ static void test_api_bbfdm_get_value_object_alias(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.", NULL, NULL);
ctx->in_param = "Device.";
ctx->instance_mode = INSTANCE_MODE_ALIAS;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -174,7 +159,10 @@ static void test_api_bbfdm_get_value_parameter_alias(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.[cpe-1].Alias", NULL, NULL);
ctx->in_param = "Device.WiFi.Radio.[cpe-1].Alias";
ctx->instance_mode = INSTANCE_MODE_ALIAS;
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -187,7 +175,10 @@ static void test_api_bbfdm_get_name_object(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.", "0", NULL);
ctx->in_param = "Device.";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_GET_NAME);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -200,7 +191,10 @@ static void test_api_bbfdm_get_name_parameter(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.Radio.1.Enable", "false", NULL);
ctx->in_param = "Device.WiFi.Radio.1.Enable";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_GET_NAME);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -213,7 +207,10 @@ static void test_api_bbfdm_get_name_dot(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, ".", "0", NULL);
ctx->in_param = ".";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_GET_NAME);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -226,46 +223,27 @@ static void test_api_bbfdm_get_name_wrong_object_path(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFii.", "0", NULL);
ctx->in_param = "Device.WiFii.";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_GET_NAME);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list == &ctx->list_parameter);
}
static void test_api_bbfdm_get_name_without_next_level(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.", NULL, NULL);
assert_int_equal(fault, FAULT_9003);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list == &ctx->list_parameter);
}
static void test_api_bbfdm_get_name_wrong_next_level(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.", "test", NULL);
assert_int_equal(fault, FAULT_9003);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list == &ctx->list_parameter);
}
static void test_api_bbfdm_get_name_parameter_alias(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.Radio.[cpe-1].Enable", "false", NULL);
ctx->in_param = "Device.WiFi.Radio.[cpe-1].Enable";
ctx->instance_mode = INSTANCE_MODE_ALIAS;
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_GET_NAME);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -275,97 +253,85 @@ static void test_api_bbfdm_get_name_parameter_alias(void **state)
static void test_api_bbfdm_set_value_object(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.", "test", NULL);
assert_int_equal(fault, FAULT_9005);
ctx->in_param = "Device.Users.User.";
ctx->in_value = "test";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list != &ctx->list_fault_param);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9005);
}
static void test_api_bbfdm_set_value_parameter(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.1.Username", "test", NULL);
assert_int_equal(fault, 0);
ctx->in_param = "Device.Users.User.1.Username";
ctx->in_value = "test";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
}
static void test_api_bbfdm_set_value_empty(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "", "test", NULL);
assert_int_equal(fault, FAULT_9005);
ctx->in_param = "";
ctx->in_value = "test";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list != &ctx->list_fault_param);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9005);
}
static void test_api_bbfdm_set_value_wrong_parameter_path(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.Username", "test", NULL);
assert_int_equal(fault, FAULT_9005);
ctx->in_param = "Device.Users.User.Username";
ctx->in_value = "test";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list != &ctx->list_fault_param);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9005);
}
static void test_api_bbfdm_set_value_parameter_non_writable(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Status", "Enabled", NULL);
assert_int_equal(fault, FAULT_9008);
ctx->in_param = "Device.WiFi.Radio.1.Status";
ctx->in_value = "Enabled";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list != &ctx->list_fault_param);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9008);
}
static void test_api_bbfdm_set_value_parameter_wrong_value(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Enable", "truee", NULL);
assert_int_equal(fault, FAULT_9007);
ctx->in_param = "Device.WiFi.Radio.1.Enable";
ctx->in_value = "truee";
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list != &ctx->list_fault_param);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, FAULT_9007);
}
static void test_api_bbfdm_set_value_parameter_alias(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.[cpe-1].Username", "test", NULL);
assert_int_equal(fault, 0);
ctx->in_param = "Device.Users.User.[cpe-1].Username";
ctx->in_value = "test";
ctx->instance_mode = INSTANCE_MODE_ALIAS;
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
}
@ -374,7 +340,9 @@ static void test_api_bbfdm_add_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.Users.User.", NULL, NULL);
ctx->in_param = "Device.Users.User.";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, 0);
assert_non_null(ctx->addobj_instance);
@ -386,7 +354,9 @@ static void test_api_bbfdm_add_wrong_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.WiFi.Users.", NULL, NULL);
ctx->in_param = "Device.WiFi.Users.";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, FAULT_9005);
assert_null(ctx->addobj_instance);
@ -397,7 +367,9 @@ static void test_api_bbfdm_add_object_non_writable(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.WiFi.Radio.", NULL, NULL);
ctx->in_param = "Device.WiFi.Radio.";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, FAULT_9005);
assert_null(ctx->addobj_instance);
@ -408,7 +380,9 @@ static void test_api_bbfdm_add_object_empty(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "", NULL, NULL);
ctx->in_param = "";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, FAULT_9005);
assert_null(ctx->addobj_instance);
@ -419,7 +393,9 @@ static void test_api_bbfdm_delete_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID.1.", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID.1.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
}
@ -428,7 +404,9 @@ static void test_api_bbfdm_delete_object_all_instances(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Users.User.", NULL, NULL);
ctx->in_param = "Device.Users.User.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
}
@ -437,7 +415,9 @@ static void test_api_bbfdm_delete_wrong_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, FAULT_9005);
}
@ -446,7 +426,9 @@ static void test_api_bbfdm_delete_object_non_writable(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Hosts.Host.", NULL, NULL);
ctx->in_param = "Device.Hosts.Host.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, FAULT_9005);
}
@ -455,7 +437,9 @@ static void test_api_bbfdm_delete_object_empty(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "", NULL, NULL);
ctx->in_param = "";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, FAULT_9005);
}
@ -464,7 +448,9 @@ static void test_api_bbfdm_valid_operate(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.WiFi.AccessPoint.1.Security.Reset()", NULL, NULL);
ctx->in_param = "Device.WiFi.AccessPoint.1.Security.Reset()";
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, CMD_SUCCESS);
}
@ -473,7 +459,9 @@ static void test_api_bbfdm_wrong_operate(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPing()", NULL, NULL);
ctx->in_param = "Device.IP.Diagnostics.IPing()";
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, CMD_NOT_FOUND);
}
@ -483,7 +471,14 @@ static void test_api_bbfdm_get_list_operate(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, NULL, NULL, NULL);
ctx->in_param = "Device.";
ctx->dm_type = BBFDM_USP;
ctx->nextlevel = false;
ctx->iscommand = true;
ctx->isevent = false;
ctx->isinfo = false;
fault = bbf_entry_method(ctx, BBF_SCHEMA);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -496,7 +491,14 @@ static void test_api_bbfdm_get_list_event(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_USP_LIST_EVENT, NULL, NULL, NULL);
ctx->in_param = "Device.";
ctx->dm_type = BBFDM_USP;
ctx->nextlevel = false;
ctx->iscommand = false;
ctx->isevent = true;
ctx->isinfo = false;
fault = bbf_entry_method(ctx, BBF_SCHEMA);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -509,7 +511,14 @@ static void test_api_bbfdm_get_schema(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_SCHEMA, NULL, NULL, NULL);
ctx->in_param = "Device.";
ctx->dm_type = BBFDM_USP;
ctx->nextlevel = false;
ctx->iscommand = true;
ctx->isevent = true;
ctx->isinfo = true;
fault = bbf_entry_method(ctx, BBF_SCHEMA);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -522,7 +531,10 @@ static void test_api_bbfdm_get_instances_object(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.", "0", NULL);
ctx->in_param = "Device.";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_INSTANCES);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -535,7 +547,10 @@ static void test_api_bbfdm_get_instances_wrong_object(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFii.", "true", NULL);
ctx->in_param = "Device.WiFii.";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_INSTANCES);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -548,26 +563,16 @@ static void test_api_bbfdm_get_instances_without_next_level(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFi.", NULL, NULL);
ctx->in_param = "Device.WiFi.";
ctx->nextlevel = false;
fault = bbf_entry_method(ctx, BBF_INSTANCES);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
}
static void test_api_bbfdm_get_instances_wrong_next_level(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFi.", "test", NULL);
assert_int_equal(fault, FAULT_9003);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list == &ctx->list_parameter);
}
static void test_api_bbfdm_json_get_value(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
@ -577,30 +582,33 @@ static void test_api_bbfdm_json_get_value(void **state)
/*
* Test of JSON Object Path
*/
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
dm_ctx_clean_sub(ctx);
dm_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_NUMBER);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
/*
* Test of JSON Parameter Path
*/
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.Enable", NULL, NULL);
ctx->in_param = "Device.UserInterface.Enable";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
dm_ctx_clean_sub(ctx);
dm_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_NUMBER);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
remove(DROPBEAR_JSON_PATH);
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -610,27 +618,20 @@ static void test_api_bbfdm_json_get_value(void **state)
static void test_api_bbfdm_json_set_value(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
dmcmd("/bin/cp", 2, DROPBEAR_FILE_PATH, DROPBEAR_JSON_PATH);
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UserInterface.Enable", "true", NULL);
ctx->in_param = "Device.UserInterface.Enable";
ctx->in_value = "true";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.1.Port";
ctx->in_value = "9856";
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
assert_int_equal(fault, 0);
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Dropbear.1.Port", "9856", NULL);
assert_int_equal(fault, 0);
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
}
@ -639,7 +640,9 @@ static void test_api_bbfdm_json_add_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, 0);
assert_non_null(ctx->addobj_instance);
@ -651,10 +654,14 @@ static void test_api_bbfdm_json_delete_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.1.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.1.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
}
@ -664,27 +671,33 @@ static void test_api_bbfdm_library_get_value(void **state)
struct dm_parameter *first_entry;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Syslog.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Syslog.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
dm_ctx_clean_sub(ctx);
dm_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_NUMBER);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.SSID.1.Enable", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID.1.Enable";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, 0);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
dm_ctx_clean_sub(ctx);
dm_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, INSTANCE_MODE_NUMBER);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
remove(LIBBBF_TEST_BBFDM_PATH);
fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Syslog.", NULL, NULL);
ctx->in_param = "Device.X_IOPSYS_EU_Syslog.";
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
assert_int_equal(fault, FAULT_9005);
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
@ -694,27 +707,20 @@ static void test_api_bbfdm_library_get_value(void **state)
static void test_api_bbfdm_library_set_value(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct param_fault *first_fault;
int fault = 0;
dmcmd("/bin/cp", 2, LIBBBF_TEST_PATH, LIBBBF_TEST_BBFDM_PATH);
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.SSID.1.Enable", "true", NULL);
ctx->in_param = "Device.WiFi.SSID.1.Enable";
ctx->in_value = "true";
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
ctx->in_param = "Device.X_IOPSYS_EU_Syslog.ServerPort";
ctx->in_value = "9856";
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
assert_int_equal(fault, 0);
fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Syslog.ServerPort", "9856", NULL);
assert_int_equal(fault, 0);
first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list);
assert_true(&first_fault->list == &ctx->list_fault_param);
fault = dm_entry_apply(ctx, CMD_SET_VALUE);
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
assert_int_equal(fault, 0);
}
@ -723,7 +729,9 @@ static void test_api_bbfdm_library_add_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.WiFi.SSID.", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID.";
fault = bbf_entry_method(ctx, BBF_ADD_OBJECT);
assert_int_equal(fault, 0);
assert_non_null(ctx->addobj_instance);
@ -735,10 +743,14 @@ static void test_api_bbfdm_library_delete_object(void **state)
struct dmctx *ctx = (struct dmctx *) *state;
int fault = 0;
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID.1.", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID.1.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID.", NULL, NULL);
ctx->in_param = "Device.WiFi.SSID.";
fault = bbf_entry_method(ctx, BBF_DEL_OBJECT);
assert_int_equal(fault, 0);
}
@ -752,17 +764,15 @@ int main(void)
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_empty, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_wrong_object_path, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_wrong_parameter_path, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_object_alias, setup_alias, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_parameter_alias, setup_alias, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_object_alias, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_parameter_alias, setup, teardown_commit),
// Get Name method test cases
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_object, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_parameter, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_dot, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_wrong_object_path, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_without_next_level, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_wrong_next_level, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_parameter_alias, setup_alias, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_parameter_alias, setup, teardown_commit),
// Set Value method test cases
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_object, setup, teardown_revert),
@ -771,7 +781,7 @@ int main(void)
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_wrong_parameter_path, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_non_writable, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_wrong_value, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_alias, setup_alias, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_alias, setup, teardown_commit),
// Add Object method test cases
cmocka_unit_test_setup_teardown(test_api_bbfdm_add_object, setup, teardown_commit),
@ -790,7 +800,6 @@ int main(void)
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_object, setup, teardown_commit),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_wrong_object, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_without_next_level, setup, teardown_revert),
cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_wrong_next_level, setup, teardown_revert),
// Operate method test cases
cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_operate, setup, teardown_commit),
@ -830,5 +839,5 @@ int main(void)
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_delete_object, setup, teardown_commit),
};
return cmocka_run_group_tests(tests, group_setup, group_teardown);
return cmocka_run_group_tests(tests, NULL, group_teardown);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
config globals 'globals'
option loglevel '1'
option refresh_time '10'
option transaction_timeout '10'

View file

@ -0,0 +1,155 @@
{
"object": "bbfdm",
"methods": [
{
"method": "get",
"args": {
"path": "Device.DeviceInfo.Manufacturer",
"optional": {"format":"raw", "proto":"usp"}
},
"rc": 0
},
{
"method": "get",
"args": {
"path": "Device.DeviceInfo.Manufacturer",
"optional": {"format":"raw", "proto":"cwmp"}
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.Users.User.*.Alias",
"optional": {"format":"raw", "proto":"cwmp"}
},
"rc": 0
},
{
"method": "get",
"args": {
"path": "Device.DeviceInfo.Manufacturer",
"optional": {"format":"raw", "proto":"both"}
},
"rc": 0
},
{
"method": "get",
"args": {
"path": "Device.DeviceInfo.Manufacturer"
},
"rc": 0
},
{
"method": "get",
"args": {
"path": "Device.DeviceInfo.Manufacturer",
"optional": {"format":"raw", "proto":"usp"},
"maxdepth": "1"
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.WiFi.SSID.1.LowerLayers"
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.WiFi.SSID.1.Name"
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.Users.User.*.Alias"
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.USB.USBHosts.Host.*.Device."
},
"rc": 0
},
{
"method": "get",
"args": {
"path":"Device.USB.USBHosts.Host.*.Device."
},
"rc": 0
},
{
"method": "hello",
"rc": 3
},
{
"method": "instances",
"args": {
"path": "Device.Users.User.",
"optional": {"format":"raw", "proto":"usp"}
},
"rc": 0
},
{
"method": "set",
"args": {
"path": "Device.WiFi.SSID.1.SSID",
"value": "test-2g"
},
"rc": 0
},
{
"method": "schema",
"args": {
"path": "Device.Users.User."
},
"rc": 0
},
{
"method": "schema",
"args": {
"path": "Device.DeviceInfo."
},
"rc": 0
},
{
"method": "transaction",
"args": {
"cmd": "commit",
"optional":{"transaction_id":123}
},
"rc": 0
},
{
"method": "transaction",
"args": {
"cmd": "abort",
"optional":{"transaction_id":123}
},
"rc": 0
},
{
"method": "get",
"args": {
"paths": ["Device.WiFi.SSID.1.SSID","Device.WiFi.SSID.2.SSID"],
"proto": "usp"
},
"rc": 0
},
{
"method": "set",
"args": {
"path": "Device.Users.User.1.",
"obj_path": {"Alias":"test", "Enable":"1"},
"optional":{"transaction_id":123}
},
"rc": 0
}
]
}

33
test/python/validate_3536.py Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/python3
import subprocess
import json
TEST_NAME = "BUG_3536"
print("Running: " + TEST_NAME)
def bbf_get(path, proto = ""):
path_arg = "{\"path\":\"" + path + "\", \"optional\":{\"format\":\"raw\", \"proto\":\"" + proto + "\"}}"
cmd = ['ubus', 'call', 'bbfdm', 'get', path_arg]
out = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
return stdout
# check fault code of invalid path
output = json.loads(bbf_get("Device", "usp"))
assert output["results"][0]["fault"] == 7026, "Wrong fault code"
# check fault code of invalid path
output = json.loads(bbf_get("Device", "cwmp"))
assert output["results"][0]["fault"] == 9005, "Wrong fault code for cwmp"
# check fault code of invalid path
output = json.loads(bbf_get("Device"))
assert output["results"][0]["fault"] == 9005, "Wrong fault code for default proto"
print("PASS: " + TEST_NAME)

26
test/python/validate_device.py Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/python3
import ubus
import pathlib
import subprocess
import json
TEST_NAME = "Get Device."
print("Running: " + TEST_NAME)
sock = pathlib.Path('/var/run/ubus/ubus.sock')
if sock.exists():
assert ubus.connect('/var/run/ubus/ubus.sock')
else:
assert ubus.connect()
out = ubus.call('bbfdm', 'get', {"path":"Device.", "optional":{"format":"raw"}})
assert isinstance(out[0]["results"][0], dict), "FAIL: get Device. on bbf with raw format"
# Check get operation for Device. path succeed
out = ubus.call('bbfdm', 'get', {"path":"Device."})
assert isinstance(out[0]['Device'], dict), "FAIL: get Device. on bbf with pretty format"
ubus.disconnect()
print("PASS: " + TEST_NAME)

View file

@ -0,0 +1,40 @@
#!/usr/bin/python3
import ubus
import json
import pathlib
TEST_NAME = "Validate fault on invalid transaction id with bbf"
print("Running: " + TEST_NAME)
def fault_wrong_transaction(cmd, param, efault):
out = ubus.call("bbfdm", cmd, param)
assert out[0]['results'][0]['fault'] == efault, "FAIL: for " + cmd + str(param) + " output " + str(out)
sock = pathlib.Path('/var/run/ubus/ubus.sock')
if sock.exists ():
assert ubus.connect('/var/run/ubus/ubus.sock')
else:
assert ubus.connect()
fault_wrong_transaction("set", {"path":"Device.Users.User.1.Username", "value":"abc", "optional":{"format":"raw", "transaction_id":1234}}, 7003)
fault_wrong_transaction("set", {"path":"Device.Users.User.1.Username", "value":"abc", "optional":{"format":"raw", "proto":"usp", "transaction_id":1234}}, 7003)
fault_wrong_transaction("set", {"path":"Device.Users.User.1.Username", "value":"abc", "optional":{"format":"raw", "proto":"cwmp", "transaction_id":1234}}, 9002)
fault_wrong_transaction("set", {"path":"Device.Users.User.1.", "obj_path":{"Username":"abc"}, "optional":{"format":"raw", "transaction_id":1234}}, 7003)
fault_wrong_transaction("set", {"path":"Device.Users.User.1.", "obj_path":{"Username":"abc"}, "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003)
fault_wrong_transaction("set", {"path":"Device.Users.User.1.", "obj_path":{"Username":"abc"}, "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002)
fault_wrong_transaction("add", {"path":"Device.Users.User.", "optional":{"format":"raw", "transaction_id":1234}}, 7003)
fault_wrong_transaction("add", {"path":"Device.Users.User.", "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003)
fault_wrong_transaction("add", {"path":"Device.Users.User.", "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002)
fault_wrong_transaction("del", {"path":"Device.Users.User.1", "optional":{"format":"raw", "transaction_id":1234}}, 7003)
fault_wrong_transaction("del", {"path":"Device.Users.User.1", "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003)
fault_wrong_transaction("del", {"path":"Device.Users.User.1", "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002)
ubus.disconnect()
print("PASS: " + TEST_NAME)

View file

@ -0,0 +1,31 @@
#!/usr/bin/python3
import pexpect
import os
print("Running: Schema updater notification validation")
ret = 1
child = pexpect.spawn('ubus monitor')
# force change in schema, by removing dependency uci file
os.rename("/etc/config/users", "/etc/config/users_1")
try:
ret = child.expect('notify', timeout=35)
except:
print("FAIL: Schema updater notification")
if ret == 0:
try:
ret = child.expect('schema_update_available')
except:
print("FAIL: Schema updater notification")
# Revert back uci changes
os.rename("/etc/config/users_1", "/etc/config/users")
if ret == 0:
print("PASS: Schema updater notification")
exit(ret)

20
test/python/validate_serial.py Executable file
View file

@ -0,0 +1,20 @@
#!/usr/bin/python3
import subprocess
import json
TEST_NAME = "Get serial number"
print("Running: " + TEST_NAME)
out = subprocess.Popen(['ubus', 'call', 'bbfdm', 'get', '{"path":"Device.DeviceInfo.SerialNumber", "optional":{"format":"raw"}}'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
jout = json.loads(stdout)
assert jout["results"][0]["data"] == "000000001", "FAIL: serial number mismatch"
print("PASS: " + TEST_NAME)

View file

@ -0,0 +1,30 @@
#!/usr/bin/python3
import ubus
import json
import pathlib
TEST_NAME = "Validate ubus event bbf"
print("Running: " + TEST_NAME)
def callback(event, data):
print("PASS: " + TEST_NAME)
ubus.disconnect()
exit(0)
sock = pathlib.Path('/var/run/ubus/ubus.sock')
if sock.exists ():
assert ubus.connect('/var/run/ubus/ubus.sock')
else:
assert ubus.connect()
ubus.listen(("bbfdm.event", callback))
ubus.call("bbfdm", "notify_event", {"name":"Device.LocalAgent.TransferComplete!", "input":{"param1":"val1", "param2":"val2"}})
ubus.loop()
ubus.disconnect()
print("FAIL: " + TEST_NAME)

Some files were not shown because too many files have changed in this diff Show more