📄 cmpppdu.cpp
字号:
// CmppPdu.cpp: implementation of the CCmppPdu class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cmpp.h"
#include "CmppPdu.h"
#include "md5.h"
#include "MailCoder.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern char CMPP_LOG_FILE[100];
CCmppPdu::CCmppPdu()
{
}
CCmppPdu::~CCmppPdu()
{
}
BOOL IsDigital(char cSrc)
{
if((cSrc>='0')&&(cSrc<='9'))
return true;
else
return false;
}
CString TrimStr(CString strSrc)
{
strSrc.TrimLeft();
strSrc.TrimRight();
return strSrc;
}
int ReceivePdu(CTcpAsyncSocket* pstSocket,char *szRecvBuf,int nMaxLen)
{
int nBytesThisTime;
time_t stOldTime = time(NULL);
time_t stCurTime;
int nLen = pstSocket->Receive(szRecvBuf,4);
if(nLen < 0)
return -1;
if(nLen <4 )
return 0;
int nPduLen=ntohl(*((int*)szRecvBuf));
if(nPduLen > nMaxLen)
return 0;
while (nLen<nPduLen)
{
nBytesThisTime = pstSocket->Receive(szRecvBuf+nLen,nPduLen-nLen);
if(nBytesThisTime <0)
return 0;
nLen+=nBytesThisTime;
stCurTime = time(NULL);
if(abs(difftime(stCurTime,stOldTime)) >1)
return 0;
}
return nPduLen;
}
void GetStatusMessage(int commandid,unsigned long status,char * szMessage)
{
if(commandid == CMPP_CONNECT_RESP)
{
switch(status)
{
case 0:
strcpy(szMessage,"[连接认证]成功");
break;
case 1:
strcpy(szMessage,"[连接认证]消息结构错");
break;
case 2:
strcpy(szMessage,"[连接认证]非法源地址");
break;
case 3:
strcpy(szMessage,"[连接认证]认证错");
break;
case 4:
strcpy(szMessage,"[连接认证]版本太高");
break;
case 5:
strcpy(szMessage,"[连接认证]其他错误");
break;
default:
printf("连接应答");
printf("%d",status);
char buffer[20];
itoa(status,buffer,10);
strcpy(szMessage,buffer);
}
}
if(commandid == CMPP_SUBMIT_RESP)
{
switch(status)
{
case 0:
strcpy(szMessage,"[发送短信]成功");
break;
case 1:
strcpy(szMessage,"[发送短信]消息结构错");
break;
case 2:
strcpy(szMessage,"[发送短信]命令字错");
break;
case 3:
strcpy(szMessage,"[发送短信]消息序号重复");
break;
case 4:
strcpy(szMessage,"[发送短信]消息长度错");
break;
case 5:
strcpy(szMessage,"[发送短信]资费代码错");
break;
case 6:
strcpy(szMessage,"[发送短信]超过最大信息长");
break;
case 7:
strcpy(szMessage,"[发送短信]业务代码错");
break;
case 8:
strcpy(szMessage,"[发送短信]流量控制错");
break;
case 9:
strcpy(szMessage,"[发送短信]本网关不负责服务此计费号码");
break;
case 10:
strcpy(szMessage,"[发送短信]Src_Id错误");
break;
case 11:
strcpy(szMessage,"[发送短信]Msg_src错误");
break;
case 12:
strcpy(szMessage,"[发送短信]Fee_terminal_Id错误");
break;
case 13:
strcpy(szMessage,"[发送短信]Dest_terminal_Id错误");
break;
default:
printf("submit应答");
printf("%d",status);
char buffer[20];
itoa(status,buffer,10);
strcpy(szMessage,buffer);
}
}
}
int UnicodeToAnsi(char *szSourceCode, int nSourceLen, char *szDestCode)
{
int size;
unsigned short* pSrc=(unsigned short*)szSourceCode;
unsigned short* p=pSrc;
BYTE cchUnicode=nSourceLen/sizeof(wchar_t);
//first network byte order to host byte order
for (int i=0;i<cchUnicode;i++)
{
*p=ntohs(*p);
p++;
}
//then unicode to mbcs code,that we normally use
size=::WideCharToMultiByte(936,0,(wchar_t*)pSrc,cchUnicode,NULL,0,NULL,NULL);
::WideCharToMultiByte(936,0,(wchar_t*)pSrc,cchUnicode,szDestCode,size,NULL,NULL);
szDestCode[size]='\0';
return size;
}
BOOL IncludeChinese(CString strMsg)
{
int iStrLength = strMsg.GetLength();
char *m_newBuffer = new char [iStrLength];
LPSTR newTempPtr = m_newBuffer;
BOOL bIncludeChinese = false;
unsigned short halfChinese=0;
int iNumOfWords = 0;
int iPos=0;
while( iPos<iStrLength ){
*newTempPtr = strMsg.GetAt(iPos);
if((unsigned char)*newTempPtr >= 0xa1){//大于0xa1的字节为汉字字节
bIncludeChinese = true ;
break;
}
iPos++;
}
delete m_newBuffer;
return bIncludeChinese;
}
void LogFile(const char* szMsg)
{
FILE* fp;
CTime stTime=CTime::GetCurrentTime();
fp = fopen(CMPP_LOG_FILE,"a+");
fprintf(fp,"[%d-%d %d:%d:%d]%s\n",stTime.GetMonth(),stTime.GetDay(),stTime.GetHour(),stTime.GetMinute(),stTime.GetSecond(),szMsg);
fclose(fp);
}
void CCmppPdu::ConnectSvr(const char *szLoginName, const char *szLoginPassword)
{
SCmppConnect stConnect;
m_nTotalLen = PDU_HEADER_SIZE + sizeof(SCmppConnect);
PacketHeader(CMPP_CONNECT,m_nTotalLen);
int nTime;
char szTime[20];
CTime stCurTime;
stCurTime = CTime::GetCurrentTime();
sprintf(szTime,"%02d%02d%02d%02d%02d",stCurTime.GetMonth(),stCurTime.GetDay(),
stCurTime.GetHour(),stCurTime.GetMinute(),stCurTime.GetSecond());
szTime[10] = '\0';
nTime = atol(szTime);
memset(&stConnect,'\0',sizeof(SCmppConnect));
strcpy(stConnect.sSource_Addr,szLoginName);
int i= 0;
char sAuSource[32];
memset(sAuSource,'\0',sizeof(sAuSource));
i = strlen(szLoginName);
memcpy(sAuSource,szLoginName,i);
i += 9;
int len;
len= strlen(szLoginPassword);
memcpy(sAuSource+i,szLoginPassword,len);
i += len;
memcpy(sAuSource+i,szTime,strlen(szTime));
i+=10;
MD5_CTX md5T;
unsigned char ucDigest[16];
md5T.MD5Update ((unsigned char *)sAuSource,i);
md5T.MD5Final (ucDigest);
memcpy(stConnect.sAuthenticatorSource,(unsigned char *)ucDigest,16);
stConnect.chVersion = 0x20;
stConnect.iTimestamp = htonl(nTime);
memcpy(m_szBuffer + PDU_HEADER_SIZE ,&stConnect,sizeof(SCmppConnect));
}
void CCmppPdu::PacketHeader(int nCommandId, int nTotalLen)
{
SCmppPduHeader stHeader;
memset(m_szBuffer,'\0',MAX_PACKET_SIZE);
memset(&stHeader,'\0',PDU_HEADER_SIZE);
stHeader.iTotal_Length = htonl(nTotalLen);
stHeader.iCommand_Id = htonl(nCommandId);
stHeader.iSequence_Id = htonl(m_nSequenceNumber);
if ( m_nSequenceNumber != 0xffffffff )
m_nSequenceNumber ++;
else // Reset Serial Number
m_nSequenceNumber = 0;
memcpy(m_szBuffer,&stHeader,PDU_HEADER_SIZE);
}
unsigned char * CCmppPdu::GetBuffer()
{
return (unsigned char*)m_szBuffer;
}
int CCmppPdu::GetLen()
{
return m_nTotalLen;
}
void CCmppPdu::GetHeaderInfo(const char *szBuf, int &nCommandID, int &nSequence)
{
SCmppPduHeader *pstHeader;
pstHeader =(SCmppPduHeader *)szBuf;
nCommandID = ntohl(pstHeader->iCommand_Id);
nSequence = ntohl(pstHeader->iSequence_Id);
}
char CCmppPdu::GetConnectResult(const char *szBuf)
{
SCmppConnectResp stConnectResp;
memcpy(&stConnectResp,szBuf +PDU_HEADER_SIZE,sizeof(SCmppConnectResp));
return ntohl(stConnectResp.iStatus);
}
void CCmppPdu::DeliverResp(const char *szBuf, const char *szMsgID,int result)
{
SCmppDeliverResp stDeliverResp;
m_nTotalLen = PDU_HEADER_SIZE + sizeof(SCmppDeliverResp);
PacketRespHeader(szBuf,CMPP_DELIVER_RESP,m_nTotalLen);
memset(&stDeliverResp,'\0',sizeof(SCmppDeliverResp));
strncpy((char *)stDeliverResp.szMsg_Id,szMsgID,8);
stDeliverResp.iResult = htonl(result);
memcpy(m_szBuffer + PDU_HEADER_SIZE ,&stDeliverResp,sizeof(SCmppDeliverResp));
}
void CCmppPdu::PacketRespHeader(const char *szBuf, int nCommandId, int nTotalLen)
{
SCmppPduHeader *pstHeader;
pstHeader =(SCmppPduHeader *)szBuf;
memset(m_szBuffer,'\0',MAX_PACKET_SIZE);
pstHeader->iTotal_Length = htonl(nTotalLen);
pstHeader->iCommand_Id = htonl(nCommandId);
memcpy(m_szBuffer,pstHeader,PDU_HEADER_SIZE);
}
void CCmppPdu::SubmitSingle(const char* szUserNumber,const char* szMessageContent,const char* szChargeNumber,
const char* szSender,const char* szServiceType,const char* szLinkID,char cFeeType,const char *szFeeValue,const char* szGivenValue,
const char* szScheduleTime,char cMessageCoding,char cMOrelatetoMTFlag,int iReportFlag,int iPriority,int iTP_pid,int iTP_udhi,int iExpireTimeSpan,int mobiletype,int feenumtype)
{
//短消息
SCmppSubmit stSubmit;
m_nTotalLen = PDU_HEADER_SIZE + sizeof(SCmppSubmit) + strlen(szMessageContent) - MAX_MESSAGE_LENGTH ;
PacketHeader(CMPP_SUBMIT,m_nTotalLen);
memset(&stSubmit,'\0',sizeof(SCmppSubmit));
stSubmit.ucPkTotal =1;
stSubmit.ucPkNumber =1;
if(iReportFlag == 1)
stSubmit.ucRegistered_Delivery = 1;
else if(iReportFlag == 3)
stSubmit.ucRegistered_Delivery = 2;
else
stSubmit.ucRegistered_Delivery = 0;
//luming mod 20050429
iPriority = abs(iPriority -9);
if(iPriority > 9)
iPriority = 9;
stSubmit.ucMsg_level = iPriority;
strncpy(stSubmit.sServiceId,szServiceType,10); //业务代码
stSubmit.cFee_UserType = feenumtype;//变通的做法
//stSubmit.cFee_UserType =3;
//luming mod 2004-0321
strncpy(stSubmit.szFee_terminal_Id,szChargeNumber,21); //付费号码
// memcpy(stSubmit.szFee_terminal_Id,WEIMA,32);
// stSubmit.cFee_terminal_type = 0;
// stSubmit.cFee_terminal_type = feenumtype;
stSubmit.cTP_pid = iTP_pid; //GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9
stSubmit.cTP_udhi = iTP_udhi; //GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
stSubmit.cMsg_Fmt = cMessageCoding;
strncpy(stSubmit.szMsg_src,m_strCorpId,6); //企业代码(0-99999)
char feetype[2];
feetype[1]='\0';
itoa(cFeeType,feetype,10);
strcpy(stSubmit.cFeeType,"0");
strcat(stSubmit.cFeeType,feetype); //计费类型
strncpy(stSubmit.szFeeCode,szFeeValue,6); //该条短消息的收费值,单位为分,由SP定义,对于包月制收费的用户,该值为月租费的值(范围0-99999)
if( iExpireTimeSpan > 0 )
{
CTime tCurTime ;
tCurTime = CTime::GetCurrentTime() ;
CTime t ;
CTimeSpan ts( iExpireTimeSpan ); // seconds
t = tCurTime + ts ;
char szTime[20] ;
int iYear = t.GetYear() %100 ;
sprintf(szTime,"%02d%02d%02d%02d%02d%02d032+",
iYear,t.GetMonth(),t.GetDay(),t.GetHour(),t.GetMinute(),t.GetSecond() );
strncpy(stSubmit.szExpireTime,szTime,16); //短消息寿命的终止时间,如果为空,表示使用短消息中心的缺省值。 //时间内容为16个字符,格式为"yymmddhhmmsstnnp" ,其中"tnnp"取固定值"032+",即默认系统为北京时间
}
//------------------------------------------------------------------------------
if(szScheduleTime != NULL && strlen(szScheduleTime)>0)
{
char szTime[20];
sprintf(szTime,"%s032+",szScheduleTime);
strncpy(stSubmit.szScheduleTime,szTime,16); //短消息定时发送的时间,如果为空,表示立刻发送该短消息。时间内容为16个字符,格式为"yymmddhhmmsstnnp" ,其中"tnnp"取固定值"032+",即默认系统为北京时间
}
stSubmit.cDestUsr_tl = 1; //接收短消息的手机数量(1--100)
strncpy(stSubmit.szDest_terminal_Id,szUserNumber,21); //接收短消息的手机号码
// stSubmit.cDest_terminal_type = 0;
// memcpy(stSubmit.szDest_terminal_Id,WEIMA,32);
// memcpy(stSubmit.szDest_terminal_Id,WEIMANEW,32);
/* CMailCoder mailcoder;
int iLen = 48;
int iOutLen=mailcoder.Base64DecodeSize(iLen);
char buffer[100];
strcpy(buffer,szUserNumber);
mailcoder.base64_encode(buffer,iLen,stSubmit.szDest_terminal_Id); */
// stSubmit.cDest_terminal_type = mobiletype;
stSubmit.nMessageLength = strlen(szMessageContent); //短消息的长度
strcpy(stSubmit.szSrc_Id,szSender); //源号码
strncpy(stSubmit.szMessageContent,szMessageContent,strlen(szMessageContent));
strcat(stSubmit.szMessageContent,szLinkID);
memcpy(m_szBuffer + PDU_HEADER_SIZE ,&stSubmit,m_nTotalLen - PDU_HEADER_SIZE);
}
void CCmppPdu::InitData(const char *szSPNumber, const char *szCorpId)
{
m_strSPNumber.Format("%s",szSPNumber); //SP的接入号码
m_strCorpId.Format("%s",szCorpId); //企业代码(0-99999)
m_nSequenceNumber = 0;
}
void CCmppPdu::Terminate()
{
m_nTotalLen = PDU_HEADER_SIZE;
PacketHeader(CMPP_TERMINATE,m_nTotalLen);
}
void CCmppPdu::ActiveTest()
{
m_nTotalLen = PDU_HEADER_SIZE;
PacketHeader(CMPP_ACTIVE_TEST,m_nTotalLen);
}
int CCmppPdu::GetSubmitRespResult(const char *szBuf,CString &strMsgID)
{
SCmppSubmitResp stSubmitResp;
// printf("%s",&szBuf);
memcpy(&stSubmitResp,szBuf +PDU_HEADER_SIZE,sizeof(SCmppSubmitResp));
int iSmall = 0;
CString strTmp;
for(int i=0;i<8;i++)
{
iSmall = stSubmitResp.szMsg_Id[i];
strTmp.Format("%d",iSmall);
strMsgID = strMsgID + strTmp;
}
/*
CString strMsgID = "";
strMsgID.Format("%ul%ul",ntohl(stSubmitResp.szMsg_Id1),ntohl(stSubmitResp.szMsg_Id2));
LogFile(strMsgID);
*/
/*
char buffer[100];
memset(buffer,'\0',100);
char temp[2];
memset(temp,'\0',2);
for(int i=0;i<8;i++)
{
wsprintf(temp,"%02x",stSubmitResp.szMsg_Id[i]);
lstrcat(buffer,temp);
}
printf(buffer);
LogFile(buffer);
printf("\r\n");
// return ntohl(stSubmitResp.iResult);
// CString strMsgID;
// iMsgID = ntohl(stSubmitResp.szMsg_Id);
// strMsgID.Format("%s",iMsgID);
// return ntohl(stSubmitResp.iResult);
// CString strMsgID = stSubmitResp.szMsg_Id;
// LogMsg(stSubmitResp.szMsg_Id);
// strMsg.Format("msg_id=%s",strMsgID);
// LogFile(strMsg);
// iMsgID = atoi(strMsgID);
*/
return stSubmitResp.iResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -