dmctx aware bbfdm api

This commit is contained in:
Suvendhu Hansa 2025-09-05 18:49:59 +05:30 committed by IOPSYS Dev
parent 2f3a0805b0
commit 19db3c2d17
No known key found for this signature in database
13 changed files with 571 additions and 442 deletions

View file

@ -212,6 +212,7 @@ struct dmctx {
struct uci_context *varstate_uci_ctx; struct uci_context *varstate_uci_ctx;
struct ubus_context *ubus_ctx; struct ubus_context *ubus_ctx;
struct list_head *memhead; struct list_head *memhead;
struct list_head *modified_uci_head;
const char *obj_buf[16]; const char *obj_buf[16];
const char *inst_buf[16]; const char *inst_buf[16];

View file

@ -15,6 +15,8 @@
#include "dmcommon.h" #include "dmcommon.h"
static struct dmctx *g_dm_ctx = NULL;
char *DiagnosticsState[] = {"None", "Requested", "Canceled", "Complete", "Error", NULL}; char *DiagnosticsState[] = {"None", "Requested", "Canceled", "Complete", "Error", NULL};
char *IPv4Address[] = {"^$", "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$", NULL}; char *IPv4Address[] = {"^$", "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$", NULL};
@ -2214,3 +2216,90 @@ int get_proto_type(const char *proto)
return type; return type;
} }
void dm_init_modified_uci(struct dmctx *ctx)
{
if (ctx == NULL) {
BBFDM_DEBUG("dmctx is NULL!!!");
return;
}
ctx->modified_uci_head = calloc(1, sizeof(struct list_head));
// Check if memory allocation was successful
if (ctx->modified_uci_head == NULL) {
BBFDM_INFO("failed to allocate memory!!!");
return;
}
// Initialize the list head
INIT_LIST_HEAD(ctx->modified_uci_head);
}
void dm_clean_modified_uci(struct dmctx *ctx)
{
if (ctx == NULL || ctx->modified_uci_head == NULL) {
return;
}
struct dm_modified_uci *dmm = NULL, *tmp = NULL;
list_for_each_entry_safe(dmm, tmp, ctx->modified_uci_head, list) {
list_del(&dmm->list);
FREE(dmm);
}
FREE(ctx->modified_uci_head);
}
void add_list_modified_uci(struct dmctx *ctx, const char *dir, const char *file)
{
if (ctx == NULL) {
BBFDM_DEBUG("dmctx is NULL!");
return;
}
struct list_head *head = ctx->modified_uci_head;
if (head == NULL) {
BBFDM_INFO("head is NULL!");
return;
}
if (DM_STRLEN(dir) == 0 || DM_STRLEN(file) == 0) {
BBFDM_DEBUG("dir name or file name is empty!");
return;
}
char uci_file[128] = {0};
snprintf(uci_file, sizeof(uci_file), "%s%s", dir, file);
struct dm_modified_uci *m;
list_for_each_entry(m, head, list) {
if (DM_STRCMP(m->uci_file, uci_file) == 0) {
// config file already added in list
return;
}
}
m = malloc(sizeof(struct dm_modified_uci));
if (m == NULL) {
BBFDM_INFO("memory allocation failed");
return;
}
snprintf(m->uci_file, sizeof(m->uci_file), "%s", uci_file);
list_add(&m->list, head);
}
/* !! TO BE REMOVED LATER START */
struct dmctx *get_bbfdm_global_dmctx(void)
{
return g_dm_ctx;
}
void set_bbfdm_global_dmctx(struct dmctx *ctx)
{
g_dm_ctx = ctx;
}
/* !! TO BE REMOVED LATER END */

View file

@ -129,6 +129,11 @@ struct dhcp_options_type {
uint8_t len; uint8_t len;
}; };
struct dm_modified_uci {
struct list_head list;
char uci_file[128];
};
pid_t get_pid(const char *pname); pid_t get_pid(const char *pname);
int compare_strings(const void *a, const void *b); int compare_strings(const void *a, const void *b);
char *get_uptime(void); char *get_uptime(void);
@ -242,4 +247,10 @@ long download_file(char *file_path, const char *url, const char *username, const
long upload_file(const char *file_path, const char *url, const char *username, const char *password); long upload_file(const char *file_path, const char *url, const char *username, const char *password);
int get_proto_type(const char *proto); int get_proto_type(const char *proto);
void dm_init_modified_uci(struct dmctx *ctx);
void dm_clean_modified_uci(struct dmctx *ctx);
void add_list_modified_uci(struct dmctx *ctx, const char *dir, const char *file);
struct dmctx *get_bbfdm_global_dmctx(); // !! TO BE REMOVED LATER
void set_bbfdm_global_dmctx(struct dmctx *ctx); // !! TO BE REMOVED LATER
#endif #endif

View file

@ -50,6 +50,7 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
dm_init_mem(ctx); dm_init_mem(ctx);
dm_uci_init(ctx); dm_uci_init(ctx);
dm_ubus_init(ctx); dm_ubus_init(ctx);
dm_init_modified_uci(ctx);
} }
void bbf_ctx_clean(struct dmctx *ctx) void bbf_ctx_clean(struct dmctx *ctx)
@ -59,6 +60,7 @@ void bbf_ctx_clean(struct dmctx *ctx)
dm_uci_exit(ctx); dm_uci_exit(ctx);
dm_clean_mem(ctx); dm_clean_mem(ctx);
dm_ubus_free(ctx); dm_ubus_free(ctx);
dm_clean_modified_uci(ctx);
} }
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj) void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj)
@ -201,6 +203,8 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
return bbf_fault_map(ctx, FAULT_9005); return bbf_fault_map(ctx, FAULT_9005);
} }
set_bbfdm_global_dmctx(ctx); // !! TO BE REMOVED LATER
switch(cmd) { switch(cmd) {
case BBF_GET_VALUE: case BBF_GET_VALUE:
fault = dm_entry_get_value(ctx); fault = dm_entry_get_value(ctx);
@ -234,6 +238,8 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
break; break;
} }
set_bbfdm_global_dmctx(NULL); // !! TO BE REMOVED LATER
return bbf_fault_map(ctx, fault); return bbf_fault_map(ctx, fault);
} }

