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