/*
 ******************************************************************************
 *  Copyright 1997 DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Intertask Mailbox Communication IMX
 *
 * File         :   imx.h
 *
 * Version      :   1.00
 *
 * Developed by :   Leon Westervoort.
 *
 * This file contains data- and prototypes of the DeltaLink Mailbox
 * Communication Interface.
 *
 */
#ifndef _IMX_DEFS_INCLUDED /* { */
#define _IMX_DEFS_INCLUDED 1

#ifndef HPUX
//#pragma pack(1)
#else
#pragma HP_ALIGN HPUX_WORD PUSH
#endif

/* Macro to compare two tags */

#define  IMX_CMPTAG( t1, t2) ( ! ( ((t1)->t_type == (t2)->t_type) && ((t1)->t_data == (t2)->t_data) ) )

/* define the IMX version */

#define   IMX_VERSION     0x03

/* define direction of data */

#define IMX_LOW_2_HIGH  0           /* LOW to HIGH addressing */
#define IMX_HIGH_2_LOW  1           /* HIGH to LOW addressing */

/* set the direction of the host */

#ifdef HOST_LOW_2_HIGH
#define HOST_DIRECTION IMX_LOW_2_HIGH
#else
#define HOST_DIRECTION IMX_HIGH_2_LOW
#endif

/* define the type of dataset identifying */

#define   IMX_TAG         0
#define   IMX_INDEX       1

/* define the maximum number of messages that can reside in a mailbox */

#define   IMX_MAX_MSG_COUNT   25000

/* IMX functionalities */

#define IMX_READ          0            
#define IMX_WRITE         1            
#define IMX_RCV           2            

/* define the different type of IMX mailboxes */

#define IMX_QUERY_CMD    0x00            /* IMX info message */
#define IMX_QUERY_RSP    0x01            /* IMX info message feed back */
#define IMX_QUERY_ERROR  0x09            /* IMX info message feed back */

#define IMX_READ_REQ     0x02            /* read request */
#define IMX_READ_RSP     0x03            /* read feed back */
#define IMX_READ_ERROR   0x0B            /* read feed back */

#define IMX_WRITE_REQ    0x04            /* write request */
#define IMX_WRITE_RSP    0x05            /* write feed back */
#define IMX_WRITE_ERROR  0x0D            /* write feed back */

#define IMX_RCV_ACT      0x06            /* unsolicited receive active */
#define IMX_RCV_RDY      0x07            /* unsolicited receive ready */
#define IMX_RCV_ERROR    0x0F            /* unsolicited receive ready */

#define IMX_MAX_TYPES    0x05            /* Maximum of imx types */

#define IMX_NO_FNC       0x00            /* No IMX functions supported */
#define IMX_QUERY_FNC    0x01            /* Query functionality */
#define IMX_READ_FNC     0x02            /* Read functionality */
#define IMX_WRITE_FNC    0x04            /* Query functionality */
#define IMX_RCV_FNC       0x08            /* Unsolicited Receive functionality */
#define IMX_ALL_FNC       0xFF            /* All functionalities */

/* define normal data write or encode data write */

#define IMX_NORMAL_WRITE    0
#define IMX_ENCODED_WRITE   1

/* define the different boundary addressing methods */

#define IMX_BIT_BND    0            /* boundaries on bit basis ( 1 char 1 bit ) */
#define IMX_BYTE_BND   1            /* boundaries on character basis ( 1 char ) */
#define IMX_WORD_BND   2            /* boundaries on word basis      ( 2 char ) */
#define IMX_LONG_BND   4            /* boundaries on long basis      ( 4 char ) */
#define IMX_DBL_BND    8            /* boundaries on double basis    ( 8 char ) */

/* define the info requests */

#define IMX_I_ALIVE     1           /* the sender of this message is alive */
#define IMX_I_DEAD      1           /* the sender of this message is dead */

/* IMX error numbers */

