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

📄 isomodem_hdlc.c

📁 modem数据通信源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "44b.H"
#include "EPT32.H"
#include "Nucleus.H"
#include "string.h"
#include "switch.h"    

#include "interdrive.h"
#include "common_exp.h"
#include "ISOModem_DRV.h"
#include "Modem_IODrv.h"
#include "exports.h"
#include "IODrive.h"
#include "Regist.h"

#include "ISOModem.h"

extern EM_modem_STS    EG_modem_STS;

/*地址信息宏定义*/
#define EM_HDLC_ADDR				0x30	/*有效的地址信息*/

/*帧类型宏定义*/
#define EM_HDLC_FRAME_I			0x00	/*信息帧*/
#define EM_HDLC_FRAME_S			0x01	/*命令帧*/
#define EM_HDLC_FRAME_U			0x03	/*无编号帧*/

/*poll/final位宏定义,表示命令帧/应答帧*/
#define EM_HDLC_FRAME_PFON		0x10	/*poll/final对应的位*/
#define EM_HDLC_FRAME_PFOFF		0x00	/*poll/final对应的位*/

/*HDLC控制帧命令/应答格式宏定义*/
#define EM_HDLC_SUPER_RR			0x01	/*接收就绪*/
#define EM_HDLC_SUPER_RNR			0x05	/*接收未准备好*/
#define EM_HDLC_SUPER_REJ			0x09	/*拒绝*/
#define EM_HDLC_SUPER_SREJ			0x0D	/*选择性拒绝*/

/*HDLC无符号帧命令格式宏定义*/
#define EM_HDLC_COMMAND_SNRM		0x83	/*设置基本同步应答模式*/
#define EM_HDLC_COMMAND_SARM		0x0F	/*设置异步应答模式,不支持*/
#define EM_HDLC_COMMAND_SABM		0x2F	/*设置异步双向模式,不支持*/
#define EM_HDLC_COMMAND_DISC		0x43	/*断开连接请求*/
#define EM_HDLC_COMMAND_SNRME	0xCF	/*设置扩展同步应答模式,不支持*/
#define EM_HDLC_COMMAND_SARME	0x4F	/*设置扩展异步应答模式,不支持*/
#define EM_HDLC_COMMAND_SABME	0x6F	/*设置扩展异步双向模式,不支持*/
#define EM_HDLC_COMMAND_SIM		0x07	/*设置初始模式*/
#define EM_HDLC_COMMAND_UP		0x23	/*无编号帧请求*/
#define EM_HDLC_COMMAND_UI		0x03	/*无编号帧信息*/
#define EM_HDLC_COMMAND_XID		0xAF	/*交换ID*/
#define EM_HDLC_COMMAND_RSET		0x8F	/*复位*/
#define EM_HDLC_COMMAND_TEST		0xE3	/*测试*/
#define EM_HDLC_COMMAND_SM		0xC3	/*设置模式*/
#define EM_HDLC_COMMAND_UIH		0xEF	/*带头校验的无编号信息帧*/

/*HDLC无符号帧应答格式宏定义*/
#define EM_HDLC_RESPONSE_UA		0x63	/*无编号帧应答*/
#define EM_HDLC_RESPONSE_FRMR		0x87	/*帧拒绝应答*/
#define EM_HDLC_RESPONSE_DM		0x0F	/*未连接状态*/
#define EM_HDLC_RESPONSE_RD		0x43	/*请求断开应答*/
#define EM_HDLC_RESPONSE_RIM		0x07	/*请求回到初始化模式应答*/
#define EM_HDLC_RESPONSE_UI		0x03	/*无编号信息应答*/
#define EM_HDLC_RESPONSE_XID		0xAF	/*交换ID应答*/
#define EM_HDLC_RESPONSE_TEST		0xE3	/*测试应答*/
#define EM_HDLC_RESPONSE_UIH		0xEF	/*带头校验的无编号信息应答*/

/*帧命令应答格式宏定义*/
#define EM_HDLC_TYPE_RESPONSE		0x00
#define EM_HDLC_TYPE_COMMAND		0x01

