mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Optimized service handling
This commit is contained in:
parent
1af9a94e0b
commit
bdce9e9f05
4 changed files with 160 additions and 70 deletions
|
|
@ -35,13 +35,13 @@ extern struct list_head json_list;
|
|||
extern struct list_head json_memhead;
|
||||
|
||||
#define BBF_SUBPROCESS_DEPTH (2)
|
||||
#define BBF_SCHEMA_UPDATE_TIMEOUT (60 * 1000)
|
||||
#define BBF_INSTANCES_UPDATE_TIMEOUT (25 * 1000)
|
||||
|
||||
LIST_HEAD(head_registered_service);
|
||||
|
||||
static void register_periodic_timers(struct ubus_context *ctx);
|
||||
static void cancel_periodic_timers(struct ubus_context *ctx);
|
||||
static void run_schema_updater(struct bbfdm_context *u);
|
||||
|
||||
// Global variables
|
||||
static unsigned int g_refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT;
|
||||
|
|
@ -274,39 +274,30 @@ static bool is_object_schema_update_available(struct bbfdm_context *u)
|
|||
};
|
||||
|
||||
memset(&data.bb, 0, sizeof(struct blob_buf));
|
||||
int schema_len = blobmsg_len(u->dm_schema.head);
|
||||
blob_buf_free(&u->dm_schema);
|
||||
blob_buf_init(&u->dm_schema, 0);
|
||||
data.bbp = &u->dm_schema;
|
||||
|
||||
// If new parameter gets added it would be a minimum tuple of three params
|
||||
blob_buf_init(&data.bb, 0);
|
||||
void *array = blobmsg_open_array(&data.bb, "results");
|
||||
void *table = blobmsg_open_table(&data.bb, NULL);
|
||||
blobmsg_add_string(&data.bb, "path", "Device.");
|
||||
blobmsg_add_string(&data.bb, "data", "0");
|
||||
blobmsg_add_string(&data.bb, "type", "xsd:string");
|
||||
blobmsg_close_table(&data.bb, table);
|
||||
blobmsg_close_array(&data.bb, array);
|
||||
min_len = blobmsg_len(data.bb.head);
|
||||
blob_buf_free(&data.bb);
|
||||
min_len = 100;
|
||||
|
||||
blob_buf_init(&data.bb, 0);
|
||||
add_path_list(ROOT_NODE, &paths_list);
|
||||
bool ret = bbf_dm_get_supported_dm(&data);
|
||||
if (ret != 0) {
|
||||
WARNING("Failed to get schema");
|
||||
blob_buf_free(&data.bb);
|
||||
free_path_list(&paths_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ll = blobmsg_len(data.bb.head);
|
||||
if (ll - u->dm_schema_len > min_len) {
|
||||
DEBUG("DM Schema update available old:new[%zd:%zd]", u->dm_schema_len, ll);
|
||||
if (u->dm_schema_len != 0) {
|
||||
ll = blobmsg_len(data.bbp->head);
|
||||
if (ll - schema_len > min_len) {
|
||||
DEBUG("DM Schema update available old:new[%zd:%zd]", schema_len, ll);
|
||||
if (schema_len != 0) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
u->dm_schema_len = ll;
|
||||
blob_buf_free(&data.bb);
|
||||
free_path_list(&paths_list);
|
||||
|
||||
return ret;
|
||||
|
|
@ -384,9 +375,6 @@ static const struct blobmsg_policy dm_schema_policy[] = {
|
|||
[DM_SCHEMA_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
|
||||
[DM_SCHEMA_PATHS] = { .name = "paths", .type = BLOBMSG_TYPE_ARRAY },
|
||||
[DM_SCHEMA_FIRST_LEVEL] = { .name = "first_level", .type = BLOBMSG_TYPE_BOOL},
|
||||
[DM_SCHEMA_COMMANDS] = { .name = "commands", .type = BLOBMSG_TYPE_BOOL},
|
||||
[DM_SCHEMA_EVENTS] = { .name = "events", .type = BLOBMSG_TYPE_BOOL},
|
||||
[DM_SCHEMA_PARAMS] = { .name = "params", .type = BLOBMSG_TYPE_BOOL},
|
||||
[DM_SCHEMA_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE},
|
||||
};
|
||||
|
||||
|
|
@ -397,6 +385,14 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob
|
|||
struct blob_attr *tb[__DM_SCHEMA_MAX];
|
||||
LIST_HEAD(paths_list);
|
||||
bbfdm_data_t data;
|
||||
struct bbfdm_context *u;
|
||||
size_t len;
|
||||
|
||||
u = container_of(ctx, struct bbfdm_context, ubus_ctx);
|
||||
if (u == NULL) {
|
||||
ERR("Failed to get the bbfdm context");
|
||||
return UBUS_STATUS_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
memset(&data, 0, sizeof(bbfdm_data_t));
|
||||
|
||||
|
|
@ -410,6 +406,12 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob
|
|||
|
||||
if (tb[DM_SCHEMA_PATH]) {
|
||||
char *path = blobmsg_get_string(tb[DM_SCHEMA_PATH]);
|
||||
|
||||
len = strlen(path);
|
||||
if (path[len-1] != '.') {
|
||||
ERR("Invalid path %s", path);
|
||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
add_path_list(path, &paths_list);
|
||||
}
|
||||
|
||||
|
|
@ -421,6 +423,11 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob
|
|||
blobmsg_for_each_attr(path, paths, rem) {
|
||||
char *path_str = blobmsg_get_string(path);
|
||||
|
||||
len = strlen(path_str);
|
||||
if (path_str[len-1] != '.') {
|
||||
ERR("Invalid path %s", path);
|
||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
add_path_list(path_str, &paths_list);
|
||||
}
|
||||
}
|
||||
|
|
@ -430,19 +437,20 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob
|
|||
unsigned int dm_type = data.bbf_ctx.dm_type;
|
||||
|
||||
data.bbf_ctx.nextlevel = (tb[DM_SCHEMA_FIRST_LEVEL]) ? blobmsg_get_bool(tb[DM_SCHEMA_FIRST_LEVEL]) : false;
|
||||
data.bbf_ctx.iscommand = (tb[DM_SCHEMA_COMMANDS]) ? blobmsg_get_bool(tb[DM_SCHEMA_COMMANDS]) : (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.bbf_ctx.isevent = (tb[DM_SCHEMA_EVENTS]) ? blobmsg_get_bool(tb[DM_SCHEMA_EVENTS]) : (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.bbf_ctx.isinfo = (tb[DM_SCHEMA_PARAMS]) ? blobmsg_get_bool(tb[DM_SCHEMA_PARAMS]) : (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.bbf_ctx.iscommand = (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.bbf_ctx.isevent = (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.bbf_ctx.isinfo = (dm_type == BBFDM_CWMP) ? false : true;
|
||||
data.plist = &paths_list;
|
||||
|
||||
blob_buf_init(&data.bb, 0);
|
||||
|
||||
if (dm_type == BBFDM_CWMP)
|
||||
if (dm_type == BBFDM_CWMP) {
|
||||
bbfdm_get_names(&data);
|
||||
else
|
||||
bbf_dm_get_supported_dm(&data);
|
||||
|
||||
ubus_send_reply(ctx, req, data.bb.head);
|
||||
ubus_send_reply(ctx, req, data.bb.head);
|
||||
} else {
|
||||
get_schema_from_blob(&u->dm_schema, &data);
|
||||
ubus_send_reply(ctx, req, data.bb.head);
|
||||
}
|
||||
|
||||
blob_buf_free(&data.bb);
|
||||
free_path_list(&paths_list);
|
||||
|
|
@ -950,9 +958,15 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
|
|||
{
|
||||
struct blob_attr *tb[__BBF_SERVICE_MAX] = {NULL};
|
||||
struct blob_buf bb;
|
||||
struct bbfdm_context *u;
|
||||
|
||||
u = container_of(ctx, struct bbfdm_context, ubus_ctx);
|
||||
if (u == NULL) {
|
||||
ERR("Failed to get the bbfdm context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
if (blobmsg_parse(service_policy, __BBF_SERVICE_MAX, tb, blob_data(msg), blob_len(msg))) {
|
||||
|
|
@ -998,6 +1012,7 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
|
|||
bool res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
|
||||
|
||||
blobmsg_add_u8(&bb, "status", res);
|
||||
run_schema_updater(u);
|
||||
} else {
|
||||
service_list(&bb);
|
||||
}
|
||||
|
|
@ -1072,32 +1087,22 @@ static struct ubus_object bbf_object = {
|
|||
.n_methods = ARRAY_SIZE(bbf_methods)
|
||||
};
|
||||
|
||||
static void periodic_schema_updater(struct uloop_timeout *t)
|
||||
static void run_schema_updater(struct bbfdm_context *u)
|
||||
{
|
||||
bool ret;
|
||||
struct bbfdm_context *u;
|
||||
struct blob_buf bb;
|
||||
char method_name[45] = {0};
|
||||
|
||||
u = container_of(t, struct bbfdm_context, schema_timer);
|
||||
if (u == NULL) {
|
||||
ERR("Failed to get the bbfdm context");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
ret = is_object_schema_update_available(u);
|
||||
if (ret) {
|
||||
struct blob_buf bb;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
INFO("Schema update available");
|
||||
snprintf(method_name, sizeof(method_name), "%s.%s", UBUS_METHOD_NAME, BBF_UPDATE_SCHEMA_EVENT);
|
||||
blob_buf_init(&bb, 0);
|
||||
ubus_send_event(&u->ubus_ctx, method_name, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
DEBUG("## Update schema after %us ##", BBF_SCHEMA_UPDATE_TIMEOUT);
|
||||
u->schema_timer.cb = periodic_schema_updater;
|
||||
uloop_timeout_set(&u->schema_timer, BBF_SCHEMA_UPDATE_TIMEOUT);
|
||||
}
|
||||
|
||||
static void broadcast_add_del_event(struct list_head *inst, bool is_add)
|
||||
|
|
@ -1417,10 +1422,19 @@ exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int bbfdm_init(struct ubus_context *ctx)
|
||||
static int bbfdm_init(struct ubus_context *ctx, bool is_daemon)
|
||||
{
|
||||
INFO("Registering ubus objects....");
|
||||
return ubus_add_object(ctx, &bbf_object);
|
||||
int ret;
|
||||
|
||||
INFO("Registering UBUS objects daemon %d", is_daemon);
|
||||
if (is_daemon == true) {
|
||||
ret = ubus_add_object(ctx, &bbf_object);
|
||||
} else {
|
||||
bbf_object.n_methods = bbf_object.n_methods - 2;
|
||||
bbf_object.type->n_methods = bbf_object.n_methods;
|
||||
ret = ubus_add_object(ctx, &bbf_object);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lookup_event_cb(struct ubus_context *ctx,
|
||||
|
|
@ -1458,8 +1472,7 @@ static void cancel_periodic_timers(struct ubus_context *ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
DEBUG("Cancelling schema_timer and instance_timer");
|
||||
uloop_timeout_cancel(&u->schema_timer);
|
||||
DEBUG("Cancelling Instance_timer");
|
||||
if (g_refresh_time != 0) {
|
||||
uloop_timeout_cancel(&u->instance_timer);
|
||||
}
|
||||
|
|
@ -1475,10 +1488,7 @@ static void register_periodic_timers(struct ubus_context *ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
DEBUG("Register schema_timer %d and instance_timer %d", BBF_SCHEMA_UPDATE_TIMEOUT, g_refresh_time);
|
||||
u->schema_timer.cb = periodic_schema_updater;
|
||||
uloop_timeout_set(&u->schema_timer, BBF_SCHEMA_UPDATE_TIMEOUT);
|
||||
|
||||
DEBUG("Register instance_timer %d", g_refresh_time);
|
||||
if (g_refresh_time != 0) {
|
||||
u->instance_timer.cb = periodic_instance_updater;
|
||||
uloop_timeout_set(&u->instance_timer, g_refresh_time);
|
||||
|
|
@ -1522,6 +1532,7 @@ int main(int argc, char **argv)
|
|||
openlog(UBUS_METHOD_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
|
||||
memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
|
||||
blob_buf_init(&bbfdm_ctx.dm_schema, 0);
|
||||
|
||||
err = ubus_connect_ctx(&bbfdm_ctx.ubus_ctx, ubus_socket);
|
||||
if (err != UBUS_STATUS_OK) {
|
||||
|
|
@ -1531,12 +1542,13 @@ int main(int argc, char **argv)
|
|||
|
||||
uloop_init();
|
||||
ubus_add_uloop(&bbfdm_ctx.ubus_ctx);
|
||||
run_schema_updater(&bbfdm_ctx);
|
||||
|
||||
if (!input_json) { // It's not a micro-service instance
|
||||
|
||||
bbf_global_init(DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE, true);
|
||||
|
||||
err = bbfdm_init(&bbfdm_ctx.ubus_ctx);
|
||||
err = bbfdm_init(&bbfdm_ctx.ubus_ctx, true);
|
||||
if (err != UBUS_STATUS_OK)
|
||||
goto exit;
|
||||
|
||||
|
|
@ -1548,13 +1560,14 @@ int main(int argc, char **argv)
|
|||
if (err != 0)
|
||||
goto exit;
|
||||
|
||||
periodic_schema_updater(&bbfdm_ctx.schema_timer);
|
||||
periodic_instance_updater(&bbfdm_ctx.instance_timer);
|
||||
} else { // It's a micro-service instance
|
||||
|
||||
err = bbfdm_init(&bbfdm_ctx.ubus_ctx);
|
||||
if (err != 0)
|
||||
err = bbfdm_init(&bbfdm_ctx.ubus_ctx, false);
|
||||
if (err != 0) {
|
||||
ERR("Failed to register ubus objects");
|
||||
goto exit;
|
||||
}
|
||||
bool is_registred = register_service(&bbfdm_ctx.ubus_ctx);
|
||||
if (is_registred == false) {
|
||||
// register for add event
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ struct bbfdm_async_req {
|
|||
|
||||
struct bbfdm_context {
|
||||
struct ubus_context ubus_ctx;
|
||||
size_t dm_schema_len;
|
||||
struct uloop_timeout schema_timer;
|
||||
struct blob_buf dm_schema;
|
||||
struct uloop_timeout instance_timer;
|
||||
struct list_head event_handlers;
|
||||
struct list_head instances;
|
||||
|
|
@ -34,6 +33,7 @@ typedef struct bbfdm_data {
|
|||
struct ubus_request_data *req;
|
||||
struct list_head *plist;
|
||||
struct dmctx bbf_ctx;
|
||||
struct blob_buf *bbp;
|
||||
struct blob_buf bb;
|
||||
uint8_t depth;
|
||||
bool is_raw;
|
||||
|
|
|
|||
|
|
@ -1085,15 +1085,94 @@ static void fill_param_schema(struct blob_buf *bb, struct dm_parameter *param)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct blob_attr *get_parameters(struct blob_attr *msg, const char *key)
|
||||
{
|
||||
struct blob_attr *params = NULL;
|
||||
struct blob_attr *cur;
|
||||
int rem;
|
||||
|
||||
blobmsg_for_each_attr(cur, msg, rem) {
|
||||
const char *name = blobmsg_name(cur);
|
||||
|
||||
if (strcmp(key, name) == 0) {
|
||||
params = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
bool valid_entry(bbfdm_data_t *data, struct blob_attr *input)
|
||||
{
|
||||
bool ret = false;
|
||||
struct blob_attr *p;
|
||||
char *name;
|
||||
size_t len;
|
||||
struct pathNode *pn;
|
||||
|
||||
p = get_parameters(input, "path");
|
||||
if (p) {
|
||||
name = blobmsg_get_string(p);
|
||||
list_for_each_entry(pn, data->plist, list) {
|
||||
len = strlen(pn->path);
|
||||
if (strncmp(pn->path, name, len) == 0) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void get_schema_from_blob(struct blob_buf *schema_bp, bbfdm_data_t *data)
|
||||
{
|
||||
struct blob_buf *bp = &data->bb;
|
||||
struct blob_attr *schema_blob = NULL;
|
||||
struct blob_attr *params;
|
||||
struct blob_attr *cur;
|
||||
size_t rem = 0;
|
||||
|
||||
void *array = blobmsg_open_array(bp, "results");
|
||||
|
||||
schema_blob = blob_memdup(schema_bp->head);
|
||||
if (schema_blob == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
params = get_parameters(schema_blob, "results");
|
||||
if (params == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
blobmsg_for_each_attr(cur, params, rem) {
|
||||
if (valid_entry(data, cur)) {
|
||||
blobmsg_add_blob(bp, cur);
|
||||
}
|
||||
}
|
||||
end:
|
||||
blobmsg_close_array(bp, array);
|
||||
FREE(schema_blob);
|
||||
}
|
||||
|
||||
int bbf_dm_get_supported_dm(bbfdm_data_t *data)
|
||||
{
|
||||
struct dm_parameter *param;
|
||||
struct pathNode *pn;
|
||||
int fault = 0;
|
||||
struct blob_buf *bp;
|
||||
|
||||
bbf_init(&data->bbf_ctx);
|
||||
|
||||
void *array = blobmsg_open_array(&data->bb, "results");
|
||||
if (data->bbp) {
|
||||
bp = data->bbp;
|
||||
} else {
|
||||
bp = &data->bb;
|
||||
}
|
||||
|
||||
void *array = blobmsg_open_array(bp, "results");
|
||||
|
||||
list_for_each_entry(pn, data->plist, list) {
|
||||
bbf_sub_init(&data->bbf_ctx);
|
||||
|
|
@ -1109,21 +1188,21 @@ int bbf_dm_get_supported_dm(bbfdm_data_t *data)
|
|||
list_for_each_entry(param, &data->bbf_ctx.list_parameter, list) {
|
||||
int cmd = get_dm_type(param->type);
|
||||
|
||||
void *table = blobmsg_open_table(&data->bb, NULL);
|
||||
void *table = blobmsg_open_table(bp, NULL);
|
||||
if (cmd == DMT_COMMAND) {
|
||||
fill_operate_schema(&data->bb, param);
|
||||
fill_operate_schema(bp, param);
|
||||
} else if (cmd == DMT_EVENT) {
|
||||
fill_event_schema(&data->bb, param);
|
||||
fill_event_schema(bp, param);
|
||||
} else {
|
||||
fill_param_schema(&data->bb, param);
|
||||
fill_param_schema(bp, param);
|
||||
}
|
||||
blobmsg_close_table(&data->bb, table);
|
||||
blobmsg_close_table(bp, table);
|
||||
}
|
||||
}
|
||||
bbf_sub_cleanup(&data->bbf_ctx);
|
||||
}
|
||||
|
||||
blobmsg_close_array(&data->bb, array);
|
||||
blobmsg_close_array(bp, array);
|
||||
|
||||
bbf_cleanup(&data->bbf_ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@ enum {
|
|||
DM_SCHEMA_PATH,
|
||||
DM_SCHEMA_PATHS,
|
||||
DM_SCHEMA_FIRST_LEVEL,
|
||||
DM_SCHEMA_COMMANDS,
|
||||
DM_SCHEMA_EVENTS,
|
||||
DM_SCHEMA_PARAMS,
|
||||
DM_SCHEMA_OPTIONAL,
|
||||
__DM_SCHEMA_MAX
|
||||
};
|
||||
|
|
@ -39,4 +36,5 @@ void bbfdm_get_instances(bbfdm_data_t *data);
|
|||
|
||||
int bbf_dm_get_supported_dm(bbfdm_data_t *data);
|
||||
|
||||
void get_schema_from_blob(struct blob_buf *schema_bp, bbfdm_data_t *data);
|
||||
#endif /* GET_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue