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 #include "le_semaphore.h"
822 
823 // =======================================
824 // DATA TYPES
825 // =======================================
826 
827 //--------------------------------------------------------------------------------------------------
828 /**
829  * Reference to a protocol.
830  */
831 //--------------------------------------------------------------------------------------------------
832 typedef struct le_msg_Protocol* le_msg_ProtocolRef_t;
833 
834 //--------------------------------------------------------------------------------------------------
835 /**
836  * Reference to an interface's service instance.
837  */
838 //--------------------------------------------------------------------------------------------------
839 typedef struct le_msg_Interface* le_msg_InterfaceRef_t;
840 
841 //--------------------------------------------------------------------------------------------------
842 /**
843  * Reference to a server's service instance.
844  */
845 //--------------------------------------------------------------------------------------------------
846 typedef struct le_msg_Service* le_msg_ServiceRef_t;
847 
848 //--------------------------------------------------------------------------------------------------
849 /**
850  * Reference to a client's service instance.
851  */
852 //--------------------------------------------------------------------------------------------------
853 typedef struct le_msg_ClientInterface* le_msg_ClientInterfaceRef_t;
854 
855 //--------------------------------------------------------------------------------------------------
856 /**
857  * Reference to a client-server session.
858  */
859 //--------------------------------------------------------------------------------------------------
860 typedef struct le_msg_Session* le_msg_SessionRef_t;
861 
862 //--------------------------------------------------------------------------------------------------
863 /**
864  * Reference to a message.
865  */
866 //--------------------------------------------------------------------------------------------------
867 typedef struct le_msg_Message* le_msg_MessageRef_t;
868 
869 //--------------------------------------------------------------------------------------------------
870 /**
871  * Reference to a handler (call-back) function for events that can occur on a service (such as
872  * opening and closing of sessions and receipt of messages).
873  */
874 //--------------------------------------------------------------------------------------------------
875 typedef struct le_msg_SessionEventHandler* le_msg_SessionEventHandlerRef_t;
876 
877 //--------------------------------------------------------------------------------------------------
878 /**
879  * Handler function prototype for handlers that take session references as their arguments.
880  *
881  * See le_msg_SetSessionCloseHandler(), le_msg_AddServiceOpenHandler(), and
882  * le_msg_AddServiceCloseHandler().
883  *
884  * @param sessionRef [in] Reference to the session that experienced the event.
885  *
886  * @param contextPtr [in] Opaque contextPtr value provided when the handler was registered.
887  */
888 //--------------------------------------------------------------------------------------------------
889 typedef void (* le_msg_SessionEventHandler_t)
890 (
891  le_msg_SessionRef_t sessionRef,
892  void* contextPtr
893 );
894 
895 
896 //--------------------------------------------------------------------------------------------------
897 /**
898  * Receive handler function prototype.
899  *
900  * See le_msg_SetSessionRecvHandler() and le_msg_SetServiceRecvHandler().
901  *
902  * @param msgRef [in] Reference to the received message. Don't forget to release this using
903  * le_msg_ReleaseMsg() when you're finished with it.
904  *
905  * @param contextPtr [in] Opaque contextPtr value provided when the handler was registered.
906  */
907 //--------------------------------------------------------------------------------------------------
908 typedef void (* le_msg_ReceiveHandler_t)
909 (
910  le_msg_MessageRef_t msgRef,
911  void* contextPtr
912 );
913 
914 
915 //--------------------------------------------------------------------------------------------------
916 /**
917  * Asynchronous response callback function prototype.
918  *
919  * See le_msg_RequestResponse().
920  *
921  * @param msgRef [in] Reference to the received response message, or NULL if the transaction
922  * failed and no response was received. If not NULL, don't forget to
923  * release it by calling le_msg_ReleaseMsg() when you're finished with it.
924  *
925  * @param contextPtr [in] Opaque contextPtr value passed to le_msg_RequestResponse().
926  */
927 //--------------------------------------------------------------------------------------------------
928 typedef void (* le_msg_ResponseCallback_t)
929 (
930  le_msg_MessageRef_t msgRef,
931  void* contextPtr
932 );
933 
934 
935 
936 
937 //--------------------------------------------------------------------------------------------------
938 /**
939  * Generic service object. Used internally as part of low-level messaging implementation.
940  */
941 //--------------------------------------------------------------------------------------------------
943 {
944  enum
945  {
946  LE_MSG_SERVICE_UNIX_SOCKET,
947  LE_MSG_SERVICE_LOCAL
948  } type;
949 };
950 
951 
952 //--------------------------------------------------------------------------------------------------
953 /**
954  * Generic message object. Holds a pointer to the session the message is associated with.
955  */
956 //--------------------------------------------------------------------------------------------------
958 {
959  le_msg_SessionRef_t sessionRef; ///< Session for this message
960 };
961 
962 
963 //--------------------------------------------------------------------------------------------------
964 /**
965  * Message handler receiver for local messages
966  */
967 //--------------------------------------------------------------------------------------------------
968 typedef struct
969 {
970  le_thread_Ref_t thread; ///< Thread on which receive should be processes.
971  le_msg_ReceiveHandler_t handler; ///< Handler function which should be called on thread
972  void* contextPtr; ///< Context pointer to pass to the handler
974 
975 
976 //--------------------------------------------------------------------------------------------------
977 /**
978  * Local service object.
979  *
980  * Create an instance of this object for each local service used by your program.
981  *
982  * @note This structure should never be accessed directly; instead access through le_msg_...()
983  * functions.
984  */
985 //--------------------------------------------------------------------------------------------------
986 typedef struct
987 {
988  struct le_msg_Service service; ///< Service
989 #if LE_CONFIG_CUSTOM_OS && defined(LE_MSG_SERVICE_READY_FLAG)
990  LE_MSG_SERVICE_READY_FLAG; ///< Indicate if service is ready in an OS-specific manner
991 #else
992  bool serviceReady; ///< Indicate if service is ready
993 #endif
994  le_msg_LocalReceiver_t receiver; ///< Server destination
995  le_mem_PoolRef_t messagePool; ///< Pool for messages on this service
997 
998 
999 //--------------------------------------------------------------------------------------------------
1000 /**
1001  * Message that's sent over a queue transport.
1002  */
1003 //--------------------------------------------------------------------------------------------------
1004 typedef struct le_msg_LocalMessage
1005 {
1006  struct le_msg_Message message; ///< Pointer to base message
1007  int fd; ///< File descriptor sent with message (via Get/SetFd)
1008  le_sem_Ref_t responseReady; ///< Semaphore which will be set when response is ready
1009  bool needsResponse; ///< True if message needs a response
1010  le_msg_ResponseCallback_t completionCallback; ///< Function to be called when transaction done.
1011  void* contextPtr; ///< Opaque value to be passed to handler function.
1012  uint8_t data[] __attribute__((aligned)); ///< Start of message data.
1013  ///< Align so any type of data can be stored inside.
1015 
1016 
1017 //--------------------------------------------------------------------------------------------------
1018 /**
1019  * Size of local message header (needs to be added to size of message in local message pools).
1020  */
1021 //--------------------------------------------------------------------------------------------------
1022 #define LE_MSG_LOCAL_HEADER_SIZE sizeof(le_msg_LocalMessage_t)
1023 
1024 
1025 // =======================================
1026 // PROTOCOL FUNCTIONS
1027 // =======================================
1028 
1029 //--------------------------------------------------------------------------------------------------
1030 /**
1031  * Gets a reference to refer to a particular version of a particular protocol.
1032  *
1033  * @return Protocol reference.
1034  */
1035 //--------------------------------------------------------------------------------------------------
1037 (
1038  const char* protocolId, ///< [in] String uniquely identifying the the protocol and version.
1039  size_t largestMsgSize ///< [in] Size (in bytes) of the largest message in the protocol.
1040 );
1041 
1042 
1043 //--------------------------------------------------------------------------------------------------
1044 /**
1045  * Gets the unique identifier string of the protocol.
1046  *
1047  * @return Pointer to the protocol identifier (null-terminated, UTF-8 string).
1048  */
1049 //--------------------------------------------------------------------------------------------------
1051 (
1052  le_msg_ProtocolRef_t protocolRef ///< [in] Reference to the protocol.
1053 );
1054 
1055 
1056 //--------------------------------------------------------------------------------------------------
1057 /**
1058  * Gets the protocol's maximum message size.
1059  *
1060  * @return The size, in bytes.
1061  */
1062 //--------------------------------------------------------------------------------------------------
1064 (
1065  le_msg_ProtocolRef_t protocolRef ///< [in] Reference to the protocol.
1066 );
1067 
1068 
1069 // =======================================
1070 // SESSION FUNCTIONS
1071 // =======================================
1072 
1073 //--------------------------------------------------------------------------------------------------
1074 /**
1075  * Creates a session that will make use of a protocol to talk to a service on a given client
1076  * interface.
1077  *
1078  * @note This doesn't actually attempt to open the session. It just creates the session
1079  * object, allowing the client the opportunity to register handlers for the session
1080  * before attempting to open it using le_msg_OpenSession().
1081  *
1082  * @return Session reference.
1083  */
1084 //--------------------------------------------------------------------------------------------------
1086 (
1087  le_msg_ProtocolRef_t protocolRef, ///< [in] Reference to the protocol to be used.
1088  const char* interfaceName ///< [in] Name of the client-side interface.
1089 );
1090 
1091 
1092 //--------------------------------------------------------------------------------------------------
1093 /**
1094  * Create a session that will always use message boxes to talk to a service in the same process
1095  * space.
1096  *
1097  * @return Session reference.
1098  */
1099 //--------------------------------------------------------------------------------------------------
1101 (
1102  le_msg_LocalService_t* servicePtr ///< [in] Reference to the service.
1103 );
1104 
1105 
1106 //--------------------------------------------------------------------------------------------------
1107 /**
1108  * Sets an opaque context value (void pointer) that can be retrieved from that session later using
1109  * le_msg_GetSessionContextPtr().
1110  */
1111 //--------------------------------------------------------------------------------------------------
1113 (
1114  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1115 
1116  void* contextPtr ///< [in] Opaque value to be returned by
1117  /// le_msg_GetSessionContextPtr().
1118 );
1119 
1120 //--------------------------------------------------------------------------------------------------
1121 /**
1122  * Fetches the opaque context value (void pointer) that was set earlier using
1123  * le_msg_SetSessionContextPtr().
1124  *
1125  * @return Context Ptr value passed into le_msg_SetSessionContextPtr(), or NULL if
1126  * le_msg_SetSessionContextPtr() has not been called for this session yet.
1127  */
1128 //--------------------------------------------------------------------------------------------------
1130 (
1131  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1132 );
1133 
1134 
1135 //--------------------------------------------------------------------------------------------------
1136 /**
1137  * Deletes a session. This will end the session and free up any resources associated
1138  * with it. Any pending request-response transactions in this session will be terminated.
1139  * If the far end has registered a session close handler callback, it will be called.
1140  *
1141  * @note Function is only used by clients. On the server side, sessions are automatically
1142  * deleted when they close.
1143  */
1144 //--------------------------------------------------------------------------------------------------
1146 (
1147  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1148 );
1149 
1150 
1151 //--------------------------------------------------------------------------------------------------
1152 /**
1153  * Sets the receive handler callback function to be called when a non-response message arrives
1154  * on this session.
1155  *
1156  * The handler function will be called by the Legato event loop of the thread that created
1157  * the session.
1158  *
1159  * @note This is a client-only function. Servers are expected to use
1160  * le_msg_SetServiceRecvHandler() instead.
1161  */
1162 //--------------------------------------------------------------------------------------------------
1164 (
1165  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1166  le_msg_ReceiveHandler_t handlerFunc,///< [in] Handler function.
1167  void* contextPtr ///< [in] Opaque pointer value to pass to the handler.
1168 );
1169 
1170 
1171 //--------------------------------------------------------------------------------------------------
1172 /**
1173  * Sets the handler callback function to be called when the session is closed from the other
1174  * end. A local termination of the session will not trigger this callback.
1175  *
1176  * The handler function will be called by the Legato event loop of the thread that created
1177  * the session.
1178  *
1179  * @note
1180  * - If this isn't set on the client side, the framework assumes the client is not designed
1181  * to recover from the server terminating the session, and the client process will terminate
1182  * if the session is terminated by the server.
1183  * - This is a client-only function. Servers are expected to use le_msg_AddServiceCloseHandler()
1184  * instead.
1185  */
1186 //--------------------------------------------------------------------------------------------------
1188 (
1189  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1190  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1191  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1192 );
1193 
1194 
1195 //--------------------------------------------------------------------------------------------------
1196 /**
1197  * Gets the handler callback function to be called when the session is closed from the other
1198  * end.
1199  */
1200 //--------------------------------------------------------------------------------------------------
1202 (
1203  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1204  le_msg_SessionEventHandler_t* handlerFunc,///< [out] Handler function.
1205  void** contextPtr ///< [out] Opaque pointer value to pass to
1206  ///< the handler.
1207 );
1208 
1209 
1210 //--------------------------------------------------------------------------------------------------
1211 /**
1212  * Opens a session with a service, providing a function to be called-back when the session is
1213  * open.
1214  *
1215  * Asynchronous sessions are not supported by mailbox sessions.
1216  *
1217  * @note Only clients open sessions. Servers must patiently wait for clients to open sessions
1218  * with them.
1219  *
1220  * @warning If the client and server don't agree on the maximum message size for the protocol,
1221  * a fatal error will be logged and the client process will be killed.
1222  */
1223 //--------------------------------------------------------------------------------------------------
1224 void le_msg_OpenSession
1225 (
1226  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1227  le_msg_SessionEventHandler_t callbackFunc, ///< [in] Function to be called when open.
1228  /// NULL if no notification is needed.
1229  void* contextPtr ///< [in] Opaque value to pass to the callback.
1230 );
1231 
1232 
1233 //--------------------------------------------------------------------------------------------------
1234 /**
1235  * Synchronously open a session with a service. Blocks until the session is open.
1236  *
1237  * This function logs a fatal error and terminates the calling process if unsuccessful.
1238  *
1239  * @note Only clients open sessions. Servers must patiently wait for clients to open sessions
1240  * with them.
1241  *
1242  * @warning If the client and server do not agree on the maximum message size for the protocol,
1243  * a fatal error will be logged and the client process will be killed.
1244  */
1245 //--------------------------------------------------------------------------------------------------
1247 (
1248  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1249 );
1250 
1251 
1252 //--------------------------------------------------------------------------------------------------
1253 /**
1254  * Synchronously open a session with a service. Does not wait for the session to become available
1255  * if not available..
1256  *
1257  * le_msg_TryOpenSessionSync() differs from le_msg_OpenSessionSync() in that
1258  * le_msg_TryOpenSessionSync() will not wait for a server session to become available if it's
1259  * not already available at the time of the call. That is, if the client's interface is not
1260  * bound to any service, or if the service that it's bound to is not currently advertised
1261  * by the server, then le_msg_TryOpenSessionSync() will return an error code, while
1262  * le_msg_OpenSessionSync() will wait until the binding is created or the server advertises
1263  * the service (or both).
1264  *
1265  * @return
1266  * - LE_OK if the session was successfully opened.
1267  * - LE_NOT_FOUND if the server is not currently offering the service to which the client is bound.
1268  * - LE_NOT_PERMITTED if the client interface is not bound to any service (doesn't have a binding).
1269  * - LE_COMM_ERROR if the Service Directory cannot be reached.
1270  *
1271  * @note Only clients open sessions. Servers' must patiently wait for clients to open sessions
1272  * with them.
1273  *
1274  * @warning If the client and server do not agree on the maximum message size for the protocol,
1275  * a fatal error will be logged and the client process will be killed.
1276  */
1277 //--------------------------------------------------------------------------------------------------
1279 (
1280  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1281 );
1282 
1283 
1284 //--------------------------------------------------------------------------------------------------
1285 /**
1286  * Terminates a session.
1287  */
1288 //--------------------------------------------------------------------------------------------------
1290 (
1291  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1292 );
1293 
1294 
1295 //--------------------------------------------------------------------------------------------------
1296 /**
1297  * Terminates a session, already having acquired the Mutex lock.
1298  */
1299 //--------------------------------------------------------------------------------------------------
1301 (
1302  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1303 );
1304 
1305 
1306 //--------------------------------------------------------------------------------------------------
1307 /**
1308  * Fetches a reference to the protocol that is being used for a given session.
1309  *
1310  * @return Reference to the protocol.
1311  */
1312 //--------------------------------------------------------------------------------------------------
1314 (
1315  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1316 );
1317 
1318 
1319 //--------------------------------------------------------------------------------------------------
1320 /**
1321  * Fetches a reference to the interface that is associated with a given session.
1322  *
1323  * @return Reference to the interface.
1324  */
1325 //--------------------------------------------------------------------------------------------------
1327 (
1328  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1329 );
1330 
1331 //--------------------------------------------------------------------------------------------------
1332 /**
1333  * Fetches the user ID of the client at the far end of a given IPC session.
1334  *
1335  * @warning This function can only be called for the server-side of a session.
1336  *
1337  * @return LE_OK if successful.
1338  * LE_CLOSED if the session has closed.
1339  **/
1340 //--------------------------------------------------------------------------------------------------
1342 (
1343  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1344  uid_t* userIdPtr ///< [out] Ptr to where the result is to be stored on success.
1345 );
1346 
1347 //--------------------------------------------------------------------------------------------------
1348 /**
1349  * Fetches the user PID of the client at the far end of a given IPC session.
1350  *
1351  * @warning This function can only be called for the server-side of a session.
1352  *
1353  * @return LE_OK if successful.
1354  * LE_CLOSED if the session has closed.
1355  **/
1356 //--------------------------------------------------------------------------------------------------
1358 (
1359  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1360  pid_t* processIdPtr ///< [out] Ptr to where the result is to be stored on success.
1361 );
1362 
1363 //--------------------------------------------------------------------------------------------------
1364 /**
1365  * Fetches the user credentials of the client at the far end of a given IPC session.
1366  *
1367  * @warning This function can only be called for the server-side of a session.
1368  *
1369  * @return LE_OK if successful.
1370  * LE_CLOSED if the session has closed.
1371  **/
1372 //--------------------------------------------------------------------------------------------------
1374 (
1375  le_msg_SessionRef_t sessionRef, ///< [in] Reference to the session.
1376  uid_t* userIdPtr, ///< [out] Ptr to where the uid is to be stored on success.
1377  pid_t* processIdPtr ///< [out] Ptr to where the pid is to be stored on success.
1378 );
1379 
1380 
1381 
1382 // =======================================
1383 // MESSAGE FUNCTIONS
1384 // =======================================
1385 
1386 //--------------------------------------------------------------------------------------------------
1387 /**
1388  * Creates a message to be sent over a given session.
1389  *
1390  * @return Message reference.
1391  *
1392  * @note
1393  * - Function never returns on failure, there's no need to check the return code.
1394  * - If you see warnings on message pools expanding, then you may be forgetting to
1395  * release the messages you have received.
1396  * - In full API this can be called by either client or server, otherwise it can only
1397  * be called by the client.
1398  */
1399 //--------------------------------------------------------------------------------------------------
1400 le_msg_MessageRef_t le_msg_CreateMsg
1401 (
1402  le_msg_SessionRef_t sessionRef ///< [in] Reference to the session.
1403 );
1404 
1405 
1406 //--------------------------------------------------------------------------------------------------
1407 /**
1408  * Adds to the reference count on a message object.
1409  */
1410 //--------------------------------------------------------------------------------------------------
1411 void le_msg_AddRef
1412 (
1413  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1414 );
1415 
1416 
1417 //--------------------------------------------------------------------------------------------------
1418 /**
1419  * Releases a message object, decrementing its reference count. If the reference count has reached
1420  * zero, the message object is deleted.
1421  */
1422 //--------------------------------------------------------------------------------------------------
1423 void le_msg_ReleaseMsg
1424 (
1425  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1426 );
1427 
1428 
1429 //--------------------------------------------------------------------------------------------------
1430 /**
1431  * Checks whether a message requires a response or not.
1432  *
1433  * @note This is intended for use on the server side only.
1434  *
1435  * @return
1436  * - TRUE if the message needs to be responded to using le_msg_Respond().
1437  * - FALSE if the message doesn't need to be responded to, and should be disposed of using
1438  * le_msg_ReleaseMsg() when it's no longer needed.
1439  */
1440 //--------------------------------------------------------------------------------------------------
1442 (
1443  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1444 );
1445 
1446 
1447 //--------------------------------------------------------------------------------------------------
1448 /**
1449  * Gets a pointer to the message payload memory buffer.
1450  *
1451  * @return Pointer to the payload buffer.
1452  *
1453  * @warning Be careful not to overflow this buffer.
1454  */
1455 //--------------------------------------------------------------------------------------------------
1457 (
1458  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1459 );
1460 
1461 
1462 //--------------------------------------------------------------------------------------------------
1463 /**
1464  * Gets the size, in bytes, of the message payload memory buffer.
1465  *
1466  * @return The size, in bytes.
1467  */
1468 //--------------------------------------------------------------------------------------------------
1470 (
1471  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1472 );
1473 
1474 
1475 //--------------------------------------------------------------------------------------------------
1476 /**
1477  * Sets the file descriptor to be sent with this message.
1478  *
1479  * This file descriptor will be closed when the message is sent (or when it's deleted without
1480  * being sent).
1481  *
1482  * At most one file descriptor is allowed to be sent per message.
1483  **/
1484 //--------------------------------------------------------------------------------------------------
1485 void le_msg_SetFd
1486 (
1487  le_msg_MessageRef_t msgRef, ///< [in] Reference to the message.
1488  int fd ///< [in] File descriptor.
1489 );
1490 
1491 
1492 //--------------------------------------------------------------------------------------------------
1493 /**
1494  * Fetches a received file descriptor from the message.
1495  *
1496  * @return The file descriptor, or -1 if no file descriptor was sent with this message or if the
1497  * fd was already fetched from the message.
1498  **/
1499 //--------------------------------------------------------------------------------------------------
1500 int le_msg_GetFd
1501 (
1502  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1503 );
1504 
1505 
1506 //--------------------------------------------------------------------------------------------------
1507 /**
1508  * Sends a message. No response expected.
1509  */
1510 //--------------------------------------------------------------------------------------------------
1511 void le_msg_Send
1512 (
1513  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1514 );
1515 
1516 //--------------------------------------------------------------------------------------------------
1517 /**
1518  * Gets a reference to the session to which a given message belongs.
1519  *
1520  * @return Session reference.
1521  */
1522 //--------------------------------------------------------------------------------------------------
1524 (
1525  le_msg_MessageRef_t msgRef ///< [in] Reference to the message.
1526 );
1527 
1528 
1529 //--------------------------------------------------------------------------------------------------
1530 /**
1531  * Requests a response from a server by sending it a request. Doesn't block. Instead,
1532  * provides a callback function to be called when the response arrives or the transaction
1533  * terminates without a response (due to the session terminating or the server deleting the
1534  * request without responding).
1535  *
1536  * Async response not supported with mailbox API
1537  *
1538  * @note
1539  * - The thread attached to the session (i.e., thread created by the session)
1540  * will trigger the callback from its main event loop. This means if
1541  * that thread doesn't run its main event loop, it won't trigger the callback.
1542  * - Function can only be used on the client side of a session.
1543  */
1544 //--------------------------------------------------------------------------------------------------
1546 (
1547  le_msg_MessageRef_t msgRef, ///< [in] Reference to the request message.
1548  le_msg_ResponseCallback_t handlerFunc,///< [in] Function to be called when transaction done.
1549  void* contextPtr ///< [in] Opaque value to be passed to handler function.
1550 );
1551 
1552 
1553 //--------------------------------------------------------------------------------------------------
1554 /**
1555  * Requests a response from a server by sending it a request. Blocks until the response arrives
1556  * or until the transaction terminates without a response (i.e., if the session terminates or
1557  * the server deletes the request without responding).
1558  *
1559  * @return Reference to the response message, or NULL if the transaction terminated without a
1560  * response.
1561  *
1562  * @note
1563  * - To prevent deadlocks, this function can only be used on the client side of a session.
1564  * Servers can't use this function.
1565  * - To prevent race conditions, only the client thread attached to the session
1566  * (the thread that created the session) is allowed to perform a synchronous
1567  * request-response transaction.
1568  *
1569  * @warning
1570  * - The calling (client) thread will be blocked until the server responds, so no other
1571  * event handling will happen in that client thread until the response is received (or the
1572  * server dies). This function should only be used when the server is certain
1573  * to respond quickly enough to ensure that it will not cause any event response time
1574  * deadlines to be missed by the client. Consider using le_msg_RequestResponse()
1575  * instead.
1576  * - If this function is used when the client and server are in the same thread, then the
1577  * message will be discarded and NULL will be returned. This is a deadlock prevention
1578  * measure.
1579  */
1580 //--------------------------------------------------------------------------------------------------
1581 le_msg_MessageRef_t le_msg_RequestSyncResponse
1582 (
1583  le_msg_MessageRef_t msgRef ///< [in] Reference to the request message.
1584 );
1585 
1586 
1587 //--------------------------------------------------------------------------------------------------
1588 /**
1589  * Sends a response back to the client that send the request message.
1590  *
1591  * Takes a reference to the request message. Copy the response payload (if any) into the
1592  * same payload buffer that held the request payload, then call le_msg_Respond().
1593  *
1594  * The messaging system will delete the message automatically when it's finished sending
1595  * the response.
1596  *
1597  * @note Function can only be used on the server side of a session.
1598  */
1599 //--------------------------------------------------------------------------------------------------
1600 void le_msg_Respond
1601 (
1602  le_msg_MessageRef_t msgRef ///< [in] Reference to the request message.
1603 );
1604 
1605 
1606 // =======================================
1607 // INTERFACE FUNCTIONS
1608 // =======================================
1609 
1610 //--------------------------------------------------------------------------------------------------
1611 /**
1612  * Creates a service that is accessible using a protocol.
1613  *
1614  * Mailbox services should be created statically.
1615  *
1616  * @return Service reference.
1617  */
1618 //--------------------------------------------------------------------------------------------------
1619 LE_FULL_API le_msg_ServiceRef_t le_msg_CreateService
1620 (
1621  le_msg_ProtocolRef_t protocolRef, ///< [in] Reference to the protocol to be used.
1622  const char* interfaceName ///< [in] Server-side interface name.
1623 );
1624 
1625 
1626 //--------------------------------------------------------------------------------------------------
1627 /**
1628  * Initialize a mailbox service.
1629  *
1630  * This must be called before any client can connect to the service, for example in COMPONENT_INIT
1631  * before any other threads are created.
1632  */
1633 //--------------------------------------------------------------------------------------------------
1634 le_msg_ServiceRef_t le_msg_InitLocalService
1635 (
1636  le_msg_LocalService_t* servicePtr,
1637  const char* serviceNameStr,
1638  le_mem_PoolRef_t messagingPoolRef
1639 );
1640 
1641 
1642 //--------------------------------------------------------------------------------------------------
1643 /**
1644  * Deletes a service. Any open sessions will be terminated.
1645  *
1646  * @note Server-only function.
1647  */
1648 //--------------------------------------------------------------------------------------------------
1650 (
1651  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1652 );
1653 
1654 //--------------------------------------------------------------------------------------------------
1655 /**
1656  * Registers a function to be called when clients open sessions with this service.
1657  *
1658  * @note Server-only function.
1659  */
1660 //--------------------------------------------------------------------------------------------------
1662 (
1663  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1664  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1665  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1666 );
1667 
1668 //--------------------------------------------------------------------------------------------------
1669 /**
1670  * Registers a function to be called whenever one of this service's sessions is closed by
1671  * the client.
1672  *
1673  * @note Server-only function.
1674  */
1675 //--------------------------------------------------------------------------------------------------
1677 (
1678  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1679  le_msg_SessionEventHandler_t handlerFunc,///< [in] Handler function.
1680  void* contextPtr ///< [in] Opaque pointer value to pass to handler.
1681 );
1682 
1683 //--------------------------------------------------------------------------------------------------
1684 /**
1685  * Remove a function previously registered by le_msg_AddServiceOpenHandler or
1686  * le_msg_AddServiceCloseHandler.
1687  *
1688  * @note This is a server-only function.
1689  */
1690 //--------------------------------------------------------------------------------------------------
1692 (
1693  le_msg_SessionEventHandlerRef_t handlerRef ///< [in] Reference to a previously call of
1694  /// le_msg_AddServiceCloseHandler()
1695 );
1696 
1697 //--------------------------------------------------------------------------------------------------
1698 /**
1699  * Registers a function to be called when messages are received from clients via sessions
1700  * that they have open with this service.
1701  *
1702  * @note Server-only function.
1703  */
1704 //--------------------------------------------------------------------------------------------------
1706 (
1707  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1708  le_msg_ReceiveHandler_t handlerFunc,///< [in] Handler function.
1709  void* contextPtr ///< [in] Opaque pointer value to pass to the handler.
1710 );
1711 
1712 
1713 //--------------------------------------------------------------------------------------------------
1714 /**
1715  * Associates an opaque context value (void pointer) with a given service that can be retrieved
1716  * later using le_msg_GetServiceContextPtr().
1717  *
1718  * @note Server-only function.
1719  */
1720 //--------------------------------------------------------------------------------------------------
1722 (
1723  le_msg_ServiceRef_t serviceRef, ///< [in] Reference to the service.
1724 
1725  void* contextPtr ///< [in] Opaque value to be returned by
1726  /// le_msg_GetServiceContextPtr().
1727 );
1728 
1729 
1730 //--------------------------------------------------------------------------------------------------
1731 /**
1732  * Fetches the opaque context value (void pointer) associated with a specified service using
1733  * le_msg_SetServiceContextPtr().
1734  *
1735  * @return Context pointer value, or NULL if le_msg_SetServiceContextPtr() was never called
1736  * for this service.
1737  *
1738  * @note Server-only function.
1739  */
1740 //--------------------------------------------------------------------------------------------------
1742 (
1743  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1744 );
1745 
1746 
1747 //--------------------------------------------------------------------------------------------------
1748 /**
1749  * Makes a given service available for clients to find.
1750  *
1751  * @note Server-only function.
1752  */
1753 //--------------------------------------------------------------------------------------------------
1755 (
1756  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1757 );
1758 
1759 
1760 //--------------------------------------------------------------------------------------------------
1761 /**
1762  * Makes a specified service unavailable for clients to find without terminating any ongoing
1763  * sessions.
1764  *
1765  * @note Server-only function.
1766  */
1767 //--------------------------------------------------------------------------------------------------
1769 (
1770  le_msg_ServiceRef_t serviceRef ///< [in] Reference to the service.
1771 );
1772 
1773 
1774 //--------------------------------------------------------------------------------------------------
1775 /**
1776  * Fetches a pointer to the name of an interface.
1777  *
1778  * @return Pointer to a null-terminated string.
1779  *
1780  * @warning Pointer returned will remain valid only until the interface is deleted.
1781  */
1782 //--------------------------------------------------------------------------------------------------
1784 (
1785  le_msg_InterfaceRef_t interfaceRef ///< [in] Reference to the interface.
1786 );
1787 
1788 
1789 //--------------------------------------------------------------------------------------------------
1790 /**
1791  * Fetches a reference to the protocol supported by a specified interface.
1792  *
1793  * @return Protocol reference.
1794  */
1795 //--------------------------------------------------------------------------------------------------
1797 (
1798  le_msg_InterfaceRef_t interfaceRef ///< [in] Reference to the interface.
1799 );
1800 
1801 
1802 //--------------------------------------------------------------------------------------------------
1803 /**
1804  * Check if the calling thread is currently running a Service's message receive handler;
1805  * if so, return a reference to the message object being handled.
1806  *
1807  * @return Reference to the message being handled, or NULL if no Service message receive handler
1808  * is currently running.
1809  **/
1810 //--------------------------------------------------------------------------------------------------
1811 le_msg_MessageRef_t le_msg_GetServiceRxMsg
1812 (
1813  void
1814 );
1815 
1816 
1817 //--------------------------------------------------------------------------------------------------
1818 /**
1819  * Logs an error message (at EMERGENCY level) and:
1820  * - if the caller is running a server-side IPC function, kills the connection to the client
1821  * and returns.
1822  * - if the caller is not running a server-side IPC function, kills the caller (doesn't return).
1823  **/
1824 //--------------------------------------------------------------------------------------------------
1825 #define LE_KILL_CLIENT(formatString, ...) \
1826 { \
1827  le_msg_MessageRef_t msgRef = le_msg_GetServiceRxMsg(); \
1828  LE_FATAL_IF(msgRef == NULL, formatString, ##__VA_ARGS__); \
1829  LE_EMERG(formatString, ##__VA_ARGS__); \
1830  le_msg_CloseSession(le_msg_GetSession(msgRef)); \
1831 }
1832 
1833 #endif // LEGATO_MESSAGING_INCLUDE_GUARD
le_msg_MessageRef_t le_msg_GetServiceRxMsg(void)
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:1011
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:45
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:968
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:890
le_result_t le_msg_TryOpenSessionSync(le_msg_SessionRef_t sessionRef)
void le_msg_AdvertiseService(le_msg_ServiceRef_t serviceRef)
Definition: le_messaging.h:942
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:853
Definition: le_messaging.h:1004
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:909
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:875
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:970
void le_msg_CloseSession(le_msg_SessionRef_t sessionRef)
struct le_mem_Pool * le_mem_PoolRef_t
Definition: le_mem.h:542
bool serviceReady
Indicate if service is ready.
Definition: le_messaging.h:992
le_mem_PoolRef_t messagePool
Pool for messages on this service.
Definition: le_messaging.h:995
le_msg_ReceiveHandler_t handler
Handler function which should be called on thread.
Definition: le_messaging.h:971
int fd
File descriptor sent with message (via Get/SetFd)
Definition: le_messaging.h:1007
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)
void le_msg_CloseSessionLocked(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:860
#define LE_FULL_API
Definition: le_apiFeatures.h:40
void le_msg_RequestResponse(le_msg_MessageRef_t msgRef, le_msg_ResponseCallback_t handlerFunc, void *contextPtr)
Definition: le_messaging.h:986
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:994
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:1010
void * contextPtr
Context pointer to pass to the handler.
Definition: le_messaging.h:972
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:832
void(* le_msg_ResponseCallback_t)(le_msg_MessageRef_t msgRef, void *contextPtr)
Definition: le_messaging.h:929
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:1008
struct le_msg_Interface * le_msg_InterfaceRef_t
Definition: le_messaging.h:839
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:959
LE_FULL_API size_t le_msg_GetProtocolMaxMsgSize(le_msg_ProtocolRef_t protocolRef)
Definition: le_messaging.h:957
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:1009