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

📄 zmodem.cpp

📁 这是G.723和G.729的音频编解码的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			 */
			cleanup();

			//return TIMEOUT;//exit(CAN);
			::ExitThread(CAN);//0x18
		}
	}
	else {
		n_cans = 0;
	}

	return c;
}

/*
 * rx; receive a single byte undoing any escaping at the
 * sending site. this bit looks like a mess. sorry for that
 * but there seems to be no other way without incurring a lot
 * of overhead. at least like this the path for a normal character
 * is relatively short.
 */

int
Czmodem::rx(int to)

{
	int c;

	/*
	 * outer loop for ever so for sure something valid
	 * will come in; a timeout will occur or a session abort
	 * will be received.
	 */

	while (TRUE) {

		/*
	 	 * fake do loop so we may continue
		 * in case a character should be dropped.
		 */

		do {
			c = rx_raw(to);
			if (c == TIMEOUT) {
				return c;
			}
	
			switch (c) {
				case ZDLE:
					break;
				case 0x11://XON
				case 0x91:
				case 0x13:
				case 0x93:
					continue;			
					break;
				default:
					/*
	 				 * if all control characters should be escaped and 
					 * this one wasnt then its spurious and should be dropped.
					 */
					if (escape_all_control_characters && (c & 0x60) == 0) {
						continue;
					}
					/*
					 * normal character; return it.
					 */
					return c;
			}
		} while (FALSE);
	
		/*
	 	 * ZDLE encoded sequence or session abort.
		 * (or something illegal; then back to the top)
		 */

		do {
			c = rx_raw(to);

			if (c == 0x11 || c == 0x13 || c == 0x91 || c == 0x93 || c == ZDLE) {
				/*
				 * these can be dropped.
				 */
				continue;
			}

			switch (c) {
				/*
				 * these four are really nasty.
				 * for convenience we just change them into 
				 * special characters by setting a bit outside the
				 * first 8. that way they can be recognized and still
				 * be processed as characters by the rest of the code.
				 */
				case ZCRCE:
				case ZCRCG:
				case ZCRCQ:
				case ZCRCW:
					return (c | ZDLEESC);
					break;
				case ZRUB0:
					return 0x7f;
					break;
				case ZRUB1:
					return 0xff;
					break;
				default:
					if (escape_all_control_characters && (c & 0x60) == 0) {
						/*
						 * a not escaped control character; probably
						 * something from a network. just drop it.
						 */
						continue;
					}
					/*
					 * legitimate escape sequence.
					 * rebuild the orignal and return it.
					 */
					if ((c & 0x60) == 0x40) {
						return c ^ 0x40;
					}
					break;
			}
		} while (FALSE);
	}

	/*
	 * not reached.
	 */

	return 0;
}

/*
 * receive a data subpacket as dictated by the last received header.
 * return 2 with correct packet and end of frame
 * return 1 with correct packet frame continues
 * return 0 with incorrect frame.
 * return TIMEOUT with a timeout
 * if an acknowledgement is requested it is generated automatically
 * here. 
 */

/*
 * data subpacket reception
 */

int Czmodem::rx_32_data(unsigned char * p,int * l)

{
	int c;
	unsigned long rxd_crc;
	unsigned long crc;
	int sub_frame_type;


	TRACE("rx_32_data\n");


	crc = 0xffffffffl;

	do {
		c = rx(1000);

		if (c == TIMEOUT) {
			return TIMEOUT;
		}
		if (c < 0x100) {
			crc = UPDCRC32(c,crc);
			*p++ = c;
			(*l)++;
			continue;
		}
	} while (c < 0x100);

	sub_frame_type = c & 0xff;

	crc = UPDCRC32(sub_frame_type, crc);

	crc = ~crc;

	rxd_crc  = rx(1000);
	rxd_crc |= rx(1000) << 8;
	rxd_crc |= rx(1000) << 16;
	rxd_crc |= rx(1000) << 24;

	if (rxd_crc != crc) {
		return FALSE;
	}

	ack_file_pos += *l;

	return sub_frame_type;
}

int
Czmodem::rx_16_data(register unsigned char * p,int * l)

{
	register int c;
	int sub_frame_type;
 	register unsigned short crc;
	unsigned short rxd_crc;


	TRACE("rx_16_data\n");


	crc = 0;

	do {
		c = rx(5000);

		if (c == TIMEOUT) {
			return TIMEOUT;
		}
		if (c < 0x100) {
			crc = UPDCRC16(c,crc);
			*p++ = c;
			(*l)++;
		}
	} while (c < 0x100);

	sub_frame_type = c & 0xff;

	crc = UPDCRC16(sub_frame_type,crc);

	crc = UPDCRC16(0,crc);
	crc = UPDCRC16(0,crc);

	rxd_crc  = rx(1000) << 8;
	rxd_crc |= rx(1000);

	if (rxd_crc != crc) {
		return FALSE;
	}

	ack_file_pos += *l;

	return sub_frame_type;
}