#define IMX_BAD_TYPE        50          /* bad message type */
#define IMX_NOT_FOUND       51          /* message with dataset control tag not found in queue */
#define IMX_NO_QUERY        52          /* no messages available to query */
#define IMX_BAD_RCVMBX      53          /* bad receive mailbox tag */
#define IMX_BAD_SNDMBX      54          /* bad mailbox send tag */
#define IMX_BAD_CTRL        55          /* bad dataset control tag */
#define IMX_NOT_ADJUST      56          /* message cannot be adjusted */
#define IMX_CDE_SIZE        57          /* operation to big for variable */
#define IMX_UNKNOWN_BOUND   58          /* unknown boundary */
#define IMX_FNC_NOT_SUPPORT 59          /* function not supported */
#define IMX_WRONG_INDEX     60          /* no message for this index present */
#define IMX_DS_NOT_DEFINED  61          /* the received remote dataset was not defined on this system */
#define IMX_NOT_REGISTERED  62          /* the received dataset was not registered */
#define IMX_MSG_NOT_QUEUED  63          /* WARNING: the message is not queued */
#define IMX_MSG_REJECTED    64          /* the message is rejected due through problems in the remote IMX */
#define IMX_BIT_ADDRESSING  65          /* illegal method of addressing bits on bit boundary */
#define IMX_X_WRITE         66          /* element cannot be written */ 
#define IMX_BUFFER          67          /* invalid buffer specified */ 
#define IMX_BLOCK           68          /* block write function possible */
#define IMX_MAX_MESSAGE     69          /* max. number of messaes in mailbox */

/*
 * IMX system information 
 */
typedef struct _IMXSYSTEM {

  id_t      task_id;                        /* FactoryLink task id of this IMX application */

  TAG       mbx;                            /* IMX mailbox of this IMX application */
  char      station_id;                     /* local station id number of this IMX user */

  ushort    functions;                      /* functions supported by the IMX application */

} IMXSYSTEM;

/*
 * lay-out of the IMX Message 
 */
typedef struct _IMXMSG {

  MBXMSG  mbx;              /* FactoryLink Mailbox Message */

  TAG     snd_mbx;          /*  mailbox tag to send to */

  MSG     buffer;            /* buffer information for this IMX message */

  uint    i;                /* i element in queue */
  uchar   rel_addr;         /* relative or absolute addressing ( 0 = absolute) */

} IMXMSG;

/* 
 * general lay-out of a IMX dataset
 */
typedef struct _IMXDS {

  char    name[ MAX_TAG_NAME + MAX_DIM_LENGTH +1];  /* tag name of dataset control tag */

  ushort  start;                                    /* start address */
  ushort  len;                                      /* length of data depending on boundary */

  uchar    boundary;                                /* boundary addressing */
  uchar    bnd_dir;                                 /* direction of boundary data */
  uchar    bit_dir;                                 /* direction of bit data */
  uchar    bnd_offset;                              /* addressing offset of boundary data */
  uchar    bit_offset;                              /* addressing offset of bit data */

  uint    ds_index;                                 /* index into dataset control tag array */

  ushort  origination;                              /* ds came from queue or from trigger */

  IMXMSG  msg;                                      /* pointer to IMX message */

  void    *u_data;                                  /* pointer to additional user dataset information */
  int     (*u_fnc)( struct _IMXDS *);               /* pointer to user function which will be called with events */

} IMXDS;

/*
 * message type and number of commands definition defined in element
 * 'MM_TYPE'
 */
typedef struct _IMXTYPE {

  u16 type:            4;    /* type of IMX message */

  u16 ident:           1;    /* use of MSG CTRL tag or address */
  u16 more:           1;    /* more data to come: yes or no  */
  u16 org_host_dir:    1;    /* set the originating host direction  */
  u16 reserved:       1;    /* reserved  */

  u16 station_id:      8;   /* station id of the sender of this message */

} IMXTYPE; 

/*
 * Definition of the 'MM_USER1' element in the MBXMSG structure
 */
typedef struct _MM_USER1 {

  u16 src_station:    8;   /* station id of the source of this message */
  u16 sequence:        8;   /* job sequence number */

} MM_USER1;

/*
 * lay-out for info header which will be placed before the user data
 */
typedef struct _IMXHDR {

  struct {                      /* structure with info of dataset */

    u16   version:    4;          /* version of IMX used */
    u16   handling:    1;          /* encoded or normal write */

    u16   reserved0:  3;          /* reserved */

    u16   bnd_dir:    1;          /* direction of boundary data */
    u16   bit_dir:    1;          /* direction of bit data */

    u16   bnd_start:  1;          /* start of boundary data */
    u16   bit_start:  1;          /* start of bit data */

    u16   boundary:    4;          /* boundary of basic data element */

  } i;

  u16       len;                 /* length of data */
  u16       start;               /* start address of data  */
  u16       cde;                 /* conversion code */

} IMXHDR;

extern uint             _Imx_q_num_active;            /* total number of active messages in the queue */
extern IMXSYSTEM        _Imx_system;
/*
 * functions prototypes of the IMX library
 */

#define    IMX_FNC_RTYPE                  int (***)( void *, VAL )
#define    IMX_FNC_ATYPE                  int (**)( void *, VAL )
#define    IMX_FNC_TYPE                  int (*)( void *, VAL )

