//
//   File:    CPAMINTERFACE.h
//   Created: Cho Chan and Kun Jiang
//   Date:    2/26/99
//
//   This file contains the interface that defines all the messages being
//  transferred via TCP/IP in the CPAM-compliant protocol.
//
 

#ifndef CPAMINTERFACE_H
#define CPAMINTERFACE_H
#include <stdlib.h>
 

/* creates a unique msgid as long as c is unique */
#define CPAMID(c) ((((UInt16)c) << 8) + (UInt16)c)

/*
 * The followings define the msgid's for the requests
 * to call each of the 9 CPAM primitives and the replies
 * of them.
 */

/* requests from client */
#define kInvoke CPAMID('i')
#define kSetUp  CPAMID('s')
#define kExamine CPAMID('e')
#define kEstimate CPAMID('m')
#define kExtract CPAMID('x')
#define kTerminate CPAMID('t')
#define kSetParam CPAMID('p')
#define kGetParam CPAMID('g')
#define kTerminateAll CPAMID('a')

/* replies from server */
#define kInvokeRpy CPAMID('I')
#define kSetUpRpy  CPAMID('S')
#define kExamineRpy CPAMID('E')
#define kEstimateRpy CPAMID('M')
#define kExtractRpy CPAMID('X')
#define kTerminateRpy CPAMID('T')
#define kSetParamRpy CPAMID('P')
#define kGetParamRpy CPAMID('G')
#define kTerminateAllRpy CPAMID('A')
#define kEstGetpExtrRpy CPAMID('W')

/* GenType requests */
#define kGenTypeRequest CPAMID('r')
/* Name requests */
#define kNameRequest CPAMID('n')

/* macros for different lengths */
#define METHOD_NAME_LEN 1024
#define CLIENT_ID_LEN 256
#define CALL_ID_LEN 4
#define MSG_HDR_LEN 4
#define GENTYPENAMESIZE 256

/* different types used in the protocol */
typedef unsigned short UInt16;
typedef unsigned int UInt32;
typedef char ChaimsClientID[CLIENT_ID_LEN];
typedef long ChaimsCallID;
enum ChaimsInvokeStatus {NOT_DONE = 0, DONE, ERR};

/* a message has to be prefixed by msgid and msgLen */
#define MSG_HEADER \
UInt16 msgid ;\
UInt16 msgLen \

/*
 *  structs to faciliate requests from client
 */

typedef struct GeneralMsg {
  MSG_HEADER;
} GeneralMsg ;
 

typedef struct InvokeMsg {
  MSG_HEADER;
  ChaimsClientID clientID ;
  char methodName[METHOD_NAME_LEN]; /* may not be just 1k, but 1k should be enough*/
  int numParameters;
} InvokeMsg ;

typedef struct SetUpMsg {
  MSG_HEADER;
  ChaimsClientID clientID;
} SetUpMsg ;

typedef struct TerminateAllMsg {
  MSG_HEADER;
  ChaimsClientID clientID;
} TermainateAllMsg;

typedef struct TerminateMsg {
  MSG_HEADER;
  ChaimsCallID callID;
} TerminateMsg ;

typedef struct ExamineMsg {
  MSG_HEADER;
  ChaimsCallID callID;
} ExamineMsg ;

typedef struct EstimateMsg {
  MSG_HEADER;
  ChaimsClientID clientID;
  char  methodName[METHOD_NAME_LEN];
  int numNames;
 
} EstimateMsg ;
 
typedef struct ExtractMsg {
  MSG_HEADER;
  ChaimsCallID callID;
  int numNames;
} ExtractMsg ;

typedef struct SetParamMsg {
  MSG_HEADER;
  ChaimsClientID clientID;
  int numParameters;
} SetParamMsg ;

typedef struct GetParamMsg {
  MSG_HEADER;
  ChaimsCallID callID;
  int numNames;
} GetParamMsg ;

/*
 *  structs to faciliate replies from server
 */

typedef struct GeneralRpy {
/*
 * GeneralRpy can be used to reply for receipt of TERMINATEALL,
 * TERMINATE, SETPARAM, SETUP which do not have any reply parameters
 */
  MSG_HEADER;
} GeneralRpy ;

typedef struct InvokeRpy {
  MSG_HEADER;
  ChaimsCallID callID;
  int sequence;
} InvokeRpy ;

typedef struct ExamineRpy {
  MSG_HEADER;
  UInt16 status;  /* will be assigned with variables of type
                   * ChaimsInvokeStatus
                   */
}ExamineRpy;

// This reply message is shared by Estimate, GetParameter and Extract calls
typedef struct EstGetpExtrRpy {
  MSG_HEADER;
  int sequence;
  int nameSize;
  char name[GENTYPENAMESIZE];
  int  valueSize;
  char value[1];
} EstGetpExtrRpy;

typedef struct SetParamRpy {
  MSG_HEADER;
  int sequence;
} SetParamRpy;

typedef struct SetUpRpy {
  MSG_HEADER;
} SetUpRpy;

typedef struct TerminateRpy {
  MSG_HEADER;
} TerminateRpy;

typedef struct TerminateAllRpy {
  MSG_HEADER;
} TerminateAllRpy;

/* struct to facilitate GenType transfers */
typedef struct GenTypeRequest {
 MSG_HEADER;
 int sequence; /* act as an ack */
        int nameSize; /* actual length of the name string */
 char name[GENTYPENAMESIZE];
 int  valueSize;
 char value[1]; /* variable size depending on the previous variable */
} GenTypeRequest;

/* struct to facilitate Name transfers */
typedef struct NameRequest {
  MSG_HEADER;
  int sequence; /* act as an ack */
  int nameSize; /* actual length of the name string */
  char name[GENTYPENAMESIZE];
} NameRequest;

#endif CPAMINTERFACE_H