#include <stdio.h>
#include <netinet/in.h>
#include <openssl/md5.h>
#include <string>
#include <sys/time.h>
#include "CMPP.h"
#include "ShortMsgOP.h"
extern LogStream sendlog;
extern LogStream proclog;
extern CShortMsgOP infoOp;
extern int gMaxWinSize;
/**********************************************************
Function: CCMPP
Description: CCMPP constructor
Parameter: none
Return: none
Exception: none
By: leida
Date: 2002/08/1
Modify By:
Modify Date:
*********************************************************/
CCMPP::CCMPP()
{
m_strHost = "";
m_iPort = 0;
m_strSystemID = "";
m_strPasswd = "";
m_bIsBinded = false;
}
/**********************************************************
Function: ~CCMPP
Description: CCMPP constructor
Parameter: none
Return: none
Exception: none
By: leida
Date: 2002/8/1
Modify By:
Modify Date:
*********************************************************/
CCMPP::~CCMPP()
{
//UnBind();
}
/************************************************************
Function: GetCurrTime
Description: get currently datetime, format:mmddhhmmss
Parameter: none
Return: int
Eeception: none
By: leida
Date: 2003/1/2
Modify By:
Modify Date:
************************************************************/
int CCMPP::GetCurrTime()
{
time_t tCurrTime ;
struct tm *tTm ;
int iyear;
//get datetime
time(&tCurrTime) ;
tTm = localtime(&tCurrTime) ;
iyear = tTm->tm_year > 100 ? (tTm->tm_year - 100) + 2000 : tTm->tm_year;
memset(m_szDateTime, 0, sizeof(m_szDateTime));
//set date character string to m_szTodayTime
sprintf(m_szDateTime, "%02d%02d%02d%02d%02d",
tTm->tm_mon + 1, tTm->tm_mday, tTm->tm_hour, tTm->tm_min, tTm->tm_sec);
m_lDateTime = atol(m_szDateTime);
return m_lDateTime;
}
/************************************************************
Function: MakeConnectPDU
Description: 制作连接数据包
Parameter: p_strSystemID : string& : 账号
p_strPasswd : string& : 密码
p_OctStr : Octstr& : 生成的数据包
Return: int
Eeception: none
By: leida
Date: 2002/8/1
Modify By:
Modify Date:
************************************************************/
int CCMPP::MakeConnectPDU(char* p_pSystemID, char* p_pPasswd, Octstr& p_OctStr)
{
//取得当前时间,格式 MMDDHHMMSS;
GetCurrTime();
//生成SP认证码
unsigned char szAuthenticatorSp[17] = "";
unsigned char szTmp[255] = {0};
int iLen, iTotalLen;
iTotalLen = 0;
iLen = strlen(p_pSystemID);
memcpy(szTmp, p_pSystemID, iLen);
iTotalLen += iLen;
iLen = 9;
iTotalLen += iLen;
iLen = strlen(p_pPasswd);
memcpy(szTmp + iTotalLen, p_pPasswd, iLen);
iTotalLen += iLen;
//MMDDHHMMSS
iLen = 10;
memcpy(szTmp + iTotalLen, m_szDateTime, iLen);
iTotalLen += iLen;
MD5(szTmp, iTotalLen, szAuthenticatorSp);
//设置包数据
cmpp_pdu_connect PDUConnect;
memset(&PDUConnect, 0, sizeof(cmpp_pdu_connect));
memcpy(PDUConnect.source_addr, p_pSystemID, 6);
memcpy(PDUConnect.authenticatorsp, szAuthenticatorSp, 16);
PDUConnect.version = 0x30; //设置CMPP的版本为3.0
PDUConnect.timestamp = htonl(m_lDateTime);
return m_PduCode.Pdu_Encode_Connect(PDUConnect, p_OctStr);
}
/************************************************************
Function: MakeSmsSendPDU
Description: 创建一个SmsSend PDU
Parameter:
p_cPkTotal : 相同Msg_Id的信息总条数,从1开始
p_cPkNumber : 相同Msg_Id的信息序号,从1开始
p_cRegisteredDelivery : 是否要求返回状态确认报告:0:不需要1:需要2:产生SMC话单
p_cMsgLevel : 信息级别
p_pServiceId : 业务类型
p_cFeeUserType : 计费用户类型字段0:对目的终端MSISDN计费;1:对源终端MSISDN计费;2:对SP计费;3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
p_pFeeTerminalId : 被计费用户的号码(如本字节填空,则表示本字段无效,对谁计费参见Fee_UserType字段,本字段与Fee_UserType字段互斥)
p_cTPpid : GSM协议类型
p_cTPudhi : GSM协议类型
p_cMsgFmt : 信息格式 0:ASCII串 3:短信写卡操作 4:二进制信息 8:UCS2编码15:含GB汉字
p_pMsg_src : 信息内容来源(SP_Id)
p_pFeeType : 资费类别01:对"计费用户号码"免费02:对"计费用户号码"按条计信息费03:对"计费用户号码"按包月收取信息费04:对"计费用户号码"的信息费封顶05:对"计费用户号码"的收费是由SP实现
p_pFeeCode : 资费代码(以分为单位)
p_pValidTime: 存活有效期,格式遵循SMPP3.3协议
p_pAtTime : 定时发送时间,格式遵循SMPP3.3协议
p_pSrcId : 源号码SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,该号码最终在用户手机上显示为短消息的主叫号码
p_pDestTerminalId : 接收短信的MSISDN号码,群发使用逗号分割号码
p_cMsgLength : 信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节)
p_pMsgContent : 信息内容
p_pReserve : 保留
Return:
Eeception: none
By: leida
Date: 2002/8/1
Modify By:
Modify Date:
************************************************************/
int CCMPP::MakeSmsSendPDU( char p_cPkTotal,
char p_cPkNumber,
char p_cRegisteredDelivery,
char p_cMsgLevel,
char* p_pServiceId,
char p_cFeeUserType,
char* p_pFeeTerminalId,
char p_cFee_terminal_type,
char p_cTPpid,
char p_cTPudhi,
char p_cMsgFmt,
char* p_pMsg_src,
char* p_pFeeType,
char* p_pFeeCode,
char* p_pValidTime,
char* p_pAtTime,
char* p_pSrcId,
char* p_pDestTerminalId,
char p_pDest_terminal_type,
char p_cMsgLength,
char* p_pMsgContent,
char* p_pLinkID,
Octstr& p_OctStr)
{
int iCount, iMsgLength;
cmpp_pdu_submit_sm PduSubmitSm;
memset(&PduSubmitSm, 0, sizeof(cmpp_pdu_submit_sm));
//判断是否是群发短信************
vector<string> v_str;
Util::splitstr((const char*)p_pDestTerminalId,',',v_str);
iCount = v_str.size();
PduSubmitSm.DestUsr_tl = iCount;
for(int i = 0; i < iCount; i++)
{
strncpy((char*)PduSubmitSm.Dest_terminal_id + i*21, v_str[i].c_str() , 32);
}
v_str.clear();
//**********************************
memset((char*)PduSubmitSm.Msg_id, 0, 8);
PduSubmitSm.Pk_total = p_cPkTotal;
PduSubmitSm.Pk_number = p_cPkNumber;
PduSubmitSm.Registered_Delivery = p_cRegisteredDelivery;
PduSubmitSm.Msg_level = p_cMsgLevel;
strncpy((char*)PduSubmitSm.Service_id, p_pServiceId, 10);
PduSubmitSm.Fee_UserType = p_cFeeUserType;
strncpy((char*)PduSubmitSm.Fee_terminal_Id, p_pFeeTerminalId, 32);
PduSubmitSm.Fee_terminal_type = p_cFee_terminal_type;
PduSubmitSm.TP_pid = p_cTPpid;
PduSubmitSm.TP_udhi = p_cTPudhi;
PduSubmitSm.Msg_Fmt = p_cMsgFmt;
strncpy((char*)PduSubmitSm.Msg_src, p_pMsg_src, 6);
strncpy((char*)PduSubmitSm.FeeType, p_pFeeType, 2);
strncpy((char*)PduSubmitSm.FeeCode, p_pFeeCode, 6);
strncpy((char*)PduSubmitSm.Valid_Time, p_pValidTime, 17);
strncpy((char*)PduSubmitSm.At_Time, p_pAtTime, 17);
strncpy((char*)PduSubmitSm.Src_Id, p_pSrcId, 21);
memcpy(PduSubmitSm.LinkID, p_pLinkID, 20);
PduSubmitSm.Dest_terminal_type = p_pDest_terminal_type;
PduSubmitSm.Msg_Length = p_cMsgLength;
iMsgLength = (int)PduSubmitSm.Msg_Length;
memcpy(PduSubmitSm.Msg_Content, p_pMsgContent, iMsgLength);
return m_PduCode.Pdu_Encode_Submit(PduSubmitSm, p_OctStr);
}
/************************************************************
Function: MakeConnectPDU
Description: 制作连接数据包
Parameter: p_strSystemID : string& : 账号
p_strPasswd : string& : 密码
p_OctStr : Octstr& : 生成的数据包
Return: int
Eeception: none
By: leida
Date: 2002/8/1
Modify By:
Modify Date:
************************************************************/
void CCMPP::MakeDeliverRespPDU(int p_lSeqNum,
char* p_pMsgId,
unsigned int p_Result,
Octstr& p_OctStr)
{
//设置包数据
cmpp_pdu_deliver_sm_resp PDUDeliverResp;
memset(&PDUDeliverResp, 0, sizeof(cmpp_pdu_deliver_sm_resp));
memcpy(PDUDeliverResp.Msg_Id, p_pMsgId, 8);
PDUDeliverResp.Result = htonl(p_Result);
m_PduCode.Pdu_Encode_Deliver_Resp(p_lSeqNum, PDUDeliverResp, p_OctStr);
return;
}
/************************************************************
Function:
Description:
Parameter:
Retur