int           Imx_Init                  ( IMXSYSTEM *);
int           Imx_Exit                  ( void);

int           Imx_Recv                  ( IMXSYSTEM *, IMXDS *);
int           Imx_Send                  ( IMXSYSTEM *, IMXDS *);
int           Imx_Send_Error            ( IMXSYSTEM *, IMXDS *, u16 );
void          Imx_Mirror                ( char *, ushort);
void          Imx_Cast                  ( IMXDS *, char);
void          Imx_Place_Data            ( IMXDS *, char);
int           Imx_Get_CDE_Size          ( ushort);
int           Imx_Buffer_Alloc          ( MSG *);

IMXDS *       Imx_Ds_Register           ( IMXDS *);
IMXDS *       Imx_Ds_R_Search           ( TAG *);
int           Imx_Ds_Prepare            ( IMXDS *, MSG *);
int           Imx_Ds_Query              ( IMXSYSTEM *, IMXDS *);
int           Imx_Ds_Queried            ( IMXDS *);
int           Imx_Ds_Remove             ( IMXSYSTEM *, IMXDS *);
int           Imx_Ds_Trigger            ( IMXSYSTEM *, IMXDS *);
int           Imx_Ds_Adjust             ( IMXDS *);
int           Imx_Ds_Evaluate_Write     ( IMXDS *);
int           Imx_Equal_Data            ( IMXDS *);

int           Imx_Event_Retrieve        ( TAG **, void ***, u32 *, IMX_FNC_RTYPE);
int           Imx_Event_Mbx             ( void *, VAL);
int           Imx_Event_Ds              ( void *, VAL);
int           Imx_Event_Query_Cmd       ( IMXSYSTEM *, IMXDS *);
int           Imx_Event_Query_Rsp       ( IMXSYSTEM *, IMXDS *);
int           Imx_Event_Check           ( void );

int           Imx_Q_Init                ( IMXSYSTEM *);
int           Imx_Q_Num                 ( IMXSYSTEM *, uint *);
int           Imx_Q_Query               ( IMXSYSTEM *, IMXDS *);
int           Imx_Q_Ds_Num_Srch         ( IMXSYSTEM *, IMXDS *, uint);
#define       Imx_Q_Ds_Srch( s, d)      Imx_Q_Ds_Num_Srch( (s), (d), _Imx_q_num_active)
int           Imx_Q_Msg_Remove          ( IMXSYSTEM *, IMXDS *);
int           Imx_Q_Num_Mbx             ( IMXSYSTEM *, TAG, uint*);

/* function which operates on the IMXHDR structure */

#define Imx_Get_Version( m)           ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->i.version)
#define Imx_Set_Version( m, v)        ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->i.version = (v))

#define Imx_Get_Handling( m)          ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->i.handling)
#define Imx_Set_Handling( m, v)       ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->i.handling = (v))

#define Imx_Set_Bnd_Dir( m, v)        ( (( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bnd_dir = (v))
#define Imx_Get_Bnd_Dir( m)           ( ( uchar)(( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bnd_dir)

#define Imx_Set_Bit_Dir( m, v)        ( (( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bit_dir = (v))
#define Imx_Get_Bit_Dir( m)           ( ( uchar)(( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bit_dir)

#define Imx_Set_Bnd_Offset( m, v)     ( (( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bnd_start = (v))
#define Imx_Get_Bnd_Offset( m)        ( ( uchar)(( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bnd_start)

#define Imx_Set_Bit_Offset( m, v)     ( (( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bit_start = (v))
#define Imx_Get_Bit_Offset( m)        ( ( uchar)(( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.bit_start)

#define Imx_Set_Boundary( m, v)       ( (( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.boundary = (v))
#define Imx_Get_Boundary( m)          ( ( uchar)(( IMXHDR *)((m)->msg.mbx.mm_msg.m_ptr))->i.boundary)

#define Imx_Set_Start( m, v)          ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->start = (v))
#define Imx_Get_Start( m)             ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->start )

#define Imx_Set_Len( m, v)            ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->len = (v))
#define Imx_Get_Len( m)               ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->len )

#define Imx_Set_CDE( m, v)            ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->cde = (v))
#define Imx_Get_CDE( m)               ( ((IMXHDR *)(m)->msg.mbx.mm_msg.m_ptr)->cde )


/* prototypes which opreate on the IMX_SYSTEM structure */

#define Imx_Sys_Get(  )               ( &_Imx_system )

#define Imx_Sys_Get_Task_Id( s)       ( (s)->task_id)
#define Imx_Sys_Set_Task_Id( s, v)    ( (s)->task_id = (v))

