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

📄 pro2004.c

📁 本程序是一个RS232转网口的。是一个透明传输的模块
💻 C
📖 第 1 页 / 共 2 页
字号:
}


/*
*****************************************************************************************************
*FUNC:  根据DT1 DT2 取得 FN
*NOTE:  
*****************************************************************************************************
*/
unsigned char GetFn(unsigned char DT1, unsigned char DT2)
{
    unsigned char i;
	unsigned char DT1_Bit1=0;

    if ((DT1 == 0) && (DT2 == 0)) {
        return UNKONW_FN; 
	}

	if (DT2 > 30) {
        return UNKONW_FN; 
	}

    for (i=0; i<8; i++) {
        if (DT1 == (1 << i)) {
		    DT1_Bit1 = i+1;
            return (DT2*8 + DT1_Bit1); 
		} 
	}
    return UNKONW_FN;	
}


/*
*****************************************************************************************************
*FUNC:  收到响应侦后,先判断是否有数据在等待响应以及他们的SEQ PFC 是否相等,如果相等说明是确认侦
*NOTE: 
*****************************************************************************************************
*/
unsigned char QueryPfc(unsigned char PFC)
{
    unsigned char i;

	for (i=0; i<RESENT_BUF_NUM; i++) {
        if ((ResentBufS[i].Statu == WAIT_CONFIRM) && (ResentBufS[i].PFC == PFC) 
		   && (ResentBufS[i].Checked == RESENT_UNCHECKED)) {                   //正等待确认
            ResentBufS[i].Checked = RESENT_CHECKED;  
			return 1;
		}
	}
	return 0;
}

/*
*****************************************************************************************************
*FUNC:  GPRS 收到数据指示
*NOTE:  //FramePush2(buf,size); 清心跳包,清已发送心跳包命令
*****************************************************************************************************
*/
#if 0   //GPRS
void OnReceiveData2004(unsigned char xdata *buf ,unsigned int len)
{
    LoginUnion  xdata LoginU;

	unsigned int  xdata i;
	unsigned int  xdata L1;     //除去8字节后的用户数据长度
	unsigned char xdata AFN;    //解析出的AFN
	unsigned char xdata Pn;     //解析出的Pn
	unsigned char xdata Fn;     //解析出的Fn
	unsigned char xdata CS_Old; //解析出的  CS_Old
    unsigned char xdata CS_New; //接收算出的CS_New
	unsigned char xdata PFC_Old;

	/*
	unsigned char xdata TestBuf[20] = {0x68,0x31,0x00,0x31,0x00,0x68,0xE9,0x33,0x44,0x10,
	                                   0x27,0x00,0x02,0x60,0x00,0x00,0x01,0x00,0xFA,0x16};

	//unsigned char xdata TestBuf[28] = {0x68,0x51,0x00,0x51,0x00,0x68,0x00,0x33,0x44,0x10,0x27,0x00,0x00,0xE0,
	//                                   0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x48,0x07,0x15,0x16,0x01,0x0A,0x16};
    buf = TestBuf;
	len = 20;
	*/

    TimerSec[T_SEND_HEART] = HeartTimeOutBak;    //心跳包时间初始化
	SendHeartFlag = FALSE;                       //清已发心跳包
	
    if ((buf[0] == 0x68) && (buf[5] == 0x68)) {  //68H L L 68H   //L: LOW HIGH
        L1 = buf[2];   //L-HIGH
        L1 <<= 8;
        L1 |= buf[1];  //L-LOW
        L1 >>= 2;

		if (((L1 + 8) == len) && (buf[len-1] == 0x16)) {      //是不是2004规约包
		    CS_Old = buf[len-2];                              //原来的CS
			CS_New = GetCheckSum(&buf[6], L1);

			if (CS_Old == CS_New) {
			    DebugMsg(31,NULL);
                for (i=0; i<18; i++ ) {                       //是2004,拷到共用型由于前18字节是固定
                    LoginU.bytes[i] = buf[i];
			    }
                AFN = LoginU.LoginS.AFN;
                Pn  = GetPn(LoginU.LoginS.DA1, LoginU.LoginS.DA2);
			    Fn  = GetFn(LoginU.LoginS.DT1, LoginU.LoginS.DT2);
				PFC_Old = LoginU.LoginS.SEQ & 0x0f;           //取SEQ的低四位PFC
                if ((AFN == 0x00) && (Pn == 0) && (Fn = 1)) { //AFN=0; PN=0; FN=1:全部确认
				    DebugMsg(33,NULL);
					if (QueryPfc(PFC_Old)) {                  //是猫的确认包,直接返回,否转发
					    DebugMsg(29,NULL);
                        return;
					}
			    }
            }
		}
	} 

	//MC55 这里要先发读数据命令 

	if ((buf[0] == 'W') && (buf[1] == 'P') && (buf[2] == '+')) {
	    ParseRemoteCmd(buf,len);
		return;
    }
	


	if (GprsSocket[SocketIndex].TransMode == TCP_TRANSMODE){        //TCP传输模式
	    Uart0Putsl(buf,len);                                        //网络来的数据直接转发到终端
	} else if (GprsSocket[SocketIndex].TransMode == UDP_TRANSMODE){ //UDP传输模式
        ;                                                           //UDP处理
	} else {
        GprsSocket[SocketIndex].TransMode = TCP_TRANSMODE;          //默认为TCP传输方式
		Uart0Putsl(buf,len);                                        //网络来的数据直接转发到终端
	}
}
#endif