int Czmodem::rx_data(unsigned char * p, int * l)
{
	unsigned char zack_header[] = { ZACK, 0, 0, 0, 0 };
	int sub_frame_type;
	long pos;

	/*
	 * fill in the file pointer in case acknowledgement is requested.	
	 * the ack file pointer will be updated in the subpacket read routine;
	 * so we need to get it now
	 */

	pos = ack_file_pos;

	/*
	 * receive the right type of frame
	 */

	*l = 0;

	if (receive_32_bit_data) {
		sub_frame_type = rx_32_data(p,l);
	}
	else {	
		sub_frame_type = rx_16_data(p,l);
	}

	switch (sub_frame_type)  {
		case TIMEOUT:
			return TIMEOUT;
			break;
		/*
		 * frame continues non-stop
		 */
		case ZCRCG:
			return FRAMEOK;
			break;
		/*
		 * frame ends
		 */
		case ZCRCE:
			return ENDOFFRAME;
			break;
		/*
 		 * frame continues; ZACK expected
		 */
		case ZCRCQ:		
			tx_pos_header(ZACK,pos);
			tx_raw(XON);//1999.10.21, add by lhf, for cdemultiplex can locate on frame zack
			return FRAMEOK;
			break;
		/*
		 * frame ends; ZACK expected
		 */
		case ZCRCW:
			tx_pos_header(ZACK,pos);
			tx_raw(XON);//1999.10.21, add by lhf, for cdemultiplex can locate on frame zack
			return ENDOFFRAME;
			break;
	}

	return FALSE;
}

int Czmodem::rx_nibble(int to) 

{
	int c;

	c = rx(to);

	if (c == TIMEOUT) {
		return c;
	}

	if (c > '9') {
		if (c < 'a' || c > 'f') {
			/*
			 * illegal hex; different than expected.
			 * we might as well time out.
			 */
			return TIMEOUT;
		}

		c -= 'a' - 10;
	}
	else {
		if (c < '0') {
			/*
			 * illegal hex; different than expected.
			 * we might as well time out.
			 */
			return TIMEOUT;
		}
		c -= '0';
	}

	return c;
}

int
Czmodem::rx_hex(int to)

{
	int n1;
	int n0;

	n1 = rx_nibble(to);

	if (n1 == TIMEOUT) {
		return n1;
	}

	n0 = rx_nibble(to);

	if (n0 == TIMEOUT) {
		return n0;
	}

	return (n1 << 4) | n0;
}

/*
 * receive routines for each of the six different styles of header.
 * each of these leaves rxd_header_len set to 0 if the end result is
 * not a valid header.
 */

void Czmodem::rx_bin16_header(int to)

{
	int c;
	int n;
	unsigned short int crc;
	unsigned short int rxd_crc;


	TRACE("rx binary header 16 bits crc\n");


	crc = 0;

	for (n=0;n<5;n++) {
		c = rx(to);
		if (c == TIMEOUT) {

			TRACE("timeout\n");

			return;
		}
		crc = UPDCRC16(c,crc);
		rxd_header[n] = c;
	}

	crc = UPDCRC16(0,crc);
	crc = UPDCRC16(0,crc);

	rxd_crc  = rx(1000) << 8;
	rxd_crc |= rx(1000);

	if (rxd_crc != crc) {

		TRACE("bad crc %4.4x %4.4x\n",rxd_crc,crc);

		return;
	}

	rxd_header_len = 5;
}

void Czmodem::rx_hex_header(int to)

{
	int c;
	int i;
	unsigned short int crc = 0;
	unsigned short int rxd_crc;


	TRACE("rx_hex_header : ");

	for (i=0;i<5;i++) {
		c = rx_hex(to);
		if (c == TIMEOUT) {
			return;
		}
		crc = UPDCRC16(c,crc);

		rxd_header[i] = c;
	}

	crc = UPDCRC16(0,crc);

	crc = UPDCRC16(0,crc);

	/*
	 * receive the crc
	 */

	c = rx_hex(to);

	if (c == TIMEOUT) {
		return;
	}

	rxd_crc = c << 8;

	c = rx_hex(to);

	if (c == TIMEOUT) {
		return;
	}

	rxd_crc |= c;

	if (rxd_crc == crc) {
		rxd_header_len = 5;
	}

	else {
		TRACE("bad crc.\n");
	}


	/*
	 * drop the end of line sequence after a hex header
	 */
	c = rx(to);
	if (c == CR) {
		/*
		 * both are expected with CR
		 */
		c = rx(to);
	}
}

void Czmodem::rx_bin32_header(int to)
{
	int c;
	int n;
	unsigned long crc;
	unsigned long rxd_crc;


	TRACE("rx binary header 32 bits crc\n");


	crc = 0xffffffffL;

	for (n=0;n<5;n++) {
		c = rx(1000);
		if (c == TIMEOUT) {
			return;
		}
		crc = UPDCRC32(c,crc);
		rxd_header[n] = c;
	}

	crc = ~crc;

	rxd_crc  = rx(1000);
	rxd_crc |= rx(1000) << 8;
	rxd_crc |= rx(1000) << 16;
	rxd_crc |= rx(1000) << 24;

	if (rxd_crc != crc) {
		return;
	}

	rxd_header_len = 5;
}

/*
 * receive any style header
 * if the errors flag is set than whenever an invalid header packet is
 * received INVHDR will be returned. otherwise we wait for a good header
 * also; a flag (receive_32_bit_data) will be set to indicate whether data
 * packets following this header will have 16 or 32 bit data attached.
 * variable headers are not implemented.
 */

int
Czmodem::rx_header_raw(int to,int errors)

{
	int c;


	TRACE("rx header : ");

	rxd_header_len = 0;

	do {
		do {
			c = rx_raw(to);
			if (c == TIMEOUT) {
				return c;
			}
		} while (c != ZPAD);

		c = rx_raw(to);
		if (c == TIMEOUT) {
			return c;
		}

		if (c == ZPAD) {
			c = rx_raw(to);
			if (c == TIMEOUT) {
				return c;
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -