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

📄 mascdriverdlg.cpp

📁 mobitex 网络的终端采用的串口通信程序。目前正在使用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}
// 当收到串口发送来的帧后进行相应的处理
//处理顺序
//MascFrameReceived-->informationFrameReceived-->HandleFrame

void CMascdriverDlg::MascFrameReceived(CString frame)
{
    switch (frame.GetAt (1)){
	case '*':  // Ack.
        AckFrameReceived(frame); // 如接收到的为Ack,则进入ACK处理函数.ACK为收到正确的信息帧之后而发回的响应
        break;
	case '?':  // Nack.
        NackFrameReceived();// 如接收到的为Nack,则进入NACK处理函数. NACK为收到不正确的信息帧(主要为帧头帧尾错误)之后而发回的响应
        break;
	case '!':             // 如接收到的为 Rack,则进入RACK处理函数. RACK意思为没收到ACK要求重发
        RackFrameReceived();//收到要求重发ack贞的函数
        break;
	case '#':  
		// 如接收到的为 SENS,则进入SENS处理函数.链路层控制(当通信链路没有通信时,发送SENS,两个SENS之间间隔至少为10秒);
		//如果处于无通信状态,则每隔10秒发一次.如果连续发两个SENS仍没有收到SACK,则认为断路,重新初始化.
        SensFrameReceived();//
        break;
	case '&':  // 如接收到的为 SACK,则进入SACK处理函数.SACK为正确收到SENS而返回的响应
        SackFrameReceived();//收到sens的应答.
        break;
	default:   // 如接收到的为信息帧,则进入信息帧处理函数.
        InformationFrameReceived(frame);
        break;
		
    }
}

