📄 serialcommlayer.cpp
字号:
#ifdef __RCC_DEBUG__
DisplayMessage("重发帧");
ASSERT(FALSE);
#endif
SendMsgFrame(frmDataAnswer); //发送终止传输帧
}
else if (FrameHeader.FrameNo == ReceFrameNo)
{ //帧收到
if(FrameHeader.Length + DataBufferLength > DataBufferMaxLength)
{ //应用程序缓冲区不够
LastError = RCC_ERROR_OVERFLOW;
PostRCCMessage(RCC_ERROR,RCC_ERROR_OVERFLOW);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
else
{ //数据收到
memcpy(&DataBuffer[DataBufferLength],Data.Data,FrameHeader.Length);
DataBufferLength += FrameHeader.Length;
PostRCCMessage(RCC_READ,0);
PrevReceFrameNo = ReceFrameNo;
SendMsgFrame(frmDataAnswer); //发送终止传输帧
}
}
else
{ //同步丢失
LastError = RCC_ERROR_SYNC;
PostRCCMessage(RCC_ERROR,RCC_ERROR_SYNC);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
}
}
else
{
LastError = RCC_ERROR_FRAME;
PostRCCMessage(RCC_ERROR,RCC_ERROR_FRAME);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
break;
case frmZippedData://压缩数据帧
if(pos + FrameHeader.Length + 2 > ReceiveBufferLength)
{ //缓冲区超出等待剩余部分数据到达
#ifdef __RCC_DEBUG__
DisplayMessage("数据字符不够解析,1");
#endif
return 1;
}
if(FrameHeader.Length>0 && FrameHeader.Length <=MaxBytesPerBlock)
{
//得到一帧数据
memcpy(&Data,&ReceiveBuffer[pos-HeaderSize],
HeaderSize + FrameHeader.Length + 2);
pos += (FrameHeader.Length + 2);
DelDealtData(ReceiveBuffer,ReceiveBufferLength,pos);
if(RCCStatus == RCC_STAT_COMM||RCCStatus == RCC_STAT_DATA)
{ //仅只有在此状态下才接收数据
WORD Crc = GetCrc(FrameHeader.Length,(BYTE *)Data.Data);
if(Data.Crc != Crc) //如果校验值不对
{
#ifdef __RCC_DEBUG__
DisplayMessage("CRC校验不对");
ASSERT(FALSE);
#endif
SendMsgFrame(frmDataAnswer,RESEND);
return 1;
}
int ReceFrameNo=PrevReceFrameNo==255?1:PrevReceFrameNo+1;
if(FrameHeader.FrameNo == PrevReceFrameNo)
{ //如果是上一帧的重发帧,则忽略,发送接收OK
#ifdef __RCC_DEBUG__
DisplayMessage("重发帧");
ASSERT(FALSE);
#endif
SendMsgFrame(frmDataAnswer); //发送终止传输帧
}
else if (FrameHeader.FrameNo == ReceFrameNo)
{ //帧收到
if(FrameHeader.Length + DataBufferLength > DataBufferMaxLength)
{ //应用程序缓冲区不够
LastError = RCC_ERROR_OVERFLOW;
PostRCCMessage(RCC_ERROR,RCC_ERROR_OVERFLOW);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
else
{ //数据收到
int RealLength = *(WORD *)Data.Data;
int UnzippedLength;
FileEncodeDecode encodeObject(Data.Data+2,ZippedBuf,Data.Header.Length-2);
UnzippedLength = encodeObject.Decode(); //赋值压缩后的长度
if(UnzippedLength == -1 || UnzippedLength != RealLength )
{
ASSERT(FALSE);
return 1;
}
memcpy(&DataBuffer[DataBufferLength],ZippedBuf,UnzippedLength);
DataBufferLength += UnzippedLength;
PostRCCMessage(RCC_READ,0);
PrevReceFrameNo = ReceFrameNo;
SendMsgFrame(frmDataAnswer); //发送应答帧
}
}
else
{ //同步丢失
LastError = RCC_ERROR_SYNC;
PostRCCMessage(RCC_ERROR,RCC_ERROR_SYNC);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
}
}
else
{
LastError = RCC_ERROR_FRAME;
PostRCCMessage(RCC_ERROR,RCC_ERROR_FRAME);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
break;
case frmDataAnswer://数据应答帧
DelDealtData(ReceiveBuffer,ReceiveBufferLength,HeaderSize);
if(RCCStatus == RCC_STAT_DATA)
{ //仅只有在数据发送出去时才接收DataAnswer
RCCStatus = RCC_STAT_COMM;
int SendFrameNo = (PrevSendFrameNo==1?255:PrevSendFrameNo - 1);
if(FrameHeader.FrameNo == SendFrameNo)
{ //重发上一帧
SendDataFrame();
}
else if(FrameHeader.FrameNo == PrevSendFrameNo)
{ //如果上一帧接收到了
PostRCCMessage(RCC_RAWWRITE,0); //发送完毕,继续发送下一帧
}
else
{ //帧同步丢失
DisplayMessage("数据帧应答时帧同步丢失");
ASSERT(FALSE);
LastError = RCC_ERROR_SYNC;
PostRCCMessage(RCC_ERROR,RCC_ERROR_SYNC);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
}
else
{ //忽略
}
break;
case frmPolling://检测帧
DelDealtData(ReceiveBuffer,ReceiveBufferLength,HeaderSize);
SendMsgFrame(frmPlAnswer);
break;
case frmPlAnswer://检测应答帧
DelDealtData(ReceiveBuffer,ReceiveBufferLength,HeaderSize);
if(RCCStatus == RCC_STAT_POLLING)
{ //仅只有在检测状态时才接收frmPlAnswer
RCCStatus = RCC_STAT_COMM;
int SendFrameNo = (PrevSendFrameNo==1?255:PrevSendFrameNo - 1);
if(FrameHeader.FrameNo == SendFrameNo)
{ //重发上一帧
SendDataFrame();
}
else if(FrameHeader.FrameNo == PrevSendFrameNo)
{ //如果上一帧接收到了
PostRCCMessage(RCC_RAWWRITE,0); //发送完毕,继续发送下一帧
}
else
{ //帧同步丢失
LastError = RCC_ERROR_SYNC;
PostRCCMessage(RCC_ERROR,RCC_ERROR_SYNC);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
}
else
{ //忽略
}
break;
case frmAbort://异常中止帧
PostRCCMessage(RCC_ERROR,0);
Close();
break;
case frmSysError://系统错误帧
DelDealtData(ReceiveBuffer,ReceiveBufferLength,ReceiveBufferLength);
if(LastFrameClass == 0) //上次什么帧也没有发送
break;
else if(LastFrameClass == 1)
{//数据帧
SendDataFrame();
}
else if(LastFrameClass == 2)
{ //消息帧
SendMsgFrame(RESEND);
}
else
ASSERT(FALSE);
break;
default:
LastError = RCC_ERROR_FRAMETYPE;
PostRCCMessage(RCC_ERROR,RCC_ERROR_FRAMETYPE);
SendMsgFrame(frmAbort); //发送终止传输帧
return 1;
}
return 0;
}
void CRCCComm::OnConnect()
{
DisplayMessage("链接建立");
}
void CRCCComm::OnSend()
{
DisplayMessage("数据空闲,发送下一块");
if(nBytesRead >= FileSize)
{
char Msg[50];
sprintf(Msg,"结束时间:%lu",GetTickCount());
DisplayMessage(Msg);
}
int SendLen = min(FileSize-nBytesRead,8192);
Send(&FileBuf[nBytesRead],SendLen);
nBytesRead += SendLen;
}
void CRCCComm::OnReceive()
{
char Msg[50];
static long num = 0;
sprintf(Msg,"接收到数据",num++);
DisplayMessage(Msg);
//#ifdef __RCC_DEBUG__
char buffer[3000];
int Length = Receive(buffer,3000);
// if(Length > 0)
// {
// buffer[Length] = 0;
// DisplayMessage(buffer);
// }
//#endif
}
void CRCCComm::OnClose()
{
DisplayMessage("链接关闭");
}
void CRCCComm::OnError()
{
DisplayMessage("发生错误");
}
void CRCCComm::OnBinaryState(DWORD State)
{
DWORD ModemStatus;
if(State & MDM_CONN)
{
if(GetCommModemStatus(hCommFile,&ModemStatus))
{
if (!(ModemStatus & MS_RLSD_ON ))
{
Close();
}
else if ( (ModemStatus & MS_RLSD_ON) && (RCCMode == MODE_RS232))
{
RCCStatus = RCC_STAT_COMM;
PostRCCMessage(RCC_CONNECT,0);
}
}
}
}
void CRCCComm::OnStringState(DWORD State)
{
if(State & MDM_CONN)
{
RCCStatus = RCC_STAT_COMM;
PostRCCMessage(RCC_CONNECT,0);
}
}
//MODEM返回字符串
char MDMAnswerStr[][20] =
{
"OK",
"NO CARRIER",
"ERROR",
"NO DIAL",
"BUSY",
"NO ANSWER",
"RING",
"CONNECT",
"PROTOCOL:",
"COMPRESSION:",
"CARRIER"
};
//
// 函数: int CRCCComm::ParseAnswer(LPSTR AnswerString,DWORD dwLength)
// 用途: 分解命令状态下MODEM返回的字符串的含义
// 参数: 无
// 返回值:
// 0 分解成功
// 1 分解失败
// 备注:
//
//
int CRCCComm::ParseAnswer(LPSTR AnswerString,DWORD dwLength)
{
DWORD MDMStatus = MDM_UNKOWN;
LPSTR pStr;
char tmpStr[40];
int i,j;
for ( i=0; i<MDMAnswerNum; i++)
{
if(pStr = strstr(AnswerString,MDMAnswerStr[i]))
break;
}
if ( i == MDMAnswerNum )
{
PostRCCMessage(RCC_STR_STATE,MDMStatus);
return 1;
}
switch(i)
{
case 0: //"OK"
MDMStatus = MDM_OK;
break;
case 1: // "NO CARRIER"
MDMStatus = MDM_DCD;
break;
case 2: // "ERROR"
MDMStatus = MDM_CMDERR;
break;
case 3: // "NO DIAL"
MDMStatus = MDM_NOTONE;
break;
case 4: // "BUSY"
MDMStatus = MDM_BUSY;
break;
case 5: //"NO ANSWER";
MDMStatus = MDM_NOANSW;
break;
case 6: //"RING"
MDMStatus = MDM_RING;
break;
case 7: //"CONNECT"
MDMStatus = MDM_CONN;
//继续分析以下三条语句
pStr += strlen(MDMAnswerStr[i]);
while(*pStr == ' ')
pStr ++;
j=0;
for(j=0;*pStr != 0x0D && *pStr != 0x0A && j<30;j++)
{
tmpStr[j] = *pStr;
pStr ++;
}
tmpStr[j]=0;
MDMConnect = atoi(tmpStr);
if(pStr = strstr(AnswerString,"PROTOCOL:"))
{
pStr += strlen("PROTOCOL:");
while(*pStr == ' ')
pStr ++;
j=0;
for(j=0;*pStr != 0x0D && *pStr != 0x0A && j<30;j++)
{
tmpStr[j] = *pStr;
pStr ++;
}
tmpStr[j]=0;
strcpy(MDMProtocol,tmpStr);
MDMStatus |= MDM_PROT;
}
if(pStr = strstr(AnswerString,"COMPRESSION:"))
{
pStr += strlen("COMPRESSION:");
while(*pStr == ' ')
pStr ++;
j=0;
for(j=0;*pStr != 0x0D && *pStr != 0x0A && j<30;j++)
{
tmpStr[j] = *pStr;
pStr ++;
}
tmpStr[j]=0;
strcpy(MDMProtocol,tmpStr);
MDMStatus |= MDM_COMP;
}
if(pStr = strstr(AnswerString,"CARRIER"))
{
pStr += strlen("CARRIER");
while(*pStr == ' ')
pStr ++;
j=0;
for(j=0;*pStr != 0x0D && *pStr != 0x0A && j<30;j++)
{
tmpStr[j] = *pStr;
pStr ++;
}
tmpStr[j]=0;
MDMCarrier = atoi(tmpStr);
MDMStatus |= MDM_CARRIER;
}
break;
case 8: //"PROTOCOL:"
MDMStatus = MDM_PROT;
break;
case 9: //"COMPRESSION:"
MDMStatus = MDM_COMP;
break;
case 10: //"CARRIER"
MDMStatus = MDM_CARRIER;
break;
}
MDMResult = MDMStatus;
PostRCCMessage(RCC_STR_STATE,MDMStatus);
return 0;
}
//
// 函数: BOOL CRCCComm::SetCommState(LPDCB lpDCB)
// 用途: 设置串口状态
// 参数:
// lpDCB 串口通讯参数结构
// 返回值:
// TRUE 设置成功
// FALSE 设置失败
// 备注:
//
BOOL CRCCComm::SetCommState(LPDCB lpDCB) //设置串口状态
{
DCB dcb;
char dcbStr[100];
sprintf( dcbStr, "\\\\.\\COM%d: baud=%lu parity=N data=8 stop=1",
CommNo,BaudRate) ;
::GetCommState( hCommFile, &dcb );
::BuildCommDCB( dcbStr,&dcb);
dcb.fNull = 0; //将NULL字符当普通字符传送
dcb.fOutxCtsFlow = 1; //采用硬件流控制
dcb.fOutxDsrFlow = 1;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fDsrSensitivity = 1;
dcb.fTXContinueOnXoff = 1;
dcb.fErrorChar = 0;
dcb.fAbortOnError = 0;
dcb.fDummy2 = 0;
dcb.wReserved = 0;
dcb.XonLim = 65535;
dcb.XoffLim = 65535;
dcb.XonChar = 17;
dcb.XoffChar = 19;
dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;
dcb.wReserved1 = 0;
// dcb.fOutX=0;
return ::SetCommState( hCommFile, &dcb);
}
BOOL CRCCComm::GetCommState(LPDCB lpDCB) //得到串口的当前设置状态
{
return ::GetCommState(hCommFile,lpDCB);
}
//在进入本函数之前,一定要将MDMResult变量设置为MDM_NONE
//等待MODEM命令串的返回,返回类似MDM_OK
int CRCCComm::WaitForCommandResult(DWORD TimeOut)
{
int OldRCCStatus = RCCStatus;
RCCStatus = RCC_STAT_INIT; //步入初始化状态,等待返回
DWORD CurTickCou
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -