Introduce a new libbbfdm-api library version 2

This commit is contained in:
Amin Ben Romdhane 2025-01-09 14:22:24 +01:00
parent b6c85dcf56
commit b7e5e0de5a
57 changed files with 1500 additions and 195 deletions

View file

@ -4,7 +4,7 @@ PROJECT(bbfdmd)
ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -g -fPIC -D_GNU_SOURCE) ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -g -fPIC -D_GNU_SOURCE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/ -I${CMAKE_SOURCE_DIR}/libbbfdm-ubus/") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/legacy -I${CMAKE_SOURCE_DIR}/libbbfdm-api/version-2 -I${CMAKE_SOURCE_DIR}/libbbfdm-ubus")
FILE(GLOB BBF_SOURCES *.c) FILE(GLOB BBF_SOURCES *.c)
ADD_EXECUTABLE(bbfdmd ${BBF_SOURCES}) ADD_EXECUTABLE(bbfdmd ${BBF_SOURCES})

View file

@ -4,7 +4,7 @@ PROJECT(dm-service C)
ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -g -fPIC -D_GNU_SOURCE) ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -g -fPIC -D_GNU_SOURCE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/ -I${CMAKE_SOURCE_DIR}/libbbfdm-ubus/") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/legacy -I${CMAKE_SOURCE_DIR}/libbbfdm-api/version-2 -I${CMAKE_SOURCE_DIR}/libbbfdm-ubus")
FILE(GLOB BBF_SOURCES *.c) FILE(GLOB BBF_SOURCES *.c)
ADD_EXECUTABLE(dm-service ${BBF_SOURCES}) ADD_EXECUTABLE(dm-service ${BBF_SOURCES})

View file