/*若收到的为ACK帧,进入ACK帧处理函数;ACK的帧格式为"^*\r"*/
void CMascdriverDlg::AckFrameReceived(CString frame)  //gg
{
	flagResetTime=TRUE;                   //停止计时
	char sequ = frame.GetAt(2);
	if(sequ == '-')                      //如MODEM在发送第一个ACK之前收到了RACK,则返回"^*-". 
	{ 
		SentInfoFrame(lastSentFrame);    //重新发送上次发送的帧	
		flagResetTime=FALSE;             //启动计时器和计数器,若在发出信息帧10秒后,仍没收到正确的ACK,
		Counter=0;                       //则会每隔10秒连续发二个RACK,在第二个RACK过10秒还没收到ACK,
		return ;
	}
	if(sequ == lastReceivedSequ)          //若接收到的ACK的SEQU与上一次接收到的ACK的SEQU相同,则说明
	{  
		SentInfoFrame(lastSentFrame);     //发送上次发送的帧
		flagResetTime=FALSE;              //启动计时器和计数器
		Counter=0;                        //计时器从零开始
		return ;
	} 

	lastReceivedSequ=sequ;         //保存上一次发送的序号
	if ((lastSentFrame == "^0010B 47E,0:5D\r") && (Counter>=10)) //此处需特殊考虑,如上次发送的是初始化帧,且10秒内
	{
		flagAllowToSent = TRUE;
		SentInfoFrame(lastSentFrame);  //没收到ACK,则重发初始化帧.而其它的帧则是发出去30秒之内没收到ACK,再重发.      
		flagResetTime=FALSE;           //启动计时器和计数器
		Counter=0;                     //计时器从零开始
		return ;		
	} 
	if  (lastSentFrame == "^0010B 47E,0:5D\r")
	{
		flagAllowToSent=TRUE;      //表明收到的为正确的ACK.可以发送下一帧,将允许发送标志置为TRUE;
		if (flagInitReceived)
		{
			requestTerminalMan();                 //判断已收到init并且已经发送init.
			flagInitDrvSucced=true;
			flagInitSent=false;                   //表明初始化已经完成
			flagInitReceived=false;
		}
		return ;
	} 
	if ((flagInitReceived==TRUE) && (flagInitSent==FALSE))  
	{
		flagAllowToSent=TRUE;      //表明收到的为正确的ACK.可以发送下一帧,将允许发送标志置为TRUE;
		if (UserSentInfoFrame("B 47E,0:",false))
			flagInitSent=true;
		flagSensRestTime=FALSE;    //开始计时,要求查询网络计时器开始计时 
		SensCounter=0;             //计时器从零开始,其实计时器从零和从其他(只要是10的整数倍数开始都可以)开始
		return ;
	}
	flagAllowToSent = TRUE;
	/*
	static tmpMascCommandId = 1;
	switch (tmpMascCommandId )
	{
	case 1:
		//UserSentInfoFrame("F 03:",FALSE);	  //运营商网络编号
		break;
	case 2:
		//UserSentInfoFrame("F A01:",FALSE);	  //获取当前的电源模式
		break;
	case 3:
		//UserSentInfoFrame("F Z01:",FALSE);	   //软件的标识号
		break;
	case 4:
		//UserSentInfoFrame("F Z02:",FALSE);	   //软件的版本号
		break;
	case 5:
		//UserSentInfoFrame("F Z03:",FALSE);	   //物理序列号
		break;
	case 6:
		//UserSentInfoFrame("F Z04:",FALSE);		//无线协议信息
		break;
	case 7:
		//UserSentInfoFrame("F A02:",FALSE);
		break;
	}
	if (tmpMascCommandId < 8)
	{
		tmpMascCommandId++;
		return ;
	}
	
		*/
/*	switch (mascCommandId)
	{
	case 1:
		//UserSentInfoFrame("PA01:",FALSE);
		break;
	case 2:
		//UserSentInfoFrame("PA02:",FALSE);
		break;
	case 3:
		//UserSentInfoFrame("PA03:",FALSE);
		break;
	case 4:
		//UserSentInfoFrame("PA04:",FALSE);
		break;
	case 5:
		UserSentInfoFrame("PA05:",FALSE);
		break;
	case 6:
		//UserSentInfoFrame("PA07:",FALSE);
		break;
	case 7:
		UserSentInfoFrame("PA09:",FALSE);
		break;
	}
	if (mascCommandId <8)
	{
		mascCommandId += 1;
		return ;
	}
   	  */
/*	switch (mascCommandId)
	{
	case 1:
		UserSentInfoFrame("PA01:",FALSE);
		break;
	case 2:
		UserSentInfoFrame("PA05:",FALSE);
		break;
	}
	if (mascCommandId <8)
	{
		mascCommandId += 1;
		return ;
	}
  */
}
/*收到重新发送信息帧的处理方式,表明MODEM收到的信息帧没通过校验,需要重发;NACK的帧格式为"^?\r"*/
void CMascdriverDlg::NackFrameReceived()
{
  
	SendMsgToUart(lastSentFrame);//重新发送信息帧,上一次未发送成功的信息桢
	Counter=0;		//计时器归零,因为计时器没有停止
		
}
/*收到重新发送控制帧信息的处理方式,表明MODEM没收到正确的ACK,需重发ACK;RACK的帧格式为"^!\r"*/
void CMascdriverDlg::RackFrameReceived()   //gg
{
	CString temp;
	temp="^*"; 
	temp=temp+lastSentSequ ;            //定义一字符串(暂放上次发送的ACK),用于发送
	temp=temp+"\r";
	SendMsgToUart(temp);
}
/*收到SENS,用于在没有通讯业务时检查通讯链路是否为通,收到之后,立即发送SACK,以应答SENS,
/*如果发送方在10秒内没收到SACK,则再发一个SENS,当两个SENS 发出后都没收到SACK,
/*则必须发送INIT帧重新启动;SENS的帧格式为"^#\r"*/
void CMascdriverDlg::SensFrameReceived()
{
	SendMsgToUart("^&\r"); 
}
/*收到SACK,此命令为SENS的应答帧;SACK的帧格式为"^&\r"*/
void CMascdriverDlg::SackFrameReceived()
{
	if (flagSensNo==TRUE)    //检查上一次是否发送了SENS,若发送了SENS,收到SACK时检查flagSensNo标志,是否为上
	{                        //一次发送SENS时设置的标志.详见ONTIMER事件.
		flagSensNo=FALSE;    //检查是否发送一SENS帧的标志,如正确发送一个SENS,则将SensNo置为TRUE;在收到SACK之后将其置为FALSE,说明没有发送SENS;
		SensCounter=0;       //发送SENS的计时器归零
		flagAllowToSent=TRUE;    //因为收到正确的SACK,则将允许发送标志置为TRUE;
	}
}
//此函数处理是初始化,信息。
//已经通过判断,认为是通常的信息贞.
void CMascdriverDlg::InformationFrameReceived(CString frame)  //gg
{
	if(AckCriteriaFulfilled((unsigned char*)(LPCTSTR)frame)) 
	{ 
		if(frame.GetAt(5) == 'B') 
		{   
			CString temp;
			
			if (flagInitDrvSucced==false) 
			flagInitReceived=true;
			else
			{
				InitDriver();
				return;
			}
			
			
			if (lastSentSequ =='-') 
				lastSentSequ='0' ; //问题 是0  是 1 都行.通常情况下选0
			else
				lastSentSequ = (lastSentSequ == '0') ? '1':'0';
				
				temp="^*" + CString(lastSentSequ);
				temp=temp+"\r";

			SendMsgToUart(temp);   
			

			if (!flagInitSent)
			{
				if (UserSentInfoFrame("B 47E,0:",false))
				flagInitSent=true;
			} else if (flagAllowToSent)
			{
				requestTerminalMan();
				flagInitDrvSucced=true;
				flagInitSent=false;
				flagInitReceived=false;
			}
			}else 
		{ 
            lastSentSequ = (lastSentSequ == '0') ? '1':'0';
            //构建ack控制贞
			CString temp;
			temp="^*" + CString(lastSentSequ);
			temp=temp+"\r";

			SendMsgToUart(temp);    //控件要求
			//将贞头、贞尾、校验、长度去掉。
			flagSensRestTime=FALSE;    //开始计时,要求查询网络计时器开始计时 
			SensCounter=0;             //计时器从零开始,其实计时器从零和从其他(只要是10的整数倍数开始都可以)开始
			HandleFrame(frame.Mid(5, frame.GetLength ()-8));
		}

	} else
		//检验贞是否合法。
		if(NackCriteriaFulfilled((unsigned char*)(LPCTSTR)frame)) 
		{
            SendMsgToUart("^?\r");

		} 

}
//将打好包的frame发送到串口
void CMascdriverDlg::SentInfoFrame(CString frame)
{
	lastSentFrame=frame;    //将打好包的信息桢保存到上一个未发送的信息包中,可以节约在发送信息时对原始信息打包的过程         
	SendMsgToUart(lastSentFrame);//重新发送信息帧,上一次未发送成功的信息桢
}
//给用户调用的接口函数
BOOL CMascdriverDlg::UserSentInfoFrame(CString frame,bool Flag)//gg
{
	
	if (Flag==TRUE)    
	{			   
		
		if ( flagAllowToSent ) //                   //当前MODEM是否处于可以发送状态
		{  
			frame=EncodeFrame(frame);        //在此打包的原因是如果不具备发送的条件根本不进行打包.
			SentInfoFrame(frame);
			huanchongframe=frame;            //只保存需要和网络联系的包,这个信息包如果在modem死机的情况下如果对
			flagMpakSentSingle=FALSE;        //表示,这个信息尚未成功发送到基站.
			flagAllowToSent=FALSE;           //表示这个信息尚未成功发送到modem
			flagResetTime=FALSE;             //开始计时,在规定的时间内,要求MODE做出应答 
			Counter=0;                       //表示计时器从零开始计时
			flagSensRestTime=TRUE;           //Sens 停止计时,有任何命令发送,都表示网络没有空闲. 在发送ACK后和收到
			return TRUE;
		}
		else  
		{
			return FALSE;                    //没有发送成功
		}
	}
	else
		if (flagAllowToSent)                      //当前莫MODEM是否处于可以发送状态.因为要发送的命令是不需要发送到网络上的
			//所以只要上次发送的命令只要是已经发送到modem上后就可以发送这个命令.
		{  
			frame=EncodeFrame(frame);
			SentInfoFrame(frame);
			flagAllowToSent=FALSE;
			flagResetTime=FALSE;             //      开始计时 
			Counter=0;
			flagSensRestTime=TRUE;           //      Sens 停止计时,有任何命令发送,都表示网络没有空闲.
			return TRUE;
		}
		else  
		{
			AddMsgToEdit(m_masc_edit,"pc-->modem  请稍后发送");
			return FALSE;                   //表示没有发送成功
		}
}
void CMascdriverDlg::OnTimer(UINT nIDEvent) //gg
{
	bWriteToDbglogFileTimer = TRUE;
	if (!flagResetTime)                       //表示在发送了信息桢后开始启动计时器.
	{
		Counter=Counter+1;
		if ((Counter)==10||(Counter)==20)                 //表示时间是否到了10秒,20秒,30秒.
		{
			SendMsgToUart("^!\r");
		} else
			if (Counter==30)
			{
				if(huanchongframe!="")           //检查缓冲区中是否有内容.如果没有内容的话就不必告诉用户. 
					Li_modemReset(huanchongframe);	 //将未完成的任务通知用户,让用户进行处理
				InitDriver();
			}
    }
	
	if (!flagSensRestTime)                    //表示网络空闲后开始启动计时器.一种是在收到ACK后.
	{
		SensCounter=SensCounter+1;
		if ((SensCounter==10) || (SensCounter==20))             //表示时间是否到了10秒,20秒,30秒
		{
			SendMsgToUart("^#\r");
			flagSensNo=TRUE; 
		} else	                            //发送询问网络情况时,标志为已经发送
			if (SensCounter==30)
			{
				if(huanchongframe!="")           //检查缓冲区中是否有内容.如果没有内容的话就不必告诉用户. 
					Li_modemReset(huanchongframe);	 //将未完成的任务通知用户,让用户进行处理
				InitDriver();
			}
	}
	if (!flagInitDrvSucced)                     //判断是否是初始化.如果在很长时间内没有反映的话,就重新进行初始化.
	{
		DriverCounter+=1;
		if(DriverCounter>MASC_INIT_TIMEOUT)  //如果在初始化后,没有反映,则重新初始化.包括串口的初始化时间3秒
		{
			
			InitDriver();
			Li_Initfailed();	             //在初始化失败地情况下不断地执行,权利交给用户
		}
	}
	//定时发送数据,
	static int q=0;
	static int m=0;

⌨️ 快捷键说明

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