📄 masc.cpp
字号:
//请给出函数的具体的流程,函数的调用关系,数据的流向。
//给出流程图??
#include "public.h"
const unsigned char NoSignal[30]="MODEM NO SIGNAL,PLEASE CHECK\r";//29 byte
const unsigned char ModemInit[35] ="MODEM IS INITIALIZING,PLEASE WAIT\r";//34 byte
const unsigned char debugStr[8]="debug-";
//信号量定义,为限制函数调用的层数,防止函数堆栈溢出。
unsigned char mpakRcved_Sigle;
unsigned char inNetworkContanct_Sigle;
unsigned char outOfNetworkContanct_Sigle;
unsigned char mpakNotSent_Sigle;
unsigned char mpakSent_Sigle;
unsigned char terminalMAN_Sigle;
unsigned char mascErrCode;
unsigned char mascErrCode_Signle;
unsigned char DteDataChar;
unsigned char powerSaveCount;
unsigned long pingBaseTimer;//
unsigned char resetInfo[2];
unsigned long LongTimeTimer;
unsigned long FGTimeOutTimer;
unsigned char backDoor[50];
//常量字符串定义
const unsigned char SendFail[10]="SEND FAIL\r";//9字节
/***********masc控制桢定义***********************/
unsigned char Mask_Sens_Frame[4]="^#\r";
unsigned char Masc_Sack_Frame[4]="^&\r";
unsigned char Masc_Rack_Frame[4]="^!\r";
unsigned char Masc_GetMan_Frame[3]="F P";
unsigned char Masc_Init_Frame[7]="B 47E,0";
unsigned char Masc_Nack_Frame[4]="^?\r";
unsigned char Masc_Ackn_Frame[5]="^*-\r";
unsigned char Masc_SetExpress_Frame[6]="F Y00";
unsigned char Masc_request_Power_Mode[9]="F A01";
unsigned char Masc_cancelLastMpak[5]="F I";
//用户数据缓冲
unsigned char User_Rx_Buf[MPAK_SIZE+1];
unsigned char mpakPacket[MPAK_SIZE+1];
unsigned long rcvedMpakUserLen;
//重发数据缓冲
unsigned char ReSendBuf[COM_NUM][FRAME_SIZE+1];
//masc发送缓冲
unsigned char Masc_Tx_Buf[COM_NUM][MASC_TX_SIZE+1];
//masc帧接收处理缓冲
unsigned char Masc_Rx_Frame[COM_NUM][FRAME_SIZE+1];//masc帧接收处理缓冲
//打包缓冲
unsigned char MakeMpakBuf[COM_NUM][FRAME_SIZE+1];
unsigned char TmpakBuf[COM_NUM][FRAME_SIZE+1];
//Masc发送缓冲读写指针
unsigned int pMascTxBuf_Rd[COM_NUM];
unsigned int pMascTxBuf_Wr[COM_NUM];
unsigned char gLastReceiveSequ[COM_NUM];
unsigned char gReSendLen[COM_NUM];
unsigned char gReSendNum[COM_NUM];
unsigned char gInitOk[COM_NUM];
unsigned char gLastSentSequ[COM_NUM]; //上一次发送的ACK的sepu
unsigned char gInitSentedFlag[COM_NUM]; //是否发送B
unsigned char gInitRxFlag[COM_NUM]; //是否收到对方的B
unsigned char gAllowSent[COM_NUM]; //是否受到ACK如收到可发下一帧
unsigned char gRackSendFlag[COM_NUM]; //是否需要发送RACK
unsigned char gRackAllow[COM_NUM]; //是否允许RACK计时
unsigned int gRackCounter[COM_NUM]; //RACK计数器
unsigned char gInitStart[COM_NUM]; //启动初始化标志
unsigned char gSignalOk[COM_NUM]; //有信号标志
unsigned int gMascFrameRxCnt[COM_NUM]; //接收完一MASC帧所用计数器
//unsigned int gIdleTime[COM_NUM]; //没有数据处理的空闲时间
//应用程序变量定义
unsigned int gIdleTime;
unsigned int gSensCounter;
unsigned long gSenderMan;
//unsigned charStartStrFlag;
//unsigned charCurPosition;//比较起始与结束字符串时用到
/**************************MASC协议解码函数*******************************
入口参数: source -----源M字符串存放位置,tar---目的字符串存放位置
出口参数: 无
返 回 值: 无
功 能: MASC协议解码函数
描 述:
/**********************************************************************//*************************************/
unsigned int MascDecode(unsigned char *source,unsigned char * tar,unsigned int DataLen)
{
unsigned int i=0,len;
unsigned charnum;
unsigned charstr[3];
//len=strlen(source);
len=DataLen/2;
for(i=0; i<len; i++)
{
str[0] = source[i*2];
str[1] = source[i*2+1];
num=HexAToDecL(str,2);
*(tar+i)=num;
}
*(tar+i)=0;
return len;
}
/**************************MASC协议编码函数*******************************
入口参数: data -----源MASC帧存放位置,num---源帧长度initializing
出口参数: 无
返 回 值: 无
功 能: MASC编码函数
描 述:
/**********************************************************************/
void MascEncode(unsigned char *source,unsigned char *tar,unsigned int DataLen)
{
unsigned int i=0;
unsigned chartemp;
unsigned char inttohexstr[4];
for(i=0;i<DataLen;i++)
{
temp = source[i];
UcharToHex(temp,inttohexstr);
MyMemCpy(tar+2*i,inttohexstr,2);
}
*(tar+2*DataLen)='\0'; //end of string
}
/*************************************/
//功能:确认是否NACK
//frame:需要确认的数据包
//返回值:1:符合条件
/*************************************/
unsigned charNackCriteriaFulfilled( unsigned char *frametmp)
{
unsigned int colonIndex=0;
unsigned int numcolon=0;
unsigned int i=0,len;
len=strlen(frametmp);
if(frametmp[0]!='^') return 0;
for(i=0;i<len;i++)
{
if (frametmp[i]==':')
{
colonIndex=i;
numcolon++;
}
}
if(numcolon!=1) return 0;
if (len<10) return 0;
if(frametmp[len-1]!= 0x0D) return 0;
return 1;
}
/*************************************/
//功能:确认是否ACK
//frame:需要确认的数据包
//返回值:1:符合条件
/*************************************/
unsigned charAckCriteriaFulfilled( unsigned char*frametmp)
{
unsigned int colonIndex=0;
unsigned int numcolon=0;
unsigned int checksum=0;
unsigned int i=0,len=0,j=0;
unsigned int len_text,len_dataa;
unsigned int chk;
unsigned charackcritmp[5];
len=strlen(frametmp);
if(frametmp[0]!='^') return 0;
for(i=0;i<len;i++) //judge the count 0f the frame have colon
{
if (frametmp[i]==':')
{
colonIndex=i;
numcolon+=1;
}
}
if(numcolon!=1) return 0;//:冒号的个数
StrSub(frametmp,ackcritmp,1,4); //长度
if (HexAToDecL(ackcritmp,4)!=len)
return 0;
i=len-3; //have the dataa xor judge
for(j=0;j<i; j++)
{
checksum=checksum^(unsigned int)frametmp[j];
}
StrSub(frametmp,ackcritmp,i,2);
chk=HexAToDecL(ackcritmp,2);
if (chk!=checksum)
{
return 0;
}
len_text=colonIndex-5; //命令
for(j=0;j<len_text;j++)
{
//3A=: 5E=^ 7D=} 20=;
if((frametmp[5+j]<0x20)||(frametmp[5+j]>0x7D)||(frametmp[5+j]==0x3A)||(frametmp[5+j]==0x5E))
return 0;
}
len_dataa=len-colonIndex-3+1;
if(len>1150 || len_dataa>1120 || len_text>256 )
{
return 0;
}
if(frametmp[len-1]!= 0x0D) return 0;
return 1;
}
/*************************************/
//功能:对从网络收到的数据的分析处理
//Frame:收到的数据
/*************************************/
void MascCmdAnalysis(unsigned charmComNum ,unsigned char *Frame,unsigned int DataLen)
{
//unsigned charonechar;
unsigned charSequ;
unsigned charmState,mClass,mType;
unsigned int num;
unsigned char sixch[7];
unsigned int mpakLen;
//unsigned long Sender;
//onechar =Frame[1];
switch(Frame[1])
{
case '*':
{
gRackAllow[mComNum]=FALSE;
gRackCounter[mComNum]=0;
Sequ = Frame[2];
if(Sequ == '-')
{
//因为重发的是信息帧,所以要按照信息帧的方式进行处理
gRackAllow[mComNum]=TRUE;//RACK开始计时
gRackCounter[mComNum]=0;
gAllowSent[mComNum] = 0;//将允许发送标志置0,即设为不允许发送
SendToUartBuffer(mComNum, &ReSendBuf[mComNum][0],gReSendLen[mComNum]);//重发
}
else if ((gInitSentedFlag[mComNum] == 1)&&(gInitRxFlag[mComNum] == 1))
{
gAllowSent[mComNum] = 1;
SendCmdFrame(mComNum,Masc_GetMan_Frame,3);
gInitSentedFlag[mComNum] = 0;
gInitRxFlag[mComNum] = 0;
}
else
{
gAllowSent[mComNum] = 1;
if ((gInitRxFlag[mComNum]==1) && (gInitSentedFlag[mComNum]==0))
{
SendCmdFrame(mComNum,Masc_Init_Frame,7);
gInitSentedFlag[mComNum]=1;
}
}
}
break;
case '?':
{
if(gReSendNum[mComNum]<3)//重发次数小于3次则重发
{
//因为重发的是信息帧,所以要按照信息帧的方式进行处理
gRackAllow[mComNum]=TRUE;//RACK开始计时
gRackCounter[mComNum]=0;
gAllowSent[mComNum] = 0;//将允许发送标志置0,即设为不允许发送
SendToUartBuffer(mComNum, &ReSendBuf[mComNum][0],gReSendLen[mComNum]);//重发
gReSendNum[mComNum]++;
}
else
Less3TimesReset(2); //连续收到?
}
break;
case '!':
{
SendToUartBuffer(mComNum,Masc_Ackn_Frame,4);
}
break;
case '#':
{
SendToUartBuffer(mComNum,Masc_Sack_Frame,3);
}
break;
case '&':
{
gSensCounter = 0;
}
break;
default:
{
if(AckCriteriaFulfilled(Frame))
{
if(Frame[5]=='B')
{
if (gLastSentSequ[mComNum] == '-')
{
gLastSentSequ[mComNum] = '0';
}
Masc_Ackn_Frame[2] = gLastSentSequ[mComNum];
SendToUartBuffer(mComNum,Masc_Ackn_Frame,4);
Delay(1);
if(mComNum==COMM2)
{
gInitRxFlag[mComNum] =1;
SendCmdFrame(mComNum,Masc_Init_Frame,7);
gInitSentedFlag[mComNum]=1;
}
}
else
{
gLastSentSequ[mComNum] =((gLastSentSequ[mComNum] =='0')?'1':'0');
Masc_Ackn_Frame[2] =gLastSentSequ[mComNum];
SendToUartBuffer(mComNum,Masc_Ackn_Frame,4);
//Delay(1);
switch(Frame[5])
{
case 'F':
{
switch(Frame[7])
{
case 'F':
{
inNetworkContanct_Sigle=1;
gSignalOk[mComNum]=1;
if(gInitOk[mComNum]==0)
{
gInitOk[mComNum]=1;
}
}
break;
case 'G':
{
outOfNetworkContanct_Sigle=1;
gSignalOk[mComNum]=0;
if(gInitOk[mComNum]==0)
{
gInitOk[mComNum]=1;
}
}
break;
case 'P':
{
MyMemCpy(sixch,&Frame[8],6);
gSenderMan=HexAToDecL(sixch,6);
terminalMAN_Sigle=1;
}
break;
case 'Y':
{
if(Frame[8]=='0')
{
if(Frame[9]=='1')
{
SendCmdFrame(COMM2,Masc_SetExpress_Frame,5);
powerSaveCount++;
if(powerSaveCount>1)
Less3TimesReset(5);//设成非省电模式失败
}
}else
powerSaveCount=0;
}
break;
case 'A':
{
if((Frame[8]=='0')&&(Frame[9]=='1'))
{
if(Frame[12]=='2')
{
SendCmdFrame(COMM2,Masc_SetExpress_Frame,5);
powerSaveCount++;
if(powerSaveCount>1)
Less3TimesReset(5);//设成非省电模式失败
}
}else
powerSaveCount=0;
}
break;
case 'H':
{
mpakSent_Sigle=1;
if(backDoorSent==1)
{
pingBaseTimer=0;//回复正常后停止计时
FGTimeOutTimer=0;//五分钟没信号
ReadFromRom(DEVADDRRD,0,resetInfo,2);//恢复正常后将重启计数器清零。
LongTimeTimer=0;//恢复正常后,24小时的定时器清零。
if (resetInfo[0]!=0)
{
#if _DEBUG_==1
_monitor_text("resetInfo[0] not equarl to 0, reset to 0 :",1);
_monitor_decimal_disp(pingBaseTimer,3);
#endif
resetInfo[0]=0;
resetInfo[1]=0xFA;
WriteToRom(DEVADDRWR,0,resetInfo,2);
}
}
}
break;
case 'K':
{
mascErrCode = HexAToDecL(&Frame[8],2) ;
mascErrCode_Signle =1;
}
default:
break;
}
}
break;
case 'M':
{
num = HexAToDecL(&Frame[19],2);
mState = (num & 0xE0);
//if(mState!=0) return;
num = HexAToDecL(&Frame[21],2);
mClass = (num & 0xC0)>>6;
mType = num & 0x1F;
switch(mClass)
{
case PSUBCOM_CLASS:
{
//从mpak包开始去掉7,去掉校验和结束符去掉3
DataLen = HexAToDecL(&Frame[1],4);
mpakLen=MascDecode((Frame+7),mpakPacket,DataLen-7-3);
//用户数据需要去掉包头 userLen-11
if(mType == MPAK_HPDATA)
rcvedMpakUserLen =mpakLen-12;
else
rcvedMpakUserLen=mpakLen-11;
mpakRcved_Sigle =1;
//for ping command,如果10分钟都没有收到数据的时候,会自发自收。在收到任何用户数据,都表示在网,所有要清零。
if(backDoorSent==1)
{
pingBaseTimer=0;//回复正常后停止计时
FGTimeOutTimer=0;
ReadFromRom(DEVADDRRD,0,resetInfo,2);//恢复正常后将重启计数器清零。
LongTimeTimer=0;//恢复正常后,24小时的定时器清零。
if (resetInfo[0]!=0)
{
#if _DEBUG_==1
_monitor_text("resetInfo[0] not equarl to 0, reset to 0 :",1);
_monitor_decimal_disp(pingBaseTimer,3);
#endif
resetInfo[0]=0;
resetInfo[1]=0xFA;
WriteToRom(DEVADDRWR,0,resetInfo,2);
}
}
}
break;
default:
break;
}
}
break;
case 'N':
{
//从mpak包开始去掉7,去掉校验和结束符去掉3
DataLen = HexAToDecL(&Frame[1],4);
mpakLen=MascDecode((Frame+7),mpakPacket,DataLen-7-3);
//用户数据需要去掉包头 userLen-11
if(mType == MPAK_HPDATA)
rcvedMpakUserLen =mpakLen-12;
else
rcvedMpakUserLen=mpakLen-11;
mpakNotSent_Sigle=1;
}
break;
}//判断第五字节
}//非初始化帧处理
}//非初始化帧处理
else if(NackCriteriaFulfilled(Frame))
{
SendToUartBuffer(mComNum,Masc_Nack_Frame,3);
}
}
break;
}
}
//发送串口发送缓冲区的字符到串口
void SendDataToUart(unsigned charmNum)
{
unsigned char ch;
unsigned char flag, tmp;
if(gUart_Send_Busy[mNum]==1)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -