#include "Error.h"

#define TEST

#define P0_VERSION 0

#define P0_ERROR 0
#define P0_ORIENTATION_REQUEST 1
#define P0_ORIENTATION_RESPONSE 2
#define P0_ACCESS_INITIALIZE 3		/* init + change */
#define P0_ACCESS_CHANGE 4
#define P0_ACCESS_RESPONSE 5
#define P0_ACCESS_UPGRADE 6		/* async reply for queues */
#define P0_STATUS_QUERY 7		/* ping */
#define P0_STATUS_RESPONSE 8
#define P0_SECURITY 9			/* extra authentication proto */
#define P0_STATE 10
#define P0_STATE_REPLY 11
#define P0_REDUCE 12
#define P0_REDUCE_ACK 13

#define SERVERVEC ((1 << P0_STATE) | (1 << P0_STATE_REPLY) | \
		   (1 << P0_REDUCE) | (1 << P0_REDUCE_ACK))

#define ISSERVERPACKET(x) (0 != (SERVERVEC & (1 << x)))

#define E_ACCESSDENIED 1	/* user/machine hasn't access */
#define E_PACKAGEUNKNOWN 2	/* server doesn't know package */
#define E_BADPACKET 3		/* packet couldn't be parsed */
#define E_BADPROTO 4		/* useful? */
#define E_SERVERLOSSAGE 5	/* server problems prevent completion */
#define E_NORESOURCES 6		/* no licenses to grant request */
#define E_CLUELESS 7		/* server doesn't know what's going on */

#define N_BM 3
#define N_MB N_BM
#define N_MC 3
#define N_retry 3
#define N_storedPools 3

#define N_reduce 3		/* number of packets to exchange */
#define T_reduce 5		/* time between packets */
#define F_reduce 2		/* number of failures to give up on */

#ifdef TEST
#define T_clueless 3
#define T_update 10
#define T_slop 3
#define T_ping 10
#define T_split 120
#define T_retry 1
#else
#define T_clueless 20
#define T_update 60
#define T_slop 20
#define T_ping 500
#define T_split 3600
#define T_retry 10
#endif

#define T_MB (T_update + T_retry * (N_retry + 1))
#define T_BM T_MB

typedef struct _P0Packet
{
  Card16 version;
  Card16 type;
  Card16 context;
  Card16 length;
  char *current;
  char *end;
  Packet *packet;
} P0Packet;

extern Trap P0_PutHeader(P0Packet *packet);
extern Trap P0_GetHeader(P0Packet *packet);
extern Trap P0_PutString(P0Packet *packet, char *string);
extern Trap P0_GetString(P0Packet *packet, char **string);
extern Trap P0_PutCard16(P0Packet *packet, Card16 card);
extern Trap P0_GetCard16(P0Packet *packet, Card16 *card);
extern Trap P0_PutCard32(P0Packet *packet, Card32 card);
extern Trap P0_GetCard32(P0Packet *packet, Card32 *card);
extern Trap P0_PutLength(P0Packet *packet);
