le_messaging.h

Go to the documentation of this file.
1 /**
2  * @page c_messaging Low-level Messaging API
3  *
4  * @subpage le_messaging.h "API Reference"
5  *
6  * <HR>
7  *
8  * Message-based interfaces in Legato are implemented in layers.
9  * This low-level messaging API is at the bottom layer.
10  * It's designed to support higher layers of the messaging system. But it's also
11  * intended to be easy to hand-code low-level messaging in C, when necessary.
12  *
13  * Two messaging types are supported, Local and Socket. "Local" allows logically distinct apps to
14  * be combined in one executable, and essentially mediates the direct function calls between them.
15  * "Socket" uses UNIX domain sockets to communicate between distinct processes.
16  *
17  * This low-level messaging API supports:
18  * - (Socket only) remote party identification (addressing)
19  * - (Socket only) very late (runtime) discovery and binding of parties
20  * - (Socket only) in-process and inter-process message delivery
21  * - location transparency
22  * - sessions
23  * - (Socket only) access control
24  * - request/reply transactions
25  * - message buffer memory management
26  * - support for single-threaded and multi-threaded programs
27  * - some level of protection from protocol mismatches between parties in a session.
28  *
29  * This API is integrated with the Legato Event Loop API so components can interact with each
30  * other using messaging without having to create threads or file descriptor
31  * sets that block other software from handling other events. Support for
32  * integration with legacy POSIX-based programs is also provided.
33  *
34  * @section c_messagingInteractionModel Interaction Model
35  *
36  * The Legato low-level messaging system follows a service-oriented pattern:
37  * - Service providers advertise their service.
38  * - Clients open sessions with those services
39  * - Both sides can send and receive messages through the session.
40  *
41  * Clients and servers can both send one-way messages within a session.
42  * Clients can start a request-response transaction by sending a request to the server,
43  * and the server can send a response. Request-response transactions can be blocking or
44  * non-blocking (with a completion callback). If the server dies or terminates the session
45  * before sending the response, Legato will automatically terminate the transaction.
46  *
47  * Servers are prevented from sending blocking requests to clients as a safety measure.
48  * If a server were to block waiting for one of its clients, it would open up the server
49  * to being blocked indefinitely by one of its clients, which would allow one client to cause
50  * a server to deny service to other clients. Also, if a client started a blocking request-response
51  * transaction at the same time that the server started a blocking request-response transaction
52  * in the other direction, a deadlock would occur.
53  *
54  * @section c_messagingAddressing Addressing
55  *
56  * Servers and clients have interfaces that can been connected to each other via bindings. Both
57  * client-side and server-side interfaces are identified by name, but the names don't have to match
58  * for them to be bound to each other. The binding determines which server-side interface will
59  * be connected to when a client opens a session.
60  *
61  * Server-side interfaces are also known as "services".
62  *
63  * When a session is opened by a client, a session reference is provided to both the client
64  * and the server. Messages are then sent within the session using the session reference.
65  * This session reference becomes invalid when the session is closed.
66  *
67  * @section c_messagingProtocols Protocols
68  *
69  * Communication between client and server is done using a message-based protocol. This protocol
70  * is defined at a higher layer than this API, so this API doesn't know the structure of the
71  * message payloads or the correct message sequences. That means this API can't check
72  * for errors in the traffic it carries. However, it does provide a basic mechanism for detecting
73  * protocol mismatches by forcing both client and server to provide the protocol identifier
74  * of the protocol to be used. The client and server must also provide
75  * the maximum message size, as an extra sanity check.
76  *
77  * To make this possible, the client and server must independently call
78  * @c le_msg_GetProtocolRef(), to get a reference to a "Protocol" object that encapsulates these
79  * protocol details:
80  *
81  * @code
82  * protocolRef = le_msg_GetProtocolRef(MY_PROTOCOL_ID, sizeof(myproto_Msg_t));
83  * @endcode
84  *
85  * @note In this example, the protocol identifier (which is a string uniquely identifying a
86  * specific version of a specific protocol) and the message structure
87  * would be defined elsewhere, in a header file shared between the client and the
88  * server. The structure @c myproto_Msg_t contains a
89  * @c union of all of the different messages included in the protocol, thereby
90  * making @c myproto_Msg_t as big as the biggest message in the protocol.
91  *
92  * When a server creates a service (by calling le_msg_CreateService()) and when a client creates
93  * a session (by calling le_msg_CreateSession()), they are required to provide a reference to a
94  * Protocol object that they obtained from le_msg_GetProtocolRef().
95  *
96  * @section c_messagingClientUsage Client Usage Model
97  *
98  * @ref c_messagingClientSending <br>
99  * @ref c_messagingClientReceiving <br>
100  * @ref c_messagingClientClosing <br>
101  * @ref c_messagingClientMultithreading <br>
102  * @ref c_messagingClientExample
103  *
104  * Clients that want to use a service do the following:
105  * -# Get a reference to the protocol they want to use by calling @c le_msg_GetProtocolRef().
106  * -# Create a session using @c le_msg_CreateSession(), passing in the protocol reference and
107  * the client's interface name.
108  * -# Optionally register a message receive callback using @c le_msg_SetSessionRecvHandler().
109  * -# Open the session using le_msg_OpenSession(), le_msg_OpenSessionSync(), or
110  * le_msg_TryOpenSessionSync().
111  *
112  * @code
113  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
114  * sessionRef = le_msg_CreateSession(protocolRef, MY_INTERFACE_NAME);
115  * le_msg_SetSessionRecvHandler(sessionRef, NotifyMsgHandlerFunc, NULL);
116  * le_msg_OpenSession(sessionRef, SessionOpenHandlerFunc, NULL);
117  * @endcode
118  *
119  * The Legato framework takes care of setting up any IPC connections, as needed (or not, if the
120  * client and server happen to be in the same process).
121  *
122  * When the session opens, the Event Loop will call the "session open handler" call-back function
123  * that was passed into le_msg_OpenSession().
124  *
125  * le_msg_OpenSessionSync() is a synchronous alternative to le_msg_OpenSession(). The difference
126  * is that le_msg_OpenSessionSync() will not return until the session has opened or failed to
127  * open (most likely due to permissions settings).
128  *
129  * le_msg_TryOpenSessionSync() is like le_msg_OpenSessionSync() except that it will not wait
130  * for a server session to become available if it's not already available at the time of the
131  * call. That is, if the client's interface is not bound to any service, or if the service that
132  * it's bound to is not currently advertised by the server, then le_msg_TryOpenSessionSync()
133  * will return an error code.
134  *
135  * @subsection c_messagingClientSending Sending a Message
136  *
137  * Before sending a message, the client must first allocate the message from the session's message
138  * pool using le_msg_CreateMsg(). It can then get a pointer to the payload part of the
139  * message using le_msg_GetPayloadPtr(). Once the message payload is populated, the client sends
140  * the message.
141  *
142  * @code
143  * msgRef = le_msg_CreateMsg(sessionRef);
144  * msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
145  * msgPayloadPtr->... = ...; // <-- Populate message payload...
146  * @endcode
147  *
148  * If no response is required from the server, the client sends the message using le_msg_Send().
149  * At this point, the client has handed off the message to the messaging system, and the messaging
150  * system will delete the message automatically once it has finished sending it.
151  *
152  * @code
153  * le_msg_Send(msgRef);
154  * @endcode
155  *
156  * If the client expects a response from the server, the client can use
157  * le_msg_RequestResponse() to send their message and specify a callback function to be called
158  * when the response arrives. This callback will be called by the event loop of the thread that
159  * created the session (i.e., the thread that called le_msg_CreateSession()).
160  *
161  * @code
162  * le_msg_RequestResponse(msgRef, ResponseHandlerFunc, NULL);
163  * @endcode
164  *
165  * If the client expects an immediate response from the server, and the client wants to block until
166  * that response is received, it can use le_msg_RequestSyncResponse() instead of
167  * le_msg_RequestResponse(). However, keep in mind that blocking the client thread will
168  * block all event handlers that share that thread. That's why le_msg_RequestSyncResponse() should
169  * only be used when the server is expected to respond immediately, or when the client thread
170  * is not shared by other event handlers.
171  *
172  * @code
173  * responseMsgRef = le_msg_RequestSyncResponse(msgRef);
174  * @endcode
175  *
176  * @warning If the client and server are running in the same thread, and the
177  * client calls le_msg_RequestSyncResponse(), it will return an error immediately, instead of
178  * blocking the thread. If the thread were blocked in this scenario, the server would also be
179  * blocked and would therefore be unable to receive the request and respond to it, resulting in
180  * a deadlock.
181  *
182  * When the client is finished with it, the <b> client must release its reference
183  * to the response message </b> by calling le_msg_ReleaseMsg().
184  *
185  * @code
186  * le_msg_ReleaseMsg(responseMsgRef);
187  * @endcode
188  *
189  * @subsection c_messagingClientReceiving Receiving a Non-Response Message
190  *
191  * When a server sends a message to the client that is not a response to a request from the client,
192  * that non-response message will be passed to the receive handler that the client
193  * registered using le_msg_SetSessionRecvHandler(). In fact, this is the only kind of message
194  * that will result in that receive handler being called.
195  *
196  * @note Some protocols don't include any messages that are not responses to client requests,
197  * which is why it's optional to register a receive handler on the client side.
198  *
199  * The payload of a received message can be accessed using le_msg_GetPayloadPtr(), and the client
200  * can check what session the message arrived through by calling le_msg_GetSession().
201  *
202  * When the client is finished with the message, the <b> client must release its reference
203  * to the message </b> by calling le_msg_ReleaseMsg().
204  *
205  * @code
206  * // Function will be called whenever the server sends us a notification message.
207  * static void NotifyHandlerFunc
208  * (
209  * le_msg_MessageRef_t msgRef, // Reference to the received message.
210  * void* contextPtr // contextPtr passed into le_msg_SetSessionRecvHandler().
211  * )
212  * {
213  * // Process notification message from the server.
214  * myproto_Msg_t* msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
215  * ...
216  *
217  * // Release the message, now that we are finished with it.
218  * le_msg_ReleaseMsg(msgRef);
219  * }
220  *
221  * COMPONENT_INIT
222  * {
223  * le_msg_ProtocolRef_t protocolRef;
224  * le_msg_SessionRef_t sessionRef;
225  *
226  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
227  * sessionRef = le_msg_CreateSession(protocolRef, MY_INTERFACE_NAME);
228  * le_msg_SetSessionRecvHandler(sessionRef, NotifyHandlerFunc, NULL);
229  * le_msg_OpenSession(sessionRef, SessionOpenHandlerFunc, NULL);
230  * }
231  * @endcode
232  *
233  * @subsection c_messagingClientClosing Closing Sessions
234  *
235  * When the client is done using a service, it can close the session using le_msg_CloseSession().
236  * This will leave the session object in existence, though, so that it can be opened again
237  * using le_msg_OpenSession().
238  *
239  * @code
240  * le_msg_CloseSession(sessionRef);
241  * @endcode
242  *
243  * To delete a session object, call le_msg_DeleteSession(). This will automatically close the
244  * session, if it's still open (but won't automatically delete any messages).
245  *
246  * @code
247  * le_msg_DeleteSession(sessionRef);
248  * @endcode
249  *
250  * @note If a client process dies while it has a session open, that session will be
251  * automatically closed and deleted by the Legato framework, so there's no need to register process
252  * clean-up handlers or anything like that for this purpose.
253  *
254  * Additionally, clients can choose to call le_msg_SetSessionCloseHandler() to register to be
255  * notified when a session gets closed by the server. Servers often keep state on behalf of their
256  * clients, and if the server closes the session (or if the system closes the session because the
257  * server died), the client most likely will still be operating under the assumption (now false)
258  * that the server is maintaining state on its behalf. If a client is designed to recover from
259  * the server losing its state, the client can register a close handler and handle the close.
260  *
261  * @code
262  * le_msg_SetSessionCloseHandler(sessionRef, SessionCloseHandler, NULL);
263  * @endcode
264  *
265  * However, most clients are not designed to recover from their session being closed by someone
266  * else, so if a close handler is not registered by a client and the session closes for some
267  * reason other than the client calling le_msg_CloseSession(), then the client process
268  * will be terminated.
269  *
270  * @note If the client closes the session, the client-side session close handler will not be called,
271  * even if one is registered.
272  *
273  * @subsection c_messagingClientMultithreading Multithreading
274  *
275  * The Low-Level Messaging API is thread safe, but not async safe.
276  *
277  * When a client creates a session, that session gets "attached" to the thread that created it
278  * (i.e., the thread that called le_msg_CreateSession()). That thread will then call any callbacks
279  * registered for that session.
280  *
281  * Note that this implies that if the client thread that creates the session does not
282  * run the Legato event loop then no callbacks will ever be called for that session.
283  * To work around this, move the session creation to another thread that that uses the Legato event
284  * loop.
285  *
286  * Furthermore, to prevent race conditions, only the thread that is attached to a given session
287  * is allowed to call le_msg_RequestSyncResponse() for that session.
288  *
289  * @subsection c_messagingClientExample Sample Code
290  *
291  * @code
292  * // Function will be called whenever the server sends us a notification message.
293  * static void NotifyHandlerFunc
294  * (
295  * le_msg_MessageRef_t msgRef, // Reference to the received message.
296  * void* contextPtr // contextPtr passed into le_msg_SetSessionRecvHandler().
297  * )
298  * {
299  * // Process notification message from the server.
300  * myproto_Msg_t* msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
301  * ...
302  *
303  * // Release the message, now that we are finished with it.
304  * le_msg_ReleaseMsg(msgRef);
305  * }
306  *
307  * // Function will be called whenever the server sends us a response message or our
308  * // request-response transaction fails.
309  * static void ResponseHandlerFunc
310  * (
311  * le_msg_MessageRef_t msgRef, // Reference to response message (NULL if transaction failed).
312  * void* contextPtr // contextPtr passed into le_msg_RequestResponse().
313  * )
314  * {
315  * // Check if we got a response.
316  * if (msgRef == NULL)
317  * {
318  * // Transaction failed. No response received.
319  * // This might happen if the server deleted the request without sending a response,
320  * // or if we had registered a "Session End Handler" and the session terminated before
321  * // the response was sent.
322  * LE_ERROR("Transaction failed!");
323  * }
324  * else
325  * {
326  * // Process response message from the server.
327  * myproto_Msg_t* msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
328  * ...
329  *
330  * // Release the response message, now that we are finished with it.
331  * le_msg_ReleaseMsg(msgRef);
332  * }
333  * }
334  *
335  * // Function will be called when the client-server session opens.
336  * static void SessionOpenHandlerFunc
337  * (
338  * le_msg_SessionRef_t sessionRef, // Reference tp the session that opened.
339  * void* contextPtr // contextPtr passed into le_msg_OpenSession().
340  * )
341  * {
342  * le_msg_MessageRef_t msgRef;
343  * myproto_Msg_t* msgPayloadPtr;
344  *
345  * // Send a request to the server.
346  * msgRef = le_msg_CreateMsg(sessionRef);
347  * msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
348  * msgPayloadPtr->... = ...; // <-- Populate message payload...
349  * le_msg_RequestResponse(msgRef, ResponseHandlerFunc, NULL);
350  * }
351  *
352  * COMPONENT_INIT
353  * {
354  * le_msg_ProtocolRef_t protocolRef;
355  * le_msg_SessionRef_t sessionRef;
356  *
357  * // Open a session.
358  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
359  * sessionRef = le_msg_CreateSession(protocolRef, MY_INTERFACE_NAME);
360  * le_msg_SetSessionRecvHandler(sessionRef, NotifyHandlerFunc, NULL);
361  * le_msg_OpenSession(sessionRef, SessionOpenHandlerFunc, NULL);
362  * }
363  * @endcode
364  *
365  * @section c_messagingServerUsage Server Usage Model
366  *
367  * @ref c_messagingServerProcessingMessages <br>
368  * @ref c_messagingServerSendingNonResponse <br>
369  * @ref c_messagingServerCleanUp <br>
370  * @ref c_messagingRemovingService <br>
371  * @ref c_messagingServerMultithreading <br>
372  * @ref c_messagingServerExample
373  *
374  * Servers that wish to offer a service do the following:
375  * -# Get a reference to the protocol they want to use by calling le_msg_GetProtocolRef().
376  * -# Create a Service object using le_msg_CreateService(), passing in the protocol reference and
377  * the service name.
378  * -# Call le_msg_SetServiceRecvHandler() to register a function to handle messages received from
379  * clients.
380  * -# Advertise the service using le_msg_AdvertiseService().
381  *
382  * @code
383  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
384  * serviceRef = le_msg_CreateService(protocolRef, SERVER_INTERFACE_NAME);
385  * le_msg_SetServiceRecvHandler(serviceRef, RequestMsgHandlerFunc, NULL);
386  * le_msg_AdvertiseService(serviceRef);
387  * @endcode
388  *
389  * Once the service is advertised, clients can open it and start sending it messages. The server
390  * will receive messages via callbacks to the function it registered using
391  * le_msg_SetServiceRecvHandler().
392  *
393  * Servers also have the option of being notified when sessions are opened by clients. They
394  * get this notification by registering a handler function using le_msg_AddServiceOpenHandler().
395  *
396  * @code
397  * // Function will be called whenever a client opens a session with our service.
398  * static void SessionOpenHandlerFunc
399  * (
400  * le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session object.
401  * void* contextPtr ///< [in] contextPtr passed to le_msg_SetSessionOpenHandler().
402  * )
403  * {
404  * // Handle new session opening...
405  * ...
406  * }
407  *
408  * COMPONENT_INIT
409  * {
410  * le_msg_ProtocolRef_t protocolRef;
411  * le_msg_ServiceRef_t serviceRef;
412  *
413  * // Create my service and advertise it.
414  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
415  * serviceRef = le_msg_CreateService(protocolRef, SERVER_INTERFACE_NAME);
416  * le_msg_AddServiceOpenHandler(serviceRef, SessionOpenHandlerFunc, NULL);
417  * le_msg_AdvertiseService(serviceRef);
418  * }
419  * @endcode
420  *
421  * Both the "Open Handler" and the "Receive Handler" will be called by the Legato event loop in
422  * the thread that registered those handlers (which must also be the same thread that created the
423  * service).
424  *
425  * @subsection c_messagingServerProcessingMessages Processing Messages from Clients
426  *
427  * The payload of any received message can be accessed using le_msg_GetPayloadPtr().
428  *
429  * If a received message does not require a response (i.e., if the client sent it using
430  * le_msg_Send()), then when the server is finished with the message, the server must release
431  * the message by calling le_msg_ReleaseMsg().
432  *
433  * @code
434  * void RequestMsgHandlerFunc
435  * (
436  * le_msg_MessageRef_t msgRef // Reference to the received message.
437  * )
438  * {
439  * myproto_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef);
440  * LE_INFO("Received request '%s'", msgPtr->request.string);
441  *
442  * // No response required and I'm done with this message, so release it.
443  * le_msg_ReleaseMsg(msgRef);
444  * }
445  * @endcode
446  *
447  * If a received message requires a response (i.e., if the client sent it using
448  * le_msg_RequestResponse() or le_msg_RequestSyncResponse()), the server must eventually respond
449  * to that message by calling le_msg_Respond() on that message. le_msg_Respond() sends the message
450  * back to the client that sent the request. The response payload is stored inside the same
451  * payload buffer that contained the request payload.
452  *
453  * To do this, the request payload pointer can be cast to a pointer to the response
454  * payload structure, and then the response payload can be written into it.
455  *
456  * @code
457  * void RequestMsgHandlerFunc
458  * (
459  * le_msg_MessageRef_t msgRef // Reference to the received message.
460  * )
461  * {
462  * myproto_RequestMsg_t* requestPtr = le_msg_GetPayloadPtr(msgRef);
463  * myproto_ResponseMsg_t* responsePtr;
464  *
465  * LE_INFO("Received request '%s'", requestPtr->string);
466  *
467  * responsePtr = (myproto_ResponseMsg_t*)requestPtr;
468  * responsePtr->value = Value;
469  * le_msg_Respond(msgRef);
470  * }
471  * @endcode
472  *
473  * Alternatively, the request payload structure and the response payload structure could be placed
474  * into a union together.
475  *
476  * @code
477  * typedef union
478  * {
479  * myproto_Request_t request;
480  * myproto_Response_t response;
481  * }
482  * myproto_Msg_t;
483  *
484  * ...
485  *
486  * void RequestMsgHandlerFunc
487  * (
488  * le_msg_MessageRef_t msgRef // Reference to the received message.
489  * )
490  * {
491  * myproto_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef);
492  * LE_INFO("Received request '%s'", msgPtr->request.string);
493  * msgPtr->response.value = Value;
494  * le_msg_Respond(msgRef);
495  * }
496  * @endcode
497  *
498  * @warning Of course, once you've started writing the response payload into the buffer, the request payload
499  * is no longer available, so if you still need it, copy it somewhere else first.
500  *
501  * @note The server doesn't have to send the response back to the client right away. It could
502  * hold onto the request for an indefinite amount of time, for whatever reason.
503  *
504  * Whenever any message is received from a client, the message is associated with the session
505  * through which the client sent it. A reference to the session can be retrieved from the message,
506  * if needed, by calling le_msg_GetSession(). This can be handy for tagging things in the
507  * server's internal data structures that need to be cleaned up when the client closes the session
508  * (see @ref c_messagingServerCleanUp for more on this).
509  *
510  * The function le_msg_NeedsResponse() can be used to check if a received message requires a
511  * response or not.
512  *
513  * @subsection c_messagingServerSendingNonResponse Sending Non-Response Messages to Clients
514  *
515  * If a server wants to send a non-response message to a client, it first needs a reference
516  * to the session that client opened. It could have got the session reference from a previous
517  * message received from the client (by calling le_msg_GetSession() on that message).
518  * Or, it could have got the session reference from a Session Open Handler callback (see
519  * le_msg_AddServiceOpenHandler()). Either way, once it has the session reference, it can call
520  * le_msg_CreateMsg() to create a message from that session's server-side message pool. The
521  * message can then be populated and sent in the same way that a client would send a message
522  * to the server using le_msg_GetPayloadPtr() and le_msg_Send().
523  *
524  * @todo Explain how to configure the sizes of the server-side message pools.
525  *
526  * @code
527  * // Function will be called whenever a client opens a session with our service.
528  * static void SessionOpenHandlerFunc
529  * (
530  * le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session object.
531  * void* contextPtr ///< [in] contextPtr passed to le_msg_SetSessionOpenHandler().
532  * )
533  * {
534  * le_msg_MessageRef_t msgRef;
535  * myproto_Msg_t* msgPayloadPtr;
536  *
537  * // Send a "Welcome" message to the client.
538  * msgRef = le_msg_CreateMsg(sessionRef);
539  * msgPayloadPtr = le_msg_GetPayloadPtr(msgRef);
540  * msgPayloadPtr->... = ...; // <-- Populate message payload...
541  * le_msg_Send(msgRef);
542  * }
543  *
544  * COMPONENT_INIT
545  * {
546  * le_msg_ProtocolRef_t protocolRef;
547  * le_msg_ServiceRef_t serviceRef;
548  *
549  * // Create my service and advertise it.
550  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
551  * serviceRef = le_msg_CreateService(protocolRef, SERVER_INTERFACE_NAME);
552  * le_msg_AddServiceOpenHandler(serviceRef, SessionOpenHandlerFunc, NULL);
553  * le_msg_AdvertiseService(serviceRef);
554  * }
555  * @endcode
556  *
557  * @subsection c_messagingServerCleanUp Cleaning up when Sessions Close
558  *
559  * If a server keeps state on behalf of its clients, it can call le_msg_AddServiceCloseHandler()
560  * to ask to be notified when clients close sessions with a given service. This allows the server
561  * to clean up any state associated with a given session when the client closes that session
562  * (or when the system closes the session because the client died). The close handler is passed a
563  * session reference, so the server can check its internal data structures and clean up anything
564  * that it has previously tagged with that same session reference.
565  *
566  * @note Servers don't delete sessions. On the server side, sessions are automatically deleted
567  * when they close.
568  *
569  * @subsection c_messagingRemovingService Removing Service
570  *
571  * If a server wants to stop offering a service, it can hide the service by calling
572  * le_msg_HideService(). This will not terminate any sessions that are already open, but it
573  * will prevent clients from opening new sessions until it's advertised again.
574  *
575  * @warning Watch out for race conditions here. It's possible that a client is in the process
576  * of opening a session when you decide to hide your service. In this case, a new session may
577  * open after you hid the service. Be prepared to handle that gracefully.
578  *
579  * The server also has the option to delete the service. This hides the service and closes
580  * all open sessions.
581  *
582  * If a server process dies, the Legato framework will automatically delete all of its services.
583  *
584  * @subsection c_messagingServerMultithreading Multithreading
585  *
586  * The Low-Level Messaging API is thread safe, but not async safe.
587  *
588  * When a server creates a service, that service gets attached to the thread that created it
589  * (i.e., the thread that called le_msg_CreateService()). That thread will call any handler
590  * functions registered for that service.
591  *
592  * This implies that if the thread that creates the service doesn't
593  * run the Legato event loop, then no callbacks will ever be called for that service.
594  * To work around this, you could move the service to another thread that that runs the Legato event
595  * loop.
596  *
597  * @subsection c_messagingServerExample Sample Code
598  *
599  * @code
600  * void RequestMsgHandlerFunc
601  * (
602  * le_msg_MessageRef_t msgRef, // Reference to the received message.
603  * void* contextPtr ///< [in] contextPtr passed to le_msg_SetServiceRecvHandler().
604  * )
605  * {
606  * // Check the message type to decide what to do.
607  * myproto_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef);
608  * switch (msgPtr->type)
609  * {
610  * case MYPROTO_MSG_TYPE_SET_VALUE:
611  * // Message doesn't require a response.
612  * Value = msgPtr->...;
613  * le_msg_ReleaseMsg(msgRef);
614  * break;
615  *
616  * case MYPROTO_MSG_TYPE_GET_VALUE:
617  * // Message is a request that requires a response.
618  * // Notice that we just reuse the request message buffer for the response.
619  * msgPtr->... = Value;
620  * le_msg_Respond(msgRef);
621  * break;
622  *
623  * default:
624  * // Unexpected message type!
625  * LE_ERROR("Received unexpected message type %d from session %s.",
626  * msgPtr->type,
627  * le_msg_GetInterfaceName(le_msg_GetSessionInterface(le_msg_GetSession(msgRef))));
628  * le_msg_ReleaseMsg(msgRef);
629  * }
630  * }
631  *
632  * COMPONENT_INIT
633  * {
634  * le_msg_ProtocolRef_t protocolRef;
635  * le_msg_ServiceRef_t serviceRef;
636  *
637  * // Create my service and advertise it.
638  * protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID, sizeof(myproto_Msg_t));
639  * serviceRef = le_msg_CreateService(protocolRef, SERVER_INTERFACE_NAME);
640  * le_msg_SetServiceRecvHandler(serviceRef, RequestMsgHandlerFunc, NULL);
641  * le_msg_AdvertiseService(serviceRef);
642  * }
643  * @endcode
644  *
645  * @section c_messagingStartUp Start Up Sequencing
646  *
647  * Worthy of special mention is the fact that the low-level messaging system can be used to
648  * solve the age-old problem of coordinating the start-up sequence of processes that interact with
649  * each other. Far too often, the start-up sequence of multiple interacting processes is addressed
650  * using hacks like polling or sleeping for arbitrary lengths of time. These solutions can
651  * waste a lot of CPU cycles and battery power, slow down start-up, and (in the case of arbitrary
652  * sleeps) introduce race conditions that can cause failures in the field.
653  *
654  * In Legato, a messaging client can attempt to open a session before the server process has even
655  * started. The client will be notified asynchronously (via callback) when the server advertises
656  * its service.
657  *
658  * In this way, clients are guaranteed to wait for the servers they use, without the inefficiency
659  * of polling, and without having to add code elsewhere to coordinate the start-up sequence.
660  * If there's work that needs to be done by the client at start-up before it opens
661  * a session with the server, the client is allowed to do that work in parallel with the start-up
662  * of the server, so the CPU can be more fully utilized to shorten the overall duration of the
663  * start-up sequence.
664  *
665  * @section c_messagingMemoryManagement Memory Management
666  *
667  * Message buffer memory is allocated and controlled behind the scenes, inside the Messaging API.
668  * This allows the Messaging API to
669  * - take some steps to remove programmer pitfalls,
670  * - provide some built-in remote troubleshooting features
671  * - encapsulate the IPC implementation, allowing for future optimization and porting.
672  *
673  * Each message object is allocated from a session. The sessions' message pool sizes can
674  * be tuned through component and application configuration files and device configuration
675  * settings.
676  *
677  * @todo Explain how to configure message pools.
678  *
679  * Generally speaking, message payload sizes are determined by the protocol that is being used.
680  * Application protocols and the packing of messages into message buffers are the domain of
681  * higher-layers of the software stack. But, at this low layer, servers and clients just declare
682  * the name and version of the protocol, and the size of the largest message in the protocol.
683  * From this, they obtain a protocol reference that they provide to sessions when they create
684  * them.
685  *
686  * @section c_messagingSecurity Security
687  *
688  * Security is provided in the form of authentication and access control.
689  *
690  * Clients cannot open sessions with servers until their client-side interface is "bound" to a
691  * server-side interface (service). The binding thereby provides configuration of both routing and
692  * access control.
693  *
694  * Neither the client-side nor the server-side IPC sockets are named. Therefore, no process other
695  * than the Service Directory has access to these sockets. The Service Directory passes client
696  * connections to the appropriate server based on the binding configuration of the client's interface.
697  *
698  * The binding configuration is kept in the "system" configuration tree, so clients that do not
699  * have write access to the "system" configuration tree have no control over their own binding
700  * configuration. By default, sandboxed apps do not have any access (read or write) to the
701  * "system" configuration tree.
702  *
703  * @section c_messagingGetClientInfo Get Client Info
704  *
705  * In rare cases, a server may wish to check the user ID of the remote client. Generally,
706  * this is not necessary because the IPC system enforces user-based access control restrictions
707  * automatically before allowing an IPC connection to be established. However, sometimes it
708  * may be useful when the service wishes to change the way it behaves, based on what user is
709  * connected to it.
710  *
711  * le_msg_GetClientUserId() can be used to fetch the user ID of the client at the far end of a
712  * given IPC session.
713  *
714  * @code
715  * uid_t clientUserId;
716  * if (le_msg_GetClientUserId(sessionRef, &clientUserId) != LE_OK)
717  * {
718  * // The session must have closed.
719  * ...
720  * }
721  * else
722  * {
723  * LE_INFO("My client has user ID %ud.", clientUserId);
724  * }
725  * @endcode
726  *
727  * le_msg_GetClientProcessId() can be used to fetch the process ID from the client.
728  *
729  * @code
730  * pid_t clientProcessId;
731  * if (le_msg_GetClientProcessId (sessionRef, &clientProcessId) != LE_OK)
732  * {
733  * {
734  * // The session must have closed.
735  * ...
736  * }
737  * else
738  * {
739  * LE_INFO("My client has process ID %ud.", clientProcessId);
740  * }
741  * @endcode
742  *
743  * le_msg_GetClientUserCreds() can be used to fetch the user credentials from the client.
744  *
745  * @code
746  * le_msg_SessionRef_t sessionRef,
747  * uid_t* userIdPtr,
748  * pid_t* processIdPtr
749  * @endcode
750  *
751  * @section c_messagingSendingFileDescriptors Sending File Descriptors
752  *
753  * It's possible to send an open file descriptor through an IPC session by adding an fd to a
754  * message before sending it. On the sender's side, le_msg_SetFd() is used to set the
755  * file descriptor to be sent. On the receiver's side, le_msg_GetFd() is used to get the fd
756  * from the message.
757  *
758  * The IPC API will close the original fd in the sender's address space once it has
759  * been sent, so if the sender still needs the fd open on its side, it should duplicate the fd
760  * (e.g., using dup() ) before sending it.
761  *
762  * On the receiving side, if the fd is not extracted from the message, it will be closed when
763  * the message is released. The fd can only be extracted from the message once. Subsequent
764  * calls to le_msg_GetFd() will return -1.
765  *
766  * @warning DO NOT SEND DIRECTORY FILE DESCRIPTORS. They can be exploited and used to break out of
767  * chroot() jails.
768  *
769  * @section c_messagingFutureEnhancements Future Enhancements
770  *
771  * As an optimization to reduce the number of copies in cases where the sender of a message
772  * already has the message payload of their message assembled somewhere (perhaps as static data
773  * or in another message buffer received earlier from somewhere), a pointer to the payload could
774  * be passed to the message, instead of having to copy the payload into the message.
775  *
776  * @code
777  * msgRef = le_msg_CreateMsg(sessionRef);
778  * le_msg_SetPayloadBuff(msgRef, &msgPayload, sizeof(msgPayload));
779  * msgRef = le_msg_RequestResponse(msgRef, ResponseHandlerFunc, contextPtr);
780  * @endcode
781  *
782  * Perhaps an "iovec" version could be added to do scatter-gather too?
783  *
784  * @section c_messagingDesignNotes Design Notes
785  *
786  * We explored the option of having asynchronous messages automatically released when their
787  * handler function returns, unless the handler calls an "AddRef" function before returning.
788  * That would reduce the amount of code required in the common case. However, we chose to require
789  * that the client release the message explicitly in all cases, because the consequences of using
790  * an invalid reference can be catastrophic and much more difficult to debug than forgetting to
791  * release a message (which will generate pool growth warning messages in the log).
792  *
793  * @section c_messagingTroubleshooting Troubleshooting
794  *
795  * If you're running as the super-user (root), you can trace messaging traffic using @b TBD.
796  * You can also inspect message queues and view lists of outstanding message objects within
797  * processes using the Process Inspector tool.
798  *
799  * If you're leaking messages by forgetting to release them when you're finished with them,
800  * you'll see warning messages in the log indicating your message pool is growing.
801  * You should be able to tell the related messaging service by the name of the expanding pool.
802  *
803  * @todo Finish this section later, when the diagnostic tools become available.
804  *
805  * <HR>
806  *
807  * Copyright (C) Sierra Wireless Inc.
808  */
809 
810 
811 /** @file le_messaging.h
812  *
813  * Legato @ref c_messaging include file.
814  *
815  * Copyright (C) Sierra Wireless Inc.
816  */
817 
818 #ifndef LE_MESSAGING_H_INCLUDE_GUARD
819 #define LE_MESSAGING_H_INCLUDE_GUARD
820 
821 // =======================================
822 // DATA TYPES
823 // =======================================
824 
825 //--------------------------------------------------------------------------------------------------
826 /**
827  * Reference to a protocol.
828  */
829 //--------------------------------------------------------------------------------------------------
830 typedef struct le_msg_Protocol* le_msg_ProtocolRef_t;
831 
832 //--------------------------------------------------------------------------------------------------
833 /**
834  * Reference to an interface's service instance.
835  */
836 //--------------------------------------------------------------------------------------------------
837 typedef struct le_msg_Interface* le_msg_InterfaceRef_t;
838 
839 //--------------------------------------------------------------------------------------------------
840 /**
841  * Reference to a server's service instance.
842  */
843 //--------------------------------------------------------------------------------------------------
844 typedef struct le_msg_Service* le_msg_ServiceRef_t;
845 
846 //--------------------------------------------------------------------------------------------------
847 /**
848  * Reference to a client's service instance.
849  */
850 //--------------------------------------------------------------------------------------------------
851 typedef struct le_msg_ClientInterface* le_msg_ClientInterfaceRef_t;
852 
853 //--------------------------------------------------------------------------------------------------
854 /**
855  * Reference to a client-server session.
856  */
857 //--------------------------------------------------------------------------------------------------
858 typedef struct le_msg_Session* le_msg_SessionRef_t;
859 
860 //--------------------------------------------------------------------------------------------------
861 /**
862  * Reference to a message.
863  */
864 //--------------------------------------------------------------------------------------------------
865 typedef struct le_msg_Message* le_msg_MessageRef_t;
866 
867 //--------------------------------------------------------------------------------------------------
868 /**
869  * Reference to a handler (call-back) function for events that can occur on a service (such as
870  * opening and closing of sessions and receipt of messages).
871  */
872 //--------------------------------------------------------------------------------------------------
873 typedef struct le_msg_SessionEventHandler* le_msg_SessionEventHandlerRef_t;
874 
875 //--------------------------------------------------------------------------------------------------
876 /**
877  * Handler function prototype for handlers that take session references as their arguments.
878  *
879  * See le_msg_SetSessionCloseHandler(), le_msg_AddServiceOpenHandler(), and
880  * le_msg_AddServiceCloseHandler().
881  *
882  * @param sessionRef [in] Reference to the session that experienced the event.
883  *
884  * @param contextPtr [in] Opaque contextPtr value provided when the handler was registered.
885  */
886 //--------------------------------------------------------------------------------------------------
887 typedef void (* le_msg_SessionEventHandler_t)
888 (
889  le_msg_SessionRef_t sessionRef,
890  void* contextPtr
891 );
892 
893 
894 //--------------------------------------------------------------------------------------------------
895 /**
896  * Receive handler function prototype.
897  *
898  * See le_msg_SetSessionRecvHandler() and le_msg_SetServiceRecvHandler().
899  *
900  * @param msgRef [in] Reference to the received message. Don't forget to release this using
901  * le_msg_ReleaseMsg() when you're finished with it.
902  *
903  * @param contextPtr [in] Opaque contextPtr value provided when the handler was registered.
904  */
905 //--------------------------------------------------------------------------------------------------
906 typedef void (* le_msg_ReceiveHandler_t)
907 (
908  le_msg_MessageRef_t msgRef,
909  void* contextPtr
910 );
911 
912 
913 //--------------------------------------------------------------------------------------------------
914 /**
915  * Asynchronous response callback function prototype.
916  *
917  * See le_msg_RequestResponse().
918  *
919  * @param msgRef [in] Reference to the received response message, or NULL if the transaction
920  * failed and no response was received. If not NULL, don't forget to
921  * release it by calling le_msg_ReleaseMsg() when you're finished with it.
922  *
923  * @param contextPtr [in] Opaque contextPtr value passed to le_msg_RequestResponse().
924  */
925 //--------------------------------------------------------------------------------------------------
926 typedef void (* le_msg_ResponseCallback_t)
927 (
928  le_msg_MessageRef_t msgRef,
929  void* contextPtr
930 );
931 
932 
933 
934 
935 //--------------------------------------------------------------------------------------------------
936 /**
937  * Generic service object. Used internally as part of low-level messaging implementation.
938  */
939 //--------------------------------------------------------------------------------------------------
941 {
942  enum
943  {
944  LE_MSG_SERVICE_UNIX_SOCKET,
945  LE_MSG_SERVICE_LOCAL
946  } type;
947 };
948 
949 
950 //--------------------------------------------------------------------------------------------------
951 /**
952  * Generic message object. Holds a pointer to the session the message is associated with.
953  */
954 //--------------------------------------------------------------------------------------------------
956 {
957  le_msg_SessionRef_t sessionRef; ///< Session for this message
958 };
959 
960 
961 //--------------------------------------------------------------------------------------------------
962 /**
963  * Message handler receiver for local messages
964  */
965 //--------------------------------------------------------------------------------------------------
966 typedef struct
967 {
968  le_thread_Ref_t thread; ///< Thread on which receive should be processes.
969  le_msg_ReceiveHandler_t handler; ///< Handler function which should be called on thread
970  void* contextPtr; ///< Context pointer to pass to the handler
972 
973 
974 //--------------------------------------------------------------------------------------------------
975 /**
976  * Local service object.
977  *
978  * Create an instance of this object for each local service used by your program.
979  *
980  * @note This structure should never be accessed directly; instead access through le_msg_...()
981  * functions.
982  */
983 //--------------------------------------------------------------------------------------------------
984 typedef struct
985 {
986  struct le_msg_Service service; ///< Service
987 #if LE_CONFIG_CUSTOM_OS && defined(LE_MSG_SERVICE_READY_FLAG)
988  LE_MSG_SERVICE_READY_FLAG; ///< Indicate if service is ready in an OS-specific manner
989 #else
990  bool serviceReady; ///< Indicate if service is ready
991 #endif
992  le_msg_LocalReceiver_t receiver; ///< Server destination
993  le_mem_PoolRef_t messagePool; ///< Pool for messages on this service
995 
996 
997 //--------------------------------------------------------------------------------------------------
998 /**
999  * Message that's sent over a queue transport.
1000  */
1001 //--------------------------------------------------------------------------------------------------
1002 typedef struct le_msg_LocalMessage
1003 {
1004  struct le_msg_Message message; ///< Pointer to base message
1005  int fd; ///< File descriptor sent with message (via Get/SetFd)
1006  le_sem_Ref_t responseReady; ///< Semaphore which will be set when response is ready
1007  bool needsResponse; ///< True if message needs a response
1008  le_msg_ResponseCallback_t completionCallback; ///< Function to be called when transaction done.
1009  void* contextPtr; ///< Opaque value to be passed to handler function.
1010  uint8_t data[] __attribute__((aligned(__BIGGEST_ALIGNMENT__))); ///< Start of message data
1011  // Align so any type of
1012  // data can be stored inside.
1014 
1015 
1016 //--------------------------------------------------------------------------------------------------
1017 /**
1018  * Size of local message header (needs to be added to size of message in local message pools).
1019  */
1020 //--------------------------------------------------------------------------------------------------
1021 #define LE_MSG_LOCAL_HEADER_SIZE sizeof(le_msg_LocalMessage_t)
1022 
1023 
1024 // =======================================
1025 // PROTOCOL FUNCTIONS
1026 // =======================================
1027 
1028 //--------------------------------------------------------------------------------------------------
1029 /**
1030  * Gets a reference to refer to a particular version of a particular protocol.
1031  *
1032  * @return Protocol reference.
1033  */
1034 //--------------------------------------------------------------------------------------------------
1036 (
1037  const char* protocolId, ///< [in] String uniquely identifying the the protocol and version.
1038  size_t largestMsgSize ///< [in] Size (in bytes) of the largest message in the protocol.
1039 );
1040 
1041 
1042 //--------------------------------------------------------------------------------------------------
1043 /**
1044  * Gets the unique identifier string of the protocol.
1045  *
1046  * @return Pointer to the protocol identifier (null-terminated, UTF-8 string).
1047  */
1048 //--------------------------------------------------------------------------------------------------
1050 (
1051  le_msg_ProtocolRef_t protocolRef ///< [in] Reference to the protocol.
1052 );
1053 
1054 
1055 //--------------------------------------------------------------------------------------------------
1056 /**
1057  * Gets the protocol's maximum message size.
1058  *
1059  * @return The size, in bytes.
1060  */
1061 //--------------------------------------------------------------------------------------------------
1063 (
1064  le_msg_ProtocolRef_t protocolRef ///< [in] Reference to the protocol.
1065 );
1066 
1067 
1068 // =======================================
1069 // SESSION FUNCTIONS
1070 // =======================================
1071 
1072 //--------------------------------------------------------------------------------------------------
1073 /**
1074  * Creates a session that will make use of a protocol to talk to a service on a given client
1075  * interface.
1076  *
1077  * @note This doesn't actually attempt to open the session. It just creates the session
1078  * object, allowing the client the opportunity to register handlers for the session
1079  * before attempting to open it using le_msg_OpenSession().
1080  *
1081  * @return Session reference.
1082  */
1083 //--------------------------------------------------------------------------------------------------
1085 (
1086  le_msg_ProtocolRef_t protocolRef, ///< [in] Reference to the protocol to be used.
1087  const char* interfaceName ///< [in] Name of the client-side interface.
1088 );
1089 
1090 
1091 //--------------------------------------------------------------------------------------------------
1092 /**
1093  * Create a session that will always use message boxes to talk to a service in the same process
1094  * space.
1095  *
1096  * @return Session reference.
1097  */
1098 //--------------------------------------------------------------------------------------------------
1100 (
1101  le_msg_LocalService_t* servicePtr ///< [in] Reference to the service.
1102 );
1103 
1104 
1105 //--------------------------------------------------------------------------------------------------
1106 /**
1107  * Sets an opaque context value (void pointer) that can be retrieved from that session later using
1108  * le_msg_GetSessionContextPtr().
1109  */
1110 //--------------------------------------------------------------------------------------------------
1112 (
1113  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1114 
1115  void* contextPtr ///< [in] Opaque value to be returned by
1116  /// le_msg_GetSessionContextPtr().
1117 );
1118 
1119 //--------------------------------------------------------------------------------------------------
1120 /**
1121  * Fetches the opaque context value (void pointer) that was set earlier using
1122  * le_msg_SetSessionContextPtr().
1123  *
1124  * @return Context Ptr value passed into le_msg_SetSessionContextPtr(), or NULL if
1125  * le_msg_SetSessionContextPtr() has not been called for this session yet.
1126  */
1127 //--------------------------------------------------------------------------------------------------
1129 (
1130  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1131 );
1132 
1133 
1134 //--------------------------------------------------------------------------------------------------
1135 /**
1136  * Deletes a session. This will end the session and free up any resources associated
1137  * with it. Any pending request-response transactions in this session will be terminated.
1138  * If the far end has registered a session close handler callback, it will be called.
1139  *
1140  * @note Function is only used by clients. On the server side, sessions are automatically
1141  * deleted when they close.
1142  */
1143 //--------------------------------------------------------------------------------------------------
1145 (
1146  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1147 );
1148 
1149 
1150 //--------------------------------------------------------------------------------------------------
1151 /**
1152  * Sets the receive handler callback function to be called when a non-response message arrives
1153  * on this session.
1154  *
1155  * The handler function will be called by the Legato event loop of the thread that created
1156  * the session.
1157  *
1158  * @note This is a client-only function. Servers are expected to use
1159  * le_msg_SetServiceRecvHandler() instead.
1160  */
1161 //--------------------------------------------------------------------------------------------------
1163 (
1164  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1165  le_msg_ReceiveHandler_t handlerFunc,///< [in] Handler function.
1166  void* contextPtr ///< [in] Opaque pointer value to pass to the handler.
1167 );
1168 
1169 
1170 //--------------------------------------------------------------------------------------------------
1171 /**
1172  * Sets the handler callback function to be called when the session is closed from the other
1173  * end. A local termination of the session will not trigger this callback.
1174  *
1175  * The handler function will be called by the Legato event loop of the thread that created
1176  * the session.
1177  *
1178  * @note
1179  * - If this isn't set on the client side, the framework assumes the client is not designed
1180  * to recover from the server terminating the session, and the client process will terminate
1181  * if the session is terminated by the server.
1182  * - This is a client-only function. Servers are expected to use le_msg_AddServiceCloseHandler()
1183  * instead.
1184  */
1185 //--------------------------------------------------------------------------------------------------
1187 (
1188  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1189  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1190  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1191 );
1192 
1193 
1194 //--------------------------------------------------------------------------------------------------
1195 /**
1196  * Gets the handler callback function to be called when the session is closed from the other
1197  * end.
1198  */
1199 //--------------------------------------------------------------------------------------------------
1201 (
1202  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1203  le_msg_SessionEventHandler_t* handlerFunc,///< [out] Handler function.
1204  void** contextPtr ///< [out] Opaque pointer value to pass to
1205  ///< the handler.
1206 );
1207 
1208 
1209 //--------------------------------------------------------------------------------------------------
1210 /**
1211  * Opens a session with a service, providing a function to be called-back when the session is
1212  * open.
1213  *
1214  * Asynchronous sessions are not supported by mailbox sessions.
1215  *
1216  * @note Only clients open sessions. Servers must patiently wait for clients to open sessions
1217  * with them.
1218  *
1219  * @warning If the client and server don't agree on the maximum message size for the protocol,
1220  * a fatal error will be logged and the client process will be killed.
1221  */
1222 //--------------------------------------------------------------------------------------------------
1223 void le_msg_OpenSession
1224 (
1225  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1226  le_msg_SessionEventHandler_t callbackFunc, ///< [in] Function to be called when open.
1227  /// NULL if no notification is needed.
1228  void* contextPtr ///< [in] Opaque value to pass to the callback.
1229 );
1230 
1231 
1232 //--------------------------------------------------------------------------------------------------
1233 /**
1234  * Synchronously open a session with a service. Blocks until the session is open.
1235  *
1236  * This function logs a fatal error and terminates the calling process if unsuccessful.
1237  *
1238  * @note Only clients open sessions. Servers must patiently wait for clients to open sessions
1239  * with them.
1240  *
1241  * @warning If the client and server do not agree on the maximum message size for the protocol,
1242  * a fatal error will be logged and the client process will be killed.
1243  */
1244 //--------------------------------------------------------------------------------------------------
1246 (
1247  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1248 );
1249 
1250 
1251 //--------------------------------------------------------------------------------------------------
1252 /**
1253  * Synchronously open a session with a service. Does not wait for the session to become available
1254  * if not available..
1255  *
1256  * le_msg_TryOpenSessionSync() differs from le_msg_OpenSessionSync() in that
1257  * le_msg_TryOpenSessionSync() will not wait for a server session to become available if it's
1258  * not already available at the time of the call. That is, if the client's interface is not
1259  * bound to any service, or if the service that it's bound to is not currently advertised
1260  * by the server, then le_msg_TryOpenSessionSync() will return an error code, while
1261  * le_msg_OpenSessionSync() will wait until the binding is created or the server advertises
1262  * the service (or both).
1263  *
1264  * @return
1265  * - LE_OK if the session was successfully opened.
1266  * - LE_NOT_FOUND if the server is not currently offering the service to which the client is bound.
1267  * - LE_NOT_PERMITTED if the client interface is not bound to any service (doesn't have a binding).
1268  * - LE_COMM_ERROR if the Service Directory cannot be reached.
1269  *
1270  * @note Only clients open sessions. Servers' must patiently wait for clients to open sessions
1271  * with them.
1272  *
1273  * @warning If the client and server do not agree on the maximum message size for the protocol,
1274  * a fatal error will be logged and the client process will be killed.
1275  */
1276 //--------------------------------------------------------------------------------------------------
1278 (
1279  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1280 );
1281 
1282 
1283 //--------------------------------------------------------------------------------------------------
1284 /**
1285  * Terminates a session.
1286  */
1287 //--------------------------------------------------------------------------------------------------
1289 (
1290  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1291 );
1292 
1293 
1294 //--------------------------------------------------------------------------------------------------
1295 /**
1296  * Fetches a reference to the protocol that is being used for a given session.
1297  *
1298  * @return Reference to the protocol.
1299  */
1300 //--------------------------------------------------------------------------------------------------
1302 (
1303  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1304 );
1305 
1306 
1307 //--------------------------------------------------------------------------------------------------
1308 /**
1309  * Fetches a reference to the interface that is associated with a given session.
1310  *
1311  * @return Reference to the interface.
1312  */
1313 //--------------------------------------------------------------------------------------------------
1315 (
1316  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1317 );
1318 
1319 //--------------------------------------------------------------------------------------------------
1320 /**
1321  * Fetches the user ID of the client at the far end of a given IPC session.
1322  *
1323  * @warning This function can only be called for the server-side of a session.
1324  *
1325  * @return LE_OK if successful.
1326  * LE_CLOSED if the session has closed.
1327  **/
1328 //--------------------------------------------------------------------------------------------------
1330 (
1331  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1332  uid_t* userIdPtr ///< [out] Ptr to where the result is to be stored on success.
1333 );
1334 
1335 //--------------------------------------------------------------------------------------------------
1336 /**
1337  * Fetches the user PID of the client at the far end of a given IPC session.
1338  *
1339  * @warning This function can only be called for the server-side of a session.
1340  *
1341  * @return LE_OK if successful.
1342  * LE_CLOSED if the session has closed.
1343  **/
1344 //--------------------------------------------------------------------------------------------------
1346 (
1347  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1348  pid_t* processIdPtr ///< [out] Ptr to where the result is to be stored on success.
1349 );
1350 
1351 //--------------------------------------------------------------------------------------------------
1352 /**
1353  * Fetches the user credentials of the client at the far end of a given IPC session.
1354  *
1355  * @warning This function can only be called for the server-side of a session.
1356  *
1357  * @return LE_OK if successful.
1358  * LE_CLOSED if the session has closed.
1359  **/
1360 //--------------------------------------------------------------------------------------------------
1362 (
1363  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1364  uid_t* userIdPtr, ///< [out] Ptr to where the uid is to be stored on success.
1365  pid_t* processIdPtr ///< [out] Ptr to where the pid is to be stored on success.
1366 );
1367 
1368 
1369 
1370 // =======================================
1371 // MESSAGE FUNCTIONS
1372 // =======================================
1373 
1374 //--------------------------------------------------------------------------------------------------
1375 /**
1376  * Creates a message to be sent over a given session.
1377  *
1378  * @return Message reference.
1379  *
1380  * @note
1381  * - Function never returns on failure, there's no need to check the return code.
1382  * - If you see warnings on message pools expanding, then you may be forgetting to
1383  * release the messages you have received.
1384  * - In full API this can be called by either client or server, otherwise it can only
1385  * be called by the client.
1386  */
1387 //--------------------------------------------------------------------------------------------------
1388 le_msg_MessageRef_t le_msg_CreateMsg
1389 (
1390  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1391 );
1392 
1393 
1394 //--------------------------------------------------------------------------------------------------
1395 /**
1396  * Adds to the reference count on a message object.
1397  */
1398 //--------------------------------------------------------------------------------------------------
1399 void le_msg_AddRef
1400 (
1401  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1402 );
1403 
1404 
1405 //--------------------------------------------------------------------------------------------------
1406 /**
1407  * Releases a message object, decrementing its reference count. If the reference count has reached
1408  * zero, the message object is deleted.
1409  */
1410 //--------------------------------------------------------------------------------------------------
1411 void le_msg_ReleaseMsg
1412 (
1413  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1414 );
1415 
1416 
1417 //--------------------------------------------------------------------------------------------------
1418 /**
1419  * Checks whether a message requires a response or not.
1420  *
1421  * @note This is intended for use on the server side only.
1422  *
1423  * @return
1424  * - TRUE if the message needs to be responded to using le_msg_Respond().
1425  * - FALSE if the message doesn't need to be responded to, and should be disposed of using
1426  * le_msg_ReleaseMsg() when it's no longer needed.
1427  */
1428 //--------------------------------------------------------------------------------------------------
1430 (
1431  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1432 );
1433 
1434 
1435 //--------------------------------------------------------------------------------------------------
1436 /**
1437  * Gets a pointer to the message payload memory buffer.
1438  *
1439  * @return Pointer to the payload buffer.
1440  *
1441  * @warning Be careful not to overflow this buffer.
1442  */
1443 //--------------------------------------------------------------------------------------------------
1445 (
1446  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1447 );
1448 
1449 
1450 //--------------------------------------------------------------------------------------------------
1451 /**
1452  * Gets the size, in bytes, of the message payload memory buffer.
1453  *
1454  * @return The size, in bytes.
1455  */
1456 //--------------------------------------------------------------------------------------------------
1458 (
1459  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1460 );
1461 
1462 
1463 //--------------------------------------------------------------------------------------------------
1464 /**
1465  * Sets the file descriptor to be sent with this message.
1466  *
1467  * This file descriptor will be closed when the message is sent (or when it's deleted without
1468  * being sent).
1469  *
1470  * At most one file descriptor is allowed to be sent per message.
1471  **/
1472 //--------------------------------------------------------------------------------------------------
1473 void le_msg_SetFd
1474 (
1475  le_msg_MessageRef_t msgRef, ///< [in] Reference to the message.
1476  int fd ///< [in] File descriptor.
1477 );
1478 
1479 
1480 //--------------------------------------------------------------------------------------------------
1481 /**
1482  * Fetches a received file descriptor from the message.
1483  *
1484  * @return The file descriptor, or -1 if no file descriptor was sent with this message or if the
1485  * fd was already fetched from the message.
1486  **/
1487 //--------------------------------------------------------------------------------------------------
1488 int le_msg_GetFd
1489 (
1490  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1491 );
1492 
1493 
1494 //--------------------------------------------------------------------------------------------------
1495 /**
1496  * Sends a message. No response expected.
1497  */
1498 //--------------------------------------------------------------------------------------------------
1499 void le_msg_Send
1500 (
1501  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1502 );
1503 
1504 //--------------------------------------------------------------------------------------------------
1505 /**
1506  * Gets a reference to the session to which a given message belongs.
1507  *
1508  * @return Session reference.
1509  */
1510 //--------------------------------------------------------------------------------------------------
1512 (
1513  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1514 );
1515 
1516 
1517 //--------------------------------------------------------------------------------------------------
1518 /**
1519  * Requests a response from a server by sending it a request. Doesn't block. Instead,
1520  * provides a callback function to be called when the response arrives or the transaction
1521  * terminates without a response (due to the session terminating or the server deleting the
1522  * request without responding).
1523  *
1524  * Async response not supported with mailbox API
1525  *
1526  * @note
1527  * - The thread attached to the session (i.e., thread created by the session)
1528  * will trigger the callback from its main event loop. This means if
1529  * that thread doesn't run its main event loop, it won't trigger the callback.
1530  * - Function can only be used on the client side of a session.
1531  */
1532 //--------------------------------------------------------------------------------------------------
1534 (
1535  le_msg_MessageRef_t msgRef, ///< [in] Reference to the request message.
1536  le_msg_ResponseCallback_t handlerFunc,///< [in] Function to be called when transaction done.
1537  void* contextPtr ///< [in] Opaque value to be passed to handler function.
1538 );
1539 
1540 
1541 //--------------------------------------------------------------------------------------------------
1542 /**
1543  * Requests a response from a server by sending it a request. Blocks until the response arrives
1544  * or until the transaction terminates without a response (i.e., if the session terminates or
1545  * the server deletes the request without responding).
1546  *
1547  * @return Reference to the response message, or NULL if the transaction terminated without a
1548  * response.
1549  *
1550  * @note
1551  * - To prevent deadlocks, this function can only be used on the client side of a session.
1552  * Servers can't use this function.
1553  * - To prevent race conditions, only the client thread attached to the session
1554  * (the thread that created the session) is allowed to perform a synchronous
1555  * request-response transaction.
1556  *
1557  * @warning
1558  * - The calling (client) thread will be blocked until the server responds, so no other
1559  * event handling will happen in that client thread until the response is received (or the
1560  * server dies). This function should only be used when the server is certain
1561  * to respond quickly enough to ensure that it will not cause any event response time
1562  * deadlines to be missed by the client. Consider using le_msg_RequestResponse()
1563  * instead.
1564  * - If this function is used when the client and server are in the same thread, then the
1565  * message will be discarded and NULL will be returned. This is a deadlock prevention
1566  * measure.
1567  */
1568 //--------------------------------------------------------------------------------------------------
1569 le_msg_MessageRef_t le_msg_RequestSyncResponse
1570 (
1571  le_msg_MessageRef_t msgRef ///< [in] Reference to the request message.
1572 );
1573 
1574 
1575 //--------------------------------------------------------------------------------------------------
1576 /**
1577  * Sends a response back to the client that send the request message.
1578  *
1579  * Takes a reference to the request message. Copy the response payload (if any) into the
1580  * same payload buffer that held the request payload, then call le_msg_Respond().
1581  *
1582  * The messaging system will delete the message automatically when it's finished sending
1583  * the response.
1584  *
1585  * @note Function can only be used on the server side of a session.
1586  */
1587 //--------------------------------------------------------------------------------------------------
1588 void le_msg_Respond
1589 (
1590  le_msg_MessageRef_t msgRef ///< [in] Reference to the request message.
1591 );
1592 
1593 
1594 // =======================================
1595 // INTERFACE FUNCTIONS
1596 // =======================================
1597 
1598 //--------------------------------------------------------------------------------------------------
1599 /**
1600  * Creates a service that is accessible using a protocol.
1601  *
1602  * Mailbox services should be created statically.
1603  *
1604  * @return Service reference.
1605  */
1606 //--------------------------------------------------------------------------------------------------
1607 LE_FULL_API le_msg_ServiceRef_t le_msg_CreateService
1608 (
1609  le_msg_ProtocolRef_t protocolRef, ///< [in] Reference to the protocol to be used.
1610  const char* interfaceName ///< [in] Server-side interface name.
1611 );
1612 
1613 
1614 //--------------------------------------------------------------------------------------------------
1615 /**
1616  * Initialize a mailbox service.
1617  *
1618  * This must be called before any client can connect to the service, for example in COMPONENT_INIT
1619  * before any other threads are created.
1620  */
1621 //--------------------------------------------------------------------------------------------------
1622 le_msg_ServiceRef_t le_msg_InitLocalService
1623 (
1624  le_msg_LocalService_t* servicePtr,
1625  const char* serviceNameStr,
1626  le_mem_PoolRef_t messagingPoolRef
1627 );
1628 
1629 
1630 //--------------------------------------------------------------------------------------------------
1631 /**
1632  * Deletes a service. Any open sessions will be terminated.
1633  *
1634  * @note Server-only function.
1635  */
1636 //--------------------------------------------------------------------------------------------------
1638 (
1639  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1640 );
1641 
1642 //--------------------------------------------------------------------------------------------------
1643 /**
1644  * Registers a function to be called when clients open sessions with this service.
1645  *
1646  * @note Server-only function.
1647  */
1648 //--------------------------------------------------------------------------------------------------
1650 (
1651  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1652  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1653  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1654 );
1655 
1656 //--------------------------------------------------------------------------------------------------
1657 /**
1658  * Registers a function to be called whenever one of this service's sessions is closed by
1659  * the client.
1660  *
1661  * @note Server-only function.
1662  */
1663 //--------------------------------------------------------------------------------------------------
1665 (
1666  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1667  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1668  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1669 );
1670 
1671 //--------------------------------------------------------------------------------------------------
1672 /**
1673  * Remove a function previously registered by le_msg_AddServiceOpenHandler or
1674  * le_msg_AddServiceCloseHandler.
1675  *
1676  * @note This is a server-only function.
1677  */
1678 //--------------------------------------------------------------------------------------------------
1680 (
1681  le_msg_SessionEventHandlerRef_t handlerRef ///< [in] Reference to a previously call of
1682  /// le_msg_AddServiceCloseHandler()
1683 );
1684 
1685 //--------------------------------------------------------------------------------------------------
1686 /**
1687  * Registers a function to be called when messages are received from clients via sessions
1688  * that they have open with this service.
1689  *
1690  * @note Server-only function.
1691  */
1692 //--------------------------------------------------------------------------------------------------
1694 (
1695  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1696  le_msg_ReceiveHandler_t handlerFunc,///< [in] Handler function.
1697  void* contextPtr ///< [in] Opaque pointer value to pass to the handler.
1698 );
1699 
1700 
1701 //--------------------------------------------------------------------------------------------------
1702 /**
1703  * Associates an opaque context value (void pointer) with a given service that can be retrieved
1704  * later using le_msg_GetServiceContextPtr().
1705  *
1706  * @note Server-only function.
1707  */
1708 //--------------------------------------------------------------------------------------------------
1710 (
1711  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1712 
1713  void* contextPtr ///< [in] Opaque value to be returned by
1714  /// le_msg_GetServiceContextPtr().
1715 );
1716 
1717 
1718 //--------------------------------------------------------------------------------------------------
1719 /**
1720  * Fetches the opaque context value (void pointer) associated with a specified service using
1721  * le_msg_SetServiceContextPtr().
1722  *
1723  * @return Context pointer value, or NULL if le_msg_SetServiceContextPtr() was never called
1724  * for this service.
1725  *
1726  * @note Server-only function.
1727  */
1728 //--------------------------------------------------------------------------------------------------
1730 (
1731  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1732 );
1733 
1734 
1735 //--------------------------------------------------------------------------------------------------
1736 /**
1737  * Makes a given service available for clients to find.
1738  *
1739  * @note Server-only function.
1740  */
1741 //--------------------------------------------------------------------------------------------------
1743 (
1744  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1745 );
1746 
1747 
1748 //--------------------------------------------------------------------------------------------------
1749 /**
1750  * Makes a specified service unavailable for clients to find without terminating any ongoing
1751  * sessions.
1752  *
1753  * @note Server-only function.
1754  */
1755 //--------------------------------------------------------------------------------------------------
1757 (
1758  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1759 );
1760 
1761 
1762 //--------------------------------------------------------------------------------------------------
1763 /**
1764  * Fetches a pointer to the name of an interface.
1765  *
1766  * @return Pointer to a null-terminated string.
1767  *
1768  * @warning Pointer returned will remain valid only until the interface is deleted.
1769  */
1770 //--------------------------------------------------------------------------------------------------
1772 (
1773  le_msg_InterfaceRef_t interfaceRef ///< [in] Reference to the interface.
1774 );
1775 
1776 
1777 //--------------------------------------------------------------------------------------------------
1778 /**
1779  * Fetches a reference to the protocol supported by a specified interface.
1780  *
1781  * @return Protocol reference.
1782  */
1783 //--------------------------------------------------------------------------------------------------
1785 (
1786  le_msg_InterfaceRef_t interfaceRef ///< [in] Reference to the interface.
1787 );
1788 
1789 
1790 //--------------------------------------------------------------------------------------------------
1791 /**
1792  * Check if the calling thread is currently running a Service's message receive handler;
1793  * if so, return a reference to the message object being handled.
1794  *
1795  * @return Reference to the message being handled, or NULL if no Service message receive handler
1796  * is currently running.
1797  **/
1798 //--------------------------------------------------------------------------------------------------
1799 le_msg_MessageRef_t le_msg_GetServiceRxMsg
1800 (
1801  void
1802 );
1803 
1804 
1805 //--------------------------------------------------------------------------------------------------
1806 /**
1807  * Logs an error message (at EMERGENCY level) and:
1808  * - if the caller is running a server-side IPC function, kills the connection to the client
1809  * and returns.
1810  * - if the caller is not running a server-side IPC function, kills the caller (doesn't return).
1811  **/
1812 //--------------------------------------------------------------------------------------------------
1813 #define LE_KILL_CLIENT(formatString, ...) \
1814 { \
1815  le_msg_MessageRef_t msgRef = le_msg_GetServiceRxMsg(); \
1816  LE_FATAL_IF(msgRef == NULL, formatString, ##__VA_ARGS__); \
1817  LE_EMERG(formatString, ##__VA_ARGS__); \
1818  le_msg_CloseSession(le_msg_GetSession(msgRef)); \
1819 }
1820 
1821 #endif // LEGATO_MESSAGING_INCLUDE_GUARD
le_msg_MessageRef_t le_msg_GetServiceRxMsg(void)
struct le_thread * le_thread_Ref_t
Definition: le_thread.h:178
void le_msg_AddRef(le_msg_MessageRef_t msgRef)
bool le_msg_NeedsResponse(le_msg_MessageRef_t msgRef)
LE_FULL_API le_msg_InterfaceRef_t le_msg_GetSessionInterface(le_msg_SessionRef_t sessionRef)
void * contextPtr
Opaque value to be passed to handler function.
Definition: le_messaging.h:1009
void le_msg_ReleaseMsg(le_msg_MessageRef_t msgRef)
le_result_t le_msg_GetClientUserCreds(le_msg_SessionRef_t sessionRef, uid_t *userIdPtr, pid_t *processIdPtr)
le_result_t
Definition: le_basics.h:35
struct le_sem_t * le_sem_Ref_t
Definition: le_semaphore.h:68
LE_FULL_API void le_msg_DeleteService(le_msg_ServiceRef_t serviceRef)
Definition: le_messaging.h:966
void le_msg_SetServiceRecvHandler(le_msg_ServiceRef_t serviceRef, le_msg_ReceiveHandler_t handlerFunc, void *contextPtr)
le_msg_SessionRef_t le_msg_CreateLocalSession(le_msg_LocalService_t *servicePtr)
void(* le_msg_SessionEventHandler_t)(le_msg_SessionRef_t sessionRef, void *contextPtr)
Definition: le_messaging.h:888
le_result_t le_msg_TryOpenSessionSync(le_msg_SessionRef_t sessionRef)
void le_msg_AdvertiseService(le_msg_ServiceRef_t serviceRef)
Definition: le_messaging.h:940
void le_msg_DeleteSession(le_msg_SessionRef_t sessionRef)
void le_msg_SetSessionRecvHandler(le_msg_SessionRef_t sessionRef, le_msg_ReceiveHandler_t handlerFunc, void *contextPtr)
void * le_msg_GetPayloadPtr(le_msg_MessageRef_t msgRef)
void le_msg_GetSessionCloseHandler(le_msg_SessionRef_t sessionRef, le_msg_SessionEventHandler_t *handlerFunc, void **contextPtr)
le_msg_ServiceRef_t le_msg_InitLocalService(le_msg_LocalService_t *servicePtr, const char *serviceNameStr, le_mem_PoolRef_t messagingPoolRef)
LE_FULL_API void le_msg_SetServiceContextPtr(le_msg_ServiceRef_t serviceRef, void *contextPtr)
LE_FULL_API le_msg_SessionEventHandlerRef_t le_msg_AddServiceOpenHandler(le_msg_ServiceRef_t serviceRef, le_msg_SessionEventHandler_t handlerFunc, void *contextPtr)
struct le_msg_ClientInterface * le_msg_ClientInterfaceRef_t
Definition: le_messaging.h:851
Definition: le_messaging.h:1002
size_t le_msg_GetMaxPayloadSize(le_msg_MessageRef_t msgRef)
le_msg_SessionRef_t le_msg_GetSession(le_msg_MessageRef_t msgRef)
LE_FULL_API le_msg_ProtocolRef_t le_msg_GetSessionProtocol(le_msg_SessionRef_t sessionRef)
void le_msg_SetFd(le_msg_MessageRef_t msgRef, int fd)
void(* le_msg_ReceiveHandler_t)(le_msg_MessageRef_t msgRef, void *contextPtr)
Definition: le_messaging.h:907
LE_FULL_API void * le_msg_GetSessionContextPtr(le_msg_SessionRef_t sessionRef)
void le_msg_Send(le_msg_MessageRef_t msgRef)
struct le_msg_SessionEventHandler * le_msg_SessionEventHandlerRef_t
Definition: le_messaging.h:873
LE_FULL_API void le_msg_SetSessionContextPtr(le_msg_SessionRef_t sessionRef, void *contextPtr)
le_thread_Ref_t thread
Thread on which receive should be processes.
Definition: le_messaging.h:968
void le_msg_CloseSession(le_msg_SessionRef_t sessionRef)
struct le_mem_Pool * le_mem_PoolRef_t
Definition: le_mem.h:540
bool serviceReady
Indicate if service is ready.
Definition: le_messaging.h:990
le_mem_PoolRef_t messagePool
Pool for messages on this service.
Definition: le_messaging.h:993
le_msg_ReceiveHandler_t handler
Handler function which should be called on thread.
Definition: le_messaging.h:969
int fd
File descriptor sent with message (via Get/SetFd)
Definition: le_messaging.h:1005
LE_FULL_API le_msg_SessionRef_t le_msg_CreateSession(le_msg_ProtocolRef_t protocolRef, const char *interfaceName)
LE_FULL_API const char * le_msg_GetInterfaceName(le_msg_InterfaceRef_t interfaceRef)
le_msg_MessageRef_t le_msg_CreateMsg(le_msg_SessionRef_t sessionRef)
int le_msg_GetFd(le_msg_MessageRef_t msgRef)
struct le_msg_Session * le_msg_SessionRef_t
Definition: le_messaging.h:858
void le_msg_RequestResponse(le_msg_MessageRef_t msgRef, le_msg_ResponseCallback_t handlerFunc, void *contextPtr)
Definition: le_messaging.h:984
le_result_t le_msg_GetClientProcessId(le_msg_SessionRef_t sessionRef, pid_t *processIdPtr)
void le_msg_OpenSession(le_msg_SessionRef_t sessionRef, le_msg_SessionEventHandler_t callbackFunc, void *contextPtr)
le_msg_LocalReceiver_t receiver
Server destination.
Definition: le_messaging.h:992
LE_FULL_API void * le_msg_GetServiceContextPtr(le_msg_ServiceRef_t serviceRef)
le_msg_ResponseCallback_t completionCallback
Function to be called when transaction done.
Definition: le_messaging.h:1008
void * contextPtr
Context pointer to pass to the handler.
Definition: le_messaging.h:970
#define LE_FULL_API
Definition: le_basics.h:288
void le_msg_Respond(le_msg_MessageRef_t msgRef)
LE_FULL_API void le_msg_HideService(le_msg_ServiceRef_t serviceRef)
LE_FULL_API le_msg_ProtocolRef_t le_msg_GetProtocolRef(const char *protocolId, size_t largestMsgSize)
LE_FULL_API void le_msg_SetSessionCloseHandler(le_msg_SessionRef_t sessionRef, le_msg_SessionEventHandler_t handlerFunc, void *contextPtr)
struct le_msg_Protocol * le_msg_ProtocolRef_t
Definition: le_messaging.h:830
void(* le_msg_ResponseCallback_t)(le_msg_MessageRef_t msgRef, void *contextPtr)
Definition: le_messaging.h:927
le_result_t le_msg_GetClientUserId(le_msg_SessionRef_t sessionRef, uid_t *userIdPtr)
LE_FULL_API le_msg_ProtocolRef_t le_msg_GetInterfaceProtocol(le_msg_InterfaceRef_t interfaceRef)
le_msg_MessageRef_t le_msg_RequestSyncResponse(le_msg_MessageRef_t msgRef)
LE_FULL_API void le_msg_RemoveServiceHandler(le_msg_SessionEventHandlerRef_t handlerRef)
le_sem_Ref_t responseReady
Semaphore which will be set when response is ready.
Definition: le_messaging.h:1006
struct le_msg_Interface * le_msg_InterfaceRef_t
Definition: le_messaging.h:837
void le_msg_OpenSessionSync(le_msg_SessionRef_t sessionRef)
LE_FULL_API le_msg_ServiceRef_t le_msg_CreateService(le_msg_ProtocolRef_t protocolRef, const char *interfaceName)
LE_FULL_API const char * le_msg_GetProtocolIdStr(le_msg_ProtocolRef_t protocolRef)
le_msg_SessionRef_t sessionRef
Session for this message.
Definition: le_messaging.h:957
LE_FULL_API size_t le_msg_GetProtocolMaxMsgSize(le_msg_ProtocolRef_t protocolRef)
Definition: le_messaging.h:955
le_msg_SessionEventHandlerRef_t le_msg_AddServiceCloseHandler(le_msg_ServiceRef_t serviceRef, le_msg_SessionEventHandler_t handlerFunc, void *contextPtr)
bool needsResponse
True if message needs a response.
Definition: le_messaging.h:1007