diff --git a/libbbfdm-api/dmapi.h b/libbbfdm-api/dmapi.h index 48e49ad6..1d43a795 100644 --- a/libbbfdm-api/dmapi.h +++ b/libbbfdm-api/dmapi.h @@ -195,7 +195,11 @@ struct dmctx { unsigned int dm_type; unsigned char inparam_isparam; unsigned char findparam; - unsigned int amin_num_of_ms; + + unsigned int amin_num_of_ms; //new + struct ubus_context *amin_ctx; //new + struct ubus_request_data *amin_new_req; //new + struct blob_buf *amin_bb; //new char *in_param; char *in_value; diff --git a/libbbfdm-api/dmbbf.c b/libbbfdm-api/dmbbf.c index d2331b73..f067c08f 100644 --- a/libbbfdm-api/dmbbf.c +++ b/libbbfdm-api/dmbbf.c @@ -1173,42 +1173,125 @@ static int get_ubus_value(struct dmctx *dmctx, struct dmnode *node) return 0; } +struct request_tracker { + struct dmctx *dmctx; + struct ubus_request ubus_req; + struct uloop_timeout timeout; + char object_name[128]; +}; + +static void request_timeout_handler(struct uloop_timeout *t) +{ + struct request_tracker *tracker = container_of(t, struct request_tracker, timeout); + + BBF_ERR("Timeout occurred for object: %s\n", tracker->object_name); + + ubus_abort_request(tracker->dmctx->amin_ctx, &tracker->ubus_req); + + // Add a timeout response to the consolidated response + blobmsg_add_string(tracker->dmctx->amin_bb, "timeout", "called"); + + // Decrement the pending request count + tracker->dmctx->amin_num_of_ms--; + + // Check if all requests are done + if (tracker->dmctx->amin_num_of_ms == 0) { + BBF_ERR("All requests completed.\n"); + ubus_send_reply(tracker->dmctx->amin_ctx, tracker->dmctx->amin_new_req, tracker->dmctx->amin_bb->head); + ubus_complete_deferred_request(tracker->dmctx->amin_ctx, tracker->dmctx->amin_new_req, UBUS_STATUS_OK); + blob_buf_free(tracker->dmctx->amin_bb); + } + + // Clean up the tracker + FREE(tracker); +} + +static void ubus_result_callback(struct ubus_request *req, int type, struct blob_attr *msg) +{ + struct request_tracker *tracker = container_of(req, struct request_tracker, ubus_req); + + /*if (msg) { + char *result = blobmsg_format_json_indent(msg, true, -1); + BBF_ERR("Response from object '%s': %s\n", tracker->object_name, result); + FREE(result); + }*/ + + blobmsg_add_string(tracker->dmctx->amin_bb, "result_callback", tracker->object_name); + + // Cancel the timeout for this request + uloop_timeout_cancel(&tracker->timeout); + + // Decrement the pending request count + tracker->dmctx->amin_num_of_ms--; + + // Check if all requests are done + if (tracker->dmctx->amin_num_of_ms == 0) { + BBF_ERR("All requests completed."); + ubus_send_reply(tracker->dmctx->amin_ctx, tracker->dmctx->amin_new_req, tracker->dmctx->amin_bb->head); + ubus_complete_deferred_request(tracker->dmctx->amin_ctx, tracker->dmctx->amin_new_req, UBUS_STATUS_OK); + blob_buf_free(tracker->dmctx->amin_bb); + } +} + +static void ubus_request_complete(struct ubus_request *req, int ret) +{ + struct request_tracker *tracker = container_of(req, struct request_tracker, ubus_req); + BBF_ERR("Request completed for '%s' with status: %d", tracker->object_name, ret); + FREE(tracker); +} + static int get_ubus_value_async(struct dmctx *dmctx, struct dmnode *node) { char *ubus_name = node->obj->checkdep; char *in_path = (dmctx->in_param[0] == '\0' || rootcmp(dmctx->in_param, "Device") == 0) ? node->current_object : dmctx->in_param; - struct blob_buf blob = {0}; - int timeout = 5000; + struct blob_buf req_buf = {0}; + uint32_t id; - if ((dm_is_micro_service() == false) && ((dmctx->dm_type & node->obj->bbfdm_type) == false)) { - BBF_DEBUG("[%s] Ignore unsupported proto objects [%s], in[%d], datamodel[%d]", __func__, ubus_name, dmctx->dm_type, node->obj->bbfdm_type); + // Look up the object ID + if (ubus_lookup_id(dmctx->amin_ctx, ubus_name, &id)) { + BBF_ERR("Failed to lookup object: %s", ubus_name); return 0; } - if (node->obj->bbfdm_type == BBFDM_CWMP) { - timeout = 10000; + BBF_ERR("UBUS GET: ubus call %s get '{\"path\":\"%s\"}'", ubus_name, in_path); + dmctx->amin_num_of_ms++; + + memset(&req_buf, 0, sizeof(struct blob_buf)); + blob_buf_init(&req_buf, 0); + + blobmsg_add_string(&req_buf, "path", in_path); + prepare_optional_table(dmctx, &req_buf); + + struct request_tracker *tracker = calloc(1, sizeof(struct request_tracker)); + if (!tracker) { + BBF_ERR("Failed to allocate memory for request tracker"); + blob_buf_free(&req_buf); + return 0; } - memset(&blob, 0, sizeof(struct blob_buf)); - blob_buf_init(&blob, 0); + snprintf(tracker->object_name, sizeof(tracker->object_name), "%s", ubus_name); - blobmsg_add_string(&blob, "path", in_path); - prepare_optional_table(dmctx, &blob); + tracker->dmctx = dmctx; - BBF_ERR("UBUS GET: ubus call %s get '{\"path\":\"%s\"}'", ubus_name, in_path); - int res = ubus_call_blob_msg(ubus_name, "get", &blob, timeout, __get_ubus_value, dmctx); + tracker->timeout.cb = request_timeout_handler; + uloop_timeout_set(&tracker->timeout, 5000); - blob_buf_free(&blob); - - if (res) - return FAULT_9005; - - if (dmctx->faultcode) - return dmctx->faultcode; + // Invoke the method asynchronously + if (ubus_invoke_async(dmctx->amin_ctx, id, "get", req_buf.head, &tracker->ubus_req)) { + BBF_ERR("Failed to invoke method asynchronously for object: %s", ubus_name); + uloop_timeout_cancel(&tracker->timeout); + FREE(tracker); + } else { + tracker->ubus_req.data_cb = ubus_result_callback; + tracker->ubus_req.complete_cb = ubus_request_complete; + ubus_complete_request_async(dmctx->amin_ctx, &tracker->ubus_req); + } + blob_buf_free(&req_buf); return 0; } + static void __get_ubus_supported_dm(struct ubus_request *req, int type, struct blob_attr *msg) { struct blob_attr *cur = NULL; @@ -2021,8 +2104,8 @@ int dm_entry_get_value_async(struct dmctx *dmctx) if (dmctx->in_param[0] == '\0' || rootcmp(dmctx->in_param, root->obj) == 0) { dmctx->inparam_isparam = 0; - dmctx->method_obj = get_value_obj; - dmctx->method_param = get_value_param; + dmctx->method_obj = get_value_async_obj; + dmctx->method_param = get_value_async_param; dmctx->checkobj = NULL; dmctx->checkleaf = NULL; dmctx->findparam = 1; diff --git a/libbbfdm-ubus/bbfdm-ubus.c b/libbbfdm-ubus/bbfdm-ubus.c index 06dd42fe..0058756c 100644 --- a/libbbfdm-ubus/bbfdm-ubus.c +++ b/libbbfdm-ubus/bbfdm-ubus.c @@ -266,113 +266,35 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _ return 0; } -static bbfdm_data_t *amin_data = NULL; - -struct request_tracker { - struct ubus_request ubus_req; - struct uloop_timeout timeout; - char object_name[128]; -}; - -static void request_timeout_handler(struct uloop_timeout *t) +static void bbfdm_get_value_async(bbfdm_data_t *data) { - struct request_tracker *tracker = container_of(t, struct request_tracker, timeout); + int fault = 0; - BBF_ERR("Timeout occurred for object: %s\n", tracker->object_name); + memset(&data->bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&data->bb, 0); - ubus_abort_request(amin_data->ctx, &tracker->ubus_req); + bbf_init(&data->bbf_ctx); - // Add a timeout response to the consolidated response - blobmsg_add_string(&amin_data->bb, "timeout", "called"); + data->bbf_ctx.in_param = data->path; + data->bbf_ctx.amin_ctx = data->ctx; + data->bbf_ctx.amin_new_req = &data->amin_new_req; + data->bbf_ctx.amin_bb = &data->bb; - // Decrement the pending request count - amin_data->pending_requests--; + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_GET_VALUE_ASYNC); + if (data->bbf_ctx.amin_num_of_ms == 0) { - // Check if all requests are done - if (amin_data->pending_requests == 0) { - BBF_ERR("All requests completed.\n"); - ubus_send_reply(amin_data->ctx, &amin_data->amin_new_req, amin_data->bb.head); - ubus_complete_deferred_request(amin_data->ctx, &amin_data->amin_new_req, UBUS_STATUS_OK); - blob_buf_free(&amin_data->bb); - } + BBF_ERR("No micro-services fault=%d && data->bbf_ctx.amin_num_of_ms=%d", fault, data->bbf_ctx.amin_num_of_ms); + blobmsg_add_string(&data->bb, "path", data->path); + blobmsg_add_string(&data->bb, "amin_num_of_ms", "0"); + ubus_send_reply(data->ctx, &data->amin_new_req, data->bb.head); + blob_buf_free(&data->bb); + ubus_complete_deferred_request(data->ctx, &data->amin_new_req, UBUS_STATUS_OK); - // Clean up the tracker - FREE(tracker); -} - -static void ubus_result_callback(struct ubus_request *req, int type, struct blob_attr *msg) -{ - struct request_tracker *tracker = container_of(req, struct request_tracker, ubus_req); - - /*if (msg) { - char *result = blobmsg_format_json_indent(msg, true, -1); - BBF_ERR("Response from object %s: %s\n", tracker->object_name, result); - FREE(result); - }*/ - - blobmsg_add_string(&amin_data->bb, "result_callback", "true"); - - // Cancel the timeout for this request - uloop_timeout_cancel(&tracker->timeout); - - // Decrement the pending request count - amin_data->pending_requests--; - - // Check if all requests are done - if (amin_data->pending_requests == 0) { - BBF_ERR("All requests completed."); - ubus_send_reply(amin_data->ctx, &amin_data->amin_new_req, amin_data->bb.head); - ubus_complete_deferred_request(amin_data->ctx, &amin_data->amin_new_req, UBUS_STATUS_OK); - blob_buf_free(&amin_data->bb); - } -} - -static void ubus_request_complete(struct ubus_request *req, int ret) -{ - BBF_ERR("Request completed with status: %d", ret); - struct request_tracker *tracker = container_of(req, struct request_tracker, ubus_req); - - FREE(tracker); -} - -static void invoke_object(const char *object_name) -{ - struct blob_buf req_buf = {0}; - uint32_t id; - - // Look up the object ID - if (ubus_lookup_id(amin_data->ctx, object_name, &id)) { - BBF_ERR("Failed to lookup object: %s", object_name); - return; - } - - memset(&req_buf, 0, sizeof(struct blob_buf)); - blob_buf_init(&req_buf, 0); - - struct request_tracker *tracker = calloc(1, sizeof(struct request_tracker)); - if (!tracker) { - BBF_ERR("Failed to allocate memory for request tracker"); - blob_buf_free(&req_buf); - return; - } - - snprintf(tracker->object_name, sizeof(tracker->object_name), "%s", object_name); - - tracker->timeout.cb = request_timeout_handler; - uloop_timeout_set(&tracker->timeout, 5000); - - // Invoke the method asynchronously - if (ubus_invoke_async(amin_data->ctx, id, "status", req_buf.head, &tracker->ubus_req)) { - BBF_ERR("Failed to invoke method asynchronously for object: %s", object_name); - uloop_timeout_cancel(&tracker->timeout); - free(tracker); + bbf_cleanup(&data->bbf_ctx); } else { - tracker->ubus_req.data_cb = ubus_result_callback; - tracker->ubus_req.complete_cb = ubus_request_complete; - ubus_complete_request_async(amin_data->ctx, &tracker->ubus_req); + BBF_ERR("there are micro-services fault=%d && data->bbf_ctx.amin_num_of_ms=%d", fault, data->bbf_ctx.amin_num_of_ms); + BBF_ERR("Wait for answer"); } - - blob_buf_free(&req_buf); } static int bbfdm_get_async_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), @@ -409,24 +331,9 @@ static int bbfdm_get_async_handler(struct ubus_context *ctx, struct ubus_object fill_optional_data(data, tb[DM_GET_OPTIONAL]); - memset(&data->bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&data->bb, 0); - - blobmsg_add_string(&data->bb, "path", data->path); - ubus_defer_request(ctx, req, &data->amin_new_req); - //bbfdm_get_value_async(&data); - - const char *objects[] = { "wifi.dataelements.collector", "wifi.ap.test1_0", "wifi" }; - int num_objects = sizeof(objects) / sizeof(objects[0]); - - data->pending_requests = num_objects; - amin_data = data; - - for (int i = 0; i < num_objects; i++) { - invoke_object(objects[i]); - } + bbfdm_get_value_async(data); return 0; }