/////////////////////////////////////////////////////////////////////
#if 1   //TCPIP
void OnReceiveData2004(unsigned char xdata *buf ,unsigned int len)
{
    LoginUnion  xdata LoginU;

	unsigned int  xdata i;
	unsigned int  xdata L1;     //除去8字节后的用户数据长度
	unsigned char xdata AFN;    //解析出的AFN
	unsigned char xdata Pn;     //解析出的Pn
	unsigned char xdata Fn;     //解析出的Fn
	unsigned char xdata CS_Old; //解析出的  CS_Old
    unsigned char xdata CS_New; //接收算出的CS_New
	unsigned char xdata PFC_Old;

	/*
	unsigned char xdata TestBuf[20] = {0x68,0x31,0x00,0x31,0x00,0x68,0xE9,0x33,0x44,0x10,
	                                   0x27,0x00,0x02,0x60,0x00,0x00,0x01,0x00,0xFA,0x16};

	//unsigned char xdata TestBuf[28] = {0x68,0x51,0x00,0x51,0x00,0x68,0x00,0x33,0x44,0x10,0x27,0x00,0x00,0xE0,
	//                                   0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x48,0x07,0x15,0x16,0x01,0x0A,0x16};
    buf = TestBuf;
	len = 20;
	*/

    TimerSec[T_SEND_HEART] = HeartTimeOutBak;    //心跳包时间初始化
	SendHeartFlag = FALSE;                       //清已发心跳包
	
    if ((buf[0] == 0x68) && (buf[5] == 0x68)) {  //68H L L 68H   //L: LOW HIGH
        L1 = buf[2];   //L-HIGH
        L1 <<= 8;
        L1 |= buf[1];  //L-LOW
        L1 >>= 2;

		if (((L1 + 8) == len) && (buf[len-1] == 0x16)) {      //是不是2004规约包
		    CS_Old = buf[len-2];                              //原来的CS
			CS_New = GetCheckSum(&buf[6], L1);

			if (CS_Old == CS_New) {
			    DebugMsg(31,NULL);
                for (i=0; i<18; i++ ) {                       //是2004,拷到共用型由于前18字节是固定
                    LoginU.bytes[i] = buf[i];
			    }
                AFN = LoginU.LoginS.AFN;
                Pn  = GetPn(LoginU.LoginS.DA1, LoginU.LoginS.DA2);
			    Fn  = GetFn(LoginU.LoginS.DT1, LoginU.LoginS.DT2);
				PFC_Old = LoginU.LoginS.SEQ & 0x0f;           //取SEQ的低四位PFC
                if ((AFN == 0x00) && (Pn == 0) && (Fn = 1)) { //AFN=0; PN=0; FN=1:全部确认
				    DebugMsg(33,NULL);
					if (QueryPfc(PFC_Old)) {                  //是猫的确认包,直接返回,否转发
					    DebugMsg(29,NULL);
                        return;
					}
			    }
            }
		}
	} 
	Uart0Putsl(buf,len);                                        //网络来的数据直接转发到终端
}
#endif

