?? ecusea.c
字號:
char *cancel_msg = "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b"; ioctl(iofd,TCFLSH,(char *)1); write(iofd,cancel_msg,16); tx_char_count += 16; report_str("CANCELling transfer",1); report_last_txhdr("CAN",0);} /* end of xmit_cancel *//*+------------------------------------------------------------------------- xmit_ack(blknum)--------------------------------------------------------------------------*/voidxmit_ack(blknum)register int blknum; /* block number */{char s16[16]; sprintf(s16,"ACK %3d",blknum); report_last_txhdr(s16,0); s16[0] = ACK; s16[1] = blknum; /* block number */ s16[2] = blknum ^ 0xFF; /* block number check */ write(iofd,s16,3); tx_char_count += 3;} /* end of xmit_ack *//*+------------------------------------------------------------------------- xmit_nak(blknum)--------------------------------------------------------------------------*/voidxmit_nak(blknum)register int blknum; /* block number */{char s16[16]; sprintf(s16,"NAK %d",blknum); report_last_txhdr(s16,1); if(crc_in_use) s16[0] = 'C'; else s16[0] = NAK; s16[1] = blknum; /* block number */ s16[2] = blknum ^ 0xFF; /* block number check */ write(iofd,s16,3); tx_char_count += 3;} /* end of xmit_nak *//*+------------------------------------------------------------------------- lgetc_timeout_SIGALRM() - called when alarm is caught by lgetc_timeout--------------------------------------------------------------------------*/#if defined(NO_SELECT)voidlgetc_timeout_SIGALRM(sig)int sig;{ longjmp(lgetc_timeout_setjmp,TIMEOUT);} /* end of lgetc_timeout_SIGALRM */#endif/*+------------------------------------------------------------------------- lgetc_timeout(tenths) reads one character from line unless timeout in tenths passes with no receipt.--------------------------------------------------------------------------*/unsigned intlgetc_timeout(tenths)int tenths;{#if defined(NO_SELECT)unsigned char rdchar;long msec;int seconds;long Nap();#elseint fdmask;struct timeval tval;unsigned char rdchar;#endif if(!tenths) { if(!rdchk(iofd)) return(TIMEOUT); else { read(iofd,&rdchar,1); rx_char_count++; return((unsigned int)rdchar); } }#if defined(NO_SELECT)/* there is a timeout ... if less than 2 secs, nap it out */ if(tenths <= 20) { msec = (tenths < 6) ? 60L : (long)tenths * 10; while(msec) { msec -= Nap(20L); if(rdchk(iofd)) { read(iofd,&rdchar,1); rx_char_count++; return((unsigned int)rdchar); } } report_last_rxhdr("TIMEOUT",0); return(TIMEOUT); }/* timeout is > 2 seconds use sleep */ seconds = (tenths / 10) + 1; if(setjmp(lgetc_timeout_setjmp)) { report_last_rxhdr("TIMEOUT",0); return(TIMEOUT); } signal(SIGALRM,lgetc_timeout_SIGALRM); alarm(seconds); while(read(iofd,&rdchar,1) != 1) ; alarm(0); signal(SIGALRM,SIG_DFL);#else if(tenths < 6) tenths = 6; tval.tv_sec = tenths / 10L; tval.tv_usec = (tenths % 10L) * 100000L; fdmask = 1 << iofd; if(select(32,&fdmask,(int *)0,(int *)0,&tval) != 1) { report_last_rxhdr("TIMEOUT",0); return(TIMEOUT); } if((!rdchk(iofd)) || (read(iofd,&rdchar,1) < 0)) { report_last_rxhdr("TIMEOUT",0); return(TIMEOUT); }#endif rx_char_count++; return((unsigned int)rdchar);} /* end of lgetc_timeout *//*+------------------------------------------------------------------------- sf_state_text(state)--------------------------------------------------------------------------*/char *sf_state_text(state)register state;{char unrecog[16]; switch(state) { case SFS_GND: return("GND"); case SFS_ACK: return("ACK"); case SFS_NAK: return("NAK"); case SFS_ACKW: return("ACKW"); case SFS_NAKW: return("NAKW"); case SFS_RGND: return("RGND"); default: sprintf(unrecog,"SFS_%d",state); return(unrecog); }} /* end of sf_state_text *//*+------------------------------------------------------------------------- set_sf_state(place,new_state)--------------------------------------------------------------------------*/voidset_sf_state(place,new_state)int place;int new_state;{ if(log_packets) { sprintf(s128,"state from %s to %s (%d)", sf_state_text(sf_state),sf_state_text(new_state),place); report_str(s128,0); } sf_state = new_state;} /* end of set_sf_state *//*+------------------------------------------------------------------------- wait_for_rcvr_response() - check for ACK or NAK sets 'sf_state' to SFS_... value depending on response from file rcvr returns 1 if TIMEOUT at state other than ground, else 0--------------------------------------------------------------------------*/intwait_for_rcvr_response(){int c; /* one byte of data */static int rawblk = 0; /* raw block number */ while((c = lgetc_timeout((sf_state == SFS_GND) ? 0 : 6)) != TIMEOUT) { if(c == CAN) { /* CANcel received? */ if((c = lgetc_timeout(20)) == CAN) { sf_nakquan = 11; report_last_rxhdr("CAN",0); /* error counted at cancel time */ } break; } if(sf_state == SFS_ACKW || sf_state == SFS_NAKW) /* windowed */ { sf_slide = 0; /* assume this will fail */ /* see if we believe the number */ if(rawblk == (c ^ 0xFF)) { rawblk = sf_blknum - ((sf_blknum - rawblk) & 0xFF); if((rawblk >= 0) && (rawblk <= sf_blknum) && (rawblk > (sf_blknum - 128))) { /* we have sliding window! */ if(sf_state == SFS_ACKW) { sf_ackblk = (sf_ackblk > rawblk) ? sf_ackblk : rawblk; sf_slide = 1; if(no_ack_mode && (++sf_ackw_count > 10)) { no_ack_mode = 0; report_str("Overdrive disengaged",0); } } else { sf_blknum = (rawblk < 0) ? 0 : rawblk; sf_slide = (sf_nakquan < 4); } sprintf(s128,"%s %5d", (sf_state == SFS_ACKW) ? "ACKW" : "NAKW",rawblk); report_last_rxhdr(s128,(sf_state != SFS_ACKW) && rawblk); } } set_sf_state(1,SFS_RGND); /* return to ground state */ } if(sf_state == SFS_ACK || sf_state == SFS_NAK) { rawblk = c; if(sf_state == SFS_ACK) set_sf_state(2,SFS_ACKW); else set_sf_state(3,SFS_NAKW); } if(!sf_slide || sf_state == SFS_GND) { if(c == ACK) { if(!sf_slide) { sprintf(s128,"ACK %3d",sf_ackblk); report_last_rxhdr(s128,0); sf_ackblk++; } set_sf_state(4,SFS_ACK); sf_nakquan = 0; } else if(c == 'C' || c == NAK) { /* if method not determined yet */ if(crc_in_use > 1) /* then do what rcvr wants */ { crc_in_use = (c == 'C'); report_protocol_crc_type(crc_in_use ? "/CRC16" : "/CHK"); } ioctl(iofd,TCFLSH,(char *)1); if(!sf_slide) { sf_blknum = sf_ackblk + 1; sprintf(s128,"NAK %3d",sf_blknum); report_last_rxhdr(s128,(!!sf_blknum)); } set_sf_state(5,SFS_NAK); sf_nakquan++; if(sf_lastnum) error_count++; } } if(sf_state == SFS_RGND) set_sf_state(6,SFS_GND); } return((sf_state != SFS_GND) && (c == TIMEOUT));} /* end of wait_for_rcvr_response *//*+------------------------------------------------------------------------- send_comm_block(blk,blknum) - format and transmit block--------------------------------------------------------------------------*/intsend_comm_block(blk,blknum)char *blk; /* data to be shipped */int blknum; /* number of block */{register unsigned short rUINT16 = 0;register int itmp;unsigned char chksum;char *cptr = blk;char s3[3]; s3[0] = SOH; /* block header */ s3[1] = blknum; /* block number */ s3[2] = blknum ^ 0xFF; /* block number check value *//* calculate the crc or checksum */ itmp = 128; if(crc_in_use) { while(itmp--) { rUINT16 = crc_update(*cptr,rUINT16); cptr++; } rUINT16 = crc_update(0,rUINT16); rUINT16 = crc_update(0,rUINT16); } else { while(itmp--) rUINT16 += *cptr++; }/* write the block */ write(iofd,s3,3); /* the header */ write(iofd,blk,128); /* the block */ if(crc_in_use) /* the crc or checksum */ { s3[0] = rUINT16 >> 8; s3[1] = rUINT16 & 0xFF; write(iofd,s3,2); tx_char_count += 133; } else { chksum = rUINT16; write(iofd,&chksum,1); tx_char_count += 132; } return(1);} /* end of send_comm_block *//*+------------------------------------------------------------------------- send_file_block(fp,blknum) - read a block from file and send it--------------------------------------------------------------------------*/voidsend_file_block(fp,blknum)FILE *fp;int blknum;{long fileaddr;char buf[128]; fileaddr = (long)(blknum - 1) * 128L; if(blknum != sf_lastnum + 1) fseek(fp,fileaddr,0); /* move where to */ sf_lastnum = blknum; report_txpos(fileaddr); memset(buf,0x1A,sizeof(buf)); /* fill buffer with control Zs */ fread(buf,1,sizeof(buf),fp); /* read in some data */ send_comm_block(buf,blknum); /* pump it out to the receiver */} /* end of send_file_block *//*+------------------------------------------------------------------------- send_file(name) - transmit a file--------------------------------------------------------------------------*/intsend_file(name)char *name;{register int endblk; /* block number of EOT */FILE *fp = (FILE *)0; /* file to send */struct stat fst;BLK0 blk0;char *basename; /* base filename */char eot = EOT; Filcnt++; if(name && *name) /* if sending a file */ { if((fp = fopen(name,"r")) == NULL) { sprintf(s128,"Cannot open %s",name); report_str(s128,1); exit_code = 253; return(0); } memset((char *)&blk0,0,sizeof(blk0)); /* clear out data block */ stat(name,&fst); /* get file statistics */ blk0.length = (long)fst.st_size; /* cnvt time from 1970 base to 1980 */ if((blk0.secs_since_1980 = fst.st_mtime-OFFSET_1980) < 0L) blk0.secs_since_1980 = 0; if((basename = strrchr(name,'/')) == NULL) /* find basename */ strcpy(blk0.filename,name); else { basename++; strcpy(blk0.filename,basename); } strcpy(blk0.sender,"ecusea "); strcat(blk0.sender,revision); blk0.send_no_acks = no_ack_mode; endblk = (int)((blk0.length + 127L) / 128L) + 1; report_file_send_open(name,&fst); } else { endblk = 0; /* fake for no file */ report_str("sending EOT indication",-1); report_txpos(blk0.length); } sf_blknum = 1; /* set starting state */ sf_ackblk = -1; sf_state = SFS_GND; sf_lastnum = 0; sf_slide = 0; sf_nakquan = 0; error_count = 0; sf_ackw_count = 0; crc_in_use = 2; /* undetermined */ while(sf_ackblk < endblk) /* while not all there yet */ { sent_EOT = 0; if(sf_blknum <= sf_ackblk + ((sf_slide && allow_slide) ? WINDOW : 1)) { if(sf_blknum < endblk) { if(sf_blknum > 0) { sprintf(s128,"sending block %d",sf_blknum); report_last_txhdr(s128,0); send_file_block(fp,sf_blknum); } else { sprintf(s128,"sending filename",sf_blknum); report_last_txhdr(s128,0); send_comm_block((char *)&blk0,0); report_txpos(0L); } if(no_ack_mode && sf_slide && allow_slide) sf_ackblk = sf_blknum; } else if(sf_blknum == endblk) { report_last_txhdr("EOT",0); write(iofd,&eot,1); sent_EOT = 1; Nap(500L); tx_char_count++; } sf_blknum++; } if(wait_for_rcvr_response() && sent_EOT) { report_str("Receiver did not ACK our EOT",-1); break; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -