/*====================================================================

        tlayer.h   headerfile used with tlayer.c -DHOST || -DTARGET

                        Version: 1.0    July 12, 1996
                        Author:  Knut Oedman, Telelogic, Sweden
                                        knut.odman@telelogic.se
             Original in delivery SDT 3.5

						Version 1.1 June 25, 1997
						Author:  Knut Odman, Telelogic Princeton, USA
										kod@telelogic.com
			Original in delivery SDT 3.2
				# Added UseTimeout, read from tarsim.cfg,
				# makes it possible to suspend target or set breakpoints
				# in a debugger without target terminating.
				# Added timeout and ping to check if SimUI is alive, if
				# not terminate self and target.
				# Updated VxWorks integration.
				# New integration for Tandem.
				# Reduced risk for bind error on target by new uppdated
				# makesocket() for Target and shutdown call on xCloseSocket().
            # Support for Windows NT as host. Without debug/log.

======================================================================*/

#if defined(_Windows) || defined(_WINDOWS) || defined(__WIN32__)\
	|| defined(WIN32) || defined(__BORLANDC__)
#ifndef WINDOWS
#define WINDOWS
#endif
#endif

#ifdef VXWORKS_SDT
#include <vxWorks.h>
#endif

#ifdef PSOS_SDT
#include <psos.h>
#include <prepc.h>
#else
#include <stdio.h>
#endif


/*************** OS dependent includes ************/
#ifndef WINDOWS
#include "post.h"
#include "sp.h"
#endif
#ifdef WINDOWS
#include <windows.h>
#include <time.h>
#include <dos.h>
#include "post.h"
#include "sp.h"
#ifdef HOST
#ifdef __BORLANDC__
#include <dir.h>
#else /* Microsoft */
#include <direct.h>
#endif
#endif
#else /* !WINDOWS */
#ifndef PSOS_SDT
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#endif /* PSOS_SDT */

#ifdef PUMA
#include <strings.h>
#include <sys/select.h>
#undef SIG_IGN
#define SIG_IGN (void (*)(int))0
#endif

#if defined(HOST) || defined(JUSTPARSER)
#include <sys/time.h>
#else /* TARGET */
#ifdef VXWORKS_SDT
#include <sys/times.h>
#include <time.h>
#endif

#ifdef PSOS_SDT
#include <phile.h>
#endif

#if !defined(VXWORKS_SDT) && !defined(PSOS_SDT)
#include <sys/time.h>
#endif

#endif /* HOST || TARGET */

#endif /* WINDOWS || Unix */


/*
#include "sp.h"
*/

/* -------------------------------------------------------------

   General defines, system independant

---------------------------------------------------------------*/

#define INITARG		"DummyArg"
#define PROTOCOL		AF_INET
#define DELIMIT		":!:"
#define DEFAULTBUFSIZE	600
#define FIXEDHEADER	36
#define TARGETINIT	33333
#define HOSTINIT		33334
#define TARGETEXIT	33335
#define HOSTEXIT		33336
#define	PM		1
#define	TRG 		2
#define	MSCE 		3
#define	SDLE 		4
#define TRG_DEAD	  	5
#define TRG_SUSPEND 	6

int outremote(int,int,char*,int,int,int);
int inremote(int *,int *, int *, int *, int *, int *, int);
int initremote(void);
void exitremote(void);



#if defined(HOST) || defined(JUSTPARSER)
/*  declarations for parser */
#define CON_FILE        "tarsim.cfg"

#ifdef WINDOWS
#define SearchListItems 1
const char *SearchList[SearchListItems] =
	{ "TARSIMPATH" };
#else /* Unix */
#define SearchListItems 4
const char *SearchList[SearchListItems] =
	{ "TARSIMPATH" , "PWD" , "HOME" , "sdtdir" };
#endif /* Windows || Unix on HOST */