View file

@ -431,117 +431,7 @@ int dmuci_revert_package(char *package)
return 0; return 0;
} }
#if 0
/**** UCI SET *****/
int dmuci_set_value(const char *package, const char *section, const char *option, const char *value)
{
struct uci_ptr ptr = {0};
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, value))
return -1;
if (uci_set(uci_ctx, &ptr) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI ADD LIST *****/
int dmuci_add_list_value(const char *package, const char *section, const char *option, const char *value)
{
struct uci_ptr ptr = {0};
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, value))
return -1;
if (uci_add_list(uci_ctx, &ptr) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI DEL LIST *****/
int dmuci_del_list_value(const char *package, const char *section, const char *option, const char *value)
{
struct uci_ptr ptr = {0};
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, value))
return -1;
if (uci_del_list(uci_ctx, &ptr) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/****** UCI ADD *******/
int dmuci_add_section(const char *package, const char *stype, struct uci_section **s)
{
struct uci_ptr ptr = {0};
char fname[128];
*s = NULL;
snprintf(fname, sizeof(fname), "%s/%s", uci_ctx->confdir, package);
if (create_empty_file(fname))
return -1;
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL))
return -1;
if (uci_add_section(uci_ctx, ptr.p, stype, s) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI DELETE *****/
int dmuci_delete(const char *package, const char *section, const char *option, const char *value)
{
struct uci_ptr ptr = {0};
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, section, option, NULL))
return -1;
if (uci_delete(uci_ctx, &ptr) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI RENAME SECTION *****/
int dmuci_rename_section(const char *package, const char *section, const char *value)
{
struct uci_ptr ptr = {0};
if (dmuci_lookup_ptr(uci_ctx, &ptr, package, section, NULL, value))
return -1;
if (uci_rename(uci_ctx, &ptr) != UCI_OK)
return -1;
if (uci_save(uci_ctx, ptr.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI LOOKUP by section pointer ****/ /**** UCI LOOKUP by section pointer ****/
static int dmuci_lookup_ptr_by_section(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *s, const char *option, const char *value) static int dmuci_lookup_ptr_by_section(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *s, const char *option, const char *value)
{ {
@ -573,6 +463,7 @@ lookup:
return 0; return 0;
} }
#endif
/**** UCI GET by section pointer*****/ /**** UCI GET by section pointer*****/
int dmuci_get_value_by_section_string(struct uci_section *s, const char *option, char **value) int dmuci_get_value_by_section_string(struct uci_section *s, const char *option, char **value)
@ -653,133 +544,6 @@ int dmuci_get_value_by_section_list(struct uci_section *s, const char *option, s
return -1; return -1;
} }
/**** UCI SET by section pointer ****/
int dmuci_set_value_by_section(struct uci_section *s, const char *option, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, option, value) == -1)
return -1;
if (uci_set(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI DELETE by section pointer *****/
int dmuci_delete_by_section(struct uci_section *s, const char *option, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
curr_ctx->flags |= UCI_FLAG_EXPORT_NAME;
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, option, value) == -1)
return -1;
if (uci_delete(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
int dmuci_delete_by_section_unnamed(struct uci_section *s, const char *option, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, option, value) == -1)
return -1;
if (uci_delete(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI ADD LIST by section pointer *****/
int dmuci_add_list_value_by_section(struct uci_section *s, const char *option, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, option, value) == -1)
return -1;
if (uci_add_list(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI DEL LIST by section pointer *****/
int dmuci_del_list_value_by_section(struct uci_section *s, const char *option, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, option, value) == -1)
return -1;
if (uci_del_list(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI RENAME SECTION by section pointer *****/
int dmuci_rename_section_by_section(struct uci_section *s, const char *value)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, NULL, value) == -1)
return -1;
if (uci_rename(curr_ctx, &up) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI REORDER SECTION by section pointer *****/
int dmuci_reoder_section_by_section(struct uci_section *s, char *pos)
{
struct uci_context *curr_ctx = get_uci_context_by_section(s);
struct uci_ptr up = {0};
if (dmuci_lookup_ptr_by_section(curr_ctx, &up, s, NULL, pos) == -1)
return -1;
if (uci_reorder_section(curr_ctx, up.s, strtoul(up.value, NULL, 10)) != UCI_OK)
return -1;
if (uci_save(curr_ctx, up.p) != UCI_OK)
return -1;
return 0;
}
/**** UCI WALK SECTIONS *****/ /**** UCI WALK SECTIONS *****/
struct uci_section *dmuci_walk_section (const char *package, const char *stype, const void *arg1, const void *arg2, int cmp , int (*filter)(struct uci_section *s, const void *value), struct uci_section *prev_section, int walk) struct uci_section *dmuci_walk_section (const char *package, const char *stype, const void *arg1, const void *arg2, int cmp , int (*filter)(struct uci_section *s, const void *value), struct uci_section *prev_section, int walk)
{ {
@ -956,3 +720,276 @@ int dmuci_set_section_name(const char *sec_name, char *str, size_t size)
return 0; return 0;
} }
enum uci_oper_type {
UCI_OP_SET,
UCI_OP_ADD_LIST,
UCI_OP_DEL_LIST,
UCI_OP_ADD,
UCI_OP_DEL,
UCI_OP_RENAME,
UCI_OP_REORDER,
__UCI_OP_MAX
};
typedef struct uci_op_data {
//Input
const char *package;
const char *section;
const char *option;
const char *value;
const char *sec_type;
struct uci_context *ucictx;
struct dmctx *dmctx;
//Output
struct uci_section **s;
} bbfdm_uci_op_data;
static int __uci_perform_op(int operation, bbfdm_uci_op_data *op_data)
{
struct uci_ptr ptr = {0};
if (op_data == NULL)
return -1;
if (dmuci_lookup_ptr(op_data->ucictx, &ptr, op_data->package, op_data->section, op_data->option, op_data->value))
return -1;
switch (operation) {
case UCI_OP_SET:
if (uci_set(op_data->ucictx, &ptr) != UCI_OK)
return -1;
break;
case UCI_OP_ADD_LIST:
if (uci_add_list(op_data->ucictx, &ptr) != UCI_OK)
return -1;
break;
case UCI_OP_DEL_LIST:
if (uci_del_list(op_data->ucictx, &ptr) != UCI_OK)
return -1;
break;
case UCI_OP_ADD:
if (uci_add_section(op_data->ucictx, ptr.p, op_data->sec_type, op_data->s) != UCI_OK)
return -1;
break;
case UCI_OP_DEL:
if (uci_delete(op_data->ucictx, &ptr) != UCI_OK)
return -1;
break;
case UCI_OP_RENAME:
if (uci_rename(op_data->ucictx, &ptr) != UCI_OK)
return -1;
break;
case UCI_OP_REORDER:
if (uci_reorder_section(op_data->ucictx, ptr.s, strtoul(ptr.value, NULL, 10)) != UCI_OK)
return -1;
break;
default:
return -1;
}
if (uci_save(op_data->ucictx, ptr.p) != UCI_OK)
return -1;
add_list_modified_uci(op_data->dmctx, op_data->ucictx->confdir, op_data->package);
return 0;
}
/**** UCI SET by section pointer ****/
int dmuci_set_value_by_section(struct uci_section *s, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_SET, &conf_data);
}
int dmuci_set_value(const char *package, const char *section, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.section = section;
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_SET, &conf_data);
}
/**** UCI ADD section *****/
int dmuci_add_section(const char *package, const char *stype, struct uci_section **s)
{
char fname[128];
bbfdm_uci_op_data conf_data = {0};
if (s == NULL)
return -1;
snprintf(fname, sizeof(fname), "%s/%s", uci_ctx->confdir, package);
if (create_empty_file(fname))
return -1;
*s = NULL;
conf_data.s = s;
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.sec_type = stype;
return __uci_perform_op(UCI_OP_ADD, &conf_data);
}
/**** UCI DELETE by section pointer *****/
int dmuci_delete_by_section(struct uci_section *s, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.option = option;
conf_data.value = value;
conf_data.ucictx->flags |= UCI_FLAG_EXPORT_NAME;
return __uci_perform_op(UCI_OP_DEL, &conf_data);
}
int dmuci_delete(const char *package, const char *section, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.section = section;
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_DEL, &conf_data);
}
int dmuci_delete_by_section_unnamed(struct uci_section *s, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_DEL, &conf_data);
}
/**** UCI ADD LIST by section pointer *****/
int dmuci_add_list_value_by_section(struct uci_section *s, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_ADD_LIST, &conf_data);
}
int dmuci_add_list_value(const char *package, const char *section, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.section = section;
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_ADD_LIST, &conf_data);
}
/**** UCI DEL LIST by section pointer *****/
int dmuci_del_list_value_by_section(struct uci_section *s, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_DEL_LIST, &conf_data);
}
int dmuci_del_list_value(const char *package, const char *section, const char *option, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.section = section;
conf_data.option = option;
conf_data.value = value;
return __uci_perform_op(UCI_OP_DEL_LIST, &conf_data);
}
/**** UCI RENAME SECTION by section pointer *****/
int dmuci_rename_section_by_section(struct uci_section *s, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.value = value;
return __uci_perform_op(UCI_OP_RENAME, &conf_data);
}
int dmuci_rename_section(const char *package, const char *section, const char *value)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = uci_ctx;
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = package;
conf_data.section = section;
conf_data.value = value;
return __uci_perform_op(UCI_OP_RENAME, &conf_data);
}
/**** UCI REORDER SECTION by section pointer *****/
int dmuci_reoder_section_by_section(struct uci_section *s, char *pos)
{
bbfdm_uci_op_data conf_data = {0};
conf_data.ucictx = get_uci_context_by_section(s);
conf_data.dmctx = get_bbfdm_global_dmctx();
conf_data.package = s ? section_config(s) : "";
conf_data.section = s ? section_name(s) : "";
conf_data.value = pos;
return __uci_perform_op(UCI_OP_REORDER, &conf_data);
}

