📄 cmpp.cpp
字号:
// CMPP.cpp: implementation of the CCMPP class.
//
//////////////////////////////////////////////////////////////////////
#include "CMPP.h"
#include <stdio.h>
//#include <windows.h>
//#include <AFXPRIV.H>
//#include <Oleauto.h>
//#include <Dispatch.h>
//#include <comdef.h>
#include <atlbase.h>
//#include <objbase.h>
#include "Md5.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
bool g_bQueryResult = FALSE;
bool g_bDeliver = FALSE;
bool g_bReport = FALSE;
CCMPP::CCMPP()
{
m_bIsInit = false;
m_bIsBinded = false;
m_bIsBinding = false;
m_bIsEnableRun = false;
m_bIsSendRun = false;
m_bIsRecvRun = false;
m_bIsUnbind = false;
m_dwSequenceNO = 0;
m_dwLastTime4TCPErr = 0;
m_dwSubmitNum = 0;
m_dwLastErr4TCP = 0;
m_dwSubmitRespFailNum = 0;
m_dwSubmitRespOKNum = 0;
m_dwCurErr4TCP = 0;
m_dwLastErr4Sys = 0;
m_bRegDeliveryFlag = 0;
m_bPriority = 0;
m_bFeeUserType = 0;
m_bTPpid = 0;
m_bTPudhi = 0;
m_BMsgContent[0] = 0;
m_dwSendTime = -1;
m_dwRespTime = -1;
m_lBufIdx4MulSM = -1;
m_lSendMaxNumPerPk = 1;
m_lTimeout4Connect = 10000000;
m_lSendIntervalTime = 1000000;
m_lTimeout4Recv = 10000;
m_lPauseTime4Recv = 10000;
m_lPauseTime4Stop = 3000000;
m_lTimeout4Resp = 30000000;
m_dwSMCID = 290500;
m_szServiceType[0] = 0;
m_szExpireTime[0] = 0;
m_szScheduleTime[0] = 0;
m_szFeeMobileID[0] = 0;
m_szMobileIDFix[0] = '\0';
m_szMobileID[0] = 0;
m_bMsgCoding = 15;
m_bVersion = 0x20;
m_hEvent4Socket = WSACreateEvent();
m_hEvent4SaveBuf = WSACreateEvent();
strcpy(m_szSPID, "926062");
strcpy(m_szSPNum, "01255");
strcpy(m_szFeeType, "01");
strcpy(m_szFeeValue, "0");
BZERO(m_sSMBuf);
}
CCMPP::~CCMPP()
{
}
DWORD WINAPI ThreadCMPPSend(LPVOID lpPara)
{
CCMPP *pcCmpp = (CCMPP*)lpPara;
DWORD dwRet, dwIndex, dwCounter;
fd_set sFDS4Write;
FD_ZERO(&sFDS4Write);
pcCmpp->m_bIsSendRun = true;
while(pcCmpp->m_bIsEnableRun)
{
dwCounter = GetTickCount();
for(dwIndex = 0; dwIndex < MAX_BUF_SIZE; dwIndex++)
{
if(pcCmpp->m_sSMBuf[dwIndex].bFlag == BUF_SENDED
&&
(((unsigned long)(dwCounter - pcCmpp->m_sSMBuf[dwIndex].dwTickCount))
>
((unsigned long)(abs(pcCmpp->m_lTimeout4Resp) / 1000))))
{
if(pcCmpp->m_lTimeout4Resp > 0)
pcCmpp->m_sSMBuf[dwIndex].bFlag++;
else
{
pcCmpp->m_sSMBuf[dwIndex].bFlag = BUF_VALID;
}
}
if(pcCmpp->m_sSMBuf[dwIndex].bFlag >= BUF_RETRY)// >=
{
if(pcCmpp->m_sSMBuf[dwIndex].bFlag - BUF_RETRY >= 3)
{
pcCmpp->m_sSMBuf[dwIndex].bFlag = BUF_VALID;
}
else
{
pcCmpp->m_sSMBuf[dwIndex].bFlag++;
if(pcCmpp->m_sSMBuf[dwIndex].bFlag == BUF_READY)
break;
}
}
}
//@@运行到这里已经找到了一个Ready的信息,或找到了一个Retry次数在4以内的信息(如果大于4次将被抛弃),是第dwIndex号
//填充CMPP信息
SYSTEMTIME sSystemTime;
GetLocalTime(&sSystemTime);
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.sMsgHead.Total_Length =
htonl(sizeof(_CMPP_HEAD) + sizeof(_CMPP_SUBMIT) -
(long)(MAX_LEN_MOBILE_ID + 1) * MAX_DEST_USR - MAX_LEN_CONTENT +
(long)(MAX_LEN_MOBILE_ID + 1) *
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg
.uMsgBody.sMsgSubmit.DestUsr_tl +
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg
.uMsgBody.sMsgSubmit.Msg_Length);
if(pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.uMsgBody
.sMsgSubmit.DestUsr_tl < MAX_DEST_USR)
{
memcpy(pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.uMsgBody
.sMsgSubmit.Dest_terminal_id +
(long)(MAX_LEN_MOBILE_ID + 1) *
pcCmpp->m_sSMBuf[dwIndex]
.sCmppMsg.uMsgBody.sMsgSubmit.DestUsr_tl,
&pcCmpp->m_sSMBuf[dwIndex]
.sCmppMsg.uMsgBody.sMsgSubmit.Msg_Length,
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.uMsgBody.
sMsgSubmit.Msg_Length + 9);
}
memcpy(pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.uMsgBody
.sMsgSubmit.Dest_terminal_id +
(long)(MAX_LEN_MOBILE_ID + 1) *
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg
.uMsgBody.sMsgSubmit.DestUsr_tl + 1 +
pcCmpp->m_sSMBuf[dwIndex].sCmppMsg
.uMsgBody.sMsgSubmit.Msg_Length,
pcCmpp->m_szReserve,
strlen(pcCmpp->m_szReserve));
while(pcCmpp->m_bIsBinding);
FD_SET(pcCmpp->m_sSocket4MT, &sFDS4Write);
dwRet = select(0, NULL, &sFDS4Write, NULL, NULL);
if(dwRet == SOCKET_ERROR)
{
goto SEND_EXIT;
}
if(dwRet == 0 || !FD_ISSET(pcCmpp->m_sSocket4MT, &sFDS4Write))
{
goto SEND_EXIT;
}
WSASetEvent(pcCmpp->m_hEvent4Socket);
dwRet = send(pcCmpp->m_sSocket4MT, (char *)&(pcCmpp->m_sSMBuf[dwIndex]
.sCmppMsg),
ntohl(pcCmpp->m_sSMBuf[dwIndex]
.sCmppMsg.sMsgHead.Total_Length),
0);
WSAResetEvent(pcCmpp->m_hEvent4Socket);
if(dwRet == SOCKET_ERROR)
{
goto SEND_EXIT;
}
if(dwRet != ntohl(pcCmpp->m_sSMBuf[dwIndex].sCmppMsg.sMsgHead.Total_Length))
{
goto SEND_EXIT;
}
pcCmpp->m_dwSubmitNum++;
pcCmpp->m_sSMBuf[dwIndex].dwTickCount = GetTickCount();
if(pcCmpp->m_sSMBuf[dwIndex].bFlag == BUF_READY)
{
pcCmpp->m_sSMBuf[dwIndex].bFlag = BUF_SENDED;
}
pcCmpp->m_dwSendTime = GetTickCount() - dwCounter;
if(pcCmpp->m_lSendIntervalTime)Sleep(pcCmpp->m_lSendIntervalTime / 1000);
}
pcCmpp->m_bIsSendRun = false;
ATLTRACE("Send退出!\n");
return 0;
SEND_EXIT:
pcCmpp->m_bIsSendRun = false;
pcCmpp->Stop();
ATLTRACE("Send退出!\n");
return 0;
}
long CCMPP::Stop()
{
if(m_bIsBinded)
{
m_bIsEnableRun = false;
Sleep(m_lPauseTime4Stop / 1000);
while(m_bIsSendRun || m_bIsRecvRun)
{
Sleep(m_lPauseTime4Stop / 1000);
}
closesocket(m_sSocket4MT);
m_bIsBinded = false;
}
return 0;
}
DWORD WINAPI ThreadCMPPRecv(LPVOID lpPara)
{
USES_CONVERSION;
CCMPP *pcCmpp = (CCMPP*)lpPara;
BSTR bStrMobileID, bStrSPID;
VARIANT MsgContent;
DWORD dwRet;/*收到的数据包的总长(模拟对象)*/
DWORD dwRetMulti; //包含多个子数据包的包的长度
_CMPP sCmppMsg;/*收到的单数据包内容(模拟对象)*/
_CMPP sCmppMsg4Resp;
BYTE pRecvMulti[sizeof(_CMPP)]; //包含多个子数据包的数据包内容
fd_set sFDS4Read;
FD_ZERO(&sFDS4Read);
fd_set sFDS4Write;
FD_ZERO(&sFDS4Write);
timeval sTimeval4Timeout;
pcCmpp->m_bIsRecvRun = true;
while(pcCmpp->m_bIsEnableRun)
{
sTimeval4Timeout.tv_sec = pcCmpp->m_lTimeout4Recv / 1000000;
sTimeval4Timeout.tv_usec = pcCmpp->m_lTimeout4Recv % 1000000;
while(pcCmpp->m_bIsBinding);
FD_SET(pcCmpp->m_sSocket4MT, &sFDS4Read);
dwRet = select(0, &sFDS4Read, NULL, NULL, &sTimeval4Timeout);
if(dwRet == SOCKET_ERROR)
{
goto RECV_EXIT;
}
if(dwRet == 0)
{
Sleep(pcCmpp->m_lPauseTime4Recv / 1000);
continue;
}
WSASetEvent(pcCmpp->m_hEvent4Socket);
dwRetMulti = recv(pcCmpp->m_sSocket4MT, (char *)pRecvMulti, sizeof(_CMPP), 0);
WSAResetEvent(pcCmpp->m_hEvent4Socket);
if(dwRetMulti == SOCKET_ERROR || !dwRetMulti)
{
goto RECV_EXIT;
}
DWORD dwCurMulti = 0;//当前的pRecvMulti的位置
while(dwCurMulti < dwRetMulti)
{
dwRet = ntohl(((_CMPP_HEAD*)(pRecvMulti + dwCurMulti))->Total_Length);//dwRet
memcpy(&sCmppMsg, pRecvMulti + dwCurMulti, sizeof(_CMPP)); //sCmppMsg
dwCurMulti += dwRet;
SYSTEMTIME sSysTime4Local;
GetLocalTime(&sSysTime4Local);
DWORD dwTime = sSysTime4Local.wMonth * 100000000 +
sSysTime4Local.wDay * 1000000 +
sSysTime4Local.wHour * 10000 +
sSysTime4Local.wMinute * 100 +
sSysTime4Local.wSecond;
switch(ntohl(sCmppMsg.sMsgHead.Command_ID))
{
case CMPP_SUBMIT_REP:
pcCmpp->m_dwCurErr4TCP =
sCmppMsg.uMsgBody.sMsgSubmitRep.bResult;
if(ntohl(sCmppMsg.sMsgHead.Total_Length) ==
sizeof(_CMPP_HEAD) + sizeof(_CMPP_SUBMIT_REP) &&
dwRet == sizeof(_CMPP_HEAD) + sizeof(_CMPP_SUBMIT_REP))
{//确保从网关发过来的数据正确
for(dwRet = 0; dwRet < MAX_BUF_SIZE; dwRet++)
{
if(pcCmpp->m_sSMBuf[dwRet].sCmppMsg.sMsgHead.Sequence_ID ==
sCmppMsg.sMsgHead.Sequence_ID)
{
pcCmpp->m_dwRespTime = GetTickCount() -
pcCmpp->m_sSMBuf[dwRet].dwTickCount;
if(sCmppMsg.uMsgBody.sMsgSubmitRep.bResult)
{
pcCmpp->m_sSMBuf[dwRet].bFlag++;
pcCmpp->m_dwLastErr4TCP = sCmppMsg.uMsgBody
.sMsgSubmitRep.bResult;
pcCmpp->m_dwLastTime4TCPErr = dwTime;
pcCmpp->m_dwSubmitRespFailNum++;
}else
{
pcCmpp->m_sSMBuf[dwRet].bFlag = BUF_VALID;
pcCmpp->m_dwSubmitRespOKNum++;
}
break;
}
}
}
break;
case CMPP_ACTIVE_REP:
pcCmpp->m_dwCurErr4TCP = sCmppMsg.uMsgBody
.sMsgActiveRep.Success_Id;
if(ntohl(sCmppMsg.sMsgHead.Total_Length) == sizeof(_CMPP_HEAD)
+ sizeof(_CMPP_ACTIVE_REP) &&
dwRet == sizeof(_CMPP_HEAD) + sizeof(_CMPP_ACTIVE_REP))
{
if(sCmppMsg.uMsgBody.sMsgActiveRep.Success_Id)
{
goto RECV_EXIT;
}
}
break;
case CMPP_ACTIVE:
break;
case CMPP_QUERY_REP:
if(ntohl(sCmppMsg.sMsgHead.Total_Length) ==
sizeof(_CMPP_HEAD) + sizeof(_CMPP_QUERY_REP) &&
dwRet == sizeof(_CMPP_HEAD) + sizeof(_CMPP_QUERY_REP))
{//确保从网关发过来的数据正确
g_bQueryResult = TRUE;
}
break;
case CMPP_DELIVER:
if(ntohl(sCmppMsg.sMsgHead.Total_Length) == dwRet)
{//确保从网关发过来的数据正确
DWORD i;
bStrMobileID = A2BSTR(sCmppMsg.uMsgBody.sMsgDeliver
.Src_terminal_id);
VariantInit(&MsgContent);
switch(sCmppMsg.uMsgBody.sMsgDeliver.Msg_Fmt)
{
case 3:
case 4:
MsgContent.vt = VT_UI1 | VT_ARRAY;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = ntohl(sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length);
MsgContent.parray = SafeArrayCreate(VT_UI1, 1, rgsabound);
if(!MsgContent.parray)goto RECV_EXIT;
SafeArrayLock(MsgContent.parray);
for(i = 0;
i < ntohl(sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length);
i++)
((BYTE *)(MsgContent.parray->pvData))[i] =
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content[i];
SafeArrayUnlock(MsgContent.parray);
break;
case 8:
{
char szDestinationData[MAX_LEN_CONTENT + 1];
long lBytesDestination = 0;
long lBytesNeeded, lWCharSource;
BOOL bUsedDefaultChar = FALSE;
lWCharSource = sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length / 2;
for(i = 0; i < ((DWORD)lWCharSource) * 2; i += 2)
{
szDestinationData[0] =
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content[i];
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content[i] =
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content[i+1];
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content[i+1] =
szDestinationData[0];
}
lBytesNeeded = WideCharToMultiByte(936, 0,
(LPWSTR)sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content,
lWCharSource,
NULL, 0,
"?", &bUsedDefaultChar);
lBytesDestination = WideCharToMultiByte(936, 0,
(LPWSTR)sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content,
lWCharSource,
szDestinationData, lBytesNeeded,
"?", &bUsedDefaultChar);
*(LPSTR)((LPSTR)szDestinationData + lBytesNeeded) = '\0';
MsgContent.vt = VT_BSTR;
MsgContent.bstrVal = A2BSTR(szDestinationData);
}
break;
default:
{
char szMessagContent[MAX_LEN_CONTENT + 1];
memcpy(szMessagContent,
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content,
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length);
szMessagContent[sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length] = '\0';
MsgContent.vt = VT_BSTR;
MsgContent.bstrVal = A2BSTR(szMessagContent);
}
}
bStrSPID = A2BSTR(sCmppMsg.uMsgBody.sMsgDeliver.Dest_terminal_id);
char szReserved[9];
memcpy(szReserved,
sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content
+ sCmppMsg.uMsgBody.sMsgDeliver.Msg_Length,
8);
szReserved[8] = '\0';//做截尾符
BSTR bstrReserved = A2W(szReserved);//转换成UNICODE
if(sCmppMsg.uMsgBody.sMsgDeliver.Reg_Delivery == 0)
{//当是“非状态报告”时才激发事件
g_bDeliver = TRUE;
}else
{//是状态报告,激发Report事件
//做参数
char szStat[8];
memcpy(szStat,
((_CMPP_DELIVER_MSGCONTENT_REPROT*)
(sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content))->szStat,
7);
szStat[7] = '\0';
char szSubmit_time[11];
memcpy(szSubmit_time,
((_CMPP_DELIVER_MSGCONTENT_REPROT*)
(sCmppMsg.uMsgBody.sMsgDeliver.Msg_Content))->
szSubmit_time, 10);
szSubmit_time[10] = '\0';
char szDone_time[11];
memcpy(szDone_time,
((_CMPP_DELIVER_MSGCONTENT_REPROT*)
(sCmppMsg.uMsgBody.sMsgDeliver
.Msg_Content))->szDone_time, 10);
szDone_time[10] = '\0';
char szDest_terminal_Id[22];
memcpy(szDest_terminal_Id,
((_CMPP_DELIVER_MSGCONTENT_REPROT*)
(sCmppMsg.uMsgBody.sMsgDeliver
.Msg_Content))->szDest_terminal_Id, 21);
szDest_terminal_Id[21] = '\0';
g_bReport = TRUE;
}
BZERO(sCmppMsg4Resp);
sCmppMsg4Resp.sMsgHead.Total_Length =
htonl(sizeof(_CMPP_HEAD) + sizeof(_CMPP_DELIVER_REP));
sCmppMsg4Resp.sMsgHead.Command_ID = htonl(CMPP_DELIVER_REP);
sCmppMsg4Resp.sMsgHead.Sequence_ID =
sCmppMsg.sMsgHead.Sequence_ID;
memcpy(&sCmppMsg4Resp.uMsgBody.sMsgDeliverRep.Msg_id,
&sCmppMsg.uMsgBody.sMsgDeliverRep.Msg_id, sizeof(_CMPP_ID));
FD_SET(pcCmpp->m_sSocket4MT, &sFDS4Write);
dwRet = select(0, NULL, &sFDS4Write, NULL, NULL);
if(dwRet == SOCKET_ERROR)
{
pcCmpp->m_dwLastErr4Sys = GetLastError();
goto RECV_EXIT;
}
if(dwRet == 0 || !FD_ISSET(pcCmpp->m_sSocket4MT, &sFDS4Write))
{
goto RECV_EXIT;
}
WSASetEvent(pcCmpp->m_hEvent4Socket);
dwRet = send(pcCmpp->m_sSocket4MT, (char *)&sCmppMsg4Resp,
ntohl(sCmppMsg4Resp.sMsgHead.Total_Length), 0);
WSAResetEvent(pcCmpp->m_hEvent4Socket);
if(dwRet == SOCKET_ERROR)
{
pcCmpp->m_dwLastErr4Sys = GetLastError();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -