#ifndef _aplmt_itc_imsgapi_h_
#define _aplmt_itc_imsgapi_h_
/*----------------------------------------------------------------------------
** SUMMARY: Inter-Thread Communications Message Interfaces (IMSG)
**
** DESCRIPTION:
**  This file provides the interface for handling ITC messages. All methods
**  in these interface apply to all ITC models.  See imboxapi.h for a detailed 
**  description of terms, ITC, and the various models supported. 
**
** CONFIGURATION 
** -------------
**  COMPILE:        USE_APLMT_ITC_MODEL_XSMALL
**                  USE_APLMT_ITC_MODEL_SMALL
**                  USE_APLMT_ITC_MODEL_NORMAL
**                  USE_APLMT_ITC_MODEL_LARGE
**                  USE_APLMT_ITC_INCLUDE_ERROR_CHECKING
**                  USE_APLMT_INIT_IMSG_IN_SYSTEM_INIT
**                                            
**  APPLICATION:    The application can override the following types/defintions
**                      AplmtImsgData
**                      AplmtImsgHdl
**                      OPTION_APLMT_IMSG_MAX_MESSAGES
**                      OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA
**                      OPTION_APLMT_IMSG_BEGIN_REQUEST_MESSAGES
**                      OPTION_APLMT_IMSG_END_REQUEST_MESSAGES
**
**  PLATFORM:       none.
**
**
**  NOTES:
**  1. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called from interrupt service routines.
**  2. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called before the platform's kernel is running.
**  3. Unless explicitly stated otherwise, all of the following methods ARE 
**     thread-safe.
**  4. For efficency/optimization some methods are 'inlined'.  The inlining
**     is done by using the preprocessor/macros.  The application should
**     treat all methods as function calls and not rely on the fact they may
**     be currently defined as macros.
----------------------------------------------------------------------------*/

#include "aplcfg.h"                 /* For: Application configuration */
#include "apl/types/types.h"        /* For: basic types */

