home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / VRAC / PPL4C11.ZIP / FILEXFER.C < prev    next >
Text File  |  1993-01-10  |  10KB  |  362 lines

  1. /*
  2. **             ---  filexfer.c V1.1 Jan 1993 ---
  3. **
  4. **  Demonstration program for the Personal Protocol Library.
  5. **
  6. **  See FILEXFER.H for configuration parameters.
  7. **
  8. **  Do NOT select YMODEM-G when using a null modem cable unless you are
  9. **  certain that RTS & CTS are reversed ( this is often not true ).
  10. **
  11. **  Requires PCL4C version 3.4 or above.
  12. */
  13. #include <stdio.h>
  14. #include "ppl4c.h"
  15. #include "ascii.h"
  16. #include "pcl4c.h"
  17. #include "filexfer.h"
  18. #include "dir_io.h"
  19.  
  20. #define FALSE 0
  21. #define TRUE !FALSE
  22. #define NO_ERROR 0
  23.  
  24. /*** protocol data ***/
  25.  
  26. static int BatchFlag = FALSE;
  27. static int OneKflag = FALSE;
  28. static char NCGchar = NAK;
  29.  
  30. /*** global variables ***/
  31.  
  32. static char RxBuf1[2048];       /* First 2K receive buffer */
  33. static char RxBuf2[2048];       /* Second 2K receive buffer */
  34. static char RxBuf3[2048];       /* Third 2K receive buffer */
  35. static char RxBuf4[2048];       /* Fourth 2K receive buffer */
  36.  
  37. static int ThisPacket;            /* packet # */
  38. static char FileSpec[64];         /* file specification */
  39. static char EmptyFile[1] = "\0";
  40. static char *BaudRate[10] =  {"300","600","1200","2400","4800","9600",
  41.                             "19200","38400","57600","115200"};
  42.  
  43. static int LastPacket[4] = {-1,-1,-1,-1};
  44. static char Protocol[4] = {'X', 'X','X','X'};
  45. static int IsIdle[4] = {TRUE,TRUE,TRUE,TRUE};
  46. static int ThePort[4] = {FIRST_PORT,SECOND_PORT,THIRD_PORT,FOURTH_PORT};
  47. static int TheBaud[4] = {FIRST_BAUD,SECOND_BAUD,THIRD_BAUD,FOURTH_BAUD};
  48. static char *TheBuffer[4] = {RxBuf1,RxBuf2,RxBuf3,RxBuf3};
  49. static char *ModelText[4] = {"Small","Compact","Medium","Large"};
  50.  
  51. char KeyRead();
  52. void UpdateStuff();
  53. void SetProtocol();
  54. void SayProtocol();
  55.  
  56.  
  57. void main()
  58. {int i;
  59.  int Code;
  60.  char ch;
  61.  int C;
  62.  int Version;
  63.  void ErrorCheck();
  64.  char *Ptr;
  65.  char Filename[15];
  66.  /* display some info */
  67.  puts("\n*** FILEXFER 1.1:  Jan 4, 1993 ***");
  68.  Version = SioInfo('V');
  69.  printf("Library = %d.%d  ",Version/16,Version%16);
  70.  printf("Memory Model = %s\n",ModelText[3&SioInfo('M')] );
  71. #if 1
  72.  /*** Custom Configuration ***/
  73.  /* use IRQ2 for COM3 */
  74.  SioIRQ(COM3,IRQ2,ThirdISR);
  75.  /* use IRQ5 for COM4 */
  76.  SioIRQ(COM4,IRQ5,FourthISR);
  77. #endif
  78.  /*printf("Preparing %d channels\n",NBR_OF_CHANNELS);*/
  79.  for(C=0;C<NBR_OF_CHANNELS;C++)
  80.    {printf("Channel %d: ",C);
  81.     printf("Port = COM%d, ",1+ThePort[C]);
  82.     printf("Rate = %s\n",BaudRate[TheBaud[C]]);
  83.     ErrorCheck( SioRxBuf(ThePort[C],TheBuffer[C],Size2048) );
  84.     ErrorCheck( SioReset(ThePort[C],TheBaud[C]) );
  85.     xyInit(C,ThePort[C]);
  86. #if RTS_CTS_CONTROL
  87.     SioFlow(ThePort[C],3*ONE_SEC);
  88.     printf("COM%d: Flow Control enabled. CTS = ",1+ThePort[C]);
  89.     if(SioCTS(ThePort[C])) puts("ON");
  90.     else puts("OFF");
  91. #endif
  92.     /* Set FIFO level if have 16550 UART */
  93.     if( SioFIFO(ThePort[C],LEVEL_14) ) printf("<COM%d: INS16550 detected>\n",1+ThePort[C]);
  94.     /* clear PCL4C receive buffer */
  95.     ErrorCheck( SioRxFlush(ThePort[C]) );
  96.     /* see FILEXFER.H for definition of AT_COMMAND_SET */
  97. #if AT_COMMAND_SET
  98.     /* wait for Modem to say its ready */
  99.     printf("Waiting for Modem DSR on COM%d.",1+ThePort[C]);
  100.     while( !SioDSR(ThePort[C]) )
  101.       {
  102.        if(SioKeyPress()||SioBrkKey()) MyExit(0,"Aborted by user");
  103.        putchar('.');
  104.        SioDelay(ONE_SEC);
  105.       }
  106.     putchar('\n');
  107.     /* initialize (Hayes compatible) modem */
  108.     SendTo(ThePort[C],"!AT!!~");
  109.     SendTo(ThePort[C],"!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!");
  110.     if(WaitFor(ThePort[C],"OK")) printf("\nCOM%d MODEM READY\n",ThePort[C]);
  111.     else printf("\nWARNING: Expected OK not received\n");
  112. #endif
  113.    } /* end for(C) */
  114.  /* begin main loop */
  115.  printf("\n");
  116.  while(1)
  117.    {
  118.     /* get user command */
  119.     printf("\nQ)uit P)rotocol S)end R)eceive A)bort C)omm Status:");
  120.     ch = KeyRead(); printf("\n");
  121.     /* update status for each channel */
  122.     for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
  123.     switch(toupper(ch))
  124.       {case 'Q':  /* QUIT */
  125.          for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
  126.          puts("Done");
  127.          exit(0);
  128.        case 'P':  /* SET PROTOCOL */
  129.          SetProtocol();
  130.          break;
  131.        case 'A':  /* ABORT TRANSFER */
  132.          C = GetChannel();
  133.          if(C!=ESC) xyAbort(C);
  134.          break;
  135.        case 'S':  /* SEND FILE */
  136.          if((C=GetChannel())==ESC) break;
  137.          if(IsIdle[C])
  138.            {if(GetString("Enter Filename:",FileSpec)==0) break;
  139.             if(!FindFirst(FileSpec,Filename))
  140.               {printf("No such file(s) '%s'\n",FileSpec);
  141.                break;
  142.               }
  143.             xyStartTx(C,FileSpec,OneKflag,BatchFlag);
  144.            }
  145.          else printf("C%d: Channel is busy\n",C);
  146.          break;
  147.        case 'R':  /* RECEIVE FILE */
  148.          if((C=GetChannel())==ESC) break;
  149.          if(IsIdle[C])
  150.            {if(BatchFlag)
  151.               {/* YMODEM provides filename */
  152.                xyStartRx(C,EmptyFile,NCGchar,BatchFlag);
  153.               }
  154.             else
  155.               {/* need filename 1st */
  156.                GetString("Enter Filename:",FileSpec);
  157.                xyStartRx(C,FileSpec,NCGchar,BatchFlag);
  158.               }
  159.            }
  160.          else printf("C%d: Channel is busy\n",C);
  161.          break;
  162.        case 'C':  /* COMM STATUS */
  163.          for(C=0;C<NBR_OF_CHANNELS;C++)
  164.            {/* get channel status */
  165.             Code = xyDriver(C);
  166.             if(Code<0)
  167.               {/* comm error returned */
  168.                printf("C%d: SIO Error %d. ",C,Code);
  169.                SioError(Code);
  170.               }
  171.             else
  172.               {/* no comm error */
  173.                if(IsIdle[C])
  174.                   {/* channel is idle */
  175.                    Code = xyGetErrorCode(C);
  176.                    if(Code==NO_ERROR)
  177.                      {/* no error on idle channel */
  178.                       printf("C%d: COM%d, ",C,1+ThePort[C]);
  179.                       SayProtocol(Protocol[C]);
  180.                       printf(", channel is idle.\n");
  181.                      }
  182.                    else
  183.                      {/* report error condition */
  184.                       printf("C%d: '%c' Error '",C,Protocol[C]);
  185.                       xySayError(Code);
  186.                       printf("' occured in state '");
  187.                       xySayState(xyGetErrorState(C));
  188.                       printf("'\n");
  189.                      }
  190.                   }
  191.                else
  192.                   {/* channel is NOT idle */
  193.                    printf("C%d: COM%d, ",C,1+ThePort[C]);
  194.                    SayProtocol(Protocol[C]);
  195.                    printf(", State='");
  196.                    xySayState(xyGetState(C));
  197.                    i = xyGetPacket(C);
  198.                    if(i>=0) printf("', Packet=%d",i);
  199.                    Ptr = xyGetFilename(C);
  200.                    if(strlen(Ptr)>0) printf(", File='%s'\n",Ptr);
  201.                    else printf("\n");
  202.                   }
  203.               }
  204.            } /* end for(C) */
  205.          break;
  206.       } /* end switch */
  207.    } /* end while */
  208. } /* end main */
  209.  
  210. char KeyRead()
  211. {/* all keyboard input MUST be called thru KeyRead */
  212.  while(!SioKeyPress()) UpdateStuff();
  213.  return( SioKeyRead() );
  214. } /* end KeyRead */
  215.  
  216. void UpdateStuff()
  217. {int C;
  218.  /* read each channel */
  219.  for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
  220. } /* end UpdateStuff */
  221.  
  222. void ErrorCheck(Code)
  223. int Code;
  224. {int C;
  225.  /* trap PCL error codes */
  226.  if(Code<0)
  227.      {SioError(Code);
  228.       for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
  229.       exit(1);
  230.      }
  231. } /* end ErrorCheck */
  232.  
  233. void SetProtocol()
  234. {char Answer;
  235.  int Flag;   /* change protocol if TRUE */
  236.  int C;
  237.  if((C=GetChannel())==ESC) return;
  238.  if(!IsIdle[C])
  239.    {printf("WARNING: Cannot change protocol until channel is idle\n");
  240.     return;
  241.    }
  242. #if RTS_CTS_CONTROL
  243.  printf("X: XMODEM   C: XMODEM-CRC   1: XMODEM-1K   Y: YMODEM   G: YMODEM-G\n");
  244.  printf("Enter X,C,1,Y, or G: ");
  245. #else
  246.  printf("X: XMODEM   C: XMODEM-CRC   1: XMODEM-1K   Y: YMODEM\n");
  247.  printf("Enter X,C,1, or Y: ");
  248. #endif
  249.  Answer = KeyRead();
  250.  SioCrtWrite(Answer);
  251.  Flag = TRUE;
  252.  switch( toupper(Answer) )
  253.    {case 'X':
  254.       BatchFlag = FALSE;
  255.       OneKflag = FALSE;
  256.       NCGchar = NAK;
  257.       break;
  258.     case 'C':
  259.       BatchFlag = FALSE;
  260.       OneKflag = FALSE;
  261.       NCGchar = 'C';
  262.       break;
  263.     case '1':
  264.       BatchFlag = FALSE;
  265.       OneKflag = TRUE;
  266.       NCGchar = 'C';
  267.       break;
  268.     case 'Y':
  269.       BatchFlag = TRUE;
  270.       OneKflag = TRUE;
  271.       NCGchar = 'C';
  272.       break;
  273. #if RTS_CTS_CONTROL
  274.     case 'G':
  275.       BatchFlag = TRUE;
  276.       OneKflag = TRUE;
  277.       NCGchar = 'G';
  278.       break;
  279. #endif
  280.     default:
  281.       Flag = FALSE;
  282.       printf("ERROR: No such protocol");
  283.    }
  284.  if(Flag)
  285.    {Protocol[C] = toupper(Answer);
  286.    }
  287. } /* end SetProtocol */
  288.  
  289. int GetChannel()
  290. {char ch;
  291.  while(1)
  292.    {printf("Enter channel [0,1,2,3] or ESC:");
  293.     ch = KeyRead();  SioCrtWrite(ch);
  294.     printf("\n");
  295. #if 0
  296.     SioCrtWrite(CR);
  297.     SioCrtWrite(LF);
  298. #endif
  299.     if(ch==ESC) return(ESC);
  300.     if((ch>='0')&&(ch<'0'+NBR_OF_CHANNELS)) return(ch-'0');
  301.     printf("ERROR: Must enter 0 to %d [or ESC]",NBR_OF_CHANNELS-1);
  302.    }
  303. } /* end GetChannel */
  304.  
  305. int GetString(Prompt,String)
  306. char *Prompt;
  307. char *String;
  308. {char ch;
  309.  int i = 0;
  310.  printf("%s",Prompt);
  311.  while(1)
  312.    {ch = KeyRead();
  313.     switch(ch)
  314.       {case CR:
  315.          SioCrtWrite(LF);
  316.          SioCrtWrite(CR);
  317.          String[i++] = '\0';
  318.          return(i);
  319.        case ESC:
  320.          String[0] = '\0';
  321.          return(0);
  322.        case BS:
  323.          if(i<=0) continue;
  324.          SioCrtWrite(BS);
  325.          SioCrtWrite(' ');
  326.          SioCrtWrite(BS);
  327.          i--;
  328.          break;
  329.       default:
  330.          SioCrtWrite(ch);
  331.          String[i++] = ch;
  332.          break;
  333.      } /* end switch */
  334.    } /* end while */
  335. } /* end GetString */
  336.  
  337. void SayProtocol(P)
  338. char P;
  339. {
  340.  printf("Protocol=");
  341.  switch(P)
  342.   {case 'X':
  343.      printf("XMODEM");
  344.      break;
  345.    case 'C':
  346.      printf("XMODEM-CRC");
  347.      break;
  348.    case '1':
  349.      printf("XMODEM-1K");
  350.      break;
  351.    case 'Y':
  352.      printf("YMODEM");
  353.      break;
  354.    case 'G':
  355.      printf("YMODEM-G");
  356.      break;
  357.    default:
  358.      printf("unknown.");
  359.      break;
  360.   } /* end switch */
  361. } /* end SayProtocol */
  362.