View file

@ -35,6 +35,17 @@ static int bbfdm_add_object(bbfdm_data_t *data)
blobmsg_close_array(&data->bb, array); blobmsg_close_array(&data->bb, array);
array = blobmsg_open_array(&data->bb, "modified_uci");
if (data->bbf_ctx.modified_uci_head != NULL) {
struct dm_modified_uci *m;
list_for_each_entry(m, data->bbf_ctx.modified_uci_head, list) {
bb_add_string(&data->bb, "", m->uci_file);
}
}
blobmsg_close_array(&data->bb, array);
return fault; return fault;
} }
@ -67,6 +78,17 @@ static int bbfdm_del_object(bbfdm_data_t *data)
blobmsg_close_array(&data->bb, array); blobmsg_close_array(&data->bb, array);
array = blobmsg_open_array(&data->bb, "modified_uci");
if (data->bbf_ctx.modified_uci_head != NULL) {
struct dm_modified_uci *m;
list_for_each_entry(m, data->bbf_ctx.modified_uci_head, list) {
bb_add_string(&data->bb, "", m->uci_file);
}
}
blobmsg_close_array(&data->bb, array);
return fault; return fault;
} }

View file

@ -3,7 +3,6 @@
enum { enum {
DM_ADD_PATH, DM_ADD_PATH,
DM_ADD_OBJ_PATH,
DM_ADD_OPTIONAL, DM_ADD_OPTIONAL,
__DM_ADD_MAX __DM_ADD_MAX
}; };

