diff --git a/.gitignore b/.gitignore index a3eb481be9940dcaedda0a2e72ca4cba0ce8de0c..7e53e1494086c71d9e197779cfda04cf5d436af0 100644 --- a/.gitignore +++ b/.gitignore @@ -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 - diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 028e766f6a7d3f6dcf3785f117b1f7eeca3de0de..acdec09c2d34ade124918bca732fea0f38b91118 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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,25 +32,27 @@ 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 +run_tools_test: + stage: unit_test + image: iopsys/code-analysis:latest allow_failure: false script: - - "./gitlab-ci/setup.sh" - - "./gitlab-ci/functional-test.sh" + - "./gitlab-ci/tools-test.sh" artifacts: when: always paths: - timestamp.log - - functional-test-coverage.xml + - tools/out/datamodel_default.xml + - tools/out/datamodel_hdm.xml + - tools/out/datamodel.xls -run_functional_api_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" @@ -61,68 +62,51 @@ run_functional_api_test: - timestamp.log - functional-api-test-coverage.xml -run_tools_test: - stage: unit_test - image: iopsys/code-analysis:latest +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/tools-test.sh" + - "./gitlab-ci/install-dependencies.sh" + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/functional-test.sh" artifacts: when: always paths: - timestamp.log - - tools/out/datamodel_default.xml - - tools/out/datamodel_hdm.xml - - tools/out/datamodel.xls + - functional-test-coverage.xml -run_memory_test: - stage: memory_test +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 - - script: - - doxygen Doxyfile - - mv doxygen/html/ public/ - - artifacts: - paths: - - public +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/ - 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index d861d7e861f63b6fa964bf90f19b37183365e6d1..32a4033ce541bb947ef6097843f144e0685d28c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/bbfd/.gitlab-ci.yml b/bbfd/.gitlab-ci.yml deleted file mode 100644 index c1901d0b2299a3ce5acfce21e2ac64c4acf32c49..0000000000000000000000000000000000000000 --- a/bbfd/.gitlab-ci.yml +++ /dev/null @@ -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/ - diff --git a/bbfd/Makefile b/bbfd/Makefile deleted file mode 100644 index f1bf9f9454f9f7098025f5798c13b3f552ae7f42..0000000000000000000000000000000000000000 --- a/bbfd/Makefile +++ /dev/null @@ -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 \; diff --git a/bbfd/add_delete.c b/bbfd/add_delete.c deleted file mode 100644 index 3004e2927d23b9c7514c53b751d3ad85aa2fc7c1..0000000000000000000000000000000000000000 --- a/bbfd/add_delete.c +++ /dev/null @@ -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); -} diff --git a/bbfd/add_delete.h b/bbfd/add_delete.h deleted file mode 100644 index f4fba2629b0d170607dfa5dd94e28b9e424200eb..0000000000000000000000000000000000000000 --- a/bbfd/add_delete.h +++ /dev/null @@ -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 */ diff --git a/bbfd/get.c b/bbfd/get.c deleted file mode 100644 index c24b97efcd5c351536587bcbd4eaa731479d3019..0000000000000000000000000000000000000000 --- a/bbfd/get.c +++ /dev/null @@ -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); -} - diff --git a/bbfd/get.h b/bbfd/get.h deleted file mode 100644 index 67e8fa011329f8beba22eeb25828057af96a7e1d..0000000000000000000000000000000000000000 --- a/bbfd/get.h +++ /dev/null @@ -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 */ diff --git a/bbfd/get_helper.c b/bbfd/get_helper.c deleted file mode 100644 index 98ea18c9f44f842ac769dd56980044b49b513c42..0000000000000000000000000000000000000000 --- a/bbfd/get_helper.c +++ /dev/null @@ -1,2039 +0,0 @@ -/* - * 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 <libbbfdm/dmbbfcommon.h> - -#include "get_helper.h" -#include "common.h" -#include "pretty_print.h" - -// 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; - char app[10]; -} g_current_trans = {.trans_id=0, .timeout_ms=10000}; - -static const char * const operations[] = { - [OPER_EQUAL_EQUAL] = "==", - [OPER_NOT_EQUAL] = "!=", - [OPER_LESS_THAN_EQUAL] = "<=", - [OPER_GREATER_THAN_EQUAL] = ">=", - [OPER_LESS_THAN] = "<", - [OPER_GREATER_THAN] = ">" -}; - -static jmp_buf gs_jump_location; -static bool gs_jump_called_by_bbf = false; -static char g_dm_version[10] = {'\0'}; - -// Common utilities -void set_datamodel_version (char *version) -{ - if(version) - snprintf(g_dm_version, sizeof(g_dm_version), "%s", version); -} - -void print_last_dm_object(void) -{ - char buff[MAX_DM_PATH]; - - dm_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); -} - -// blobmsg result in segfault when null values added -void bb_add_string(struct blob_buf *bb, const char *name, const char *value) -{ - if (value) - blobmsg_add_string(bb, name, value); - else - blobmsg_add_string(bb, name, ""); -} - -void bbf_configure_ubus(struct ubus_context *ctx) -{ - dm_config_ubus(ctx); -} - -void bbf_init(struct dmctx *dm_ctx, int instance) -{ - dm_ctx_init(dm_ctx, instance); -} - -void bbf_cleanup(struct dmctx *dm_ctx) -{ - dm_ctx_clean(dm_ctx); -} - -static void bbf_sub_init(struct dmctx *dm_ctx, char *path); -static void bbf_sub_cleanup(struct dmctx *dm_ctx); - -static void bbf_sub_init(struct dmctx *dm_ctx, char *path) -{ - unsigned int instance = INSTANCE_MODE_NUMBER; - - if (match(path, "[[]+")) { - if (!match(path, GLOB_EXPR)) - instance = INSTANCE_MODE_ALIAS; - } - DEBUG("instance|%u|", instance); - dm_ctx_init_sub(dm_ctx, instance); -} - -static void bbf_sub_cleanup(struct dmctx *dm_ctx) -{ - dm_ctx_clean_sub(dm_ctx); -} - -static bool get_base_path(char *query_path, char *base_path) -{ - bool found; - size_t i, qlen, lastdot, j; - char ch; - - if (base_path == NULL) - return false; - - base_path[0] = '\0'; - - if (strncmp(query_path, ROOT_NODE, DM_STRLEN(ROOT_NODE)) != 0) - return false; - - lastdot = 6; - qlen = DM_STRLEN(query_path); - found = false; - for (i = 0; i < qlen; i++) { - switch (query_path[i]) { - case '.': - lastdot = i + 1; - break; - case '[': - if (query_path[i - 1] != '.') - return false; - - for (j = i + 1; j < qlen; j++) { - ch = query_path[j]; - if ((ch == '>') || - (ch == '<') || - (ch == '=')) { - found = true; - break; - } - if (query_path[j] == ']') { - i = j; - break; - } - } - break; - case '*': - if (query_path[i - 1] != '.' && - query_path[i + 1] != '.') - return false; - found = true; - break; - case '+': - case '#': - if (query_path[i - 1] == '.') - return false; - - i = lastdot; - found = true; - break; - } - if (found) - break; - } - - strncpyt(base_path, query_path, i + 1); - return true; -} - -int get_resolved_paths(struct dmctx *bbf_ctx, char *qpath, struct list_head *resolved_paths) -{ - int fault = USP_ERR_OK; - char bpath[MAX_DM_PATH] = {0}; - - if (get_base_path(qpath, bpath)) { - size_t pos = 0; - - pos = DM_STRLEN(bpath); - INFO("Base Path :: |%s| Pos :: |%d|", bpath, pos); - - fault = bbf_dm_get_values(bbf_ctx, bpath); - if (fault == USP_ERR_OK) { - add_path_node(bpath, resolved_paths); - fault = resolve_path(bbf_ctx, qpath, pos, resolved_paths); - } - } else { - INFO("Not able to get base path"); - fault = usp_fault_map(FAULT_9005); - } - - if (fault) - WARNING("qpath(%s), fault(%d)", qpath, fault); - - return fault; -} - -bool get_instance(char *path, size_t start, char *instance) -{ - char *ptr; - size_t plen, path_len; - - if (instance == NULL) - return false; - - path_len = DM_STRLEN(path); - if (path_len <= start) - return false; - - ptr = strchr(path + start, '.'); - - if (ptr == NULL) - return false; - - plen = (size_t)labs(ptr - path) - start; - if (plen > path_len) - return false; - - strncpyt(instance, path + start, plen + 1); - if (strtol(instance, NULL, 10) == 0) { - if (instance[0] != '[') - return false; - } - - return true; -} - -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; -} - -/* This function is not used anywhere but kept for debugging purpose hence suppressed */ -// cppcheck-suppress unusedFunction -bool path_present_in_pvlist(struct list_head *pvlist, char *entry) -{ - struct pvNode *pv; - size_t len; - - len = DM_STRLEN(entry); - list_for_each_entry(pv, pvlist, list) { - if (!strncmp(pv->param, entry, len)) - return true; - } - - return false; -} - -int seperator(char *token, char *para, enum operation *oper, char *value) -{ - char *ptr; - size_t plen; - bool found; - uint8_t i, op_count; - - // handle ==, !=, <=, >= - if (token == NULL || para == NULL || - oper == NULL || value == NULL) - return USP_FAULT_INTERNAL_ERROR; - - found = false; - op_count = ARRAY_SIZE(operations); - for (i = 0; i < op_count; i++) { - ptr = strstr(token, operations[i]); - if (ptr) { - *oper = i; - plen = (size_t)labs(ptr - token); - ptr += DM_STRLEN(operations[i]); - found = true; - break; - } - } - - if (found) { - strncpyt(para, token, plen + 1); - plen = DM_STRLEN(ptr); - strncpyt(value, ptr, plen + 1); - return 0; - } - - return USP_FAULT_INVALID_PATH_SYNTAX; -} - -void add_path_node(char *para, struct list_head *plist) -{ - struct pathNode *node = NULL; - size_t len; - - node = (struct pathNode *) malloc(sizeof(*node)); - - if (!node) { - ERR("Out of memory!"); - return; - } - - len = DM_STRLEN(para); - strncpyt(node->path, para, len + 1); - - INIT_LIST_HEAD(&node->list); - list_add_tail(&node->list, plist); -} - -void add_pv_node(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_path_list(struct list_head *head) -{ - struct pathNode *iter, *node; - - list_for_each_entry_safe(iter, node, head, list) { - list_del(&iter->list); - free(iter); - } -} - -void free_pv_list(struct list_head *head) -{ - struct pvNode *iter, *node; - - list_for_each_entry_safe(iter, node, head, list) { - free(iter->param); - free(iter->val); - free(iter->type); - - list_del(&iter->list); - free(iter); - } -} - -void refresh_path_list(struct list_head *path_list, struct list_head *plist_local) -{ - - struct pathNode *iter; - - free_path_list(path_list); - - list_for_each_entry(iter, plist_local, list) { - add_path_node(iter->path, path_list); - } -} - -static bool handle_uint(char *v1, char *v2, enum operation op, int *fault) -{ - uint32_t ui1, ui2; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - ui1 = (uint32_t) strtoul(v1, NULL, 10); - ui2 = (uint32_t) strtoul(v2, NULL, 10); - - if ((ui1 == 0 && v1[0] != '0') || - (ui2 == 0 && v2[0] != '0')) { - *fault = USP_FAULT_INVALID_TYPE; - return false; - } - - switch (op) { - case OPER_EQUAL_EQUAL: - return (ui1 == ui2); - case OPER_NOT_EQUAL: - return (ui1 != ui2); - case OPER_LESS_THAN: - return (ui1 < ui2); - case OPER_GREATER_THAN: - return (ui1 > ui2); - case OPER_LESS_THAN_EQUAL: - return (ui1 <= ui2); - case OPER_GREATER_THAN_EQUAL: - return (ui1 >= ui2); - } - - return false; -} - -static bool handle_int(char *v1, char *v2, enum operation op, int *fault) -{ - int32_t i1, i2; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - i1 = (int32_t) strtol(v1, NULL, 10); - i2 = (int32_t) strtol(v2, NULL, 10); - - if ((i1 == 0 && v1[0] != '0') || - (i2 == 0 && v2[0] != '0')) { - *fault = USP_FAULT_INVALID_TYPE; - return false; - } - - switch (op) { - case OPER_EQUAL_EQUAL: - return (i1 == i2); - case OPER_NOT_EQUAL: - return (i1 != i2); - case OPER_LESS_THAN: - return (i1 < i2); - case OPER_GREATER_THAN: - return (i1 > i2); - case OPER_LESS_THAN_EQUAL: - return (i1 <= i2); - case OPER_GREATER_THAN_EQUAL: - return (i1 >= i2); - } - - return false; -} - -static bool handle_unlong(char *v1, char *v2, enum operation op, int *fault) -{ - uint64_t ul1, ul2; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - ul1 = (uint64_t) strtoll(v1, NULL, 10); - ul2 = (uint64_t) strtoll(v2, NULL, 10); - - if ((ul1 == 0 && v1[0] != '0') || - (ul2 == 0 && v2[0] != '0')) { - *fault = USP_FAULT_INVALID_TYPE; - return false; - } - - switch (op) { - case OPER_EQUAL_EQUAL: - return (ul1 == ul2); - case OPER_NOT_EQUAL: - return (ul1 != ul2); - case OPER_LESS_THAN: - return (ul1 < ul2); - case OPER_GREATER_THAN: - return (ul1 > ul2); - case OPER_LESS_THAN_EQUAL: - return (ul1 <= ul2); - case OPER_GREATER_THAN_EQUAL: - return (ul1 >= ul2); - } - - return false; -} - -static bool handle_long(char *v1, char *v2, enum operation op, int *fault) -{ - int64_t l1, l2; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - l1 = (int64_t) strtoll(v1, NULL, 10); - l2 = (int64_t) strtoll(v2, NULL, 10); - - if ((l1 == 0 && v1[0] != '0') || - (l2 == 0 && v2[0] != '0')) { - *fault = USP_FAULT_INVALID_TYPE; - return false; - } - - switch (op) { - case OPER_EQUAL_EQUAL: - return (l1 == l2); - case OPER_NOT_EQUAL: - return (l1 != l2); - case OPER_LESS_THAN: - return (l1 < l2); - case OPER_GREATER_THAN: - return (l1 > l2); - case OPER_LESS_THAN_EQUAL: - return (l1 <= l2); - case OPER_GREATER_THAN_EQUAL: - return (l1 >= l2); - } - - return false; -} - -static bool handle_bool(char *v1, char *v2, enum operation op, int *fault) -{ - bool vb1, vb2; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - vb1 = get_boolean_string(v1); - vb2 = get_boolean_string(v2); - - switch (op) { - case OPER_EQUAL_EQUAL: - return (vb1 == vb2); - case OPER_NOT_EQUAL: - return (vb1 != vb2); - case OPER_LESS_THAN: - case OPER_GREATER_THAN: - case OPER_LESS_THAN_EQUAL: - case OPER_GREATER_THAN_EQUAL: - *fault = USP_FAULT_INVALID_PATH_SYNTAX; - return false; - } - - return false; -} - -static bool handle_time(char *v1, char *v2, enum operation op, const int *fault) -{ - struct tm tm1, tm2; - char *tmp; - time_t t1, t2; - double sec; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) - return false; - - memset(&tm1, 0, sizeof(t1)); - memset(&tm2, 0, sizeof(t2)); - - tmp = strptime(v1, "%Y-%m-%dT%H:%M:%S", &tm1); - if (tmp == NULL) - return USP_FAULT_INVALID_TYPE; - - tmp = strptime(v2, "%Y-%m-%dT%H:%M:%S", &tm2); - if (tmp == NULL) - return USP_FAULT_INVALID_TYPE; - - t1 = timegm(&tm1); - t2 = timegm(&tm2); - - sec = difftime(t1, t2); - switch (op) { - case OPER_EQUAL_EQUAL: - return (sec == 0); - case OPER_NOT_EQUAL: - return (sec != 0); - case OPER_LESS_THAN: - return (sec < 0); - case OPER_GREATER_THAN: - return (sec > 0); - case OPER_LESS_THAN_EQUAL: - return (sec <= 0); - case OPER_GREATER_THAN_EQUAL: - return (sec >= 0); - } - - return false; -} - -static bool handle_hexbin(const char *v1, const char *v2, - enum operation op __attribute__((unused)), - int *fault) -{ - if (v1 == NULL || v2 == NULL) - return false; - - *fault = USP_FAULT_INVALID_PATH_SYNTAX; - return false; -} - -void handle_special_escape_sequence(char *value, char *buff, size_t buff_len) -{ - size_t i, len, j; - - if (buff == NULL) - return; - - len = DM_STRLEN(value); - j = 0; - for (i = 0; i < len && j < buff_len-1; ++i) { - if (value[i] == '%' && len > i + 2) { - if (value[i + 1] == '2') { - if (value[i + 2] == '5') { - buff[j++] = '%'; - i += 2; - continue; - } else if (value[i + 2] == '2') { - buff[j++] = '"'; - i += 2; - continue; - } - } - } - buff[j++] = value[i]; - } - buff[j] = '\0'; - - DEBUG("value(%s), new_value(%s)", value, buff); -} - -static bool handle_string(char *v1, char *v2, enum operation op, int *fault) -{ - char temp[MAX_DM_VALUE]; - - if (!fault) - return false; - - if (v1 == NULL || v2 == NULL) { - return false; - } - - int v2_len = DM_STRLEN(v2); - if (v2_len == 0) { - *fault = USP_FAULT_INVALID_PATH_SYNTAX; - return false; - } - - if (v2[0] != '"' || v2[v2_len - 1] != '"') { - *fault = USP_FAULT_INVALID_PATH_SYNTAX; - return false; - } - - // Check for %22 and %25 special escape sequences - char buff[MAX_DM_VALUE] = {0}; - handle_special_escape_sequence(v2, buff, MAX_DM_VALUE); - - snprintf(temp, MAX_DM_VALUE, "\"%s\"", v1); - switch (op) { - case OPER_EQUAL_EQUAL: - return !strcmp(temp, buff); - case OPER_NOT_EQUAL: - return !!strcmp(temp, buff); - case OPER_LESS_THAN: - case OPER_GREATER_THAN: - case OPER_LESS_THAN_EQUAL: - case OPER_GREATER_THAN_EQUAL: - *fault = USP_FAULT_INVALID_PATH_SYNTAX; - return false; - } - - return false; -} - -static bool check_values(char *val_type, char *val1, char *val2, enum operation oper, int *fault) -{ - bool result = false; - - DEBUG("type(%s), val1(%s), Val2(%s), Oper(%d)", val_type, val1, val2, oper); - switch (get_dm_type(val_type)) { - case DMT_STRING: - result = handle_string(val1, val2, oper, fault); - break; - case DMT_UNINT: - result = handle_uint(val1, val2, oper, fault); - break; - case DMT_INT: - result = handle_int(val1, val2, oper, fault); - break; - case DMT_UNLONG: - result = handle_unlong(val1, val2, oper, fault); - break; - case DMT_LONG: - result = handle_long(val1, val2, oper, fault); - break; - case DMT_BOOL: - result = handle_bool(val1, val2, oper, fault); - break; - case DMT_TIME: - result = handle_time(val1, val2, oper, fault); - break; - case DMT_HEXBIN: - result = handle_hexbin(val1, val2, oper, fault); - break; - } - - return result; -} - -bool match_bbf_value(char *path, char *value, enum operation op, int *fault) -{ - bool ret; - struct dm_parameter *n; - struct dmctx sub_ctx; - - - if (path == NULL || value == NULL || fault == NULL) - return false; - - DEBUG("path(%s)", path); - - memset(&sub_ctx, 0, sizeof(struct dmctx)); - bbf_sub_init(&sub_ctx, path); - - *fault = bbf_dm_get_values(&sub_ctx, path); - if (*fault) { - bbf_sub_cleanup(&sub_ctx); - ERR("Fault form bbf_get_value : |0x%x| ", fault); - return false; - } - - ret = false; - list_for_each_entry(n, &sub_ctx.list_parameter, list) { - ret = check_values(n->type, n->data, value, op, fault); - if (ret) - break; - - if (*fault != USP_ERR_OK) - break; - } - - bbf_sub_cleanup(&sub_ctx); - return ret; -} - -bool split_reference_info(char *para, char *refer, char *ref_num_str, char *ref_param) -{ - char *ptr; - uint8_t index; - bool found; - size_t len, i; - - if (para == NULL || refer == NULL || ref_num_str == NULL || ref_param == NULL) - return false; - - len = DM_STRLEN(para); - found = false; - ptr = refer; - index = 0; - ref_num_str[0] = '\0'; - ref_param[0] = '\0'; - refer[0] = '\0'; - for (i = 0; i < len; i++) { - if (index >= len) - return false; - - if (para[i] == '#') { - found = true; - ptr[index] = '\0'; - index = 0; - ptr = ref_num_str; - } else if (para[i] == '+') { - ptr[index] = '\0'; - index = 0; - ptr = ref_param; - } else { - ptr[index++] = para[i]; - } - } - ptr[index] = '\0'; - if (found) { - if (ref_num_str[0] != '*' && strtol(ref_num_str, NULL, 10) == 0) - return false; - - size_t ref_num_str_len = DM_STRLEN(ref_num_str); - if (ref_num_str_len > 3) - return false; - } - - if (ref_param[0] != '.') - return false; - - return true; -} - -static int _get_ref_from_path(char *path, char *num, char *ref) -{ - long ref_num, count; - char *token, *save; - - ref[0] = '\0'; - ref_num = strtol(num, NULL, 10); - if (ref_num == 0) - return USP_FAULT_INVALID_PATH_SYNTAX; - - token = strtok_r(path, DM_VALUE_SEP, &save); - count = 0; - while (token) { - count++; - if (ref_num == count) - break; - token = strtok_r(NULL, DM_VALUE_SEP, &save); - } - if (ref_num > count) - return USP_FAULT_INVALID_PATH_SYNTAX; - - if (token) { - size_t len = DM_STRLEN(token); - strncpyt(ref, token, len + 1); - } - - return USP_ERR_OK; -} - -int handle_reference(char *bPath, struct list_head *pv_list, char *para, - enum operation oper, char *val, struct list_head *resolved_plist) -{ - char temp[MAX_DM_PATH+MAX_DM_KEY_LEN]; - int fault = 0; - size_t len; - char refer[MAX_DM_KEY_LEN], ref_num_str[MAX_DM_KEY_LEN] = {0}, ref_param[MAX_DM_KEY_LEN]; - bool found; - struct pvNode *pv; - char *token, *save; - struct pathNode *iter; - - // parameter will be in order para (SSIDReference#n+.SSID) value("MyHome") - found = split_reference_info(para, refer, ref_num_str, ref_param); - if (found == false) - return USP_FAULT_INVALID_PATH_SYNTAX; - - len = DM_STRLEN(bPath); - if (list_empty(resolved_plist)) { - list_for_each_entry(pv, pv_list, list) { - char inst[MAX_DM_KEY_LEN]; - - if (strncmp(pv->param, bPath, len) != 0) - continue; - - if (get_instance(pv->param, len, inst) == false) - continue; - - snprintf(temp, MAX_DM_PATH, "%s%s.%s", bPath, inst, refer); - if (strcmp(pv->param, temp) != 0) - continue; - - if (ref_num_str[0] == '*') { - found = true; - token = strtok_r(pv->val, DM_VALUE_SEP, &save); - while (token) { - snprintf(temp, MAX_DM_PATH, "%s.%s", token, &ref_param[1]); - if (match_bbf_value(temp, val, oper, &fault) == false) { - if (fault != 0) - return fault; - - found = false; - break; - } - snprintf(temp, MAX_DM_PATH, "%s%s.", bPath, inst); - token = strtok_r(NULL, DM_VALUE_SEP, &save); - } - - if (found) - add_path_node(temp, resolved_plist); // Resolved List - - continue; - } - - char buff[MAX_DM_PATH+MAX_DM_KEY_LEN+MAX_DM_KEY_LEN] = {0}; - if (DM_STRLEN(ref_num_str)) { - fault = _get_ref_from_path(pv->val, ref_num_str, temp); - if (fault) - return fault; - - snprintf(buff, sizeof(buff), "%s.%s", temp, &ref_param[1]); - } else { - snprintf(buff, sizeof(buff), "%s.%s", pv->val, &ref_param[1]); - } - - if (match_bbf_value(buff, val, oper, &fault)) { - snprintf(buff, sizeof(buff), "%s%s.", bPath, inst); - add_path_node(buff, resolved_plist); // Resolved List - } else { - if (fault != 0) - return fault; - } - } - } else { - struct pathNode *node; - - list_for_each_entry_safe(iter, node, resolved_plist, list) { - snprintf(temp, sizeof(temp), "%s%s", iter->path, refer); - - found = false; - list_for_each_entry(pv, pv_list, list) { - if (strcmp(pv->param, temp) == 0) { - found = true; - break; - } - } - - if (found == false) - return USP_FAULT_INVALID_PATH_SYNTAX; - - if (ref_num_str[0] == '*') { - token = strtok_r(pv->val, DM_VALUE_SEP, &save); - while (token) { - snprintf(temp, MAX_DM_PATH, "%s.%s", token, &ref_param[1]); - if (match_bbf_value(temp, val, oper, &fault) == false) { - list_del(&iter->list); - free(iter); - if (fault != 0) - return fault; - } - token = strtok_r(NULL, DM_VALUE_SEP, &save); - } - continue; - } - - char buff[MAX_DM_PATH+MAX_DM_KEY_LEN+MAX_DM_KEY_LEN] = {0}; - if (DM_STRLEN(ref_num_str)) { - fault = _get_ref_from_path(pv->val, ref_num_str, temp); - if (fault) - return fault; - - snprintf(buff, sizeof(buff), "%s%s", temp, &ref_param[1]); - } else { - snprintf(buff, sizeof(buff), "%s.%s", pv->val, &ref_param[1]); - } - - if (match_bbf_value(buff, val, oper, &fault) == false) { - list_del(&iter->list); - free(iter); - if (fault != 0) - return fault; - } - } - } - - return 0; -} - -int search_n_apply(char *bPath, char *para, enum operation oper, char *value, - struct list_head *fltrd, struct list_head *resolved_plist) -{ - char temp[MAX_DM_PATH] = {0}; - struct pvNode *pv; - size_t blen; - int fault = USP_ERR_OK; - - blen = DM_STRLEN(bPath); - if (match(para, "[+]+")) - return handle_reference(bPath, fltrd, para, oper, value, resolved_plist); - - if (!list_empty(resolved_plist)) { - struct pathNode *iter, *node; - - list_for_each_entry_safe(iter, node, resolved_plist, list) { - bool is_present = false; - - snprintf(temp, MAX_DM_PATH, "%s%s", iter->path, para); - - list_for_each_entry(pv, fltrd, list) { - if (strcmp(pv->param, temp) == 0) { - is_present = true; - break; - } - } - - if (!is_present) { - list_del(&iter->list); - free(iter); - continue; - } - - if (check_values(pv->type, pv->val, value, oper, &fault) == false) { - list_del(&iter->list); - free(iter); - if (fault != USP_ERR_OK) - return fault; - } - } - } else { - list_for_each_entry(pv, fltrd, list) { - char inst[MAX_DM_KEY_LEN]; - - if (strncmp(pv->param, bPath, blen) != 0) - continue; - - if (get_instance(pv->param, blen, inst) == false) - continue; - - snprintf(temp, MAX_DM_PATH, "%s%s.%s", bPath, inst, para); - - if (strcmp(pv->param, temp) != 0) - continue; - - if (check_values(pv->type, pv->val, value, oper, &fault)) { - snprintf(temp, MAX_DM_PATH, "%s%s.", bPath, inst); - add_path_node(temp, resolved_plist); // Resolved List - } else { - if (fault) - return fault; - } - } - } - - return fault; -} - -static int solve_all_filters(struct dmctx *bbf_ctx, char *bPath, char *param, struct list_head *resolved_plist) -{ - int ret = 0; - char *token, *save; - struct dm_parameter *n; - size_t blen; - - LIST_HEAD(pv_local); - LIST_HEAD(plist_local); - - INFO("## Basepath(%s), param(%s)", bPath, param); - // Use shorter list for rest of the operation - blen = DM_STRLEN(bPath); - list_for_each_entry(n, &bbf_ctx->list_parameter, list) { - if (strncmp(n->name, bPath, blen) == 0) - add_pv_node(n->name, n->data, n->type, &pv_local); - } - - token = strtok_r(param, "&&", &save); - while (token) { - enum operation oper; - char para[MAX_DM_KEY_LEN] = {0}; - char value[MAX_DM_VALUE] = {0}; - - ret = seperator(token, para, &oper, value); - if (ret != 0) - break; - - INFO("Filter Para(%s), oper(%d), Val(%s)", para, oper, value); - if (match(para, "[*]+")) - ret = USP_FAULT_INVALID_TYPE; - else - ret = search_n_apply(bPath, para, oper, value, &pv_local, &plist_local); - - if (ret != 0) - break; - - if (list_empty(&plist_local)) - break; - - token = strtok_r(NULL, "&&", &save); - } - - //dump_resolved_list(&plist_local); - if (ret == 0) { - struct pathNode *iter; - - list_for_each_entry(iter, &plist_local, list) { - add_path_node(iter->path, resolved_plist); - } - } - - free_path_list(&plist_local); - free_pv_list(&pv_local); - return ret; -} - -// Will fill param with only the Dot seperated_token -bool get_next_param(char *qPath, size_t *pos, char *param) -{ - size_t qlen, i; - bool found; - - if (qPath == NULL || pos == NULL || param == NULL) - return false; - - qlen = DM_STRLEN(qPath); - if (*pos >= qlen || *pos >= MAX_DM_PATH || qlen >= MAX_DM_PATH) - return false; - - param[0] = '\0'; - found = false; - for (i = *pos; i < qlen; i++) { - switch (qPath[i]) { - case '[': - while (i < qlen) { - if (qPath[++i] == ']') - break; - } - if (qPath[++i] != '.') { - ERR("No dot after search parameters"); - return false; - } - // skip the dot - i++; - found = true; - break; - case '.': - i++; - found = true; - break; - case '+': - case '#': - i = qlen; - found = true; - break; - } - if (found) - break; - } - if (i == qlen) - strncpyt(param, qPath + *pos, i - *pos + 1); - else - strncpyt(param, qPath + *pos, i - *pos); - - *pos = i; - - // removing last . from param - qlen = DM_STRLEN(param); - if (qlen > 0) { - if (param[qlen - 1] == '.') - param[qlen - 1] = '\0'; - } - - if (param[0] == '*') { - size_t param_len = DM_STRLEN(param); - if (param_len > 1) { - ERR("* followed by other characters(%s)", param); - return false; - } - - // * is not followed by . - if (qPath[*pos - 1] != '.') { - ERR("* not followed by dot(%c)", qPath[*pos - 1]); - return false; - } - } - - return true; -} - -static int append_all_instances(char *bPath, struct list_head *plist_local) -{ - int fault = USP_ERR_OK; - char temp[MAX_DM_PATH]; - struct dmctx sub_ctx; - struct dm_parameter *n; - - memset(&sub_ctx, 0, sizeof(struct dmctx)); - bbf_sub_init(&sub_ctx, bPath); - - fault = bbf_dm_get_instances(&sub_ctx, bPath, "1"); - list_for_each_entry(n, &sub_ctx.list_parameter, list) { - temp[0] = '\0'; - - // Add . - snprintf(temp, MAX_DM_PATH, "%s.", n->name); - add_path_node(temp, plist_local); - } - - bbf_sub_cleanup(&sub_ctx); - return fault; -} - -static int follow_ref(struct dmctx *bbf_ctx, char *bPath, char *param, - struct list_head *plist_local) -{ - char temp[MAX_DM_VALUE]; - char refer[MAX_DM_KEY_LEN], ref_num_str[MAX_DM_KEY_LEN], ref_param[MAX_DM_KEY_LEN]; - bool found; - int fault; - struct dm_parameter *n; - uint8_t ref_num, count; - char *token, *save; - - DEBUG("bpath(%s), param(%s)", bPath, param); - - found = split_reference_info(param, refer, ref_num_str, ref_param); - if (found == false) - return USP_FAULT_INVALID_PATH_SYNTAX; - - DEBUG("re(%s), num(%s), ref_param(%s)", refer, ref_num_str, ref_param); - snprintf(temp, sizeof(temp), "%s%s", bPath, refer); - - found = false; - list_for_each_entry(n, &bbf_ctx->list_parameter, list) { - if (strcmp(n->name, temp) == 0) { - found = true; - break; - } - } - - if (found == false) - return USP_FAULT_INVALID_PATH_SYNTAX; - - if (get_dm_type(n->type) != DMT_STRING) - return USP_FAULT_INVALID_VALUE; - - // all references - if (ref_num_str[0] == '*') { - token = strtok_r(n->data, DM_VALUE_SEP, &save); - while (token) { - snprintf(temp, sizeof(temp), "%s.%s", token, &ref_param[1]); - DEBUG("## Getting dm * (%s)", temp); - fault = bbf_dm_get_values(bbf_ctx, temp); - if (fault) { - ERR("Fault form bbf_get_value : |0x%x| ", fault); - return fault; - } - add_path_node(temp, plist_local); - token = strtok_r(NULL, DM_VALUE_SEP, &save); - } - return USP_ERR_OK; - } - - ref_num = (uint8_t) strtoul(ref_num_str, NULL, 10); - count = 0; - if (ref_num) { - token = strtok_r(n->data, DM_VALUE_SEP, &save); - while (token) { - count++; - if (count == ref_num) { - break; - } - token = strtok_r(NULL, DM_VALUE_SEP, &save); - } - if (ref_num > count) - return USP_FAULT_UNSUPPORTED_PARAM; - if (token) { - snprintf(temp, sizeof(temp), "%s.%s", token, &ref_param[1]); - } - } else { - size_t ref_num_str_len = DM_STRLEN(ref_num_str); - if (ref_num_str_len != 0) - return USP_FAULT_INVALID_PATH_SYNTAX; - - snprintf(temp, sizeof(temp), "%s.%s", n->data, &ref_param[1]); - } - - INFO("## Getting dm pv for (%s)", temp); - fault = bbf_dm_get_values(bbf_ctx, temp); - if (fault) { - ERR("Fault form bbf_get_value : |0x%x| ", fault); - return fault; - } - add_path_node(temp, plist_local); - - return 0; -} - -static bool is_present_in_datamodel(struct dmctx *bbf_ctx, char *path) -{ - bool found = false; - struct dm_parameter *n; - size_t plen; - - DEBUG("path(%s)", path); - plen = DM_STRLEN(path); - list_for_each_entry(n, &bbf_ctx->list_parameter, list) { - if (strncmp(n->name, path, plen) == 0) { - found = true; - break; - } - } - - return found; -} - -int resolve_path(struct dmctx *bbf_ctx, char *qPath, size_t pos, struct list_head *resolved_plist) -{ - char temp[MAX_DM_PATH + 5] = {0}; - char param[MAX_DM_PATH] = {0}; - size_t plen; - struct pathNode *ptr; - int fault; - bool check = true; - size_t start; - bool non_leaf = false; - - LIST_HEAD(plist_local); - - start = pos; - size_t qPath_len = DM_STRLEN(qPath); - if (start >= qPath_len) - return 0; - - if (list_empty(resolved_plist)) - return 0; - - INFO("Entry Len :: %d & qPath :: %s", start, qPath); - - if (strchr(qPath+start, '.') != NULL) - non_leaf = true; - - if (get_next_param(qPath, &start, param) == false) - return USP_FAULT_INVALID_PATH_SYNTAX; - - plen = DM_STRLEN(param); - DEBUG("PARAM ::(%s) pos ::(%d)", param, start); - - fault = 0; - list_for_each_entry(ptr, resolved_plist, list) { - size_t len = DM_STRLEN(ptr->path); - if (len == 0) - continue; - - snprintf(temp, sizeof(temp), "%s%s", ptr->path, (ptr->path[len - 1] != '.') ? "." : ""); - - if (param[0] == '[') { - param[plen-1] = 0; - fault = solve_all_filters(bbf_ctx, temp, param+1, &plist_local); - } else if (param[0] == '*') { - fault = append_all_instances(temp, &plist_local); - } else if (match(param, "[+]+")) { - fault = follow_ref(bbf_ctx, temp, param, &plist_local); - } else { - char buff[MAX_DM_VALUE] = {0}; - if (non_leaf) - snprintf(buff, sizeof(buff), "%s%s.", temp, param); - else - snprintf(buff, sizeof(buff), "%s%s", temp, param); - - check = is_present_in_datamodel(bbf_ctx, buff); - if (check) - add_path_node(buff, &plist_local); - } - if (fault) { - free_path_list(&plist_local); - return fault; - } - } - - if (check == false && list_empty(&plist_local)) { - free_path_list(&plist_local); - return usp_fault_map(FAULT_9005); - } - - refresh_path_list(resolved_plist, &plist_local); - free_path_list(&plist_local); - - return resolve_path(bbf_ctx, qPath, start, resolved_plist); -} - -static int usp_dm_exec(struct dmctx *bbf_ctx, int cmd, char *path, char *arg1, char *arg2) -{ - int fault = 0; - - if (path == NULL) - return USP_FAULT_INTERNAL_ERROR; - - if (sigsetjmp(gs_jump_location, 1) == 0) { - gs_jump_called_by_bbf = true; - fault = dm_entry_param_method(bbf_ctx, cmd, path, arg1, arg2); - } else { - ERR("PID [%ld]::Exception on [%d => %s]", getpid(), cmd, path); - print_last_dm_object(); - fault = USP_FAULT_INTERNAL_ERROR; - } - - gs_jump_called_by_bbf = false; - - if (fault) - WARNING("Fault [%d => %d => %s]", fault, cmd, path); - - return fault; -} - -int usp_dm_exec_apply(struct dmctx *bbf_ctx, int cmd) -{ - int fault = 0; - - if (sigsetjmp(gs_jump_location, 1) == 0) { - gs_jump_called_by_bbf = true; - fault = dm_entry_apply(bbf_ctx, cmd); - } else { - ERR("PID [%ld]::Exception on [%d] apply", getpid(), cmd); - print_last_dm_object(); - fault = USP_FAULT_INTERNAL_ERROR; - } - - gs_jump_called_by_bbf = false; - - return fault; -} - -int usp_dm_set(struct dmctx *dm_ctx, char *path, char *value) -{ - int fault = 0; - - fault = usp_dm_exec(dm_ctx, CMD_SET_VALUE, path, value, NULL); - - INFO("path(%s), value(%s), fault(%d)", path, value, fault); - - return fault; -} - -int usp_dm_operate(struct blob_buf *bb, char *path, char *input_params, bool raw, int instance) -{ - int fault = 0, ret = 0; - struct dmctx bbf_ctx = {0}; - void *table, *array; - - LIST_HEAD(pv_local); - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - bbf_init(&bbf_ctx, instance); - - ret = usp_dm_exec(&bbf_ctx, CMD_USP_OPERATE, path, input_params, NULL); - 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; - } - - if (ret == CMD_SUCCESS) { - struct dm_parameter *n; - - list_for_each_entry(n, &bbf_ctx.list_parameter, list) { - add_pv_node(n->name, n->data, n->type, &pv_local); - } - } else { - fill_err_code(bb, fault); - } - - bbf_cleanup(&bbf_ctx); - - if (fault != USP_ERR_OK) { - WARNING("Fault(%d) path(%s) input(%s)", fault, path, input_params); - free_pv_list(&pv_local); - return fault; - } - - if (raw) { - struct pvNode *pv; - - array = blobmsg_open_array(bb, "parameters"); - list_for_each_entry(pv, &pv_local, list) { - table = blobmsg_open_table(bb, NULL); - bb_add_string(bb, "parameter", pv->param); - bb_add_string(bb, "value", pv->val); - bb_add_string(bb, "type", pv->type); - blobmsg_close_table(bb, table); - } - blobmsg_close_array(bb, array); - } else { - array = blobmsg_open_array(bb, "result"); - table = blobmsg_open_table(bb, NULL); - prepare_result_blob(bb, &pv_local); - blobmsg_close_table(bb, table); - blobmsg_close_array(bb, array); - } - - free_pv_list(&pv_local); - - return USP_ERR_OK; -} - -int usp_add_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey) -{ - uint32_t fault = 0; - - INFO("Req to add object |%s|", path); - - if (pkey == NULL || pkey[0] == 0) - pkey = "true"; - - fault = (uint32_t)usp_dm_exec(bbf_ctx, CMD_ADD_OBJECT, path, (char *)pkey, NULL); - - bb_add_string(bb, "parameter", path); - if (fault) { - blobmsg_add_u32(bb, "fault", fault); - blobmsg_add_u8(bb, "status", 0); - } else { - if (bbf_ctx->addobj_instance) { - blobmsg_add_u8(bb, "status", 1); - bb_add_string(bb, "instance", bbf_ctx->addobj_instance); - } else { - blobmsg_add_u8(bb, "status", 0); - } - } - - return fault; -} - -int usp_del_object(struct dmctx *bbf_ctx, struct blob_buf *bb, char *path, const char *pkey) -{ - uint32_t fault = 0; - - if (pkey == NULL || pkey[0] == 0) - pkey = "true"; - - fault = (uint32_t)usp_dm_exec(bbf_ctx, CMD_DEL_OBJECT, path, (char *)pkey, NULL); - - bb_add_string(bb, "parameter", path); - if (fault) { - blobmsg_add_u8(bb, "status", 0); - blobmsg_add_u32(bb, "fault", fault); - } else { - blobmsg_add_u8(bb, "status", 1); - } - - return fault; -} - -int bbf_get_blob(usp_data_t *data, struct blob_buf *bb) -{ - int fault = USP_ERR_OK; - struct dmctx dm_ctx; - struct pathNode *pn; - - memset(&dm_ctx, 0, sizeof(struct dmctx)); - - set_bbfdatamodel_type(data->proto); - - list_for_each_entry(pn, data->plist, list) { - char *path = pn->path; - size_t plen = DM_STRLEN(path); - if (plen == 0) - continue; - - bbf_init(&dm_ctx, data->instance); - DEBUG("Entry path |%s|", path); - fault = usp_dm_exec(&dm_ctx, data->dm_cmd, pn->path, data->next_level, NULL); - if (!fault) { - void *t = NULL; - size_t poff = 0; - struct dm_parameter *n; - - if (path[plen - 1] == '.') { - t = blobmsg_open_table(bb, path); - poff = plen; - } - - // cppcheck-suppress unknownMacro - list_for_each_entry(n, &dm_ctx.list_parameter, list) - bb_add_string(bb, n->name + poff, n->data); - - if (t) - blobmsg_close_table(bb, t); - } else { - bb_add_string(bb, "path", path); - blobmsg_add_u32(bb, "fault", (uint32_t)fault); - } - bbf_cleanup(&dm_ctx); - } - - return fault; -} - -int bbf_get_raw(usp_data_t *data, struct blob_buf *bb) -{ - int fault = USP_ERR_OK; - struct dmctx dm_ctx; - struct pathNode *pn; - - memset(&dm_ctx, 0, sizeof(struct dmctx)); - - set_bbfdatamodel_type(data->proto); - - list_for_each_entry(pn, data->plist, list) { - void *table; - char *path = pn->path; - - INFO("Entry path |%s|", path); - bbf_init(&dm_ctx, data->instance); - fault = usp_dm_exec(&dm_ctx, data->dm_cmd, path, data->next_level, NULL); - if (!fault) { - struct dm_parameter *n; - - list_for_each_entry(n, &dm_ctx.list_parameter, list) { - 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 { - table = blobmsg_open_table(bb, NULL); - bb_add_string(bb, "parameter", path); - blobmsg_add_u32(bb, "fault", (uint32_t)fault); - blobmsg_close_table(bb, table); - } - bbf_cleanup(&dm_ctx); - } - - return fault; -} - -static void fill_operate_schema(struct blob_buf *bb, struct dm_parameter *param) -{ - blobmsg_add_string(bb, "parameter",param->name); - blobmsg_add_string(bb,"type",param->type); - blobmsg_add_string(bb,"cmd_type",param->additional_data); - if(param->data) { - void *array; - const char **in, **out; - operation_args *args; - int i; - - args = (operation_args *) param->data; - in = args->in; - if (in) { - array = blobmsg_open_array(bb, "in"); - for (i = 0; in[i] != NULL; i++) - blobmsg_add_string(bb, NULL, in[i]); - - blobmsg_close_array(bb, array); - } - - out = args->out; - if (out) { - array = blobmsg_open_array(bb, "out"); - for (i = 0; out[i] != NULL; i++) - blobmsg_add_string(bb, NULL, out[i]); - - blobmsg_close_array(bb, array); - } - } -} - -static void fill_event_schema(struct blob_buf *bb, struct dm_parameter *param) -{ - blobmsg_add_string(bb, "parameter",param->name); - blobmsg_add_string(bb,"type",param->type); - if(param->data) { - event_args *ev; - - ev = (event_args *)param->data; - - if (ev->param) { - const char **in = ev->param; - void *key = blobmsg_open_array(bb, "in"); - - for (int i = 0; in[i] != NULL; i++) - blobmsg_add_string(bb, NULL, in[i]); - blobmsg_close_array(bb, key); - } - } -} - -static void fill_param_schema(struct blob_buf *bb, struct dm_parameter *param) -{ - blobmsg_add_string(bb, "parameter",param->name); - if(param->data) - blobmsg_add_string(bb,"writable",param->data); - else - blobmsg_add_string(bb,"writable","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, "unique_keys"); - - for (int i = 0; uniq_keys[i] != NULL; i++) - blobmsg_add_string(bb, NULL, uniq_keys[i]); - - blobmsg_close_array(bb, key); - } -} - -int bbf_dm_get_supported_dm(struct blob_buf *bb, char *path, bool first_level, int schema_type) -{ - int fault=0; - struct dmctx bbf_ctx; - struct dm_parameter *param; - - memset(&bbf_ctx,0 ,sizeof(struct dmctx)); - - set_bbfdatamodel_type(BBFDM_USP); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - - fault = dm_get_supported_dm(&bbf_ctx, path, first_level, schema_type); - if(fault) { - blobmsg_add_u32(bb, "fault", fault); - bbf_cleanup(&bbf_ctx); - return fault; - } - - void *array = blobmsg_open_array(bb,"parameters"); - - list_for_each_entry(param, &bbf_ctx.list_parameter, list) { - int cmd = get_dm_type(param->type); - - void *table = blobmsg_open_table(bb,NULL); - if (cmd == DMT_COMMAND) { - fill_operate_schema(bb, param); - } else if (cmd == DMT_EVENT) { - fill_event_schema(bb, param); - } else { - fill_param_schema(bb, param); - } - - blobmsg_close_table(bb, table); - } - blobmsg_close_array(bb, array); - - bbf_cleanup(&bbf_ctx); - - return fault; -} - -bool bbf_dm_event_registered(char *ename) -{ - bool ret = false; - struct dmctx bbf_ctx; - struct dm_parameter *param; - - memset(&bbf_ctx,0 ,sizeof(struct dmctx)); - set_bbfdatamodel_type(BBFDM_USP); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - - dm_get_supported_dm(&bbf_ctx, ROOT_NODE, false, EVENT_ONLY); - list_for_each_entry(param, &bbf_ctx.list_parameter, list) { - if (strcmp(param->name, ename) == 0) { - ret = true; - break; - } - } - - bbf_cleanup(&bbf_ctx); - - return ret; -} - -int bbf_dm_get_schema(struct blob_buf *bb) -{ - int fault = 0; - struct dmctx bbf_ctx; - struct dm_parameter *n; - void *array; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - - set_bbfdatamodel_type(BBFDM_USP); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - - fault = usp_dm_exec(&bbf_ctx, CMD_GET_SCHEMA, ROOT_NODE, NULL, NULL); - if (fault) { - bbf_cleanup(&bbf_ctx); - return fault; - } - - 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); - if (n->data) - blobmsg_add_string(bb, "writable", n->data); - else - blobmsg_add_string(bb, "writable", "0"); - - blobmsg_add_string(bb, "type", n->type); - - if (n->additional_data) { - const char **uniq_keys = (const char **)n->additional_data; - void *key = blobmsg_open_array(bb, "unique_keys"); - - for (int i = 0; uniq_keys[i] != NULL; i++) - blobmsg_add_string(bb, NULL, uniq_keys[i]); - - blobmsg_close_array(bb, key); - } - blobmsg_close_table(bb, table); - } - blobmsg_close_array(bb, array); - - bbf_cleanup(&bbf_ctx); - - return fault; -} - -int bbf_dm_get_values(struct dmctx *bbf_ctx, char *path) -{ - int fault = 0; - - fault = usp_dm_exec(bbf_ctx, CMD_GET_VALUE, path, NULL, NULL); - - return fault; -} - -int bbf_dm_get_instances(struct dmctx *bbf_ctx, char *path, char *next) -{ - int fault = 0; - - fault = usp_dm_exec(bbf_ctx, CMD_GET_INSTANCES, path, next, NULL); - - return fault; -} - -int bbf_dm_get_names(struct dmctx *bbf_ctx, char *path, char *next) -{ - int fault = 0; - - fault = usp_dm_exec(bbf_ctx, CMD_GET_NAME, path, next, NULL); - - return fault; -} - -int bbf_dm_list_operate(struct dmctx *bbf_ctx) -{ - int fault = 0; - - fault = usp_dm_exec(bbf_ctx, CMD_USP_LIST_OPERATE, ROOT_NODE, NULL, NULL); - - return fault; -} - -bool get_granural_object_paths(struct list_head *path_list, uint8_t maxdepth) -{ - uint8_t count; - int fault; - struct dmctx bbf_ctx; - struct dm_parameter *n; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - - set_bbfdatamodel_type(BBFDM_BOTH); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - - fault = bbf_dm_get_names(&bbf_ctx, ROOT_NODE, "0"); - list_for_each_entry(n, &bbf_ctx.list_parameter, list) { - if (strcmp(n->type, "xsd:object") == 0) { - count = count_delim(n->name); - if (count < maxdepth) - add_path_node(n->name, path_list); - } - } - - bbf_cleanup(&bbf_ctx); - - if (fault) - return false; - - return true; -} - -void fill_err_code(struct blob_buf *bb, int fault) -{ - int f; - - f = usp_fault_map(fault); - if (bb && fault) - blobmsg_add_u32(bb, "fault", f); -} - -void fill_resolve_err(struct blob_buf *bb, char *spath, int fault) -{ - int f; - void *array, *table; - - f = usp_fault_map(fault); - array = blobmsg_open_array(bb, "parameters"); - table = blobmsg_open_table(bb, NULL); - blobmsg_add_string(bb, "parameter", spath); - blobmsg_add_u8(bb, "status", false); - blobmsg_add_u32(bb, "fault", f); - blobmsg_close_table(bb, table); - blobmsg_close_array(bb, array); -} - -static void transaction_timeout_handler(struct uloop_timeout *t __attribute__((unused))) -{ - INFO("Transaction timeout called"); - transaction_abort(g_current_trans.trans_id); -} - -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(const char *app, 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; - } else { - timeout = g_current_trans.timeout_ms; - } - ret = get_random_id(); - g_current_trans.trans_id = ret; - strncpyt(g_current_trans.app, app, 10); - 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 fill_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, "app", g_current_trans.app); - blobmsg_add_string(bb, "status", "on-going"); - blobmsg_add_u32(bb, "remaining_time", rem); - } 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) -{ - bool ret = false; - - if (trans_id == 0) - return false; - - ret = (trans_id == g_current_trans.trans_id); - - return ret; -} - -int transaction_commit(int trans_id, struct blob_buf *bp_service_list, bool is_service_restart) -{ - struct dmctx bbf_ctx; - int ret = -1; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - if (is_transaction_valid(trans_id)) { - uloop_timeout_cancel(&g_current_trans.trans_timeout); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - g_current_trans.app[0] = '\0'; - g_current_trans.trans_id = 0; - - if (is_service_restart == false && bp_service_list != NULL) { - INFO("Deffer restart services"); - dm_entry_manage_services(bp_service_list, is_service_restart); - } else { - INFO("Commit on-going transaction"); - dm_entry_restart_services(); - } - - bbf_cleanup(&bbf_ctx); - - ret = 0; - } else { - WARNING("Trans id mismatch(%d)", trans_id); - } - - return ret; -} - -int transaction_abort(int trans_id) -{ - struct dmctx bbf_ctx; - int ret = -1; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - if (is_transaction_valid(trans_id)) { - INFO("Abort on-going transaction"); - uloop_timeout_cancel(&g_current_trans.trans_timeout); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - g_current_trans.trans_id = 0; - g_current_trans.app[0] = '\0'; - dm_entry_revert_changes(); - bbf_cleanup(&bbf_ctx); - - 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; -} diff --git a/bbfd/get_helper.h b/bbfd/get_helper.h deleted file mode 100644 index 159adb2425e278b9f915415df04291376d0b36e1..0000000000000000000000000000000000000000 --- a/bbfd/get_helper.h +++ /dev/null @@ -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 */ diff --git a/bbfd/operate.c b/bbfd/operate.c deleted file mode 100644 index 59e5c68c8b57d39152af12bad07fe9b7e488ea1e..0000000000000000000000000000000000000000 --- a/bbfd/operate.c +++ /dev/null @@ -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); -} diff --git a/bbfd/set.c b/bbfd/set.c deleted file mode 100644 index 59acfb5fd86a27f8f1c176a4fa2207aab4edb978..0000000000000000000000000000000000000000 --- a/bbfd/set.c +++ /dev/null @@ -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; -} diff --git a/bbfd/set.h b/bbfd/set.h deleted file mode 100644 index c149d3dbb12ce7bc2b64bbdefc76a76f84e13222..0000000000000000000000000000000000000000 --- a/bbfd/set.h +++ /dev/null @@ -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 */ - diff --git a/bbfd/usp.c b/bbfd/usp.c deleted file mode 100644 index 1bc8540746e56d51f69fa1ccaa23476d69a56a0b..0000000000000000000000000000000000000000 --- a/bbfd/usp.c +++ /dev/null @@ -1,1686 +0,0 @@ -/* - * usp.c: USP deamon - * - * Copyright (C) 2021 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 - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <libubox/blobmsg.h> -#include <libubox/uloop.h> -#include <libubus.h> -#include <sys/prctl.h> - -#include <libbbfdm/dmbbfcommon.h> - -#include "usp.h" -#include "set.h" -#include "get.h" -#include "get_helper.h" -#include "operate.h" -#include "add_delete.h" -#include "ipc.h" -#include "events.h" -#include "pretty_print.h" -#include "get_helper.h" - -#define INSTANCE_UPDATE_TIMEOUT (25 * 1000) - -static void periodic_instance_updater(struct uloop_timeout *t); - -// Global variables -static unsigned int g_refresh_time = INSTANCE_UPDATE_TIMEOUT; -static int g_subprocess_level = USP_SUBPROCESS_DEPTH; -static int uspd_start_deferred(usp_data_t *data, - void (*EXEC_CB)(usp_data_t *data, void *output)); - -void signal_init(); - -static unsigned int get_refresh_time(void) -{ - char *temp = NULL; - - get_uci_option_string("uspd", "usp", "refresh_time", &temp); - if (temp) { - unsigned int refresh_time = (unsigned int) strtoul(temp, NULL, 10); - free(temp); - return (refresh_time * 1000); - } - - return INSTANCE_UPDATE_TIMEOUT; -} - -// In case of granular objects, Concatenate relative path to ubus object -// path must be of size PATH_MAX -static void get_path_from_gran_obj(char *path, const char *obj_name, struct blob_attr *blob) -{ - if (strncmp(obj_name, USPEXT, DM_STRLEN(USPEXT)) == 0) { - snprintf(path, PATH_MAX, "%s%s", obj_name + USP_EXT_LEN, - (char *)blobmsg_data(blob)); - } else { - snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(blob)); - } -} - -static void add_ubus_obj(void *obj, struct list_head *o_list) -{ - struct obNode *node = NULL; - - node = (struct obNode *) malloc(sizeof(*node)); - - if (!node) { - ERR("Out of memory!"); - return; - } - - node->obj = obj; - - INIT_LIST_HEAD(&node->list); - list_add_tail(&node->list, o_list); -} - -static void free_ubus_obj_list(struct list_head *head) -{ - struct obNode *iter = NULL, *node = NULL; - - list_for_each_entry_safe(iter, node, head, list) { - char *name = (char *) iter->obj->name; - struct ubus_object_type *type = iter->obj->type; - - free(iter->obj); - list_del(&iter->list); - free(type); - free(iter); - free(name); - } -} - -static int get_bbf_proto_type(struct blob_attr *proto) -{ - int type; - - if (proto) { - const char *val = blobmsg_get_string(proto); - - if (is_str_eq("cwmp", val)) - type = BBFDM_CWMP; - else if (is_str_eq("usp", val)) - type = BBFDM_USP; - else - type = BBFDM_BOTH; - } else { - type = BBFDM_BOTH; - } - - set_bbfdatamodel_type(type); - return type; -} - -static int get_instance_mode(struct blob_attr *ins) -{ - int instance_mode = INSTANCE_MODE_NUMBER; - - if (ins) - instance_mode = blobmsg_get_u32(ins); - - if (instance_mode > INSTANCE_MODE_ALIAS) - instance_mode = INSTANCE_MODE_NUMBER; - - return instance_mode; -} - -static const struct blobmsg_policy dm_getm_policy[] = { - [DM_GET_SAFE_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY }, - [DM_GET_SAFE_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_GET_SAFE_NXT_LVL] = { .name = "next-level", .type = BLOBMSG_TYPE_INT8 }, - [DM_GET_SAFE_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, -}; - -int get_multi(struct ubus_context *ctx, - struct ubus_object *obj, - struct ubus_request_data *req, - struct blob_attr *msg, - int bbf_cmd) -{ - struct blob_attr *tb[__DM_GET_SAFE_MAX]; - struct blob_attr *paths; - struct blob_attr *path; - char *nxt_lvl = "0"; - size_t rem; - usp_data_t data; - LIST_HEAD(paths_list); - - memset(&data, 0, sizeof(usp_data_t)); - blobmsg_parse(dm_getm_policy, __DM_GET_SAFE_MAX, - tb, blob_data(msg), blob_len(msg)); - - paths = tb[DM_GET_SAFE_PATHS]; - if (paths == NULL) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[DM_GET_SAFE_NXT_LVL]) { - if (blobmsg_get_u8(tb[DM_GET_SAFE_NXT_LVL])) - nxt_lvl = "1"; - } - - - blobmsg_for_each_attr(path, paths, rem) { - char *path_str = blobmsg_get_string(path); - - add_path_node(path_str, &paths_list); - } - - - data.ctx = ctx; - data.req = req; - data.proto = get_bbf_proto_type(tb[DM_GET_SAFE_PROTO]); - data.is_raw = is_str_eq(obj->name, USPRAW); - data.next_level = nxt_lvl; - data.plist = &paths_list; - data.dm_cmd = bbf_cmd; - data.instance = get_instance_mode(tb[DM_GET_SAFE_INSTANCE]); - - set_bbfdatamodel_type(data.proto); - - get_mpath(&data); - - free_path_list(&paths_list); - - return 0; -} - -int usp_getm_values(struct ubus_context *ctx, - struct ubus_object *obj, - struct ubus_request_data *req, - __attribute__((unused)) const char *method, - struct blob_attr *msg) -{ - return get_multi(ctx, obj, req, msg, CMD_GET_VALUE); -} - -int usp_getm_names(struct ubus_context *ctx, - struct ubus_object *obj, - struct ubus_request_data *req, - __attribute__((unused)) const char *method, - struct blob_attr *msg) -{ - return get_multi(ctx, obj, req, msg, CMD_GET_NAME); -} - -static const struct blobmsg_policy dm_add_policy[] = { - [DM_ADD_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_ADD_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_ADD_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, -}; - -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) -{ - struct blob_attr *tb[__DM_ADD_MAX]; - char path[PATH_MAX]; - struct blob_buf bb = {}; - usp_data_t data; - int trans_id; - - if (blobmsg_parse(dm_add_policy, __DM_ADD_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!(tb[DM_ADD_PATH])) - return UBUS_STATUS_INVALID_ARGUMENT; - - memset(&data, 0, sizeof(usp_data_t)); - data.ctx = ctx; - data.proto = get_bbf_proto_type(tb[DM_ADD_PROTO]); - data.is_raw = is_str_eq(obj->name, USPRAW); - set_bbfdatamodel_type(data.proto); - - get_path_from_gran_obj(path, obj->name, tb[DM_ADD_PATH]); - - data.qpath = path; - - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - - data.instance = get_instance_mode(tb[DM_ADD_INSTANCE]); - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - // for non-raw objects start a transaction internally and commit - trans_id = transaction_start("internal", 0); - if (trans_id) { - data.trans_id = trans_id; - if (is_str_eq(method, "add_object")) - create_add_response(&data, &bb); - else if (is_str_eq(method, "del_object")) - create_del_response(&data, &bb); - - transaction_commit(trans_id, NULL, true); - } else { - WARNING("Failed to get the lock for the transaction"); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - } - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -static const struct blobmsg_policy dm_raw_add_policy[] = { - [DM_RAW_ADD_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_RAW_ADD_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_RAW_ADD_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, - [DM_RAW_ADD_TRANS_ID] = { .name = "transaction_id", .type = BLOBMSG_TYPE_INT32 }, -}; - -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) -{ - struct blob_attr *tb[__DM_RAW_ADD_MAX]; - char path[PATH_MAX]; - struct blob_buf bb = {}; - usp_data_t data; - size_t len; - - if (blobmsg_parse(dm_raw_add_policy, __DM_RAW_ADD_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[DM_RAW_ADD_PATH] || !tb[DM_RAW_ADD_TRANS_ID]) - return UBUS_STATUS_INVALID_ARGUMENT; - - memset(&bb, 0, sizeof(struct blob_buf)); - memset(&data, 0, sizeof(usp_data_t)); - data.ctx = ctx; - data.proto = get_bbf_proto_type(tb[DM_RAW_ADD_PROTO]); - data.is_raw = is_str_eq(obj->name, USPRAW); - data.trans_id = blobmsg_get_u32(tb[DM_RAW_ADD_TRANS_ID]); - set_bbfdatamodel_type(data.proto); - - // no need to process it further since transaction is not valid - if (!is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - blob_buf_init(&bb, 0); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; - } - - get_path_from_gran_obj(path, obj->name, tb[DM_RAW_ADD_PATH]); - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - - len = DM_STRLEN(path); - if (len == 0) { - WARNING("Path len is 0"); - blob_buf_init(&bb, 0); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; - } - - if (path[len - 1] != DELIM) { - path[len] = DELIM; - path[len + 1] = '\0'; - } - - data.qpath = path; - - data.instance = get_instance_mode(tb[DM_RAW_ADD_INSTANCE]); - blob_buf_init(&bb, 0); - - if (is_str_eq(method, "add_object")) - create_add_response(&data, &bb); - else if (is_str_eq(method, "del_object")) - create_del_response(&data, &bb); - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -static bool is_subprocess_required(const char *path) -{ - bool ret = false; - size_t len = DM_STRLEN(path); - if (len == 0) - return ret; - - if (count_delim(path) < g_subprocess_level) { - if (path[len - 1] == '.') - ret = true; - } - - return ret; -} - -static const struct blobmsg_policy dm_get_policy[] = { - [DM_GET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_GET_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_GET_MAXDEPTH] = { .name = "maxdepth", .type = BLOBMSG_TYPE_INT32 }, - [DM_GET_NXT_LVL] = { .name = "next-level", .type = BLOBMSG_TYPE_INT8 }, - [DM_GET_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, -}; - -static const struct blobmsg_policy get_supported_dm_policy[] = { - [DM_SUPPORTED_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_SUPPORTED_NXT_LEVEL] = { .name = "next-level", .type = BLOBMSG_TYPE_INT8}, - [DM_SUPPORTED_SCHEMA_TYPE] = { .name = "schema_type", .type = BLOBMSG_TYPE_INT32}, -}; - -int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method __attribute__((unused)), - struct blob_attr *msg) -{ - struct blob_attr *tb[__DM_GET_MAX]; - usp_data_t data; - const bool raw = is_str_eq(obj->name, USPRAW); - char path[PATH_MAX]; - uint8_t maxdepth = 0; - char *nxt_lvl_str = "0"; - - if (blobmsg_parse(dm_get_policy, __DM_GET_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!(tb[DM_GET_PATH])) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[DM_GET_MAXDEPTH]) - maxdepth = blobmsg_get_u32(tb[DM_GET_MAXDEPTH]); - - if (tb[DM_GET_NXT_LVL]) - nxt_lvl_str = blobmsg_get_u8(tb[DM_GET_NXT_LVL]) ? "1" : "0"; - - get_path_from_gran_obj(path, obj->name, tb[DM_GET_PATH]); - - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - memset(&data, 0, sizeof(usp_data_t)); - - data.ctx = ctx; - data.req = req; - data.qpath = path; - data.proto = get_bbf_proto_type(tb[DM_GET_PROTO]); - data.is_raw = raw; - data.depth = maxdepth; - data.next_level = nxt_lvl_str; - data.instance = get_instance_mode(tb[DM_GET_INSTANCE]); - set_bbfdatamodel_type(data.proto); - - if (is_str_eq(method, "get")) { - if (is_subprocess_required(path)) { - INFO("Creating subprocess for get (%s)", path); - uspd_start_deferred(&data, usp_get_value_async); - } else { - usp_get_value(&data); - } - } else if (is_str_eq(method, "object_names")) { - usp_get_name(&data); - } else if (is_str_eq(method, "instances")) { - usp_get_instance(&data); - } else if (is_str_eq(method, "validate")) { - usp_validate_path(&data); - } else { - ERR("method(%s) not defined", method); - } - - return 0; -} - -static const struct blobmsg_policy dm_set_policy[] = { - [DM_SET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_SET_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING }, - [DM_SET_VALUE_TABLE] = { .name = "values", .type = BLOBMSG_TYPE_TABLE }, - [DM_SET_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_SET_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, -}; - -int usp_set(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_buf bb = {}; - struct blob_attr *tb[__DM_SET_MAX] = {NULL}; - char path[PATH_MAX] = {'\0'}; - usp_data_t data; - int fault = USP_ERR_OK; - struct list_head pv_list; - int trans_id = 0; - - INIT_LIST_HEAD(&pv_list); - - memset(&bb, 0, sizeof(struct blob_buf)); - memset(&data, 0, sizeof(usp_data_t)); - - if (blobmsg_parse(dm_set_policy, __DM_SET_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[DM_SET_PATH]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (!tb[DM_SET_VALUE] && !tb[DM_SET_VALUE_TABLE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - get_path_from_gran_obj(path, obj->name, tb[DM_SET_PATH]); - data.proto = get_bbf_proto_type(tb[DM_SET_PROTO]); - data.instance = get_instance_mode(tb[DM_SET_INSTANCE]); - set_bbfdatamodel_type(data.proto); - - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - - // for non-raw objects start a transaction internally and commit afterwards - // if transaction already in-progress return error - trans_id = transaction_start("internal", 0); - if (trans_id == 0) { - WARNING("Failed to get the lock for the transaction"); - blob_buf_init(&bb, 0); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; - } - - fault = fill_pvlist_from_path(path, tb[DM_SET_VALUE], &pv_list, data.instance); - if (fault == USP_ERR_OK) - fault = fill_pvlist_from_table(path, tb[DM_SET_VALUE_TABLE], &pv_list, data.instance); - - if (fault) { - ERR("Fault in set path |%s|", path); - blob_buf_init(&bb, 0); - fill_resolve_err(&bb, path, fault); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - free_pv_list(&pv_list); - transaction_abort(trans_id); - return 0; - } - - data.ctx = ctx; - data.req = req; - data.qpath = path; - data.pv_list = &pv_list; - data.is_raw = is_str_eq(obj->name, USPRAW); - data.trans_id = trans_id; - - usp_set_value(&data); - - free_pv_list(&pv_list); - transaction_commit(trans_id, NULL, true); - - return 0; -} - -static const struct blobmsg_policy dm_raw_set_policy[] = { - [DM_RAW_SET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_RAW_SET_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING }, - [DM_RAW_SET_VALUE_TABLE] = { .name = "values", .type = BLOBMSG_TYPE_TABLE }, - [DM_RAW_SET_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_RAW_SET_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, - [DM_RAW_SET_TRANS_ID] = { .name = "transaction_id", .type = BLOBMSG_TYPE_INT32 }, -}; - -int usp_raw_set(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_buf bb = {}; - struct blob_attr *tb[__DM_RAW_SET_MAX] = {NULL}; - char path[PATH_MAX] = {'\0'}; - usp_data_t data; - int fault = USP_ERR_OK; - struct list_head pv_list; - - INIT_LIST_HEAD(&pv_list); - memset(&bb, 0, sizeof(struct blob_buf)); - memset(&data, 0, sizeof(usp_data_t)); - - if (blobmsg_parse(dm_raw_set_policy, __DM_RAW_SET_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[DM_RAW_SET_PATH] || !tb[DM_RAW_SET_TRANS_ID]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (!tb[DM_RAW_SET_VALUE] && !tb[DM_RAW_SET_VALUE_TABLE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - get_path_from_gran_obj(path, obj->name, tb[DM_RAW_SET_PATH]); - - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - - - data.instance = get_instance_mode(tb[DM_RAW_SET_INSTANCE]); - data.proto = get_bbf_proto_type(tb[DM_RAW_SET_PROTO]); - data.trans_id = blobmsg_get_u32(tb[DM_RAW_SET_TRANS_ID]); - - set_bbfdatamodel_type(data.proto); - - if (!is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - blob_buf_init(&bb, 0); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; - } - - fault = fill_pvlist_from_path(path, tb[DM_RAW_SET_VALUE], &pv_list, data.instance); - if (fault == USP_ERR_OK) - fault = fill_pvlist_from_table(path, tb[DM_RAW_SET_VALUE_TABLE], &pv_list, data.instance); - - if (fault) { - ERR("Fault in raw set path |%s|", path); - blob_buf_init(&bb, 0); - fill_resolve_err(&bb, path, fault); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - free_pv_list(&pv_list); - return 0; - } - - data.ctx = ctx; - data.req = req; - data.qpath = path; - data.pv_list = &pv_list; - data.is_raw = is_str_eq(obj->name, USPRAW); - - usp_set_value(&data); - - free_pv_list(&pv_list); - - return 0; -} -static const struct blobmsg_policy dm_operate_policy[__DM_OPERATE_MAX] = { - [DM_OPERATE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [DM_OPERATE_ACTION] = { .name = "action", .type = BLOBMSG_TYPE_STRING }, - [DM_OPERATE_INPUT] = { .name = "input", .type = BLOBMSG_TYPE_TABLE }, - [DM_OPERATE_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_OPERATE_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, -}; - -static void async_req_free(struct uspd_async_req *r) -{ - free(r); -} - -static void async_complete_cb(struct uloop_process *p, __attribute__((unused)) int ret) -{ - struct uspd_async_req *r = container_of(p, struct uspd_async_req, process); - - if (r) { - INFO("Async call with pid(%d) completes", r->process.pid); - struct blob_buf *bb = (struct blob_buf *)&r->result; - - ubus_send_reply(r->ctx, &r->req, bb->head); - INFO("pid(%d) blob data sent raw(%d)", r->process.pid, blob_raw_len(bb->head)); - ubus_complete_deferred_request(r->ctx, &r->req, 0); - munmap(r->result, DEF_IPC_DATA_LEN); - async_req_free(r); - } - -} - -static struct uspd_async_req *async_req_new(void) -{ - struct uspd_async_req *r = malloc(sizeof(*r)); - - if (r) { - memset(&r->process, 0, sizeof(r->process)); - r->result = NULL; - } - - return r; -} - -static int uspd_start_deferred(usp_data_t *data, - void (*EXEC_CB)(usp_data_t *data, void *d)) -{ - struct uspd_async_req *r = NULL; - pid_t child; - struct usp_context *u; - void *result = NULL; - - result = mmap(NULL, DEF_IPC_DATA_LEN, PROT_READ| PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); - if (result == MAP_FAILED) { - ERR("Error creating memory map for result"); - goto err_out; - } - memset(result, 0, DEF_IPC_DATA_LEN); - r = async_req_new(); - if (r == NULL) { - ERR("Error allocating async req"); - goto err_out; - } - - child = fork(); - if (child == -1) { - ERR("fork error"); - goto err_out; - } else if (child == 0) { - u = container_of(data->ctx, struct usp_context, ubus_ctx); - if (u == NULL) { - ERR("Failed to get the usp context"); - exit(EXIT_FAILURE); - } - - // child initialise signal to prevent segfaults - signal_init(); - /* free fd's and memory inherited from parent */ - ubus_shutdown(data->ctx); - bbf_configure_ubus(NULL); - uloop_done(); - async_req_free(r); - fclose(stdin); - fclose(stdout); - fclose(stderr); - - INFO("Calling from subprocess"); - EXEC_CB(data, result); - if (data->op_input) - free(data->op_input); - - usp_cleanup(u); - closelog(); - /* write result and exit */ - exit(EXIT_SUCCESS); - } - - // parent - INFO("Creating usp(%d) sub process(%d) for path(%s)", getpid(), child, data->qpath); - r->result = result; - r->ctx = data->ctx; - r->process.pid = child; - r->process.cb = async_complete_cb; - uloop_process_add(&r->process); - ubus_defer_request(data->ctx, data->req, &r->req); - return 0; - -err_out: - if (r) - async_req_free(r); - - if (result) - munmap(result, DEF_IPC_DATA_LEN); - - return UBUS_STATUS_UNKNOWN_ERROR; -} - -static bool is_sync_cmd(usp_data_t *data __attribute__((unused))) -{ - - // TODO: Put a check to determine the command type - return false; -} - -int usp_operate(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), - struct ubus_request_data *req, const char *method __attribute__((unused)), - struct blob_attr *msg) -{ - struct blob_attr *tb[__DM_OPERATE_MAX] = {NULL}; - char path[MAX_DM_PATH] = {0}; - char cmd[MAX_DM_KEY_LEN] = {0}; - char *blob_msg = NULL; - usp_data_t data; - - if (blobmsg_parse(dm_operate_policy, __DM_OPERATE_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!(tb[DM_OPERATE_PATH])) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (!(tb[DM_OPERATE_ACTION])) - return UBUS_STATUS_INVALID_ARGUMENT; - - get_path_from_gran_obj(path, obj->name, tb[DM_ADD_PATH]); - blob_msg = blobmsg_data(tb[DM_OPERATE_ACTION]); - strncpyt(cmd, blob_msg, sizeof(cmd)); - INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); - - memset(&data, 0, sizeof(usp_data_t)); - data.ctx = ctx; - data.req = req; - data.qpath = path; - data.op_action = cmd; - data.proto = get_bbf_proto_type(tb[DM_OPERATE_PROTO]); - data.is_raw = is_str_eq(obj->name, USPRAW); - - if (tb[DM_OPERATE_INPUT]) - data.op_input = blobmsg_format_json(tb[DM_OPERATE_INPUT], true); - - if (is_sync_cmd(&data)) { - usp_operate_cmd_sync(&data); - } else { - uspd_start_deferred(&data, usp_operate_cmd_async); - } - - if (data.op_input) - free(data.op_input); - - return 0; -} - -int usp_list_supported_dm(struct ubus_context *actx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method __attribute__((unused)), - struct blob_attr *msg) -{ - struct blob_attr *tb[__DM_SUPPORTED_MAX]; - char path[PATH_MAX] = "Device."; - bool nxt_lvl = false; - uint32_t schema_type = 0; - struct blob_buf bb; - - memset(&bb, 0, sizeof(struct blob_buf)); - - if (blobmsg_parse(get_supported_dm_policy, __DM_SUPPORTED_MAX, tb, blob_data(msg), blob_len(msg)) == 0) { - - if (tb[DM_SUPPORTED_PATH]) - get_path_from_gran_obj(path, obj->name, tb[DM_SUPPORTED_PATH]); - - if (tb[DM_SUPPORTED_NXT_LEVEL]) - nxt_lvl = blobmsg_get_bool(tb[DM_SUPPORTED_NXT_LEVEL]); - - if(tb[DM_SUPPORTED_SCHEMA_TYPE]) - schema_type = blobmsg_get_u32(tb[DM_SUPPORTED_SCHEMA_TYPE]); - } - - INFO("Path:[%s], next:[%d], schema_type:[%u]", path, nxt_lvl, schema_type); - blob_buf_init(&bb, 0); - - bbf_dm_get_supported_dm(&bb, path, nxt_lvl, schema_type); - - ubus_send_reply(actx, req, bb.head); - - blob_buf_free(&bb); - - return 0; -} - -int usp_list_schema(struct ubus_context *actx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg __attribute__((unused))) -{ - struct blob_buf bb; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - INFO("ubus method|%s|, name|%s|", method, obj->name); - bbf_dm_get_schema(&bb); - ubus_send_reply(actx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -int usp_list_operate(struct ubus_context *actx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg __attribute__((unused))) -{ - struct blob_buf bb; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - INFO("ubus method|%s|, name|%s|", method, obj->name); - list_operate_schema(&bb); - ubus_send_reply(actx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -static const struct blobmsg_policy dm_notify_event_policy[] = { - [DM_NOTIFY_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, - [DM_NOTIFY_PRAMS] = { .name = "input", .type = BLOBMSG_TYPE_TABLE }, -}; - -int usp_notify_event(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req __attribute__((unused)), const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__DM_NOTIFY_MAX] = {NULL}; - char *event_name; - - if (blobmsg_parse(dm_notify_event_policy, __DM_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[DM_NOTIFY_NAME]) - return UBUS_STATUS_INVALID_ARGUMENT; - - INFO("ubus method|%s|, name|%s|", method, obj->name); - event_name = blobmsg_get_string(tb[DM_NOTIFY_NAME]); - if (is_registered_event(event_name)) { - ubus_send_event(ctx, "usp.event", msg); - } else { - WARNING("Event %s not registered", event_name); - } - - return 0; -} - -int usp_list_events(struct ubus_context *actx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg __attribute__((unused))) -{ - struct blob_buf bb; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - INFO("ubus method|%s|, name|%s|", method, obj->name); - list_event_schema(&bb); - ubus_send_reply(actx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -static const struct blobmsg_policy dm_set_multi_policy[] = { - [DM_SET_MULTI_TUPLE] = { .name = "pv_tuple", .type = BLOBMSG_TYPE_ARRAY }, - [DM_SET_MULTI_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, - [DM_SET_MULTI_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 }, - [DM_SET_MULTI_TRANS_ID] = { .name = "transaction_id", .type = BLOBMSG_TYPE_INT32 }, -}; - -int handle_set_multi_value(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method __attribute__((unused)), - struct blob_attr *msg) -{ - struct blob_attr *tb[__DM_SET_MULTI_MAX]; - usp_data_t data; - struct list_head pv_list; - struct blob_buf bb; - - memset(&data, 0, sizeof(usp_data_t)); - memset(&bb, 0, sizeof(struct blob_buf)); - blobmsg_parse(dm_set_multi_policy, __DM_SET_MULTI_MAX, tb, - blob_data(msg), blob_len(msg)); - - if (tb[DM_SET_MULTI_TUPLE] == NULL || !tb[DM_SET_MULTI_TRANS_ID]) - return UBUS_STATUS_INVALID_ARGUMENT; - - data.trans_id = blobmsg_get_u32(tb[DM_SET_MULTI_TRANS_ID]); - data.proto = get_bbf_proto_type(tb[DM_SET_MULTI_PROTO]); - - set_bbfdatamodel_type(data.proto); - // no need to process it further since transaction is not valid - if (!is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - blob_buf_init(&bb, 0); - fill_err_code(&bb, USP_FAULT_INTERNAL_ERROR); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; - } - - INIT_LIST_HEAD(&pv_list); - - fill_pvlist_from_tuple(tb[DM_SET_MULTI_TUPLE], &pv_list); - if (list_empty(&pv_list)) { - WARNING("Path value tuple contains invalid paths"); - return UBUS_STATUS_INVALID_ARGUMENT; - } - - data.ctx = ctx; - data.req = req; - data.is_raw = is_str_eq(obj->name, USPRAW); - data.instance = get_instance_mode(tb[DM_SET_MULTI_INSTANCE]); - data.pv_list = &pv_list; - - usp_set_value(&data); - - free_pv_list(&pv_list); - - return 0; -} -static struct ubus_method usp_methods[] = { - UBUS_METHOD_NOARG("list_operate", usp_list_operate), - UBUS_METHOD("get_supported_dm", usp_list_supported_dm, get_supported_dm_policy), - UBUS_METHOD("get", usp_get_handler, dm_get_policy), - UBUS_METHOD("object_names", usp_get_handler, dm_get_policy), - UBUS_METHOD("instances", usp_get_handler, dm_get_policy), - UBUS_METHOD("validate", usp_get_handler, dm_get_policy), - UBUS_METHOD("set", usp_set, dm_set_policy), - UBUS_METHOD("operate", usp_operate, dm_operate_policy), - UBUS_METHOD("add_object", usp_add_del_handler, dm_add_policy), - UBUS_METHOD("del_object", usp_add_del_handler, dm_add_policy), -}; - -enum { - TRANS_ID, - TRANS_APP_NAME = TRANS_ID, - TRANS_TIMEOUT, - __TRANS_MAX, -}; - -static const struct blobmsg_policy trans_policy[] = { - [TRANS_ID] = { .name = "transaction_id", .type = BLOBMSG_TYPE_INT32 }, -}; - -static const struct blobmsg_policy trans_start_policy[] = { - [TRANS_APP_NAME] = { .name = "app", .type = BLOBMSG_TYPE_STRING }, - [TRANS_TIMEOUT] = { .name = "max_timeout", .type = BLOBMSG_TYPE_INT32 }, -}; - -enum { - TRANS_COMMIT_ID, - TRANS_COMMIT_RESTART, - __TRANS_COMMIT_MAX, -}; -static const struct blobmsg_policy trans_commit_policy[] = { - [TRANS_COMMIT_ID] = { .name = "transaction_id", .type = BLOBMSG_TYPE_INT32 }, - [TRANS_COMMIT_RESTART] = { .name = "restart_services", .type = BLOBMSG_TYPE_INT8 }, -}; - -int usp_transaction_commit_handler(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__TRANS_COMMIT_MAX] = {NULL}; - struct blob_buf bb; - int trans_id = 0, ret; - bool is_service_restart = true; - - INFO("ubus method|%s|, name|%s|", method, obj->name); - - if (blobmsg_parse(trans_commit_policy, __TRANS_COMMIT_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[TRANS_COMMIT_ID]) - return UBUS_STATUS_INVALID_ARGUMENT; - - trans_id = blobmsg_get_u32(tb[TRANS_COMMIT_ID]); - - if (tb[TRANS_COMMIT_RESTART]) - is_service_restart = blobmsg_get_bool(tb[TRANS_COMMIT_RESTART]); - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - ret = transaction_commit(trans_id, &bb, is_service_restart); - blobmsg_add_u8(&bb, "status", (ret == 0)); - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -int usp_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__TRANS_MAX] = {NULL}; - struct blob_buf bb; - int trans_id = 0, ret; - const char *app = NULL; - uint32_t max_timeout = 0; - - INFO("ubus method|%s|, name|%s|", method, obj->name); - - if (strcmp(method, "transaction_start") == 0) { - if (blobmsg_parse(trans_start_policy, __TRANS_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[TRANS_APP_NAME]) - return UBUS_STATUS_INVALID_ARGUMENT; - - app = blobmsg_get_string(tb[TRANS_APP_NAME]); - if (tb[TRANS_TIMEOUT]) - max_timeout = blobmsg_get_u32(tb[TRANS_TIMEOUT]); - } else { - if (blobmsg_parse(trans_policy, __TRANS_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[TRANS_ID]) - return UBUS_STATUS_INVALID_ARGUMENT; - - trans_id = blobmsg_get_u32(tb[TRANS_ID]); - } - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - if (strcmp(method, "transaction_start") == 0) { - ret = transaction_start(app, max_timeout); - if (ret) { - blobmsg_add_u8(&bb, "status", true); - blobmsg_add_u32(&bb, "transaction_id", ret); - } else { - blobmsg_add_u8(&bb, "status", false); - } - } else if (strcmp(method, "transaction_abort") == 0) { - ret = transaction_abort(trans_id); - blobmsg_add_u8(&bb, "status", (ret == 0)); - } else if (strcmp(method, "transaction_status") == 0) { - fill_transaction_status(&bb, trans_id); - } else { - WARNING("method(%s) not supported", method); - } - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - return 0; -} - -static struct ubus_method usp_raw_methods[] = { - UBUS_METHOD_NOARG("dump_schema", usp_list_schema), - UBUS_METHOD_NOARG("list_operate", usp_list_operate), - UBUS_METHOD_NOARG("list_events", usp_list_events), - UBUS_METHOD("get_supported_dm", usp_list_supported_dm, get_supported_dm_policy), - UBUS_METHOD("get", usp_get_handler, dm_get_policy), - UBUS_METHOD("getm_values", usp_getm_values, dm_getm_policy), - UBUS_METHOD("getm_names", usp_getm_names, dm_getm_policy), - UBUS_METHOD("object_names", usp_get_handler, dm_get_policy), - UBUS_METHOD("instances", usp_get_handler, dm_get_policy), - UBUS_METHOD("validate", usp_get_handler, dm_get_policy), - UBUS_METHOD("transaction_start", usp_transaction_handler, trans_start_policy), - UBUS_METHOD("set", usp_raw_set, dm_raw_set_policy), - UBUS_METHOD("operate", usp_operate, dm_operate_policy), - UBUS_METHOD("add_object", usp_raw_add_del_handler, dm_raw_add_policy), - UBUS_METHOD("del_object", usp_raw_add_del_handler, dm_raw_add_policy), - UBUS_METHOD("setm_values", handle_set_multi_value, dm_set_multi_policy), - UBUS_METHOD("transaction_commit", usp_transaction_commit_handler, trans_commit_policy), - UBUS_METHOD("transaction_abort", usp_transaction_handler, trans_policy), - UBUS_METHOD("transaction_status", usp_transaction_handler, trans_policy), - UBUS_METHOD("notify_event", usp_notify_event, dm_notify_event_policy), -}; - -static void test_client_subscribe_cb(USP_ATTR_UNUSED struct ubus_context *ctx, - struct ubus_object *obj) -{ - INFO("usp obj_name(%s), active Subscriber[%d]", obj->name, obj->has_subscribers); -} - -static int usp_add_ubus_object(struct usp_context *u, char *name, - struct ubus_method *m, int method_count) -{ - int retval = UBUS_STATUS_OK; - struct ubus_object *obj; - struct ubus_object_type *type; - char *obj_name; - - obj = (struct ubus_object *) calloc(1, sizeof(*obj)); - if (!obj) { - ERR("Out of memory!!"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - type = (struct ubus_object_type *) calloc(1, sizeof(struct ubus_object_type)); - if (!type) { - ERR("Out of memory!!"); - free(obj); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - obj_name = strdup(name); - - type->name = obj_name; - type->id = 0; - type->methods = m; - type->n_methods = method_count; - - obj->name = obj_name; - obj->type = type; - obj->methods = m; - obj->n_methods = method_count; - obj->subscribe_cb = test_client_subscribe_cb; - - retval = ubus_add_object(&u->ubus_ctx, obj); - if (retval) - ERR("Failed to add 'usp' ubus object: %s\n", ubus_strerror(retval)); - - if (strcmp(name, USPRAW) == 0) - u->notify_object = obj; - - add_ubus_obj(obj, &u->obj_list); - - return retval; -} - -static int add_granular_objects(struct usp_context *u, uint8_t gn_level) -{ - int fault; - char obj_path[PATH_MAX]; - struct pathNode *pnode; - int m_num; - - LIST_HEAD(path_list); - - get_granural_object_paths(&path_list, gn_level); - - fault = UBUS_STATUS_OK; - m_num = ARRAY_SIZE(usp_methods); - list_for_each_entry(pnode, &path_list, list) { - snprintf(obj_path, PATH_MAX, "%s.%s", USP, pnode->path); - fault = usp_add_ubus_object(u, obj_path, usp_methods, m_num); - - if (fault != UBUS_STATUS_OK) - break; - } - - free_path_list(&path_list); - - return fault; -} - -static int usp_init(struct usp_context *u) -{ - int ret; - uint8_t gran_level; - char *temp = NULL; - int m_num; - - INFO("Registering ubus objects...."); - - get_uci_option_string("uspd", "usp", "loglevel", &temp); - if (temp) { - uint8_t log_level = (uint8_t) strtoul(temp, NULL, 10); - set_debug_level(log_level); - free(temp); - } - - get_uci_option_string("uspd", "usp", "subprocess_level", &temp); - if (temp) { - g_subprocess_level = (uint8_t) strtoul(temp, NULL, 10); - free(temp); - } - - gran_level = 0; - get_uci_option_string("uspd", "usp", "granularitylevel", &temp); - if (temp) { - gran_level = (uint8_t) strtoul(temp, NULL, 10); - free(temp); - } - if (gran_level > MAX_GRANURALITY_DEPTH) - gran_level = MAX_GRANURALITY_DEPTH; - - get_uci_option_string("uspd", "usp", "bbf_caching_time", &temp); - if (temp) { - uint8_t bbf_cache_time = (uint8_t) strtoul(temp, NULL, 10); - dm_ctx_init_cache(bbf_cache_time); - free(temp); - } - - get_uci_option_string("uspd", "usp", "dm_version", &temp); - if(temp){ - set_datamodel_version(temp); - free (temp); - } - - m_num = ARRAY_SIZE(usp_methods); - ret = usp_add_ubus_object(u, USP, usp_methods, m_num); - if (ret) - return ret; - - m_num = ARRAY_SIZE(usp_raw_methods); - ret = usp_add_ubus_object(u, USPRAW, usp_raw_methods, m_num); - if (ret) - return ret; - - // Get Granularity level of 'uspd' ubus objects - if (gran_level) - ret = add_granular_objects(u, gran_level); - - return ret; -} - -bool usp_pre_init(struct usp_context *u) -{ - bool ret = true; - struct blob_buf bb; - // Initialize ubus ctx for bbf - bbf_configure_ubus(&u->ubus_ctx); - - // Initialize dmmap - init_dmmap(); - - // Initialise blobs - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - if (bbf_dm_get_supported_dm(&bb, ROOT_NODE, 0, 0) != 0) - ret = false; - - u->dm_schema_len = blobmsg_len(bb.head); - blob_buf_free(&bb); - - return ret; -} - -static bool is_object_schema_update_available(struct usp_context *u) -{ - size_t ll, min_len; - bool ret = false; - struct blob_buf bb; - void *table; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - // If new parameter gets added it would be a minimum tuple of three params - table = blobmsg_open_table(&bb, NULL); - blobmsg_add_string(&bb, "parameter", "Device."); - blobmsg_add_string(&bb, "writable", "0"); - blobmsg_add_string(&bb, "type", "xsd:string"); - blobmsg_close_table(&bb, table); - min_len = blobmsg_len(bb.head); - blob_buf_free(&bb); - blob_buf_init(&bb, 0); - - ret = bbf_dm_get_supported_dm(&bb, ROOT_NODE, 0, 0); - if (ret != 0) { - WARNING("Failed to get schema"); - blob_buf_free(&bb); - return ret; - } - - ll = blobmsg_len(bb.head); - if (ll - u->dm_schema_len > min_len) { - ERR("DM Schema update available old:new[%zd:%zd]", u->dm_schema_len, ll); - ret = true; - } - u->dm_schema_len = ll; - blob_buf_free(&bb); - - return ret; -} - -static void periodic_process_updater(void) -{ - struct dmctx bbf_ctx; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - bbf_dm_get_instances(&bbf_ctx, ROOT_NODE"DeviceInfo.ProcessStatus.Process.", "0"); - bbf_cleanup(&bbf_ctx); -} - -static void periodic_schema_updater(struct uloop_timeout *t) -{ - bool ret; - struct usp_context *u; - struct blob_buf bb; - - u = container_of(t, struct usp_context, schema_timer); - if (u == NULL) { - ERR("Failed to get the usp context"); - return; - } - - if (is_transaction_running()) { - DEBUG("Transaction ongoing, schedule schema update timer after %dsec", SCHEMA_UPDATE_TIMEOUT); - u->schema_timer.cb = periodic_schema_updater; - uloop_timeout_set(&u->schema_timer, SCHEMA_UPDATE_TIMEOUT); - return; - } - - memset(&bb, 0, sizeof(struct blob_buf)); - - ret = is_object_schema_update_available(u); - if (ret) { - INFO("Schema update available"); - blob_buf_init(&bb, 0); - blobmsg_add_string(&bb, "action", "schema_update_available"); - ubus_notify(&u->ubus_ctx, u->notify_object, "usp.raw", bb.head, 1000); - blob_buf_free(&bb); - } - - periodic_process_updater(); - - DEBUG("Creating timer for schema update checker(%d) ##", u->notify_object->id); - u->schema_timer.cb = periodic_schema_updater; - uloop_timeout_set(&u->schema_timer, SCHEMA_UPDATE_TIMEOUT); -} - -enum inst_type { - GET_INST_PARMS, - __GET_INST_MAX -}; - -enum param_type { - INST_PARM_NAME, - __INST_PARM_MAX -}; - -const struct blobmsg_policy inst_policy[__GET_INST_MAX] = { - [GET_INST_PARMS] = { .name = "parameters", .type = BLOBMSG_TYPE_ARRAY }, -}; - -const struct blobmsg_policy param_policy[__INST_PARM_MAX] = { - [INST_PARM_NAME] = { .name = "parameter", .type = BLOBMSG_TYPE_STRING }, -}; - -static void broadcast_add_del_event(struct list_head *inst, bool is_add) -{ - struct ubus_context ctx; - struct blob_buf bb; - struct pathNode *ptr; - void *a; - int ret; - - if (list_empty(inst)) { - return; - } - - ret = ubus_connect_ctx(&ctx, NULL); - if (ret != UBUS_STATUS_OK) { - fprintf(stderr, "Failed to connect to ubus\n"); - return; - } - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - a = blobmsg_open_array(&bb, "instances"); - list_for_each_entry(ptr, inst, list) { - blobmsg_add_string(&bb, NULL, ptr->path); - DEBUG("#%s:: %s #", (is_add)?"Add":"Del", ptr->path); - } - blobmsg_close_array(&bb, a); - - if (is_add) - ubus_send_event(&ctx, USP_ADD_EVENT, bb.head); - else - ubus_send_event(&ctx, USP_DEL_EVENT, bb.head); - - blob_buf_free(&bb); - ubus_shutdown(&ctx); -} - -static void update_instances_list(struct list_head *inst) -{ - struct dmctx bbf_ctx; - - memset(&bbf_ctx, 0, sizeof(struct dmctx)); - set_bbfdatamodel_type(BBFDM_USP); - bbf_init(&bbf_ctx, INSTANCE_MODE_NUMBER); - - if (0 == bbf_dm_get_instances(&bbf_ctx, ROOT_NODE, "0")) { - struct dm_parameter *nptr_dp; - - list_for_each_entry(nptr_dp, &bbf_ctx.list_parameter, list) { - add_path_node(nptr_dp->name, inst); - } - } - bbf_cleanup(&bbf_ctx); -} - -static void instance_fork_done(struct uloop_process *p, int ret) -{ - struct uspd_async_req *r = container_of(p, struct uspd_async_req, process); - - if (r) { - INFO("Instance updater(%d) completed, starting a new instance timer", r->process.pid); - struct usp_context *u = (struct usp_context *)r->result; - - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, g_refresh_time); - free_path_list(&u->old_instances); - async_req_free(r); - } - if (ret) { - DEBUG("Instance updater cb failed %d", ret); - } -} - -void instance_compare_publish(struct list_head *new_inst, struct list_head *old_inst) -{ - struct pathNode *ptr; - LIST_HEAD(inst_list); - - list_for_each_entry(ptr, old_inst, list) { - if (!present_in_path_list(new_inst, ptr->path)) { - add_path_node(ptr->path, &inst_list); - } - } - broadcast_add_del_event(&inst_list, false); - free_path_list(&inst_list); - - list_for_each_entry(ptr, new_inst, list) { - if (!present_in_path_list(old_inst, ptr->path)) { - add_path_node(ptr->path, &inst_list); - } - } - broadcast_add_del_event(&inst_list, true); - free_path_list(&inst_list); -} - -static int fork_instance_checker(struct usp_context *u) -{ - struct uspd_async_req *r = NULL; - pid_t child; - - r = async_req_new(); - if (r == NULL) { - ERR("Error allocating instance req"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, g_refresh_time); - free_path_list(&u->old_instances); - goto err_out; - } - child = fork(); - if (child == 0) { - prctl(PR_SET_NAME, (unsigned long) "usp_instance"); - // child initialise signal to prevent segfaults - signal_init(); - /* free fd's and memory inherited from parent */ - ubus_shutdown(&u->ubus_ctx); - bbf_configure_ubus(NULL); - uloop_done(); - async_req_free(r); - fclose(stdin); - fclose(stdout); - fclose(stderr); - - DEBUG("subprocess instances checker"); - instance_compare_publish(&u->instances, &u->old_instances); - usp_cleanup(u); - closelog(); - /* write result and exit */ - exit(EXIT_SUCCESS); - } - - // parent - DEBUG("Creating instance checker process child %d", child); - r->result = u; - r->process.pid = child; - r->process.cb = instance_fork_done; - uloop_process_add(&r->process); - return 0; - -err_out: - if (r) - async_req_free(r); - - return UBUS_STATUS_UNKNOWN_ERROR; -} - -static void periodic_instance_updater(struct uloop_timeout *t) -{ - struct usp_context *u; - - u = container_of(t, struct usp_context, instance_timer); - if (u == NULL) { - ERR("Failed to get the usp context"); - return; - } - - if (is_transaction_running()) { - DEBUG("Transaction ongoing, schedule refresh timer after 1s"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, 1000); - return; - } - - if (list_empty(&u->instances)) { - update_instances_list(&u->instances); - DEBUG("Creating timer for instance update checker, init instances"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, g_refresh_time); - return; - } - - list_splice_init(&u->instances, &u->old_instances); - update_instances_list(&u->instances); - - // fork a process and send it to compare, when process completes - // delete the old instances and add a new timer - fork_instance_checker(u); -} - -bool usp_cleanup(struct usp_context *u) -{ - free_ubus_obj_list(&u->obj_list); - free_path_list(&u->instances); - free_path_list(&u->old_instances); - bbf_dm_cleanup(); - - return true; -} - -void sig_handler(int sig) -{ - if (sig == SIGSEGV) { - handle_pending_signal(sig); - } else if (sig == SIGUSR1) { - print_last_dm_object(); - } -} - -void signal_init() -{ - signal(SIGSEGV, sig_handler); - signal(SIGUSR1, sig_handler); -} - -void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [options]\n", prog); - fprintf(stderr, "\n"); - fprintf(stderr, "options:\n"); - fprintf(stderr, " -s <socket path> ubus socket\n"); - fprintf(stderr, " -t <timeout> Transaction timeout in sec\n"); - fprintf(stderr, "\n"); -} - -int main(int argc, char **argv) -{ - struct usp_context usp_ctx; - const char *ubus_socket = NULL; - int ret = 0, ch; - - while ((ch = getopt(argc, argv, "hs:t:")) != -1) { - switch (ch) { - case 's': - ubus_socket = optarg; - break; - case 't': - configure_transaction_timeout(strtol(optarg, NULL, 10)); - break; - case 'h': - usage(argv[0]); - exit(0); - default: - break; - } - } - - openlog("uspd", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); - - memset(&usp_ctx, 0, sizeof(struct usp_context)); - INIT_LIST_HEAD(&usp_ctx.obj_list); - INIT_LIST_HEAD(&usp_ctx.instances); - INIT_LIST_HEAD(&usp_ctx.old_instances); - INIT_LIST_HEAD(&usp_ctx.event_handlers); - - uloop_init(); - - ret = ubus_connect_ctx(&usp_ctx.ubus_ctx, ubus_socket); - if (ret != UBUS_STATUS_OK) { - fprintf(stderr, "Failed to connect to ubus\n"); - return -1; - } - signal_init(); - - ret = register_events_to_ubus(&usp_ctx.ubus_ctx, &usp_ctx.event_handlers); - if (ret != 0) { - goto exit; - } - - ubus_add_uloop(&usp_ctx.ubus_ctx); - usp_pre_init(&usp_ctx); - - ret = usp_init(&usp_ctx); - if (ret != UBUS_STATUS_OK) { - ret = UBUS_STATUS_UNKNOWN_ERROR; - goto exit; - } - - usp_ctx.schema_timer.cb = periodic_schema_updater; - uloop_timeout_set(&usp_ctx.schema_timer, SCHEMA_UPDATE_TIMEOUT); - - g_refresh_time = get_refresh_time(); - if (g_refresh_time != 0) { - usp_ctx.instance_timer.cb = periodic_instance_updater; - // initial timer should be bigger to give more space to other applications - // to initialize - uloop_timeout_set(&usp_ctx.instance_timer, 3 * g_refresh_time); - } - - INFO("Waiting on uloop...."); - uloop_run(); - -exit: - free_ubus_event_handler(&usp_ctx.ubus_ctx, &usp_ctx.event_handlers); - ubus_shutdown(&usp_ctx.ubus_ctx); - bbf_configure_ubus(NULL); - uloop_done(); - usp_cleanup(&usp_ctx); - closelog(); - - return ret; -} diff --git a/bbfd/usp.h b/bbfd/usp.h deleted file mode 100644 index 03ef3be3c54d8d250d51fc2a072cb3b049538c62..0000000000000000000000000000000000000000 --- a/bbfd/usp.h +++ /dev/null @@ -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 */ diff --git a/bbfd/.gitignore b/bbfdmd/.gitignore similarity index 100% rename from bbfd/.gitignore rename to bbfdmd/.gitignore diff --git a/bbfdmd/src/CMakeLists.txt b/bbfdmd/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a6a362b195f9b558d0b03d3db6b8b3ebf117485b --- /dev/null +++ b/bbfdmd/src/CMakeLists.txt @@ -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) diff --git a/bbfdmd/src/add_delete.c b/bbfdmd/src/add_delete.c new file mode 100644 index 0000000000000000000000000000000000000000..186b3d4aabe0021e98aeadecafdfb289e37c1749 --- /dev/null +++ b/bbfdmd/src/add_delete.c @@ -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); +} diff --git a/bbfdmd/src/add_delete.h b/bbfdmd/src/add_delete.h new file mode 100644 index 0000000000000000000000000000000000000000..4a5ccddea076fc6b9c111da7e82782cb893de11e --- /dev/null +++ b/bbfdmd/src/add_delete.h @@ -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 */ diff --git a/bbfdmd/src/bbfdmd.c b/bbfdmd/src/bbfdmd.c new file mode 100644 index 0000000000000000000000000000000000000000..2f037fa581e93d71d665a24accdf65dd294246ad --- /dev/null +++ b/bbfdmd/src/bbfdmd.c @@ -0,0 +1,1321 @@ +/* + * bbfdmd.c: BBFDMD deamon + * + * 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 <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <libubox/blobmsg.h> +#include <libubox/uloop.h> +#include <libubus.h> +#include <sys/prctl.h> + +#include "bbfdmd.h" +#include "set.h" +#include "get.h" +#include "get_helper.h" +#include "operate.h" +#include "add_delete.h" +#include "ipc.h" +#include "events.h" +#include "pretty_print.h" +#include "get_helper.h" +#include "libbbf_api/dmentry.h" + +#define USP_SUBPROCESS_DEPTH (2) +#define BBF_SCHEMA_UPDATE_TIMEOUT (60 * 1000) +#define BBF_INSTANCES_UPDATE_TIMEOUT (25 * 1000) + +// Global variables +static unsigned int g_refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT; +static int g_subprocess_level = USP_SUBPROCESS_DEPTH; + +static void sig_handler(int sig) +{ + if (sig == SIGSEGV) { + handle_pending_signal(sig); + } else if (sig == SIGUSR1) { + print_last_dm_object(); + } +} + +static void signal_init(void) +{ + signal(SIGSEGV, sig_handler); + signal(SIGUSR1, sig_handler); +} + +static void usage(char *prog) +{ + fprintf(stderr, "Usage: %s [options]\n", prog); + fprintf(stderr, "\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -s <socket path> ubus socket\n"); + fprintf(stderr, " -t <timeout> Transaction timeout in sec\n"); + fprintf(stderr, "\n"); +} + +static void usp_cleanup(struct usp_context *u) +{ + free_path_list(&u->instances); + free_path_list(&u->old_instances); + bbf_global_clean(DM_ROOT_OBJ); +} + +static bool is_sync_operate_cmd(usp_data_t *data __attribute__((unused))) +{ + return false; +} + +static bool is_subprocess_required(const char *path) +{ + bool ret = false; + size_t len = DM_STRLEN(path); + if (len == 0) + return ret; + + if (count_delim(path) < g_subprocess_level) { + if (path[len - 1] == '.') + ret = true; + } + + return ret; +} + +static int get_proto_type(struct blob_attr *proto) +{ + int type = BBFDM_BOTH; + + if (proto) { + const char *val = blobmsg_get_string(proto); + + if (is_str_eq("cwmp", val)) + type = BBFDM_CWMP; + else if (is_str_eq("usp", val)) + type = BBFDM_USP; + else + type = BBFDM_BOTH; + } + + return type; +} + +static int get_instance_mode(struct blob_attr *ins) +{ + int instance_mode = INSTANCE_MODE_NUMBER; + + if (ins) + instance_mode = blobmsg_get_u32(ins); + + if (instance_mode > INSTANCE_MODE_ALIAS) + instance_mode = INSTANCE_MODE_NUMBER; + + return instance_mode; +} + +static void fill_optional_data(usp_data_t *data, struct blob_attr *msg) +{ + struct blob_attr *attr; + size_t rem; + + if (!data || !msg) + return; + + blobmsg_for_each_attr(attr, msg, rem) { + if (is_str_eq(blobmsg_name(attr), "proto")) + data->bbf_ctx.dm_type = get_proto_type(attr); + + if (is_str_eq(blobmsg_name(attr), "instance_mode")) + data->bbf_ctx.instance_mode = get_instance_mode(attr); + + if (is_str_eq(blobmsg_name(attr), "transaction_id")) + data->trans_id = blobmsg_get_u32(attr); + + if (is_str_eq(blobmsg_name(attr), "format")) + data->is_raw = is_str_eq(blobmsg_get_string(attr), "raw") ? true : false; + } + + DEBUG("Proto:|%s|, Inst Mode:|%s|, Tran-id:|%d|, Format:|%s|", + (data->bbf_ctx.dm_type == BBFDM_BOTH) ? "both" : (data->bbf_ctx.dm_type == BBFDM_CWMP) ? "cwmp" : "usp", + (data->bbf_ctx.instance_mode == 0) ? "Number" : "Alias", + data->trans_id, + data->is_raw ? "raw" : "pretty"); +} + +static void async_req_free(struct uspd_async_req *r) +{ + free(r); +} + +static void async_complete_cb(struct uloop_process *p, __attribute__((unused)) int ret) +{ + struct uspd_async_req *r = container_of(p, struct uspd_async_req, process); + + if (r) { + INFO("Async call with pid(%d) completes", r->process.pid); + struct blob_buf *bb = (struct blob_buf *)&r->result; + + ubus_send_reply(r->ctx, &r->req, bb->head); + INFO("pid(%d) blob data sent raw(%d)", r->process.pid, blob_raw_len(bb->head)); + ubus_complete_deferred_request(r->ctx, &r->req, 0); + munmap(r->result, DEF_IPC_DATA_LEN); + async_req_free(r); + } + +} + +static struct uspd_async_req *async_req_new(void) +{ + struct uspd_async_req *r = malloc(sizeof(*r)); + + if (r) { + memset(&r->process, 0, sizeof(r->process)); + r->result = NULL; + } + + return r; +} + +static int uspd_start_deferred(usp_data_t *data, void (*EXEC_CB)(usp_data_t *data, void *d)) +{ + struct uspd_async_req *r = NULL; + pid_t child; + struct usp_context *u; + void *result = NULL; + + result = mmap(NULL, DEF_IPC_DATA_LEN, PROT_READ| PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); + if (result == MAP_FAILED) { + ERR("Error creating memory map for result"); + goto err_out; + } + memset(result, 0, DEF_IPC_DATA_LEN); + r = async_req_new(); + if (r == NULL) { + ERR("Error allocating async req"); + goto err_out; + } + + child = fork(); + if (child == -1) { + ERR("fork error"); + goto err_out; + } else if (child == 0) { + u = container_of(data->ctx, struct usp_context, ubus_ctx); + if (u == NULL) { + ERR("Failed to get the usp context"); + exit(EXIT_FAILURE); + } + + // child initialise signal to prevent segfaults + signal_init(); + /* free fd's and memory inherited from parent */ + ubus_shutdown(data->ctx); + uloop_done(); + async_req_free(r); + fclose(stdin); + fclose(stdout); + fclose(stderr); + + INFO("Calling from subprocess"); + EXEC_CB(data, result); + + usp_cleanup(u); + closelog(); + /* write result and exit */ + exit(EXIT_SUCCESS); + } + + // parent + INFO("Creating usp(%d) sub process(%d) for path(%s)", getpid(), child, data->bbf_ctx.in_param); + r->result = result; + r->ctx = data->ctx; + r->process.pid = child; + r->process.cb = async_complete_cb; + uloop_process_add(&r->process); + ubus_defer_request(data->ctx, data->req, &r->req); + return 0; + +err_out: + if (r) + async_req_free(r); + + if (result) + munmap(result, DEF_IPC_DATA_LEN); + + return UBUS_STATUS_UNKNOWN_ERROR; +} + +static bool is_object_schema_update_available(struct usp_context *u) +{ + size_t ll, min_len; + LIST_HEAD(paths_list); + usp_data_t data = { + .is_raw = true, + .plist = &paths_list, + .bbf_ctx.nextlevel = false, + .bbf_ctx.iscommand = true, + .bbf_ctx.isevent = true, + .bbf_ctx.isinfo = true, + .bbf_ctx.dm_type = BBFDM_USP + }; + + memset(&data.bb, 0, sizeof(struct blob_buf)); + + // If new parameter gets added it would be a minimum tuple of three params + blob_buf_init(&data.bb, 0); + void *array = blobmsg_open_array(&data.bb, "results"); + void *table = blobmsg_open_table(&data.bb, NULL); + blobmsg_add_string(&data.bb, "path", "Device."); + blobmsg_add_string(&data.bb, "data", "0"); + blobmsg_add_string(&data.bb, "type", "xsd:string"); + blobmsg_close_table(&data.bb, table); + blobmsg_close_array(&data.bb, array); + min_len = blobmsg_len(data.bb.head); + blob_buf_free(&data.bb); + + blob_buf_init(&data.bb, 0); + add_path_list(ROOT_NODE, &paths_list); + bool ret = bbf_dm_get_supported_dm(&data); + if (ret != 0) { + WARNING("Failed to get schema"); + blob_buf_free(&data.bb); + free_path_list(&paths_list); + return ret; + } + + ll = blobmsg_len(data.bb.head); + if (ll - u->dm_schema_len > min_len) { + INFO("DM Schema update available old:new[%zd:%zd]", u->dm_schema_len, ll); + ret = true; + } + + u->dm_schema_len = ll; + blob_buf_free(&data.bb); + free_path_list(&paths_list); + + return ret; +} + +static const struct blobmsg_policy dm_get_policy[] = { + [DM_GET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_GET_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY }, + [DM_GET_MAXDEPTH] = { .name = "maxdepth", .type = BLOBMSG_TYPE_INT32 }, + [DM_GET_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE}, +}; + +static int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_GET_MAX]; + LIST_HEAD(paths_list); + usp_data_t data; + uint8_t maxdepth = 0; + bool is_subprocess_needed = false; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_get_policy, __DM_GET_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!(tb[DM_GET_PATH]) && !(tb[DM_GET_PATHS])) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[DM_GET_PATH]) { + char *path = blobmsg_get_string(tb[DM_GET_PATH]); + add_path_list(path, &paths_list); + is_subprocess_needed = is_subprocess_required(path); + } + + if (tb[DM_GET_PATHS]) { + struct blob_attr *paths = tb[DM_GET_PATHS]; + struct blob_attr *path = NULL; + size_t rem; + + blobmsg_for_each_attr(path, paths, rem) { + char *path_str = blobmsg_get_string(path); + + add_path_list(path_str, &paths_list); + if (!is_subprocess_needed) + is_subprocess_needed = is_subprocess_required(path_str); + } + } + + if (tb[DM_GET_MAXDEPTH]) + maxdepth = blobmsg_get_u32(tb[DM_GET_MAXDEPTH]); + + data.ctx = ctx; + data.req = req; + data.plist = &paths_list; + data.depth = maxdepth; + + fill_optional_data(&data, tb[DM_GET_OPTIONAL]); + + if (is_subprocess_needed) { + INFO("Creating subprocess for get method"); + uspd_start_deferred(&data, usp_get_value_async); + } else { + usp_get_value(&data); + } + + free_path_list(&paths_list); + return 0; +} + +static const struct blobmsg_policy dm_schema_policy[] = { + [DM_SCHEMA_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_SCHEMA_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY }, + [DM_SCHEMA_FIRST_LEVEL] = { .name = "first_level", .type = BLOBMSG_TYPE_BOOL}, + [DM_SCHEMA_COMMANDS] = { .name = "commands", .type = BLOBMSG_TYPE_BOOL}, + [DM_SCHEMA_EVENTS] = { .name = "events", .type = BLOBMSG_TYPE_BOOL}, + [DM_SCHEMA_PARAMS] = { .name = "params", .type = BLOBMSG_TYPE_BOOL}, + [DM_SCHEMA_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE}, +}; + +static int usp_schema_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_SCHEMA_MAX]; + LIST_HEAD(paths_list); + usp_data_t data; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_schema_policy, __DM_SCHEMA_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!(tb[DM_SCHEMA_PATH]) && !(tb[DM_SCHEMA_PATHS])) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[DM_SCHEMA_PATH]) { + char *path = blobmsg_get_string(tb[DM_SCHEMA_PATH]); + add_path_list(path, &paths_list); + } + + if (tb[DM_SCHEMA_PATHS]) { + struct blob_attr *paths = tb[DM_GET_PATHS]; + struct blob_attr *path = NULL; + size_t rem; + + blobmsg_for_each_attr(path, paths, rem) { + char *path_str = blobmsg_get_string(path); + + add_path_list(path_str, &paths_list); + } + } + + fill_optional_data(&data, tb[DM_SCHEMA_OPTIONAL]); + + unsigned int dm_type = data.bbf_ctx.dm_type; + + data.bbf_ctx.nextlevel = (tb[DM_SCHEMA_FIRST_LEVEL]) ? blobmsg_get_bool(tb[DM_SCHEMA_FIRST_LEVEL]) : false; + data.bbf_ctx.iscommand = (tb[DM_SCHEMA_COMMANDS]) ? blobmsg_get_bool(tb[DM_SCHEMA_COMMANDS]) : (dm_type == BBFDM_CWMP) ? false : true; + data.bbf_ctx.isevent = (tb[DM_SCHEMA_EVENTS]) ? blobmsg_get_bool(tb[DM_SCHEMA_EVENTS]) : (dm_type == BBFDM_CWMP) ? false : true; + data.bbf_ctx.isinfo = (tb[DM_SCHEMA_PARAMS]) ? blobmsg_get_bool(tb[DM_SCHEMA_PARAMS]) : (dm_type == BBFDM_CWMP) ? false : true; + data.plist = &paths_list; + + blob_buf_init(&data.bb, 0); + + if (dm_type == BBFDM_CWMP) + usp_get_names(&data); + else + bbf_dm_get_supported_dm(&data); + + ubus_send_reply(ctx, req, data.bb.head); + + blob_buf_free(&data.bb); + free_path_list(&paths_list); + return 0; +} + +static const struct blobmsg_policy dm_instances_policy[] = { + [DM_INSTANCES_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_INSTANCES_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY }, + [DM_INSTANCES_FIRST_LEVEL] = { .name = "first_level", .type = BLOBMSG_TYPE_BOOL }, + [DM_INSTANCES_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +static int usp_instances_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_INSTANCES_MAX]; + LIST_HEAD(paths_list); + usp_data_t data; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_instances_policy, __DM_INSTANCES_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!(tb[DM_INSTANCES_PATH]) && !(tb[DM_INSTANCES_PATHS])) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[DM_INSTANCES_PATH]) { + char *path = blobmsg_get_string(tb[DM_INSTANCES_PATH]); + add_path_list(path, &paths_list); + } + + if (tb[DM_INSTANCES_PATHS]) { + struct blob_attr *paths = tb[DM_INSTANCES_PATHS]; + struct blob_attr *path = NULL; + size_t rem; + + blobmsg_for_each_attr(path, paths, rem) { + char *path_str = blobmsg_get_string(path); + + add_path_list(path_str, &paths_list); + } + } + + data.bbf_ctx.nextlevel = (tb[DM_INSTANCES_FIRST_LEVEL]) ? blobmsg_get_bool(tb[DM_INSTANCES_FIRST_LEVEL]) : false; + data.plist = &paths_list; + + fill_optional_data(&data, tb[DM_INSTANCES_OPTIONAL]); + + blob_buf_init(&data.bb, 0); + usp_get_instances(&data); + ubus_send_reply(ctx, req, data.bb.head); + + blob_buf_free(&data.bb); + free_path_list(&paths_list); + return 0; +} + +static const struct blobmsg_policy dm_set_policy[] = { + [DM_SET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_SET_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING }, + [DM_SET_OBJ_PATH] = { .name = "obj_path", .type = BLOBMSG_TYPE_TABLE }, + [DM_SET_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +int usp_set_handler(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_SET_MAX] = {NULL}; + char path[PATH_MAX] = {'\0'}; + usp_data_t data; + int fault = USP_ERR_OK; + int trans_id = 0; + LIST_HEAD(pv_list); + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_set_policy, __DM_SET_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!tb[DM_SET_PATH]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (!tb[DM_SET_VALUE] && !tb[DM_SET_OBJ_PATH]) + return UBUS_STATUS_INVALID_ARGUMENT; + + snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[DM_SET_PATH])); + + fill_optional_data(&data, tb[DM_SET_OPTIONAL]); + + INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, path); + + data.bbf_ctx.in_param = path; + + fault = fill_pvlist_set(path, tb[DM_SET_VALUE] ? blobmsg_get_string(tb[DM_SET_VALUE]) : NULL, tb[DM_SET_OBJ_PATH], &pv_list); + if (fault) { + ERR("Fault in fill pvlist set path |%s|", data.bbf_ctx.in_param); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + + data.plist = &pv_list; + + blob_buf_init(&data.bb, 0); + bbf_init(&data.bbf_ctx); + + // no need to process it further since transaction-id is not valid + if (data.trans_id && !is_transaction_valid(data.trans_id)) { + WARNING("Transaction not started yet"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + + if (data.trans_id == 0) { + // Transaction-id is not defined so create an internal transaction + trans_id = transaction_start(0); + if (trans_id == 0) { + WARNING("Failed to get the lock for the transaction"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + } + + usp_set_value(&data); + + if (data.trans_id == 0) { + // Internal transaction: need to commit the changes + transaction_commit(trans_id, NULL, true); + } + +end: + ubus_send_reply(ctx, req, data.bb.head); + blob_buf_free(&data.bb); + free_pv_list(&pv_list); + bbf_cleanup(&data.bbf_ctx); + return 0; +} + +static const struct blobmsg_policy dm_operate_policy[__DM_OPERATE_MAX] = { + [DM_OPERATE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING }, + [DM_OPERATE_COMMAND_KEY] = { .name = "command_key", .type = BLOBMSG_TYPE_STRING }, + [DM_OPERATE_INPUT] = { .name = "input", .type = BLOBMSG_TYPE_TABLE }, + [DM_OPERATE_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +static int usp_operate_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_OPERATE_MAX] = {NULL}; + char path[MAX_DM_PATH] = {0}; + usp_data_t data; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_operate_policy, __DM_OPERATE_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!(tb[DM_OPERATE_COMMAND])) + return UBUS_STATUS_INVALID_ARGUMENT; + + snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[DM_OPERATE_COMMAND])); + + data.ctx = ctx; + data.req = req; + data.bbf_ctx.in_param = path; + data.bbf_ctx.linker = tb[DM_OPERATE_COMMAND_KEY] ? blobmsg_get_string(tb[DM_OPERATE_COMMAND_KEY]) : ""; + + if (tb[DM_OPERATE_INPUT]) + data.bbf_ctx.in_value = blobmsg_format_json(tb[DM_OPERATE_INPUT], true); + + fill_optional_data(&data, tb[DM_OPERATE_OPTIONAL]); + + INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, data.bbf_ctx.in_param); + + if (is_sync_operate_cmd(&data)) { + usp_operate_cmd_sync(&data); + } else { + uspd_start_deferred(&data, usp_operate_cmd_async); + } + + return 0; +} + +static const struct blobmsg_policy dm_add_policy[] = { + [DM_ADD_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_ADD_OBJ_PATH] = { .name = "obj_path", .type = BLOBMSG_TYPE_TABLE }, + [DM_ADD_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +int usp_add_handler(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_ADD_MAX]; + char path[PATH_MAX]; + usp_data_t data; + int trans_id = 0; + int fault = 0; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_add_policy, __DM_ADD_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!tb[DM_ADD_PATH]) + return UBUS_STATUS_INVALID_ARGUMENT; + + snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[DM_ADD_PATH])); + + data.bbf_ctx.in_param = path; + + fill_optional_data(&data, tb[DM_ADD_OPTIONAL]); + + INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, data.bbf_ctx.in_param); + + blob_buf_init(&data.bb, 0); + bbf_init(&data.bbf_ctx); + + // no need to process it further since transaction-id is not valid + if (data.trans_id && !is_transaction_valid(data.trans_id)) { + WARNING("Transaction not started yet"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + + if (data.trans_id == 0) { + // Transaction-id is not defined so create an internal transaction + trans_id = transaction_start(0); + if (trans_id == 0) { + ERR("Failed to get the lock for the transaction"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + } + + fault = create_add_response(&data); + if (fault) { + ERR("Fault in add path |%s|", data.bbf_ctx.in_param); + + if (data.trans_id == 0) { + // Internal transaction: need to abort the changes + transaction_abort(trans_id, NULL); + } + + goto end; + } + + if (tb[DM_ADD_OBJ_PATH]) { + LIST_HEAD(pv_list); + + snprintf(path, PATH_MAX, "%s%s.", (char *)blobmsg_data(tb[DM_ADD_PATH]), data.bbf_ctx.addobj_instance); + + fault = fill_pvlist_set(path, NULL, tb[DM_ADD_OBJ_PATH], &pv_list); + if (fault) { + ERR("Fault in fill pvlist set path |%s|", path); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + + if (data.trans_id == 0) { + // Internal transaction: need to abort the changes + transaction_abort(trans_id, NULL); + } + + free_pv_list(&pv_list); + goto end; + } + + data.plist = &pv_list; + + usp_set_value(&data); + + free_pv_list(&pv_list); + } + + if (data.trans_id == 0) { + // Internal transaction: need to commit the changes + transaction_commit(trans_id, NULL, true); + } + +end: + ubus_send_reply(ctx, req, data.bb.head); + blob_buf_free(&data.bb); + bbf_cleanup(&data.bbf_ctx); + return 0; +} + +static const struct blobmsg_policy dm_del_policy[] = { + [DM_DEL_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + [DM_DEL_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY }, + [DM_DEL_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +int usp_del_handler(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__DM_DEL_MAX]; + LIST_HEAD(paths_list); + usp_data_t data; + int trans_id = 0; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(dm_del_policy, __DM_DEL_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!tb[DM_DEL_PATH] && !tb[DM_DEL_PATHS]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[DM_DEL_PATH]) { + char *path = blobmsg_get_string(tb[DM_DEL_PATH]); + add_path_list(path, &paths_list); + } + + if (tb[DM_DEL_PATHS]) { + struct blob_attr *paths = tb[DM_DEL_PATHS]; + struct blob_attr *path = NULL; + size_t rem; + + blobmsg_for_each_attr(path, paths, rem) { + char *path_str = blobmsg_get_string(path); + + add_path_list(path_str, &paths_list); + } + } + + data.plist = &paths_list; + + fill_optional_data(&data, tb[DM_DEL_OPTIONAL]); + + INFO("ubus method|%s|, name|%s|", method, obj->name); + + blob_buf_init(&data.bb, 0); + bbf_init(&data.bbf_ctx); + + data.bbf_ctx.in_param = tb[DM_DEL_PATH] ? blobmsg_get_string(tb[DM_DEL_PATH]) : ""; + + // no need to process it further since transaction-id is not valid + if (data.trans_id && !is_transaction_valid(data.trans_id)) { + WARNING("Transaction not started yet"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + + if (data.trans_id == 0) { + // Transaction-id is not defined so create an internal transaction + trans_id = transaction_start(0); + if (trans_id == 0) { + WARNING("Failed to get the lock for the transaction"); + fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + goto end; + } + } + + create_del_response(&data); + + if (data.trans_id == 0) { + // Internal transaction: need to commit the changes + transaction_commit(trans_id, NULL, true); + } + +end: + ubus_send_reply(ctx, req, data.bb.head); + blob_buf_free(&data.bb); + bbf_cleanup(&data.bbf_ctx); + free_path_list(&paths_list); + return 0; +} + +enum { + TRANS_CMD, + TRANS_TIMEOUT, + TRANS_RESTART, + TRANS_OPTIONAL, + __TRANS_MAX, +}; + +static const struct blobmsg_policy transaction_policy[] = { + [TRANS_CMD] = { .name = "cmd", .type = BLOBMSG_TYPE_STRING }, + [TRANS_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 }, + [TRANS_RESTART] = { .name = "restart_services", .type = BLOBMSG_TYPE_INT8 }, + [TRANS_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, +}; + +static int usp_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__TRANS_MAX] = {NULL}; + usp_data_t data; + + bool is_service_restart = true; + uint32_t max_timeout = 0; + char *trans_cmd = "status"; + int ret; + + memset(&data, 0, sizeof(usp_data_t)); + + if (blobmsg_parse(transaction_policy, __TRANS_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!tb[TRANS_CMD]) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (tb[TRANS_CMD]) + trans_cmd = blobmsg_get_string(tb[TRANS_CMD]); + + if (tb[TRANS_TIMEOUT]) + max_timeout = blobmsg_get_u32(tb[TRANS_TIMEOUT]); + + if (tb[TRANS_RESTART]) + is_service_restart = blobmsg_get_bool(tb[TRANS_RESTART]); + + fill_optional_data(&data, tb[TRANS_OPTIONAL]); + if (!is_str_eq(trans_cmd, "start") && data.trans_id == 0) + return UBUS_STATUS_INVALID_ARGUMENT; + + INFO("ubus method|%s|, name|%s|", method, obj->name); + + bbf_init(&data.bbf_ctx); + blob_buf_init(&data.bb, 0); + + if (is_str_eq(trans_cmd, "start")) { + ret = transaction_start(max_timeout); + if (ret) { + blobmsg_add_u8(&data.bb, "status", true); + blobmsg_add_u32(&data.bb, "transaction_id", ret); + } else { + blobmsg_add_u8(&data.bb, "status", false); + } + } else if (is_str_eq(trans_cmd, "commit")) { + ret = transaction_commit(data.trans_id, &data.bb, is_service_restart); + blobmsg_add_u8(&data.bb, "status", (ret == 0)); + } else if (is_str_eq(trans_cmd, "abort")) { + ret = transaction_abort(data.trans_id, &data.bb); + blobmsg_add_u8(&data.bb, "status", (ret == 0)); + } else if (is_str_eq(trans_cmd, "status")) { + transaction_status(&data.bb, data.trans_id); + } else { + WARNING("method(%s) not supported", method); + } + + ubus_send_reply(ctx, req, data.bb.head); + blob_buf_free(&data.bb); + bbf_cleanup(&data.bbf_ctx); + + return 0; +} + +enum { + BBF_NOTIFY_NAME, + BBF_NOTIFY_PRAMS, + __BBF_NOTIFY_MAX, +}; + +static const struct blobmsg_policy dm_notify_event_policy[] = { + [BBF_NOTIFY_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, + [BBF_NOTIFY_PRAMS] = { .name = "input", .type = BLOBMSG_TYPE_TABLE }, +}; + +static int usp_notify_event(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req __attribute__((unused)), const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__BBF_NOTIFY_MAX] = {NULL}; + char *event_name; + + if (blobmsg_parse(dm_notify_event_policy, __BBF_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg))) { + ERR("Failed to parse blob"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + + if (!tb[BBF_NOTIFY_NAME]) + return UBUS_STATUS_INVALID_ARGUMENT; + + INFO("ubus method|%s|, name|%s|", method, obj->name); + event_name = blobmsg_get_string(tb[BBF_NOTIFY_NAME]); + if (is_registered_event(event_name)) { + ubus_send_event(ctx, BBF_EVENT, msg); + } else { + WARNING("Event %s not registered", event_name); + } + + return 0; +} + +static struct ubus_method bbf_methods[] = { + UBUS_METHOD("get", usp_get_handler, dm_get_policy), + UBUS_METHOD("schema", usp_schema_handler, dm_schema_policy), + UBUS_METHOD("instances", usp_instances_handler, dm_instances_policy), + UBUS_METHOD("set", usp_set_handler, dm_set_policy), + UBUS_METHOD("operate", usp_operate_handler, dm_operate_policy), + UBUS_METHOD("add", usp_add_handler, dm_add_policy), + UBUS_METHOD("del", usp_del_handler, dm_del_policy), + UBUS_METHOD("transaction", usp_transaction_handler, transaction_policy), + UBUS_METHOD("notify_event", usp_notify_event, dm_notify_event_policy), +}; + +static struct ubus_object_type bbf_type = UBUS_OBJECT_TYPE(METHOD_NAME, bbf_methods); + +static struct ubus_object bbf_object = { + .name = METHOD_NAME, + .type = &bbf_type, + .methods = bbf_methods, + .n_methods = ARRAY_SIZE(bbf_methods) +}; + +static void periodic_schema_updater(struct uloop_timeout *t) +{ + bool ret; + struct usp_context *u; + struct blob_buf bb; + + u = container_of(t, struct usp_context, schema_timer); + if (u == NULL) { + ERR("Failed to get the usp context"); + return; + } + + if (is_transaction_running()) { + DEBUG("Transaction ongoing, schedule schema update timer after %dsec", BBF_SCHEMA_UPDATE_TIMEOUT); + u->schema_timer.cb = periodic_schema_updater; + uloop_timeout_set(&u->schema_timer, BBF_SCHEMA_UPDATE_TIMEOUT); + return; + } + + memset(&bb, 0, sizeof(struct blob_buf)); + + ret = is_object_schema_update_available(u); + if (ret) { + INFO("Schema update available"); + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "action", "schema_update_available"); + ubus_notify(&u->ubus_ctx, &bbf_object, METHOD_NAME, bb.head, 1000); + blob_buf_free(&bb); + } + + DEBUG("## Update schema after %us ##", BBF_SCHEMA_UPDATE_TIMEOUT); + u->schema_timer.cb = periodic_schema_updater; + uloop_timeout_set(&u->schema_timer, BBF_SCHEMA_UPDATE_TIMEOUT); +} + +static void broadcast_add_del_event(struct list_head *inst, bool is_add) +{ + struct ubus_context ctx; + struct blob_buf bb; + struct pathNode *ptr; + void *a; + int ret; + + if (list_empty(inst)) { + return; + } + + ret = ubus_connect_ctx(&ctx, NULL); + if (ret != UBUS_STATUS_OK) { + fprintf(stderr, "Failed to connect to ubus\n"); + return; + } + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + + a = blobmsg_open_array(&bb, "instances"); + list_for_each_entry(ptr, inst, list) { + blobmsg_add_string(&bb, NULL, ptr->path); + DEBUG("#%s:: %s #", (is_add)?"Add":"Del", ptr->path); + } + blobmsg_close_array(&bb, a); + + if (is_add) + ubus_send_event(&ctx, BBF_ADD_EVENT, bb.head); + else + ubus_send_event(&ctx, BBF_DEL_EVENT, bb.head); + + blob_buf_free(&bb); + ubus_shutdown(&ctx); +} + +static void update_instances_list(struct list_head *inst) +{ + struct dmctx bbf_ctx = { + .in_param = ROOT_NODE, + .nextlevel = false, + .instance_mode = INSTANCE_MODE_NUMBER, + .dm_type = BBFDM_USP + }; + + bbf_init(&bbf_ctx); + + if (0 == usp_dm_exec(&bbf_ctx, BBF_INSTANCES)) { + struct dm_parameter *nptr_dp; + + list_for_each_entry(nptr_dp, &bbf_ctx.list_parameter, list) { + add_path_list(nptr_dp->name, inst); + } + } + + bbf_cleanup(&bbf_ctx); +} + +static void periodic_instance_updater(struct uloop_timeout *t); +static void instance_fork_done(struct uloop_process *p, int ret) +{ + struct uspd_async_req *r = container_of(p, struct uspd_async_req, process); + + if (r) { + INFO("Instance updater(%d) completed, starting a new instance timer", r->process.pid); + struct usp_context *u = (struct usp_context *)r->result; + + u->instance_timer.cb = periodic_instance_updater; + uloop_timeout_set(&u->instance_timer, g_refresh_time); + free_path_list(&u->old_instances); + async_req_free(r); + } + if (ret) { + DEBUG("Instance updater cb failed %d", ret); + } +} + +static void instance_compare_publish(struct list_head *new_inst, struct list_head *old_inst) +{ + struct pathNode *ptr; + LIST_HEAD(inst_list); + + list_for_each_entry(ptr, old_inst, list) { + if (!present_in_path_list(new_inst, ptr->path)) { + add_path_list(ptr->path, &inst_list); + } + } + broadcast_add_del_event(&inst_list, false); + free_path_list(&inst_list); + + list_for_each_entry(ptr, new_inst, list) { + if (!present_in_path_list(old_inst, ptr->path)) { + add_path_list(ptr->path, &inst_list); + } + } + broadcast_add_del_event(&inst_list, true); + free_path_list(&inst_list); +} + +static int fork_instance_checker(struct usp_context *u) +{ + struct uspd_async_req *r = NULL; + pid_t child; + + r = async_req_new(); + if (r == NULL) { + ERR("Error allocating instance req"); + u->instance_timer.cb = periodic_instance_updater; + uloop_timeout_set(&u->instance_timer, g_refresh_time); + free_path_list(&u->old_instances); + goto err_out; + } + child = fork(); + if (child == 0) { + prctl(PR_SET_NAME, (unsigned long) "usp_instance"); + // child initialise signal to prevent segfaults + signal_init(); + /* free fd's and memory inherited from parent */ + ubus_shutdown(&u->ubus_ctx); + uloop_done(); + async_req_free(r); + fclose(stdin); + fclose(stdout); + fclose(stderr); + + DEBUG("subprocess instances checker"); + instance_compare_publish(&u->instances, &u->old_instances); + usp_cleanup(u); + closelog(); + /* write result and exit */ + exit(EXIT_SUCCESS); + } + + // parent + DEBUG("Creating instance checker process child %d", child); + r->result = u; + r->process.pid = child; + r->process.cb = instance_fork_done; + uloop_process_add(&r->process); + return 0; + +err_out: + if (r) + async_req_free(r); + + return UBUS_STATUS_UNKNOWN_ERROR; +} + +static void periodic_instance_updater(struct uloop_timeout *t) +{ + struct usp_context *u; + + u = container_of(t, struct usp_context, instance_timer); + if (u == NULL) { + ERR("Failed to get the usp context"); + return; + } + + if (is_transaction_running()) { + DEBUG("Transaction ongoing, schedule refresh timer after 1s"); + u->instance_timer.cb = periodic_instance_updater; + uloop_timeout_set(&u->instance_timer, 1000); + return; + } + + if (list_empty(&u->instances)) { + update_instances_list(&u->instances); + DEBUG("Creating timer for instance update checker, init instances"); + u->instance_timer.cb = periodic_instance_updater; + uloop_timeout_set(&u->instance_timer, g_refresh_time); + return; + } + + list_splice_init(&u->instances, &u->old_instances); + update_instances_list(&u->instances); + + // fork a process and send it to compare, when process completes + // delete the old instances and add a new timer + fork_instance_checker(u); +} + +static int usp_get_config(void) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg = NULL; + struct uci_element *e = NULL; + + ctx = uci_alloc_context(); + if (!ctx) + return -1; + + if (uci_load(ctx, "bbfdmd", &pkg)) { + uci_free_context(ctx); + return -1; + } + + uci_foreach_element(&pkg->sections, e) { + + struct uci_section *s = uci_to_section(e); + if (s == NULL || s->type == NULL) + continue; + + if (strcmp(s->type, "globals") == 0) { + struct uci_option *opn = NULL; + + opn = uci_lookup_option(ctx, s, "loglevel"); + if (opn) { + uint8_t log_level = (uint8_t) strtoul(opn->v.string, NULL, 10); + set_debug_level(log_level); + } + + opn = uci_lookup_option(ctx, s, "subprocess_level"); + if (opn) { + g_subprocess_level = (unsigned int) strtoul(opn->v.string, NULL, 10); + } + + opn = uci_lookup_option(ctx, s, "refresh_time"); + if (opn) { + unsigned int refresh_time = (unsigned int) strtoul(opn->v.string, NULL, 10); + g_refresh_time = refresh_time * 1000; + } + } + } + + uci_unload(ctx, pkg); + uci_free_context(ctx); + return 0; +} + +static int usp_init(struct usp_context *u) +{ + int ret; + + ret = usp_get_config(); + if (ret) + return ret; + + INFO("Registering ubus objects...."); + ret = ubus_add_object(&u->ubus_ctx, &bbf_object); + + return ret; +} + +int main(int argc, char **argv) +{ + struct usp_context usp_ctx; + const char *ubus_socket = NULL; + int ret = 0, ch; + + while ((ch = getopt(argc, argv, "hs:t:")) != -1) { + switch (ch) { + case 's': + ubus_socket = optarg; + break; + case 't': + configure_transaction_timeout(strtol(optarg, NULL, 10)); + break; + case 'h': + usage(argv[0]); + exit(0); + default: + break; + } + } + + openlog("bbfdm", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); + + memset(&usp_ctx, 0, sizeof(struct usp_context)); + + INIT_LIST_HEAD(&usp_ctx.instances); + INIT_LIST_HEAD(&usp_ctx.old_instances); + INIT_LIST_HEAD(&usp_ctx.event_handlers); + + uloop_init(); + + ret = ubus_connect_ctx(&usp_ctx.ubus_ctx, ubus_socket); + if (ret != UBUS_STATUS_OK) { + fprintf(stderr, "Failed to connect to ubus\n"); + return -1; + } + + signal_init(); + + ret = register_events_to_ubus(&usp_ctx.ubus_ctx, &usp_ctx.event_handlers); + if (ret != 0) { + goto exit; + } + + ubus_add_uloop(&usp_ctx.ubus_ctx); + + ret = usp_init(&usp_ctx); + if (ret != UBUS_STATUS_OK) { + ret = UBUS_STATUS_UNKNOWN_ERROR; + goto exit; + } + + usp_ctx.schema_timer.cb = periodic_schema_updater; + uloop_timeout_set(&usp_ctx.schema_timer, BBF_SCHEMA_UPDATE_TIMEOUT); + + // initial timer should be bigger to give more space to other applications to initialize + usp_ctx.instance_timer.cb = periodic_instance_updater; + uloop_timeout_set(&usp_ctx.instance_timer, 3 * g_refresh_time); + + INFO("Waiting on uloop...."); + uloop_run(); + +exit: + free_ubus_event_handler(&usp_ctx.ubus_ctx, &usp_ctx.event_handlers); + ubus_shutdown(&usp_ctx.ubus_ctx); + uloop_done(); + usp_cleanup(&usp_ctx); + closelog(); + + return ret; +} diff --git a/bbfdmd/src/bbfdmd.h b/bbfdmd/src/bbfdmd.h new file mode 100644 index 0000000000000000000000000000000000000000..890163c52730bb848023ad40c48d4dedd1279c99 --- /dev/null +++ b/bbfdmd/src/bbfdmd.h @@ -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 */ diff --git a/bbfd/common.c b/bbfdmd/src/common.c similarity index 72% rename from bbfd/common.c rename to bbfdmd/src/common.c index 56945dcafb1595f1f1615f0f8583155001d34b2f..ef0b6b921acc4b14690de98830aed84b18c70fdb 100644 --- a/bbfd/common.c +++ b/bbfdmd/src/common.c @@ -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; +} diff --git a/bbfd/common.h b/bbfdmd/src/common.h similarity index 83% rename from bbfd/common.h rename to bbfdmd/src/common.h index 93a8cc1a2a2df7a918eb9f147ae1030698737cc0..7c244bf43ab08fafa0f9fcf664f5bb7795600bc9 100644 --- a/bbfd/common.h +++ b/bbfdmd/src/common.h @@ -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) diff --git a/bbfd/events.c b/bbfdmd/src/events.c similarity index 88% rename from bbfd/events.c rename to bbfdmd/src/events.c index 2f1c13d41ad1cae6fcaf809bea08427a90c20287..3c798a0d21d204bb7f3ad26f1db5232bf727b45d 100644 --- a/bbfd/events.c +++ b/bbfdmd/src/events.c @@ -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; +} diff --git a/bbfd/events.h b/bbfdmd/src/events.h similarity index 87% rename from bbfd/events.h rename to bbfdmd/src/events.h index 7a1bf0055b5cb9a8e1b681ef812bb00aba6f885f..294e87391e7d575f19ee2be623503a89d4bb71a3 100644 --- a/bbfd/events.h +++ b/bbfdmd/src/events.h @@ -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 */ diff --git a/bbfdmd/src/get.c b/bbfdmd/src/get.c new file mode 100644 index 0000000000000000000000000000000000000000..3714e54358c55f6ae411103aea6986be4e207d75 --- /dev/null +++ b/bbfdmd/src/get.c @@ -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; +} diff --git a/bbfdmd/src/get.h b/bbfdmd/src/get.h new file mode 100644 index 0000000000000000000000000000000000000000..0b8842942b668a65bb888e5bdf3562a4c3bdf3a7 --- /dev/null +++ b/bbfdmd/src/get.h @@ -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 */ diff --git a/bbfdmd/src/get_helper.c b/bbfdmd/src/get_helper.c new file mode 100644 index 0000000000000000000000000000000000000000..0acfaade438c192e8e5af32c91c540a99b15c36d --- /dev/null +++ b/bbfdmd/src/get_helper.c @@ -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; +} diff --git a/bbfdmd/src/get_helper.h b/bbfdmd/src/get_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..5d62af168c38c813f64319696a865aa938087bc4 --- /dev/null +++ b/bbfdmd/src/get_helper.h @@ -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 */ diff --git a/bbfd/ipc.h b/bbfdmd/src/ipc.h similarity index 98% rename from bbfd/ipc.h rename to bbfdmd/src/ipc.h index 4e5c133bdff840ae46af073671d514ffd110f44b..67362fd87f334dff92fcfe2c7de2642f3b88e764 100644 --- a/bbfd/ipc.h +++ b/bbfdmd/src/ipc.h @@ -31,4 +31,4 @@ #define DEF_IPC_DATA_LEN (10 * 1024 * 1024 - 128) // 10M - 128 bytes #endif -#endif // end IPC_H +#endif /* IPC_H */ diff --git a/bbfdmd/src/operate.c b/bbfdmd/src/operate.c new file mode 100644 index 0000000000000000000000000000000000000000..ffc4fd6b2d4d31562fcbab21415b94e4868cc8ec --- /dev/null +++ b/bbfdmd/src/operate.c @@ -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); +} diff --git a/bbfd/operate.h b/bbfdmd/src/operate.h similarity index 62% rename from bbfd/operate.h rename to bbfdmd/src/operate.h index ca950863add2b4c6e658890357d5eb53f915603e..f3e6adc5392905dc096c106b2318078c65bed985 100644 --- a/bbfd/operate.h +++ b/bbfdmd/src/operate.h @@ -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 */ diff --git a/bbfd/pretty_print.c b/bbfdmd/src/pretty_print.c similarity index 75% rename from bbfd/pretty_print.c rename to bbfdmd/src/pretty_print.c index 6f343eb5c013435c1e236933958169f6dca8be2a..316557929a697ac1e5a2f406cb776710756c874a 100644 --- a/bbfd/pretty_print.c +++ b/bbfdmd/src/pretty_print.c @@ -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); -} diff --git a/bbfd/pretty_print.h b/bbfdmd/src/pretty_print.h similarity index 74% rename from bbfd/pretty_print.h rename to bbfdmd/src/pretty_print.h index ec7646479a6d195ca306855a6c5f941af09cd8d0..2fc7ea26c8b7250e10e05e1bc396de75692c6597 100644 --- a/bbfd/pretty_print.h +++ b/bbfdmd/src/pretty_print.h @@ -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 */ diff --git a/bbfdmd/src/set.c b/bbfdmd/src/set.c new file mode 100644 index 0000000000000000000000000000000000000000..d053c04079551751f6f0adc25af9495429e1cb69 --- /dev/null +++ b/bbfdmd/src/set.c @@ -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; +} diff --git a/bbfdmd/src/set.h b/bbfdmd/src/set.h new file mode 100644 index 0000000000000000000000000000000000000000..c77068116204c4862ce9e5cb9fcda16376135265 --- /dev/null +++ b/bbfdmd/src/set.h @@ -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 */ + diff --git a/docs/apis/ubus/bbf.md b/docs/apis/ubus/bbf.md new file mode 100644 index 0000000000000000000000000000000000000000..9187a6de1e69ad0ac9ed3aaa5e4b7c414cd69909 --- /dev/null +++ b/docs/apis/ubus/bbf.md @@ -0,0 +1,2313 @@ +# bbf Schema + +``` +https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/docs/api/bbfdm.md +``` + +| Custom Properties | Additional Properties | +| ----------------- | --------------------- | +| Forbidden | Forbidden | + +# bbf + +| List of Methods | +| ----------------------------- | +| [add](#add) | Method | bbf (this schema) | +| [del](#del) | Method | bbf (this schema) | +| [get](#get) | Method | bbf (this schema) | +| [instances](#instances) | Method | bbf (this schema) | +| [notify_event](#notify_event) | Method | bbf (this schema) | +| [operate](#operate) | Method | bbf (this schema) | +| [schema](#schema) | Method | bbf (this schema) | +| [set](#set) | Method | bbf (this schema) | +| [transaction](#transaction) | Method | bbf (this schema) | + +## add + +### Add a new object instance + +Add a new object in multi instance object + +`add` + +- type: `Method` + +### add Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ---------- | ------ | ------------ | +| `obj_path` | object | Optional | +| `optional` | object | **Required** | +| `path` | string | **Required** | + +#### obj_path + +`obj_path` + +- is optional +- type: `object` + +##### obj_path Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ---- | -------- | +| None | None | None | + +#### optional + +`optional` + +- is **required** +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | +| ---------------- | ------- | -------- | +| `transaction_id` | integer | Optional | + +#### transaction_id + +`transaction_id` + +- is optional +- type: reference + +##### transaction_id Type + +`integer` + +- minimum value: `1` + +#### path + +Complete object element path as per TR181 + +`path` + +- is **required** +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1. +``` + +```json +Device.WiFi. +``` + +### Ubus CLI Example + +``` +ubus call bbf add {"path":"aute dolore","optional":{"transaction_id":6658315},"obj_path":{}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "add", + { "path": "aute dolore", "optional": { "transaction_id": 6658315 }, "obj_path": {} } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ "results": [{ "path": "cupidatat enim non ullamco tempor", "data": "aliqua eu", "fault": 8966, "fault_msg": "ci" }] } +``` + +## del + +### Delete object instance + +Delete a object instance from multi instance object + +`del` + +- type: `Method` + +### del Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ---------- | ------ | ------------ | +| `optional` | object | Optional | +| `path` | string | **Required** | +| `paths` | array | Optional | + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | +| ---------------- | ------- | -------- | +| `transaction_id` | integer | Optional | + +#### transaction_id + +`transaction_id` + +- is optional +- type: reference + +##### transaction_id Type + +`integer` + +- minimum value: `1` + +#### path + +Complete object element path as per TR181 + +`path` + +- is **required** +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1. +``` + +```json +Device.WiFi. +``` + +#### paths + +`paths` + +- is optional +- type: `array` + +##### paths Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "type": "array", + "uniqueItems": true, + "items": [ + { + "$ref": "#/definitions/query_path_t" + } + ], + "simpletype": "`array`" +} +``` + +### Ubus CLI Example + +``` +ubus call bbf del {"path":"ea enim","paths":["commodo proi"],"optional":{"transaction_id":35247793}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "del", + { "path": "ea enim", "paths": ["commodo proi"], "optional": { "transaction_id": 35247793 } } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ + "results": [ + { "path": "laborum aliqua", "data": "tempor culpa in", "fault": 7997, "fault_msg": "amet reprehenderit consec" } + ] +} +``` + +## get + +### Get handler + +Query the datamodel object + +`get` + +- type: `Method` + +### get Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ---------- | ------- | ------------ | +| `maxdepth` | integer | Optional | +| `optional` | object | Optional | +| `path` | string | **Required** | +| `paths` | array | Optional | + +#### maxdepth + +Integer to decide the depth of data model to be parsed + +`maxdepth` + +- is optional +- type: `integer` + +##### maxdepth Type + +`integer` + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | Default | +| --------------- | ------- | -------- | ---------- | +| `format` | string | Optional | `"pretty"` | +| `instance_mode` | integer | Optional | `0` | +| `proto` | string | Optional | `"both"` | + +#### format + +`format` + +- is optional +- type: reference +- default: `"pretty"` + +##### format Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#get-known-values). + +##### format Known Values + +| Value | +| ------ | +| raw | +| pretty | + +#### instance_mode + +`instance_mode` + +- is optional +- type: reference +- default: `0` + +##### instance_mode Type + +`integer` + +- minimum value: `0` +- maximum value: `1` + +#### proto + +`proto` + +- is optional +- type: reference +- default: `"both"` + +##### proto Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#get-known-values). + +##### proto Known Values + +| Value | +| ----- | +| usp | +| cwmp | +| both | + +#### path + +DM object path with search queries + +`path` + +- is **required** +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1.BSSID +``` + +```json +Device.WiFi.SSID.*.BSSID +``` + +```json +Device.WiFi. +``` + +#### paths + +`paths` + +- is optional +- type: `array` + +##### paths Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "type": "array", + "uniqueItems": true, + "items": [ + { + "$ref": "#/definitions/query_path_t" + } + ], + "simpletype": "`array`" +} +``` + +### Ubus CLI Example + +``` +ubus call bbf get {"path":"aute dolor ut laborum deserunt","paths":["Loremnisi sunt enim"],"maxdepth":-13915475,"optional":{"format":"raw","proto":"usp","instance_mode":0}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "get", + { + "path": "aute dolor ut laborum deserunt", + "paths": ["Loremnisi sunt enim"], + "maxdepth": -13915475, + "optional": { "format": "raw", "proto": "usp", "instance_mode": 0 } + } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ + "results": [ + { + "path": "adipisicing labore", + "data": "anim Excepteur laboris", + "type": "xsd:hexBinary", + "fault": 8645, + "fault_msg": "tempor" + } + ] +} +``` + +## instances + +### Instance query handler + +Get the instances of multi object + +`instances` + +- type: `Method` + +### instances Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | Optional | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ------------- | ------- | ------------ | +| `first_level` | boolean | Optional | +| `optional` | object | Optional | +| `path` | string | **Required** | + +#### first_level + +gets only first level objects if true + +`first_level` + +- is optional +- type: `boolean` + +##### first_level Type + +`boolean` + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | Default | +| --------------- | ------- | -------- | -------- | +| `instance_mode` | integer | Optional | `0` | +| `proto` | string | Optional | `"both"` | + +#### instance_mode + +`instance_mode` + +- is optional +- type: reference +- default: `0` + +##### instance_mode Type + +`integer` + +- minimum value: `0` +- maximum value: `1` + +#### proto + +`proto` + +- is optional +- type: reference +- default: `"both"` + +##### proto Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#instances-known-values). + +##### proto Known Values + +| Value | +| ----- | +| usp | +| cwmp | +| both | + +#### path + +DM object path with search queries + +`path` + +- is **required** +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1.BSSID +``` + +```json +Device.WiFi.SSID.*.BSSID +``` + +```json +Device.WiFi. +``` + +### Ubus CLI Example + +``` +ubus call bbf instances {"path":"labore","first_level":false,"optional":{"proto":"usp","instance_mode":1}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "instances", + { "path": "labore", "first_level": false, "optional": { "proto": "usp", "instance_mode": 1 } } + ] +} +``` + +#### output + +`output` + +- is optional +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ "results": [{ "path": "aliqua reprehenderit Except", "fault": 8825, "fault_msg": "minim eu incididunt" }] } +``` + +## notify_event + +### notify occurance of an event on ubus + +`notify_event` + +- type: `Method` + +### notify_event Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | | Optional | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | Optional | +| `name` | string | **Required** | + +#### input + +`input` + +- is optional +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ---- | -------- | +| None | None | None | + +#### name + +`name` + +- is **required** +- type: `string` + +##### name Type + +`string` + +### Ubus CLI Example + +``` +ubus call bbf notify_event {"name":"veniam dolor t","input":{}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": ["<SID>", "bbf", "notify_event", { "name": "veniam dolor t", "input": {} }] +} +``` + +#### output + +`output` + +- is optional +- type: complex + +##### output Type + +Unknown type ``. + +```json +{ + "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 + } + }, + "out": "{\"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}}}", + "simpletype": "complex" +} +``` + +### Output Example + +```json +{ + "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 } + } +} +``` + +## operate + +### Operate handler + +Operate on object element provided in path + +`operate` + +- type: `Method` + +### operate Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ------------- | ------ | ------------ | +| `command` | string | **Required** | +| `command_key` | string | Optional | +| `input` | object | Optional | +| `optional` | object | Optional | + +#### command + +Datamodel object schema path + +`command` + +- is **required** +- type: reference + +##### command Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### command Examples + +```json +Device.IP.Diagnostics.IPPing() +``` + +```json +Device.DHCPv4.Client.{i}.Renew() +``` + +```json +Device.FactoryReset() +``` + +#### command_key + +`command_key` + +- is optional +- type: `string` + +##### command_key Type + +`string` + +#### input + +Input arguments for the operate command as defined in TR-181-2.13 + +`input` + +- is optional +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ---- | -------- | +| None | None | None | + +##### input Example + +```json +{ "path": "Device.IP.Diagnostics.IPPing()", "input": { "Host": "iopsys.eu" } } +``` + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | Default | +| --------------- | ------- | -------- | ---------- | +| `format` | string | Optional | `"pretty"` | +| `instance_mode` | integer | Optional | `0` | +| `proto` | string | Optional | `"both"` | + +#### format + +`format` + +- is optional +- type: reference +- default: `"pretty"` + +##### format Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#operate-known-values). + +##### format Known Values + +| Value | +| ------ | +| raw | +| pretty | + +#### instance_mode + +`instance_mode` + +- is optional +- type: reference +- default: `0` + +##### instance_mode Type + +`integer` + +- minimum value: `0` +- maximum value: `1` + +#### proto + +`proto` + +- is optional +- type: reference +- default: `"both"` + +##### proto Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#operate-known-values). + +##### proto Known Values + +| Value | +| ----- | +| usp | +| cwmp | +| both | + +### Ubus CLI Example + +``` +ubus call bbf operate {"command":"officia nostrud sunt","command_key":"sunt qui","input":{},"optional":{"format":"raw","proto":"both","instance_mode":1}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "operate", + { + "command": "officia nostrud sunt", + "command_key": "sunt qui", + "input": {}, + "optional": { "format": "raw", "proto": "both", "instance_mode": 1 } + } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ + "results": [ + { + "path": "fugiat occaecat", + "data": "1", + "fault": 8855, + "fault_msg": "magna deserunt labore enim", + "output": [{ "path": "dolore ullamco", "data": "1", "type": "xsd:unsignedLong" }] + } + ] +} +``` + +## schema + +### Get list of supported datamodel parameters + +Schema will have all the nodes/objects supported by libbbf + +`schema` + +- type: `Method` + +### schema Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | Optional | +| `output` | object | **Required** | + +#### input + +`input` + +- is optional +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ------------- | ------- | -------- | +| `commands` | boolean | Optional | +| `events` | boolean | Optional | +| `first_level` | boolean | Optional | +| `optional` | object | Optional | +| `params` | boolean | Optional | +| `path` | string | Optional | +| `paths` | array | Optional | + +#### commands + +includes commands in the list if true + +`commands` + +- is optional +- type: `boolean` + +##### commands Type + +`boolean` + +#### events + +includes events in the list if true + +`events` + +- is optional +- type: `boolean` + +##### events Type + +`boolean` + +#### first_level + +gets only first level objects if true + +`first_level` + +- is optional +- type: `boolean` + +##### first_level Type + +`boolean` + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | Default | +| -------- | ------ | -------- | -------- | +| `proto` | string | Optional | `"both"` | + +#### proto + +`proto` + +- is optional +- type: reference +- default: `"both"` + +##### proto Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#schema-known-values). + +##### proto Known Values + +| Value | +| ----- | +| usp | +| cwmp | +| both | + +#### params + +includes objs/params in the list if true + +`params` + +- is optional +- type: `boolean` + +##### params Type + +`boolean` + +#### path + +DM object path with search queries + +`path` + +- is optional +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1.BSSID +``` + +```json +Device.WiFi.SSID.*.BSSID +``` + +```json +Device.WiFi. +``` + +#### paths + +`paths` + +- is optional +- type: `array` + +##### paths Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "type": "array", + "uniqueItems": true, + "items": [ + { + "$ref": "#/definitions/query_path_t" + } + ], + "simpletype": "`array`" +} +``` + +### Ubus CLI Example + +``` +ubus call bbf schema {"path":"proident elit","paths":["in null"],"first_level":false,"commands":true,"events":false,"params":true,"optional":{"proto":"both"}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "schema", + { + "path": "proident elit", + "paths": ["in null"], + "first_level": false, + "commands": true, + "events": false, + "params": true, + "optional": { "proto": "both" } + } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ + "results": [ + { + "path": "utipsum magna", + "data": "0", + "type": "xsd:boolean", + "fault": 8703, + "fault_msg": "eu dolor est", + "input": [{ "path": "Excepteur Ut incididunt", "data": "1", "type": "xsd:unsignedLong" }], + "output": [{ "path": "ullamco adipisicing in", "data": "1", "type": "xsd:command" }] + } + ] +} +``` + +## set + +### Set handler + +Set values of datamodel object element + +`set` + +- type: `Method` + +### set Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ---------- | ------ | ------------ | +| `obj_path` | object | Optional | +| `optional` | object | **Required** | +| `path` | string | **Required** | +| `value` | string | **Required** | + +#### obj_path + +To set multiple values at once, path should be relative to object elements + +`obj_path` + +- is optional +- type: `object` + +##### obj_path Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ---- | -------- | +| None | None | None | + +##### obj_path Examples + +```json +{ "path": "Device.WiFi.SSID.1", "values": { ".SSID": "test_ssid", ".Name": "test_name" } } +``` + +```json +{ "path": "Device.WiFi.SSID.2", "values": { ".SSID": "test_ssid" } } +``` + +#### optional + +`optional` + +- is **required** +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | Default | +| ---------------- | ------- | -------- | -------- | +| `instance_mode` | integer | Optional | `0` | +| `proto` | string | Optional | `"both"` | +| `transaction_id` | integer | Optional | | + +#### instance_mode + +`instance_mode` + +- is optional +- type: reference +- default: `0` + +##### instance_mode Type + +`integer` + +- minimum value: `0` +- maximum value: `1` + +#### proto + +`proto` + +- is optional +- type: reference +- default: `"both"` + +##### proto Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#set-known-values). + +##### proto Known Values + +| Value | +| ----- | +| usp | +| cwmp | +| both | + +#### transaction_id + +`transaction_id` + +- is optional +- type: reference + +##### transaction_id Type + +`integer` + +- minimum value: `1` + +#### path + +DM object path with search queries + +`path` + +- is **required** +- type: reference + +##### path Type + +`string` + +- minimum length: 6 characters +- maximum length: 1024 characters + +##### path Examples + +```json +Device. +``` + +```json +Device.DeviceInfo.Manufacturer +``` + +```json +Device.WiFi.SSID.1.BSSID +``` + +```json +Device.WiFi.SSID.*.BSSID +``` + +```json +Device.WiFi. +``` + +#### value + +value of the object element provided in path, path should contains valid writable object element + +`value` + +- is **required** +- type: `string` + +##### value Type + +`string` + +##### value Examples + +```json +{ "path": "Device.WiFi.SSID.1.SSID", "value": "test_ssid" } +``` + +```json +{ "path": "Device.WiFi.SSID.2.Enable", "value": "true" } +``` + +```json +{ "path": "Device.WiFi.SSID.1.Enable", "value": "0" } +``` + +### Ubus CLI Example + +``` +ubus call bbf set {"path":"amet id ex adipisicing","value":"elit","optional":{"proto":"both","instance_mode":0,"transaction_id":13670657},"obj_path":{}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "set", + { + "path": "amet id ex adipisicing", + "value": "elit", + "optional": { "proto": "both", "instance_mode": 0, "transaction_id": 13670657 }, + "obj_path": {} + } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------- | ----- | -------- | +| `results` | array | Optional | + +#### results + +`results` + +- is optional +- type: `array` + +##### results Type + +Array type: `array` + +All items must be of the type: Unknown type ``. + +```json +{ + "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"] + } + ], + "simpletype": "`array`" +} +``` + +### Output Example + +```json +{ + "results": [ + { "path": "cillum dolore enim ea tempor", "data": "1", "fault": 7177, "fault_msg": "cupidatat do fugiat sed" } + ] +} +``` + +## transaction + +### Start/commit/abort/status a transaction before set/add/del operations + +`transaction` + +- type: `Method` + +### transaction Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | **Required** | + +#### input + +`input` + +- is **required** +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ------------------ | ------- | ------------ | +| `cmd` | string | **Required** | +| `optional` | object | Optional | +| `restart_services` | boolean | Optional | +| `timeout` | integer | Optional | + +#### cmd + +`cmd` + +- is **required** +- type: reference + +##### cmd Type + +`string` + +The value of this property **must** be equal to one of the [known values below](#transaction-known-values). + +##### cmd Known Values + +| Value | +| ------ | +| start | +| commit | +| abort | +| status | + +#### optional + +`optional` + +- is optional +- type: `object` + +##### optional Type + +`object` with following properties: + +| Property | Type | Required | +| ---------------- | ------- | -------- | +| `transaction_id` | integer | Optional | + +#### transaction_id + +`transaction_id` + +- is optional +- type: reference + +##### transaction_id Type + +`integer` + +- minimum value: `1` + +#### restart_services + +`restart_services` + +- is optional +- type: `boolean` + +##### restart_services Type + +`boolean` + +#### timeout + +`timeout` + +- is optional +- type: `integer` + +##### timeout Type + +`integer` + +- minimum value: `0` + +### Ubus CLI Example + +``` +ubus call bbf transaction {"cmd":"commit","timeout":67151755,"restart_services":true,"optional":{"transaction_id":45369701}} +``` + +### JSONRPC Example + +```json +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "bbf", + "transaction", + { "cmd": "commit", "timeout": 67151755, "restart_services": true, "optional": { "transaction_id": 45369701 } } + ] +} +``` + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| ---------------- | ------- | ------------ | +| `error` | string | Optional | +| `status` | boolean | **Required** | +| `transaction_id` | integer | Optional | + +#### error + +`error` + +- is optional +- type: `string` + +##### error Type + +`string` + +#### status + +`status` + +- is **required** +- type: `boolean` + +##### status Type + +`boolean` + +#### transaction_id + +`transaction_id` + +- is optional +- type: `integer` + +##### transaction_id Type + +`integer` + +- minimum value: `1` + +### Output Example + +```json +{ "status": true, "transaction_id": 61009982, "error": "amet qui Duis eiusmod" } +``` diff --git a/docs/apis/uci/bbfd.md b/docs/apis/uci/bbfd.md new file mode 100644 index 0000000000000000000000000000000000000000..e7e4c2a04ae89daa214f357e9cb52886892bfa87 --- /dev/null +++ b/docs/apis/uci/bbfd.md @@ -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> diff --git a/docs/guide/dynamic_dm.md b/docs/guide/dynamic_dm.md index 0d454fe2dbe31a3acd09a0af830784efd95fe27a..929862785ec60d2710c0001448e08c007d6a0ed8 100644 --- a/docs/guide/dynamic_dm.md +++ b/docs/guide/dynamic_dm.md @@ -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 diff --git a/gitlab-ci/bbfdmd-functional-test.sh b/gitlab-ci/bbfdmd-functional-test.sh new file mode 100755 index 0000000000000000000000000000000000000000..dc5d5f4b66ba9ba943b97445d696b634959d7961 --- /dev/null +++ b/gitlab-ci/bbfdmd-functional-test.sh @@ -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" diff --git a/gitlab-ci/functional-api-test.sh b/gitlab-ci/functional-api-test.sh index be86acf3d7de5a36ed7d60ebebbd3e7dd66758b4..c04d13f646045b5b9803951c6dcfa21101a3cbc9 100755 --- a/gitlab-ci/functional-api-test.sh +++ b/gitlab-ci/functional-api-test.sh @@ -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" diff --git a/gitlab-ci/functional-test.sh b/gitlab-ci/functional-test.sh index bade6de6e6c7459eb20d42b845a0977d34793071..3c0342a29b674f99e844f747c70cf8a5ae86dd64 100755 --- a/gitlab-ci/functional-test.sh +++ b/gitlab-ci/functional-test.sh @@ -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" diff --git a/gitlab-ci/install-dependencies.sh b/gitlab-ci/install-dependencies.sh new file mode 100755 index 0000000000000000000000000000000000000000..59e4b2450cc26b759b23a44499f5e119af84eb14 --- /dev/null +++ b/gitlab-ci/install-dependencies.sh @@ -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/ diff --git a/gitlab-ci/iopsys-supervisord.conf b/gitlab-ci/iopsys-supervisord.conf index 6092415a04734bc1d380487a969e5482011cf85e..f40e19b565990505424ce1a803b2772de0981ce9 100755 --- a/gitlab-ci/iopsys-supervisord.conf +++ b/gitlab-ci/iopsys-supervisord.conf @@ -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" diff --git a/gitlab-ci/memory-test.sh b/gitlab-ci/memory-test.sh index cd25b8530058d36511b7bcf5a1b37e0ae9696101..3b4b7063cbdb3f5e47ef8a4c17b461547c97bd46 100755 --- a/gitlab-ci/memory-test.sh +++ b/gitlab-ci/memory-test.sh @@ -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 - -install_libbbf_test -install_libperiodicstats +echo "Starting supervisor" +supervisorctl shutdown +sleep 1 +supervisord -c /etc/supervisor/supervisord.conf +sleep 3 -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 -u get 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 instances Device. +run_valgrind -c instances Device. -run_valgrind -u get Device. -run_valgrind -c get 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" diff --git a/gitlab-ci/setup.sh b/gitlab-ci/setup.sh index 758d1f1a285896443f94893c4f38c1d36d17e0ac..20224a64a7796a1fb33f56f98602a38b65c8f804 100755 --- a/gitlab-ci/setup.sh +++ b/gitlab-ci/setup.sh @@ -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/ diff --git a/gitlab-ci/shared.sh b/gitlab-ci/shared.sh index d0e0fcf30ab4faf3f77dc86a5cdeb91a3684bede..149f827aec794ce1dc3159ea9152439e87e32ac7 100755 --- a/gitlab-ci/shared.sh +++ b/gitlab-ci/shared.sh @@ -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 +} + diff --git a/gitlab-ci/tools-test.sh b/gitlab-ci/tools-test.sh index 7ae0ba5e82d530c505d123823086eb67f3cd7141..189481ad4c5b4156748e8844d01a527eba1204a5 100755 --- a/gitlab-ci/tools-test.sh +++ b/gitlab-ci/tools-test.sh @@ -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" diff --git a/gitlab-ci/unit-test.sh b/gitlab-ci/unit-test.sh index 765b1f5e130c89affc02aa895ecee3b095a02dfb..a762ca8699f26aff4f9a3076a5ca404fe1e0f4e5 100755 --- a/gitlab-ci/unit-test.sh +++ b/gitlab-ci/unit-test.sh @@ -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" diff --git a/libbbf_api/dm_plugin/dmdynamicjson.c b/libbbf_api/dm_plugin/dmdynamicjson.c index 77418600355b6b30abd26aa099cf8b525ff8f9fd..a8ca0969bac64dfa2e006f15702a1976e706af95 100644 --- a/libbbf_api/dm_plugin/dmdynamicjson.c +++ b/libbbf_api/dm_plugin/dmdynamicjson.c @@ -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))) { diff --git a/libbbf_api/dm_plugin/dmdynamiclibrary.c b/libbbf_api/dm_plugin/dmdynamiclibrary.c index 1e39ff79b25e219f5f685090fce1ca2cd2dbc34c..a9292ce270a88da20d4a7fe771ca549095e17322 100644 --- a/libbbf_api/dm_plugin/dmdynamiclibrary.c +++ b/libbbf_api/dm_plugin/dmdynamiclibrary.c @@ -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); } diff --git a/libbbf_api/dmapi.h b/libbbf_api/dmapi.h index 89c97232b6d904729bd03b538bd191bcf2ca89a2..2fb4df8a1ed3763985332f2f9e6103e46af71875 100644 --- a/libbbf_api/dmapi.h +++ b/libbbf_api/dmapi.h @@ -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, diff --git a/libbbf_api/dmbbf.c b/libbbf_api/dmbbf.c index d4bd2c1e96f4f7cf30b7ebc1a6dcef624c9b3e34..d6e75f42d96cc7cf93d737a6afae9eb71f74de42 100644 --- a/libbbf_api/dmbbf.c +++ b/libbbf_api/dmbbf.c @@ -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(¶m_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(¶m_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; } diff --git a/libbbf_api/dmbbf.h b/libbbf_api/dmbbf.h index 9d020f43ea619c157257b5160a0e868310f21480..05f94a599b2e2921e49617bb6b7727fcfb41c95b 100644 --- a/libbbf_api/dmbbf.h +++ b/libbbf_api/dmbbf.h @@ -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) { diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index 4d64fedeaedeb447fbf61a86f9b03ed3577f7d4b..31b33caa97806768a9478546cae1fab4552cb20f 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -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; diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 3c0986803dd9573f600b5478db3b2eb726cd6a08..429eb6ce370ececf1341659b7553c014ac75bb72 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -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); diff --git a/libbbf_api/dmentry.c b/libbbf_api/dmentry.c index 4cc0b0dd01686f70cf3009d0dd114f92b008dec5..f927c75c24f5108109e2722d4efde3ae7a6dce43 100644 --- a/libbbf_api/dmentry.c +++ b/libbbf_api/dmentry.c @@ -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; + 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(); +} - // initialise with default value - buff[0] = '\0'; +void bbf_ctx_clean(struct dmctx *ctx) +{ + free_all_list_parameter(ctx); - return dm_browse_last_access_path(buff, len); + dm_uci_exit(); + dmubus_free(); + dmcleanmem(); } -int usp_fault_map(int fault) +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(&global_memhead); + free_dynamic_arrays(dm_entryobj); +} + +int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]) +{ + if (!value || !objects) + return -1; + + if (*value == '\0') + return 0; - dm_dynamic_cleanmem(&main_memhead); - free_dm_browse_node_dynamic_object_tree(&node, root); + 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 set_bbfdatamodel_type(int bbf_type) +int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, char **value) { - bbfdatamodel_type = bbf_type; + 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); +} diff --git a/libbbf_api/dmentry.h b/libbbf_api/dmentry.h index 11945f20bb27bd78fe4d422ade9ae056f14e882e..402832d4aea45cf52fc588cd851e2b396a9a28d2 100644 --- a/libbbf_api/dmentry.h +++ b/libbbf_api/dmentry.h @@ -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__ diff --git a/libbbf_api/dmmem.c b/libbbf_api/dmmem.c index 916bb43ba235d0aa1daf1d5b6cbe553566799eea..56d57b76b997eeb99b779bc18bb3630fd78a31b2 100644 --- a/libbbf_api/dmmem.c +++ b/libbbf_api/dmmem.c @@ -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; } diff --git a/libbbf_api/dmmem.h b/libbbf_api/dmmem.h index 265b93b9b90e753cca4ece4339067cf48d92ad38..b3bcf18f1cf7fcda7c70dd085987804b3378a681 100644 --- a/libbbf_api/dmmem.h +++ b/libbbf_api/dmmem.h @@ -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 */ diff --git a/libbbf_api/dmubus.c b/libbbf_api/dmubus.c index 69f66481ec35005f484fddd0302cdfa8ce1068c5..fa36cf4cc88cb1a7b790b3f2b7beef0bd3af24a2 100644 --- a/libbbf_api/dmubus.c +++ b/libbbf_api/dmubus.c @@ -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) diff --git a/libbbf_api/dmuci.c b/libbbf_api/dmuci.c index 40ed83d8ce6ebc2b8d65dcfabd5c9b1fcafb77a5..11ed351f755a4300621ba2699ae46920ebb32368 100644 --- a/libbbf_api/dmuci.c +++ b/libbbf_api/dmuci.c @@ -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); } } diff --git a/libbbf_api/dmuci.h b/libbbf_api/dmuci.h index 310e0947468bdb2db9bf5958f4e7e766a53026d0..2e30ca1f383a0c354c39ff7c397c339e64028891 100644 --- a/libbbf_api/dmuci.h +++ b/libbbf_api/dmuci.h @@ -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); diff --git a/libbbf_api/include/libbbf_api.h b/libbbf_api/include/libbbf_api.h index 4a228f5eef1b293ad8d2652a3ebf96009bc35150..71e2bed61f6dbc15ca2b6c48e43110f9ba16d329 100644 --- a/libbbf_api/include/libbbf_api.h +++ b/libbbf_api/include/libbbf_api.h @@ -31,7 +31,7 @@ #include <libubox/list.h> #include <json-c/json.h> -#include "libbbf_api/dmapi.h" +#include <libbbf_api/dmapi.h> /******************* * diff --git a/libbbf_dm/CMakeLists.txt b/libbbf_dm/CMakeLists.txt index 0b5d08438457070df65a1fc44d403834017b9c56..e39c4de80bd5385f44a56778c65eec2242ccb2dd 100644 --- a/libbbf_dm/CMakeLists.txt +++ b/libbbf_dm/CMakeLists.txt @@ -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) diff --git a/libbbf_dm/dmdiagnostics.c b/libbbf_dm/dmdiagnostics.c index d87e085f75db0805e35600d2257c33f47ca334b5..bf696c6e637e024164f8b9dc51933e6c88dc5184 100644 --- a/libbbf_dm/dmdiagnostics.c +++ b/libbbf_dm/dmdiagnostics.c @@ -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); } diff --git a/libbbf_dm/dmtree/tr104/common.c b/libbbf_dm/dmtree/tr104/common.c index 6c22cb4480f591ed3fb211eb2e728fd1645d332c..fea5f9250e22a6a2270e2f211d07162ca6748115 100644 --- a/libbbf_dm/dmtree/tr104/common.c +++ b/libbbf_dm/dmtree/tr104/common.c @@ -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; diff --git a/libbbf_dm/dmtree/tr143/diagnostics.c b/libbbf_dm/dmtree/tr143/diagnostics.c index 8ff0663953f813dec7a95593dfa260d6cc855f33..3b1988aefddc9ac6ef6cfa1807817c8d72e43ed7 100644 --- a/libbbf_dm/dmtree/tr143/diagnostics.c +++ b/libbbf_dm/dmtree/tr143/diagnostics.c @@ -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{ diff --git a/libbbf_dm/dmtree/tr181/device.c b/libbbf_dm/dmtree/tr181/device.c index 493b64d808e9cda5d7963ebb2a76b3edf401e521..72b3d61f5b76cca136e65181772377fe500a2b54 100644 --- a/libbbf_dm/dmtree/tr181/device.c +++ b/libbbf_dm/dmtree/tr181/device.c @@ -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; } diff --git a/libbbf_dm/dmtree/tr181/deviceinfo.c b/libbbf_dm/dmtree/tr181/deviceinfo.c index d442ff6672f12ad909e6fce6b16c7d1c467c9be2..14a5bb889196c8a3b20a8f7616765d9cc9468fa4 100644 --- a/libbbf_dm/dmtree/tr181/deviceinfo.c +++ b/libbbf_dm/dmtree/tr181/deviceinfo.c @@ -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; diff --git a/libbbf_dm/dmtree/tr181/dns.c b/libbbf_dm/dmtree/tr181/dns.c index 71eb1825134f3226fdf46cbd7627cbc26064ba50..e5c8bade8ccc72d63861828af5f4e08e658a58ba 100644 --- a/libbbf_dm/dmtree/tr181/dns.c +++ b/libbbf_dm/dmtree/tr181/dns.c @@ -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{ diff --git a/libbbf_dm/dmtree/tr181/firewall.c b/libbbf_dm/dmtree/tr181/firewall.c index 49f42724ac5322a1cc8d2a81d9e760121289ea7e..08495e6fa7cb5d60cc0107b6d18477183d68b20e 100644 --- a/libbbf_dm/dmtree/tr181/firewall.c +++ b/libbbf_dm/dmtree/tr181/firewall.c @@ -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); } } diff --git a/libbbf_dm/dmtree/tr181/ssh.c b/libbbf_dm/dmtree/tr181/ssh.c index 6d98967ff64fc89365f3b7ca62376d100cbc11db..c2f63024d1b4223f9cb03ca195e9626f2fa7faac 100644 --- a/libbbf_dm/dmtree/tr181/ssh.c +++ b/libbbf_dm/dmtree/tr181/ssh.c @@ -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); } } diff --git a/libbbf_dm/dmtree/tr181/userinterface.c b/libbbf_dm/dmtree/tr181/userinterface.c index 4e73cb35d3dff1bd506f11b85bf0146dad9e999f..011b2c8421e29ddbcfba7b64f0abc573d0a4c1fc 100644 --- a/libbbf_dm/dmtree/tr181/userinterface.c +++ b/libbbf_dm/dmtree/tr181/userinterface.c @@ -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); } } diff --git a/libbbf_dm/dmtree/tr181/wifi.c b/libbbf_dm/dmtree/tr181/wifi.c index 8224a11724370a87b3192de3e75baa21b1e44d8f..4417ccd2ee31afbf4d1e336a2a28d158f608efa6 100644 --- a/libbbf_dm/dmtree/tr181/wifi.c +++ b/libbbf_dm/dmtree/tr181/wifi.c @@ -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"); } diff --git a/libbbf_dm/dmtree/tr471/iplayercap.c b/libbbf_dm/dmtree/tr471/iplayercap.c index aaf5cc2bdd244ed1b3f0bedf35577f04611f88da..199572c809c0554504817c7920e642600a042aef 100644 --- a/libbbf_dm/dmtree/tr471/iplayercap.c +++ b/libbbf_dm/dmtree/tr471/iplayercap.c @@ -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); diff --git a/libbbf_dm/scripts/bbf_activate_handler.sh b/libbbf_dm/scripts/bbf_activate_handler.sh index f5a43a41f8e381f02590ffed9cfbe85272ad3347..62e1e7dc7062212b23ccd79c8a97ff33854d706b 100755 --- a/libbbf_dm/scripts/bbf_activate_handler.sh +++ b/libbbf_dm/scripts/bbf_activate_handler.sh @@ -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() { diff --git a/schemas/ubus/bbf.json b/schemas/ubus/bbf.json new file mode 100644 index 0000000000000000000000000000000000000000..691345442a7ca64f9bffca8c77c17aed33b1a168 --- /dev/null +++ b/schemas/ubus/bbf.json @@ -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": {} + } + } + } +} diff --git a/schemas/uci/bbfd.json b/schemas/uci/bbfd.json new file mode 100644 index 0000000000000000000000000000000000000000..4a2016df211a4e0b7a1fcfe2da6317087c5e3e4f --- /dev/null +++ b/schemas/uci/bbfd.json @@ -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." + } + ] + } + ] +} diff --git a/supervisord.conf b/supervisord.conf deleted file mode 100644 index f9d1afc54179c680ce04e4f1569c1dbcaf9e61a4..0000000000000000000000000000000000000000 --- a/supervisord.conf +++ /dev/null @@ -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 - diff --git a/test/api/json/dmtest.validation.json b/test/api/json/dmtest.validation.json deleted file mode 100644 index 7c8b856dbaf38681e4e7f70a44463070dfc90cd4..0000000000000000000000000000000000000000 --- a/test/api/json/dmtest.validation.json +++ /dev/null @@ -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 - } - ] -} diff --git a/test/bbf_test/Makefile b/test/bbf_test/Makefile index 639262b8d00ba102b2350a7397bd40acac8dc290..b9c11a9994a57bcf25f7b0da8f217819b5f8b8ac 100644 --- a/test/bbf_test/Makefile +++ b/test/bbf_test/Makefile @@ -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 $@ $< diff --git a/test/bbf_test/bbf_dm.c b/test/bbf_test/bbf_dm.c index ec74d8a88048506cb2b6ac784055a0ec5257fda3..e79d91db36367d7972ccb476785452042f88ee4b 100644 --- a/test/bbf_test/bbf_dm.c +++ b/test/bbf_test/bbf_dm.c @@ -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]); + + bbf_ctx.instance_mode = INSTANCE_MODE_NUMBER; - dm_ctx_init(&bbf_ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, 0); + if (DM_STRCMP(argv[1], "-c") == 0) + bbf_ctx.dm_type = BBFDM_CWMP; + else + bbf_ctx.dm_type = BBFDM_USP; - if (arg2 && *arg2) { - bbf_ctx.dm_version = arg2; - printf("config version %s\n", bbf_ctx.dm_version); + 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; - } - - 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]; + bbf_dm_exec(argc, argv); - 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); } diff --git a/test/bbf_test/libbbf_test.c b/test/bbf_test/libbbf_test.c index 7e02fef1976bd1ad299edbb8a993867aae5e7761..476cee4e6e39a32659bf31c08a9a76cd7ae274aa 100644 --- a/test/bbf_test/libbbf_test.c +++ b/test/bbf_test/libbbf_test.c @@ -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*/ diff --git a/test/bbf_test/libbbf_test.h b/test/bbf_test/libbbf_test.h index fdc7e2f8682d36f725f9949d59b9521b752a681f..4fb3347a434fc8d0b139fc6ae1d9f5363b8af0bb 100644 --- a/test/bbf_test/libbbf_test.h +++ b/test/bbf_test/libbbf_test.h @@ -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[]; diff --git a/test/cmocka/Makefile b/test/cmocka/Makefile index 79056ed5fbceb73b470f63807a59b83245bc1ac0..63e6c762209f5966bd2076b023ff1bcfcb0e61ea 100644 --- a/test/cmocka/Makefile +++ b/test/cmocka/Makefile @@ -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 diff --git a/test/cmocka/functional_api_test_bbfd.c b/test/cmocka/functional_api_test_bbfd.c index 9bc09f4df623bd2fac05d557900eeae8195f4dc4..0b57a1f77f0ee57475e747bd908f504c568f6f4f 100644 --- a/test/cmocka/functional_api_test_bbfd.c +++ b/test/cmocka/functional_api_test_bbfd.c @@ -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; } diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c index 1627418f89a233e9d56c9ed7f6a79f9654480d3a..65139b2ed70db17a3b163d894cd58b6e9e1112d9 100644 --- a/test/cmocka/functional_test_bbfd.c +++ b/test/cmocka/functional_test_bbfd.c @@ -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> @@ -16,37 +16,14 @@ static DM_MAP_VENDOR *TR181_VENDOR_EXTENSION[2] = { }; static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude; -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; @@ -56,8 +33,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; @@ -65,12 +42,7 @@ static int teardown_commit(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; } @@ -79,8 +51,8 @@ static void validate_parameter(struct dmctx *ctx, const char *name, const char * { struct dm_parameter *n; - 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_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -101,26 +73,28 @@ static void test_api_bbfdm_get_set_standard_parameter(void **state) int fault = 0; // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Channel", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.1.Channel"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.Radio.1.Channel", "1", "xsd:unsignedInt"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Channel", "64t", NULL); + ctx->in_param = "Device.WiFi.Radio.1.Channel"; + ctx->in_value = "64t"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Channel", "64", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.WiFi.Radio.1.Channel"; + ctx->in_value = "64"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Channel", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.1.Channel"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter after setting to 64: name, type, value @@ -133,57 +107,40 @@ static void test_api_bbfdm_get_set_json_parameter(void **state) int fault = 0; // get value ==> expected "0" error - //fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.CurrentLanguage", NULL, NULL); - //assert_int_equal(fault, 0); - - // validate parameter : name, type, value - //validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "en", "xsd:string"); - - // set value ==> expected "0" error - //fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UserInterface.CurrentLanguage", "fr", NULL); - //assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - //fault = dm_entry_apply(ctx, CMD_SET_VALUE); - //assert_int_equal(fault, 0); - - // get value ==> expected "0" error - //fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.CurrentLanguage", NULL, NULL); - //assert_int_equal(fault, 0); - - // validate parameter after setting to fr: name, type, value - //validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "fr", "xsd:string"); - - // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.X_IOPSYS_EU_Radio.1.Noise", NULL, NULL); + ctx->in_param = "Device.WiFi.X_IOPSYS_EU_Radio.1.Noise"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.X_IOPSYS_EU_Radio.2.Noise", "-87", "xsd:int"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.X_IOPSYS_EU_Radio.2.Noise", NULL, NULL); + ctx->in_param = "Device.WiFi.X_IOPSYS_EU_Radio.2.Noise"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.X_IOPSYS_EU_Radio.2.Noise", "-85", "xsd:int"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.X_IOPSYS_EU_Radio.2.Band", NULL, NULL); + ctx->in_param = "Device.WiFi.X_IOPSYS_EU_Radio.2.Band"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.X_IOPSYS_EU_Radio.2.Band", "2.4GHz", "xsd:string"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.X_IOPSYS_EU_Radio.1.Stats.BytesSent", NULL, NULL); + ctx->in_param = "Device.WiFi.X_IOPSYS_EU_Radio.1.Stats.BytesSent"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.X_IOPSYS_EU_Radio.1.Stats.BytesSent", "14418177,", "xsd:unsignedInt"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.X_IOPSYS_EU_Radio.2.Stats.BytesSent", NULL, NULL); + ctx->in_param = "Device.WiFi.X_IOPSYS_EU_Radio.2.Stats.BytesSent"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value @@ -197,22 +154,22 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state) int fault = 0; // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.Password", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.Password"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.Password", "", "xsd:string"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.Password", "iopsys_test", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.UCI_TEST_V1.Password"; + ctx->in_value = "iopsys_test"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.Password", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.Password"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value @@ -224,81 +181,86 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state) assert_string_equal(value, "iopsys_test"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSDNumberOfEntries", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSDNumberOfEntries"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSDNumberOfEntries", "3", "xsd:unsignedInt"); // set value ==> expected "9008" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.OWSDNumberOfEntries", "5", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSDNumberOfEntries"; + ctx->in_value = "5"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9008); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.2.IPv6", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.2.IPv6"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.2.IPv6", "off", "xsd:unsignedInt"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.OWSD.2.IPv6", "on", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.2.IPv6"; + ctx->in_value = "on"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.2.IPv6", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.2.IPv6"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.2.IPv6", "on", "xsd:unsignedInt"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.1.Port", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.1.Port"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.1.Port", "80", "xsd:unsignedInt"); // set value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.OWSD.1.Port", "65536", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.1.Port"; + ctx->in_value = "65536"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.OWSD.1.Port", "8081", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.1.Port"; + ctx->in_value = "8081"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.1.Port", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.1.Port"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.1.Port", "8081", "xsd:unsignedInt"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.3.Password", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UCI_TEST_V1.OWSD.3.Password", "", "xsd:string"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UCI_TEST_V1.OWSD.3.Password", "owsd_pwd", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password"; + ctx->in_value = "owsd_pwd"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UCI_TEST_V1.OWSD.3.Password", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value @@ -310,62 +272,73 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state) assert_string_equal(value, "owsd_pwd"); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UBUS_TEST_V1.Uptime", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Uptime"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UBUS_TEST_V1.Uptime", "5859", "xsd:string"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UBUS_TEST_V1.Uptime", "lan", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.UBUS_TEST_V1.Uptime"; + ctx->in_value = "lan"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UBUS_TEST_V1.InterfaceNumberOfEntries", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.InterfaceNumberOfEntries"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UBUS_TEST_V1.InterfaceNumberOfEntries", "10", "xsd:unsignedInt"); // set value ==> expected "9008" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UBUS_TEST_V1.InterfaceNumberOfEntries", "5", NULL); + ctx->in_param = "Device.UBUS_TEST_V1.InterfaceNumberOfEntries"; + ctx->in_value = "5"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9008); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UBUS_TEST_V1.Interface.3.MacAddress", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.3.MacAddress"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UBUS_TEST_V1.Interface.3.MacAddress", "60:8d:26:c4:96:f7", "xsd:string"); // set value ==> expected "9008" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UBUS_TEST_V1.Interface.3.MacAddress", "49:d4:40:71:7e:55", NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.3.MacAddress"; + ctx->in_value = "49:d4:40:71:7e:55"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9008); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UBUS_TEST_V1.Interface.4.Ifname", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.4.Ifname"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UBUS_TEST_V1.Interface.4.Ifname", "eth4", "xsd:string"); // set value ==> expected "9008" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UBUS_TEST_V1.Interface.4.Ifname", "lan5", NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.4.Ifname"; + ctx->in_value = "lan5"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9008); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UBUS_TEST_V1.Interface.2.Media", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.2.Media"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.UBUS_TEST_V1.Interface.2.Media", "IEEE 802_3AB_GIGABIT_ETHERNET", "xsd:string"); // set value ==> expected "9008" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UBUS_TEST_V1.Interface.2.Media", "IEEE 802_11AX_5_GHZ", NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.2.Media"; + ctx->in_value = "IEEE 802_11AX_5_GHZ"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9008); } @@ -375,26 +348,28 @@ static void test_api_bbfdm_get_set_library_parameter(void **state) int fault = 0; // get value ==> expected "0" error - 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); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.SSID.1.Enable", "1", "xsd:boolean"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.SSID.1.Enable", "truee", NULL); + ctx->in_param = "Device.WiFi.SSID.1.Enable"; + ctx->in_value = "truee"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.SSID.1.Enable", "0", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.WiFi.SSID.1.Enable"; + ctx->in_value = "0"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - 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); // validate parameter after setting to 0: name, type, value @@ -406,63 +381,66 @@ static void test_api_bbfdm_get_set_standard_parameter_alias(void **state) struct dmctx *ctx = (struct dmctx *) *state; int fault = 0; + ctx->instance_mode = INSTANCE_MODE_ALIAS; + // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.[cpe-1].Channel", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.[cpe-1].Channel"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter : name, type, value validate_parameter(ctx, "Device.WiFi.Radio.[cpe-1].Channel", "64", "xsd:unsignedInt"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.[cpe-1].Channel", "64t", NULL); + ctx->in_param = "Device.WiFi.Radio.[cpe-1].Channel"; + ctx->in_value = "64t"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.[cpe-1].Channel", "84", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.WiFi.Radio.[cpe-1].Channel"; + ctx->in_value = "84"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.[cpe-1].Channel", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.[cpe-1].Channel"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter after setting to 64: name, type, value validate_parameter(ctx, "Device.WiFi.Radio.[cpe-1].Channel", "84", "xsd:unsignedInt"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.[cpe-1].Alias", "iopsys_test", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.WiFi.Radio.[cpe-1].Alias"; + ctx->in_value = "iopsys_test"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.[iopsys_test].Alias", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.[iopsys_test].Alias"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter after setting to 64: name, type, value validate_parameter(ctx, "Device.WiFi.Radio.[iopsys_test].Alias", "iopsys_test", "xsd:string"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.[iopsys_test].Channel", "74", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + ctx->in_param = "Device.WiFi.Radio.[iopsys_test].Channel"; + ctx->in_value = "74"; + fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.[iopsys_test].Channel", NULL, NULL); + ctx->in_param = "Device.WiFi.Radio.[iopsys_test].Channel"; + fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); // validate parameter after setting to 64: name, type, value validate_parameter(ctx, "Device.WiFi.Radio.[iopsys_test].Channel", "74", "xsd:unsignedInt"); } +#if 0 static void test_api_bbfdm_input_value_validation_json_parameter(void **state) { struct dmctx *ctx = (struct dmctx *) *state; @@ -473,23 +451,19 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "64t", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "64t", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "truee", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "truee", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "true", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", "true", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Enable", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -500,53 +474,41 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Mapping without range: Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "64t", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "64t", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "15600", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "15600", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_Retries", "15600", "xsd:unsignedInt"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1050", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1050", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [0-1000] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1000", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "1000", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Port", "1000", "xsd:unsignedInt"); // Mapping with range: set value in the second range [15000-65535] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "20546", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", "20546", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Port", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -557,72 +519,56 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Mapping with range (only min): Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-300", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-300", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-273", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-273", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Min_value", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Min_value", "-273", "xsd:int"); // Mapping with range (only max): Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "280", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "280", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [0-1000] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "274", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", "274", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Max_value", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Max_value", "274", "xsd:int"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-3", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-3", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [-10:-5] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-7", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "-7", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.value", "-7", "xsd:int"); // Mapping with range: set value in the second range [-1:10] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "1", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", "1", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Value", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -633,53 +579,41 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Mapping without range: Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "64t", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "64t", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "15600", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "15600", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_bytes", "15600", "xsd:unsignedLong"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "499", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "499", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [0-100] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "99", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "99", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "99", "xsd:unsignedLong"); // Mapping with range: set value in the second range [500-3010] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "1024", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", "1024", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Nbr_packets", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -690,57 +624,45 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Mapping without range: Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-300t", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-300t", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-273", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-273", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.MaxTxPower", "-273", "xsd:long"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "-91", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "-91", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [-90:36] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "274", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "274", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "274", "xsd:long"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "37", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "37", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [70:360] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "70", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", "70", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerLimit", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -751,23 +673,19 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2030-01-01T11:22:33.2Z", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2030-01-01T11:22:33.2Z", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22.2222Z", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22.2222Z", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22Z", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", "2022-01-01T12:20:22Z", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.AssociationTime", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -778,72 +696,56 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Mapping without range: Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64t", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64t", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64ab78cef12", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64ab78cef12", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.ButtonColor", "64ab78cef12", "xsd:hexBinary"); // Mapping with range: Set Wrong Value out of range ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "am123", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "am123", NULL); assert_int_equal(fault, FAULT_9007); // Mapping with range: set value in the first range [3-3] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "123abc", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "123abc", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TextColor", "123abc", "xsd:hexBinary"); // Mapping with range: set value in the second range [5-5] ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "12345abcde", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", "12345abcde", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TextColor", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.TextColor", "12345abcde", "xsd:hexBinary"); // Mapping without range: Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "12345abce", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "12345abce", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "45a1bd", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", "45a1bd", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.BackgroundColor", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -854,72 +756,56 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "64", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "64", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "wan", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", "wan", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Interface", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Interface", "wan", "xsd:string"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.1.789", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.1.789", NULL); assert_int_equal(fault, FAULT_9007); // Set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.117.45", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.117.45", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.IPAddr", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.IPAddr", "192.168.117.45", "xsd:string"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-D", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-D", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-DM", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-DM", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Protocol", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.Protocol", "OMA-DM", "xsd:string"); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", "bbf validate test", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", "bbf validate test", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.Description", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -930,46 +816,38 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "te,be,re,yu", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "te,be,re,yu", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "ExcessiveDelay,InsufficientBuffers", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "ExcessiveDelay,InsufficientBuffers", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "LowRate,Other", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "LowRate,Other", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.FailureReasons", "LowRate,Other", "xsd:string"); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "200MHz,10MHz", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "200MHz,10MHz", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "ExcessiveDelay,InsufficientBuffers", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "ExcessiveDelay,InsufficientBuffers", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "40MHz,80+80MHz", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", "40MHz,80+80MHz", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.SupportedOperatingChannelBandwidths", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -980,23 +858,19 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-5,-3,99,120", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-5,-3,99,120", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,990", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,990", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,100", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", "-1,9,100", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.TransmitPowerSupported", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value @@ -1007,40 +881,39 @@ static void test_api_bbfdm_input_value_validation_json_parameter(void **state) */ // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "8,1,2,3", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "8,1,2,3", NULL); assert_int_equal(fault, FAULT_9007); // Set Wrong Value ==> expected "9007" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "1,2,3,4,5,6,7,8", NULL); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "1,2,3,4,5,6,7,8", NULL); assert_int_equal(fault, FAULT_9007); // set value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "0,1,2,3,4,5,6,7", NULL); - assert_int_equal(fault, 0); - - // apply value ==> expected "0" error - fault = dm_entry_apply(ctx, CMD_SET_VALUE); + fault = bbf_entry_method(ctx, BBF_SET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "0,1,2,3,4,5,6,7", NULL); assert_int_equal(fault, 0); // get value ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", NULL, NULL); + fault = bbf_entry_method(ctx, BBF_GET_VALUE, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", NULL, NULL); assert_int_equal(fault, 0); // validate parameter after setting to true: name, type, value validate_parameter(ctx, "Device.X_IOPSYS_EU_TEST.1.PriorityRegeneration", "0,1,2,3,4,5,6,7", "xsd:string"); } - +#endif static void test_api_bbfdm_add_del_standard_object(void **state) { struct dmctx *ctx = (struct dmctx *) *state; int fault = 0; // Get name object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.", "1", NULL); + ctx->in_param = "Device.Users.User."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, 0); // add object ==> expected "0" error - 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); // check the new instance @@ -1048,19 +921,25 @@ static void test_api_bbfdm_add_del_standard_object(void **state) assert_string_equal(ctx->addobj_instance, "2"); // delete object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Users.User.2.", NULL, NULL); + ctx->in_param = "Device.Users.User.2."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); // Get name object after deleting instance 2 ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.2.", "1", NULL); + ctx->in_param = "Device.Users.User.2."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); // delete all object ==> expected "0" error - 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); // Get name object after deleting all instances ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.1.", "1", NULL); + ctx->in_param = "Device.Users.User.1."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); } @@ -1070,11 +949,14 @@ static void test_api_bbfdm_add_del_json_object(void **state) int fault = 0; // Get name object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.", "1", NULL); + ctx->in_param = "Device.X_IOPSYS_EU_Dropbear."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, 0); // add object ==> expected "0" error - 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); // check the new instance @@ -1082,19 +964,25 @@ static void test_api_bbfdm_add_del_json_object(void **state) assert_string_equal(ctx->addobj_instance, "2"); // delete object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.2.", NULL, NULL); + ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.2."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); // Get name object after deleting instance 2 ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.2.", "1", NULL); + ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.2."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); // delete all object ==> expected "0" error - 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); // Get name object after deleting all instances ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.1.", "1", NULL); + ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.1."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); } @@ -1104,11 +992,14 @@ static void test_api_bbfdm_add_del_json_v1_object(void **state) int fault = 0; // Get name object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.UCI_TEST_V1.OWSD.", "1", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, 0); // add object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.UCI_TEST_V1.OWSD.", "test", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD."; + fault = bbf_entry_method(ctx, BBF_ADD_OBJECT); assert_int_equal(fault, 0); // check the new instance @@ -1116,27 +1007,35 @@ static void test_api_bbfdm_add_del_json_v1_object(void **state) assert_string_equal(ctx->addobj_instance, "4"); // delete object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.UCI_TEST_V1.OWSD.2.", NULL, NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.2."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); // Get name object after deleting instance 2 ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.UCI_TEST_V1.OWSD.2.", "1", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.2."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); // delete all object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.UCI_TEST_V1.OWSD.", "test", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); // Get name object after deleting all instances ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.UCI_TEST_V1.OWSD.1.", "1", NULL); + ctx->in_param = "Device.UCI_TEST_V1.OWSD.1."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); // add object ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.UBUS_TEST_V1.Interface.", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface."; + fault = bbf_entry_method(ctx, BBF_ADD_OBJECT); assert_int_equal(fault, FAULT_9005); // delete all object ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.UBUS_TEST_V1.Interface.", "test", NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, FAULT_9005); } @@ -1146,11 +1045,14 @@ static void test_api_bbfdm_add_del_library_object(void **state) int fault = 0; // Get name object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.SSID.", "1", NULL); + ctx->in_param = "Device.WiFi.SSID."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, 0); // add object ==> expected "0" error - 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); // check the new instance @@ -1158,30 +1060,38 @@ static void test_api_bbfdm_add_del_library_object(void **state) assert_string_equal(ctx->addobj_instance, "4"); // delete object ==> expected "0" error - fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID.2.", NULL, NULL); + ctx->in_param = "Device.WiFi.SSID.2."; + fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); // Get name object after deleting instance 2 ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.2.", "1", NULL); + ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.2."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); // delete all object ==> expected "0" error - 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); // Get name object after deleting all instances ==> expected "9005" error - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.SSID.1.", "1", NULL); + ctx->in_param = "Device.WiFi.SSID.1."; + ctx->nextlevel = true; + fault = bbf_entry_method(ctx, BBF_GET_NAME); assert_int_equal(fault, FAULT_9005); } static void test_api_bbfdm_valid_standard_operate(void **state) { struct dmctx *ctx = (struct dmctx *) *state; - char *input = "{\"Host\":\"iopsys.eu\",\"NumberOfRepetitions\":\"1\",\"Timeout\":\"5000\",\"DataBlockSize\":\"64\"}"; struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPPing()", input, NULL); + ctx->in_param = "Device.IP.Diagnostics.IPPing()"; + ctx->in_value = "{\"Host\":\"iopsys.eu\",\"NumberOfRepetitions\":\"1\",\"Timeout\":\"5000\",\"DataBlockSize\":\"64\"}"; + + fault = bbf_entry_method(ctx, BBF_OPERATE); assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1210,7 +1120,14 @@ static void test_api_bbfdm_valid_standard_list_operate(void **state) struct dm_parameter *n; int fault = 0, i = 0; - fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, "Device.", 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, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1278,11 +1195,13 @@ static void test_api_bbfdm_valid_standard_list_operate(void **state) static void test_api_bbfdm_valid_library_operate(void **state) { struct dmctx *ctx = (struct dmctx *) *state; - char *input = "{\"Host\":\"iopsys.eu\"}"; struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.X_IOPSYS_EU_PingTEST.Run()", input, NULL); + ctx->in_param = "Device.X_IOPSYS_EU_PingTEST.Run()"; + ctx->in_value = "{\"Host\":\"iopsys.eu\"}"; + + fault = bbf_entry_method(ctx, BBF_OPERATE); assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1296,7 +1215,14 @@ static void test_api_bbfdm_valid_library_list_operate(void **state) struct dm_parameter *n; int fault = 0, i = 0; - fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, "Device.", 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, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1350,7 +1276,9 @@ static void test_api_bbfdm_valid_json_operate(void **state) struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.X_IOPSYS_EU_TEST.1.Status()", NULL, NULL); + ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Status()"; + + fault = bbf_entry_method(ctx, BBF_OPERATE); assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1366,7 +1294,14 @@ static void test_api_bbfdm_valid_json_list_operate(void **state) struct dm_parameter *n; int fault = 0, i = 0; - fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, "Device.", 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, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1408,7 +1343,9 @@ static void test_api_bbfdm_valid_json_v1_operate(void **state) struct dm_parameter *n; int fault = 0; - fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.UBUS_TEST_V1.Interface.3.Status()", NULL, NULL); + ctx->in_param = "Device.UBUS_TEST_V1.Interface.3.Status()"; + + fault = bbf_entry_method(ctx, BBF_OPERATE); assert_int_equal(fault, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1424,7 +1361,14 @@ static void test_api_bbfdm_valid_json_v1_list_operate(void **state) struct dm_parameter *n; int fault = 0, i = 0; - fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, "Device.", 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, CMD_SUCCESS); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1472,7 +1416,14 @@ static void test_api_bbfdm_valid_library_event(void **state) struct dm_parameter *n; int fault = 0, idx = 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); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1509,7 +1460,7 @@ static void test_api_bbfdm_valid_library_event(void **state) idx++; } - assert_int_equal(idx, 8); + assert_int_equal(idx, 9); } static void test_api_bbfdm_valid_json_event(void **state) @@ -1518,7 +1469,14 @@ static void test_api_bbfdm_valid_json_event(void **state) struct dm_parameter *n; int fault = 0, idx = 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); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1549,7 +1507,7 @@ static void test_api_bbfdm_valid_json_event(void **state) idx++; } - assert_int_equal(idx, 8); + assert_int_equal(idx, 9); } static void test_api_bbfdm_valid_json_v1_event(void **state) @@ -1558,7 +1516,14 @@ static void test_api_bbfdm_valid_json_v1_event(void **state) struct dm_parameter *n; int fault = 0, idx = 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); list_for_each_entry(n, &ctx->list_parameter, list) { @@ -1591,7 +1556,7 @@ static void test_api_bbfdm_valid_json_v1_event(void **state) idx++; } - assert_int_equal(idx, 8); + assert_int_equal(idx, 9); } int main(void) @@ -1602,9 +1567,10 @@ int main(void) cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_json_parameter, setup, teardown_commit), cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_json_v1_parameter, setup, teardown_commit), cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_library_parameter, setup, teardown_commit), - cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_standard_parameter_alias, setup_alias, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_standard_parameter_alias, setup, teardown_commit), +#if 0 cmocka_unit_test_setup_teardown(test_api_bbfdm_input_value_validation_json_parameter, setup, teardown_commit), - +#endif // Add/Delete Object method test cases cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_standard_object, setup, teardown_commit), cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_json_object, setup, teardown_commit), @@ -1627,7 +1593,7 @@ int main(void) cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_json_v1_event, setup, teardown_commit), }; - return cmocka_run_group_tests(tests, group_setup, group_teardown); + return cmocka_run_group_tests(tests, NULL, group_teardown); } diff --git a/test/cmocka/unit_test_bbfd.c b/test/cmocka/unit_test_bbfd.c index 07cd5eb566832c4994354140e52b1bc2ebc4bc1d..541d04d355652b4b125d0423a5525ad3a323c63c 100644 --- a/test/cmocka/unit_test_bbfd.c +++ b/test/cmocka/unit_test_bbfd.c @@ -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; - - return 0; -} + bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE); -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,47 +207,27 @@ 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); - 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_wrong_object_path(void **state) -{ - struct dmctx *ctx = (struct dmctx *) *state; - struct dm_parameter *first_entry; - int fault = 0; + ctx->in_param = "."; + ctx->nextlevel = false; - fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFii.", "0", NULL); + 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) +static void test_api_bbfdm_get_name_wrong_object_path(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); + ctx->in_param = "Device.WiFii."; + ctx->nextlevel = false; - 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); + 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); @@ -265,7 +239,11 @@ static void test_api_bbfdm_get_name_parameter_alias(void **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); - - 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.Users.User.1.Username"; + ctx->in_value = "test"; - 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); - - 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.Users.User.[cpe-1].Username"; + ctx->in_value = "test"; + ctx->instance_mode = INSTANCE_MODE_ALIAS; - 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); - 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); - assert_int_equal(fault, 0); + ctx->in_param = "Device.UserInterface.Enable"; + ctx->in_value = "true"; - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Dropbear.1.Port", "9856", NULL); + 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); + 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); - assert_int_equal(fault, 0); + ctx->in_param = "Device.WiFi.SSID.1.Enable"; + ctx->in_value = "true"; - 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); - assert_int_equal(fault, 0); - - fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Syslog.ServerPort", "9856", NULL); + 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); + 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); } diff --git a/test/files/etc/bbfdm/json/cwmp_management_server.json b/test/files/etc/bbfdm/json/CWMPManagementServer.json similarity index 100% rename from test/files/etc/bbfdm/json/cwmp_management_server.json rename to test/files/etc/bbfdm/json/CWMPManagementServer.json diff --git a/test/files/etc/bbfdm/json/bulkdata.json b/test/files/etc/bbfdm/json/bulkdata.json deleted file mode 100644 index 52e5d642522b5dd001664f5b0e4959b133e92242..0000000000000000000000000000000000000000 --- a/test/files/etc/bbfdm/json/bulkdata.json +++ /dev/null @@ -1,1190 +0,0 @@ -{ - "Device.BulkData.": { - "type": "object", - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "access": false, - "array": false, - "Enable": { - "type": "boolean", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "bulkdata", - "name": "bulkdata" - }, - "option": { - "name": "enable" - } - } - } - ] - }, - "Status": { - "type": "string", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "enumerations": [ - "Enabled", - "Disabled", - "Error" - ] - }, - "MinReportingInterval": { - "type": "unsignedInt", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "unit": "seconds" - }, - "Protocols": { - "type": "string", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "list": { - "datatype": "string", - "enumerations": [ - "Streaming", - "File", - "HTTP", - "MQTT" - ] - } - }, - "EncodingTypes": { - "type": "string", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "list": { - "datatype": "string", - "enumerations": [ - "XML", - "XDR", - "CSV", - "JSON" - ] - } - }, - "ParameterWildCardSupported": { - "type": "boolean", - "read": true, - "write": false, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean" - }, - "MaxNumberOfProfiles": { - "type": "int", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "int", - "range": [ - { - "min": -1 - } - ] - }, - "MaxNumberOfParameterReferences": { - "type": "int", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "int", - "range": [ - { - "min": -1 - } - ] - }, - "ProfileNumberOfEntries": { - "type": "unsignedInt", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile" - }, - "option": { - "name": "@Count" - } - } - } - ] - }, - "Device.BulkData.Profile.{i}.": { - "type": "object", - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "uniqueKeys": [ - "Alias" - ], - "access": true, - "array": true, - "mapping": { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile" - }, - "dmmapfile": "dmmap_bulkdata" - } - }, - "Enable": { - "type": "boolean", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "enable" - } - } - } - ] - }, - "Alias": { - "type": "string", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "Alias", - "range": [ - { - "max": 64 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "alias" - } - } - } - ] - }, - "Name": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 255 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "name" - } - } - } - ] - }, - "NumberOfRetainedFailedReports": { - "type": "int", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "int", - "range": [ - { - "min": -1 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "nbre_of_retained_failed_reports" - } - } - } - ] - }, - "Protocol": { - "type": "string", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "protocol" - } - } - } - ] - }, - "EncodingType": { - "type": "string", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "encoding_type" - } - } - } - ] - }, - "ReportingInterval": { - "type": "unsignedInt", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "range": [ - { - "min": 1 - } - ], - "unit": "seconds", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "reporting_interval" - } - } - } - ] - }, - "TimeReference": { - "type": "dateTime", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "dateTime", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "time_reference" - } - } - } - ] - }, - "ParameterNumberOfEntries": { - "type": "unsignedInt", - "read": true, - "write": false, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_parameter" - }, - "option": { - "name": "@Count" - } - } - } - ] - }, - "Device.BulkData.Profile.{i}.Parameter.{i}.": { - "type": "object", - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "access": true, - "array": true, - "mapping": { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_parameter" - }, - "dmmapfile": "dmmap_bulkdata" - } - }, - "Name": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 64 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_parameter", - "index": "@i-1" - }, - "option": { - "name": "name" - } - } - } - ] - }, - "Reference": { - "type": "string", - "read": true, - "write": true, - "version": "2.5", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 256 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_parameter", - "index": "@i-1" - }, - "option": { - "name": "reference" - } - } - } - ] - } - }, - "Device.BulkData.Profile.{i}.CSVEncoding.": { - "type": "object", - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "access": false, - "array": false, - "FieldSeparator": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "csv_encoding_field_separator" - } - } - } - ] - }, - "RowSeparator": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "csv_encoding_row_separator" - } - } - } - ] - }, - "EscapeCharacter": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "csv_encoding_escape_character" - } - } - } - ] - }, - "ReportFormat": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "enumerations": [ - "ParameterPerRow", - "ParameterPerColumn" - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "csv_encoding_report_format" - } - } - } - ] - }, - "RowTimestamp": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "enumerations": [ - "Unix-Epoch", - "ISO-8601", - "None" - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "csv_encoding_row_time_stamp" - } - } - } - ] - } - }, - "Device.BulkData.Profile.{i}.JSONEncoding.": { - "type": "object", - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "access": false, - "array": false, - "ReportFormat": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "enumerations": [ - "ObjectHierarchy", - "NameValuePair" - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "json_encoding_report_format" - } - } - } - ] - }, - "ReportTimestamp": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "enumerations": [ - "Unix-Epoch", - "ISO-8601", - "None" - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "json_encoding_report_time_stamp" - } - } - } - ] - } - }, - "Device.BulkData.Profile.{i}.HTTP.": { - "type": "object", - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "access": false, - "array": false, - "URL": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "URL", - "range": [ - { - "max": 2048 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_url" - } - } - } - ] - }, - "Username": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 256 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_username" - } - } - } - ] - }, - "Password": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 256 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_password" - } - } - } - ] - }, - "CompressionsSupported": { - "type": "string", - "read": true, - "write": false, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "list": { - "datatype": "string", - "enumerations": [ - "GZIP", - "Compress", - "Deflate" - ] - } - }, - "Compression": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_compression" - } - } - } - ] - }, - "MethodsSupported": { - "type": "string", - "read": true, - "write": false, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "list": { - "datatype": "string", - "enumerations": [ - "POST", - "PUT" - ] - } - }, - "Method": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_method" - } - } - } - ] - }, - "UseDateHeader": { - "type": "boolean", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_use_date_header" - } - } - } - ] - }, - "RetryEnable": { - "type": "boolean", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_retry_enable" - } - } - } - ] - }, - "RetryMinimumWaitInterval": { - "type": "unsignedInt", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "range": [ - { - "min": 1, - "max": 65535 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_retry_minimum_wait_interval" - } - } - } - ] - }, - "RetryIntervalMultiplier": { - "type": "unsignedInt", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "range": [ - { - "min": 1000, - "max": 65535 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_retry_interval_multiplier" - } - } - } - ] - }, - "RequestURIParameterNumberOfEntries": { - "type": "unsignedInt", - "read": true, - "write": false, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "unsignedInt", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_http_request_uri_parameter" - }, - "option": { - "name": "@Count" - } - } - } - ] - }, - "PersistAcrossReboot": { - "type": "boolean", - "read": true, - "write": true, - "version": "2.12", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "boolean", - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile", - "index": "@i-1" - }, - "option": { - "name": "http_persist_across_reboot" - } - } - } - ] - }, - "Device.BulkData.Profile.{i}.HTTP.RequestURIParameter.{i}.": { - "type": "object", - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "access": true, - "array": true, - "mapping": { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_http_request_uri_parameter" - }, - "dmmapfile": "dmmap_bulkdata" - } - }, - "Name": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 64 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_http_request_uri_parameter", - "index": "@i-1" - }, - "option": { - "name": "name" - } - } - } - ] - }, - "Reference": { - "type": "string", - "read": true, - "write": true, - "version": "2.10", - "protocols": [ - "cwmp", - "usp" - ], - "datatype": "string", - "range": [ - { - "max": 256 - } - ], - "mapping": [ - { - "type": "uci", - "uci": { - "file": "bulkdata", - "section": { - "type": "profile_http_request_uri_parameter", - "index": "@i-1" - }, - "option": { - "name": "reference" - } - } - } - ] - } - } - } - } - } -} diff --git a/test/files/etc/config/bbfdmd b/test/files/etc/config/bbfdmd new file mode 100644 index 0000000000000000000000000000000000000000..78f0848773c74d27b6b746f5fa1e0a1ce046c7e1 --- /dev/null +++ b/test/files/etc/config/bbfdmd @@ -0,0 +1,5 @@ + +config globals 'globals' + option loglevel '1' + option refresh_time '10' + option transaction_timeout '10' diff --git a/test/funl/validation/bbf.validation.json b/test/funl/validation/bbf.validation.json new file mode 100644 index 0000000000000000000000000000000000000000..ec85259710b93e81d5326e95aacd65c881b24909 --- /dev/null +++ b/test/funl/validation/bbf.validation.json @@ -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 + } + ] +} diff --git a/test/python/validate_3536.py b/test/python/validate_3536.py new file mode 100755 index 0000000000000000000000000000000000000000..02007a4bad868b0604b9047607e6df39e0099a87 --- /dev/null +++ b/test/python/validate_3536.py @@ -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) diff --git a/test/python/validate_device.py b/test/python/validate_device.py new file mode 100755 index 0000000000000000000000000000000000000000..0ce5ea4d4be8894badbe8924bdb564898dbbbabf --- /dev/null +++ b/test/python/validate_device.py @@ -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) diff --git a/test/python/validate_invalid_transaction_id.py b/test/python/validate_invalid_transaction_id.py new file mode 100755 index 0000000000000000000000000000000000000000..cb2da7d04238af96e2a9270d1d618542917d07af --- /dev/null +++ b/test/python/validate_invalid_transaction_id.py @@ -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) diff --git a/test/python/validate_schema_notify.py b/test/python/validate_schema_notify.py new file mode 100755 index 0000000000000000000000000000000000000000..b89159932ce554349ea70ada4e43612340bbeae1 --- /dev/null +++ b/test/python/validate_schema_notify.py @@ -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) diff --git a/test/python/validate_serial.py b/test/python/validate_serial.py new file mode 100755 index 0000000000000000000000000000000000000000..cfc940666e32e156693fa597126a0e67ee02ae82 --- /dev/null +++ b/test/python/validate_serial.py @@ -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) diff --git a/test/python/validate_ubus_event.py b/test/python/validate_ubus_event.py new file mode 100755 index 0000000000000000000000000000000000000000..3a2007b996132e0060faa8d2b40efcfcf0db228c --- /dev/null +++ b/test/python/validate_ubus_event.py @@ -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) diff --git a/tools/convert_dm_json_to_c.py b/tools/convert_dm_json_to_c.py index 9a2372a724f6b722ff44d2d0d4dea391c41e5eaf..10c2324bade558a78939206b23b33b3006b57dab 100755 --- a/tools/convert_dm_json_to_c.py +++ b/tools/convert_dm_json_to_c.py @@ -334,7 +334,7 @@ def printheaderObjCommon(objname): def cprintheaderOBJS(objname): fp = open('./.objparamarray.c', 'a', encoding='utf-8') print("DMOBJ %s[] = {" % ("t" + getname(objname) + "Obj"), file=fp) - print("/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/", file=fp) + print("/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */", file=fp) fp.close() @@ -853,7 +853,7 @@ def cprintEvent(geteventargs, param_args, struct_name): def cprintheaderPARAMS(objname): fp = open('./.objparamarray.c', 'a', encoding='utf-8') print("DMLEAF %s[] = {" % ("t" + getname(objname) + "Params"), file=fp) - print("/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/", file=fp) + print("/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */", file=fp) fp.close() @@ -871,7 +871,6 @@ def printPARAMline(parentname, dmparam, value): typeparam = bbf.get_option_value(value, "type") bbfdm = getprotocolsparam(value, "protocols") accessparam = bbf.get_option_value(value, "write") - version = bbf.get_option_value(value, "version") if accessparam: access = "&DMWRITE" @@ -889,8 +888,8 @@ def printPARAMline(parentname, dmparam, value): instance, typeparam, parentname, dmparam, value) fp = open('./.objparamarray.c', 'a', encoding='utf-8') - print("{\"%s\", %s, %s, %s, %s, %s, \"%s\"}," % - (dmparam, access, ptype, getvalue, setvalue, bbfdm, version), file=fp) + print("{\"%s\", %s, %s, %s, %s, %s}," % + (dmparam, access, ptype, getvalue, setvalue, bbfdm), file=fp) fp.close() @@ -902,7 +901,6 @@ def printCOMMANDline( parentname, dmparam, value ): asyncparam = bbf.get_option_value(value, "async") in_args = bbf.get_option_value(value, "input") out_args = bbf.get_option_value(value, "output") - version = bbf.get_option_value(value, "version") if asyncparam: c_type = "&DMASYNC" @@ -917,7 +915,7 @@ def printCOMMANDline( parentname, dmparam, value ): cprintOperateCommands(getoperateargs, operate, in_args, out_args, commonname.replace("()", "").lower()+"_args") fp = open('./.objparamarray.c', 'a', encoding='utf-8') - print("{\"%s\", %s, %s, %s, %s, %s, \"%s\"}," % (dmparam, c_type, ptype, getoperateargs, operate, bbfdm, version), file=fp) + print("{\"%s\", %s, %s, %s, %s, %s}," % (dmparam, c_type, ptype, getoperateargs, operate, bbfdm), file=fp) fp.close() @@ -926,8 +924,7 @@ def printEVENTline( parentname, dmparam, value ): ptype = bbf.get_param_type(value) bbfdm = getprotocolsparam(value, "protocols") hasparam = bbf.obj_has_param(value) - version = bbf.get_option_value(value, "version") - + if hasparam: geteventargs = "get_event_args_" + commonname.replace("!", "") cprintEvent(geteventargs, value, commonname.replace("!", "").lower()+"_args") @@ -935,7 +932,7 @@ def printEVENTline( parentname, dmparam, value ): geteventargs = "NULL" fp = open('./.objparamarray.c', 'a', encoding='utf-8') - print("{\"%s\", &DMREAD, %s, %s, NULL, %s, \"%s\"}," % (dmparam, ptype, geteventargs, bbfdm, version), file=fp) + print("{\"%s\", &DMREAD, %s, %s, NULL, %s}," % (dmparam, ptype, geteventargs, bbfdm), file=fp) fp.close() @@ -955,7 +952,6 @@ def printOBJline(dmobject, value): mappingobj = bbf.get_option_value(value, "mapping") bbfdm = getprotocolsparam(value, "protocols") uniquekeys = getuniquekeys(value, "uniqueKeys") - version = bbf.get_option_value(value, "version") if accessobj: access = "&DMWRITE" @@ -987,11 +983,11 @@ def printOBJline(dmobject, value): fp = open('./.objparamarray.c', 'a', encoding='utf-8') if uniquekeys: - print("{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, %s, %s, \"%s\"}," % (getlastname( - dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm, uniquekeys, version), file=fp) + print("{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, %s, %s}," % (getlastname( + dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm, uniquekeys), file=fp) else: - print("{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, %s, NULL, \"%s\"}," % (getlastname( - dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm, version), file=fp) + print("{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, %s, NULL}," % (getlastname( + dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm), file=fp) fp.close()