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