View file

@ -446,7 +446,6 @@ static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *o
static const struct blobmsg_policy dm_add_policy[] = { static const struct blobmsg_policy dm_add_policy[] = {
[DM_ADD_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, [DM_ADD_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
[DM_ADD_OBJ_PATH] = { .name = "obj_path", .type = BLOBMSG_TYPE_TABLE },
[DM_ADD_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, [DM_ADD_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE },
}; };
@ -487,26 +486,6 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj,
goto end; goto end;
} }
if (tb[DM_ADD_OBJ_PATH]) {
LIST_HEAD(pv_list);
snprintf(path, PATH_MAX, "%s%s.", (char *)blobmsg_data(tb[DM_ADD_PATH]), data.bbf_ctx.addobj_instance);
fault = fill_pvlist_set(path, NULL, NULL, tb[DM_ADD_OBJ_PATH], &pv_list);
if (fault) {
BBF_ERR("Fault in fill pvlist set path |%s|", path);
fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR);
free_pv_list(&pv_list);
goto end;
}
data.plist = &pv_list;
bbfdm_set_value(&data);
free_pv_list(&pv_list);
}
end: end:
if (data.bbf_ctx.dm_type == BBFDM_BOTH) { if (data.bbf_ctx.dm_type == BBFDM_BOTH) {
bbf_entry_services(data.bbf_ctx.dm_type, (!fault) ? true : false, true); bbf_entry_services(data.bbf_ctx.dm_type, (!fault) ? true : false, true);

View file

@ -46,5 +46,27 @@ void bbfdm_operate_cmd(bbfdm_data_t *data, void *output)
ubus_send_reply(data->ctx, data->req, data->bbf_ctx.bb.head); ubus_send_reply(data->ctx, data->req, data->bbf_ctx.bb.head);
} }
/* Commit or Revert changes in uci files */
if (data->bbf_ctx.modified_uci_head != NULL) {
struct dm_modified_uci *m;
struct blob_buf bb = {0};
blob_buf_init(&bb, 0);
void *array = blobmsg_open_array(&bb, "services");
list_for_each_entry(m, data->bbf_ctx.modified_uci_head, list) {
blobmsg_add_string(&bb, NULL, m->uci_file);
}
blobmsg_close_array(&bb, array);
blobmsg_add_string(&bb, "proto", (data->bbf_ctx.dm_type == BBFDM_USP) ? "usp" : "both");
blobmsg_add_u8(&bb, "reload", (fault == 0) ? true : false);
dmubus_call_blob_msg_timeout("bbf.config", (fault == 0) ? "commit" : "revert", &bb, 10000);
blob_buf_free(&bb);
}
bbf_cleanup(&data->bbf_ctx); bbf_cleanup(&data->bbf_ctx);
} }

View file

@ -39,6 +39,17 @@ int bbfdm_set_value(bbfdm_data_t *data)
blobmsg_close_array(&data->bb, array); blobmsg_close_array(&data->bb, array);
array = blobmsg_open_array(&data->bb, "modified_uci");
if (data->bbf_ctx.modified_uci_head != NULL) {
struct dm_modified_uci *m;
list_for_each_entry(m, data->bbf_ctx.modified_uci_head, list) {
bb_add_string(&data->bb, "", m->uci_file);
}
}
blobmsg_close_array(&data->bb, array);
return fault; return fault;
} }