/*HDLC链路连接状态宏定义*/
#define EM_HDLC_STATUS_0			0x00	/*未连接状态*/	
#define EM_HDLC_STATUS_1			0x01	/*数据传输状态,连接状态*/
#define EM_HDLC_STATUS_2			0x02	/*断线状态*/	

#define EM_HDLC_FRMR_W    			0x01    /* Control field invalid    */
#define EM_HDLC_FRMR_X    			0x02    /* I field invalid      */
#define EM_HDLC_FRMR_Y    			0x04    /* I field too long     */
#define EM_HDLC_FRMR_Z    			0x08    /* Invalid N(R)         */

#define EM_HDLC_FRAME_ILLEGAL		0x100	/*不存在的帧格式*/

#define EG_hdlc_STS EG_modem_STS.hdlc_s

char EI_hdlc_decode_packet(struct hdlc_frame_info *frame,uchar *buf,unsigned int len);
void EI_hdlc_status0_prcess(struct hdlc_frame_info *frame,char *buf,unsigned int len);
void EI_hdlc_status1_prcess(struct hdlc_frame_info *frame,char *buf,unsigned int len);
void EI_hdlc_need_response(unsigned char pf);
void EI_hdlc_send_control( unsigned char frame_type , unsigned char poll_bit , unsigned char type);
void EI_hdlc_transmit_frmr(void);
unsigned int EI_hdlc_data_indication(char *buf,unsigned int len);
void EI_hdlc_disconnect(void);
void EI_hdlc_recv_snrm(struct hdlc_frame_info *frame);

void EI_SetHdlc_sendflag(uchar status)
{
    EG_modem_STS.hdlc_s.send_flag = status;
    /*switch(status)
    {
        case EM_HDLC_TRANSMIT_NODATA:
            uprintf("HDLC: set send buf to NODATA\r\n");
            break;
        case EM_HDLC_TRANSMIT_DATA:
            uprintf("HDLC: set send buf to DATA\r\n");
            break;
        case EM_HDLC_TRANSMIT_DATA_NOACK:
            uprintf("HDLC: set send buf to DATA NOACK\r\n");
            break;
        default:
            break;
    }*/
}

void EI_Init_hdlc(void)
{
    EG_modem_STS.hdlc_s.status = EM_HDLC_STATUS_0;
    EG_modem_STS.hdlc_s.vr = 0;
    EG_modem_STS.hdlc_s.vs = 0;
    EG_modem_STS.hdlc_s.can_send = 0;
    EI_SetHdlc_sendflag(EM_HDLC_TRANSMIT_NODATA);
    loop_reset(EG_modem_STS.hdlc_recvbuf);
    memset(EG_modem_STS.hdlc_s.resend_buf,0x00,sizeof(EG_modem_STS.hdlc_s.resend_buf));
    EG_modem_STS.hdlc_s.resend_len = 0;
}

/*发送控制帧和无符号帧*/
void EI_hdlc_send_control( unsigned char frame_type , unsigned char poll_bit , unsigned char type)
{
    unsigned char buf[256];
	unsigned char *p = buf;
	
	*p++ = EG_modem_STS.hdlc_s.addr;					/*地址信息*/
	*p   = frame_type;						/*控制域信息*/
	*p  |= poll_bit;
	if ( (frame_type & EM_HDLC_FRAME_U) == EM_HDLC_FRAME_S)
	{
		*p |= (EG_modem_STS.hdlc_s.vr & 0x07) << 5;
	}
	EI_hdlc_transmit_hdlctov80(buf,2);
	EI_WriteUart(EG_modem_STS.v80_sendbuf,EG_modem_STS.v80_sendbuf_len);
}

/*如果是poll/final,则要回送RR应答帧*/
void EI_hdlc_need_response(unsigned char pf)
{
	if( pf )
	{
		EI_hdlc_send_control(EM_HDLC_SUPER_RR, EM_HDLC_FRAME_PFON , EM_HDLC_TYPE_RESPONSE);
		//EI_modem_debug_msg("EI_hdlc_send_control end\n");
	}
}

