📄 mascdriverdlg.cpp
字号:
}
// 当收到串口发送来的帧后进行相应的处理
//处理顺序
//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 + -