/*
*****************************************************************************************************
*FUNC:  在等待确认后,开始计算重发间隔时间
*NOTE: 
*****************************************************************************************************
*/
void ResenBuf_Interval(void)                                 
{
    unsigned char i;

	for (i=0; i<RESENT_BUF_NUM; i++) {
        if (ResentBufS[i].Statu == WAIT_CONFIRM) {    //有数据在等待确认,开始计时以待重发
            if (ResentBufS[i].Interval > 0) {
                ResentBufS[i].Interval--;             //间隔时间
			} else {
                ResentBufS[i].Statu = WAIT_SENT;
			}
		} 
	}
}

/*
*****************************************************************************************************
*FUNC:  根据各状态执行  WAIT_SENT => WAIT_CONFIRM
*NOTE: 
*****************************************************************************************************
*/
void ReSentFunc(unsigned char index) 
{
    
    switch (ResentBufS[index].Statu) {
		case STATU_IDLE:		                                               //空闲状态
		     break;
	    case WAIT_SENT:		                                                   //等待运行
             if (ResentBufS[index].Interval > 0) {
                 return;
			 }                                                                 //间隔时间到可发送
		     if (ResentBufS[index].Count > 0) {
                 ResentBufS[index].Count--;
				 ResentBufS[index].Statu    = WAIT_CONFIRM;                    //切换状态为等待确认状态
				 ResentBufS[index].Checked  = RESENT_UNCHECKED;                //未确认
				 ResentBufS[index].Interval = 20;                              //间隔20S再重发
                 /*
				 Uart0Putf("\r\n应该发:");
	             Uart0Putsl(ResentBufS[index].Buf,ResentBufS[index].Length);   //FOR DEBUG 
                 */ 
                 FramePush(ResentBufS[index].Buf,ResentBufS[index].Length);    //压入缓冲区,准备发送
			 } else {
                 DebugMsg(28,NULL);  // 重发超过次数处理
                 RSBInitNum(index);  // ???????????????
			 }		     
		     break;
	    case WAIT_CONFIRM:	                                                   //等待确认
		     if (ResentBufS[index].Checked == RESENT_CHECKED) {
			     DebugMsg(30,NULL);  // 重发超过次数处理
                 RSBInitNum(index);  //得到确认后,清各标志                                  
			 }
		     break;
        default:
             RSBInitNum(index);
		     break;
	}
}

/*
*****************************************************************************************************
*FUNC:  为了2004规约重发机制而添加的
*NOTE:  TimerMil[T_RESENT_INTERVAL]
*****************************************************************************************************
*/
void ParseReSentBuf(void)
{
 
	while (ResentOut < RESENT_BUF_NUM) {
        if (ResentBufS[ResentOut].Statu != STATU_IDLE) {    //缓冲区有数据
            ReSentFunc(ResentOut);                          //处理数据                                          
			ResentOut++;                                    //处理完一侦退出,不要连续做四侦
			break;
		} else { 
	        ResentOut++;
		}
	}

	if (ResentOut >= RESENT_BUF_NUM) {
        ResentOut = 0;
	}
}


/*
*****************************************************************************************************
*FUNC:  2004规约初始化
*NOTE:  单个重发缓冲区初始化 
*****************************************************************************************************
*/
void RSBInitNum(unsigned char num)
{
    ResentBufS[num].Statu    = STATU_IDLE;
    ResentBufS[num].Checked  = RESENT_UNCHECKED;    
	ResentBufS[num].Interval = 0;        
    ResentBufS[num].PFC      = 0;        
	ResentBufS[num].Count    = 0;
}

void RSBInit(void)
{
    unsigned char i;

	PFC = 0;
	ResentIn = ResentOut = 0;

	for (i=0; i<RESENT_BUF_NUM; i++) {
        RSBInitNum(i);
	}
}

void Pro2004Init(void)
{
    RSBInit();   
    ID2BCD();
}



/**************************************************************************************************/
#endif
/**************************************************************************************************/

⌨️ 快捷键说明

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