/*
 *   wcez.c
 *    Industrial ZMODEM(Tm) bindings for WinCE
 *  Copyright 2004 Omen Technology INC All Rights Reserved
 */
#define FLUSH
#define flushmoc flushmo
#define sendline(c)	(--Txleft < 0 ? flushline((unsigned char) (c)) : \
			(int) (*Txcq++ = (unsigned char) (c)))

#include <stdio.h>
FILE *in, *fout;

extern Txleft;		/* number of characters in Txlbuf */
extern char *Txcq;	/* pointer for storing chars to Txlbuf */

COMMTIMEOUTS Ctmo;
#define RSIZE 2048	/* Size of receive buffer */
char Rxlbuf[RSIZE+1];
long rxlcount[1+RSIZE/16];	/* for debugging */
long Rxnum = 24;		/* In term fnx should be 100 MS worth of bytes */
/* DO NOT CHANGE TO DWORD -- breaks readline */
long Rxleft=0;		/* number of characters in Rxlbuf */
char *Rxcdq = Rxlbuf;	/* pointer for removing chars from Rxlbuf */

#ifdef FLUSH
#define TSIZE 350	/* Size of send buffer */
char Txlbuf[TSIZE+1];
int Txnum=64;		/* number of characters WE SHALL USE in Txlbuf */
int Txleft=64;		/* number of characters in Txlbuf */
char *Txcq = Txlbuf;	/* pointer for storing chars to Txlbuf */
#endif


COMSTAT Cst;
DWORD Cerr;
checkline()
{
	ClearCommError(hPort, &Cerr, &Cst);
	return Cst.cbInQue;
}

void
zclose(status)
{
#ifdef DIAGS
	vfile("zclose: status=%d", status);
#endif
	if (in) {
		fclose(in);
#ifdef DIAGS
		vfile("fclose returned");
#endif
	} else {
#ifdef DIAGS
	vfile("file already closed!!");
#endif
	}

	in = 0;
}
int
zseek(n)
long n;
{
	clearerr(in);	/* Clear EOF */
	return (fseek(in, n, 0));
}

/* Fill buffer with blklen chars */
int
zfilbuf()
{
	int n;

#ifdef NOCOPYTX
	n = (int)fread(secbuf=privsecbuf, 1, blklen, in);
#else
	n = (int)fread(secbuf, 1, blklen, in);
#endif
	if (n < blklen)
		Eofseen = 1;
	return n;
}




#ifdef DIAGS
int Verbose = 10;
/* VARARGS1 */
void
vfile(f, a, b, c)
register char *f;
{
	if (Verbose > 2) {
		fprintf(stderr, f, a, b, c);
		fprintf(stderr, "\n");
		fflush(stderr);
	}
}

/*
 * Log an error
 */
/*VARARGS1*/
void
zperr(s,p,u)
char *s, *p, *u;
{
	if (Verbose <= 0)
		return;
	fprintf(stderr, s, p, u);
	fprintf(stderr, "\n");
}

#endif


#ifdef FLUSH
void
flushline(c)
unsigned char c;
{
	Txleft = 0;
	flushmo();
	--Txleft;
	*Txcq++ = c;
}

/* Start output, do not wait if possible */
void
flushmo()
{
	register int n;
	DWORD ocnt;

	n = Txcq - Txlbuf;
	Txcq=Txlbuf;  Txleft = Txnum;
	if (n == 0)
		return;
	WriteFile(hPort, Txlbuf, n, &ocnt, NULL);
}
#else
void
sendline(c)
{
	DWORD ocnt;
	int d;

	d = c;
	WriteFile(hPort, &d, 1, &ocnt, NULL);
}
#endif

/*
 * This version of readline is reasoably well suited for
 * reading many characters.
 *
 * timeout is in tenths of seconds
 */
readline(timeout)
int timeout;
{
#ifdef DIAGS
	int c;
	register char *p;
#endif

#ifdef DIAGS
		vfile("Entering Readline rxleft=%d", Rxleft);
#endif
	if (--Rxleft>=0)
		return (*Rxcdq++ & 0377);
	Rxleft = 0;
	Rxlbuf[0] = 0;


	Rxcdq = Rxlbuf;
	if (Ctmo.ReadTotalTimeoutConstant != 100) {
		Ctmo.ReadTotalTimeoutConstant = 100;
#ifdef DIAGS
		vfile("Readline calling setcommtimeouts");
#endif
		SetCommTimeouts(hPort, &Ctmo);
	}
	do {
#ifdef DIAGS
		if (Verbose > 8) vfile("Readline calling readfile"); 
#endif
		if ( !ReadFile(hPort, Rxlbuf, Rxnum, &Rxleft, NULL)) {
		}
		if (Rxleft > 0) {
#ifdef DIAGS
			if (Verbose > 8) {
				vfile("Read returned: %d\n", Rxleft);
				for (p = Rxcdq, c = Rxleft; --c >= 0; ) {
					fprintf(stderr, "%02x ", (*p++ &0377));
				}
				fprintf(stderr, "\n");
			}
#endif
			++rxlcount[Rxleft/16];	/* for debugging */
			--Rxleft;
			return (*Rxcdq++ & 0377);
		}
	}
		while (--timeout > 0);
	Rxleft = 0;
	return TIMEOUT;
}

/* Clear out the input buffer */
void
purgeline()
{
	Rxleft = 0;
	PurgeComm(hPort, PURGE_RXABORT|PURGE_RXCLEAR);
}

void
sendbrk()
{
	SetCommBreak(hPort);
	Sleep(200);
	ClearCommBreak(hPort);
	Sleep(10);			/* Insure marking follows */
}


int
openit(name)
char *name;
{
	if ((in=fopen(name, "r"))==NULL) {
		return IZERROR;	/* pass over it, there may be others */
	}
	return IZOK;
}
/*
 * Close the receive dataset
 */
void
closeit(status)
{
	if (fout)
		fclose(fout);
	fout = 0;
}
/*
 * Process incoming file information header
 **   a quick hack to get something going
 **   See func in irz.c for more complete version
 */
long
crprocheader(name)
char *name;
{
	closeit();
	if ((fout=fopen(name, "w")) == NULL)
		return IZERROR;
	return 0;
}


/*
 * Putsec writes the n characters of buf to receive file fout.
 *  If not in binary mode, carriage returns, and all characters
 *  starting with CPMEOF are discarded.
 *  This routine is specific to Unix like systems!!!
 */
void
putsec(buf, n)
char *buf;
register n;
{
	register char *p;

	if (n == 0)
		return;
	for (p=buf; --n>=0; )
		putc( *p++, fout);
}


void
sleep(n)
{
	Sleep(n * 1000);
}

