mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
dmctx aware bbfdm api
This commit is contained in:
parent
2f3a0805b0
commit
19db3c2d17
13 changed files with 571 additions and 442 deletions
|
|
@ -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];
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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__
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue