/*
 ******************************************************************************
 *  Copyright 1994 DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Mailbox Communication Interface
 *
 * File         :   mci.h
 *
 * Version      :   2.00
 *
 * Developed by :   Leon Westervoort.
 *
 *                  DeltaLink b.v.
 *                  Saffierborch 6c
 *                  5241LN Rosmalen
 *                  The Netherlands.
 *                  Tel. (31) 4192-20025
 *                  Fax. (31) 4192-15251
 *
 * This file contains data- and prototypes of the DeltaLink Mailbox
 * Communication Interface.
 *
 */
#ifndef _MCI_DEFS_INCLUDED /* { */
#define _MCI_DEFS_INCLUDED 1

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

/* define the MCI version */

#define   MCI_VERSION     0x01

/* set the direction of the host */

#ifdef HOST_LOW_2_HIGH
#define HOST_DIRECTION MCI_LOW_2_HIGH
#else
#define HOST_DIRECTION MCI_HIGH_2_LOW
#endif

/* define the type of dataset identifying */

#define   MCI_TAG         0
#define   MCI_INDEX       1


/* define the different type of MCI mailboxes */

#define MCI_QUERY_CMD    0x00            /* MCI info message */
#define MCI_QUERY_RSP    0x01            /* MCI info message feed back */
#define MCI_QUERY_ERROR  0x09            /* MCI info message feed back */

#define MCI_READ_REQ     0x02            /* read request */
#define MCI_READ_RSP     0x03            /* read feed back */
#define MCI_READ_ERROR   0x0B            /* read feed back */

#define MCI_WRITE_REQ    0x04            /* write request */
#define MCI_WRITE_RSP    0x05            /* write feed back */
#define MCI_WRITE_ERROR  0x0D            /* write feed back */

#define MCI_RCV_ACT      0x06            /* unsolicited receive active */
#define MCI_RCV_RDY      0x07            /* unsolicited receive ready */
#define MCI_RCV_ERROR    0x0F            /* unsolicited receive ready */

#define MCI_MAX_TYPES    0x05            /* Maximum of mci types */

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

#define MCI_NORMAL_WRITE    0
#define MCI_ENCODED_WRITE   1

/* define the different boundary addressing methods */

#define MCI_BIT_BND    0            /* boundaries on bit basis ( 1 char 1 bit ) */
#define MCI_BYTE_BND   1            /* boundaries on character basis ( 1 char ) */
#define MCI_WORD_BND   2            /* boundaries on word basis      ( 2 char ) */
#define MCI_LONG_BND   4            /* boundaries on long basis      ( 4 char ) */
#define MCI_DBL_BND    8            /* boundaries on double basis    ( 8 char ) */

/* define direction of data */

#define MCI_LOW_2_HIGH  0           /* LOW to HIGH addressing */
#define MCI_HIGH_2_LOW  1           /* HIGH to LOW addressing */

/* define the info requests */

#define MCI_I_ALIVE     1         /* the sender of this message is alive */
#define MCI_I_DEAD      1         /* the sender of this message is dead */

/* MCI error numbers */

#define MCI_FLBASE_ERROR    400      /* error numbers of FactoryLink functions */

#define MCI_BAD_TYPE        100        /* bad message type */
#define MCI_NOT_FOUND       101        /* message with dataset control tag not found in queue */
#define MCI_NO_QUERY        102        /* no messages available to query */
#define MCI_BAD_RCVMBX      103        /* bad receive mailbox tag */
#define MCI_BAD_SNDMBX      104        /* bad mailbox send tag */
#define MCI_BAD_CTRL        105        /* bad dataset control tag */
#define MCI_NOT_ADJUST      106        /* message cannot be adjusted */
#define MCI_CDE_SIZE        107        /* operation to big for variable */
#define MCI_UNKNOWN_BOUND   108        /* unknown boundary */

/* lay-out of the MCI Message */

typedef struct _MCIMSG {

  MBXMSG  mbx;              /* FactoryLink Mailbox Message */

  TAG     rcv_mbx;          /*  mailbox tag to receive from */
  TAG     snd_mbx;          /*  mailbox tag to send to */

  void    *buffer;          /* pointer to user buffer with DATA and MCI HEADER */
  u16     max_len;          /* maximum length of data */

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

} MCIMSG;

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

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

  u16 ident:         1;    /* use of MSG CTRL tag or address */
  u16 reserved:      1;    /* reserved */

  u16 nr_commands:   10;   /* number of commands */

} MCITYPE; 

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

  struct {                    /* structure with info of dataset */

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

    u16 	reserved0:   3;    /* reserved */

    u16 	bound_dir:   1;    /* direction of data */
    u16 	bit_dir:     1;    /* direction of data */

    u16 	bound_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 */

} MCIHDR;


/* normal prototypes of implemented functions */

int Mci_Init            ( id_t);
int Mci_Alloc_Buffer    ( id_t, MCIMSG *);
MCIMSG * Mci_Alloc_Msg  ( id_t, uint);

int    Mci_Nr_Msg          ( id_t, TAG, uint *);
int    Mci_Recv            ( id_t, MCIMSG *);
int    Mci_Send            ( id_t, MCIMSG *);
int    Mci_Trigger         ( id_t, MCIMSG *);
int    Mci_Query_Msg       ( id_t, MCIMSG *);
int    Mci_Srch_Msg        ( id_t, MCIMSG *);
int    Mci_Adjust_Msg      ( MCIMSG *);
void   Mci_Cast            ( MCIMSG *, char);
void   Mci_Place_Data      ( MCIMSG *, char);

int    Mci_Get_CDE_Size    ( ushort);

/*
 * define the prototypes which operate on a normal data MCIMSG.
 * Functions which operate on the MCIMSG structure and the MBXMSG. These functions operate
 * always in Host format. 
 */

#define Mci_Get_Buffer( m)            ( ( char *)(m)->buffer + sizeof( MCIHDR))
#define Mci_Set_Buffer( m, v)         ( (m)->buffer = (v))

#define Mci_Get_BufLen( m)            ( (m)->max_len - sizeof( MCIHDR))
#define Mci_Set_BufLen( m, v)         ( (m)->max_len = (v))

#define Mci_Get_Type( m)              ( (( MCITYPE *)&(m)->mbx.mm_type)->type)
#define Mci_Set_Type( m, v)           ( (( MCITYPE *)&(m)->mbx.mm_type)->type = ( u16)(v))

#define Mci_Get_Id( m)                ( (( MCITYPE *)&(m)->mbx.mm_type)->ident)
#define Mci_Set_Id( m, v)             ( (( MCITYPE *)&(m)->mbx.mm_type)->ident = (v))

#define Mci_Get_Nr_Commands( m)       ( (( MCITYPE *)&(m)->mbx.mm_type)->nr_commands)
#define Mci_Set_Nr_Commands( m, v)    ( (( MCITYPE *)&(m)->mbx.mm_type)->nr_commands = ( u16)(v))

#define Mci_Get_JobSequence( m)       ( ((m)->mbx.mm_user1) )
#define Mci_Set_JobSequence( m, v)    ( ((m)->mbx.mm_user1) = (v))

#define Mci_Get_MsgCtrl( m)           ( ( TAG *)&((m)->mbx.mm_user2) )
#define Mci_Set_MsgCtrl( m, v)        ( memcpy( &((m)->mbx.mm_user2), &(v), sizeof( TAG)))

#define Mci_Get_Snd_Mbx( m)           ( (m)->snd_mbx )
#define Mci_Set_Snd_Mbx( m, v)        ( (m)->snd_mbx = (v))

#define Mci_Get_Rcv_Mbx( m)           ( (m)->rcv_mbx )
#define Mci_Set_Rcv_Mbx( m, v)        ( (m)->rcv_mbx = (v))

#define Mci_Get_Index( m)             ( (m)->i )
#define Mci_Set_Index( m, v)          ( (m)->i = (v))

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

#endif /* _MCI_DEFS_INCLUDED */