char TriedToOpen[100];
char TARGETIPNR[30]="",HOSTIPNR[30]="";
int     TARGETPORT=0,HOSTPORT=0;
char TARGETNAME[30]="?",HOSTNAME[30]="?";
int     DEBUG = FALSE;
char TARGETCOMSTRING[5]="TCP";
#ifndef WINDOWS
FILE    *LOGFILE/* = stderr;    */;
char    LOGFILESTRING[60]="NONE";
#endif /*!WINDOWS*/
#ifdef WINDOWS
#define PATHSEPARATOR '\\'
#else
#define PATHSEPARATOR '/'
#endif /* WINDOWS */
char    SDLSOURCEPATH[80];
int     CHANGEPATH = FALSE;
FILE *SearchConfigFile(char **FileSearchlist, int*);
FILE *CheckConfigFile(char *pathptr);
int LoadConfigFile(void);
struct hostent *convertIP(char *);
int xPrintString(char *);
int xGetString(char *,int);
int xReleaseUI(int);
int xErrorShell(int);
int xPingPM(void);
int xExitMessage(void);
int PathChanger(char *);
/*#ifndef WINDOWS*/
int xShell(void);
int GrepSetup(char *);
int GrepFilter(char *);
int logger(int ,int ,int ,int ,int ,char *);
void messNrtoStr(int);
static int GREP = 0;
static char GREPSTRING[5][50];
#endif /*!WINDOWS*/
char *  indata;
/*#endif*/ /* HOST || JUSTPARSER */

#ifdef HOST
/* HOST main routines */
int   HostInitPM(int);
int   HostExitPM(void);
int   HostReadPM(int);
int   HostReadTarget(int Resync);
#ifdef DONT
int SPBroadcast( int message, void *data, int len);
int SPSendToPid( int pid, int message, void *data, int len);
int SPRead( int timeOut, int *sender, int *message, void **data, int * len);
int SPInit (int toolType, char *argv0,  void * mlist);
int SPExit (void);
#endif
int   PIDREQUEST = 0;

#ifdef JUSTPARSER
#define CFG_ERROR(STRING)  fprintf(stderr,(STRING));
#else
#define CFG_ERROR(STRING)  xPrintString(STRING);
#endif

#endif /* HOST */
#ifdef TARGET
extern void SDL_Halt(void);
#endif /*TARGET*/


#ifdef TCP
/* -------------------------------------------------------------

   This secton contains general TCP/IP defines.

---------------------------------------------------------------*/
/* TCP SOCKET ERRORS */
static int comerror;   /* must be in continuous numeric order */
#define CE_OK                             0
#define CE_SOCKETERROR                    1
#define CE_UNKNOWNHOST                    2
#define CE_CONNECTREFUSED                 3
#define CE_WRITEERROR                     4
#define CE_READERROR                      5
#define CE_ACCEPTERROR                    6
#define CE_LISTENERROR                    7
#define CE_SELECTERROR                    8
#define CE_TIMEOUT                        9
#define CE_DEFINEDERRORS	           10 /* amount of defined err:s! */
int tcpsend(int, int, char *, int, int, int);
int tcpread(int *,int *, int *, int *, int *, int *, int);
int xInitSocket(void);
void xCloseSocket(void);
int xOutSocket(char *, int ,int);
int xInSocket( int, int );


#ifdef HOST
#define xSOCK 1
#else /* TARGET */
#define xSOCK 2
#define TARGETPORT      18000
#endif /* HOST || TARGET */

/* -------------------------------------------------------------

   This secton contains OS specific implementation of TCP/IP
   primitives.

   To compile under Windows95 or Windows NT use compiler flag:
   	-DWINDOWS
   	
   Default is Unix.

---------------------------------------------------------------*/

/**** waits the specified amount of milliseconds ****/
#ifdef WINDOWS
#define WAIT(wTime) \
	Sleep ( (DWORD)(wTime) );
#else
#define WAIT(wTime) \
	timeOut.tv_sec = (wTime)/1000; \
	timeOut.tv_usec =((wTime)%1000)*1000; \
	select(0L,0L,0L,0L,&timeOut);
#endif

#ifdef WINDOWS
/*************** OS dependent includes ************/
#include <winsock.h>

/* WIN32 API defines LPHOSTENT, LPSOCKADDR, SOCKET */
/* errno defined in errno.h under Unix */
#define errno WSAGetLastError()
#define WS_VERSION_REQUIRED    MAKEWORD(1,1)

/********** file tcp.c make_socket() **********/
#define BIND_ERROR_TEST \
		if(ret==SOCKET_ERROR) return INVALID_SOCKET;
		
/********** file tcp.c xInitSocket() **********/
#define STARTUP_TARGET \
	ret = WSAStartup(WS_VERSION_REQUIRED,&wsaData);\
	if(ret !=0 ) SDL_Halt();