#define Imx_Sys_Get_Station_Id( s)    ( (s)->station_id)
#define Imx_Sys_Set_Station_Id( s, v) ( (s)->station_id = (v))

#define Imx_Sys_Get_Mbx( s)           ( (s)->mbx)
#define Imx_Sys_Set_Mbx( s, v)        ( memcpy( &(s)->mbx, &(v), sizeof( TAG)) )

#define Imx_Sys_Get_Functions( s)     ( (s)->functions)
#define Imx_Sys_Set_Functions( s, v)  ( (s)->functions |= (v))


/* prototypes which opreate on the IMXMSG structure */

#define Imx_Get_Type( m)              ( (( IMXTYPE *)&(m)->msg.mbx.mm_type)->type)
#define Imx_Set_Type( m, v)           ( (( IMXTYPE *)&(m)->msg.mbx.mm_type)->type = ( u16)(v))

#define Imx_Get_Org_Host_Dir( m)      ( (( IMXTYPE *)&(m)->msg.mbx.mm_type)->org_host_dir)
#define Imx_Set_Org_Host_Dir( m, v)   ( (( IMXTYPE *)&(m)->msg.mbx.mm_type)->org_host_dir = (v))

#define Imx_Get_Station_Id( m)         ( ( char)(( IMXTYPE *)&(m)->msg.mbx.mm_type)->station_id)
#define Imx_Set_Station_Id( m, v)      ( (( IMXTYPE *)&(m)->msg.mbx.mm_type)->station_id = ( char)(v))

#define Imx_Get_Job_Sequence( m)      ( (( MM_USER1 *)&(m)->msg.mbx.mm_user1)->sequence )
#define Imx_Set_Job_Sequence( m, v)   ( (( MM_USER1 *)&(m)->msg.mbx.mm_user1)->sequence = ( u8)(v) )

#define Imx_Get_Src_Station( m)       ( (( MM_USER1 *)&(m)->msg.mbx.mm_user1)->src_station )
#define Imx_Set_Src_Station( m, v)    ( (( MM_USER1 *)&(m)->msg.mbx.mm_user1)->src_station = ( u8)(v) )

#define Imx_Get_Ds_Ctrl( m)           ( ( TAG *)&((m)->msg.mbx.mm_user2) )
#define Imx_Set_Ds_Ctrl( m, v)        ( memcpy( ( char *)&(m)->msg.mbx.mm_user2, ( char *)&(v), sizeof( TAG)))

#define Imx_Get_R_Buffer( m)           ( &(m)->msg.buffer)
#define Imx_Set_R_Buffer( m, v)       ( memcpy( &(m)->msg.buffer, (v), sizeof( MSG)) )

#define Imx_Get_T_Buffer( m)           ( &(m)->msg.mbx.mm_msg)
#define Imx_Set_T_Buffer( m, v)       ( memcpy( &(m)->msg.mbx.mm_msg, (v), sizeof( MSG)) )

#define Imx_Get_U_Buffer( m)          ( ( char *)(m)->msg.mbx.mm_msg.m_ptr + sizeof( IMXHDR))
#define Imx_Reset_Buffer( m)          ( memset( ( char *)&((m)->msg.mbx.mm_msg), 0x00, sizeof( MSG)) )

#define Imx_Get_Snd_Mbx( m)           ( (m)->msg.snd_mbx )
#define Imx_Set_Snd_Mbx( m, v)        ( memcpy( &(m)->msg.snd_mbx, ( char *)&(v), sizeof( TAG)))

#define Imx_Get_Index( m)             ( (m)->msg.i )
#define Imx_Set_Index( m, v)          ( (m)->msg.i = (v))

#define Imx_Get_Active( )             ( _Imx_q_num_active ) 
#define Imx_Set_Active( v)            ( _Imx_q_num_active = 0) 

/* prototypes which operates on the IMXDS structure */

#define Imx_Get_Name( m)              ( (m)->name)
#define Imx_Set_Name( m, v)           ( strcpy( (m)->name, (v)) )

#define Imx_Get_Udata_Ptr( m)          ( (m)->u_data)
#define Imx_Set_Udata_Ptr( m, v)       ( (m)->u_data = (v) )

#define Imx_Get_Ufnc_Ptr( m)          ( (m)->u_fnc)
#define Imx_Set_Ufnc_Ptr( m, v)       ( (m)->u_fnc = (v) )

#ifndef HPUX
//#pragma pack()
#else
#pragma HP_ALIGN POP
#endif

#endif /* _IMX_DEFS_INCLUDED */
