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

📄 isomodem_hdlc.c

📁 modem数据通信源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    					EI_hdlc_disconnect();
    				}	
				}		
				else
				{
					EI_hdlc_need_response(frame->pf);	
				}
		 	}
		 	else
		 	{/*Nr错误*/
		 		EG_hdlc_STS.status 	   = EM_HDLC_STATUS_0;
		 		EG_hdlc_STS.frmr_data  = *frame;
				EG_hdlc_STS.frmr_type  = EM_HDLC_FRMR_Z;
                EI_hdlc_transmit_frmr();
            }		
            break; 
         case EM_HDLC_FRAME_I:
            uprintf("receive I! len=%d ns=%d nr=%d vs=%d vr=%d\r\n",len-2,frame->ns,frame->nr,EG_hdlc_STS.vs,EG_hdlc_STS.vr);
         	/*如果主站的发送帧不是等待接收的帧号则通知主战拒绝接收该帧*/
    		if (frame->ns == EG_hdlc_STS.vr) 
    		{
            	/*接收数据*/
            	EI_hdlc_data_indication(buf,len);
            	EG_hdlc_STS.vr = (EG_hdlc_STS.vr + 1) % 8;
            } 
            else 
            {
            	EI_hdlc_send_control(EM_HDLC_SUPER_REJ,frame->pf,EM_HDLC_TYPE_RESPONSE);
                break;
            }
            /*分析主站的应答信息*/
            if ( frame->nr == ( ( EG_hdlc_STS.vs - 1) % 0x07))
		 	{/*前一帧数据接收失败,需要重发*/
		 		if ( EG_modem_STS.hdlc_s.send_flag == EM_HDLC_TRANSMIT_DATA_NOACK)
				{
					if ( EG_hdlc_STS.re_count < EG_hdlc_STS.re_cnt)
    				{
    				    uprintf("RESEND frame!\r\n");
    					EG_hdlc_STS.re_count++;
    					/*因为此时vr的值被修改,因此需要重新进行设置*/
    					EG_hdlc_STS.resend_buf[1] = EG_hdlc_STS.resend_buf[1] & 0x1F;
    					EG_hdlc_STS.resend_buf[1] |= (EG_hdlc_STS.vr & 0x07) << 5;	
    					EI_hdlc_transmit_hdlctov80(EG_hdlc_STS.resend_buf,EG_hdlc_STS.resend_len);
						/*发送数据*/
						EI_WriteUart(EG_modem_STS.v80_sendbuf,EG_modem_STS.v80_sendbuf_len);	
    				}
    				else
    				{
    					EI_hdlc_disconnect();
    				}	
				}		
				else
				{
					EI_hdlc_need_response(frame->pf);	
				}
		 	}
		 	else if (frame->nr == EG_hdlc_STS.vs)
		 	{
		 		if ( EG_modem_STS.hdlc_s.send_flag == EM_HDLC_TRANSMIT_DATA)
				{
					/*因为此时vr的值被修改,因此需要重新进行设置*/
					EG_hdlc_STS.resend_buf[1] = EG_hdlc_STS.resend_buf[1] & 0x1F;
					EG_hdlc_STS.resend_buf[1] |= (EG_hdlc_STS.vr & 0x07) << 5;
					EI_hdlc_transmit_hdlctov80(EG_hdlc_STS.resend_buf,EG_hdlc_STS.resend_len);
					/*发送数据*/
					EI_WriteUart(EG_modem_STS.v80_sendbuf,EG_modem_STS.v80_sendbuf_len);	
					EI_SetHdlc_sendflag(EM_HDLC_TRANSMIT_DATA_NOACK);
					EG_hdlc_STS.vs = (EG_hdlc_STS.vs + 1) % 8;
				}		
				else
				{
					/*允许发送数据*/
					EI_SetHdlc_sendflag(EM_HDLC_TRANSMIT_NODATA);
					EI_hdlc_need_response(frame->pf);	
				}
				EG_hdlc_STS.re_count 	= 0;
		 	}
		 	else
		 	{
		 		EG_hdlc_STS.status 	   = EM_HDLC_STATUS_0;
		 		EG_hdlc_STS.frmr_data  = *frame;
				EG_hdlc_STS.frmr_type  = EM_HDLC_FRMR_Z;
                EI_hdlc_transmit_frmr();
            }
            break;
        case EM_HDLC_FRAME_ILLEGAL:
            uprintf("??? receive ILLEGAL!\r\n");
            EG_hdlc_STS.frmr_data  = *frame;
			EG_hdlc_STS.frmr_type  = EM_HDLC_FRMR_W;
			EG_hdlc_STS.status 	   = EM_HDLC_STATUS_0;
            EI_hdlc_transmit_frmr();
            break;
        case EM_HDLC_COMMAND_UI:
            uprintf("??? receive UI!\r\n");        	
        	break;    
		default:
		    uprintf("??? receive UNKNOWN!\r\n");				
			break;
	}	
}

char EI_hdlc_decode_packet(struct hdlc_frame_info *frame,uchar *buf,unsigned int len)
{
    if(len<2)
        return EM_ERROR;
        
	/*保存控制域信息*/
	frame->addr = buf[0];
	frame->control  = buf[1];
	frame->pf   	= frame->control & EM_HDLC_FRAME_PFON;	
	
	if( (frame->control & EM_HDLC_FRAME_S) == EM_HDLC_FRAME_I)
	{
		frame->type = EM_HDLC_FRAME_I;
		frame->ns   = (frame->control & 0x0E) >> 1;
		frame->nr   = (frame->control & 0xE0) >> 5;
	}
	else if( (frame->control & EM_HDLC_FRAME_U) == EM_HDLC_FRAME_S)
	{
		frame->type = frame->control & 0x0F;
		frame->nr   = (frame->control & 0xE0) >> 5;
	}
	else if ( (frame->control & EM_HDLC_FRAME_U) == EM_HDLC_FRAME_U)
	{
		frame->type = frame->control & 0xEF;
	}
	
	if(frame->type!=EM_HDLC_COMMAND_SNRM)
	{
	    if(frame->addr!=EG_modem_STS.hdlc_s.addr)
	        return EM_ERROR;
	}
	return EM_SUCCESS;	
}

void EI_hdlc_protocol_process(void)
{
	struct hdlc_frame_info frame;
	char buf[1024];
	unsigned int len;
	
	memset(buf,0x00,sizeof(buf));
	len = loop_read(EG_modem_STS.v80_recvbuf,buf,1024);
	//TRACE_CONTENTS(len,buf);
	/*进行数据解码*/
	if ( EI_hdlc_decode_packet(&frame,(uchar *)buf,len) == EM_MODEM_ERROR)
		return;
		
	//TRACE("frame.type = %x\r\nframe.nr = %x\r\nframe.ns = %x\r\nframe.pf = %x\r\nframe->control=%x\r\n",frame.type,frame.nr,frame.ns,frame.pf,frame.control);
	switch(EG_modem_STS.hdlc_s.status)
	{
		case EM_HDLC_STATUS_0:
			EI_hdlc_status0_prcess(&frame,buf,len);
			break;
		case EM_HDLC_STATUS_1:
			EI_hdlc_status1_prcess(&frame,buf,len);
			break;
		default:
			break;												
	}
}

void EI_hdlc_status0_prcess(struct hdlc_frame_info *frame,char *buf,unsigned int len)
{
    switch(frame->type)
	{
		case EM_HDLC_COMMAND_SNRM:/*只支持普通应答模式*/
		    EI_hdlc_recv_snrm(frame);			
    		break;
    	default:
    		if ( EG_hdlc_STS.frmr_type != 0)
    		{
    			if ( EG_hdlc_STS.re_count < EG_hdlc_STS.re_cnt)
    			{
    				EG_hdlc_STS.re_count++;	
    				EI_hdlc_transmit_frmr();
    			}
    			else
    			{
    				EI_hdlc_disconnect();	
    			}	
    		}
			else if ( frame->pf )
			{
				EI_hdlc_send_control(EM_HDLC_RESPONSE_DM, frame->pf,EM_HDLC_TYPE_RESPONSE);			
			}	
			break;
	}	
}