#ifdef __cplusplus
extern "C" {
#endif


/*-------------- ERRORS ----------------------------------------------------*/
/** An invalid message handle was specified when calling an Aplmt_imsgXXX() 
    method. Note: Error Checking must be enable for this error to occur.
 */
/***/
#define APLMT_ERRSTR_IMSG_INVALID_HANDLE        "IMSG: A invalid message handle was used when making a all to a IMSG method."
/***/
#define APLMT_ERR_IMSG_INVALID_HANDLE           _APLMT_ERR_IMSG_INVALID_HANDLE


/*-------------- CONSTANTS -------------------------------------------------*/
/** NULL Message Handle. */
#define APLMT_NULL_IMSG_HANDLE                      _APLMT_NULL_IMSG_HANDLE

/** Pre-defined message Identifier.  This ID indicates that
    the mailbox was signal (and there is no actual message)
 */
#define APLMT_IMSG_MBOX_SIGNALED                    _APLMT_IMSG_MBOX_SIGNALED  

/** Pre-defined message Identifier.  This ID indicates that
    the mailbox 'timed-out' and NO message was received
 */
#define APLMT_IMSG_MBOX_TIMED_OUT                   _APLMT_IMSG_MBOX_TIMED_OUT

/** Response message Identifer.  The application arithmetically ADDS this 
    symbol with the original request message identifier to create the 
    response message identifier.  NOTE: This symbol only has meaning if using
    SMALL, NORMAL, or LARGE models.
 */
#define APLMT_IMSG_RESPONSE_ID                      _APLMT_IMSG_RESPONSE_ID


/** Message Identifiers: START/END of Messages WITH data 
    (Note: Only applies to models: XS, S, N) 
*/
#define APLMT_IMSG_BEGIN_MSGIDS_WITHDATA            0
#define APLMT_IMSG_END_MSGIDS_WITHDATA              (OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA-1)

/** Message Identifiers: START/END of Messages WITHOUT data 
    (Note: Only applies to models: XS, S, N)
*/
#define APLMT_IMSG_BEGIN_MSGIDS_NODATA              (APLMT_IMSG_END_MSGIDS_WITHDATA+1)
#define APLMT_IMSG_END_MSGIDS_NODATA                (OPTION_APLMT_IMSG_MAX_MESSAGES-1)


/** Maximum number of messages (default value) 
    NOTES:
    o This parameter includes both the data-less messages and messages
      with data.
    o This parameter does NOT INCLUDE response messages.  The number of
      response message is automagically added to this value.  The default
      is to create a response message for every request message, i.e the
      actual allocated number of raw messages is 2x the value.  See below
      for more details about request/response message allocation.
*/
#ifndef OPTION_APLMT_IMSG_MAX_MESSAGES
#define OPTION_APLMT_IMSG_MAX_MESSAGES              16
#endif

/** Number of message that can contain data (default value) */
#ifndef OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA
#define OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA    8
#endif

/*
** NOTE: The following Symbols are used to fine-tune/tweak the allocation of
**       response message when using ITC models SMALL and/or NORMAL.  The
**       default is to allocate a response for all request messages and all
**       messages are assumed to be request messages.
*/
/** Start of Request messages.  Default is All message are request messages */
#ifndef OPTION_APLMT_IMSG_BEGIN_REQUEST_MESSAGES
#define OPTION_APLMT_IMSG_BEGIN_REQUEST_MESSAGES    0
#endif

/** Start of Request messages.  Default is All message are request messages */
#ifndef OPTION_APLMT_IMSG_END_REQUEST_MESSAGES
#define OPTION_APLMT_IMSG_END_REQUEST_MESSAGES      (OPTION_APLMT_IMSG_MAX_MESSAGES-1)
#endif



/*-------------- TYPES -----------------------------------------------------*/
/** Mailbox Handle.  For the models: XS, S, N, the default limits the maximum 
    number of messages to 254 
*/
#ifndef AplmtImsgHdl
#define AplmtImsgHdl                            _AplmtImsgHdl
#endif

/** Message Identifier. (For models XS,S,N: Map Message IDs directly to Message Handles) */
#define AplmtImsgId                             _AplmtImsgId

/** Message data. Default is the size holds a pointer */
#ifndef AplmtImsgData
#define AplmtImsgData                           void*
#endif
                       

/*-------------- INLINE IMPLEMENTATION -------------------------------------*/
#include "aplmt/itc/iprivate.h"             /* For: inline implementation */


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method is used to initalize the message sub-system.  This method
    must be called BEFORE calling any other Aplmt_imsgXXXX() or 
    Aplmt_imboxXXX() methods.
    NOTES:
        o If USE_APLMT_INIT_IMSG_IN_SYSTEM_INIT is defined, then APL will
          internally call this method as part of the Aplmt_systemInit()
        o This method has no meaning if the application is using the LARGE
          model (i.e. do not need to call, but if called does nothing).

    Prototype:
        void Aplmt_imsgInitialize(void);
 */
#define Aplmt_imsgInitialize                    _Aplmt_imsgInitialize

/** This method is used to initialize and identify the ITC message.  The 
    client is required to call this method EVERY TIME (and before) it 
    posts the message.  The server should NEVER call this message.
    NOTES:
        o The application is required allocate/create the message.  Use
          the data type: AplmtImsg to allocate a concrete message instance.
        o The parameter 'idForTheMessage' must be a value between 0 and
          0x7FFE.
        o Data Types: AplmtImsg* == AplmtImsgHdl. The application must
          provide an actual INSTANCE, not just a pointer, to the message
          being initialized.
        o This method is ONLY valid/available when using the LARGE model.
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        void Aplmt_imsgInit( AplmtImsg* messageToInit, AplmtImsgId idForTheMessage );
 */
#define Aplmt_imsgInit                          _Aplmt_imsgInit


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method returns the Identifier for the specified message.
    The message Identifier should be used when examing what the
    message is (i.e. to be used in the 'switch' statement of
    message processing loop). The message identifier also indicates if
    the specified message is a request or response message.  See
    the description above of APLMT_IMSG_RESPONSE_ID for more details.
    NOTES:
        o There are two predefined message ID that can be returned
          by this call, APLMT_IMSG_MBOX_SIGNALED and APLMT_IMSG_MBOX_TIMED_OUT.
          See description above for more details.
        o It is OK to ALWAYS pass the results of Aplmt_imboxGetNextMessage()
          to this method.  It proper handles the 'non-message' return
          codes generated by the mailbox get-next-message method(s).
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        AplmtImsgId  Aplmt_imsgGetId( AplmtImsgHdl msg );
 */
#define Aplmt_imsgGetId                         _Aplmt_imsgGetId
        
/** This method returns non-zero (true) if the specified message is
    currently being 'processed'.  A message is consider 'in-process'
    from the time the client calls Aplmt_imboxPost(), till the sever
    calls Aplmt_imsgReturnToSender().  The client should never 
    operate-on/access a message that is 'in-use'.
    NOTES: 
        o If the message in question was originally posted using
          Aplmt_imboxPostRequest(), this method has no meaning
          and should NOT be used on the message.  Under this
          scenerio, the response message is the handshake and/or
          acknowledgement that the client now has ownership of
          the message.  Also, it has no meaing if the message
          was posted using Aplmt_imboxPostSync() given the semantics
          of the Aplmt_imboxPostSync() (i.e. the client gets
          ownership of the message when Aplmt_imboxPostSync()
          returns).
        o When using the LARGE model, the client can NOT call
          this method until it has first called Aplmt_imsgInit().
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        AplBool Aplmt_imsgIsInUse( AplmtImsgHdl msg );
 */
#define Aplmt_imsgIsInUse                       _Aplmt_imsgIsInUse

/** This method returns non-zero (true) if the specified message
    has a data associated with it. 
    NOTES: 
        o This method has no meaning if the application has set 
          OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA to zero.
        o When using the LARGE model, this method always returns
          true.
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        AplBool Aplmt_imsgHasData( AplmtImsgHdl msg );
 */
#define Aplmt_imsgHasData                       _Aplmt_imsgHasData

/** This method returns the data associated with the specified message.
    This method should only be called the the OWNER of the message (i.e. 
    the ITC client before its posts the message; or the ITC server after 
    it receives message and before it calls return-to-sender). The results 
    are undefined if the specified message does not contain data. Use 
    Aplmt_imsgHasData() to determine if the message actually contains data. 
    NOTES: 
        o This method has no meaning if the application has set 
          OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA to zero.
        o This message is always valid for the LARGE model (since
          all message in the LARGE model have data).
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        AplmtImsgData Aplmt_imsgGetData( AplmtImsgHdl msg );
 */
#define Aplmt_imsgGetData                       _Aplmt_imsgGetData

/** This method 'binds' the specified data parameter to the specified
    message.  This method should only be called the the OWNER of
    the message (i.e. the ITC client before its posts the message; or
    the ITC server after it receives message and before it calls
    return-to-sender). The results are undefined if the specified message 
    does not contain data. Use Aplmt_imsgHasData() to determine if the 
    message actually contains data. 
    NOTES:
        o This method has no meaning if the application has set 
          OPTION_APLMT_IMSG_MAX_MESSAGES_WITH_DATA to zero.
        o This message is always valid for the LARGE model (since
          all message in the LARGE model have data).
        o This method CAN be called from an interrupt service 
          routine.

    Prototype:
        void Aplmt_imsgPutData( AplmtImsgHdl msg, AplmtImsgData data );
 */
#define Aplmt_imsgPutData                       _Aplmt_imsgPutData
 
/** This method is used by the SERVER to relinquish ownership of 
    the specified message. NOTE: This method does NOT NECCESARLY means 
    that the server is done with its processing, only that is no longer 
    has/needs ownership of the message. 

    Prototype:
        void Aplmt_imsgReturnToSender( AplmtImsgHdl msg );
 */
#define Aplmt_imsgReturnToSender                _Aplmt_imsgReturnToSender



#ifdef __cplusplus
}
#endif
/*--------------------------------------------------------------------------*/
#endif  /* end _aplmt_itc_imsgapi_h_ */

