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

📄 bsc_states.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	so = bsc->bscp_socket;	crcloc();	bmtmp = mtod(so->so_snd.sb_mb, struct bsc_data *);	if (bmtmp->data[0] == DLE)		d_flag = 1;	else		d_flag = 0;	m_head = m_getclr(M_DONTWAIT, MT_DATA);	if ( m_head == (struct mbuf *)NULL ){		return(ENOBUFS);	}	m_head->m_len = MLEN;	m_head->m_off = MMAXOFF - m_head->m_len; 	bmtmp = mtod(m_head, struct bsc_data *);	if (d_flag){	/* transparent */		bmtmp->data[i++] = DLE;		bmtmp->data[i++] = STX;		m_head->m_len = (unsigned)i;		j = 1;	}else{		/* nontransparent */		bmtmp->data[i++] = STX;		m_head->m_len = (unsigned)i;		j = 0;	}	m_head->m_next = m_copy(so->so_snd.sb_mb, j, M_COPYALL);	m = m_head->m_next;	bm = mtod(m, struct bsc_data *);	len = m->m_len;	j = 0;loop:	for ( j; j < len; j++ ){ 		c = bm->data[j];		if ((c==ETX) && (bm->data[j-1]!=DLE) && (m->m_next==NULL)){			state = SENDBLKLAST;				break;		}		/* We've seen the ETB indicator in the buffer so escape. */		if ((c== ETB) && (bm->data[j-1]!=DLE))			break;	 	if (( c == DLE) || (c == SYNC))			continue;		crc16(c); 		if (( c == ITB) && (d_flag == 0))			break;	}	if ( c == ITB ){		j++;		m->m_len = j;		m_new = m_getclr(M_DONTWAIT, MT_DATA);			if ( m_new == (struct mbuf *)NULL )			return(ENOBUFS);		m_new->m_len = MLEN;		m_new->m_off = MMAXOFF - m_new->m_len; 		bmtmp = mtod(m_new, struct bsc_data *);		bmtmp->data[0] = crc[0];		bmtmp->data[1] = crc[1];		crcloc();		/* if (d_flag){		 *	bmtmp->data[2] = SYN;		 *	bmtmp->data[3] = SYN;		 *	bmtmp->data[4] = DLE;		 *	crc16(c);		 *	bmtmp->data[5] = STX;		 *	crc16(c);		 *	i = 6;		 * }else{		 *	bmtmp->data[2] = SYN;		 *	bmtmp->data[3] = SYN;		 *	i = 4;	     		 * }		 */		i = 2;		for (j; j<len; j++)			bmtmp->data[i++] = bm->data[j];		m_new->m_len = i;		if (m->m_next == NULL){			m->m_next = m_new;			m_new->m_next = NULL;			m = m->m_next;			len = m->m_len;			bm = mtod(m, struct bsc_data *);			j = 2;			goto loop;		}		if (m->m_next != NULL){			mp = m->m_next;			m->m_next = m_new;			m_new->m_next = mp;			m = m->m_next;			len = m->m_len;			bm = mtod(m, struct bsc_data *);			j = 2;			goto loop;		}	}	if ( (m->m_next != NULL) ){		mp = m->m_next;		len = mp->m_len;		bm = mtod(mp, struct bsc_data *);		m = mp;			if ( c != ITB)			j = 0;		goto loop;	}	/* Delete the marker in the buffer indicating EOF or EOB */	m->m_len = m->m_len - 1; 	m->m_next = m_getclr(M_DONTWAIT, MT_DATA);	if ( m->m_next == (struct mbuf *)NULL ){		return(ENOBUFS);	}	m->m_next->m_len = MLEN;	m->m_next->m_off = MMAXOFF - m->m_next->m_len; 	bmtmp = mtod(m->m_next, struct bsc_data *);	i = 0;		if (state == SENDBLKLAST){		if (d_flag){			bmtmp->data[i++] = DLE;			bmtmp->data[i++] = ETX;			crc16(ETX);		}else{			bmtmp->data[i++] = ETX;			crc16(ETX);		}	}else{		if (d_flag){			bmtmp->data[i++] = DLE;			bmtmp->data[i++] = ETB;			crc16(ETB);		}else{			bmtmp->data[i++] = ETB;			crc16(ETB);		}	}	bmtmp->data[i++] = crc[0];	bmtmp->data[i++] = crc[1];	m->m_next->m_len = i; 	CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);	error = (*ifp->if_output)(ifp, m_head, (struct sockaddr *)dst);	RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);	m_freem(m_head);	return(error);}	/* * Xmtctl is a generic routine that generates and transmits a message * containing one or two control characters plus sync and ending pad * characters.  Use this routine to transmit, for example, an EOT message. */xmtctl(byte1, byte2, ifp)	char byte1, byte2;	register struct ifnet *ifp;{	struct mbuf *m_tmp;	/* Temp mbuf for control characters */	int i = 0;	struct sockaddr_bsc *dst;	int	error;	struct bsc_data *bdat;	int saveaffinity;	m_tmp = m_getclr(M_DONTWAIT, MT_DATA);	if ( m_tmp == (struct mbuf *)NULL ){		return(ENOBUFS);	}	m_tmp->m_len = MLEN;	m_tmp->m_off = MMAXOFF - m_tmp->m_len; 	bdat = mtod(m_tmp, struct bsc_data *);	bdat->data[i++] = byte1;	if ( byte2 != NULL )		bdat->data[i++] = byte2;	bdat->data[i++] = PAD; 	bdat->data[i++] = PAD;	m_tmp->m_len = (unsigned)i;	CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);	error = (*ifp->if_output)(ifp, m_tmp, (struct sockaddr *)dst);	RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);	m_free(m_tmp);	return(error);}/*  * Rec() is a key routine on the receive side.  Bscrcv tells what the data is * and rec processes that data.  For control messages coming in, rec * sees if the message is okay and returns either success or failure * to the case statements in bsc_input.  For data coming in, rec() calls * routines to get a clean mbuf (getrbuf) to write only the * data to and then rec() calls a routine to 'put()' the data to the * clean mbuf.   */rec(){	crcloc();	dat_dvr = mtod(m_dvr, struct bsc_data *);	rsom(SYNC);	bscrcv();	switch(byte){	case EOT:		return(EOT);		break;	case ENQ:		return(ENQ);		break;	case NAK:		return(R_NAK);		break;	case STX:			getrbuf();			byte = rcvdat();			compress();				while ((byte != ETB) && (byte != ETX)){				if (flag == 1){					break;				}				if((byte&0x05) == 0x05){					punch = 1;					put();				}else{					punch = 0;					put();				}				/* if(byte == 0){				 *	break;				 * }				 */				byte = rcvdat();				compress();					while ((byte != ETB) && (byte != ETX)){					if (flag == 1){						break;					}					if ( byte == IUS){						rcvcrc(0);						if(crc[0] != 0){							return(R_ERBLK);						}						rcvcrc(1);						if(crc[1] != 0){							return(R_ERBLK);						}						crcloc();					}					/* if(byte == 0){ 					 *	break;					 * }					 */					put();					byte = rcvdat();					compress();				} 		} 		rcvcrc(0);		rcvcrc(1);		bscrcv();		if(crc[0] != 0){			return(R_ERBLK);		 }		if(crc[1] != 0){			return(R_ERBLK);		}		return(R_OKBLK);		break;	case DLE:		bscrcv();		switch(byte){		case X70:			if (ackseq != X70)				return(R_SEQ);			/* If timers need to kick in while state is SENDACK0			 * the following if statement will prevent the ackseq			 * from being bumped.  Without this if statement you			 * would always be out of sequence.			 */			if ( state == SENDACK0) 				return(R_ACK);			ackseq = 0x61;			return(R_ACK);			/* else			 *	return(R_ERROR);			 */			break;		case 0x61:				if (ackseq != 0x61)				return(R_SEQ);			ackseq = X70;			return(R_ACK);			/* else			 *	return(R_ERROR);			 */			break;		case 0X7c:				/* bsc_pulloutofband(bsc); */			return(R_RVI);			break;		case ENQ: 			/* bsc_pulloutofband(bsc); */			return(ENQ);			break;		case STX:			getrbuf();			byte = rcvdat();			compress();				while ((byte != ETB) && (byte != ETX)){				if (flag == 1){					break;				}				if((byte&0x05) == 0x05){					punch = 1;					put();				}else{					punch = 0;					put();				}				/* if(byte == 0){				 *	break;				 * }				 */				byte = rcvdat();				compress();					while ((byte != ETB) && (byte != ETX)){					if (flag == 1){						break;					}					if ( byte == IUS){						rcvcrc(0);						if(crc[0] != 0){							return(R_ERBLK);						}						rcvcrc(1);						if(crc[1] != 0){							return(R_ERBLK);						}						crcloc();					}					/* if(byte == 0){ 					 *	break;					 * }					 */					put();					byte = rcvdat();					compress();					} 			} 			rcvcrc(0);			rcvcrc(1);			bscrcv();			if(crc[0] != 0){				return(R_ERBLK);			 }			if(crc[1] != 0){				return(R_ERBLK);			}			return(R_OKBLK);			break;		default:			return(R_ERROR);		}		break;	default:		return(R_ERROR);	}}/* Do all compression interpretation here except for HT.  HT in a format * record is handled by the daemon. */compress(){	char byte_save;loopss:	if (byte==ESC){		byte = rcvdat();		switch(byte){		case 0x61:  /* / */			byte = LF;			put();			break;		case 0xe2: /* S */			byte = LF;			put();			byte = LF;			put();			break;		case 0xe3: /* T */			byte = 0x40;			put();			byte = 0x40;			put();			byte = 0x40;			put();			break;		case 0xc1: /* A */			byte = 0x0c;			put();			break;		default:			byte_save = byte;			byte = ESC;			put();			byte = byte_save;			put();			break;		} 	byte = rcvdat();	if (byte == ESC)		goto loopss;	} /* if */	else 		return;}rcvcrc(i)int i;{	bscrcv();	crc[i] = crc[i] - (unsigned)byte;	return(0);}rcvdat(){	for (;;){		bscrcv();		if(byte != DLE) {			if(byte == SYNC)				continue;			crc16(byte);			return(byte);		} else {			bscrcv();			if(byte == SYNC)				continue;			crc16(byte);			return(byte);		}	} }xmtack(bsc)	struct bscpcb *bsc;{	struct ifnet *ifp;	struct sockaddr_bsc *sin = &bsc->bscp_laddr;	struct mbuf *m_tmp;	struct sockaddr_bsc *dst;	struct bsc_data *bdat;	int error;	int i = 0;	int saveaffinity;	ifp = (struct ifnet *)bsc_ifpfinder( sin );	if (ifp == 0)		return(EADDRNOTAVAIL);	m_tmp = m_getclr(M_DONTWAIT, MT_DATA);	if ( m_tmp == (struct mbuf *)NULL ){		return(ENOBUFS);	}	m_tmp->m_len = MLEN;	m_tmp->m_off = MMAXOFF - m_tmp->m_len;	bdat = mtod(m_tmp, struct bsc_data *);	bdat->data[i++] = DLE;	bdat->data[i++] = ackseq; 	bdat->data[i++] = PAD;	m_tmp->m_len = (unsigned)i;	CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);	error = (*ifp->if_output)(ifp, m_tmp, (struct sockaddr *)dst);	RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);	m_free(m_tmp); 	return(error);}crcloc(  ){	crc[0]=0;	crc[1]=0;  }/* * Strip off the leading rec_ch (sync) characters from the mbuf you get * from the driver. */rsom( rec_ch )	char rec_ch;{	int i = 0;	data_loc_dvr = 0;	while ( dat_dvr->data[i] == rec_ch ){		i++;		}	data_loc_dvr = i;	flag = 0;	return (0);}/* * Get a character from the mbuf you get from the driver. */bscrcv(){	if ( m_dvr->m_len == data_loc_dvr){		if (m_dvr->m_next == NULL){			if ( byte == ETX)				flag = 1;			if (byte == ETB)				flag = 1;			return(0);		}		m_dvr = m_dvr->m_next;		data_loc_dvr = 0;		dat_dvr = mtod(m_dvr, struct bsc_data *);	}	byte = dat_dvr->data[data_loc_dvr++];	flag = 0;	return(0);}/* * Get an mbuf that will be used only for the purpose of collecting incoming * data that has been stripped of bisync control characters. */getrbuf(){	int i;	m_up = m_get(M_DONTWAIT, MT_DATA);	if ( m_up == (struct mbuf *)NULL ){		return(ENOBUFS);	}	m_up->m_len = MLEN;	m_up->m_off = MMAXOFF - m_up->m_len;	bsc_mbuf_len = m_up->m_len;	data_loc_up = 0;	dat_up = mtod(m_up, struct bsc_data *);	/* Before storing data, be sure entire buffer is clean */	for (i=0; i<bsc_mbuf_len; i++)		dat_up->data[i] = 0x40;	m_up_ptr = m_up;		/* save a pointer to the head of the					 * receive queue.  The pointer you save					 * is what gets passed up to the socket					 * receive queue.                    */	return(0);}/* * Now write only data characters to m_up.  Put data characters only from m_dvr * the mbuf you get from the driver, into m_up. You may want to do some buffer * size checking in here. */put(){	struct mbuf *m_temp;	int i;	if (bsc_mbuf_len == data_loc_up){		m_temp = m_get(M_DONTWAIT, MT_DATA);		if ( m_temp == (struct mbuf *)NULL )			return(ENOBUFS);		m_temp->m_len = MLEN;		m_temp->m_off = MMAXOFF - m_temp->m_len;		data_loc_up = 0;		bsc_mbuf_len = m_temp->m_len;		/* Now link m_temp into the m_up chain and reset 		 * m_up_ptr to point to the new mbuf.	      */		m_up_ptr->m_next = m_temp;		m_up_ptr = m_up_ptr->m_next;		dat_up = mtod(m_up_ptr, struct bsc_data *);		/* Before storing data, be sure entire buffer is clean  */		for (i=0; i<bsc_mbuf_len; i++)			dat_up->data[i] = 0x40;	}	dat_up->data[data_loc_up++] = byte;	return(0);}/* crc16 takes 1 character as input and updates the CRC[] for the whole   message */crc16(crc_ch)	char crc_ch;{	unsigned short tmp,result;	result= (crc[1] & 0x00ff) << 8; 	/* put crc[] into result, */	result |= (crc[0] & 0x00ff);		/* ie  result=crc[0-1] */	tmp= (0xffff & result) ^ (0xff & crc_ch); /* next 3 - calc. new crc */	tmp= (0xfff & (tmp >> 4)) ^ crctable[tmp & 0xf];	result= (0xfff & (tmp >>4)) ^ crctable[tmp & 0xf];	crc[0]=(result & 0x00ff);		/* put new crc in crc[] */        crc[1]=(result & 0xff00) >> 8;}/* * Pull out of band byte out of a segment. */bsc_pulloutofband(bsc)	struct bscpcb *bsc;{	struct socket *so;	register struct mbuf *m;	so = bsc->bscp_socket;	bsc->b_iobc = byte;	so->so_oobmark = so->so_rcv.sb_cc + 1;}bscintr(){/*  * This is where the driver input routine returns. * It calls the mother routine, bsc_states to respond to the incoming  * message. */	register struct mbuf *m;	int s;	struct sockaddr_bsc *sin;	struct ifnet *ifp;	int saveaffinity;	saveaffinity = switch_affinity(boot_cpu_mask);	/*	 * Get datagram off input queue.	 */	s = splimp();	IF_DEQUEUE(&bscintrq, m);	splx(s);	if (ifp)		sin = (struct sockaddr_bsc *)&ifp->if_addr;	(*bscnetsw[1].pr_input)(m, sin);}

⌨️ 快捷键说明

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