void EI_hdlc_transmit_frmr(void)
{
    unsigned char  buf[256];
	unsigned char  *p=buf;
	
	memset(buf,0x00,sizeof(buf));
	*p++ = EG_hdlc_STS.addr;					/*地址信息*/
	*p++ = EM_HDLC_RESPONSE_FRMR;			/*控制域信息*/
	*p++ = EG_hdlc_STS.frmr_data.control;	/*对应的控制命令*/	
	*p   = (EG_hdlc_STS.vs & 0x07) << 1;	/*Ns/CR/Nr*/
	*p  |= (EG_hdlc_STS.vr & 0x07) << 5;   
	p++;
	*p++ = EG_hdlc_STS.frmr_type;			/*错误类型*/
	
	EI_hdlc_transmit_hdlctov80(buf , 5 );
	/*调用串口命令发送*/
	EI_WriteUart(EG_modem_STS.v80_sendbuf,EG_modem_STS.v80_sendbuf_len);	
}

unsigned int EI_hdlc_data_indication(char *buf,unsigned int len)
{
    loop_write(EG_modem_STS.hdlc_recvbuf,buf+2,len-2);
    //TRACE_CONTENTS(len-2,buf+2);
    return EM_SUCCESS;
}

void EI_hdlc_disconnect(void)
{
    EG_modem_STS.hdlc_s.status = EM_HDLC_STATUS_2;
    EI_ModemOffline();
}

/*发送信息帧,在数据前增加地址和控制域信息然后交给v80函数完成数据格式转换和发送*/
void EI_hdlc_send_iframe(unsigned char *buf , unsigned int len)
{
	unsigned char *p;
	
	p = EG_hdlc_STS.resend_buf;
	*p++ = EG_hdlc_STS.addr;					/*地址信息*/
	*p   = EM_HDLC_FRAME_I;					/*控制域信息*/
	*p  |= EM_HDLC_FRAME_PFON;
	*p  |= (EG_hdlc_STS.vr & 0x07) << 5;
	*p  |= (EG_hdlc_STS.vs & 0x07) << 1;
	p++;
	memcpy(p , buf , len);
	EG_hdlc_STS.resend_len = len + 2;
}

void EI_hdlc_recv_snrm(struct hdlc_frame_info *frame)
{
    if ( frame->pf)
	{
	    {
	        UNSIGNED time_cur;
            time_cur = NU_Retrieve_Clock(); 
	        uprintf("SNRM time %d ms\r\n",(time_cur-EG_modem_STS.dial_start)*10);
	    }
		EG_hdlc_STS.status 		= EM_HDLC_STATUS_1;
		EG_hdlc_STS.vs			= 0;
		EG_hdlc_STS.vr			= 0;
		EG_hdlc_STS.frmr_type   = 0;
		EG_hdlc_STS.re_count 	= 0;
		if(frame->addr!=0xff&&frame->addr!=0x00)
            EG_modem_STS.hdlc_s.addr = frame->addr;
		/*修改modem状态为连接状态*/
		EI_SetModemOnline(EM_ONLINE_DATA);    			
		/*允许发送数据*/
		EI_SetHdlc_sendflag(EM_HDLC_TRANSMIT_NODATA);
		EI_hdlc_send_control(EM_HDLC_RESPONSE_UA,frame->pf,EM_HDLC_TYPE_RESPONSE);
		EI_vShow(EM_icon_SHOW,EM_icon_ONLINE);
	}	
}



⌨️ 快捷键说明

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