home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / PPL4C11.ZIP / XYPACKET.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-18  |  11.1 KB  |  372 lines

  1. /*** xypacket.c ***/
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <fcntl.h>
  6. #include <io.h>
  7. #include <conio.h>
  8. #include <sys\types.h>
  9. #include <sys\stat.h>
  10.  
  11. #include "pcl4c.h"
  12. #include "term.h"
  13. #include "crc16.h"
  14. #include "ascii.h"
  15. #include "term_io.h"
  16. #include "term.cfg"
  17. #include "timing.h"
  18. #include "win_io.h"
  19.  
  20. #define DEBUG 0
  21.  
  22. #define FALSE 0
  23. #define TRUE !FALSE
  24.  
  25. #define MAXTRY  5
  26. #define LIMIT  60
  27. #define XYDELAY 1
  28.  
  29. void PacketError(int ,int ,int ,char *);
  30.  
  31. int TxPacket(
  32.    int Port,            /* COM port [0..3] */
  33.    int PacketNbr,       /* Packet # to send */
  34.    int PacketSize,      /* Packet size ( must be 128 or 1024 ) */
  35.    char Buffer[],       /* Data buffer */
  36.    char NCGchar)        /* NAK, 'C', or 'G' */
  37. {int  i;
  38.  int Code;
  39.  unsigned short CheckSum;
  40.  int Attempt;
  41.  int PacketType;
  42.  char Temp[81];
  43.  int Full;
  44.  /* begin */
  45.  Full = GetBufSize();
  46. #if DEBUG
  47. sprintf(Temp,"[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
  48.     1+Port,PacketNbr,PacketSize,NCGchar);
  49. WinPutString(SCR_WIN,Temp);
  50. #endif
  51.  /* better be 128 or 1024 packet length */
  52.  if(PacketSize==1024) PacketType = STX;
  53.  else PacketType = SOH;
  54.  PacketNbr &= 0x00ff;
  55.  /* make up to MAXTRY attempts to send this packet */
  56.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  57.      {/* send SOH/STX  */
  58.       Code = CharPut(Port,(char)PacketType);
  59.       SioDelay(XYDELAY);
  60.       /* send packet # */
  61.       Code = CharPut(Port,(char)PacketNbr);
  62.       /* send 1's complement of packet */
  63.       Code = CharPut(Port,(char)(255-PacketNbr));
  64.       /* send data */
  65.       CheckSum = 0;
  66.       for(i=0;i<PacketSize;i++)
  67.           {Code = CharPut(Port,Buffer[i]);
  68.            if(NCGchar==NAK) CheckSum += Buffer[i];
  69.            else CheckSum = UpdateCRC(Buffer[i],CheckSum);
  70.            if(i%32==0)
  71.              {while(SioTxQue(Port)>=Full-32) SioDelay(1);
  72.              }
  73.           }
  74.       /* flush reverse channel */
  75.       SioRxClear(Port);
  76.       /* send checksum */
  77.       if(NCGchar==NAK)
  78.           {Code = CharPut(Port,(char)(CheckSum & 0x00ff) );
  79.           }
  80.       else
  81.           {Code = CharPut(Port, (char)((CheckSum>>8) & 0x00ff) );
  82.            Code = CharPut(Port, (char)(CheckSum & 0x00ff) );
  83.           }
  84.       /* no ACK to wait for if 'G' */
  85.       if(NCGchar=='G')
  86.          {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
  87.           return(TRUE);
  88.          }
  89.       /* wait for receivers ACK */
  90.       SioDelay(XYDELAY);     /* ??? */
  91.       Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
  92.       if(Code==-1)
  93.           {WriteMsg("No response from receiver");
  94.            return FALSE;
  95.           }
  96.       if((char)Code==CAN)
  97.           {WriteMsg("*** Canceled by REMOTE ***");
  98.            return(FALSE);
  99.           }
  100.       if((char)Code==ACK) return(TRUE);
  101.       if((char)Code!=NAK)
  102.           {sprintf(Temp,"Expecting ACK/NAK not %xH",(char)Code);
  103.            PacketError(Port,PacketNbr,Attempt,Temp);
  104.            return(FALSE);
  105.           }
  106.       /* Attempt again */
  107.       sprintf(Temp,"Packet %d NAKed\n",PacketNbr);
  108.       WinPutString(SCR_WIN,Temp);
  109.      }/* end -- for(Attempt) */
  110.  /* can't send packet ! */
  111.  SayError(Port,"packet timeout (3 NAKs)");
  112.  return(FALSE);
  113. } /* end -- TxPacket */
  114.  
  115. int RxPacket(
  116.    int Port,            /* COM port [0..3] */
  117.    int PacketNbr,       /* Packet # expected */
  118.    int *PacketSizePtr,  /* Pointer to PacketSize received ( 128 or 1024) */
  119.    char Buffer[],       /* 1024 byte data buffer */
  120.    char NCGchar,        /* NAK, C, or G */
  121.    int *EOTptr)         /* Pointer to EOT flag */
  122. {int i;
  123.  int Code;
  124.  int Attempt;
  125.  int RxPacketNbr;
  126.  int RxPacketNbrComp;
  127.  unsigned short CheckSum;
  128.  unsigned short RxCheckSum;
  129.  unsigned short RxCheckSum1;
  130.  unsigned short RxCheckSum2;
  131.  char Temp[81];
  132.  /* begin */
  133. #if DEBUG
  134. sprintf(Temp,"[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]\n",
  135.     1+Port,PacketNbr,NCGchar,*EOTptr);
  136. WinPutString(SCR_WIN,Temp);
  137. #endif
  138.  PacketNbr &= 0x00ff;
  139.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  140.      {/* wait for SOH / STX */
  141.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  142.       if(Code==-1)
  143.           {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
  144.            return(FALSE);
  145.           }
  146.       switch((char)Code)
  147.           {case SOH:
  148.                /* 128 byte buffer incoming */
  149.                *PacketSizePtr = 128;
  150.                break;
  151.            case STX:
  152.                /* 1024 byte buffer incoming */
  153.                *PacketSizePtr = 1024;
  154.                break;
  155.            case CAN:
  156.                 /* sender has canceled ! */
  157.                 WriteMsg("*** Canceled by REMOTE ***");
  158.                 return(FALSE);
  159.            case EOT:
  160.                 /* all packets have been sent */
  161.                 Code = CharPut(Port,ACK);
  162.                 *EOTptr = TRUE;
  163.                 return(TRUE);
  164.            default:
  165.                 /* error ! */
  166.                 sprintf(Temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
  167.                 PacketError(Port,PacketNbr,Attempt,Temp);
  168.                 return(FALSE);
  169.           }
  170.       /* receive packet # */
  171.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  172.       if(Code==-1)
  173.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
  174.          return(FALSE);
  175.         }
  176.       RxPacketNbr = 0x00ff & Code;
  177.       /* receive 1's complement */
  178.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  179.       if(Code==-1)
  180.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
  181.          return(FALSE);
  182.         }
  183.       RxPacketNbrComp = 0x00ff & Code;
  184.       /* verify packet number */
  185.       if(RxPacketNbr+RxPacketNbrComp!=255)
  186.           {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
  187.            return(FALSE);
  188.           }
  189.       /* receive data */
  190.       CheckSum = 0;
  191.       for(i=0;i<*PacketSizePtr;i++)
  192.           {Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
  193.            if(Code==-1)
  194.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
  195.                 return(FALSE);
  196.                }
  197.            Buffer[i] = Code;
  198.            /* compute CRC or checksum */
  199.            if(NCGchar!=NAK) CheckSum = UpdateCRC((unsigned char)Code,CheckSum);
  200.            else CheckSum = (CheckSum + Code) & 0x00ff;
  201.           }
  202.       /* receive CRC/checksum */
  203.       if(NCGchar!=NAK)
  204.           {/* receive 2 byte CRC */
  205.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  206.            if(Code==-1)
  207.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
  208.                 return(FALSE);
  209.                }
  210.            RxCheckSum1 = Code & 0x00ff;
  211.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  212.            if(Code==-1)
  213.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
  214.                 return(FALSE);
  215.                }
  216.            RxCheckSum2 = Code & 0x00ff;
  217.            RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
  218.           }
  219.       else
  220.           {/* receive one byte checksum */
  221.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  222.            if(Code==-1)
  223.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
  224.                 return(FALSE);
  225.                }
  226.            RxCheckSum = Code & 0x00ff;
  227.           }
  228.       /* don't send ACK if 'G' */
  229.       if(NCGchar=='G') return(TRUE);
  230.       /* checksum OK ? */
  231.       if(RxCheckSum!=CheckSum)
  232.           {WriteMsg("Bad packet checksum");
  233.            Code = CharPut(Port,NAK);
  234.            sprintf(Temp,"NAKing packet %d\n",PacketNbr);
  235.            WinPutString(SCR_WIN,Temp);
  236. #if DEBUG
  237.  sprintf(Temp,"RxPacket %d: Checksum: RX = %xH, Computed = %xH (%c)\n",
  238.         RxPacketNbr,RxCheckSum,CheckSum,NCGchar);
  239. WinPutString(SCR_WIN,Temp);
  240. #endif
  241.           }
  242.       /* packet number OK ? */
  243.       else if(RxPacketNbr!=PacketNbr)
  244.           {WriteMsg("Bad packet number");
  245.            Code = CharPut(Port,NAK);
  246.            sprintf(Temp,"NAKing packet %d\n",PacketNbr);
  247.            WinPutString(SCR_WIN,Temp);
  248.           }
  249.       else
  250.           {/* flush reverse channel */
  251.            SioRxClear(Port);
  252.            /* ACK the packet */
  253.            CharPut(Port,ACK);
  254.            return(TRUE);
  255.           } /* end if */
  256.      } /* end -- for(Attempt) */
  257.  /* can't receive packet */
  258.  SayError(Port,"RX packet timeout");
  259.  return(FALSE);
  260. } /* end -- RxPacket */
  261.  
  262.  
  263. void PacketError(int Port, int Packet, int Attempt, char *MsgPtr)
  264. {char Temp[81];
  265.  sprintf(Temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
  266.  SayError(Port,Temp);
  267. }
  268.  
  269. void SayNCGchar(char NCGchar)
  270. {switch(NCGchar)
  271.    {case NAK:
  272.         WriteMsg("Using Checksum");
  273.         break;
  274.     case 'C':
  275.         WriteMsg("Using CRC");
  276.         break;
  277.     case 'G':
  278.         WriteMsg("Using 'G'");
  279.         break;
  280.     default:
  281.         WriteHexMsg("What is ",NCGchar);
  282.    }
  283. }
  284.  
  285. int TxStartup(int Port,char *NCGcharPtr)
  286. {int i, c;
  287.  int Code;
  288. #if DEBUG
  289.  char Temp[81];
  290.  sprintf(Temp,"### TxStartup");
  291.  WinPutString(SCR_WIN,Temp);
  292. #endif
  293.  /* clear Rx buffer */
  294.  SioRxClear(Port);
  295.  /* wait for receivers start up NAK, 'C', or 'G' */
  296.  for(i=1;i<LIMIT;i++)
  297.      {if(kbhit())
  298.           {SayError(Port,"Aborted by user");
  299.            return(FALSE);
  300.           }
  301.       Code = CharGet(Port,ONE_SECOND);
  302.       if(Code==-1) continue;
  303.       /* received a byte */
  304.       SayNCGchar(*NCGcharPtr);
  305.       if(((char)Code==NAK)||((char)Code=='C')||((char)Code=='G'))
  306.          {*NCGcharPtr = (char)Code;
  307.           return TRUE;
  308.          }
  309.      } /* end -- for(i) */
  310.  /* no response */
  311.  SayError(Port,"No response from receiver");
  312.  return(FALSE);
  313. } /* end -- TxStartup */
  314.  
  315.  
  316. int RxStartup(int Port,char *NCGcharPtr)
  317. {int i, c;
  318.  int Code;
  319. #if DEBUG
  320.  char Temp[81];
  321.  sprintf(Temp,"### RxStartup");
  322.  WinPutString(SCR_WIN,Temp);
  323.  sprintf(Temp," %c<%xH>\n",*NCGcharPtr,*NCGcharPtr);
  324.  WinPutString(SCR_WIN,Temp);
  325. #endif
  326.  /* clear Rx buffer */
  327.  SioRxClear(Port);
  328.  SayNCGchar(*NCGcharPtr);
  329.  /* Send NAKs, 'C's, or 'G's */
  330.  for(i=1;i<LIMIT;i++)
  331.      {if(kbhit())
  332.           {WriteMsg("*** Canceled by USER ***");
  333.            return(FALSE);
  334.           }
  335.       /* stop attempting CRC/'G' after 1st 4 tries */
  336.       if((*NCGcharPtr!=NAK)&&(i==5))
  337.          {WriteMsg("Switching to NAKs");
  338.           *NCGcharPtr = NAK;
  339.          }
  340.       /* tell sender that I am ready to receive */
  341.       Code = CharPut(Port,*NCGcharPtr);
  342. #if DEBUG
  343. sprintf(Temp,"<%xH>",*NCGcharPtr);
  344. WinPutString(SCR_WIN,Temp);
  345. #endif
  346.       Code = CharGet(Port,ONE_SECOND);
  347.       if(Code==-1) continue;
  348.       /* no error -- must be incoming byte -- push byte back onto queue ! */
  349.       SioUnGetc(Port,(char)Code);
  350. #if DEBUG
  351.       sprintf("OK <%xH>\n",Code);
  352.       WinPutString(SCR_WIN,Temp);
  353. #endif
  354.       return(TRUE);
  355.      } /* end -- for(i) */
  356.  /* no response */
  357.  SayError(Port,"No response from sender");
  358.  return(FALSE);
  359. } /* end -- RxStartup */
  360.  
  361. int TxEOT(int Port)
  362. {int i;
  363.  int Code;
  364.  for(i=0;i<10;i++)
  365.      {Code = CharPut(Port,EOT);
  366.       /* await response */
  367.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  368.       if((char)Code==ACK) return(TRUE);
  369.      } /* end -- for(i) */
  370.   return(FALSE);
  371.  } /* end -- TxEOT */
  372.