Cannot get callback between components (IPC) to work properly

Hi,

I’m currently working on an application that must send data from one component (component A) to the other (component B) (via IPC).
The sending part is implemented via API in component B.

communication.api

FUNCTION send
(
char buffer[BUFFER_SIZE] IN
);

However component B can have data ready at any time for component A. For this case I want to use a callback to send data from component B to component A.

I tried the following:
communication.api

DEFINE BUFFER_SIZE = 64;

HANDLER onDataAvailable
(
char buffer[BUFFER_SIZE] IN
);

FUNCTION register_handler
(
onDataAvailable dataEventHandler IN
);

component_b.c


communication_onDataAvailableFunc_t communicatorEventHandler;

void communication_register_handler(communication_onDataAvailableFunc_t callback, void* contextPtr)
{
communicatorEventHandler = callback;
}

In component A call the communication_register_handler function to associate the callback to a function. This work… sort off: it only works once. When the handler is called a second time I got an error:

Handler passed to communication_register_callback() can’t be called more than once



So after some research I found out that Legato has an Event Loop API that can provide such functionality.

I tried to implement this as described in the API reference, but i run into some issues.
The code below is from Layered Publish-Subscribe Handlers example and is used as reference.

The mktool creates a tempSensor_server.h based on the tempSensor.api file (such as the first code block on the API reference page).

Then the implementation in component B (same as the second code blocK on the API reference page) gives me an error on the following line:

clientHandlerFunc(*temperaturePtr, le_event_GetContextPtr())

The error I got is:
error: called object ‘clientHandlerFunc’ is not a function or function pointer

The clientHandlerFunc is of type: tempSensor_ChangeHandlerRef_t which is generated:

typedef struct tempSensor_ChangeHandler* tempSensor_ChangeHandlerRef_t;

Which should make sense that this gives an error because it is a pointer to a struct and not e.g. a void.

Has anybody encountered this issue, or is there an other way to implement a callback between two components via IPC?

you can refer to my application.IPC_step4.rar (303.8 KB)

Thanks for the response jyijyi!
I got the callback working based on your application.


The reference code (as seen here) is not correct, the following line:

tempSensor_ChangeHandlerRef_t clientHandlerFunc = secondLayerHandlerFunc;

has to be:

tempSensor_ChangeHandlerFunc_t clientHandlerFunc = secondLayerHandlerFunc;

Thanks again :slight_smile:

Hi

I use your application IPC_step4.rar and it works very well. Thank you.
I am trying to use string as payload, instead of uint32 in your example, but I get buffer overflow problems.

I change sizeof(uint32) to sizeof(strPtr), and change all the variable types, and allocate enough buffer, but still having trouble.

Can you help?

Here is an example to return STRUCT inside handler:

You can see if it can be ported to your existing application.

On the other hand, you can do another IPC call inside the handler to get the required data.
Please see this sample application:
IPC_step4_payload_test.7z (3.0 KB)