diff --git a/src/common.c b/src/common.c index 07eb7a9..417e044 100755 --- a/src/common.c +++ b/src/common.c @@ -135,6 +135,7 @@ int global_env_init(int argc, char **argv, struct env *env) execute_cwmp_cli_command(argv[2], argv + 3); FREE(cwmp_main); + icwmp_free_ubus(); exit(0); case 'h': show_help(); diff --git a/src/cwmp.c b/src/cwmp.c index a5c15dc..e39d9b6 100644 --- a/src/cwmp.c +++ b/src/cwmp.c @@ -133,88 +133,6 @@ static int create_cwmp_temporary_files(void) return CWMP_OK; } -static bool g_bbf_object_available = false; - -static void lookup_event_cb(struct ubus_context *ctx __attribute__((unused)), - struct ubus_event_handler *ev __attribute__((unused)), - const char *type, struct blob_attr *msg) -{ - const struct blobmsg_policy policy = { - "path", BLOBMSG_TYPE_STRING - }; - struct blob_attr *attr; - const char *path; - - if (CWMP_STRCMP(type, "ubus.object.add") != 0) - return; - - blobmsg_parse(&policy, 1, &attr, blob_data(msg), blob_len(msg)); - if (!attr) - return; - - path = blobmsg_data(attr); - if (CWMP_STRCMP(path, BBFDM_OBJECT_NAME) == 0) { - g_bbf_object_available = true; - uloop_end(); - } -} - -static void lookup_timeout_cb(struct uloop_timeout *timeout __attribute__((unused))) -{ - uloop_end(); -} - -static int wait_for_bbf_object() -{ -#define BBF_WAIT_TIMEOUT 60 - - struct ubus_context *uctx; - int ret; - uint32_t ubus_id; - struct ubus_event_handler add_event; - struct uloop_timeout u_timeout; - - g_bbf_object_available = false; - uctx = ubus_connect(NULL); - if (uctx == NULL) { - CWMP_LOG(ERROR, "Can't create ubus context"); - return FAULT_CPE_INTERNAL_ERROR; - } - - uloop_init(); - ubus_add_uloop(uctx); - - // register for add event - CWMP_MEMSET(&add_event, 0, sizeof(struct ubus_event_handler)); - add_event.cb = lookup_event_cb; - ubus_register_event_handler(uctx, &add_event, "ubus.object.add"); - - // check if object already present - ret = ubus_lookup_id(uctx, BBFDM_OBJECT_NAME, &ubus_id); - if (ret == 0) { - g_bbf_object_available = true; - goto end; - } - - // Set timeout to expire lookup - CWMP_MEMSET(&u_timeout, 0, sizeof(struct uloop_timeout)); - u_timeout.cb = lookup_timeout_cb; - uloop_timeout_set(&u_timeout, BBF_WAIT_TIMEOUT * 1000); - - uloop_run(); - uloop_done(); - -end: - ubus_free(uctx); - - if (g_bbf_object_available == false) { - CWMP_LOG(ERROR, "%s object not found", BBFDM_OBJECT_NAME); - return FAULT_CPE_INTERNAL_ERROR; - } - - return 0; -} - static void wait_for_time_sync(void) { struct cwmp_dm_parameter cwmp_dm_param = {0}; @@ -372,39 +290,62 @@ int main(int argc, char **argv) int error; struct env env; - error = wait_for_bbf_object(); + error = icwmp_connect_ubus(); if (error) return error; + error = wait_for_bbf_object(); + if (error) { + icwmp_free_ubus(); + return error; + } + CWMP_MEMSET(&env, 0, sizeof(struct env)); - if ((error = global_env_init(argc, argv, &env))) + if ((error = global_env_init(argc, argv, &env))) { + icwmp_free_ubus(); return error; + } - if ((error = create_cwmp_temporary_files())) + if ((error = create_cwmp_temporary_files())) { + icwmp_free_ubus(); return error; + } - if ((error = cwmp_init())) + if ((error = cwmp_init())) { + icwmp_free_ubus(); return error; + } CWMP_MEMCPY(&(cwmp_main->env), &env, sizeof(struct env)); - if ((error = cwmp_init_backup_session(NULL, ALL))) + if ((error = cwmp_init_backup_session(NULL, ALL))) { + icwmp_free_ubus(); return error; + } - if ((error = cwmp_root_cause_events())) + if ((error = cwmp_root_cause_events())) { + icwmp_free_ubus(); return error; + } icwmp_http_server_init(); uloop_init(); - icwmp_uloop_ubus_init(); - - if (0 != initiate_autonomous_complpolicy()) + if ((error = icwmp_uloop_ubus_register())) { + icwmp_free_ubus(); return error; + } - if (0 != initiate_interface_update()) + if ((error = initiate_autonomous_complpolicy())) { + icwmp_uloop_ubus_exit(); return error; + } + + if ((error = initiate_interface_update())) { + icwmp_uloop_ubus_exit(); + return error; + } trigger_cwmp_session_timer(); diff --git a/src/ubus_utils.c b/src/ubus_utils.c index 7f3c394..2aa36c6 100644 --- a/src/ubus_utils.c +++ b/src/ubus_utils.c @@ -20,7 +20,9 @@ typedef int (*callback)(struct blob_buf *b); +static bool g_bbf_object_available = false; static struct ubus_context *ubus_ctx = NULL; +struct uloop_timeout u_timeout; struct command_cb { char *str; @@ -398,12 +400,20 @@ void bb_add_string(struct blob_buf *bb, const char *name, const char *value) blobmsg_add_string(bb, name, ""); } -int icwmp_uloop_ubus_init() +int icwmp_connect_ubus() { ubus_ctx = ubus_connect(NULL); if (!ubus_ctx) return -1; + return 0; +} + +int icwmp_uloop_ubus_register() +{ + if (!ubus_ctx) + return -1; + ubus_add_uloop(ubus_ctx); if (icwmp_register_object(ubus_ctx)) @@ -426,24 +436,16 @@ int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg uint32_t id; int rc = 0; - struct ubus_context *ctx = NULL; - - ctx = ubus_connect(NULL); - if (ctx == NULL) { + if (ubus_ctx == NULL) { CWMP_LOG(ERROR, "Failed to connect with ubus err: %d", errno); return -1; } - if (!ubus_lookup_id(ctx, obj, &id)) - rc = ubus_invoke(ctx, id, method, msg, icwmp_callback, callback_arg, 60000); + if (!ubus_lookup_id(ubus_ctx, obj, &id)) + rc = ubus_invoke(ubus_ctx, id, method, msg, icwmp_callback, callback_arg, 60000); else rc = -1; - if (ctx) { - ubus_free(ctx); - ctx = NULL; - } - return rc; } @@ -496,3 +498,89 @@ void clean_interface_update(void) ubus_unregister_event_handler(ubus_ctx, cwmp_main->intf_ev); } + +static void lookup_event_cb(struct ubus_context *ctx __attribute__((unused)), + struct ubus_event_handler *ev __attribute__((unused)), + const char *type, struct blob_attr *msg) +{ + const struct blobmsg_policy policy = { + "path", BLOBMSG_TYPE_STRING + }; + struct blob_attr *attr; + const char *path; + + if (CWMP_STRCMP(type, "ubus.object.add") != 0) + return; + + blobmsg_parse(&policy, 1, &attr, blob_data(msg), blob_len(msg)); + if (!attr) + return; + + path = blobmsg_data(attr); + if (CWMP_STRCMP(path, BBFDM_OBJECT_NAME) == 0) { + g_bbf_object_available = true; + uloop_timeout_cancel(&u_timeout); + uloop_end(); + } +} + +static void lookup_timeout_cb(struct uloop_timeout *timeout __attribute__((unused))) +{ + uloop_end(); +} + +int wait_for_bbf_object() +{ +#define BBF_WAIT_TIMEOUT 60 + + int ret; + uint32_t ubus_id; + struct ubus_event_handler add_event; + + g_bbf_object_available = false; + if (ubus_ctx == NULL) { + CWMP_LOG(ERROR, "Can't create ubus context"); + return FAULT_CPE_INTERNAL_ERROR; + } + + uloop_init(); + ubus_add_uloop(ubus_ctx); + + // register for add event + CWMP_MEMSET(&add_event, 0, sizeof(struct ubus_event_handler)); + add_event.cb = lookup_event_cb; + ubus_register_event_handler(ubus_ctx, &add_event, "ubus.object.add"); + + // check if object already present + ret = ubus_lookup_id(ubus_ctx, BBFDM_OBJECT_NAME, &ubus_id); + if (ret == 0) { + g_bbf_object_available = true; + goto end; + } + + // Set timeout to expire lookup + CWMP_MEMSET(&u_timeout, 0, sizeof(struct uloop_timeout)); + u_timeout.cb = lookup_timeout_cb; + uloop_timeout_set(&u_timeout, BBF_WAIT_TIMEOUT * 1000); + + uloop_run(); + uloop_done(); + +end: + ubus_remove_object(ubus_ctx, &add_event.obj); + + if (g_bbf_object_available == false) { + CWMP_LOG(ERROR, "%s object not found", BBFDM_OBJECT_NAME); + return FAULT_CPE_INTERNAL_ERROR; + } + + return 0; +} + +void icwmp_free_ubus() +{ + if (ubus_ctx) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + } +} diff --git a/src/ubus_utils.h b/src/ubus_utils.h index 002305f..6109775 100644 --- a/src/ubus_utils.h +++ b/src/ubus_utils.h @@ -21,10 +21,13 @@ int icwmp_register_object(struct ubus_context *ctx); int icwmp_delete_object(struct ubus_context *ctx); int icwmp_ubus_invoke(const char *obj, const char *method, struct blob_attr *msg, icwmp_ubus_cb icwmp_callback, void *callback_arg); -int icwmp_uloop_ubus_init(); -void icwmp_uloop_ubus_exit(); +int icwmp_uloop_ubus_register(void); +void icwmp_uloop_ubus_exit(void); int initiate_autonomous_complpolicy(void); void clean_autonomous_complpolicy(void); int initiate_interface_update(void); void clean_interface_update(void); +int icwmp_connect_ubus(void); +int wait_for_bbf_object(void); +void icwmp_free_ubus(void); #endif /* __ICWMP_UBUS_UTILS_H__ */ diff --git a/test/cmocka/icwmp_unit_test.c b/test/cmocka/icwmp_unit_test.c index dedfa99..19b0a32 100644 --- a/test/cmocka/icwmp_unit_test.c +++ b/test/cmocka/icwmp_unit_test.c @@ -1,10 +1,14 @@ #include #include "icwmp_unit_test.h" +#include "ubus_utils.h" + +struct ubus_context *ubus_ctx = NULL; int main() { int ret = 0; + icwmp_connect_ubus(); ret += icwmp_notifications_test(); ret += icwmp_cli_unit_test(); ret += icwmp_soap_msg_test(); @@ -12,6 +16,7 @@ int main() ret += icwmp_datamodel_interface_test(); ret += icwmp_backup_session_test(); ret += icwmp_download_unit_test(); + icwmp_free_ubus(); return ret; }