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