⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecusea.c

📁 一个通讯程序源码
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -