rxhdlc

Capsim Block Documentation

Short Description

Process an HDLC frame and generate ACK and NACK. Use only in ARQ simulation

Top
Input Connections
Port Type Name
0 float x
Top
Output Connections
Port Type Name
0 byteVector_t y
1 int rack
Top
Parameters
Num Description Type Name Default Value
0 Number of bits per frame (Info Only) int numberOfBits 128
1 Debug:1=true,0=false int debugFlag 0
Top
States
Num Type Name Initial Value Description
0 int byteCount 0
1 int numberBytes 0
2 UINT8* vect_P
3 UINT16 buildByte 0
4 int buildByteBits 0
5 UINT16 acc 0
6 int count 0
7 UINT16 shreg 0
8 UINT16 fcsshreg 0
9 int bitCount 0
10 int endFrame 0
11 int fcs 0
12 int frameCount 0
13 int errorCount 0
14 int correctCount 0
15 int contFlag
16 int done 0
17 int removeZero 0
18 int first 1
19 int first2 1
20 int begFrame 0
21 int fcsReg 0
22 int fcsbit
23 int startFCS 0
24 int bit 0
25 int rxFrameFlag 0
26 int rxBitFlag 0
27 int frameBits 0
28 int nr 0
29 int errorFlag 0
30 FILE* debug_F
31 int totalBitsInput 0
Top

Declarations


 

UINT16	stuffCheck;
UINT16	flagCheck;
unsigned short	carry;
int	i;
int	numberOfSamples;
byteVector_t	codedBlock;
int	ns;



Top

Initialization Code



 

/*
 * account for address and control and FCS 
 * we will ignore on output
 */
numberBytes=numberOfBits/8+1+1+1+2;
acc=0;
if(debugFlag) {
	debug_F=fopen("rxhdlc.dbg","w");
	if(debug_F == NULL) return(2);
}




Top

Main Code



 


if(first2) {

	IT_OUT(1);
	nr=0;
	rxFrameFlag=1;
	rack(0) = 0x80 | nr;
}
first2=0;

while(IT_IN(0)) {
	rxBitFlag=1;
	/*
	 * output the bit check if address+cntrl+info+FCS
 	 * also ignore if removing a zero
	 */
	if(!removeZero && begFrame) {
		/*
		 */ 
		fcsshreg |= bit;
		if(startFCS) {
			fcsbit = (0x100 & fcsshreg) ? 1:0;
			{
				carry=(acc&0x8000) ? 1:0;
				acc <<= 1;
				acc ^= ((fcsbit ^ carry) ? GENERATOR_POLY:0);
			}
		}
#if 1
if(debugFlag)
	fprintf(debug_F,"shreg=%4x fcsshreg=%4x fcsbit=%d bit=%d acc=%4x\n",shreg,fcsshreg,fcsbit,bit,acc);
#endif
		fcsshreg <<= 1;
		buildByte |= bit;
		buildByteBits++;
		if(buildByteBits == 8) {
			vect_P[byteCount]=buildByte;
			buildByte=0;
			buildByteBits=0;
			byteCount++;
		}
		buildByte <<= 1;
		frameBits++;
		/*
		 * check if received bits  exceeds payload size plus address
		 * control,and FCS
		 */
		if(frameBits > numberOfBits +8+8+16+8) {
			/*
			 * If exceeds then we have an error condition.
			 * Possiblility is that end flag corrupted.
			 * In this case we request retransmission as if error
			 * occured.
			 * We must also flush out input buffer.
			 */
			frameBits=0;
			endFrame=1;
			first=1;
			begFrame=0;
			shreg=0;
			fcsshreg=0;
			acc=0;
			startFCS=0;
			bit=0;
			count=0;

			/*
			 * get ns from transmitted frame
			 */
			ns=vect_P[1];
			ns = ns >> 3;
			ns = ns & 0x07;
			
			IT_OUT(1);
			rack(0) = 0x90 | nr;
			rxFrameFlag=1;
			if(debugFlag)
				fprintf(debug_F,"Bad End Flag Received NS=%d NR %d\n",ns,nr);
			/*
			 * Flush input port
			 */
			while(IT_IN(0));
			break;
		}
	}
	else
		removeZero=0;


     	/*
      	 * collect the bits
       	 */
       	bit=(int)(x(0)+0.001);
	totalBitsInput++;

	shreg |= bit;
	stuffCheck=shreg & 0x3f;
	if(stuffCheck == 0x3e ) {	
		if(debugFlag)
			fprintf(debug_F,"Unstuff zero condition\n");
		removeZero=1;
	}
	stuffCheck=shreg & 0x7f;
	if(stuffCheck == 0x7f ) {	
		if(debugFlag)
			fprintf(debug_F,"Abort condition\n");

		/*
		 * reset and start over. 
		 * reject frame and request retransmission
		 */
			frameBits=0;
			endFrame=1;
			first=1;
			begFrame=0;
			shreg=0;
			fcsshreg=0;
			acc=0;
			startFCS=0;
			bit=0;
			count=0;

			/*
			 * get ns from transmitted frame
			 */
			ns=vect_P[1];
			ns = ns >> 3;
			ns = ns & 0x07;
			
			IT_OUT(1);
			rack(0) = 0x90 | nr;
			rxFrameFlag=1;
			if(debugFlag)
				fprintf(debug_F,"Abort Received NS=%d NR %d\n",ns,nr);
			/*
			 * Flush input port
			 */
			while(IT_IN(0));
			break;
	}
	/*
	 * Frame Check Sequence
	 */
	if(startFCS) {
	}
	/*
	 * check if FLAG (beginning or end)
	 */
	flagCheck=shreg & 0xff;
	if(flagCheck == 0x7e) {
		/*
		 * found a flag
		 */
		removeZero=0;
		if(first) {
			/*
			 * beginning of frame flag
			 */
			acc=0;
			first=0;
			begFrame=1;
			if(debugFlag)
				fprintf(debug_F,"Start Flag\n");
			frameCount++;
			bitCount=0;
			/*
			 * beginning of frame
			 * allocate vector of bytes 
			 */
			
			vect_P=(char*)calloc(numberBytes,sizeof(char));
			byteCount=0;
			buildByte=0;
			buildByteBits=0;
#if 1
			/*
			 * a trick to not include last bit of flag in
			 * output vector
			 */
			removeZero=1;
#endif
		}
		else {
			/*
			 * end of frame flag
		 	 */
			if(debugFlag)
				fprintf(debug_F,"END Flag\n");
			if(shreg == 0x7e7e) {
				/*
				 * Two consecutive flags encountered.
				 * Set state to beginning
				 * flag 
				 */
				count=0;
				fcsshreg =  0;
				acc=0;
				shreg=0x7e;
				first=0;
				begFrame=1;
				byteCount=0;
				buildByte=0;
				buildByteBits=0;
				removeZero=1;
				frameBits=0;

			} else {
			frameBits=0;
			fcsshreg =  0;
			for(i=0; i<2; i++) {
				/*
				 * Flush FCS
				 */
				fcsshreg <<=1;
				fcsbit = (0x100 & fcsshreg) ? 1:0;
				{
					carry=0;
					acc <<= 1;
					acc ^= ((fcsbit ^ carry) ? GENERATOR_POLY:0);
				}
#if 0
fprintf(stderr,"Flushing fcsshreg=%4x acc=%4x \n",fcsshreg,acc);
#endif
			}
			errorFlag=0;
			if( acc) { 
				errorFlag=1;
				if(debugFlag)
				   fprintf(debug_F,"Frame Error\n");
				errorCount++;

			}  
			else
				correctCount++;
			endFrame=1;
			first=1;
			begFrame=0;
			shreg=0;
			fcsshreg=0;
			acc=0;
			startFCS=0;
			bit=0;
			count=0;

			/*
			 * get ns from transmitted frame
			 */
			ns=vect_P[1];
			ns = ns >> 3;
			ns = ns & 0x07;
			
    			if(!errorFlag) {
			   if(IT_OUT(0) ){ KrnOverflow("rxhdlc",0);return(99);}
			   codedBlock.vector_P=&vect_P[2];
			   codedBlock.length=byteCount-2-2;
			   if(codedBlock.length > numberBytes) {
				fprintf(debug_F,"rxhdlc: bad frame length=%d\n",
					codedBlock.length);
				codedBlock.length=numberBytes;
			   }
    			   y(0) = codedBlock; 
			}
		
			IT_OUT(1);
			if(errorFlag) {
				rxFrameFlag=1;
				rack(0) = 0x90 | nr;
			} else {
				nr++;
				nr %= 8;
				rxFrameFlag=1;
				rack(0) = 0x80 | nr;

			}
			if(debugFlag)
				fprintf(debug_F,"Received NS=%d NR %d\n",ns,nr);
			} /*end double flag */

			
		}
	} 
	shreg <<= 1;
	if(begFrame ) {
		/*
		 * start FCS after first FLAG
		 * delay also allows time to check for end of frame flag
		 * so that it is not used in computation of FCS
		 */
		if(count == 10) { 
			startFCS=1;
		
			if(debugFlag)
				   fprintf(debug_F,"Begin startFCS\n");
		}
		count++;
	} 
	
}
if(!rxFrameFlag && rxBitFlag) {
	/*
	 * Bad news all input bits exhausted but no frame encountered.
	 * This could be due to the fact that a flag got corrupted
	 * In this case request retransmission and reset every thing
	 */
			frameBits=0;
			endFrame=1;
			first=1;
			begFrame=0;
			shreg=0;
			fcsshreg=0;
			acc=0;
			startFCS=0;
			bit=0;
			count=0;
			/*
			 * reject and request retransmission
			 */
			IT_OUT(1);
			rack(0) = 0x90 | nr;
			rxFrameFlag=1;
			if(debugFlag)
				fprintf(debug_F,"Damaged Frame:NR %d\n",nr);

}
rxFrameFlag=0;
rxBitFlag=0;

return(0);




Top

Wrapup Code



 

	fprintf(stderr,"RxHDLC: number of received frames=%d\n",frameCount);
	fprintf(stderr,"RxHDLC: number of bits received %d\n",totalBitsInput);
	fprintf(stderr,"RxHDLC: number of errors =%d\n",errorCount);
	fprintf(stderr,"RxHDLC: number of correct frames =%d\n",correctCount);
	if(debugFlag)
		fclose(debug_F);




Top

License



/*  Capsim (r) Text Mode Kernel (TMK) Star Library (Blocks)
    Copyright (C) 1989-2017  Silicon DSP Corporation

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    http://www.silicondsp.com
    Silicon DSP  Corporation
    Las Vegas, Nevada
*/


Top

Description



 

/*
 * 
 * Written by: Sasan H. Ardalan
 *(c) Copyright 1993-2000 XCAD Corporation, Raleigh, NC All Rights Reserved
 * Date: November 30, 1993
 */
 /*
  * IMPORTANT:
  *  This star assumes that an HDLC frame worth of bits is on its input buffer.
  *  To guarantee this, make sure that the input is comming from a galaxy
  *  This way the galaxy (data pump) will consume all of its input bits
  * from the transmitter, and output them on its output terminal before
  * returning control to the connected block ( rxhdlc in this case).
  * If you do not do this, there is no gaurantee that a whole Frame (damaged
  * or not) is at the input buffer. It could arrive in pieces. 
  * The reason for requiring this, is so that rxhdlc can asses whether a 
  * damaged flag exists or other conditions.
  * If this condition is not to be detected then the code must be modified.
  * A more elaborate scheme must be devised to detect damaged frame flags.
  * See main_code at the if(rxframeFlag) statement. If input has been
  * exausted and this flag has not been set ( either correct
  * an FCS error or abort) then flags were damaged.
  */
/*

rxhdlc


Process an HDLC frame and generate ACK and NACK. Use only in ARQ simulation
  * IMPORTANT:
  *  This star assumes that an HDLC frame worth of bits is on its input buffer.
  *  To guarantee this, make sure that the input is comming from a galaxy
  *  This way the galaxy (data pump) will consume all of its input bits
  * from the transmitter, and output them on its output terminal before
  * returning control to the connected block ( rxhdlc in this case).
  * If you do not do this, there is no gaurantee that a whole Frame (damaged
  * or not) is at the input buffer. It could arrive in pieces. 
  * The reason for requiring this, is so that rxhdlc can asses whether a 
  * damaged flag exists or other conditions.
  * If this condition is not to be detected then the code must be modified.
  * A more elaborate scheme must be devised to detect damaged frame flags.
  * See main_code at the if(rxframeFlag) statement. If input has been
  * exausted and this flag has not been set ( either correct
  * an FCS error or abort) then flags were damaged.


Written by: Sasan H. Ardalan
Date: November 30, 1993

*/