📄 isomodem_hdlc.c
字号:
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 + -