@ -2,34 +2,5 @@ cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm-api) PROJECT(libbbfdm-api)
ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE) add_subdirectory(legacy)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}") add_subdirectory(version-2)
IF(${BBF_MAX_OBJECT_INSTANCES})
ADD_DEFINITIONS(-DBBF_MAX_OBJECT_INSTANCES=${BBF_MAX_OBJECT_INSTANCES})
ENDIF()
OPTION(BBF_SCHEMA_FULL_TREE "build with schema full tree" OFF)
IF(BBF_SCHEMA_FULL_TREE)
add_compile_definitions(BBF_SCHEMA_FULL_TREE)
ENDIF(BBF_SCHEMA_FULL_TREE)
FILE(GLOB BBF_API_SOURCES *.c plugin/*.c)
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm-api uci ubus ubox json-c blobmsg_json dl curl)
INSTALL(TARGETS bbfdm-api
LIBRARY DESTINATION usr/lib)
FILE(GLOB libbbfdm-api_headers *.h)
INSTALL(FILES ${libbbfdm-api_headers}
DESTINATION usr/include/libbbfdm-api
)
FILE(GLOB libbbfdm-api_include_headers include/*.h)
INSTALL(FILES ${libbbfdm-api_include_headers}
DESTINATION usr/include
)

View file

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm-api-legacy)
ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR}")
IF(${BBF_MAX_OBJECT_INSTANCES})
ADD_DEFINITIONS(-DBBF_MAX_OBJECT_INSTANCES=${BBF_MAX_OBJECT_INSTANCES})
ENDIF()
OPTION(BBF_SCHEMA_FULL_TREE "build with schema full tree" OFF)
IF(BBF_SCHEMA_FULL_TREE)
add_compile_definitions(BBF_SCHEMA_FULL_TREE)
ENDIF(BBF_SCHEMA_FULL_TREE)
FILE(GLOB BBF_API_SOURCES *.c plugin/*.c)
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm-api uci ubus ubox json-c blobmsg_json dl curl bbfdm-api-v2)
INSTALL(TARGETS bbfdm-api
LIBRARY DESTINATION usr/lib)
FILE(GLOB libbbfdm-api_headers *.h)
INSTALL(FILES ${libbbfdm-api_headers}
DESTINATION usr/include/libbbfdm-api
)
FILE(GLOB libbbfdm-api_headers *.h)
INSTALL(FILES ${libbbfdm-api_headers}
DESTINATION usr/include/libbbfdm-api/legacy
)
FILE(GLOB libbbfdm-api_include_headers include/*.h)
INSTALL(FILES ${libbbfdm-api_include_headers}
DESTINATION usr/include
)

View file

@ -406,30 +406,3 @@ int bbfdm_operate_reference_linker(struct dmctx *ctx, const char *reference_path
return 0; return 0;
} }
__attribute__ ((deprecated)) int bbf_get_reference_param(char *path, char *key_name, char *key_value, char **value)
{
if (DM_STRLEN(path) == 0 || DM_STRLEN(key_name) == 0 || DM_STRLEN(key_value) == 0 || !value)
return -1;
dmasprintf(value, "%s[%s==\"%s\"].", path, key_name, key_value);
return 0;
}
__attribute__ ((deprecated)) int bbf_get_reference_args(char *value, struct dm_reference *reference_args)
{
if (DM_STRLEN(value) == 0)
return -1;
reference_args->path = value;
char *seperator = strstr(value, "=>");
if (!seperator)
return -1;
*seperator = 0;
reference_args->value = seperator + 2;
return 0;
}

View file

@ -26,6 +26,8 @@
#include <json-c/json.h> #include <json-c/json.h>
#include <libubox/blob.h> #include <libubox/blob.h>
#include "libbbfdm-api/version-2/bbfdm_api.h"
extern struct dm_permession_s DMREAD; extern struct dm_permession_s DMREAD;
extern struct dm_permession_s DMWRITE; extern struct dm_permession_s DMWRITE;
extern struct dm_permession_s DMSYNC; extern struct dm_permession_s DMSYNC;
@ -422,12 +424,6 @@ struct range_args {
const char *max; const char *max;
}; };
struct __attribute__((deprecated("'dmmap_dup' is deprecated, please use the new structure 'dm_data'"))) dmmap_dup {
struct list_head list;
struct uci_section *config_section;
struct uci_section *dmmap_section;
};
struct dm_data { struct dm_data {
struct list_head list; struct list_head list;
struct uci_section *config_section; struct uci_section *config_section;

View file

@ -899,7 +899,7 @@ char *get_value_by_reference(struct dmctx *ctx, char *value)
return ""; return "";
} }
static char *check_value_by_type(char *value, int type) static char *check_value_by_type(const char *param_name, char *value, int type)
{ {
int i = 0, len = DM_STRLEN(value); int i = 0, len = DM_STRLEN(value);
char buf[len + 1]; char buf[len + 1];
@ -911,8 +911,10 @@ static char *check_value_by_type(char *value, int type)
case DMT_UNINT: case DMT_UNINT:
case DMT_UNLONG: case DMT_UNLONG:
while (buf[i] != 0) { while (buf[i] != 0) {
if (isdigit(buf[i]) == 0) if (isdigit(buf[i]) == 0) {
BBF_WARNING("The parameter '%s' contains an invalid value '%s' for its type. Defaulting to '0'", param_name, buf);
return "0"; return "0";
}
i++; i++;
} }
break; break;
@ -921,8 +923,10 @@ static char *check_value_by_type(char *value, int type)
if (buf[i] == '-') if (buf[i] == '-')
i++; i++;
while (buf[i] != 0) { while (buf[i] != 0) {
if (isdigit(buf[i]) == 0) if (isdigit(buf[i]) == 0) {
BBF_WARNING("The parameter '%s' contains an invalid value '%s' for its type. Defaulting to '0'", param_name, buf);
return "0"; return "0";
}
i++; i++;
} }
break; break;
@ -930,21 +934,27 @@ static char *check_value_by_type(char *value, int type)
return dmuci_string_to_boolean(buf) ? "1" : "0"; return dmuci_string_to_boolean(buf) ? "1" : "0";
case DMT_HEXBIN: case DMT_HEXBIN:
while (buf[i] != 0) { while (buf[i] != 0) {
if (isxdigit(buf[i]) == 0) if (isxdigit(buf[i]) == 0) {
BBF_WARNING("The parameter '%s' contains an invalid hexadecimal value '%s'. Defaulting to an empty value", param_name, buf);
return ""; return "";
}
i++; i++;
} }
break; break;
case DMT_BASE64: case DMT_BASE64:
while (buf[i] != 0) { while (buf[i] != 0) {
if (is64digit(buf[i]) == 0) if (is64digit(buf[i]) == 0) {
return "0"; BBF_WARNING("The parameter '%s' contains an invalid Base64 value '%s'. Defaulting to 'AA=='.", param_name, buf);
return "AA==";
}
i++; i++;
} }
break; break;
case DMT_TIME: case DMT_TIME:
if (!strptime(buf, "%Y-%m-%dT%H:%M:%S", &tm)) if (!strptime(buf, "%Y-%m-%dT%H:%M:%S", &tm)) {
BBF_WARNING("The parameter '%s' contains an invalid time value '%s'. Defaulting to '0001-01-01T00:00:00Z'.", param_name, buf);
return "0001-01-01T00:00:00Z"; return "0001-01-01T00:00:00Z";
}
break; break;
default: default:
break; break;
@ -952,7 +962,7 @@ static char *check_value_by_type(char *value, int type)
return value; return value;
} }
static char *get_default_value_by_type(int type) static char *get_default_value_by_type(const char *param_name, int type)
{ {
switch (type) { switch (type) {
case DMT_UNINT: case DMT_UNINT:
@ -960,10 +970,13 @@ static char *get_default_value_by_type(int type)
case DMT_UNLONG: case DMT_UNLONG:
case DMT_LONG: case DMT_LONG:
case DMT_BOOL: case DMT_BOOL:
BBF_WARNING("The parameter '%s' is empty but must have a value according to its type. Defaulting to '0'", param_name);
return "0"; return "0";
case DMT_BASE64: case DMT_BASE64:
BBF_WARNING("The parameter '%s' is empty but must have a value according to its Base64 type. Defaulting to 'AA=='", param_name);
return "AA=="; // base64 encoded hex value 00 return "AA=="; // base64 encoded hex value 00
case DMT_TIME: case DMT_TIME:
BBF_WARNING("The parameter '%s' is empty but must have a value according to its Time type. Defaulting to '0001-01-01T00:00:00Z'", param_name);
return "0001-01-01T00:00:00Z"; return "0001-01-01T00:00:00Z";
default: default:
return ""; return "";
@ -1037,15 +1050,18 @@ static int ubus_call_blob_msg(const char *obj, const char *method, struct blob_b
ubus_ctx = ubus_connect(NULL); ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL) { if (ubus_ctx == NULL) {
BBF_DEBUG("UBUS context is null\n\r"); BBF_ERR("UBUS context is null");
return -1; return -1;
} }
if (!ubus_lookup_id(ubus_ctx, obj, &id)) { if (ubus_lookup_id(ubus_ctx, obj, &id)) {
rc = ubus_invoke(ubus_ctx, id, method, blob->head, BBF_ERR("Failed to lookup UBUS object ID for '%s'", obj);
ms_callback, callback_arg, timeout); ubus_free(ubus_ctx);
return -1;
} }
rc = ubus_invoke(ubus_ctx, id, method, blob->head, ms_callback, callback_arg, timeout);
if (ubus_ctx) { if (ubus_ctx) {
ubus_free(ubus_ctx); ubus_free(ubus_ctx);
ubus_ctx = NULL; ubus_ctx = NULL;
@ -1777,10 +1793,10 @@ static int get_value_param(DMPARAM_ARGS)
if (leaf->dm_flags & DM_FLAG_REFERENCE) { if (leaf->dm_flags & DM_FLAG_REFERENCE) {
value = get_value_by_reference(dmctx, value); value = get_value_by_reference(dmctx, value);
} else { } else {
value = check_value_by_type(value, leaf->type); value = check_value_by_type(full_param, value, leaf->type);
} }
} else { } else {
value = get_default_value_by_type(leaf->type); value = get_default_value_by_type(full_param, leaf->type);
} }
fill_blob_param(&dmctx->bb, full_param, value, DMT_TYPE[leaf->type], leaf->dm_flags); fill_blob_param(&dmctx->bb, full_param, value, DMT_TYPE[leaf->type], leaf->dm_flags);
@ -1824,9 +1840,9 @@ static int mparam_get_value_in_param(DMPARAM_ARGS)
if (leaf->dm_flags & DM_FLAG_REFERENCE) { if (leaf->dm_flags & DM_FLAG_REFERENCE) {
value = get_value_by_reference(dmctx, value); value = get_value_by_reference(dmctx, value);
} else } else
value = check_value_by_type(value, leaf->type); value = check_value_by_type(full_param, value, leaf->type);
} else { } else {
value = get_default_value_by_type(leaf->type); value = get_default_value_by_type(full_param, leaf->type);
} }
fill_blob_param(&dmctx->bb, full_param, value, DMT_TYPE[leaf->type], leaf->dm_flags); fill_blob_param(&dmctx->bb, full_param, value, DMT_TYPE[leaf->type], leaf->dm_flags);

View file

@ -81,21 +81,16 @@ static inline int DM_LINK_INST_OBJ(struct dmctx *dmctx, DMNODE *parent_node, voi
#endif #endif
// Macros for different log levels // Macros for different log levels
#define BBF_ERR(MESSAGE, ...) do { \ #define BBF_ERR(MESSAGE, ...) \
syslog(LOG_ERR, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \ BBFDM_ERR(MESSAGE, ##__VA_ARGS__)
} while(0)
#define BBF_WARNING(MESSAGE, ...) do { \ #define BBF_WARNING(MESSAGE, ...) \
syslog(LOG_WARNING, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \ BBFDM_WARNING(MESSAGE, ##__VA_ARGS__)
} while(0)
#define BBF_INFO(MESSAGE, ...) do { \ #define BBF_INFO(MESSAGE, ...) \
syslog(LOG_INFO, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \ BBFDM_INFO(MESSAGE, ##__VA_ARGS__)
} while(0)
#define BBF_DEBUG(MESSAGE, ...) do { \
syslog(LOG_DEBUG, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#define BBF_DEBUG(MESSAGE, ...) \
BBFDM_DEBUG(MESSAGE, ##__VA_ARGS__)
#endif //__DMBBF_H__ #endif //__DMBBF_H__

View file

@ -1717,40 +1717,22 @@ int bbfdm_validate_hexBinary_list(struct dmctx *ctx, const char *value, int min_
bool folder_exists(const char *path) bool folder_exists(const char *path)
{ {
struct stat buffer; return bbfdm_folder_exists(path);
return stat(path, &buffer) == 0 && S_ISDIR(buffer.st_mode);
} }
bool file_exists(const char *path) bool file_exists(const char *path)
{ {
struct stat buffer; return bbfdm_file_exists(path);
return stat(path, &buffer) == 0;
} }
bool is_regular_file(const char *path) bool is_regular_file(const char *path)
{ {
struct stat buffer; return bbfdm_is_regular_file(path);
return stat(path, &buffer) == 0 && S_ISREG(buffer.st_mode);
} }
int create_empty_file(const char *file_name) int create_empty_file(const char *file_name)
{ {
if (!file_name) return bbfdm_create_empty_file(file_name);
return -1;
// Skip creating the file if it already exists
if (file_exists(file_name))
return 0;
FILE *fp = fopen(file_name, "w");
if (fp == NULL)
return -1;
fclose(fp);
return 0;
} }
unsigned long file_system_size(const char *path, const enum fs_size_type_enum type) unsigned long file_system_size(const char *path, const enum fs_size_type_enum type)

View file

@ -47,16 +47,16 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
blob_buf_init(&ctx->bb, 0); blob_buf_init(&ctx->bb, 0);
ctx->dm_entryobj = tEntryObj; ctx->dm_entryobj = tEntryObj;
bbfdm_init_mem(ctx); dm_init_mem(ctx);
bbfdm_uci_init(ctx); dm_uci_init(ctx);
} }
void bbf_ctx_clean(struct dmctx *ctx) void bbf_ctx_clean(struct dmctx *ctx)
{ {
blob_buf_free(&ctx->bb); blob_buf_free(&ctx->bb);
bbfdm_uci_exit(ctx); dm_uci_exit(ctx);
bbfdm_clean_mem(ctx); dm_clean_mem(ctx);
dmubus_free(); dmubus_free();
} }

View file

@ -167,7 +167,7 @@ static struct list_head *get_ctx_memhead_list(struct dmctx *ctx)
return ctx->memhead; return ctx->memhead;
} }
void bbfdm_init_mem(struct dmctx *ctx) void dm_init_mem(struct dmctx *ctx)
{ {
struct list_head *memory_list_head = calloc(1, sizeof(struct list_head)); struct list_head *memory_list_head = calloc(1, sizeof(struct list_head));
@ -183,7 +183,7 @@ void bbfdm_init_mem(struct dmctx *ctx)
ctx->memhead = dm_memhead_ptr = memory_list_head; ctx->memhead = dm_memhead_ptr = memory_list_head;
} }
void bbfdm_clean_mem(struct dmctx *ctx) void dm_clean_mem(struct dmctx *ctx)
{ {
struct dmmem *dmm = NULL, *tmp = NULL; struct dmmem *dmm = NULL, *tmp = NULL;
@ -201,7 +201,7 @@ void bbfdm_clean_mem(struct dmctx *ctx)
dm_memhead_ptr = NULL; dm_memhead_ptr = NULL;
} }
void *bbfdm_malloc(struct dmctx *ctx, size_t size) void *dm_malloc(struct dmctx *ctx, size_t size)
{ {
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx); struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL) if (ctx_memhead == NULL)
@ -213,7 +213,7 @@ void *bbfdm_malloc(struct dmctx *ctx, size_t size)
return (void *)m->mem; return (void *)m->mem;
} }
void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size) void *dm_calloc(struct dmctx *ctx, int n, size_t size)
{ {
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx); struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL) if (ctx_memhead == NULL)
@ -225,7 +225,7 @@ void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size)
return (void *)m->mem; return (void *)m->mem;
} }
void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size) void *dm_realloc(struct dmctx *ctx, void *n, size_t size)
{ {
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx); struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL) if (ctx_memhead == NULL)
@ -249,13 +249,13 @@ void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size)
return (void *)m->mem; return (void *)m->mem;
} }
char *bbfdm_strdup(struct dmctx *ctx, const char *s) char *dm_strdup(struct dmctx *ctx, const char *s)
{ {
if (s == NULL) if (s == NULL)
return NULL; return NULL;
size_t len = strlen(s) + 1; size_t len = strlen(s) + 1;
void *new = bbfdm_malloc(ctx, len); void *new = dm_malloc(ctx, len);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
@ -263,7 +263,7 @@ char *bbfdm_strdup(struct dmctx *ctx, const char *s)
return (char *) memcpy(new, s, len); return (char *) memcpy(new, s, len);
} }
int bbfdm_asprintf(struct dmctx *ctx, char **s, const char *format, ...) int dm_asprintf(struct dmctx *ctx, char **s, const char *format, ...)
{ {
va_list arg; va_list arg;
char *str = NULL; char *str = NULL;
@ -276,7 +276,7 @@ int bbfdm_asprintf(struct dmctx *ctx, char **s, const char *format, ...)
if (size < 0 || str == NULL) if (size < 0 || str == NULL)
return -1; return -1;
*s = bbfdm_strdup(ctx, str); *s = dm_strdup(ctx, str);
FREE(str); FREE(str);
if (*s == NULL) if (*s == NULL)

View file

@ -35,13 +35,13 @@ int __dmastrcat(struct list_head *mem_list, char **s, char *obj, char *lastname)
* Initialize memory management. * Initialize memory management.
* @param ctx - Pointer to bbf context * @param ctx - Pointer to bbf context
*/ */
void bbfdm_init_mem(struct dmctx *ctx); void dm_init_mem(struct dmctx *ctx);
/* /*
* Clean up memory management. * Clean up memory management.
* @param ctx - Pointer to bbf context * @param ctx - Pointer to bbf context
*/ */
void bbfdm_clean_mem(struct dmctx *ctx); void dm_clean_mem(struct dmctx *ctx);
/* /*
* Allocate memory block of the specified size. * Allocate memory block of the specified size.
@ -49,7 +49,7 @@ void bbfdm_clean_mem(struct dmctx *ctx);
* @param size - Size of memory block to allocate * @param size - Size of memory block to allocate
* @return Pointer to the allocated memory block * @return Pointer to the allocated memory block
*/ */
void *bbfdm_malloc(struct dmctx *ctx, size_t size); void *dm_malloc(struct dmctx *ctx, size_t size);
/* /*
* Allocate memory for an array of n elements, each of size bytes, initialized to zero. * Allocate memory for an array of n elements, each of size bytes, initialized to zero.
@ -58,7 +58,7 @@ void *bbfdm_malloc(struct dmctx *ctx, size_t size);
* @param size - Size of each element * @param size - Size of each element
* @return Pointer to the allocated memory block * @return Pointer to the allocated memory block
*/ */
void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size); void *dm_calloc(struct dmctx *ctx, int n, size_t size);
/* /*
* Resize the memory block pointed to by n to the new size size. * Resize the memory block pointed to by n to the new size size.
@ -67,7 +67,7 @@ void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size);
* @param size - New size of the memory block * @param size - New size of the memory block
* @return Pointer to the resized memory block * @return Pointer to the resized memory block
*/ */
void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size); void *dm_realloc(struct dmctx *ctx, void *n, size_t size);
/* /*
* Duplicate the string s. * Duplicate the string s.
@ -75,7 +75,7 @@ void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size);
* @param s - Pointer to the string to duplicate * @param s - Pointer to the string to duplicate
* @return Pointer to the duplicated string * @return Pointer to the duplicated string
*/ */
char *bbfdm_strdup(struct dmctx *ctx, const char *s); char *dm_strdup(struct dmctx *ctx, const char *s);
/* /*
* Allocate a string with a format similar to printf. * Allocate a string with a format similar to printf.
@ -85,13 +85,13 @@ char *bbfdm_strdup(struct dmctx *ctx, const char *s);
* @param ... - Additional arguments for the format string * @param ... - Additional arguments for the format string
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int bbfdm_asprintf(struct dmctx *ctx, char **s, const char *format, ...); int dm_asprintf(struct dmctx *ctx, char **s, const char *format, ...);
#define dmmalloc(x) bbfdm_malloc(0, x) #define dmmalloc(x) dm_malloc(0, x)
#define dmcalloc(n, x) bbfdm_calloc(0, n, x) #define dmcalloc(n, x) dm_calloc(0, n, x)
#define dmrealloc(x, n) bbfdm_realloc(0, x, n) #define dmrealloc(x, n) dm_realloc(0, x, n)
#define dmstrdup(x) bbfdm_strdup(0, x) #define dmstrdup(x) dm_strdup(0, x)
#define dmasprintf(s, format, ...) bbfdm_asprintf(0, s, format, ## __VA_ARGS__) #define dmasprintf(s, format, ...) dm_asprintf(0, s, format, ## __VA_ARGS__)
#define dm_dynamic_malloc(m, x) __dmmalloc(m, x) #define dm_dynamic_malloc(m, x) __dmmalloc(m, x)
#define dm_dynamic_calloc(m, n, x) __dmcalloc(m, n, x) #define dm_dynamic_calloc(m, n, x) __dmcalloc(m, n, x)

View file

@ -99,25 +99,23 @@ static void receive_call_result_data(struct ubus_request *req, int type, struct
static int __dm_ubus_call_internal(const char *obj, const char *method, int timeout, struct blob_attr *attr) static int __dm_ubus_call_internal(const char *obj, const char *method, int timeout, struct blob_attr *attr)
{ {
uint32_t id = 0; uint32_t id = 0;
int rc = 0;
json_res = NULL; json_res = NULL;
if (ubus_ctx == NULL) { if (ubus_ctx == NULL) {
ubus_ctx = dm_libubus_init(); ubus_ctx = dm_libubus_init();
if (ubus_ctx == NULL) { if (ubus_ctx == NULL) {
printf("UBUS context is null\n\r"); BBF_ERR("UBUS context is null");
return -1; return -1;
} }
} }
if (!ubus_lookup_id(ubus_ctx, obj, &id)) if (ubus_lookup_id(ubus_ctx, obj, &id)) {
rc = ubus_invoke(ubus_ctx, id, method, attr, BBF_ERR("Failed to lookup UBUS object ID for '%s'", obj);
receive_call_result_data, NULL, timeout); return -1;
else }
rc = -1;
return rc; return ubus_invoke(ubus_ctx, id, method, attr, receive_call_result_data, NULL, timeout);
} }
static int __dm_ubus_call(const char *obj, const char *method, struct blob_attr *attr) static int __dm_ubus_call(const char *obj, const char *method, struct blob_attr *attr)
@ -351,11 +349,14 @@ static int dmubus_call_blob_internal(const char *obj, const char *method, json_o
} }
} }
if (!ubus_lookup_id(ubus_ctx, obj, &id)) { if (ubus_lookup_id(ubus_ctx, obj, &id)) {
rc = ubus_invoke(ubus_ctx, id, method, blob.head, BBF_ERR("Failed to lookup UBUS object ID for '%s'", obj);
receive_call_result_data, NULL, timeout); blob_buf_free(&blob);
return rc;
} }
rc = ubus_invoke(ubus_ctx, id, method, blob.head, receive_call_result_data, NULL, timeout);
if (resp) *resp = json_res; if (resp) *resp = json_res;
blob_buf_free(&blob); blob_buf_free(&blob);
return rc; return rc;
@ -396,16 +397,18 @@ static int dmubus_call_blob_msg_internal(const char *obj, const char *method, st
if (ubus_ctx == NULL) { if (ubus_ctx == NULL) {
ubus_ctx = dm_libubus_init(); ubus_ctx = dm_libubus_init();
if (ubus_ctx == NULL) { if (ubus_ctx == NULL) {
printf("UBUS context is null\n\r"); BBF_ERR("UBUS context is null");
return -1; return -1;
} }
} }
if (!ubus_lookup_id(ubus_ctx, obj, &id)) { if (ubus_lookup_id(ubus_ctx, obj, &id)) {
rc = ubus_invoke(ubus_ctx, id, method, data->head, BBF_ERR("Failed to lookup UBUS object ID for '%s'", obj);
receive_call_result_data, NULL, timeout); return -1;
} }
rc = ubus_invoke(ubus_ctx, id, method, data->head, receive_call_result_data, NULL, timeout);
if (resp) if (resp)
*resp = json_res; *resp = json_res;

View file

@ -37,7 +37,7 @@ static void bbfdm_uci_init_ctx(struct uci_context **uci_ctx, const char *confdir
uci_set_savedir(*uci_ctx, savedir); uci_set_savedir(*uci_ctx, savedir);
} }
void bbfdm_uci_init(struct dmctx *bbf_ctx) void dm_uci_init(struct dmctx *bbf_ctx)
{ {
if (bbf_ctx->dm_type == BBFDM_CWMP) { if (bbf_ctx->dm_type == BBFDM_CWMP) {
bbfdm_uci_init_ctx(&bbf_ctx->config_uci_ctx, config_dir, "/tmp/bbfdm/.cwmp/config/"); bbfdm_uci_init_ctx(&bbf_ctx->config_uci_ctx, config_dir, "/tmp/bbfdm/.cwmp/config/");
@ -57,7 +57,7 @@ void bbfdm_uci_init(struct dmctx *bbf_ctx)
uci_ctx_varstate = bbf_ctx->varstate_uci_ctx; uci_ctx_varstate = bbf_ctx->varstate_uci_ctx;
} }
void bbfdm_uci_exit(struct dmctx *bbf_ctx) void dm_uci_exit(struct dmctx *bbf_ctx)
{ {
if (bbf_ctx->config_uci_ctx) { if (bbf_ctx->config_uci_ctx) {
uci_free_context(bbf_ctx->config_uci_ctx); uci_free_context(bbf_ctx->config_uci_ctx);

View file

@ -274,8 +274,8 @@ int dmuci_delete_by_section_unnamed_##UCI_PATH(struct uci_section *s, const char
return res; \ return res; \
}\ }\
void bbfdm_uci_init(struct dmctx *bbf_ctx); void dm_uci_init(struct dmctx *bbf_ctx);
void bbfdm_uci_exit(struct dmctx *bbf_ctx); void dm_uci_exit(struct dmctx *bbf_ctx);
char *dmuci_list_to_string(struct uci_list *list, const char *delimitor); char *dmuci_list_to_string(struct uci_list *list, const char *delimitor);
int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, const char *package, const char *section, const char *option, const char *value); int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, const char *package, const char *section, const char *option, const char *value);

View file

@ -893,12 +893,4 @@ int bbfdm_validate_hexBinary_list(struct dmctx *ctx, const char *value, int min_
**************************************************************************/ **************************************************************************/
void bbfdm_set_fault_message(struct dmctx *ctx, const char *format, ...); void bbfdm_set_fault_message(struct dmctx *ctx, const char *format, ...);
/**********************
*
* BBF DEPRECATED APIs
*
**********************/
__attribute__ ((deprecated("Use bbfdm_get_references"))) int bbf_get_reference_param(char *path, char *key_name, char *key_value, char **value);
__attribute__ ((deprecated("Use bbfdm_get_reference_linker"))) int bbf_get_reference_args(char *value, struct dm_reference *reference_args);
#endif //__LIBBBFDM_API_H__ #endif //__LIBBBFDM_API_H__

