/*** xypacket.c ***/ #include #include #include #include #include #include #include "pcl4c.h" #include "term.h" #include "crc.h" #include "ascii.h" #include "term_io.h" #include "term.cfg" #define DEBUG 0 #define FALSE 0 #define TRUE !FALSE #define MAXTRY 5 #define LIMIT 20 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]; /* begin */ #if DEBUG printf("[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]", 1+Port,PacketNbr,PacketSize,NCGchar); #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 = PutChar(Port,(char)PacketType); /* send packet # */ Code = PutChar(Port,(char)PacketNbr); /* send 1's complement of packet */ Code = PutChar(Port,(char)(255-PacketNbr)); /* send data */ CheckSum = 0; for(i=0;i>8) & 0x00ff) ); Code = PutChar(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 */ Code = GetChar(Port,LONG_WAIT*ONE_SECOND); if((char)Code==CAN) {DisplayLine("*** Canceled by REMOTE ***",NULL,0); return(FALSE); } if((char)Code==ACK) return(TRUE); if((char)Code!=NAK) {PacketError(Port,PacketNbr,Attempt,"Out of sync"); return(FALSE); } /* Attempt again */ }/* 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, RxCheckSum2; /*char PacketType;*/ char temp[81]; /* begin */ #if DEBUG printf("[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]", 1+Port,PacketNbr,NCGchar,*EOTptr); #endif PacketNbr &= 0x00ff; for(Attempt=1;Attempt<=MAXTRY;Attempt++) {/* wait for SOH / STX */ Code = GetChar(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 */ /*PacketType = SOH;*/ *PacketSizePtr = 128; break; case STX: /* 1024 byte buffer incoming */ /*PacketType = STX;*/ *PacketSizePtr = 1024; break; case CAN: /* sender has canceled ! */ DisplayLine("*** Canceled by REMOTE ***",NULL,0); return(FALSE); case EOT: /* all packets have been sent */ Code = PutChar(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 = GetChar(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 = GetChar(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 = GetChar(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(CheckSum,(unsigned char)Code); else CheckSum = (CheckSum + Code) & 0x00ff; } /* receive CRC/checksum */ if(NCGchar!=NAK) {/* receive 2 byte CRC */ Code = GetChar(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 = GetChar(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 = GetChar(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) {DisplayLine("Bad packet checksum",NULL,0); Code = PutChar(Port,NAK); #if DEBUG printf("RxPacket %d: Checksum: RX = %xH, Computed = %xH (%c)\n", RxPacketNbr,RxCheckSum,CheckSum,NCGchar); #endif } /* packet number OK ? */ else if(RxPacketNbr!=PacketNbr) {DisplayLine("Bad packet number",NULL,0); Code = PutChar(Port,NAK); } else {/* ACK the packet */ PutChar(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); } int TxStartup(int Port,char *NCGcharPtr) {int i; int Code; #if DEBUG printf("### TxStartup"); #endif /* clear Rx buffer */ SioRxFlush(Port); /* wait for receivers start up NAK, 'C', or 'G' */ for(i=1;i"); #endif } /* tell sender that I am ready to receive */ Code = PutChar(Port,*NCGcharPtr); #if DEBUG printf("<%c>",*NCGcharPtr); #endif Code = GetChar(Port,SHORT_WAIT*ONE_SECOND); if(Code==-1) continue; /* no error -- must be incoming byte -- push byte back onto queue ! */ SioUnGetc(Port,(char)Code); #if DEBUG printf("OK\n"); #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 = PutChar(Port,EOT); /* await response */ Code = GetChar(Port,SHORT_WAIT*ONE_SECOND); if((char)Code==ACK) return(TRUE); } /* end -- for(i) */ return(FALSE); } /* end -- TxEOT */