Apply for get method

This commit is contained in:
Amin Ben Romdhane 2025-01-24 21:08:22 +01:00
parent 485c2ada13
commit 7124816a60
3 changed files with 130 additions and 136 deletions

View file

@ -195,7 +195,11 @@ struct dmctx {
unsigned int dm_type; unsigned int dm_type;
unsigned char inparam_isparam; unsigned char inparam_isparam;
unsigned char findparam; 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_param;
char *in_value; char *in_value;

View file

@ -1173,42 +1173,125 @@ static int get_ubus_value(struct dmctx *dmctx, struct dmnode *node)
return 0; 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) static int get_ubus_value_async(struct dmctx *dmctx, struct dmnode *node)
{ {
char *ubus_name = node->obj->checkdep; 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; 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}; struct blob_buf req_buf = {0};
int timeout = 5000; uint32_t id;
if ((dm_is_micro_service() == false) && ((dmctx->dm_type & node->obj->bbfdm_type) == false)) { // Look up the object ID
BBF_DEBUG("[%s] Ignore unsupported proto objects [%s], in[%d], datamodel[%d]", __func__, ubus_name, dmctx->dm_type, node->obj->bbfdm_type); if (ubus_lookup_id(dmctx->amin_ctx, ubus_name, &id)) {
BBF_ERR("Failed to lookup object: %s", ubus_name);
return 0; return 0;
} }
if (node->obj->bbfdm_type == BBFDM_CWMP) {
timeout = 10000;
}
memset(&blob, 0, sizeof(struct blob_buf));
blob_buf_init(&blob, 0);
blobmsg_add_string(&blob, "path", in_path);
prepare_optional_table(dmctx, &blob);
BBF_ERR("UBUS GET: ubus call %s get '{\"path\":\"%s\"}'", ubus_name, in_path); 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); dmctx->amin_num_of_ms++;
blob_buf_free(&blob); memset(&req_buf, 0, sizeof(struct blob_buf));
blob_buf_init(&req_buf, 0);
if (res) blobmsg_add_string(&req_buf, "path", in_path);
return FAULT_9005; prepare_optional_table(dmctx, &req_buf);
if (dmctx->faultcode)
return dmctx->faultcode;
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; return 0;
} }
snprintf(tracker->object_name, sizeof(tracker->object_name), "%s", ubus_name);
tracker->dmctx = dmctx;
tracker->timeout.cb = request_timeout_handler;
uloop_timeout_set(&tracker->timeout, 5000);
// 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) static void __get_ubus_supported_dm(struct ubus_request *req, int type, struct blob_attr *msg)
{ {
struct blob_attr *cur = NULL; 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) { if (dmctx->in_param[0] == '\0' || rootcmp(dmctx->in_param, root->obj) == 0) {
dmctx->inparam_isparam = 0; dmctx->inparam_isparam = 0;
dmctx->method_obj = get_value_obj; dmctx->method_obj = get_value_async_obj;
dmctx->method_param = get_value_param; dmctx->method_param = get_value_async_param;
dmctx->checkobj = NULL; dmctx->checkobj = NULL;
dmctx->checkleaf = NULL; dmctx->checkleaf = NULL;
dmctx->findparam = 1; dmctx->findparam = 1;

View file

@ -266,113 +266,35 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _
return 0; return 0;
} }
static bbfdm_data_t *amin_data = NULL; static void bbfdm_get_value_async(bbfdm_data_t *data)
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)
{ {
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 data->bbf_ctx.in_param = data->path;
blobmsg_add_string(&amin_data->bb, "timeout", "called"); 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 fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_GET_VALUE_ASYNC);
amin_data->pending_requests--; if (data->bbf_ctx.amin_num_of_ms == 0) {
// Check if all requests are done BBF_ERR("No micro-services fault=%d && data->bbf_ctx.amin_num_of_ms=%d", fault, data->bbf_ctx.amin_num_of_ms);
if (amin_data->pending_requests == 0) { blobmsg_add_string(&data->bb, "path", data->path);
BBF_ERR("All requests completed.\n"); blobmsg_add_string(&data->bb, "amin_num_of_ms", "0");
ubus_send_reply(amin_data->ctx, &amin_data->amin_new_req, amin_data->bb.head); ubus_send_reply(data->ctx, &data->amin_new_req, data->bb.head);
ubus_complete_deferred_request(amin_data->ctx, &amin_data->amin_new_req, UBUS_STATUS_OK); blob_buf_free(&data->bb);
blob_buf_free(&amin_data->bb); ubus_complete_deferred_request(data->ctx, &data->amin_new_req, UBUS_STATUS_OK);
}
// Clean up the tracker bbf_cleanup(&data->bbf_ctx);
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);
} else { } else {
tracker->ubus_req.data_cb = ubus_result_callback; BBF_ERR("there are micro-services fault=%d && data->bbf_ctx.amin_num_of_ms=%d", fault, data->bbf_ctx.amin_num_of_ms);
tracker->ubus_req.complete_cb = ubus_request_complete; BBF_ERR("Wait for answer");
ubus_complete_request_async(amin_data->ctx, &tracker->ubus_req);
} }
blob_buf_free(&req_buf);
} }
static int bbfdm_get_async_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), 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]); 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); ubus_defer_request(ctx, req, &data->amin_new_req);
//bbfdm_get_value_async(&data); 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]);
}
return 0; return 0;
} }