home *** CD-ROM | disk | FTP | other *** search
- /*** xypacket.c ***/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <io.h>
- #include <conio.h>
- #include <sys\types.h>
- #include <sys\stat.h>
-
- #include "pcl4c.h"
- #include "term.h"
- #include "crc16.h"
- #include "ascii.h"
- #include "term_io.h"
- #include "term.cfg"
- #include "timing.h"
- #include "win_io.h"
-
- #define DEBUG 0
-
- #define FALSE 0
- #define TRUE !FALSE
-
- #define MAXTRY 5
- #define LIMIT 60
- #define XYDELAY 1
-
- void PacketError(int ,int ,int ,char *);
-
- int TxPacket(
- int Port, /* COM port [0..3] */
- int PacketNbr, /* Packet # to send */
- int PacketSize, /* Packet size ( must be 128 or 1024 ) */
- char Buffer[], /* Data buffer */
- char NCGchar) /* NAK, 'C', or 'G' */
- {int i;
- int Code;
- unsigned short CheckSum;
- int Attempt;
- int PacketType;
- char Temp[81];
- int Full;
- /* begin */
- Full = GetBufSize();
- #if DEBUG
- sprintf(Temp,"[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
- 1+Port,PacketNbr,PacketSize,NCGchar);
- WinPutString(SCR_WIN,Temp);
- #endif
- /* better be 128 or 1024 packet length */
- if(PacketSize==1024) PacketType = STX;
- else PacketType = SOH;
- PacketNbr &= 0x00ff;
- /* make up to MAXTRY attempts to send this packet */
- for(Attempt=1;Attempt<=MAXTRY;Attempt++)
- {/* send SOH/STX */
- Code = CharPut(Port,(char)PacketType);
- SioDelay(XYDELAY);
- /* send packet # */
- Code = CharPut(Port,(char)PacketNbr);
- /* send 1's complement of packet */
- Code = CharPut(Port,(char)(255-PacketNbr));
- /* send data */
- CheckSum = 0;
- for(i=0;i<PacketSize;i++)
- {Code = CharPut(Port,Buffer[i]);
- if(NCGchar==NAK) CheckSum += Buffer[i];
- else CheckSum = UpdateCRC(Buffer[i],CheckSum);
- if(i%32==0)
- {while(SioTxQue(Port)>=Full-32) SioDelay(1);
- }
- }
- /* flush reverse channel */
- SioRxClear(Port);
- /* send checksum */
- if(NCGchar==NAK)
- {Code = CharPut(Port,(char)(CheckSum & 0x00ff) );
- }
- else
- {Code = CharPut(Port, (char)((CheckSum>>8) & 0x00ff) );
- Code = CharPut(Port, (char)(CheckSum & 0x00ff) );
- }
- /* no ACK to wait for if 'G' */
- if(NCGchar=='G')
- {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
- return(TRUE);
- }
- /* wait for receivers ACK */
- SioDelay(XYDELAY); /* ??? */
- Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
- if(Code==-1)
- {WriteMsg("No response from receiver");
- return FALSE;
- }
- if((char)Code==CAN)
- {WriteMsg("*** Canceled by REMOTE ***");
- return(FALSE);
- }
- if((char)Code==ACK) return(TRUE);
- if((char)Code!=NAK)
- {sprintf(Temp,"Expecting ACK/NAK not %xH",(char)Code);
- PacketError(Port,PacketNbr,Attempt,Temp);
- return(FALSE);
- }
- /* Attempt again */
- sprintf(Temp,"Packet %d NAKed\n",PacketNbr);
- WinPutString(SCR_WIN,Temp);
- }/* end -- for(Attempt) */
- /* can't send packet ! */
- SayError(Port,"packet timeout (3 NAKs)");
- return(FALSE);
- } /* end -- TxPacket */
-
- int RxPacket(
- int Port, /* COM port [0..3] */
- int PacketNbr, /* Packet # expected */
- int *PacketSizePtr, /* Pointer to PacketSize received ( 128 or 1024) */
- char Buffer[], /* 1024 byte data buffer */
- char NCGchar, /* NAK, C, or G */
- int *EOTptr) /* Pointer to EOT flag */
- {int i;
- int Code;
- int Attempt;
- int RxPacketNbr;
- int RxPacketNbrComp;
- unsigned short CheckSum;
- unsigned short RxCheckSum;
- unsigned short RxCheckSum1;
- unsigned short RxCheckSum2;
- char Temp[81];
- /* begin */
- #if DEBUG
- sprintf(Temp,"[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]\n",
- 1+Port,PacketNbr,NCGchar,*EOTptr);
- WinPutString(SCR_WIN,Temp);
- #endif
- PacketNbr &= 0x00ff;
- for(Attempt=1;Attempt<=MAXTRY;Attempt++)
- {/* wait for SOH / STX */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
- return(FALSE);
- }
- switch((char)Code)
- {case SOH:
- /* 128 byte buffer incoming */
- *PacketSizePtr = 128;
- break;
- case STX:
- /* 1024 byte buffer incoming */
- *PacketSizePtr = 1024;
- break;
- case CAN:
- /* sender has canceled ! */
- WriteMsg("*** Canceled by REMOTE ***");
- return(FALSE);
- case EOT:
- /* all packets have been sent */
- Code = CharPut(Port,ACK);
- *EOTptr = TRUE;
- return(TRUE);
- default:
- /* error ! */
- sprintf(Temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
- PacketError(Port,PacketNbr,Attempt,Temp);
- return(FALSE);
- }
- /* receive packet # */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
- return(FALSE);
- }
- RxPacketNbr = 0x00ff & Code;
- /* receive 1's complement */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
- return(FALSE);
- }
- RxPacketNbrComp = 0x00ff & Code;
- /* verify packet number */
- if(RxPacketNbr+RxPacketNbrComp!=255)
- {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
- return(FALSE);
- }
- /* receive data */
- CheckSum = 0;
- for(i=0;i<*PacketSizePtr;i++)
- {Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
- return(FALSE);
- }
- Buffer[i] = Code;
- /* compute CRC or checksum */
- if(NCGchar!=NAK) CheckSum = UpdateCRC((unsigned char)Code,CheckSum);
- else CheckSum = (CheckSum + Code) & 0x00ff;
- }
- /* receive CRC/checksum */
- if(NCGchar!=NAK)
- {/* receive 2 byte CRC */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
- return(FALSE);
- }
- RxCheckSum1 = Code & 0x00ff;
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
- return(FALSE);
- }
- RxCheckSum2 = Code & 0x00ff;
- RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
- }
- else
- {/* receive one byte checksum */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if(Code==-1)
- {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
- return(FALSE);
- }
- RxCheckSum = Code & 0x00ff;
- }
- /* don't send ACK if 'G' */
- if(NCGchar=='G') return(TRUE);
- /* checksum OK ? */
- if(RxCheckSum!=CheckSum)
- {WriteMsg("Bad packet checksum");
- Code = CharPut(Port,NAK);
- sprintf(Temp,"NAKing packet %d\n",PacketNbr);
- WinPutString(SCR_WIN,Temp);
- #if DEBUG
- sprintf(Temp,"RxPacket %d: Checksum: RX = %xH, Computed = %xH (%c)\n",
- RxPacketNbr,RxCheckSum,CheckSum,NCGchar);
- WinPutString(SCR_WIN,Temp);
- #endif
- }
- /* packet number OK ? */
- else if(RxPacketNbr!=PacketNbr)
- {WriteMsg("Bad packet number");
- Code = CharPut(Port,NAK);
- sprintf(Temp,"NAKing packet %d\n",PacketNbr);
- WinPutString(SCR_WIN,Temp);
- }
- else
- {/* flush reverse channel */
- SioRxClear(Port);
- /* ACK the packet */
- CharPut(Port,ACK);
- return(TRUE);
- } /* end if */
- } /* end -- for(Attempt) */
- /* can't receive packet */
- SayError(Port,"RX packet timeout");
- return(FALSE);
- } /* end -- RxPacket */
-
-
- void PacketError(int Port, int Packet, int Attempt, char *MsgPtr)
- {char Temp[81];
- sprintf(Temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
- SayError(Port,Temp);
- }
-
- void SayNCGchar(char NCGchar)
- {switch(NCGchar)
- {case NAK:
- WriteMsg("Using Checksum");
- break;
- case 'C':
- WriteMsg("Using CRC");
- break;
- case 'G':
- WriteMsg("Using 'G'");
- break;
- default:
- WriteHexMsg("What is ",NCGchar);
- }
- }
-
- int TxStartup(int Port,char *NCGcharPtr)
- {int i, c;
- int Code;
- #if DEBUG
- char Temp[81];
- sprintf(Temp,"### TxStartup");
- WinPutString(SCR_WIN,Temp);
- #endif
- /* clear Rx buffer */
- SioRxClear(Port);
- /* wait for receivers start up NAK, 'C', or 'G' */
- for(i=1;i<LIMIT;i++)
- {if(kbhit())
- {SayError(Port,"Aborted by user");
- return(FALSE);
- }
- Code = CharGet(Port,ONE_SECOND);
- if(Code==-1) continue;
- /* received a byte */
- SayNCGchar(*NCGcharPtr);
- if(((char)Code==NAK)||((char)Code=='C')||((char)Code=='G'))
- {*NCGcharPtr = (char)Code;
- return TRUE;
- }
- } /* end -- for(i) */
- /* no response */
- SayError(Port,"No response from receiver");
- return(FALSE);
- } /* end -- TxStartup */
-
-
- int RxStartup(int Port,char *NCGcharPtr)
- {int i, c;
- int Code;
- #if DEBUG
- char Temp[81];
- sprintf(Temp,"### RxStartup");
- WinPutString(SCR_WIN,Temp);
- sprintf(Temp," %c<%xH>\n",*NCGcharPtr,*NCGcharPtr);
- WinPutString(SCR_WIN,Temp);
- #endif
- /* clear Rx buffer */
- SioRxClear(Port);
- SayNCGchar(*NCGcharPtr);
- /* Send NAKs, 'C's, or 'G's */
- for(i=1;i<LIMIT;i++)
- {if(kbhit())
- {WriteMsg("*** Canceled by USER ***");
- return(FALSE);
- }
- /* stop attempting CRC/'G' after 1st 4 tries */
- if((*NCGcharPtr!=NAK)&&(i==5))
- {WriteMsg("Switching to NAKs");
- *NCGcharPtr = NAK;
- }
- /* tell sender that I am ready to receive */
- Code = CharPut(Port,*NCGcharPtr);
- #if DEBUG
- sprintf(Temp,"<%xH>",*NCGcharPtr);
- WinPutString(SCR_WIN,Temp);
- #endif
- Code = CharGet(Port,ONE_SECOND);
- if(Code==-1) continue;
- /* no error -- must be incoming byte -- push byte back onto queue ! */
- SioUnGetc(Port,(char)Code);
- #if DEBUG
- sprintf("OK <%xH>\n",Code);
- WinPutString(SCR_WIN,Temp);
- #endif
- return(TRUE);
- } /* end -- for(i) */
- /* no response */
- SayError(Port,"No response from sender");
- return(FALSE);
- } /* end -- RxStartup */
-
- int TxEOT(int Port)
- {int i;
- int Code;
- for(i=0;i<10;i++)
- {Code = CharPut(Port,EOT);
- /* await response */
- Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
- if((char)Code==ACK) return(TRUE);
- } /* end -- for(i) */
- return(FALSE);
- } /* end -- TxEOT */