How to correctly use ubus_invoke?

Hi all,

I use ubus on my device with openwrt firmware.
There are two daemons, A and B.
At both daemons, we will add A/B into ubus via ubus_add_object, and we can use ubus command to list/call methods, anything looks good.

Today, I try to implement a function that A can call B's method, please check following code.

uint32_t id;                                                                                                                                                                                                                                    
    blob_buf_init(&blob, 0);                                                                                                                                                                                                                     
    blobmsg_add_u32(&blob, "stream", stream);
    if (ubus_lookup_id(ctx, "B", &id)) {
        warn("Failed to look up B object\n");
        break;
    }
    ubus_invoke(ctx, id, "forceIDR", blob.head, NULL, NULL, 0);

If I use command line to do, the result is

root@OpenWrt:/# ubus call B forceIDR '{"stream":0}'
{
        "reply": "okay"
}

Since daemon A don't need the result from B, so I set callback/args as NULL.
And daemon A is quite easy to block at ubus_invoke, why?
Anything I can trace or debug? Please help. Thanks.

Hi everyone,

One question, if the ctx is created for daemon and may I use same ctx to send msg to other daemon? If yes, could you please give me a sample code? If no, how should I do if daemon want to send msg to another daemon via ubus? Thanks.

You should not nest ubus calls, that is invoking ubus_invoke from within a running method handler. If you want an ubus method handler to invoke another ubus method itself, you need to use ubus_invoke_async()

1 Like

Hi Jow,

Thanks. I will study it first.

Hi Jow,

I change a little bit the flow of my program.

  1. Get object_videod_id after ubus_add_uloop.
  2. use ubus_invoke_async without callback.
         struct ubus_request req;                                                                                                                                                                                                        
         blob_buf_init(&blob, 0);                                                                                                                                                                                                        
         blobmsg_add_u32(&blob, "stream", stream);                                                                                                                                                                                       
         ubus_invoke_async(ctx, object_videod_id, "forceIDR", blob.head, &req);                                                                                                                                                          
         req.fd_cb = NULL;                                                                                                                                                                                                               
         req.complete_cb = NULL;
         ubus_complete_request_async(ctx, &req);

I always get segment fault. Any idea where I am wrong? Thanks.