void EI_hdlc_status1_prcess(struct hdlc_frame_info *frame,char *buf,unsigned int len)
{
	switch(frame->type)
	{
		case EM_HDLC_COMMAND_SNRM:		    
		    uprintf("??? receive SNRM!\r\n");	
			EI_hdlc_recv_snrm(frame);
			break;	
		case EM_HDLC_COMMAND_DISC:/*请求断开连接*/
		    uprintf("??? receive DISC!\r\n");
		    EI_hdlc_send_control(EM_HDLC_RESPONSE_UA,frame->pf,EM_HDLC_TYPE_RESPONSE);			
            EI_hdlc_disconnect();           
			break;
		case EM_HDLC_COMMAND_SIM:
		    uprintf("??? receive SIM!\r\n");
    		//EI_hdlc_disconnect();
			break;	
		case EM_HDLC_COMMAND_UP:
		    uprintf("??? receive UP!\r\n");
    		//EI_hdlc_disconnect();
    		break;	
		case EM_HDLC_SUPER_RNR:   
        	/*主站忙,拒绝接收任何帧信息*/ 
           	/*禁止发送数据*/
           	uprintf("??? receive RNR!\r\n");
           	if ( frame->nr == ( ( EG_hdlc_STS.vs - 1) % 0x07))
		 	{/*数据接收失败,当主站空闲后发送的RR帧Nr值应该是Vs-1,需要执行重发处理*/
		 		EI_hdlc_need_response(frame->pf);	
		 	}
		 	else if( frame->nr == EG_hdlc_STS.vs)
		 	{/*从VS帧数据开始,将不再接收直到主站回送RR帧*/
		 	    EG_hdlc_STS.can_send = 0;
		 		EI_hdlc_need_response(frame->pf);	
		 	}
		 	else
		 	{/*Nr错误*/		 		
		 	    EG_hdlc_STS.can_send = 0;
		 		EG_hdlc_STS.frmr_data  = *frame;
				EG_hdlc_STS.frmr_type  = EM_HDLC_FRMR_Z;
				EG_hdlc_STS.status 	   = EM_HDLC_STATUS_0;
                EI_hdlc_transmit_frmr();
            }
            break; 
		 case EM_HDLC_SUPER_RR:
		    uprintf("receive RR! nr=%d vs=%d\r\n",frame->nr,EG_hdlc_STS.vs);
		 	/*主站准备就绪,可以接收从站发送I帧*/
		 	/*检查Nr是否正确*/
		 	if ( frame->nr == ( ( EG_hdlc_STS.vs - 1) % 0x07))
		 	{/*数据接收失败,需要重发*/
		 	    EG_hdlc_STS.can_send = 1;
		 		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++;	
    					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)
		 	{/*已经成功接收到发送的数据,如果有数据可以继续发送*/
		 		//EI_modem_debug_msg("EG_modem_STS.send_flag = %d\n",EG_modem_STS.send_flag);
		 		EG_hdlc_STS.can_send = 1;
		 		if ( EG_modem_STS.hdlc_s.send_flag == EM_HDLC_TRANSMIT_DATA)
				{
					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_modem_debug_msg("EI_hdlc_need_response begin\n");
					EI_hdlc_need_response(frame->pf);	
					//EI_modem_debug_msg("EI_hdlc_need_response end\n");
				}
				EG_hdlc_STS.re_count 	= 0;
		 	}
		 	else
		 	{/*Nr错误*/
		 		EG_hdlc_STS.frmr_data  = *frame;
				EG_hdlc_STS.frmr_type  = EM_HDLC_FRMR_Z;
				EG_hdlc_STS.status 	   = EM_HDLC_STATUS_0;
                EI_hdlc_transmit_frmr();
            }
            break; 
        case EM_HDLC_SUPER_REJ:/*因为目前的处理是每一帧都是独立的一帧,主站应答后才发送下一帧,因此收到拒绝帧时应该是前面发送的一帧*/	
            uprintf("??? receive REJ!\r\n");
			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++;	
    					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
    				{

⌨️ 快捷键说明

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