View file

@ -25,17 +25,8 @@
#define DEFAULT_LOG_LEVEL LOG_INFO #define DEFAULT_LOG_LEVEL LOG_INFO
#define BBF_CONFIG_DAEMON_NAME "bbf_configd" #define BBF_CONFIG_DAEMON_NAME "bbf_configd"
#define CONFIG_CONFDIR "/etc/config/"
#define DMMAP_CONFDIR "/etc/bbfdm/dmmap/"
#define CRITICAL_DEF_JSON "/etc/bbfdm/critical_services.json" #define CRITICAL_DEF_JSON "/etc/bbfdm/critical_services.json"
struct proto_args {
const char *name;
const char *config_savedir;
const char *dmmap_savedir;
unsigned char index;
};
// Structure to represent an instance of a service // Structure to represent an instance of a service
struct instance { struct instance {
char name[NAME_LENGTH]; char name[NAME_LENGTH];
@ -119,18 +110,6 @@ static void show_package_tree(struct config_package *packages)
} }
#endif #endif
static struct proto_args supported_protocols[] = {
{
"both", "/tmp/bbfdm/.bbfdm/config/", "/tmp/bbfdm/.bbfdm/dmmap/", 0
},
{
"cwmp", "/tmp/bbfdm/.cwmp/config/", "/tmp/bbfdm/.cwmp/dmmap/", 1
},
{
"usp", "/tmp/bbfdm/.usp/config/", "/tmp/bbfdm/.usp/dmmap/", 2
},
};
static bool g_internal_commit = false; static bool g_internal_commit = false;
enum { enum {
@ -146,16 +125,6 @@ static const struct blobmsg_policy bbf_config_policy[] = {
[SERVICES_RELOAD] = { .name = "reload", .type = BLOBMSG_TYPE_BOOL }, [SERVICES_RELOAD] = { .name = "reload", .type = BLOBMSG_TYPE_BOOL },
}; };
static unsigned char get_idx_by_proto(const char *proto)
{
for (int i = 0; i < ARRAY_SIZE(supported_protocols); i++) {
if (strcmp(supported_protocols[i].name, proto) == 0)
return supported_protocols[i].index;
}
return 0;
}
static int find_config_idx(struct config_package *package, const char *config_name) static int find_config_idx(struct config_package *package, const char *config_name)
{ {
if (!config_name) if (!config_name)
@ -419,9 +388,13 @@ static bool validate_required_services(struct ubus_context *ctx, struct config_p
// Iterate through each service attribute // Iterate through each service attribute
blobmsg_for_each_attr(service, services, rem) { blobmsg_for_each_attr(service, services, rem) {
char *config_name = blobmsg_get_string(service); char *config_name = blobmsg_get_string(service);
char *p = strrchr(config_name, '/');
if (p) {
p = p + 1;
}
// Find the index of the configuration package // Find the index of the configuration package
int idx = find_config_idx(package, config_name); int idx = find_config_idx(package, p ? p : config_name);
if (idx < 0) if (idx < 0)
continue; continue;
@ -567,7 +540,7 @@ struct blob_attr *get_blob_attr_with_idx(int idx, struct blob_attr *msg)
struct blob_attr *params = NULL; struct blob_attr *params = NULL;
struct blob_attr *cur; struct blob_attr *cur;
int rem; int rem;
const char *proto = supported_protocols[idx].name; const char *proto = get_proto_name_by_idx(idx);
blobmsg_for_each_attr(cur, msg, rem) { blobmsg_for_each_attr(cur, msg, rem) {
const char *name = blobmsg_name(cur); const char *name = blobmsg_name(cur);
@ -588,7 +561,7 @@ static bool check_if_critical_service(int proto_idx, const char *sname)
services_ba = get_blob_attr_with_idx(proto_idx, g_critical_bb.head); services_ba = get_blob_attr_with_idx(proto_idx, g_critical_bb.head);
if (services_ba == NULL) { if (services_ba == NULL) {
ULOG_DEBUG("Critical service not defined for %s proto", supported_protocols[proto_idx].name); ULOG_DEBUG("Critical service not defined for %s proto", get_proto_name_by_idx(proto_idx));
return is_critical; return is_critical;
} }
@ -600,7 +573,7 @@ static bool check_if_critical_service(int proto_idx, const char *sname)
break; break;
} }
} }
ULOG_DEBUG("Service %s, found %d, in %s critical list", sname, is_critical, supported_protocols[proto_idx].name); ULOG_DEBUG("Service %s, found %d, in %s critical list", sname, is_critical, get_proto_name_by_idx(proto_idx));
return is_critical; return is_critical;
} }
@ -676,11 +649,6 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
#endif #endif
} }
if (reload) {
ULOG_INFO("Applying changes to dmmap UCI config");
uci_apply_changes(DMMAP_CONFDIR, supported_protocols[idx].dmmap_savedir, true);
}
struct blob_attr *services = tb[SERVICES_NAME]; struct blob_attr *services = tb[SERVICES_NAME];
size_t arr_len = (services) ? blobmsg_len(services) : 0; size_t arr_len = (services) ? blobmsg_len(services) : 0;
@ -701,10 +669,12 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
} }
ULOG_INFO("Committing changes for specified services and reloading"); ULOG_INFO("Committing changes for specified services and reloading");
reload_specified_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, async_req->services, true, reload, &wifi_config_flags); reload_specified_services(ctx, idx, async_req->services, true, reload, &wifi_config_flags);
} else { } else {
ULOG_INFO("Applying changes to dmmap UCI config");
uci_apply_changes(DMMAP_CONFDIR, idx, true); // commit dmmap changes
ULOG_INFO("Committing changes for all services and reloading"); ULOG_INFO("Committing changes for all services and reloading");
reload_all_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, true, reload, &wifi_config_flags); reload_all_services(ctx, idx, true, reload, &wifi_config_flags);
} }
if (wifi_config_flags) { if (wifi_config_flags) {
@ -763,15 +733,14 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec
if (arr_len) { if (arr_len) {
ULOG_INFO("Reverting specified services"); ULOG_INFO("Reverting specified services");
reload_specified_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, services, false, false, NULL); reload_specified_services(ctx, idx, services, false, false, NULL);
} else { } else {
ULOG_INFO("Applying changes to dmmap UCI config");
uci_apply_changes(DMMAP_CONFDIR, idx, false); // revert dmmap changes
ULOG_INFO("Reverting all services"); ULOG_INFO("Reverting all services");
reload_all_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, false, false, NULL); reload_all_services(ctx, idx, false, false, NULL);
} }
ULOG_INFO("Applying changes to revert all UCI dmmap configurations");
uci_apply_changes(DMMAP_CONFDIR, supported_protocols[idx].dmmap_savedir, false);
ULOG_INFO("Sending success response"); ULOG_INFO("Sending success response");
send_reply(ctx, req, "status", "ok"); send_reply(ctx, req, "status", "ok");
@ -783,52 +752,6 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec
return 0; return 0;
} }
static int update_critical_services(int proto_idx, struct blob_buf *bb)
{
struct blob_attr *services_ba = NULL;
services_ba = get_blob_attr_with_idx(proto_idx, g_critical_bb.head);
if (services_ba != NULL) {
blobmsg_add_field(bb, blobmsg_type(services_ba), "critical_services", blobmsg_data(services_ba), blobmsg_data_len(services_ba));
}
return 0;
}
static int bbf_config_changes_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)),
struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg)
{
struct blob_attr *tb[__MAX];
struct blob_buf bb = {0};
unsigned char idx = 0;
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&bb, 0);
if (blobmsg_parse(bbf_config_policy, __MAX, tb, blob_data(msg), blob_len(msg))) {
blobmsg_add_string(&bb, "error", "Failed to parse blob");
goto end;
}
if (tb[SERVICES_PROTO]) {
char *proto = blobmsg_get_string(tb[SERVICES_PROTO]);
idx = get_idx_by_proto(proto);
}
void *array = blobmsg_open_array(&bb, "configs");
uci_config_changes(CONFIG_CONFDIR, supported_protocols[idx].config_savedir, &bb);
blobmsg_close_array(&bb, array);
update_critical_services(idx, &bb);
end:
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
static void receive_notify_event(struct ubus_context *ctx, struct ubus_event_handler *ev, static void receive_notify_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg) const char *type, struct blob_attr *msg)
{ {
@ -845,7 +768,6 @@ static void receive_notify_event(struct ubus_context *ctx, struct ubus_event_han
static const struct ubus_method bbf_config_methods[] = { static const struct ubus_method bbf_config_methods[] = {
UBUS_METHOD("commit", bbf_config_commit_handler, bbf_config_policy), UBUS_METHOD("commit", bbf_config_commit_handler, bbf_config_policy),
UBUS_METHOD("revert", bbf_config_revert_handler, bbf_config_policy), UBUS_METHOD("revert", bbf_config_revert_handler, bbf_config_policy),
UBUS_METHOD("changes", bbf_config_changes_handler, bbf_config_policy),
}; };
static struct ubus_object_type bbf_config_object_type = UBUS_OBJECT_TYPE("bbf.config", bbf_config_methods); static struct ubus_object_type bbf_config_object_type = UBUS_OBJECT_TYPE("bbf.config", bbf_config_methods);

View file

@ -16,6 +16,62 @@
#define DEFAULT_UBUS_TIMEOUT 5000 #define DEFAULT_UBUS_TIMEOUT 5000
struct proto_args {
const char *name;
const char *config_savedir;
const char *dmmap_savedir;
unsigned char index;
};
static struct proto_args supported_protocols[] = {
{
"both", "/tmp/bbfdm/.bbfdm/config/", "/tmp/bbfdm/.bbfdm/dmmap/", 0
},
{
"cwmp", "/tmp/bbfdm/.cwmp/config/", "/tmp/bbfdm/.cwmp/dmmap/", 1
},
{
"usp", "/tmp/bbfdm/.usp/config/", "/tmp/bbfdm/.usp/dmmap/", 2
},
};
unsigned char get_idx_by_proto(const char *proto)
{
for (int i = 0; i < ARRAY_SIZE(supported_protocols); i++) {
if (strcmp(supported_protocols[i].name, proto) == 0)
return supported_protocols[i].index;
}
return 0;
}
const char *get_proto_conf_savedir_by_idx(int idx)
{
if (idx < ARRAY_SIZE(supported_protocols)) {
return supported_protocols[idx].config_savedir;
}
return "";
}
const char *get_proto_dmmap_savedir_by_idx(int idx)
{
if (idx < ARRAY_SIZE(supported_protocols)) {
return supported_protocols[idx].dmmap_savedir;
}
return "";
}
const char *get_proto_name_by_idx(int idx)
{
if (idx < ARRAY_SIZE(supported_protocols)) {
return supported_protocols[idx].name;
}
return "";
}
void strncpyt(char *dst, const char *src, size_t n) void strncpyt(char *dst, const char *src, size_t n)
{ {
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
@ -105,7 +161,8 @@ static void reload_service(struct ubus_context *ctx, const char *config_name, bo
blob_buf_free(&bb); blob_buf_free(&bb);
} }
void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, struct blob_attr *services,
void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services,
bool is_commit, bool reload, uint32_t *wifi_config_flags) bool is_commit, bool reload, uint32_t *wifi_config_flags)
{ {
struct uci_context *uci_ctx = NULL; struct uci_context *uci_ctx = NULL;
@ -118,25 +175,42 @@ void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, c
return; return;
} }
if (conf_dir) {
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir);
uci_set_confdir(uci_ctx, conf_dir);
}
if (save_dir) {
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
uci_set_savedir(uci_ctx, save_dir);
}
ULOG_DEBUG("Processing services list..."); ULOG_DEBUG("Processing services list...");
blobmsg_for_each_attr(service, services, rem) { blobmsg_for_each_attr(service, services, rem) {
struct uci_ptr ptr = {0}; struct uci_ptr ptr = {0};
char conf_dir[64] = {0};
char save_dir[64] = {0};
char package[64] = {0};
bool is_dmmap = false;
char *config_name = blobmsg_get_string(service); char *config_name = blobmsg_get_string(service);
if (strncmp(CONFIG_CONFDIR, config_name, strlen(CONFIG_CONFDIR)) == 0) {
/* standard uci path received */
snprintf(conf_dir, sizeof(conf_dir), "%s", CONFIG_CONFDIR);
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_conf_savedir_by_idx(idx));
snprintf(package, sizeof(package), "%s", config_name + strlen(CONFIG_CONFDIR));
} else if (strncmp(DMMAP_CONFDIR, config_name, strlen(DMMAP_CONFDIR)) == 0) {
/* dmmap uci path received */
snprintf(conf_dir, sizeof(conf_dir), "%s", DMMAP_CONFDIR);
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_dmmap_savedir_by_idx(idx));
snprintf(package, sizeof(package), "%s", config_name + strlen(DMMAP_CONFDIR));
is_dmmap = true;
} else {
/* no path default to standard uci */
snprintf(conf_dir, sizeof(conf_dir), "%s", CONFIG_CONFDIR);
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_conf_savedir_by_idx(idx));
snprintf(package, sizeof(package), "%s", config_name);
}
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir);
uci_set_confdir(uci_ctx, conf_dir);
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
uci_set_savedir(uci_ctx, save_dir);
ULOG_DEBUG("Looking up UCI configuration for service '%s'", config_name); ULOG_DEBUG("Looking up UCI configuration for service '%s'", config_name);
if (uci_lookup_ptr(uci_ctx, &ptr, config_name, true) != UCI_OK) { if (uci_lookup_ptr(uci_ctx, &ptr, package, true) != UCI_OK) {
ULOG_ERR("Failed to lookup UCI pointer for service '%s'. Skipping", config_name); ULOG_ERR("Failed to lookup UCI pointer for service '%s'. Skipping", config_name);
continue; continue;
} }
@ -155,12 +229,12 @@ void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, c
} }
} }
if (reload) { if (reload && !is_dmmap) {
if (is_wifi_configs(config_name, wifi_config_flags)) if (is_wifi_configs(package, wifi_config_flags))
continue; continue;
ULOG_INFO("Reloading service '%s'", config_name); ULOG_INFO("Reloading service '%s'", package);
reload_service(ctx, config_name, is_commit); reload_service(ctx, package, is_commit);
} }
} }
@ -168,8 +242,8 @@ void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, c
uci_free_context(uci_ctx); uci_free_context(uci_ctx);
} }
void reload_all_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
bool is_commit, bool reload, uint32_t *wifi_config_flags) bool reload, uint32_t *wifi_config_flags)
{ {
struct uci_context *uci_ctx = NULL; struct uci_context *uci_ctx = NULL;
char **configs = NULL, **p = NULL; char **configs = NULL, **p = NULL;
@ -180,15 +254,12 @@ void reload_all_services(struct ubus_context *ctx, const char *conf_dir, const c
return; return;
} }
if (conf_dir) { ULOG_DEBUG("Setting UCI configuration directory to '%s'", CONFIG_CONFDIR);
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir); uci_set_confdir(uci_ctx, CONFIG_CONFDIR);
uci_set_confdir(uci_ctx, conf_dir);
}
if (save_dir) { const char *save_dir = get_proto_conf_savedir_by_idx(idx);
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir); ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
uci_set_savedir(uci_ctx, save_dir); uci_set_savedir(uci_ctx, save_dir);
}
if (uci_list_configs(uci_ctx, &configs) != UCI_OK) { if (uci_list_configs(uci_ctx, &configs) != UCI_OK) {
ULOG_ERR("Failed to list UCI configurations"); ULOG_ERR("Failed to list UCI configurations");
@ -259,10 +330,11 @@ void wifi_reload_handler_script(uint32_t wifi_config_flags)
} }
} }
void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commit) void uci_apply_changes(const char *conf_dir, int idx, bool is_commit)
{ {
struct uci_context *uci_ctx = NULL; struct uci_context *uci_ctx = NULL;
char **configs = NULL, **p = NULL; char **configs = NULL, **p = NULL;
char save_dir[128] = {0};
uci_ctx = uci_alloc_context(); uci_ctx = uci_alloc_context();
if (!uci_ctx) { if (!uci_ctx) {
@ -273,12 +345,16 @@ void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commi
if (conf_dir) { if (conf_dir) {
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir); ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir);
uci_set_confdir(uci_ctx, conf_dir); uci_set_confdir(uci_ctx, conf_dir);
if (strcmp(conf_dir, DMMAP_CONFDIR) == 0) {
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_dmmap_savedir_by_idx(idx));
} else if(strcmp(conf_dir, CONFIG_CONFDIR) == 0) {
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_conf_savedir_by_idx(idx));
}
} }
if (save_dir) { ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir); uci_set_savedir(uci_ctx, save_dir);
uci_set_savedir(uci_ctx, save_dir);
}
if (uci_list_configs(uci_ctx, &configs) != UCI_OK) { if (uci_list_configs(uci_ctx, &configs) != UCI_OK) {
ULOG_ERR("Failed to list UCI configurations"); ULOG_ERR("Failed to list UCI configurations");
@ -316,55 +392,3 @@ void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commi
exit: exit:
uci_free_context(uci_ctx); uci_free_context(uci_ctx);
} }
void uci_config_changes(const char *conf_dir, const char *save_dir, struct blob_buf *bb)
{
struct uci_context *uci_ctx = NULL;
char **configs = NULL, **p = NULL;
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
ULOG_ERR("Failed to allocate UCI context");
return;
}
if (conf_dir) {
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir);
uci_set_confdir(uci_ctx, conf_dir);
}
if (save_dir) {
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
uci_set_savedir(uci_ctx, save_dir);
}
if (uci_list_configs(uci_ctx, &configs) != UCI_OK) {
ULOG_ERR("Failed to list UCI configurations");
goto exit;
}
ULOG_DEBUG("Identifying configurations with unsaved changes...");
for (p = configs; p && *p; p++) {
struct uci_ptr ptr = {0};
ULOG_DEBUG("Looking up UCI configuration for '%s'", *p);
if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) {
ULOG_ERR("Failed to lookup UCI pointer for config '%s'. Skipping.", *p);
continue;
}
if (uci_list_empty(&ptr.p->saved_delta)) {
ULOG_DEBUG("No unsaved changes in config '%s'. Skipping", *p);
continue;
}
ULOG_INFO("Unsaved changes detected in config '%s', adding to blob buffer", *p);
blobmsg_add_string(bb, NULL, *p);
}
FREE(configs);
exit:
uci_free_context(uci_ctx);
}

