home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
VRAC
/
PPL4C11.ZIP
/
FILEXFER.C
< prev
next >
Wrap
Text File
|
1993-01-10
|
10KB
|
362 lines
/*
** --- filexfer.c V1.1 Jan 1993 ---
**
** Demonstration program for the Personal Protocol Library.
**
** See FILEXFER.H for configuration parameters.
**
** Do NOT select YMODEM-G when using a null modem cable unless you are
** certain that RTS & CTS are reversed ( this is often not true ).
**
** Requires PCL4C version 3.4 or above.
*/
#include <stdio.h>
#include "ppl4c.h"
#include "ascii.h"
#include "pcl4c.h"
#include "filexfer.h"
#include "dir_io.h"
#define FALSE 0
#define TRUE !FALSE
#define NO_ERROR 0
/*** protocol data ***/
static int BatchFlag = FALSE;
static int OneKflag = FALSE;
static char NCGchar = NAK;
/*** global variables ***/
static char RxBuf1[2048]; /* First 2K receive buffer */
static char RxBuf2[2048]; /* Second 2K receive buffer */
static char RxBuf3[2048]; /* Third 2K receive buffer */
static char RxBuf4[2048]; /* Fourth 2K receive buffer */
static int ThisPacket; /* packet # */
static char FileSpec[64]; /* file specification */
static char EmptyFile[1] = "\0";
static char *BaudRate[10] = {"300","600","1200","2400","4800","9600",
"19200","38400","57600","115200"};
static int LastPacket[4] = {-1,-1,-1,-1};
static char Protocol[4] = {'X', 'X','X','X'};
static int IsIdle[4] = {TRUE,TRUE,TRUE,TRUE};
static int ThePort[4] = {FIRST_PORT,SECOND_PORT,THIRD_PORT,FOURTH_PORT};
static int TheBaud[4] = {FIRST_BAUD,SECOND_BAUD,THIRD_BAUD,FOURTH_BAUD};
static char *TheBuffer[4] = {RxBuf1,RxBuf2,RxBuf3,RxBuf3};
static char *ModelText[4] = {"Small","Compact","Medium","Large"};
char KeyRead();
void UpdateStuff();
void SetProtocol();
void SayProtocol();
void main()
{int i;
int Code;
char ch;
int C;
int Version;
void ErrorCheck();
char *Ptr;
char Filename[15];
/* display some info */
puts("\n*** FILEXFER 1.1: Jan 4, 1993 ***");
Version = SioInfo('V');
printf("Library = %d.%d ",Version/16,Version%16);
printf("Memory Model = %s\n",ModelText[3&SioInfo('M')] );
#if 1
/*** Custom Configuration ***/
/* use IRQ2 for COM3 */
SioIRQ(COM3,IRQ2,ThirdISR);
/* use IRQ5 for COM4 */
SioIRQ(COM4,IRQ5,FourthISR);
#endif
/*printf("Preparing %d channels\n",NBR_OF_CHANNELS);*/
for(C=0;C<NBR_OF_CHANNELS;C++)
{printf("Channel %d: ",C);
printf("Port = COM%d, ",1+ThePort[C]);
printf("Rate = %s\n",BaudRate[TheBaud[C]]);
ErrorCheck( SioRxBuf(ThePort[C],TheBuffer[C],Size2048) );
ErrorCheck( SioReset(ThePort[C],TheBaud[C]) );
xyInit(C,ThePort[C]);
#if RTS_CTS_CONTROL
SioFlow(ThePort[C],3*ONE_SEC);
printf("COM%d: Flow Control enabled. CTS = ",1+ThePort[C]);
if(SioCTS(ThePort[C])) puts("ON");
else puts("OFF");
#endif
/* Set FIFO level if have 16550 UART */
if( SioFIFO(ThePort[C],LEVEL_14) ) printf("<COM%d: INS16550 detected>\n",1+ThePort[C]);
/* clear PCL4C receive buffer */
ErrorCheck( SioRxFlush(ThePort[C]) );
/* see FILEXFER.H for definition of AT_COMMAND_SET */
#if AT_COMMAND_SET
/* wait for Modem to say its ready */
printf("Waiting for Modem DSR on COM%d.",1+ThePort[C]);
while( !SioDSR(ThePort[C]) )
{
if(SioKeyPress()||SioBrkKey()) MyExit(0,"Aborted by user");
putchar('.');
SioDelay(ONE_SEC);
}
putchar('\n');
/* initialize (Hayes compatible) modem */
SendTo(ThePort[C],"!AT!!~");
SendTo(ThePort[C],"!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!");
if(WaitFor(ThePort[C],"OK")) printf("\nCOM%d MODEM READY\n",ThePort[C]);
else printf("\nWARNING: Expected OK not received\n");
#endif
} /* end for(C) */
/* begin main loop */
printf("\n");
while(1)
{
/* get user command */
printf("\nQ)uit P)rotocol S)end R)eceive A)bort C)omm Status:");
ch = KeyRead(); printf("\n");
/* update status for each channel */
for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
switch(toupper(ch))
{case 'Q': /* QUIT */
for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
puts("Done");
exit(0);
case 'P': /* SET PROTOCOL */
SetProtocol();
break;
case 'A': /* ABORT TRANSFER */
C = GetChannel();
if(C!=ESC) xyAbort(C);
break;
case 'S': /* SEND FILE */
if((C=GetChannel())==ESC) break;
if(IsIdle[C])
{if(GetString("Enter Filename:",FileSpec)==0) break;
if(!FindFirst(FileSpec,Filename))
{printf("No such file(s) '%s'\n",FileSpec);
break;
}
xyStartTx(C,FileSpec,OneKflag,BatchFlag);
}
else printf("C%d: Channel is busy\n",C);
break;
case 'R': /* RECEIVE FILE */
if((C=GetChannel())==ESC) break;
if(IsIdle[C])
{if(BatchFlag)
{/* YMODEM provides filename */
xyStartRx(C,EmptyFile,NCGchar,BatchFlag);
}
else
{/* need filename 1st */
GetString("Enter Filename:",FileSpec);
xyStartRx(C,FileSpec,NCGchar,BatchFlag);
}
}
else printf("C%d: Channel is busy\n",C);
break;
case 'C': /* COMM STATUS */
for(C=0;C<NBR_OF_CHANNELS;C++)
{/* get channel status */
Code = xyDriver(C);
if(Code<0)
{/* comm error returned */
printf("C%d: SIO Error %d. ",C,Code);
SioError(Code);
}
else
{/* no comm error */
if(IsIdle[C])
{/* channel is idle */
Code = xyGetErrorCode(C);
if(Code==NO_ERROR)
{/* no error on idle channel */
printf("C%d: COM%d, ",C,1+ThePort[C]);
SayProtocol(Protocol[C]);
printf(", channel is idle.\n");
}
else
{/* report error condition */
printf("C%d: '%c' Error '",C,Protocol[C]);
xySayError(Code);
printf("' occured in state '");
xySayState(xyGetErrorState(C));
printf("'\n");
}
}
else
{/* channel is NOT idle */
printf("C%d: COM%d, ",C,1+ThePort[C]);
SayProtocol(Protocol[C]);
printf(", State='");
xySayState(xyGetState(C));
i = xyGetPacket(C);
if(i>=0) printf("', Packet=%d",i);
Ptr = xyGetFilename(C);
if(strlen(Ptr)>0) printf(", File='%s'\n",Ptr);
else printf("\n");
}
}
} /* end for(C) */
break;
} /* end switch */
} /* end while */
} /* end main */
char KeyRead()
{/* all keyboard input MUST be called thru KeyRead */
while(!SioKeyPress()) UpdateStuff();
return( SioKeyRead() );
} /* end KeyRead */
void UpdateStuff()
{int C;
/* read each channel */
for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
} /* end UpdateStuff */
void ErrorCheck(Code)
int Code;
{int C;
/* trap PCL error codes */
if(Code<0)
{SioError(Code);
for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
exit(1);
}
} /* end ErrorCheck */
void SetProtocol()
{char Answer;
int Flag; /* change protocol if TRUE */
int C;
if((C=GetChannel())==ESC) return;
if(!IsIdle[C])
{printf("WARNING: Cannot change protocol until channel is idle\n");
return;
}
#if RTS_CTS_CONTROL
printf("X: XMODEM C: XMODEM-CRC 1: XMODEM-1K Y: YMODEM G: YMODEM-G\n");
printf("Enter X,C,1,Y, or G: ");
#else
printf("X: XMODEM C: XMODEM-CRC 1: XMODEM-1K Y: YMODEM\n");
printf("Enter X,C,1, or Y: ");
#endif
Answer = KeyRead();
SioCrtWrite(Answer);
Flag = TRUE;
switch( toupper(Answer) )
{case 'X':
BatchFlag = FALSE;
OneKflag = FALSE;
NCGchar = NAK;
break;
case 'C':
BatchFlag = FALSE;
OneKflag = FALSE;
NCGchar = 'C';
break;
case '1':
BatchFlag = FALSE;
OneKflag = TRUE;
NCGchar = 'C';
break;
case 'Y':
BatchFlag = TRUE;
OneKflag = TRUE;
NCGchar = 'C';
break;
#if RTS_CTS_CONTROL
case 'G':
BatchFlag = TRUE;
OneKflag = TRUE;
NCGchar = 'G';
break;
#endif
default:
Flag = FALSE;
printf("ERROR: No such protocol");
}
if(Flag)
{Protocol[C] = toupper(Answer);
}
} /* end SetProtocol */
int GetChannel()
{char ch;
while(1)
{printf("Enter channel [0,1,2,3] or ESC:");
ch = KeyRead(); SioCrtWrite(ch);
printf("\n");
#if 0
SioCrtWrite(CR);
SioCrtWrite(LF);
#endif
if(ch==ESC) return(ESC);
if((ch>='0')&&(ch<'0'+NBR_OF_CHANNELS)) return(ch-'0');
printf("ERROR: Must enter 0 to %d [or ESC]",NBR_OF_CHANNELS-1);
}
} /* end GetChannel */
int GetString(Prompt,String)
char *Prompt;
char *String;
{char ch;
int i = 0;
printf("%s",Prompt);
while(1)
{ch = KeyRead();
switch(ch)
{case CR:
SioCrtWrite(LF);
SioCrtWrite(CR);
String[i++] = '\0';
return(i);
case ESC:
String[0] = '\0';
return(0);
case BS:
if(i<=0) continue;
SioCrtWrite(BS);
SioCrtWrite(' ');
SioCrtWrite(BS);
i--;
break;
default:
SioCrtWrite(ch);
String[i++] = ch;
break;
} /* end switch */
} /* end while */
} /* end GetString */
void SayProtocol(P)
char P;
{
printf("Protocol=");
switch(P)
{case 'X':
printf("XMODEM");
break;
case 'C':
printf("XMODEM-CRC");
break;
case '1':
printf("XMODEM-1K");
break;
case 'Y':
printf("YMODEM");
break;
case 'G':
printf("YMODEM-G");
break;
default:
printf("unknown.");
break;
} /* end switch */
} /* end SayProtocol */