Remove support for libbbf_ubus

This commit is contained in:
Amin Ben Romdhane 2023-03-27 13:52:32 +02:00
parent ea8afbf980
commit 6e9a821ebd
9 changed files with 0 additions and 1313 deletions

View file

@ -7,9 +7,6 @@ This package comprises of the below libraries:
| ------- | ------------------------------------------------- |
| libbbfdm | This provides the mechanism to add new parameters or extend the existing DM tree using json plugin or shared library plugin. |
| libbbf_api | This provides the APIs for UCI, Ubus, JSON, CLI and memory management. |
| libbbf_ubus | This library helps to expose the datamodel directly over ubus. Application can expose any datamodel(need not be part of "Device."/TR-181) using this library. |
Note: Applications that use libbbf_ubus to expose datamodel, not required to use libbbfdm.
## Design of bbfdm
@ -28,7 +25,6 @@ Note: Applications that use libbbf_ubus to expose datamodel, not required to use
│   ├── openwrt
│   └── vendor.h
├── libbbf_api
├── libbbf_ubus
├── scripts
└── tools
```
@ -48,9 +44,6 @@ Note: Applications that use libbbf_ubus to expose datamodel, not required to use
- `libbbf_api` folder which contains the source code of all API functions (UCI, Ubus, JSON, CLI and memory management). These API are used for GET/SET/ADD/Delete/Operate calls which can be called in internal or external packages.
All APIs exposed by libbbf_api are presented in this header file [libbbf_api.h](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/include/libbbf_api.h).
- `libbbf_ubus` folder which contains the source code of all API functions helps in exposing datamodel constructed with the help of libbbf APIs directly over ubus.
All APIs exposed by libbbf_ubus are presented in this header file [libbbf_ubus.h](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/include/libbbf_ubus.h).
- `scripts` folder which contains the Diagnostics scripts
- `tools` folder which contains some tools to generate Data Model in C, JSON, XML and Excel format
@ -69,20 +62,6 @@ All APIs exposed by libbbf_ubus are presented in this header file [libbbf_ubus.h
* [Expose datamodel over UBUS using libbbf APIs](./docs/guide/dm_expose_over_ubus.md)
## Dependencies of of libbbfdm and libbbf_ubus
To successfully build libbbfdm or libbbf_ubus, the following libraries are needed:
| Dependency | Link | License |
| ----------- | ------------------------------------------- | -------------- |
| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 |
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
| libubus | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
| libcurl | https://dl.uxnr.de/mirror/curl | MIT |
| libwolfssl | https://github.com/wolfSSL/wolfssl | GPL-2.0 |
## External dependencies for datamodel objects
| Datamodel | Package | Link |

View file

@ -1,12 +0,0 @@
# How to expose datamodel over ubus directly with the help of libbbf APIs
`Libbbf_ubus` is the library that helps in exposing the datamodel over ubus directly using libbbf_api.
Application using `libbbf_ubus`, shall not use the `libbbfdm` library because all needed operations from `libbbfdm` library has been internally handled in `libbbf_ubus`.
To identify the mechanism of exposing datamodel directly over ubus please refer to the sample code [dmtest.c](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/test/dynamicdm_ubus_test/bbf_ubus.c)
For more info you can see the schemas at:
- Raw schema [link](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/schemas/dmtest.json)
- Markdown schema [link](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/schemas/dmtest.md)

View file

@ -1,56 +0,0 @@
#!/bin/bash
echo "$0 preparation script"
pwd
source ./gitlab-ci/shared.sh
echo "Starting supervisor in current directory"
supervisorctl shutdown
sleep 1
supervisord -c supervisord.conf
# clean and make
# compile and install libbbf
install_libbbf
#compile and install libbbf_test dynamic extension library
install_libbbf_test
supervisorctl update
supervisorctl restart all
supervisorctl status all
exec_cmd ubus wait_for dmtest
supervisorctl status all
# debug logging
echo "Checking ubus status [$(date '+%d/%m/%Y %H:%M:%S')]"
ubus list
ubus -v list dmtest
echo "Checking system resources"
free -h
df -h
sleep 5
# run functional on dmtest object validation
if [ -f "/usr/share/rpcd/schemas/dmtest.json" ]; then
rm /usr/share/rpcd/schemas/dmtest.json
fi
cp -r ./schemas/dmtest.json /usr/share/rpcd/schemas
ubus-api-validator -t 5 -f ./test/api/json/dmtest.validation.json >> ./api-result.log
check_ret $?
supervisorctl status all
supervisorctl stop all
supervisorctl status
#report part
date +%s > timestamp.log
exec_cmd tap-junit --input ./api-result.log --output report
echo "Checking memory leaks..."
grep -q "Leak" memory-report.xml
error_on_zero $?
echo "Functional libbbf_ubus API test :: PASS"

View file

@ -114,14 +114,7 @@ function install_libbbf_test()
echo "installing libbbf_test"
cp -f test/bbf_test/libbbf_test.so /usr/lib/bbfdm
echo "pre-installation for libbbf_ubus_test"
cp -f test/bbf_test/libbbf_test.so /usr/local/lib
ldconfig
# compile and install libbbf_ubus_test
#echo "Compiling libbbf_ubus_test"
#make clean -C test/dynamicdm_ubus_test/
#make -C test/dynamicdm_ubus_test/
}
function install_libperiodicstats()

View file

@ -1,118 +0,0 @@
/*
* Copyright (C) 2021 Iopsys Software Solutions AB
*
* Author: Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* 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
*/
/**
* \file libbbf_ubus.h
*
* This Library provides APIs to expose the datamodel constructed with the help
* of libbbf API over the ubus directly.
* This library has an external dependency on libbbf_api
*/
#ifndef __LIBBBF_UBUS_H__
#define __LIBBBF_UBUS_H__
#include <libubus.h>
#include "libbbf_api/dmbbf.h"
/*********************************************************************//**
**
** dynamicdm_init
**
** This API is to register the predefined ubus methods to work on provided
** `DMOBJ` tree.
**
** NOTE: dynamicdm_free should be called to deregister and free the allocated
** resources used in this API.
**
** \param ctx - pre-allocated ubus context, should not be NULL
** \param ubus_name - name of the ubus object on which pre-defined usus methods will be registered.
** It should not be NULL or Empty
** \param entry - Object which points to the root node of the tree. More details available in
** libbbf_api documentation.
**
** \return 0 if ubus methods are registered with the given tree, -1 otherwise
**
**************************************************************************/
int dynamicdm_init(struct ubus_context *ctx, char *ubus_name, DMOBJ *entry);
/*********************************************************************//**
**
** dynamicdm_init_plugin_object
**
** This API is to register the predefined ubus methods to work on provided
** `DM_MAP_OBJ` tree.
**
** NOTE: dynamicdm_free_plugin_object should be called to deregister and free
** the allocated resources used in this API.
** This API is for developer purpose and can register a tree with intermediate
** node.
**
** \param ctx - pre-allocated ubus context, should not be NULL
** \param ubus_name - name of the ubus object on which pre-defined usus methods will be registered.
** It should not be NULL or Empty
** \param entry - Object which points to the root node of the tree. More details available in
** libbbf_api documentation.
**
** \return 0 if ubus methods are registered with the given tree, -1 otherwise
**
**************************************************************************/
int dynamicdm_init_plugin_object(struct ubus_context *ctx, char *ubus_name, DM_MAP_OBJ *entry);
/*********************************************************************//**
**
** dynamicdm_free
**
** This is the API responsible to deregister/remove the allocated resources
** used in dynamicdm_init
**
** NOTE: It's the responsibility of the application to call this API before
** termination in order to free the resources if dynamicdm_init has been used.
**
** \param ctx - pre-allocated ubus context, should not be NULL
** \param ubus_name - name of the ubus object on which pre-defined usus methods are registered.
** It should not be NULL or Empty
**
** \return None
**
**************************************************************************/
void dynamicdm_free(struct ubus_context *ctx, const char *ubus_name);
/*********************************************************************//**
**
** dynamicdm_free
**
** This is the API responsible to deregister/remove the allocated resources
** used in dynamicdm_init_plugin_object
**
** NOTE: It's the responsibility of the application to call this API before
** termination in order to free the resources if dynamicdm_init_plugin_object
** has been used.
**
** \param ctx - pre-allocated ubus context, should not be NULL
** \param ubus_name - name of the ubus object on which pre-defined usus methods are registered.
** It should not be NULL or Empty
**
** \return None
**
**************************************************************************/
void dynamicdm_free_plugin_object(struct ubus_context *ctx, const char *ubus_name);
#endif //__LIBBBF_UBUS_H__

View file

@ -1,34 +0,0 @@
MAINTAINERCLEANFILES = Makefile.in
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libbbf_ubus.la
libbbf_ubus_la_SOURCES = \
../dmentry.c \
../dmbbfcommon.c \
libbbf_ubus.c
libbbf_ubus_la_CFLAGS = \
$(AM_CFLAGS) \
$(LIBUCI_CFLAGS) \
$(LIBUBOX_CFLAGS) \
$(LIBUBUS_CFLAGS)
libbbf_ubus_la_LDFLAGS = \
$(AM_LDFLAGS) \
$(LIBUCI_LDFLAGS) \
$(LIBUBOX_LDFLAGS) \
$(LIBUBUS_LDFLAGS)
libbbf_ubus_la_LIBADD = \
$(AM_LIBS) \
$(LIBUCI_LIBS) \
$(LIBUBOX_LIBS) \
$(LIBUBUS_LIBS) \
$(LIBJSON_LIBS) \
$(LBLOBMSG_LIBS) \
$(LIBCURL_LIBS) \
-L../bin/
libbbf_ubus_la_CFLAGS+=-I../
libbbf_ubus_la_CFLAGS+=-I../include

View file

@ -1,68 +0,0 @@
AC_INIT([libbbf_ubus], [0.1], [suvendhu.hansa@iopsys.eu])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_PROG_CC
AC_PROG_CC_C_O
AC_ENABLE_SHARED
LT_INIT
LIBJSON_LIBS='-ljson-c'
AC_SUBST([LIBJSON_LIBS])
AC_ARG_WITH([uci-include-path],
[AS_HELP_STRING([--with-uci-include-path],
[location of the uci library headers])],
[LIBUCI_CFLAGS="-I$withval"])
AC_SUBST([LIBUCI_CFLAGS])
AC_ARG_WITH([uci-lib-path],
[AS_HELP_STRING([--with-uci-lib-path], [location of the uci library])], [LIBUCI_LDFLAGS="-L$withval"])
AC_SUBST([LIBUCI_LDFLAGS])
LIBUCI_LIBS='-luci'
AC_SUBST([LIBUCI_LIBS])
AC_ARG_WITH([libubox-include-path],
[AS_HELP_STRING([--with-libubox-include-path],
[location of the libubox library headers])],
[LIBUBOX_CFLAGS="-I$withval"])
AC_SUBST([LIBUBOX_CFLAGS])
AC_ARG_WITH([libubox-lib-path],
[AS_HELP_STRING([--with-libubox-lib-path], [location of the libubox library])], [LIBUBOX_LDFLAGS="-L$withval"])
AC_SUBST([LIBUBOX_LDFLAGS])
LIBUBOX_LIBS='-lubox'
AC_SUBST([LIBUBOX_LIBS])
AC_ARG_WITH([libubus-include-path],
[AS_HELP_STRING([--with-libubus-include-path],
[location of the libubus library headers])],
[LIBUBUS_CFLAGS="-I$withval"])
AC_SUBST([LIBUBUS_CFLAGS])
AC_ARG_WITH([libubus-lib-path],
[AS_HELP_STRING([--with-libubus-lib-path], [location of the libubus library])], [LIBUBOX_LDFLAGS="-L$withval"])
AC_SUBST([LIBUBUS_LDFLAGS])
LIBUBUS_LIBS='-lubus'
AC_SUBST([LIBUBUS_LIBS])
LBLOBMSG_LIBS='-lblobmsg_json'
AC_SUBST([LBLOBMSG_LIBS])
LIBDLOPEN_LIBS='-ldl'
AC_SUBST([LIBDLOPEN_LIBS])
LIBCURL_LIBS='-lcurl'
AC_SUBST([LIBCURL_LIBS])
# checks for header files
AC_CHECK_HEADERS([stdlib.h string.h])
# checks for typedefs, structures, and compiler characteristics
AC_TYPE_UINT8_T
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View file

@ -1,963 +0,0 @@
/*
* Copyright (C) 2021 Iopsys Software Solutions AB
*
* Author: Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* 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 <stdlib.h>
#include <libubox/blobmsg.h>
#include "dmentry.h"
#include "dmbbfcommon.h"
#include "libbbf_ubus.h"
#define PATH_MAX 4096
struct obj_node {
struct ubus_object *ob;
struct ubus_object_type *ob_type;
char *obj_name;
DMOBJ *tUsrObj;
struct obj_node *next;
};
enum {
LIBBBF_UBUS_GET_PATH,
LIBBBF_UBUS_GET_PROTO,
__LIBBBF_UBUS_GET_MAX
};
enum {
LIBBBF_UBUS_SET_PATH,
LIBBBF_UBUS_SET_VALUE,
LIBBBF_UBUS_SET_PROTO,
__LIBBBF_UBUS_SET_MAX
};
enum {
LIBBBF_UBUS_OPERATE_PATH,
LIBBBF_UBUS_OPERATE_INPUT,
__LIBBBF_UBUS_OPERATE_MAX
};
enum {
LIBBBF_UBUS_SUPPORTED_PATH,
LIBBBF_UBUS_SUPPORTED_PROTO,
LIBBBF_UBUS_SUPPORTED_NXT_LEVEL,
LIBBBF_UBUS_SUPPORTED_SCHEMA_TYPE,
__LIBBBF_UBUS_SUPPORTED_MAX
};
enum {
LIBBBF_UBUS_ADD_DEL_PATH,
LIBBBF_UBUS_ADD_DEL_PROTO,
__LIBBBF_UBUS_ADD_DEL_MAX
};
static bool g_dynamicdm_transaction_start = false;
static struct obj_node *g_dynamicdm_head = NULL;
static int libbbf_ubus_supported_dm(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static int libbbf_ubus_get_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static int libbbf_ubus_set_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static int libbbf_ubus_operate(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static int libbbf_ubus_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static int libbbf_ubus_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg);
static const struct blobmsg_policy libbbf_ubus_supported_dm_policy[] = {
[LIBBBF_UBUS_SUPPORTED_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_SUPPORTED_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_SUPPORTED_NXT_LEVEL] = { .name = "next-level", .type = BLOBMSG_TYPE_INT8},
[LIBBBF_UBUS_SUPPORTED_SCHEMA_TYPE] = { .name = "schema_type", .type = BLOBMSG_TYPE_INT32},
};
static const struct blobmsg_policy libbbf_ubus_get_policy[] = {
[LIBBBF_UBUS_GET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_GET_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }
};
static const struct blobmsg_policy libbbf_ubus_set_policy[] = {
[LIBBBF_UBUS_SET_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_SET_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_SET_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }
};
static const struct blobmsg_policy libbbf_ubus_operate_policy[] = {
[LIBBBF_UBUS_OPERATE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_OPERATE_INPUT] = { .name = "input", .type = BLOBMSG_TYPE_TABLE }
};
static const struct blobmsg_policy libbbf_ubus_add_del_policy[] = {
[LIBBBF_UBUS_ADD_DEL_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[LIBBBF_UBUS_ADD_DEL_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }
};
static struct ubus_method libbbf_ubus_methods[] = {
UBUS_METHOD("get_supported_dm", libbbf_ubus_supported_dm, libbbf_ubus_supported_dm_policy),
UBUS_METHOD("get", libbbf_ubus_get_handler, libbbf_ubus_get_policy),
UBUS_METHOD("set", libbbf_ubus_set_handler, libbbf_ubus_set_policy),
UBUS_METHOD("operate", libbbf_ubus_operate, libbbf_ubus_operate_policy),
UBUS_METHOD("add_object", libbbf_ubus_add_del_handler, libbbf_ubus_add_del_policy),
UBUS_METHOD("del_object", libbbf_ubus_add_del_handler, libbbf_ubus_add_del_policy),
UBUS_METHOD_NOARG("transaction_start", libbbf_ubus_transaction_handler),
UBUS_METHOD_NOARG("transaction_abort", libbbf_ubus_transaction_handler),
UBUS_METHOD_NOARG("transaction_commit", libbbf_ubus_transaction_handler),
};
static int get_protocol(const char *val)
{
int type;
if (DM_LSTRCMP(val, "cwmp") == 0)
type = BBFDM_CWMP;
else if (DM_LSTRCMP(val, "usp") == 0)
type = BBFDM_USP;
else
type = BBFDM_BOTH;
return type;
}
static int get_bbf_proto_type(struct blob_attr *proto)
{
int type;
if (proto) {
const char *val = blobmsg_get_string(proto);
type = get_protocol(val);
} else {
type = BBFDM_BOTH;
}
return type;
}
static 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, "");
}
static struct obj_node* find_obj_node(const char *ubus_name)
{
struct obj_node *temp = g_dynamicdm_head;
if (temp == NULL)
return NULL;
while (DM_STRCMP(ubus_name, temp->obj_name) != 0) {
if (temp->next == NULL) {
return NULL;
} else {
temp = temp->next;
}
}
return temp;
}
static DMOBJ* get_entry_object(const char *name)
{
if (!name)
return NULL;
struct obj_node *ob_node = find_obj_node(name);
if (!ob_node)
return NULL;
return ob_node->tUsrObj;
}
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) {
const char **in, **out = NULL;
operation_args *args = NULL;
void *array = NULL;
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 = NULL;
ev = (event_args *)param->data;
if (ev->param) {
const char **in = NULL;
void *key = NULL;
int i;
in = ev->param;
key = blobmsg_open_array(bb, "in");
for (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);
blobmsg_add_string(bb, "writable", param->data ? param->data : "0");
blobmsg_add_string(bb, "type", param->type);
if (param->additional_data) {
const char **uniq_keys = NULL;
void *key = NULL;
int i;
uniq_keys = (const char **)param->additional_data;
key = blobmsg_open_array(bb, "unique_keys");
for (i = 0; uniq_keys[i] != NULL; i++)
blobmsg_add_string(bb, NULL, uniq_keys[i]);
blobmsg_close_array(bb, key);
}
}
static int handle_add_del_req(struct ubus_context *ctx, const char *ubus_name, struct ubus_request_data *req,
char *path, const char *method, int proto)
{
int fault = 0;
struct dmctx bbf_ctx;
struct blob_buf bb;
char *pkey = "true";
DMOBJ *tEntryObj = get_entry_object(ubus_name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (!g_dynamicdm_transaction_start) {
printf("Transaction not started\n\r");
blobmsg_add_u32(&bb, "fault", usp_fault_map(USP_FAULT_INTERNAL_ERROR));
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(proto);
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
if (DM_LSTRCMP(method, "add_object") == 0) {
fault = dm_entry_param_method(&bbf_ctx, CMD_ADD_OBJECT, path, pkey, NULL);
} else {
fault = dm_entry_param_method(&bbf_ctx, CMD_DEL_OBJECT, path, pkey, NULL);
}
void *array = blobmsg_open_array(&bb, "parameters");
void *table = blobmsg_open_table(&bb, NULL);
bb_add_string(&bb, "parameter", path);
if (fault) {
blobmsg_add_u32(&bb, "fault", fault);
blobmsg_add_u8(&bb, "status", 0);
} else {
if (DM_LSTRCMP(method, "add_object") == 0) {
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);
}
} else {
blobmsg_add_u8(&bb, "status", 1);
}
}
blobmsg_close_table(&bb, table);
blobmsg_close_array(&bb, array);
dm_ctx_clean(&bbf_ctx);
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
static void libbbf_ubus_obj_node_free(struct obj_node *obj)
{
if (!obj)
return;
if (obj->ob_type)
FREE(obj->ob_type);
if (obj->ob)
FREE(obj->ob);
if (obj->obj_name)
FREE(obj->obj_name);
FREE(obj);
}
static int libbbf_ubus_supported_dm(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[__LIBBBF_UBUS_SUPPORTED_MAX];
char path[PATH_MAX] = {0};
bool nxt_lvl = false;
uint32_t schema_type = 0;
struct blob_buf bb;
int fault = 0, proto;
struct dmctx bbf_ctx;
if (blobmsg_parse(libbbf_ubus_supported_dm_policy, __LIBBBF_UBUS_SUPPORTED_MAX, tb, blob_data(msg), blob_len(msg)) == 0) {
if (tb[LIBBBF_UBUS_SUPPORTED_PATH])
snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_SUPPORTED_PATH]));
if (tb[LIBBBF_UBUS_SUPPORTED_NXT_LEVEL])
nxt_lvl = blobmsg_get_bool(tb[LIBBBF_UBUS_SUPPORTED_NXT_LEVEL]);
if (tb[LIBBBF_UBUS_SUPPORTED_SCHEMA_TYPE])
schema_type = blobmsg_get_u32(tb[LIBBBF_UBUS_SUPPORTED_SCHEMA_TYPE]);
}
DMOBJ *tEntryObj = get_entry_object(obj->name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
proto = get_bbf_proto_type(tb[LIBBBF_UBUS_SUPPORTED_PROTO]);
set_bbfdatamodel_type(proto);
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
fault = dm_get_supported_dm(&bbf_ctx, path, nxt_lvl, schema_type);
if(fault) {
blobmsg_add_u32(&bb, "fault", fault);
} else {
struct dm_parameter *param = NULL;
void *array = NULL, *table = NULL;
array = blobmsg_open_array(&bb,"parameters");
list_for_each_entry(param, &bbf_ctx.list_parameter, list) {
int cmd = get_dm_type(param->type);
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);
}
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
dm_ctx_clean(&bbf_ctx);
return fault;
}
static void init_dm_path(DMOBJ *tEntryObj)
{
struct dmctx bbf_ctx;
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(BBFDM_BOTH);
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
dm_entry_param_method(&bbf_ctx, CMD_GET_VALUE, "", NULL, NULL);
dm_ctx_clean(&bbf_ctx);
}
static int libbbf_ubus_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[__LIBBBF_UBUS_GET_MAX] = {NULL};
char path[PATH_MAX] = {0};
struct dmctx bbf_ctx;
struct blob_buf bb;
int fault = 0, proto;
if (blobmsg_parse(libbbf_ubus_get_policy, __LIBBBF_UBUS_GET_MAX, tb, blob_data(msg), blob_len(msg))) {
printf("Failed to parse blob\n");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (!(tb[LIBBBF_UBUS_GET_PATH]))
return UBUS_STATUS_INVALID_ARGUMENT;
DMOBJ *tEntryObj = get_entry_object(obj->name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_GET_PATH]));
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
proto = get_bbf_proto_type(tb[LIBBBF_UBUS_GET_PROTO]);
set_bbfdatamodel_type(proto);
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
fault = dm_entry_param_method(&bbf_ctx, CMD_GET_VALUE, path, NULL, NULL);
if (!fault) {
struct dm_parameter *n = NULL;
void *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, "value", n->data);
bb_add_string(&bb, "type", n->type);
blobmsg_close_table(&bb, table);
}
blobmsg_close_array(&bb, array);
} else {
blobmsg_add_u32(&bb, "fault", fault);
}
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
dm_ctx_clean(&bbf_ctx);
return fault;
}
static int libbbf_ubus_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[__LIBBBF_UBUS_OPERATE_MAX] = {NULL};
char path[PATH_MAX] = {0};
char *input = NULL;
struct blob_buf bb;
struct dmctx bbf_ctx;
int fault = 0, len;
if (blobmsg_parse(libbbf_ubus_operate_policy, __LIBBBF_UBUS_OPERATE_MAX, tb, blob_data(msg), blob_len(msg))) {
printf("Failed to parse blob\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (!(tb[LIBBBF_UBUS_OPERATE_PATH]))
return UBUS_STATUS_INVALID_ARGUMENT;
if (tb[LIBBBF_UBUS_OPERATE_INPUT])
input = blobmsg_format_json(tb[LIBBBF_UBUS_OPERATE_INPUT], true);
DMOBJ *tEntryObj = get_entry_object(obj->name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
if (input)
free(input);
return UBUS_STATUS_UNKNOWN_ERROR;
}
snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_OPERATE_PATH]));
len = DM_STRLEN(path);
if (len == 0) {
if (input)
free(input);
return UBUS_STATUS_INVALID_ARGUMENT;
}
if (path[len - 1] == '.') {
printf("path can't end with (.)\n\r");
if (input)
free(input);
return UBUS_STATUS_UNKNOWN_ERROR;
}
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
set_bbfdatamodel_type(BBFDM_USP);
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
fault = dm_entry_param_method(&bbf_ctx, CMD_USP_OPERATE, path, input, NULL);
switch (fault) {
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 = 0;
break;
default:
printf("Case(%d) not found\n\r", fault);
fault = USP_FAULT_INVALID_PATH;
break;
}
void *array = blobmsg_open_array(&bb, "Results");
void *table = blobmsg_open_table(&bb, NULL);
blobmsg_add_string(&bb, "path", path);
if (fault == 0) {
struct dm_parameter *n = NULL;
void *array_in = blobmsg_open_array(&bb, "parameters");
list_for_each_entry(n, &bbf_ctx.list_parameter, list) {
void *table_in = 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_in);
}
blobmsg_close_array(&bb, array_in);
} else {
fault = usp_fault_map(fault);
blobmsg_add_u32(&bb, "fault", fault);
}
blobmsg_close_table(&bb, table);
blobmsg_close_array(&bb, array);
dm_ctx_clean(&bbf_ctx);
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
if (input)
free(input);
return 0;
}
static int libbbf_ubus_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[__LIBBBF_UBUS_ADD_DEL_MAX] = {NULL};
char path[PATH_MAX] = {0};
int plen, proto;
if (blobmsg_parse(libbbf_ubus_add_del_policy, __LIBBBF_UBUS_ADD_DEL_MAX, tb, blob_data(msg), blob_len(msg))) {
printf("Failed to parse blob");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (!tb[LIBBBF_UBUS_ADD_DEL_PATH])
return UBUS_STATUS_INVALID_ARGUMENT;
snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_ADD_DEL_PATH]));
plen = DM_STRLEN(path);
if (plen == 0) {
return UBUS_STATUS_INVALID_ARGUMENT;
}
if (path[plen - 1] != '.') {
if (plen > PATH_MAX - 2) {
printf("path too long(%d) can't append (.)\n\r", plen);
return UBUS_STATUS_UNKNOWN_ERROR;
}
strcat(path, ".");
}
proto = get_bbf_proto_type(tb[LIBBBF_UBUS_ADD_DEL_PROTO]);
return handle_add_del_req(ctx, obj->name, req, path, method, proto);
}
static int libbbf_ubus_set_handler(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[__LIBBBF_UBUS_SET_MAX] = {NULL};
char path[PATH_MAX] = {'\0'}, value[PATH_MAX] = {'\0'};
int fault = 0, proto;
void *array = NULL, *table = NULL;
struct dmctx bbf_ctx;
bool fault_occured = false;
if (blobmsg_parse(libbbf_ubus_set_policy, __LIBBBF_UBUS_SET_MAX, tb, blob_data(msg), blob_len(msg))) {
printf("Failed to parse blob");
return UBUS_STATUS_UNKNOWN_ERROR;
}
if (!tb[LIBBBF_UBUS_SET_PATH])
return UBUS_STATUS_INVALID_ARGUMENT;
if (!tb[LIBBBF_UBUS_SET_VALUE])
return UBUS_STATUS_INVALID_ARGUMENT;
DMOBJ *tEntryObj = get_entry_object(obj->name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
snprintf(path, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_SET_PATH]));
snprintf(value, PATH_MAX, "%s", (char *)blobmsg_data(tb[LIBBBF_UBUS_SET_VALUE]));
int plen = DM_STRLEN(path);
if (plen == 0) {
return UBUS_STATUS_INVALID_ARGUMENT;
}
if (path[plen - 1] == '.') {
printf("path can't end with (.)\n\r");
return UBUS_STATUS_INVALID_ARGUMENT;
}
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (!g_dynamicdm_transaction_start) {
printf("Transaction not started\n\r");
blobmsg_add_u32(&bb, "fault", usp_fault_map(USP_FAULT_INTERNAL_ERROR));
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
proto = get_bbf_proto_type(tb[LIBBBF_UBUS_SET_PROTO]);
set_bbfdatamodel_type(proto);
memset(&bbf_ctx, 0, sizeof(struct dmctx));
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
fault = dm_entry_param_method(&bbf_ctx, CMD_SET_VALUE, path, value, NULL);
if (fault) {
if (fault_occured == false) {
fault_occured = true;
array = blobmsg_open_array(&bb, "parameters");
}
}
while (bbf_ctx.list_fault_param.next != &bbf_ctx.list_fault_param) {
struct param_fault *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);
}
//Apply the parameter
fault = dm_entry_apply(&bbf_ctx, CMD_SET_VALUE);
if (fault == 0 && fault_occured == false)
blobmsg_add_u8(&bb, "status", true);
else {
if (!array)
array = blobmsg_open_array(&bb, "parameters");
while (bbf_ctx.list_fault_param.next != &bbf_ctx.list_fault_param) {
struct param_fault *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 (array)
blobmsg_close_array(&bb, array);
ubus_send_reply(ctx, req, bb.head);
// free
blob_buf_free(&bb);
dm_ctx_clean(&bbf_ctx);
return 0;
}
static int libbbf_ubus_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg)
{
struct dmctx bbf_ctx;
struct blob_buf bb;
DMOBJ *tEntryObj = get_entry_object(obj->name);
if (!tEntryObj) {
printf("Failed to get DM entry obj\n\r");
return UBUS_STATUS_UNKNOWN_ERROR;
}
memset(&bbf_ctx, 0, sizeof(struct dmctx));
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (DM_LSTRCMP(method, "transaction_start") == 0) {
if (!g_dynamicdm_transaction_start) {
g_dynamicdm_transaction_start = true;
blobmsg_add_u8(&bb, "status", true);
} else {
printf("Transaction already in process\n");
blobmsg_add_u8(&bb, "status", false);
}
} else if(DM_LSTRCMP(method, "transaction_abort") == 0) {
if (g_dynamicdm_transaction_start) {
g_dynamicdm_transaction_start = false;
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
dm_entry_revert_changes();
dm_ctx_clean(&bbf_ctx);
blobmsg_add_u8(&bb, "status", true);
} else {
printf("Transaction still not started\n\r");
blobmsg_add_u8(&bb, "status", false);
}
} else if (DM_LSTRCMP(method, "transaction_commit") == 0) {
if (g_dynamicdm_transaction_start) {
g_dynamicdm_transaction_start = false;
dm_ctx_init_entry(&bbf_ctx, tEntryObj, 0);
dm_entry_manage_services(&bb, true);
dm_entry_restart_services();
dm_ctx_clean(&bbf_ctx);
blobmsg_add_u8(&bb, "status", true);
} else {
printf("Transaction still not started\n\r");
blobmsg_add_u8(&bb, "status", false);
}
} else {
printf("Unsupported method %s\n\r", method);
}
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
int dynamicdm_init(struct ubus_context *ctx, char *ubus_name, DMOBJ *entry)
{
if (!ctx || !ubus_name || ubus_name[0] == '\0' || !entry)
return -1;
struct obj_node *new = (struct obj_node *)malloc(sizeof(struct obj_node));
if (!new)
return -1;
memset(new, 0, sizeof(struct obj_node));
new->ob = (struct ubus_object *) calloc(1, sizeof(struct ubus_object));
if (!new->ob) {
printf("Out of memory!!\n\r");
libbbf_ubus_obj_node_free(new);
return -1;
}
new->ob_type = (struct ubus_object_type *) calloc(1, sizeof(struct ubus_object_type));
if (!new->ob_type) {
printf("Out of memory!!\n\r");
libbbf_ubus_obj_node_free(new);
return -1;
}
new->obj_name = strdup(ubus_name);
new->ob_type->name = new->obj_name;
new->ob_type->id = 0;
new->ob_type->methods = libbbf_ubus_methods;
new->ob_type->n_methods = ARRAY_SIZE(libbbf_ubus_methods);
new->ob->name = new->obj_name;
new->ob->type = new->ob_type;
new->ob->methods = libbbf_ubus_methods;
new->ob->n_methods = ARRAY_SIZE(libbbf_ubus_methods);
if (ubus_add_object(ctx, new->ob)) {
printf("Failed to add object.\n\r");
libbbf_ubus_obj_node_free(new);
return -1;
}
new->tUsrObj = entry;
new->next = g_dynamicdm_head;
g_dynamicdm_head = new;
init_dm_path(entry);
return 0;
}
int dynamicdm_init_plugin_object(struct ubus_context *ctx, char *ubus_name, DM_MAP_OBJ *entry)
{
int i;
DMOBJ *tEntryObj = NULL, *tmp = NULL;
if (!entry)
return -1;
for (i = 0; entry[i].path != NULL; i++) {
tmp = (DMOBJ*)realloc(tEntryObj, sizeof(DMOBJ) * (i+1));
if (tmp == NULL) {
FREE(tEntryObj);
printf("No Memory exists\n\r");
return -1;
}
tEntryObj = tmp;
memset(&tEntryObj[i], 0, sizeof(DMOBJ));
tEntryObj[i].obj = entry[i].path;
tEntryObj[i].permission = &DMREAD;
tEntryObj[i].nextobj = entry[i].root_obj;
tEntryObj[i].leaf = entry[i].root_leaf;
tEntryObj[i].bbfdm_type = BBFDM_BOTH;
}
/* Make the last empty entry */
tmp = (DMOBJ*)realloc(tEntryObj, sizeof(DMOBJ) * (i+1));
if (tmp == NULL) {
FREE(tEntryObj);
printf("No Memory exists\n\r");
return -1;
}
tEntryObj = tmp;
memset(&tEntryObj[i], 0, sizeof(DMOBJ));
if (0 != dynamicdm_init(ctx, ubus_name, tEntryObj)) {
FREE(tEntryObj);
return -1;
}
return 0;
}
void dynamicdm_free(struct ubus_context *ctx, const char *ubus_name)
{
struct obj_node *curr = g_dynamicdm_head, *prev = NULL;
if (!ctx|| !ubus_name || ubus_name[0] == '\0')
return;
if (curr == NULL)
return;
while (DM_STRCMP(ubus_name, curr->obj_name) != 0) {
if (curr->next == NULL) {
return;
} else {
prev = curr;
curr = curr->next;
}
}
if (curr == g_dynamicdm_head) {
g_dynamicdm_head = g_dynamicdm_head->next;
} else {
prev->next = curr->next;
}
if (curr->tUsrObj)
dm_cleanup_dynamic_entry(curr->tUsrObj);
ubus_remove_object(ctx, curr->ob);
libbbf_ubus_obj_node_free(curr);
}
void dynamicdm_free_plugin_object(struct ubus_context *ctx, const char *ubus_name)
{
if (!ctx || !ubus_name || ubus_name[0] == '\0')
return;
struct obj_node *ob_node = find_obj_node(ubus_name);
if (!ob_node)
return;
dm_cleanup_dynamic_entry(ob_node->tUsrObj);
FREE(ob_node->tUsrObj);
dynamicdm_free(ctx, ubus_name);
}

View file

@ -1,34 +0,0 @@
#include <stdio.h>
#include <libbbf_ubus/libbbf_ubus.h>
#include <libbbf_api/dmbbf.h>
#include <libubox/uloop.h>
extern DM_MAP_OBJ tDynamicObj[];
int main(int argc, char *argv[])
{
struct ubus_context *ctx = ubus_connect(NULL);
if (!ctx) {
printf("Failed to connect to ubus\n\r");
return -1;
}
printf("Sending entry obj: (%s)\n\r", tDynamicObj[0].path);
ubus_add_uloop(ctx);
if (-1 == dynamicdm_init_plugin_object(ctx, "dmtest", tDynamicObj)) {
printf("Failed to create ubus object\n\r");
return -1;
}
uloop_run();
dynamicdm_free_plugin_object(ctx, "dmtest");
ubus_free(ctx);
uloop_done();
return 0;
}