home *** CD-ROM | disk | FTP | other *** search
- /*
- ** --- 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 */