View file

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm-api-version-2)
ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE)
FILE(GLOB BBFDM_API_SOURCES *.c)
ADD_LIBRARY(bbfdm-api-v2 SHARED ${BBFDM_API_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm-api-v2 uci ubus)
INSTALL(TARGETS bbfdm-api-v2
LIBRARY DESTINATION usr/lib)
FILE(GLOB libbbfdm-api-v2_headers *.h)
INSTALL(FILES ${libbbfdm-api-v2_headers}
DESTINATION usr/include/libbbfdm-api
)
FILE(GLOB libbbfdm-api-v2_headers *.h)
INSTALL(FILES ${libbbfdm-api-v2_headers}
DESTINATION usr/include/libbbfdm-api/version-2
)

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "bbfdm_api.h"
int bbfdm_init_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
memset(bbfdm_ctx, 0, sizeof(struct bbfdm_ctx));
bbfdm_init_uci_ctx(bbfdm_ctx);
bbfdm_init_ubus_ctx(bbfdm_ctx);
bbfdm_init_mem(bbfdm_ctx);
return 0;
}
int bbfdm_free_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
bbfdm_free_uci_ctx(bbfdm_ctx);
bbfdm_free_ubus_ctx(bbfdm_ctx);
bbfdm_free_mem(bbfdm_ctx);
return 0;
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __BBFDM_API_H
#define __BBFDM_API_H
#ifdef __cplusplus
extern "C" {
#endif
#include <uci.h>
#include <libubus.h>
#include <syslog.h>
struct bbfdm_ctx;
#include "bbfdm_uci.h"
#include "bbfdm_ubus.h"
#include "bbfdm_mem.h"
#include "bbfdm_system.h"
struct bbfdm_ctx {
struct uci_context *uci_ctx; /**< Pointer to the UCI context. */
struct ubus_context *ubus_ctx; /**< Pointer to the UBUS context. */
struct list_head *mem_head; /**< Pointer to the list head for memory management. */
const char *uci_confdir; /**< Path to the UCI configuration directory. */
const char *uci_savedir; /**< Path to the UCI save directory. */
};
/**
* @brief Initialize the BBFDM context.
*
* This function initializes the UCI and UBUS contexts and allocates memory required for the BBFDM context.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context structure.
* @return 0 on success, non-zero on failure.
*/
int bbfdm_init_ctx(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Free resources associated with the BBFDM context.
*
* This function releases the UCI and UBUS contexts and any allocated memory within the BBFDM context.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context structure.
* @return 0 on success, non-zero on failure.
*/
int bbfdm_free_ctx(struct bbfdm_ctx *bbfdm_ctx);
#ifndef BBFDM_FREE
#define BBFDM_FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
#endif
#define BBFDM_ERR(MESSAGE, ...) \
do { \
syslog(LOG_ERR, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#define BBFDM_WARNING(MESSAGE, ...) \
do { \
syslog(LOG_WARNING, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#define BBFDM_INFO(MESSAGE, ...) \
do { \
syslog(LOG_INFO, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#define BBFDM_DEBUG(MESSAGE, ...) \
do { \
syslog(LOG_DEBUG, "[%s:%d] " MESSAGE, __FUNCTION__, __LINE__, ##__VA_ARGS__); /* Flawfinder: ignore */ \
} while(0)
#ifdef __cplusplus
}
#endif
#endif //__BBFDM_API_H

View file

@ -0,0 +1,131 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "bbfdm_api.h"
struct bbfdm_mem {
struct list_head list;
char mem[0];
};
void bbfdm_init_mem(struct bbfdm_ctx *bbfdm_ctx)
{
bbfdm_ctx->mem_head = calloc(1, sizeof(struct list_head));
if (bbfdm_ctx->mem_head == NULL) {
BBFDM_ERR("Failed to allocate memory for the list head!!!");
return;
}
// Initialize the list head
INIT_LIST_HEAD(bbfdm_ctx->mem_head);
}
void bbfdm_free_mem(struct bbfdm_ctx *bbfdm_ctx)
{
struct bbfdm_mem *dmm = NULL, *tmp = NULL;
if (bbfdm_ctx->mem_head == NULL) {
BBFDM_ERR("Memory list is NULL!");
return;
}
list_for_each_entry_safe(dmm, tmp, bbfdm_ctx->mem_head, list) {
list_del(&dmm->list);
BBFDM_FREE(dmm);
}
BBFDM_FREE(bbfdm_ctx->mem_head);
}
void *bbfdm_malloc(struct bbfdm_ctx *bbfdm_ctx, size_t size)
{
struct bbfdm_mem *m = malloc(sizeof(struct bbfdm_mem) + size);
if (m == NULL)
return NULL;
list_add(&m->list, bbfdm_ctx->mem_head);
return (void *)m->mem;
}
void *bbfdm_calloc(struct bbfdm_ctx *bbfdm_ctx, int n, size_t size)
{
struct bbfdm_mem *m = calloc(n, sizeof(struct bbfdm_mem) + size);
if (m == NULL)
return NULL;
list_add(&m->list, bbfdm_ctx->mem_head);
return (void *)m->mem;
}
void *bbfdm_realloc(struct bbfdm_ctx *bbfdm_ctx, void *n, size_t size)
{
struct bbfdm_mem *m = NULL;
if (n != NULL) {
m = container_of(n, struct bbfdm_mem, mem);
list_del(&m->list);
}
struct bbfdm_mem *new_m = realloc(m, sizeof(struct bbfdm_mem) + size);
if (new_m == NULL) {
bbfdm_free_mem_bloc(m);
return NULL;
} else {
m = new_m;
}
list_add(&m->list, bbfdm_ctx->mem_head);
return (void *)m->mem;
}
char *bbfdm_strdup(struct bbfdm_ctx *bbfdm_ctx, const char *s)
{
if (s == NULL)
return NULL;
size_t len = strlen(s) + 1;
void *new = bbfdm_malloc(bbfdm_ctx, len);
if (new == NULL)
return NULL;
return (char *) memcpy(new, s, len);
}
int bbfdm_asprintf(struct bbfdm_ctx *bbfdm_ctx, char **s, const char *format, ...)
{
va_list arg;
char *str = NULL;
int size = 0;
va_start(arg, format);
size = vasprintf(&str, format, arg);
va_end(arg);
if (size < 0 || str == NULL)
return -1;
*s = bbfdm_strdup(bbfdm_ctx, str);
BBFDM_FREE(str);
if (*s == NULL)
return -1;
return 0;
}
void bbfdm_free_mem_bloc(const void *m)
{
if (m == NULL) return;
struct bbfdm_mem *rm;
rm = container_of(m, struct bbfdm_mem, mem);
list_del(&rm->list);
BBFDM_FREE(rm);
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __BBFDM_MEM_H
#define __BBFDM_MEM_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes the memory management list for the bbfdm context.
*
* This function allocates and initializes a memory list head within the given
* bbfdm context. This list is used to manage dynamic memory allocations.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
*
* @note This function must be called before using any other memory-related functions.
* Ensure to free the memory by calling `bbfdm_free_mem()` when done.
*/
void bbfdm_init_mem(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Frees all dynamically allocated memory in the bbfdm context.
*
* This function traverses the memory list and frees all dynamically allocated
* memory blocks, as well as the list head itself.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
*
* @note Ensure that all allocated memory in the context is no longer in use
* before calling this function.
*/
void bbfdm_free_mem(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Allocates a block of memory and tracks it in the bbfdm context.
*
* This function allocates a block of memory of the specified size and adds it
* to the memory management list in the bbfdm context.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param size Size of the memory block to allocate.
* @return Pointer to the allocated memory block, or NULL on failure.
*/
void *bbfdm_malloc(struct bbfdm_ctx *bbfdm_ctx, size_t size);
/**
* @brief Allocates and zero-initializes a block of memory and tracks it in the bbfdm context.
*
* This function allocates a block of memory for an array of `n` elements of
* `size` bytes each and initializes all bytes to zero. The allocation is
* tracked in the memory management list in the bbfdm context.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param n Number of elements to allocate.
* @param size Size of each element in bytes.
* @return Pointer to the allocated and zero-initialized memory block, or NULL on failure.
*/
void *bbfdm_calloc(struct bbfdm_ctx *bbfdm_ctx, int n, size_t size);
/**
* @brief Reallocates a previously allocated memory block to a new size.
*
* This function adjusts the size of a previously allocated memory block and
* updates the memory management list in the bbfdm context. If the reallocation
* fails, the original memory block is freed.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param n Pointer to the existing memory block.
* @param size New size of the memory block in bytes.
* @return Pointer to the reallocated memory block, or NULL on failure.
*/
void *bbfdm_realloc(struct bbfdm_ctx *bbfdm_ctx, void *n, size_t size);
/**
* @brief Duplicates a string and tracks it in the bbfdm context.
*
* This function allocates memory for a copy of the given string and adds it to
* the memory management list in the bbfdm context.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param s String to duplicate.
* @return Pointer to the duplicated string, or NULL on failure.
*/
char *bbfdm_strdup(struct bbfdm_ctx *bbfdm_ctx, const char *s);
/**
* @brief Formats a string and allocates memory for it in the bbfdm context.
*
* This function formats a string according to the given format specifier and
* stores the result in a newly allocated memory block, tracked in the bbfdm
* context.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param s Pointer to a char pointer where the formatted string will be stored.
* @param format Format specifier (similar to printf).
* @param ... Additional arguments for the format specifier.
* @return 0 on success, or -1 on failure.
*/
int bbfdm_asprintf(struct bbfdm_ctx *bbfdm_ctx, char **s, const char *format, ...);
/**
* @brief Frees a specific memory block from the bbfdm context's memory list.
*
* This function removes a specific memory block from the memory management list
* and frees its associated memory.
*
* @param m Pointer to the memory block to free.
*
* @note This function does not require the bbfdm context as it determines the
* list entry from the given memory block pointer.
*/
void bbfdm_free_mem_bloc(const void *m);
#ifdef __cplusplus
}
#endif
#endif //__BBFDM_MEM_H

View file

@ -0,0 +1,62 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include <stdio.h>
#include <stdbool.h>
#include <stddef.h>
#include <sys/stat.h>
bool bbfdm_folder_exists(const char *path)
{
struct stat buffer;
if (!path)
return false;
return stat(path, &buffer) == 0 && S_ISDIR(buffer.st_mode);
}
bool bbfdm_file_exists(const char *path)
{
struct stat buffer;
if (!path)
return false;
return stat(path, &buffer) == 0;
}
bool bbfdm_is_regular_file(const char *path)
{
struct stat buffer;
if (!path)
return false;
return stat(path, &buffer) == 0 && S_ISREG(buffer.st_mode);
}
int bbfdm_create_empty_file(const char *path)
{
if (!path)
return -1;
// Skip creating the file if it already exists
if (bbfdm_file_exists(path))
return 0;
FILE *fp = fopen(path, "w");
if (fp == NULL)
return -1;
fclose(fp);
return 0;
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __BBFDM_SYSTEM_H
#define __BBFDM_SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Check if a folder exists at the given path.
*
* This function verifies the existence of a folder at the specified path.
*
* @param[in] path Path to the folder.
* @return true if the folder exists, false otherwise.
*/
bool bbfdm_folder_exists(const char *path);
/**
* @brief Check if a file exists at the given path.
*
* This function verifies the existence of a file at the specified path.
*
* @param[in] path Path to the file.
* @return true if the file exists, false otherwise.
*/
bool bbfdm_file_exists(const char *path);
/**
* @brief Check if a file is a regular file.
*
* This function determines whether the file at the specified path is a regular file.
*
* @param[in] path Path to the file.
* @return true if the file is a regular file, false otherwise.
*/
bool bbfdm_is_regular_file(const char *path);
/**
* @brief Create an empty file at the specified path.
*
* This function creates an empty file if it does not already exist. If the file already exists, it skips creation.
*
* @param[in] path Path to the file.
* @return 0 on success, -1 on failure.
*/
int bbfdm_create_empty_file(const char *path);
#ifdef __cplusplus
}
#endif
#endif //__BBFDM_SYSTEM_H

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "bbfdm_api.h"
int bbfdm_init_ubus_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
bbfdm_ctx->ubus_ctx = ubus_connect(NULL);
if (!bbfdm_ctx->ubus_ctx) {
BBFDM_ERR("Failed to connect to UBUS");
return -1;
}
return 0;
}
int bbfdm_free_ubus_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
if (bbfdm_ctx->ubus_ctx) {
ubus_free(bbfdm_ctx->ubus_ctx);
}
return 0;
}
int bbfdm_ubus_invoke_sync(struct bbfdm_ctx *bbfdm_ctx, const char *obj, const char *method, struct blob_attr *msg, int timeout,
bbfdm_ubus_cb data_callback, void *callback_args)
{
uint32_t id;
if (!bbfdm_ctx || !bbfdm_ctx->ubus_ctx) {
BBFDM_ERR("Invalid context or UBUS context is NULL");
return -1;
}
if (ubus_lookup_id(bbfdm_ctx->ubus_ctx, obj, &id)) {
BBFDM_ERR("Failed to lookup UBUS object ID for '%s'", obj);
return -1;
}
int ret = ubus_invoke(bbfdm_ctx->ubus_ctx, id, method, msg, data_callback, callback_args, timeout);
if (ret != 0) {
BBFDM_ERR("UBUS invoke failed for obj='%s', method='%s', error code=%d", obj, method, ret);
}
return ret;
}
int bbfdm_ubus_invoke_async(struct ubus_context *ubus_ctx, const char *obj, const char *method, struct blob_attr *msg,
bbfdm_ubus_cb data_callback, bbfdm_ubus_async_cb complete_callback)
{
struct ubus_request *req = NULL;
uint32_t id;
if (ubus_ctx == NULL) {
BBFDM_ERR("UBUS context is NULL");
return -1;
}
if (ubus_lookup_id(ubus_ctx, obj, &id)) {
BBFDM_ERR("Failed to lookup UBUS object ID for '%s'", obj);
return -1;
}
req = (struct ubus_request *)calloc(1, sizeof(struct ubus_request));
if (req == NULL) {
BBFDM_ERR("Failed to allocate memory for UBUS request");
return -1;
}
if (ubus_invoke_async(ubus_ctx, id, method, msg, req)) {
BBFDM_ERR("UBUS async invoke failed for obj='%s', method='%s'", obj, method);
BBFDM_FREE(req);
return -1;
}
if (data_callback)
req->data_cb = data_callback;
if (complete_callback)
req->complete_cb = complete_callback;
ubus_complete_request_async(ubus_ctx, req);
return 0;
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __BBFDM_UBUS_H
#define __BBFDM_UBUS_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*bbfdm_ubus_cb)(struct ubus_request *req, int type, struct blob_attr *msg);
typedef void (*bbfdm_ubus_async_cb)(struct ubus_request *req, int ret);
/**
* @brief Initializes the UBUS context within the BBFDM context.
*
* This function establishes a connection to the UBUS system and assigns the
* resulting context to the provided `bbfdm_ctx`.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context to initialize.
* @return 0 on success, -1 on failure.
*/
int bbfdm_init_ubus_ctx(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Frees the UBUS context within the BBFDM context.
*
* This function releases resources associated with the UBUS context in
* the provided `bbfdm_ctx`.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context to free.
* @return 0 on success.
*/
int bbfdm_free_ubus_ctx(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Invokes a UBUS method synchronously.
*
* Sends a synchronous request to a UBUS object and invokes the provided callback
* with the result.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context.
* @param[in] obj Name of the UBUS object to invoke.
* @param[in] method Name of the method to invoke.
* @param[in] msg Pointer to a `blob_attr` message to send as input.
* @param[in] timeout Timeout for the request in milliseconds.
* @param[in] data_callback Callback function for handling response data.
* @param[in] callback_args User-provided arguments to pass to the callback.
* @return 0 on success, -1 on failure.
*/
int bbfdm_ubus_invoke_sync(struct bbfdm_ctx *bbfdm_ctx, const char *obj, const char *method, struct blob_attr *msg, int timeout,
bbfdm_ubus_cb data_callback, void *callback_args);
/**
* @brief Invokes a UBUS method asynchronously.
*
* Sends an asynchronous request to a UBUS object and sets up the provided callbacks
* for data and completion handling.
*
* @param[in] ubus_ctx Pointer to the UBUS context.
* @param[in] obj Name of the UBUS object to invoke.
* @param[in] method Name of the method to invoke.
* @param[in] msg Pointer to a `blob_attr` message to send as input.
* @param[in] data_callback Callback function for handling response data.
* @param[in] complete_callback Callback function to call upon request completion.
* @return 0 on success, -1 on failure.
*/
int bbfdm_ubus_invoke_async(struct ubus_context *ubus_ctx, const char *obj, const char *method, struct blob_attr *msg,
bbfdm_ubus_cb data_callback, bbfdm_ubus_async_cb complete_callback);
/**
* @brief Invokes a synchronous UBUS method.
*
* This macro simplifies the process of initializing a context, invoking a UBUS
* method synchronously, and cleaning up the context.
*
* @param obj The name of the UBUS object to invoke.
* @param method The name of the method to invoke.
* @param msg Pointer to a `blob_attr` message to send as input.
* @param data_callback Callback function for handling response data.
* @param callback_args User-provided arguments to pass to the callback.
* @return Always returns 0.
*/
#define BBFDM_UBUS_INVOKE_SYNC(obj, method, msg, timeout, data_callback, callback_args) \
do { \
struct bbfdm_ctx ctx = {0}; \
memset(&ctx, 0, sizeof(struct bbfdm_ctx)); \
bbfdm_init_ctx(&ctx); \
bbfdm_ubus_invoke_sync(&ctx, obj, method, msg, timeout, data_callback, callback_args); \
bbfdm_free_ctx(&ctx); \
} while (0)
#ifdef __cplusplus
}
#endif
#endif //__BBFDM_UBUS_H

View file

@ -0,0 +1,283 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "bbfdm_api.h"
int bbfdm_init_uci_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
bbfdm_ctx->uci_ctx = uci_alloc_context();
if (!bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Failed to allocate UCI context");
return -1;
}
if (bbfdm_ctx->uci_confdir) {
BBFDM_DEBUG("Setting UCI configuration directory: %s", bbfdm_ctx->uci_confdir);
uci_set_confdir(bbfdm_ctx->uci_ctx, bbfdm_ctx->uci_confdir);
}
if (bbfdm_ctx->uci_savedir) {
BBFDM_DEBUG("Setting UCI save directory: %s", bbfdm_ctx->uci_savedir);
uci_set_savedir(bbfdm_ctx->uci_ctx, bbfdm_ctx->uci_savedir);
}
return 0;
}
int bbfdm_free_uci_ctx(struct bbfdm_ctx *bbfdm_ctx)
{
if (bbfdm_ctx->uci_ctx) {
uci_free_context(bbfdm_ctx->uci_ctx);
}
return 0;
}
int bbfdm_uci_get_buf(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *default_value,
char *buffer, size_t buffer_size)
{
struct uci_ptr ptr = {0};
char uci_str[512] = {0};
if (!package || !section || !option || !default_value || !buffer || !buffer_size) {
BBFDM_ERR("Invalid parameters provided to bbfdm_uci_get_buf API");
return -1;
}
if (!bbfdm_ctx || !bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Invalid UCI context");
return -1;
}
snprintf(uci_str, sizeof(uci_str), "%s.%s.%s", package, section, option);
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK || ptr.o == NULL) {
BBFDM_WARNING("UCI value not found for '%s.%s.%s'. Using default: '%s'", package, section, option, default_value);
snprintf(buffer, buffer_size, "%s", default_value);
return -1;
}
snprintf(buffer, buffer_size, "%s", ptr.o->v.string);
return 0;
}
int bbfdm_uci_get(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, char **value)
{
char buffer[1024] = {0};
int res = bbfdm_uci_get_buf(bbfdm_ctx, package, section, option, "", buffer, sizeof(buffer));
*value = bbfdm_strdup(bbfdm_ctx, buffer);
return res;
}
int bbfdm_uci_get_fallback_def(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *default_value, char **value)
{
char buffer[1024] = {0};
int res = bbfdm_uci_get_buf(bbfdm_ctx, package, section, option, default_value, buffer, sizeof(buffer));
*value = bbfdm_strdup(bbfdm_ctx, buffer);
return res;
}
int bbfdm_uci_get_by_section_buf(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *section, const char *option, const char *default_value,
char *buffer, size_t buffer_size)
{
struct uci_element *e = NULL;
if (!section || !option || !default_value || !buffer || !buffer_size) {
BBFDM_ERR("Invalid parameters provided to bbfdm_uci_get_by_section_buf API");
return -1;
}
uci_foreach_element(&section->options, e) {
struct uci_option *o = uci_to_option(e);
if (strcmp(o->e.name, option) == 0 && o->type == UCI_TYPE_STRING) {
snprintf(buffer, buffer_size, "%s", o->v.string);
return 0;
}
}
snprintf(buffer, buffer_size, "%s", default_value);
return -1;
}
int bbfdm_uci_get_by_section(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *section, const char *option, char **value)
{
char buffer[1024] = {0};
int res = bbfdm_uci_get_by_section_buf(bbfdm_ctx, section, option, "", buffer, sizeof(buffer));
*value = bbfdm_strdup(bbfdm_ctx, buffer);
return res;
}
int bbfdm_uci_set(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *value)
{
struct uci_ptr ptr = {0};
char uci_str[512] = {0};
if (!package || !section || !value) {
BBFDM_ERR("Invalid parameters provided to bbfdm_uci_set API");
return -1;
}
if (!bbfdm_ctx || !bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Invalid UCI context");
return -1;
}
snprintf(uci_str, sizeof(uci_str), "%s.%s%s%s=%s",
package,
section,
option ? "." : "",
option ? option : "",
value);
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK ||
uci_set(bbfdm_ctx->uci_ctx, &ptr) != UCI_OK ||
uci_save(bbfdm_ctx->uci_ctx, ptr.p) != UCI_OK) {
BBFDM_ERR("Failed to set UCI option: %s", uci_str);
return -1;
}
return 0;
}
int bbfdm_uci_add(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *type, struct uci_section **s)
{
struct uci_ptr ptr = {0};
char uci_str[64] = {0};
char config_name[128];
if (!package || !type) {
BBFDM_ERR("Invalid parameters provided to bbfdm_uci_add API");
return -1;
}
if (!bbfdm_ctx || !bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Invalid UCI context");
return -1;
}
snprintf(config_name, sizeof(config_name), "%s/%s", bbfdm_ctx->uci_ctx->confdir, package);
if (bbfdm_create_empty_file(config_name)) {
BBFDM_ERR("Failed to create empty UCI file: %s", config_name);
return -1;
}
snprintf(uci_str, sizeof(uci_str), "%s", package);
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK ||
uci_add_section(bbfdm_ctx->uci_ctx, ptr.p, type, s) != UCI_OK ||
uci_save(bbfdm_ctx->uci_ctx, ptr.p) != UCI_OK) {
BBFDM_ERR("Failed to add UCI section to package: %s with type: %s", package, type);
return -1;
}
return 0;
}
int bbfdm_uci_delete(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option)
{
struct uci_ptr ptr = {0};
char uci_str[64] = {0};
if (!package || !section)
return -1;
if (!bbfdm_ctx || !bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Invalid UCI context");
return -1;
}
snprintf(uci_str, sizeof(uci_str), "%s.%s%s%s",
package,
section,
option ? "." : "",
option ? option : "");
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK ||
uci_delete(bbfdm_ctx->uci_ctx, &ptr) != UCI_OK ||
uci_save(bbfdm_ctx->uci_ctx, ptr.p) != UCI_OK) {
BBFDM_ERR("Failed to delete UCI entry: %s", uci_str);
return -1;
}
return 0;
}
int bbfdm_uci_delete_section(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *s)
{
return bbfdm_uci_delete(bbfdm_ctx, bbfdm_section_config(s), bbfdm_section_name(s), NULL);
}
int bbfdm_uci_commit_package(struct bbfdm_ctx *bbfdm_ctx, const char *package)
{
struct uci_ptr ptr = {0};
char uci_str[64] = {0};
if (!package || !strlen(package)) {
BBFDM_ERR("Invalid package name in bbfdm_uci_commit_package API");
return -1;
}
if (!bbfdm_ctx || !bbfdm_ctx->uci_ctx) {
BBFDM_ERR("Invalid UCI context");
return -1;
}
snprintf(uci_str, sizeof(uci_str), "%s", package);
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK ||
uci_commit(bbfdm_ctx->uci_ctx, &ptr.p, false) != UCI_OK) {
BBFDM_ERR("Failed to commit UCI package: %s", package);
return -1;
}
return 0;
}
struct uci_section *bbfdm_uci_walk_section(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *type, struct uci_section *prev_section)
{
struct uci_list *ul = NULL, *shead = NULL;
struct uci_ptr ptr = {0};
if (prev_section) {
ul = &prev_section->e.list;
shead = &prev_section->package->sections;
} else {
char uci_str[64] = {0};
snprintf(uci_str, sizeof(uci_str), "%s", package);
if (uci_lookup_ptr(bbfdm_ctx->uci_ctx, &ptr, uci_str, true) != UCI_OK)
return NULL;
ul = &ptr.p->sections;
shead = &ptr.p->sections;
}
while (ul->next != shead) {
struct uci_element *e = container_of(ul->next, struct uci_element, list);
struct uci_section *next_section = uci_to_section(e);
if (strcmp(next_section->type, type) == 0)
return next_section;
ul = ul->next;
}
return NULL;
}

View file

@ -0,0 +1,321 @@
/*
* Copyright (C) 2025 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#ifndef __BBFDM_UCI_H
#define __BBFDM_UCI_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def bbfdm_section_name(s)
* @brief Retrieves the name of a UCI section.
* @param s Pointer to the UCI section.
* @return Name of the section, or an empty string if the section is NULL.
*/
#define bbfdm_section_name(s) s ? (s)->e.name : ""
/**
* @def bbfdm_section_type(s)
* @brief Retrieves the type of a UCI section.
* @param s Pointer to the UCI section.
* @return Type of the section, or an empty string if the section is NULL.
*/
#define bbfdm_section_type(s) s ? (s)->type : ""
/**
* @def bbfdm_section_config(s)
* @brief Retrieves the configuration name of a UCI section.
* @param s Pointer to the UCI section.
* @return Name of the configuration, or an empty string if the section is NULL.
*/
#define bbfdm_section_config(s) s ? (s)->package->e.name : ""
/**
* @brief Initializes the UCI context within the BBFDM context.
*
* Allocates and sets up the UCI context for use with BBFDM operations.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context structure.
* @return 0 on success, -1 on failure.
*/
int bbfdm_init_uci_ctx(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Frees the UCI context within the BBFDM context.
*
* Releases resources associated with the UCI context.
*
* @param[in,out] bbfdm_ctx Pointer to the BBFDM context structure.
* @return 0 on success, -1 on failure.
*/
int bbfdm_free_uci_ctx(struct bbfdm_ctx *bbfdm_ctx);
/**
* @brief Retrieves a UCI option value into a buffer.
*
* Fetches the value of a specific option within a package and section, falling back to a default value if the option is not found.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] section Name of the section within the package.
* @param[in] option Name of the option within the section.
* @param[in] default_value Default value to use if the option is not found.
* @param[out] buffer Buffer to store the retrieved value.
* @param[in] buffer_size Size of the buffer.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_get_buf(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *default_value,
char *buffer, size_t buffer_size);
/**
* @brief Retrieves a UCI option value as a dynamically allocated string.
*
* Fetches the value of a specific option within a package and section, returning it as a string allocated by the BBFDM memory system.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] section Name of the section within the package.
* @param[in] option Name of the option within the section.
* @param[out] value Pointer to store the allocated string containing the option value.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_get(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, char **value);
/**
* @brief Retrieves a UCI option value with a fallback default.
*
* Fetches the value of a specific option within a package and section, falling back to the specified default value if the option is not found.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] section Name of the section within the package.
* @param[in] option Name of the option within the section.
* @param[in] default_value Fallback default value if the option is not found.
* @param[out] value Pointer to store the allocated string containing the option value.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_get_fallback_def(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *default_value, char **value);
/**
* @brief Retrieves a UCI option value by section into a buffer.
*
* Searches for an option within a given section and stores the value in a buffer. If not found, a default value is used.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] section Pointer to the UCI section.
* @param[in] option Name of the option within the section.
* @param[in] default_value Default value to use if the option is not found.
* @param[out] buffer Buffer to store the retrieved value.
* @param[in] buffer_size Size of the buffer.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_get_by_section_buf(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *section, const char *option, const char *default_value,
char *buffer, size_t buffer_size);
/**
* @brief Retrieves a UCI option value by section as a dynamically allocated string.
*
* Searches for an option within a given section and returns the value as a dynamically allocated string.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] section Pointer to the UCI section.
* @param[in] option Name of the option within the section.
* @param[out] value Pointer to store the allocated string containing the option value.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_get_by_section(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *section, const char *option, char **value);
/**
* @brief Sets a UCI option value.
*
* Updates the value of a specific option within a package and section.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] section Name of the section within the package.
* @param[in] option Name of the option within the section.
* @param[in] value Value to set for the option.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_set(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option, const char *value);
/**
* @brief Adds a new section to a UCI package.
*
* Creates a new section of the specified type within the given package.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] type Type of the section to create.
* @param[out] s Pointer to store the created section.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_add(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *type, struct uci_section **s);
/**
* @brief Deletes a UCI option or section.
*
* Removes a specific option or an entire section from a UCI package.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] section Name of the section within the package.
* @param[in] option Name of the option to delete, or NULL to delete the section.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_delete(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *section, const char *option);
/**
* @brief Deletes a UCI section.
*
* Removes a specific section from a UCI package.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] s Pointer to the section to delete.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_delete_section(struct bbfdm_ctx *bbfdm_ctx, struct uci_section *s);
/**
* @brief Commits changes to a UCI package.
*
* Saves all modifications made to a UCI package.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @return 0 on success, -1 on failure.
*/
int bbfdm_uci_commit_package(struct bbfdm_ctx *bbfdm_ctx, const char *package);
/**
* @brief Iterates over sections of a specific type in a UCI package.
*
* Traverses through all sections of the specified type within a package.
*
* @param[in] bbfdm_ctx Pointer to the BBFDM context structure.
* @param[in] package Name of the UCI package.
* @param[in] type Type of the sections to iterate.
* @param[in] prev_section Pointer to the previous section, or NULL to start from the first section.
* @return Pointer to the next section, or NULL if no more sections are found.
*/
struct uci_section *bbfdm_uci_walk_section(struct bbfdm_ctx *bbfdm_ctx, const char *package, const char *type, struct uci_section *prev_section);
/**
* @brief Retrieves a value from the UCI configuration system.
*
* This macro simplifies the process of initializing a context, retrieving a UCI
* configuration value, and cleaning up the context.
*
* @param package The name of the UCI package.
* @param section The section name within the package.
* @param option The option name within the section.
* @param default_value Default value to use if the option is not found.
* @param buffer Buffer to store the retrieved value.
* @param buffer_size Size of the buffer.
* @return Always returns 0.
*/
#define BBFDM_UCI_GET(package, section, option, default_value, buffer, buffer_size) \
do { \
struct bbfdm_ctx ctx = {0}; \
memset(&ctx, 0, sizeof(struct bbfdm_ctx)); \
bbfdm_init_ctx(&ctx); \
bbfdm_uci_get_buf(&ctx, package, section, option, default_value, buffer, buffer_size); \
bbfdm_free_ctx(&ctx); \
} while (0)
/**
* @brief Sets a value in the UCI configuration system.
*
* This macro simplifies the process of initializing a context, setting a UCI
* configuration value, committing the changes, and cleaning up the context.
*
* @param package The name of the UCI package.
* @param section The section name within the package.
* @param option The option name within the section.
* @param value The value to set for the specified option.
* @return Always returns 0.
*/
#define BBFDM_UCI_SET(package, section, option, value) \
do { \
struct bbfdm_ctx ctx = {0}; \
memset(&ctx, 0, sizeof(struct bbfdm_ctx)); \
bbfdm_init_ctx(&ctx); \
bbfdm_uci_set(&ctx, package, section, option, value); \
bbfdm_uci_commit_package(&ctx, package); \
bbfdm_free_ctx(&ctx); \
} while (0)
/**
* @brief Iterates over all sections of a specific type in a UCI package.
*
* This macro provides a convenient way to traverse all sections of a given type
* within a specified UCI package. It uses the `bbfdm_uci_walk_section` function
* to retrieve each section one by one.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param package Name of the UCI package to iterate over.
* @param type Type of the sections to filter during iteration.
* @param section Variable to hold the current section being processed during the loop.
*
* @note This macro modifies the value of the `section` variable during iteration.
* Ensure `section` is properly declared before using the macro.
*
* Example usage:
* @code
* const char *section;
* BBFDM_UCI_FOREACH_SECTION(&ctx, "network", "interface", section) {
* printf("Processing section: %s\n", section);
* }
* @endcode
*/
#define BBFDM_UCI_FOREACH_SECTION(bbfdm_ctx, package, type, section) \
for (section = bbfdm_uci_walk_section(bbfdm_ctx, package, type, NULL); \
section != NULL; \
section = bbfdm_uci_walk_section(bbfdm_ctx, package, type, section))
/**
* @brief Safely iterates over all sections of a specific type in a UCI package.
*
* This macro provides a safe way to traverse all sections of a given type within
* a specified UCI package. It ensures that the loop remains valid even if the
* current section is modified or deleted during the iteration.
*
* @param bbfdm_ctx Pointer to the bbfdm context.
* @param package Name of the UCI package to iterate over.
* @param type Type of the sections to filter during iteration.
* @param _tmp Temporary variable to store the next section during iteration. Must be declared beforehand.
* @param section Variable to hold the current section being processed during the loop.
*
* @note Both `_tmp` and `section` variables are modified during iteration.
* Ensure they are properly declared before using the macro.
*
* Example usage:
* @code
* const char *section, *next_section;
* BBFDM_UCI_FOREACH_SECTION_SAFE(&ctx, "network", "interface", next_section, section) {
* printf("Processing section: %s\n", section);
* }
* @endcode
*/
#define BBFDM_UCI_FOREACH_SECTION_SAFE(bbfdm_ctx, package, type, _tmp, section) \
for(section = bbfdm_uci_walk_section(bbfdm_ctx, package, type, NULL), \
_tmp = (section) ? bbfdm_uci_walk_section(bbfdm_ctx, package, type, section) : NULL; \
section != NULL; \
section = _tmp, _tmp = (section) ? bbfdm_uci_walk_section(bbfdm_ctx, package, type, section) : NULL)
#ifdef __cplusplus
}
#endif
#endif //__BBFDM_UCI_H

View file

@ -5,7 +5,7 @@ PROJECT(libbbfdm-ubus)
ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE) ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}") ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/legacy -I${CMAKE_SOURCE_DIR}/libbbfdm-api/version-2")
IF(${BBFDMD_MAX_MSG_LEN}) IF(${BBFDMD_MAX_MSG_LEN})
ADD_DEFINITIONS(-DBBFDM_MAX_MSG_LEN=${BBFDMD_MAX_MSG_LEN}) ADD_DEFINITIONS(-DBBFDM_MAX_MSG_LEN=${BBFDMD_MAX_MSG_LEN})

View file

@ -5,7 +5,7 @@
#include <libubox/blobmsg.h> #include <libubox/blobmsg.h>
#include <libubox/list.h> #include <libubox/list.h>
#include <libbbfdm-api/dmbbf.h> #include "libbbfdm-api/legacy/dmbbf.h"
#define BBFDM_DEFAULT_UBUS_OBJ "bbfdm" #define BBFDM_DEFAULT_UBUS_OBJ "bbfdm"

View file

@ -14,7 +14,7 @@
#include <libubox/utils.h> #include <libubox/utils.h>
#include <libubox/list.h> #include <libubox/list.h>
#include <libbbfdm-api/dmcommon.h> #include <libbbfdm-api/legacy/dmcommon.h>
#include "bbfdm-ubus.h" #include "bbfdm-ubus.h"
#define STRINGIFY(x) #x #define STRINGIFY(x) #x

View file

@ -15,7 +15,7 @@
#include "common.h" #include "common.h"
#include "get_helper.h" #include "get_helper.h"
#include "../libbbfdm-api/plugin/json_plugin.h" #include "libbbfdm-api/legacy/plugin/json_plugin.h"
extern struct list_head loaded_json_files; extern struct list_head loaded_json_files;

View file

@ -4,7 +4,7 @@ PROJECT(libbbfdm)
ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE -DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}") ADD_DEFINITIONS(-Wall -Werror -g -D_GNU_SOURCE -DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/version-2")
FILE(GLOB BBF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c) FILE(GLOB BBF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
ADD_LIBRARY(bbfdm STATIC ${BBF_SOURCES}) ADD_LIBRARY(bbfdm STATIC ${BBF_SOURCES})

View file

@ -13,7 +13,7 @@
#ifndef __DEVICE_H #ifndef __DEVICE_H
#define __DEVICE_H #define __DEVICE_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DM_MAP_OBJ tDynamicObj[]; extern DM_MAP_OBJ tDynamicObj[];

View file

@ -12,7 +12,7 @@
#ifndef __GATEWAYINFO_H #ifndef __GATEWAYINFO_H
#define __GATEWAYINFO_H #define __GATEWAYINFO_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMLEAF tGatewayInfoParams[]; extern DMLEAF tGatewayInfoParams[];

View file

@ -11,7 +11,7 @@
#ifndef __LANCONFIGSECURITY_H #ifndef __LANCONFIGSECURITY_H
#define __LANCONFIGSECURITY_H #define __LANCONFIGSECURITY_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMLEAF tLANConfigSecurityParams[]; extern DMLEAF tLANConfigSecurityParams[];

View file

@ -11,7 +11,7 @@
#ifndef __SCHEDULES_H #ifndef __SCHEDULES_H
#define __SCHEDULES_H #define __SCHEDULES_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMOBJ tSchedulesObj[]; extern DMOBJ tSchedulesObj[];
extern DMLEAF tSchedulesParams[]; extern DMLEAF tSchedulesParams[];

View file

@ -11,7 +11,7 @@
#ifndef __SECURITY_H #ifndef __SECURITY_H
#define __SECURITY_H #define __SECURITY_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMOBJ tSecurityObj[]; extern DMOBJ tSecurityObj[];
extern DMLEAF tSecurityParams[]; extern DMLEAF tSecurityParams[];

View file

@ -10,16 +10,16 @@ static struct dmctx bbf_ctx = {0};
static int setup_teardown(void **state) static int setup_teardown(void **state)
{ {
bbfdm_init_mem(&bbf_ctx); dm_init_mem(&bbf_ctx);
bbfdm_uci_init(&bbf_ctx); dm_uci_init(&bbf_ctx);
bbf_ctx.dm_type = BBFDM_USP; bbf_ctx.dm_type = BBFDM_USP;
return 0; return 0;
} }
static int group_teardown(void **state) static int group_teardown(void **state)
{ {
bbfdm_uci_exit(&bbf_ctx); dm_uci_exit(&bbf_ctx);
bbfdm_clean_mem(&bbf_ctx); dm_clean_mem(&bbf_ctx);
dmubus_free(); dmubus_free();
return 0; return 0;
} }

View file

@ -3,11 +3,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <libubox/blobmsg.h> #include <libubox/blobmsg.h>
#include "../../libbbfdm-api/dmapi.h" #include <libbbfdm-api/dmapi.h>
#include "../../libbbfdm-ubus/bbfdm-ubus.h" #include <libbbfdm-ubus/bbfdm-ubus.h>
#include "../../libbbfdm-api/dmentry.h" #include <libbbfdm-api/dmentry.h>
#include "../../libbbfdm-ubus/plugin.h"
#include "../../libbbfdm-ubus/plugin.h"
#include "../../libbbfdm/device.h" #include "../../libbbfdm/device.h"
static int cli_exec_schema(struct dmctx *bbfdm_ctx, char *in_path) static int cli_exec_schema(struct dmctx *bbfdm_ctx, char *in_path)

View file

@ -12,7 +12,7 @@
#ifndef __TEST_DEVICE_H #ifndef __TEST_DEVICE_H
#define __TEST_DEVICE_H #define __TEST_DEVICE_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMOBJ tTEST_DeviceObj[]; extern DMOBJ tTEST_DeviceObj[];

View file

@ -1,7 +1,7 @@
#ifndef __TEST_DEVICEINFO_H #ifndef __TEST_DEVICEINFO_H
#define __TEST_DEVICEINFO_H #define __TEST_DEVICEINFO_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMOBJ tTEST_DeviceInfoObj[]; extern DMOBJ tTEST_DeviceInfoObj[];
extern DMLEAF tTEST_DeviceInfoParams[]; extern DMLEAF tTEST_DeviceInfoParams[];

View file

@ -12,7 +12,7 @@
#ifndef __TEST_VENDOR_H #ifndef __TEST_VENDOR_H
#define __TEST_VENDOR_H #define __TEST_VENDOR_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DM_MAP_OBJ tVendorExtensionOverwriteTEST[]; extern DM_MAP_OBJ tVendorExtensionOverwriteTEST[];
extern DM_MAP_OBJ tVendorExtensionTEST[]; extern DM_MAP_OBJ tVendorExtensionTEST[];

View file

@ -12,7 +12,7 @@
#ifndef __TEST_FIREWALL_H #ifndef __TEST_FIREWALL_H
#define __TEST_FIREWALL_H #define __TEST_FIREWALL_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMOBJ tTEST_FirewallChainRuleObj[]; extern DMOBJ tTEST_FirewallChainRuleObj[];
extern DMLEAF tTEST_FirewallChainRuleParams[]; extern DMLEAF tTEST_FirewallChainRuleParams[];

View file

@ -12,7 +12,7 @@
#ifndef __TEST_DROPBEAR_H #ifndef __TEST_DROPBEAR_H
#define __TEST_DROPBEAR_H #define __TEST_DROPBEAR_H
#include "libbbfdm-api/dmcommon.h" #include "libbbfdm-api/legacy/dmcommon.h"
extern DMLEAF X_TEST_COM_DropbearParams[]; extern DMLEAF X_TEST_COM_DropbearParams[];

View file

@ -361,7 +361,7 @@ def hprinttopfile(fp, filename):
print("#ifndef __%s_H" % filename.upper(), file=fp) print("#ifndef __%s_H" % filename.upper(), file=fp)
print("#define __%s_H" % filename.upper(), file=fp) print("#define __%s_H" % filename.upper(), file=fp)
print("", file=fp) print("", file=fp)
print("#include <libbbfdm-api/dmcommon.h>", file=fp) print("#include <libbbfdm-api/legacy/dmcommon.h>", file=fp)
print("", file=fp) print("", file=fp)

View file

@ -450,7 +450,7 @@
"libdm/tr104/*.c" "libdm/tr104/*.c"
], ],
"extra_dependencies": [ "extra_dependencies": [
"-I /builds/bbf/bbfdm/libbbfdm-api", "-I /builds/bbf/bbfdm/libbbfdm-api/legacy",
"-I libdm/common" "-I libdm/common"
] ]
}, },
@ -489,7 +489,7 @@
"libdm/extensions/iowrt/*.c" "libdm/extensions/iowrt/*.c"
], ],
"extra_dependencies": [ "extra_dependencies": [
"-I /builds/bbf/bbfdm/libbbfdm-api", "-I /builds/bbf/bbfdm/libbbfdm-api/legacy",
"-I libdm/common" "-I libdm/common"
] ]
} }