1 /*
2 * Copyright (c) 2011-2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
34 /*
35 * ======== RcmClient.h ========
36 *
37 */
39 /*!
40 * @file ti/grcm/RcmClient.h
41 *
42 * @brief Remote Command Message Client Module. An RcmClient is used
43 * for sending messages to an RcmServer for processing.
44 *
45 * @sa RcmServer.h <br>
46 * @ref ti_grcm "RCM Overview"
47 */
49 /*!
50 * @defgroup ti_grcm_RcmClient RcmClient
51 *
52 * @brief Remote Command Message Client Module. An RcmClient is used
53 * for sending messages to an RcmServer for processing.
54 *
55 * The RcmClient module is used to send messages to an RcmServer for
56 * processing. An RcmClient instance must be created which will
57 * communicate with a single RcmServer instance. An RcmServer instance
58 * can receive messages from many RcmClient instances but an RcmClient
59 * instance can send messages to only one RcmServer instance.
60 *
61 * <a name="error_handling"></a><h2>Error Handling</h2>
62 *
63 * Errors may be raised at various points in the execution flow of a
64 * single message. These are the types of errors raised by RCM:
65 * - RCM Errors
66 * - User Errors
67 * - Message Function Errors
68 * - Library Function Errors
69 *
70 * The following diagram illustrates the call flow and highlights the
71 * points at which errors can be raised.
72 *
73 * @image html ti/grcm/doc-files/ExecFlow.png "Diagram 1: Execution Flow"
74 *
75 * RCM errors are raised by the RCM implementation. For example, when
76 * calling RcmClient_exec(), it may raise an error if it
77 * is unable to send the message. This will be reported immediately to
78 * the caller, the server is never involved. This is highlighted in the
79 * diagram at point [A].
80 *
81 * RCM errors may also be raised by the RcmServer. Once RcmClient_exec()
82 * sends a message, it waits for the return message. When the server
83 * receives the message, it has to decode its type. If this fails, the
84 * server records this error in the message and sends it back to the
85 * client. This is highlighted at point [B] in the diagram. When
86 * RcmClient_exec() receives the return message, it inspects the status
87 * field and recognizes the error. It then raises an appropriate error
88 * to the caller.
89 *
90 * User errors are raised by RCM as a result of an invalid runtime
91 * condition. They are typically detected and raised by the server and
92 * then sent back to the client for processing. For example, when the
93 * server receives a message, it will lookup the function index in it's
94 * table and invoke the corresponding message function. If the index is
95 * invalid, this is detected by the server and reported as an error.
96 * The message function is never invoked. The message is returned to
97 * the client and RcmClient_exec() will raise the appropriate error.
98 * This error is raised at point [B] in the diagram.
99 *
100 * Message function errors are raised by the message function itself.
101 * This is highlighted at point [C] in the diagram. In the body of the
102 * message function, an error is encountered either when calling a
103 * framework function or when unmarshalling the arguments from the
104 * message payload. In both cases, the message function will abort and
105 * return an error value as its return value. The error value must be
106 * less than zero (< 0). When control returns to the server, it inspects
107 * the message function's return value. If the message was sent by
108 * RcmClient_exec(), then the server simply stores the return value in
109 * the message and returns it to the client. However, if the message was
110 * send by RcmClient_execCmd(), the behavior is slightly
111 * different. If the return value is < 0 (error condition), then the
112 * server behaves the same as for the RcmClient_exec() case. However,
113 * if there is no error, the server simply frees the message. The message
114 * is never returned to the client.
115 *
116 * Library functions errors are raised by the library functions invoked
117 * by the message function, highlighted at point [D] in the diagram. It
118 * is the responsibility of the message function to detect a library
119 * function error and to marshal the appropriate error code into the
120 * message payload. The message function must also return an error value
121 * (< 0) so that server can do proper error handing as described
122 * in the preceeding paragraph. It is the stub function's responsibility
123 * to unmarshal the error value from the message payload and take the
124 * appropriate action.
125 *
126 * Understanding the types of errors raised by RCM and where they are
127 * raised is important when writing the upper layer software. The following
128 * code fragment illustrates how to check for the errors discussed above.
129 * See <a href"#error_handling">Error Handling</a> above.
130 *
131 * @code
132 * RcmClient_Message *msg;
133 *
134 * // send message
135 * status = RcmClient_exec(h, msg, &msg);
136 *
137 * // check for error
138 * switch (status) {
139 *
140 * case RcmClient_S_SUCCESS:
141 * // no error, all is well
142 * break;
143 *
144 * case RcmClient_E_EXECFAILED:
145 * // RCM error, unable to send message
146 * :
147 * break;
148 *
149 * case RcmClient_E_INVALIDFXNIDX:
150 * // user error, bad function index
151 * :
152 * break;
153 *
154 * case RcmClient_E_MSGFXNERROR:
155 * // decode message function error
156 * msgFxnErr = msg->result;
157 * :
158 * // decode library function error
159 * libFxnErr = msg->data[0];
160 * :
161 * break;
162 * }
163 *
164 * // free message if one was returned
165 * if (msg != NULL) {
166 * RcmClient_free(h, msg);
167 * msg = NULL;
168 * }
169 * @endcode
170 *
171 * The upper layer software begins by calling RcmClient_exec()
172 * to send the message to the server. If RCM encounters a transport error
173 * and is unable to send the message, an RcmClient_E_EXECFAILED error is
174 * returned.
175 *
176 * If the server encounters an error while decoding the message, say an
177 * invalid function index, the server returns the message and an
178 * RcmClient_E_INVALIDFXNIDX error is returned.
179 *
180 * If the message function or the library function encounter an error,
181 * the message is returned and an RcmClient_E_MSGFXNERROR error is
182 * returned. The upper layer software must decode the results field to
183 * see what error the message function returned. If the library function
184 * returned an error, its error code must be unmarshalled from the payload.
185 * This is illustrated by decoding the first word in the payload
186 * (msg->data[0]). The actual marshal format is implementation specific.
187 *
188 * The message function must return >=0 for success, <0 for error.
189 * Here is a very simple message function which simply turns on an LED.
190 *
191 * @code
192 * Int32 Led_On(UInt32 size, UInt32 *data)
193 * {
194 * Ptr led = <addr>;
195 *
196 * *led = 1; // turn on LED
197 * return(0); // success
198 * }
199 * @endcode
200 *
201 * In this example, the message payload is not used. The message function
202 * does all the work, it just sets a bit in the LED control register, and
203 * returns success.
204 *
205 * This next example illustrates a very simple RPC style skel function.
206 * It unmarshalls two arguments and invokes the libraray function. If the
207 * library function succeeds, the message function returns 0, otherwise it
208 * returns -1 to indicate failure. In both cases, the library function's
209 * return value is marshalled into the payload. The calling stub function
210 * can umarshal the return value to get the library function's error code.
211 *
212 * @code
213 * Int32 MediaSkel_process(UInt32 size, UInt32 *data)
214 * {
215 * Int a, b, x;
216 * Int32 status = 0; // success
217 *
218 * // unmarshal args
219 * a = (Int)data[1];
220 * b = (Int)data[2];
221 *
222 * // invoke library function, returns >=0 on success
223 * x = Media_process(a, b);
224 *
225 * // marshal return value
226 * data[0] = (Int32)x;
227 *
228 * // return status
229 * return(x >= 0 ? 0 : -1);
230 * }
231 * @endcode
232 *
233 * @sa ti_grcm_RcmServer <br>
234 * @ref ti_grcm "RCM Overview"
235 */
237 #ifndef ti_grcm_RcmClient__include
238 #define ti_grcm_RcmClient__include
240 #include <xdc/runtime/knl/GateThread.h>
243 /** @ingroup ti_grcm_RcmClient */
244 /*@{*/
246 #if defined (__cplusplus)
247 extern "C" {
248 #endif
251 /* -------- status codes --------*/
253 /*!
254 * @brief Success return code
255 */
256 #define RcmClient_S_SUCCESS (0)
258 /*!
259 * @brief General failure return code
260 */
261 #define RcmClient_E_FAIL (-1)
263 /*!
264 * @brief The client has not been configured for asynchronous notification
265 *
266 * In order to use the RcmClient_execAsync() function, the RcmClient
267 * must be configured with callbackNotification set to true in the
268 * instance create parameters.
269 */
270 #define RcmClient_E_EXECASYNCNOTENABLED (-2)
272 /*!
273 * @brief The client was unable to send the command message to the server
274 *
275 * An IPC transport error occurred. The message was never sent to the server.
276 */
277 #define RcmClient_E_EXECFAILED (-3)
279 /*!
280 * @brief A heap id must be provided in the create params
281 *
282 * When an RcmClient instance is created, a heap id must be given
283 * in the create params. This heap id must be registered with MessageQ
284 * before calling RcmClient_create().
285 */
286 #define RcmClient_E_INVALIDHEAPID (-4)
288 /*!
289 * @brief Invalid function index
290 *
291 * An RcmClient_Message was sent to the server which contained a
292 * function index value (in the fxnIdx field) that was not found
293 * in the server's function table.
294 */
295 #define RcmClient_E_INVALIDFXNIDX (-5)
297 /*!
298 * @brief Message function error
299 *
300 * There was an error encountered in either the message function or
301 * the library function invoked by the message function. The semantics
302 * of the error code are implementation dependent.
303 */
304 #define RcmClient_E_MSGFXNERROR (-6)
306 /*!
307 * @brief An unknown error has been detected from the IPC layer
308 *
309 * Check the error log for additional information.
310 */
311 #define RcmClient_E_IPCERROR (-7)
313 /*!
314 * @brief Failed to create the list object
315 */
316 #define RcmClient_E_LISTCREATEFAILED (-8)
318 /*!
319 * @brief The expected reply message from the server was lost
320 *
321 * A command message was sent to the RcmServer but the reply
322 * message was not received. This is an internal error.
323 */
324 #define RcmClient_E_LOSTMSG (-9)
326 /*!
327 * @brief Insufficient memory to allocate a message
328 *
329 * The message heap cannot allocate a buffer of the requested size.
330 * The reported size it the requested data size and the underlying
331 * message header size.
332 */
333 #define RcmClient_E_MSGALLOCFAILED (-10)
335 /*!
336 * @brief The client message queue could not be created
337 *
338 * Each RcmClient instance must create its own message queue for
339 * receiving return messages from the RcmServer. The creation of
340 * this message queue failed, thus failing the RcmClient instance
341 * creation.
342 */
343 #define RcmClient_E_MSGQCREATEFAILED (-11)
345 /*!
346 * @brief The server message queue could not be opened
347 *
348 * Each RcmClient instance must open the server's message queue.
349 * This error is raised when an internal error occurred while trying
350 * to open the server's message queue.
351 */
352 #define RcmClient_E_MSGQOPENFAILED (-12)
354 /*!
355 * @brief The server returned an unknown error code
356 *
357 * The server encountered an error with the given message but
358 * the error code is not recognized by the client.
359 */
360 #define RcmClient_E_SERVERERROR (-13)
362 /*!
363 * @brief The server specified in the create params was not found
364 *
365 * When creating an RcmClient instance, the specified server could not
366 * be found. This could occur if the server name is incorrect, or
367 * if the RcmClient instance is created before the RcmServer. In such an
368 * instance, the client can retry when the RcmServer is expected to
369 * have been created.
370 */
371 #define RcmClient_E_SERVERNOTFOUND (-14)
373 /*!
374 * @brief The given symbol was not found in the server symbol table
375 *
376 * This error could occur if the symbol spelling is incorrect or
377 * if the RcmServer is still loading its symbol table.
378 */
379 #define RcmClient_E_SYMBOLNOTFOUND (-15)
381 /*!
382 * @brief There is insufficient memory left in the heap
383 */
384 #define RcmClient_E_NOMEMORY (-16)
386 /*!
387 * @brief The given job id was not found on the server
388 *
389 * When releasing a job id with a call to RcmClient_releaseJobId(),
390 * this error return value indicates that the given job id was not
391 * previously allocated with a call to RcmClient_acquireJobId().
392 */
393 #define RcmClient_E_JOBIDNOTFOUND (-17)
396 /* -------- constants and types --------*/
398 /*!
399 * @brief Invalid function index
400 */
401 #define RcmClient_INVALIDFXNIDX ((UInt32)(0xFFFFFFFF))
403 /*!
404 * @brief Invalid heap id
405 */
406 #define RcmClient_INVALIDHEAPID ((UInt16)(0xFFFF))
408 /*!
409 * @brief Invalid message id
410 */
411 #define RcmClient_INVALIDMSGID (0)
413 /*!
414 * @brief Default worker pool id
415 *
416 * The default worker pool is used to process all anonymous messages.
417 * When a new message is allocated, the pool id property is
418 * initialized to this value.
419 */
420 #define RcmClient_DEFAULTPOOLID ((UInt16)(0x8000))
422 /*!
423 * @brief Invalid job stream id
424 *
425 * All discrete messages must have their jobId property set to this value.
426 * When a new message is allocated, the jobId property is initialized tothis value.
427 */
428 #define RcmClient_DISCRETEJOBID (0)
430 /*!
431 * @brief RcmClient instance object handle
432 */
433 typedef struct RcmClient_Object_tag *RcmClient_Handle;
435 /*!
436 * @brief Remote Command Message structure
437 *
438 * An RcmClient needs to fill in this message before sending it
439 * to the RcmServer for execution.
440 */
441 typedef struct {
442 /*!
443 * @brief The worker pool id that will process this message.
444 *
445 * The message will be processed by a worker thread from the worker
446 * pool specified in this field. The default value is the default
447 * pool id.
448 */
449 UInt16 poolId;
451 /*!
452 * @brief The job id associated with this message.
453 *
454 * All messages beloging to a job id must have this field set to
455 * that id. Use the value RcmClient_DISCRETEJOBID if the message
456 * does not belong to any job.
457 */
458 UInt16 jobId;
460 /*!
461 * @brief The index of the remote function to execute.
462 */
463 UInt32 fxnIdx;
465 /*!
466 * @brief The return value of the remote message function.
467 */
468 Int32 result;
470 /*!
471 * @brief The size of the data buffer (in chars).
472 *
473 * This field should be considered as read-only. It is set by
474 * the call to the RcmClient_alloc() function.
475 */
476 UInt32 dataSize;
478 /*!
479 * @brief The data buffer containing the message payload.
480 *
481 * The size of this field is dataSize chars. The space is allocated
482 * by the call to the RcmClient_alloc() function.
483 */
484 UInt32 data[1];
486 } RcmClient_Message;
488 /*!
489 * @brief Callback function type
490 *
491 * When using callback notification, the application must supply a
492 * callback function of this type. The callback will be invoked with
493 * the pointer to the RcmClient_Message returned from the server and
494 * the application data pointer supplied in the call to RcmClient_execAsync().
495 */
496 typedef Void (*RcmClient_CallbackFxn)(RcmClient_Message *, Ptr);
498 /*!
499 * @brief Instance create parameters
500 */
501 typedef struct {
502 /*!
503 * @brief The heapId used by this instance for allocating messages
504 *
505 * If sending messages to a remote server, the specified heap must
506 * be compatible with the transport used for delivering messages
507 * to the remote processor.
508 */
509 UInt16 heapId;
511 /*!
512 * @brief Asynchronous callback notification support
513 *
514 * When remote functions submitted with RcmClient_execAsync()
515 * complete, the given callback function is invoked. The callback
516 * function executes in the context of this RcmClient instance's
517 * callback server thread.
518 *
519 * This config param must be set to true when using RcmClient_execAsync()
520 * to execute remote functions.
521 *
522 * When set to false, the callback server thread is not created.
523 */
524 Bool callbackNotification;
526 } RcmClient_Params;
528 /*!
529 * @brief Opaque client structure large enough to hold an instance object
530 *
531 * Use this structure to define an embedded RcmClient object.
532 *
533 * @sa RcmClient_construct
534 */
535 typedef struct {
536 xdc_runtime_knl_GateThread_Struct _f1;
537 Ptr _f2;
538 Ptr _f3;
539 UInt16 _f4;
540 Ptr _f5;
541 UInt32 _f6;
542 Bool _f7;
543 UInt16 _f8;
544 Ptr _f9;
545 Ptr _f10;
546 Ptr _f11;
547 Ptr _f12;
548 } RcmClient_Struct;
551 /* -------- functions --------*/
553 /*
554 * ======== RcmClient_acquireJobId ========
555 */
556 /*!
557 * @brief Get a job id from the server
558 *
559 * Acquire a unique job id from the server. The job id is used to associate
560 * messages with a common job id. The server will process all messages for
561 * a given job id in sequence.
562 */
563 Int RcmClient_acquireJobId(
564 RcmClient_Handle handle,
565 UInt16 * jobId
566 );
568 /*
569 * ======== RcmClient_addSymbol ========
570 */
571 /*!
572 * @brief Add a symbol and its address to the server table
573 *
574 * This function is used by the client to dynamically load a new
575 * function address into the server's function pointer table. The
576 * given address must be in the server's address space. The function
577 * must already be loaded into the server's memory.
578 *
579 * This function is useful when dynamically loading code onto the
580 * remote processor (as in the case of DLL's).
581 *
582 * @param[in] handle Handle to an instance object
583 *
584 * @param[in] name The function's name.
585 *
586 * @param[in] addr The function's address as specified in the
587 * remote processor's address space.
588 *
589 * @param[out] index The function's index value to be used in the
590 * RcmClient_Message.fxnIdx field.
591 *
592 * @retval RcmClient_S_SUCCESS Success
593 * @retval RcmClient_E_FAIL Failure
594 */
595 Int RcmClient_addSymbol(
596 RcmClient_Handle handle,
597 String name,
598 Fxn addr,
599 UInt32 * index
600 );
602 /*
603 * ======== RcmClient_alloc ========
604 */
605 /*!
606 * @brief Allocate a message from the heap configured for this instance
607 *
608 * When a message is allocated, the RcmClient instance is the owner
609 * of the message. All messages must be returned to the heap by
610 * calling RcmClient_free().
611 *
612 * During a call to all of the exec functions, the ownership of the
613 * message is temporarily transfered to the server. If the exec
614 * function returns an RcmClient_Message pointer, then ownership of
615 * the message is returned to the instance. For the other exec
616 * functions, the client acquires ownership of the return message
617 * by calling RcmClient_waitUntilDone().
618 *
619 * A message should not be accessed when ownership has been given
620 * away. Once ownership has been reacquired, the message can be
621 * either reused or returned to the heap.
622 *
623 * @param[in] handle Handle to an instance object
624 *
625 * @param[in] dataSize Specifies (in chars) how much space to allocate
626 * for the RcmClient_Message.data array. The actual memory allocated
627 * from the heap will be larger as it includes the size of the
628 * internal message header.
629 *
630 * @param[out] message A pointer to the allocated message or NULL on error.
631 */
632 Int RcmClient_alloc(
633 RcmClient_Handle handle,
634 UInt32 dataSize,
635 RcmClient_Message ** message
636 );
638 /*
639 * ======== RcmClient_checkForError ========
640 */
641 /*!
642 * @brief Check if an error message has been returned from the server
643 *
644 * When using RcmClient_execCmd() to send messages to the server, the
645 * message will be freed by the server unless an error occurs. In the
646 * case of an error, the message is returned to the client. Use this
647 * function to check for and to retrieve these error messages.
648 *
649 * Note that the latency of the return message is dependent on many
650 * system factors. In particular, the server's response time to processing
651 * a message will be a significant factor. It is possible to call
652 * RcmClient_execCmd() several times before any error message is returned.
653 * There is no way to know when all the messages have been processed.
654 *
655 * The return value of RcmClient_checkForError() is designed to mimic
656 * the return value of RcmClient_exec(). When an error message is returned
657 * to the caller, the return value of RcmClient_checkForError() will be
658 * the appropriate error code as if the error had occured during a call
659 * to RcmClient_exec(). For example, if a message is prepared with an
660 * incorrect function index, the return value from RcmClient_exec() would
661 * be RcmClient_E_INVALIDFXNIDX. However, the same message sent with
662 * RcmClient_execCmd() will not return an error, because the function does
663 * not wait for the return message. When the server receives the message
664 * and detects the function index error, it will return the message to
665 * the client on a special error queue. The subsequent call to
666 * RcmClient_checkForError() will pickup this error message and return
667 * with a status value of RcmClient_E_INVALIDFXNIDX, just as the call
668 * to RcmClient_exec() would have done.
669 *
670 * A return value of RcmClient_S_SUCCESS means there are no error messages.
671 * This function will never return a message and a success status code at
672 * the same time.
673 *
674 * When this function returns an error message, the caller must return
675 * the message to the heap by calling RcmClient_free().
676 *
677 * It is possible that RcmClient_checkForError() will return with an error
678 * but without an error message. This can happen when an internal error
679 * occurs in RcmClient_checkForError() before it has checked the error
680 * queue. In this case, an error is returned but the returnMsg argument
681 * will be set to NULL.
682 *
683 * @param[in] handle Handle to an instance object
684 *
685 * @param[out] returnMsg A pointer to the error message or NULL if there
686 * are no error messages in the queue.
687 *
688 * @retval RcmClient_S_SUCCESS
689 * @retval RcmClient_E_IPCERROR
690 * @retval RcmClient_E_INVALIDFXNIDX
691 * @retval RcmClient_E_MSGFXNERROR
692 * @retval RcmClient_E_SERVERERROR
693 */
694 Int RcmClient_checkForError(
695 RcmClient_Handle handle,
696 RcmClient_Message ** returnMsg
697 );
699 /*
700 * ======== RcmClient_construct ========
701 */
702 /*!
703 * @brief Initialize a new instance object inside the provided structure
704 *
705 * This function is the same as RcmClient_create() except that it does not
706 * allocate memory for the instance object. The instance object is
707 * constructed inside the provided structure. Call RcmClient_destruct()
708 * to finalize a constructed instance object.
709 *
710 * @param[in] structPtr A pointer to an allocated structure.
711 *
712 * @param[in] server The name of the server that messages will be sent to for
713 * executing commands. The name must be a system-wide unique name.
714 *
715 * @param[in] params The create params used to customize the instance object.
716 *
717 * @sa RcmClient_create
718 */
719 Int RcmClient_construct(
720 RcmClient_Struct * structPtr,
721 String server,
722 const RcmClient_Params *params
723 );
725 /*
726 * ======== RcmClient_create ========
727 */
728 /*!
729 * @brief Create an RcmClient instance
730 *
731 * The RcmClient instance is used by the application to send messages to
732 * an RcmServer for executing remote functions. A given
733 * instance can send messages only to the server it was configured
734 * for. If an application needs to send messages to multiple servers,
735 * then create an RcmClient instance for each server.
736 *
737 * The assigned server to this instance must already exist and be
738 * running before creating RcmClient instances which send messages to it.
739 *
740 * @param[in] server The name of the server that messages will be sent to for
741 * executing commands. The name must be a system-wide unique name.
742 *
743 * @param[in] params The create params used to customize the instance object.
744 *
745 * @param[out] handle An opaque handle to the created instance object.
746 */
747 Int RcmClient_create(
748 String server,
749 const RcmClient_Params *params,
750 RcmClient_Handle * handle
751 );
753 /*
754 * ======== RcmClient_delete ========
755 */
756 /*!
757 * @brief Delete an RcmClient instance
758 *
759 * @param[in,out] handlePtr Handle to the instance object to delete.
760 */
761 Int RcmClient_delete(
762 RcmClient_Handle * handlePtr
763 );
765 /*
766 * ======== RcmClient_destruct ========
767 */
768 /*!
769 * @brief Finalize the instance object inside the provided structure
770 *
771 * @param[in] structPtr A pointer to the structure containing the
772 * instance object to finalize.
773 */
774 Int RcmClient_destruct(
775 RcmClient_Struct * structPtr
776 );
778 /*
779 * ======== RcmClient_exec ========
780 */
781 /*!
782 * @brief Execute a command message on the server
783 *
784 * The message is sent to the server for processing. This call will
785 * block until the remote function has completed. When this function
786 * returns, the message will contain the return value of the remote
787 * function as well as a possibly modified context.
788 *
789 * After calling exec, the message can be either reused for another
790 * call to exec or it can be freed.
791 *
792 * @param[in] handle Handle to an instance object
793 *
794 * @param[in] cmdMsg Pointer to an RcmClient_Message structure.
795 *
796 * @param[out] returnMsg A pointer to the return message or NULL on
797 * error. The client must free this message. The return value of the
798 * message function is stored in the results field. The return value
799 * of the library function is marshalled into the data field.
800 *
801 * @retval RcmClient_S_SUCCESS
802 * @retval RcmClient_E_EXECFAILED
803 * @retval RcmClient_E_INVALIDFXNIDX
804 * @retval RcmClient_E_LOSTMSG
805 * @retval RcmClient_E_MSGFXNERROR
806 * @retval RcmClient_E_SERVERERROR
807 */
808 Int RcmClient_exec(
809 RcmClient_Handle handle,
810 RcmClient_Message * cmdMsg,
811 RcmClient_Message ** returnMsg
812 );
814 /*
815 * ======== RcmClient_execAsync ========
816 */
817 /*!
818 * @brief Execute a command message and use a callback for notification
819 *
820 * The message is sent to the server for execution, but this call does
821 * not wait for the remote function to execute. This call returns
822 * as soon as the message has been dispatched to the transport. Upon
823 * returning from this function, the ownership of the message has been
824 * lost; do not access the message at this time.
825 *
826 * When the remote function completes, the given callback function is
827 * invoked by this RcmClient instance's callback server thread. The
828 * callback function is used to asynchronously notify the client that
829 * the remote function has completed.
830 *
831 * The RcmClient instance must be create with callbackNotification
832 * set to true in order to use this function.
833 *
834 * @param[in] handle Handle to an instance object
835 *
836 * @param[in] cmdMsg Pointer to an RcmClient_Message structure.
837 *
838 * @param[in] callback A callback function pointer supplied by the
839 * application. It will be invoked by the callback server thread to
840 * notify the application that the remote function has completed.
841 *
842 * @param[in] appData A private data pointer supplied by the application.
843 * This allows the application to provide its own context when
844 * receiving the callback.
845 */
846 Int RcmClient_execAsync(
847 RcmClient_Handle handle,
848 RcmClient_Message * cmdMsg,
849 RcmClient_CallbackFxn callback,
850 Ptr appData
851 );
853 /*
854 * ======== RcmClient_execCmd ========
855 */
856 /*!
857 * @brief Execute a one-way command message on the server
858 *
859 * The message is sent to the server for processing but this function
860 * does not wait for the return message. This function is non-blocking.
861 * The server will processes the message and then free it, unless an
862 * error occurs. The return value from the remote function is discarded.
863 *
864 * If an error occurs on the server while processing the message, the server
865 * will return the message to the client. Use RcmClient_checkForError()
866 * to collect these return error messages.
867 *
868 * When this function returns, ownership of the message has been transfered
869 * to the server. Do not access the message after this function returns,
870 * it could cause cache inconsistencies or a memory access violation.
871 *
872 * @param[in] handle Handle to an instance object
873 *
874 * @param[in] cmdMsg Pointer to an RcmClient_Message structure.
875 *
876 * @retval RcmClient_S_SUCCESS
877 * @retval RcmClient_E_IPCERROR
878 */
879 Int RcmClient_execCmd(
880 RcmClient_Handle handle,
881 RcmClient_Message * cmdMsg
882 );
884 /*
885 * ======== RcmClient_execDpc ========
886 */
887 /*!
888 * @brief Execute a deferred procedure call on the server
889 *
890 * The return field of the message is not used.
891 *
892 * @param[in] handle Handle to an instance object
893 *
894 * @param[in] cmdMsg Pointer to an RcmClient_Message structure.
895 *
896 * @param[out] returnMsg A pointer to the return message or NULL
897 * on error. The client must free this message.
898 */
899 Int RcmClient_execDpc(
900 RcmClient_Handle handle,
901 RcmClient_Message * cmdMsg,
902 RcmClient_Message ** returnMsg
903 );
905 /*
906 * ======== RcmClient_execNoWait ========
907 */
908 /*!
909 * @brief Submit a command message to the server and return immediately
910 *
911 * The message is sent to the server for execution but this call does
912 * not wait for the remote function to execute. The call returns
913 * as soon as the message has been dispatched to the transport. Upon
914 * returning from this function, the ownership of the message has been
915 * lost; do not access the message at this time.
916 *
917 * Using this call to execute a remote message does not require a
918 * callback server thread. The application must call
919 * RcmClient_waitUntilDone() to get the return message from the remote
920 * function.
921 *
922 * @param[in] handle Handle to an instance object
923 *
924 * @param[in] cmdMsg A pointer to an RcmClient_Message structure.
925 *
926 * @param[out] msgId Pointer used for storing the message id. Use
927 * the message id in a call to RcmClient_WaitUntilDone() to retrieve
928 * the return value of the remote function.
929 */
930 Int RcmClient_execNoWait(
931 RcmClient_Handle handle,
932 RcmClient_Message * cmdMsg,
933 UInt16 * msgId
934 );
936 /*
937 * ======== RcmClient_exit ========
938 */
939 /*!
940 * @brief Finalize the RcmClient module
941 *
942 * This function is used to finalize the RcmClient module. Any resources
943 * acquired by RcmClient_init() will be released. Do not call any RcmClient
944 * functions after calling RcmClient_exit().
945 *
946 * This function must be serialized by the caller.
947 */
948 Void RcmClient_exit(Void);
950 /*
951 * ======== RcmClient_free ========
952 */
953 /*!
954 * @brief Free the given message
955 *
956 * @param[in] handle Handle to an instance object
957 *
958 * @param msg Pointer to an RcmClient_Message structure.
959 */
960 Int RcmClient_free(
961 RcmClient_Handle handle,
962 RcmClient_Message * msg
963 );
965 /*
966 * ======== RcmClient_getSymbolIndex ========
967 */
968 /*!
969 * @brief Return the function index from the server
970 *
971 * Query the server for the given function name and return its index.
972 * Use the index in the fxnIdx field of the RcmClient_Message struct.
973 *
974 * @param[in] handle Handle to an instance object
975 *
976 * @param[in] name The function's name.
977 *
978 * @param[out] index The function's index.
979 */
980 Int RcmClient_getSymbolIndex(
981 RcmClient_Handle handle,
982 String name,
983 UInt32 * index
984 );
986 /*
987 * ======== RcmClient_init ========
988 */
989 /*!
990 * @brief Initialize the RcmClient module
991 *
992 * This function is used to initialize the RcmClient module. Call this
993 * function before calling any other RcmClient function.
994 *
995 * This function must be serialized by the caller
996 */
997 Void RcmClient_init(Void);
999 /*
1000 * ======== RcmClient_Parmas_init ========
1001 */
1002 /*!
1003 * @brief Initialize the instance create params structure
1004 */
1005 Void RcmClient_Params_init(
1006 RcmClient_Params * params
1007 );
1009 /*
1010 * ======== RcmClient_releaseJobId ========
1011 */
1012 /*!
1013 * @brief Return a job id to the server and release all resources
1014 *
1015 * @param[in] handle Handle to an instance object
1016 *
1017 * @param[in] jobId The job id to be released
1018 */
1019 Int RcmClient_releaseJobId(
1020 RcmClient_Handle handle,
1021 UInt16 jobId
1022 );
1024 /*
1025 * ======== RcmClient_removeSymbol ========
1026 */
1027 /*!
1028 * @brief Remove a symbol and from the server function table
1029 *
1030 * Useful when unloading a DLL from the server.
1031 *
1032 * @param[in] handle Handle to an instance object
1033 *
1034 * @param[in] name The function name.
1035 */
1036 Int RcmClient_removeSymbol(
1037 RcmClient_Handle handle,
1038 String name
1039 );
1041 /*
1042 * ======== RcmClient_waitUntilDone ========
1043 */
1044 /*!
1045 * @brief Block until the specified message has been executed
1046 *
1047 * This function will wait until the remote function invoked by the
1048 * specified message has completed. Upon return from this call, the
1049 * message will contain the return value and the return context of
1050 * the remote function.
1051 *
1052 * @param[in] handle Handle to an instance object
1053 *
1054 * @param[in] msgId The message ID to wait for.
1055 *
1056 * @param[out] returnMsg A pointer to the return message or NULL
1057 * on error. The client must free this message.
1058 */
1059 Int RcmClient_waitUntilDone(
1060 RcmClient_Handle handle,
1061 UInt16 msgId,
1062 RcmClient_Message ** returnMsg
1063 );
1066 #if defined (__cplusplus)
1067 }
1068 #endif /* defined (__cplusplus) */
1070 /*@}*/
1072 #endif /* ti_grcm_RcmClient__include */