#define LISTEN \
	if (listen(tcpsocket[0],1)==SOCKET_ERROR) return CE_LISTENERROR;
#define SELECT_SERVER \
	do{ret = select(FD_SETSIZE,(void*)&active_fd_set,NULL,NULL,&timeOut);\
	}while(ret == SOCKET_ERROR && errno == WSAEINTR);\
	if(ret == SOCKET_ERROR) return CE_SELECTERROR;\
	else if(ret == 0)return CE_TIMEOUT;
#define ACCEPT(sock) \
     if(ret){\
	  tcpsocket[(sock)] = accept(tcpsocket[0],(struct sockaddr *)&peer, &peerlen);\
	  if (tcpsocket[(sock)] == INVALID_SOCKET) return CE_ACCEPTERROR;\
	  FD_SET (tcpsocket[(sock)], &active_fd_set);\
	}
#define STARTUP_HOST \
 	ret = WSAStartup(WS_VERSION_REQUIRED,&wsaData);\
	if(ret !=0 ) exit(1);
#define SIGNAL_DISPATCH  /* not under win32 */
#define CONNECT_ERROR_TEST \
	if(ret == SOCKET_ERROR) return CE_CONNECTREFUSED; 

/********** file tcp.c xCloseSocket() **********/
#define CLOSE	     closesocket
#define PRE_EXIT 	(void) WSACleanup();  

/********** file tcp.c xOutSocket() **********/  

#define SEND_HEADER \
	if ( send (tcpsocket[sock], lenheader, 4, 0 ) == SOCKET_ERROR)\
			return CE_WRITEERROR;
#define SEND_MESSAGE \
	do {\
	  if((nbytes = send(tcpsocket[sock],bufp,bytesleft,0))!= SOCKET_ERROR){\
		bytesleft -= nbytes;\
		bufp += nbytes;\
	  }\
	} while((nbytes == SOCKET_ERROR && errno == WSAEINTR) ||\
		   (nbytes != SOCKET_ERROR && bytesleft >0));\
	if(nbytes == SOCKET_ERROR) return CE_WRITEERROR;\
	else return SPOK;
	                         
/********** file tcp.c xInSocket() **********/ 
 /*
#define SELECT_READ \
	do {ret = select (FD_SETSIZE, (void*)&read_fd_set, NULL, NULL, tp);\
   	nbytes = recv (tcpsocket[sock], lenheader, 4,MSG_PEEK);\
	} while (ret == SOCKET_ERROR && errno == WSAEINTR || \
   	nbytes == 0 && errno == WSAEWOULDBLOCK );  \
	if( ret == SOCKET_ERROR) return CE_READERROR; \
   if (nbytes == SOCKET_ERROR) return CE_READERROR; \
   if (nbytes == 0 && errno != WSAEWOULDBLOCK)return CE_READERROR; \
   if (nbytes == 0) ret =0;
This might be the beginning of a solution to the stupid non blocking
select() but there has not been time to solve it.*/

#define SELECT_READ \
	do {ret = select (FD_SETSIZE, (void*)&read_fd_set, NULL, NULL, tp);\
	} while (ret == SOCKET_ERROR && errno == WSAEINTR); \
  	if( ret == SOCKET_ERROR) return CE_READERROR;

#define READ_HEADER \
		nbytes = recv (tcpsocket[sock], lenheader, 4,0);
#define READ_MESSAGE \
	while (bytesleft > 0 &&\
	 (nbytes = recv (tcpsocket[sock], buffer, bytesleft,0))!= SOCKET_ERROR){\
		buffer += nbytes;\
		bytesread += nbytes;\
		bytesleft -= nbytes;\
	}

#else  /**%%%%%%%%%  POSIX  below %%%%%%%%%%%%**/

/*************** OS dependent includes ************/

#if defined(HOST) || defined(JUSTPARSER)
#include <netdb.h>
#else /* TARGET */

#endif /* HOST / TARGET */

#ifdef PSOS_SDT
#undef TCP  /* TCP flag is defined in pna.h */
#include <pna.h>
#ifndef TCP
#define TCP
#endif
#else /* std POSIX below */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif /* PSOS_SDT */

/* following are already defined in WIN32 */
typedef struct hostent *        LPHOSTENT;
#ifdef PSOS_SDT
typedef struct sockaddr_in *    LPSOCKADDR;
#else /* std POSIX below */
typedef struct sockaddr *       LPSOCKADDR;
#endif /* PSOS_SDT */
typedef int              	  	  SOCKET;
#define INVALID_SOCKET			  -1

