home *** CD-ROM | disk | FTP | other *** search
/ PC Media 4 / PC MEDIA CD04.iso / share / prog / pcl4c42 / xypacket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-21  |  10.2 KB  |  344 lines

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