#ifndef _TCP_T_H_
#define _TCP_T_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <pthread.h>
#endif

#include <ctype.h>
#ifndef WIN32
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#ifndef __USE_MISC
#define __USE_MISC
#endif
#ifndef CRTSCTS
#define CRTSCTS  020000000000
#endif
#include <errno.h>
#include <termios.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef WIN_DLL
#define EXPORT __declspec(dllexport) /* for Windows DLL */
#else
#define EXPORT
#endif

#ifdef WIN32
#define dev_t               HANDLE
#define socket_t            SOCKET
typedef int socklen_t;
#else
#define dev_t               int
#define socket_t            int
#define closesocket         close
#endif

#ifndef MAXCLI
#define MAXCLI              32          /* max client connection for tcp svr */
#endif

#ifndef MAXSTRPATH
#define MAXSTRPATH  1024                /* max length of stream path */
#endif

#ifndef TCPBUFSIZE
#define TCPBUFSIZE  4096                /* max length of stream path */
#endif

typedef struct {            /* tcp control type */
    int state;              /* state (0:close,1:wait,2:connect) */
    char saddr[256];        /* address string */
    int port;               /* port */
    struct sockaddr_in addr; /* address resolved */
    socket_t sock;          /* socket descriptor */
    int tcon;               /* reconnect time (ms) (-1:never,0:now) */
    unsigned int tact;      /* data active tick */
    unsigned int tdis;      /* disconnect tick */
} tcp_t;

typedef struct tcpsvr_tag { /* tcp server type */
    tcp_t svr;              /* tcp server control */
    tcp_t cli[MAXCLI];      /* tcp client controls */
} tcpsvr_t;

typedef struct {            /* tcp cilent type */
    tcp_t svr;              /* tcp server control */
    int toinact;            /* inactive timeout (ms) (0:no timeout) */
    int tirecon;            /* reconnect interval (ms) (0:no reconnect) */
} tcpcli_t;

typedef struct {
    char    path[MAXSTRPATH];      // path
    void*   handle;                // callback
} thread_tcpclient_arg;

EXPORT tcpsvr_t *opentcpsvr(const char *path, char *msg);
EXPORT void closetcpsvr(tcpsvr_t *tcpsvr);
/* read tcp server -----------------------------------------------------------*/
EXPORT int readtcpsvr(tcpsvr_t *tcpsvr, unsigned char *buff, int n, char *msg);
EXPORT int writetcpsvr(tcpsvr_t *tcpsvr, unsigned char *buff, int n, char *msg);
/* update tcp server ---------------------------------------------------------*/
EXPORT void updatetcpsvr(tcpsvr_t *tcpsvr, char *msg);
/* accept client connection --------------------------------------------------*/
EXPORT int accsock(tcpsvr_t *tcpsvr, char *msg);
EXPORT int statetcpsvr(tcpsvr_t *tcpsvr);
EXPORT int statextcp(tcp_t *tcp, char *msg);
/* get extended state tcp server ---------------------------------------------*/
EXPORT int statextcpsvr(tcpsvr_t *tcpsvr, char *msg);

/* open tcp client -----------------------------------------------------------*/
EXPORT tcpcli_t *opentcpcli(const char *path, char *msg);
/* close tcp client ----------------------------------------------------------*/
EXPORT void closetcpcli(tcpcli_t *tcpcli);
/* read tcp client -----------------------------------------------------------*/
EXPORT int readtcpcli(tcpcli_t *tcpcli, unsigned char *buff, int n, char *msg);
/* write tcp client ----------------------------------------------------------*/
EXPORT int writetcpcli(tcpcli_t *tcpcli, unsigned char *buff, int n, char *msg);
/* get state tcp client ------------------------------------------------------*/
EXPORT int statetcpcli(tcpcli_t *tcpcli);
/* get extended state tcp client ---------------------------------------------*/
EXPORT int statextcpcli(tcpcli_t *tcpcli, char *msg);


#ifdef __cplusplus
}
#endif

#endif // _TCP_T_H_