
#ifndef _INCLUDED_gap_connection
#define _INCLUDED_gap_connection

#include "prlock.h"
#include "dbll.h"
#include "GDisp.h"
#include "GDispSem.h"
#include "ASPipe.h"
#include "ASock.h"
#include "mq.h"

typedef enum conn_state {
    CONN_CLOSED = 0,
    CONN_GET_ADDRESS = 1,
    CONN_CONNECTED = 2,
    CONN_SAY_HELLO = 3,
    CONN_WORK = 4,
    CONN_CLOSING = 5,
    CONN_DELETED = -1
} conn_state_t;

typedef struct conn_struct conn_t;

typedef struct gap_conn_ctx_struct gap_conn_ctx_t;

#define CONN_READ_TIMEOUT 20000 /* 20 seconds */
#define CONN_RES_TIMEOUT 20000 /* 20 seconds */
#define CONN_CONNECT_TIMEOUT 20000 /* 20 seconds */

#define CONN_READ_BUFFER_SIZE 16384

#define CONN_ELIMBO -1001
#define CONN_ERESOLV -1002

void conn_new_server(gap_conn_ctx_t *cx,
		     GDisp *worker,
		     ASock *asock,
		     const char *host, int port,
		     void (*recv_cb)(void *, char *, unsigned int),
		     void *recv_ctx,
		     void (*close_ack)(void *),
		     void *close_ctx,
		     conn_t **conn);

void conn_open(gap_conn_ctx_t *cx,
	       GDisp *worker, 
	       const char *host, unsigned short port,
	       void (*recv_cb)(void *, char *, unsigned int),
	       void *recv_ctx,
	       void (*open_ack)(void *, int, void *),
	       void (*close_ack)(void *),
	       void *data);

conn_t *conn_open_s(gap_conn_ctx_t *cx,
		    GDisp *worker, 
		    const char *host, int port,
		    void (*recv_cb)(void *, char *, unsigned int),
		    void *recv_ctx,
		    void (*close_ack)(void *),
		    void *data);

void gap_conn_delete(conn_t *conn);

/* int conn_write(conn_t *conn, const char *data, int data_len); */

void conn_async_write(conn_t *conn,
		      void (*ack)(void *, int rc), void *ctx, 
		      char *data, unsigned int data_len);

void conn_async_printf(conn_t *conn,
		       void (*ack)(void *, int), void *ctx,
		       const char *format, ...);

void conn_async_printf_and_write(conn_t *conn,
				 void (*ack)(void *, int), void *ctx,
				 char *data, unsigned int data_len,
				 const char *format, ...);


int conn_readline(conn_t *conn, char **line);

void conn_unrecv(conn_t *conn, char *buf, unsigned int len);

gap_conn_ctx_t *conn_init_client(GDispCx *gdc);

gap_conn_ctx_t *conn_init_server(GDispCx *gdc,
				 struct in_addr *ina,
				 unsigned short port, 
				 int (*acceptable_connection)(void *,
						struct sockaddr *, socklen_t),
				 void (*new_connection)(void *, ASock *,
							GDisp *, char *host),
				 void *cx);

void conn_exit(gap_conn_ctx_t *cx);

void conn_trace(conn_t *conn, const char *line, int len, int direction);


#endif /* _INCLUDED_gap_connection */