View file

@ -25,6 +25,9 @@
#define ULOG_DEBUG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__) #define ULOG_DEBUG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__)
#endif #endif
#define CONFIG_CONFDIR "/etc/config/"
#define DMMAP_CONFDIR "/etc/bbfdm/dmmap/"
enum wifi_config_flags_enum { enum wifi_config_flags_enum {
WIRELESS_CONFIG = 1, WIRELESS_CONFIG = 1,
MAPCONTROLLER_CONFIG = 1<<1, MAPCONTROLLER_CONFIG = 1<<1,
@ -34,16 +37,19 @@ void strncpyt(char *dst, const char *src, size_t n);
int bbf_config_call(struct ubus_context *ctx, const char *object, const char *method, struct blob_buf *data, ubus_data_handler_t callback, void *arg); int bbf_config_call(struct ubus_context *ctx, const char *object, const char *method, struct blob_buf *data, ubus_data_handler_t callback, void *arg);
void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, struct blob_attr *services, void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services,
bool is_commit, bool reload, uint32_t *wifi_config_flags); bool is_commit, bool reload, uint32_t *wifi_config_flags);
void reload_all_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
bool is_commit, bool reload, uint32_t *wifi_config_flags); bool reload, uint32_t *wifi_config_flags);
void wifi_reload_handler_script(uint32_t wifi_config_flags); void wifi_reload_handler_script(uint32_t wifi_config_flags);
void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commit); void uci_apply_changes(const char *conf_dir, int idx, bool is_commit);
void uci_config_changes(const char *conf_dir, const char *save_dir, struct blob_buf *bb); unsigned char get_idx_by_proto(const char *proto);
const char *get_proto_conf_savedir_by_idx(int idx);
const char *get_proto_dmmap_savedir_by_idx(int idx);
const char *get_proto_name_by_idx(int idx);
#endif //__UTILS_H__ #endif //__UTILS_H__