/********** file tcp.c make_socket() **********/

#define BIND_ERROR_TEST\
     if(ret<0)\
	{\
    		perror ("bind");\
    		return INVALID_SOCKET;\
	}
/********** file tcp.c xInitSocket() **********/


#define STARTUP_TARGET  /* not in Unix implementation */
#define LISTEN \
	if (listen(tcpsocket[0],1)<0) return CE_LISTENERROR;
#define SELECT_SERVER \
	do{ret = select(FD_SETSIZE,(void*)&active_fd_set,NULL,NULL,&timeOut);\
	} while(ret<0 && errno == EINTR);\
	if(ret < 0) return CE_SELECTERROR;\
	else if(ret == 0) return CE_TIMEOUT; 
#define ACCEPT(sock) \
     if(ret){ \
       tcpsocket[(sock)] = accept(tcpsocket[0],(LPSOCKADDR)&peer,&peerlen);\
          if (tcpsocket[(sock)] < 0) return CE_ACCEPTERROR;\
          FD_SET (tcpsocket[(sock)], &active_fd_set);\
	}
#define STARTUP_HOST /* not in Unix implementation */

#ifdef PSOS_SDT
#define SIGNAL_DISPATCH
#else /* std POSIX below */
#define SIGNAL_DISPATCH		signal(SIGPIPE,SIG_IGN);
#endif /* PSOS_SDT */

#define CONNECT_ERROR_TEST \
	if(ret!=0) return CE_CONNECTREFUSED;				

/********** file tcp.c xCloseSocket() **********/
#define CLOSE	     close
#define PRE_EXIT 	/* not in Unix implementation */  

/********** file tcp.c xOutSocket() **********/  
#ifdef PSOS_SDT
#define SEND_HEADER \
	if ( 0 > send (tcpsocket[sock], lenheader, 4,0) )\
			return CE_WRITEERROR;
#define SEND_MESSAGE \
	do {\
		if((nbytes = send(tcpsocket[sock], bufp, bytesleft,0)) >0){\
			bytesleft -= nbytes;\
			bufp += nbytes;\
		}\
	} while((nbytes <0 && errno == EINTR) ||\
		   (nbytes >=0 && bytesleft >0));\
	if(nbytes < 0) return CE_WRITEERROR;\
	else return SPOK;
#else /* std POSIX below */
#define SEND_HEADER \
	if ( 0 > write (tcpsocket[sock], lenheader, 4) )\
			return CE_WRITEERROR;
#define SEND_MESSAGE \
	do {\
		if((nbytes = write(tcpsocket[sock], bufp, bytesleft)) >0){\
			bytesleft -= nbytes;\
			bufp += nbytes;\
		}\
	} while((nbytes <0 && errno == EINTR) ||\
		   (nbytes >=0 && bytesleft >0));\
	if(nbytes < 0) return CE_WRITEERROR;\
	else return SPOK;
#endif /* PSOS_SDT */                       
/********** file tcp.c xInSocket() **********/  

#define SELECT_READ \
  	do { ret = select (FD_SETSIZE, (void*)&read_fd_set, NULL, NULL, tp);\
	} while (ret < 0 && errno == EINTR);\
	if( ret < 0 ) return CE_SELECTERROR;

#ifdef PSOS_SDT
#define READ_HEADER \
	nbytes = recv (tcpsocket[sock], lenheader, 4,0);
#define READ_MESSAGE \
	while (bytesleft > 0 && \
	  (nbytes = recv (tcpsocket[sock], buffer, bytesleft,0))>0){\
	  	buffer += nbytes;\
  		bytesread += nbytes;\
  		bytesleft -= nbytes;\
	}
#else  /* std POSIX below */
#define READ_HEADER \
	nbytes = read (tcpsocket[sock], lenheader, 4);
#define READ_MESSAGE \
	while (bytesleft > 0 && \
	  (nbytes = read (tcpsocket[sock], buffer, bytesleft))>0){\
	  	buffer += nbytes;\
  		bytesread += nbytes;\
  		bytesleft -= nbytes;\
	}
#endif /* PSOS_SDT */
	
#endif  /*  WINDOWS flag for non POSIX implementation */

#endif /* TCP */
