www.pudn.com > xltsm.rar > SendSM.cpp
#include "StdAfx.h"
#include "smei.h"
#include "smset.h"
#include "SendSM.h"
extern char szIcpNbr[];
extern char szCorpId[];
typedef struct tagSUBMITINFO {
long lRelatedMO; //对应的MO标识,为0表示由SP发起的
LPCSTR lpcszFromMobile; //发送方,可以是服务号码+用户定义标识,最长不超过19位
LPCSTR lpcszToMobile; //接受该短消息的手机号
LPCSTR lpcszServiceType; //业务代码,由sp定义
int nFeeType; //计费类型
int nFeeCode; //该条短消息的收费值;单位为分
int nPriority; //优先级0-9,从低到高
LPCSTR lpcszFeeMobile; //收费的手机号码,为NULL或"",则表示不指定
LPCSTR lpcszExpireTime; //短消息寿命的终止时间;"yymmddhhmmsstnnp";"tnnp"取固定值"032+"
LPCSTR lpcszScheduleTime; //定时发送时间
int nMessageLength; //短消息长度
LPCSTR lpcszMsgContent; //短消息内容
} SUBMITINFO, * PSUBMITINFO, FAR * LPSUBMITINFO;
BOOL bInitOK = FALSE;
BOOL bLoginOK = FALSE;
static BOOL bStop = FALSE;
void MoveTitle()
{
char szChar[3], szTitle[80];
memset(szTitle, 0, sizeof(szTitle));
GetConsoleTitle(szTitle, sizeof(szTitle));
memcpy(szChar, szTitle, 2);
szChar[2] = '\0';
memmove(szTitle, szTitle + sizeof(unsigned short), strlen(szTitle + sizeof(unsigned short)) + 1);
strcat(szTitle, szChar);
SetConsoleTitle(szTitle);
}
void ProcRawMsgID(LPCSTR lpcszRawMsgID, LPSTR lpszMsgID, int cbMsgID)
{
_ASSERT(cbMsgID >= 21);
memset(lpszMsgID, 0, cbMsgID);
for (int i = 0; i < 10; i ++) sprintf(lpszMsgID + strlen(lpszMsgID), "%02X", 0xFF & lpcszRawMsgID[i]);
}
void LoggingDeliveryInfo(DELIVERRESP& dr)
{
CString strError;
CString msg, sql;
if (dr.nIsReply) {
// 收到状态报告
//printf("\n移动状态报告:%s\n", dr.sMsgContent);
return;
}
_ASSERT (dr.nMsgLen <= 116);
// 将信息拷入msg中,以便处理,因为dr.lpcszMsgContent不一定以\0结尾
try {
LPSTR p = msg.GetBuffer(dr.nMsgLen + 1);
memcpy(p, dr.sMsgContent, dr.nMsgLen);
p[dr.nMsgLen] = '\0';
msg.ReleaseBuffer();
} catch(CMemoryException*){
FatalAppExit(0, "内存不足,无法创建缓冲区。");
}
// 将 ' 变成 ''
msg.Replace("'", "\x3");
msg.Replace("\x3", "''");
CMyDatabase db;
printf("\n收到%s发到%s信息(ID:%s):%s", dr.sSrcTermID, dr.sDestTermID, dr.sServiceID, msg);
if (MakeSureDBConnected(db, strError)){
sql.Format( "EXECUTE ismr_sp_delivery \r\n"
" @FROMMOBILE = '%s', \r\n"
" @TOMOBILE = '%s', \r\n"
" @ICPNUMBER = '%s', \r\n"
" @MSGLEVEL = %d, \r\n"
" @MESSAGE = '%s' \r\n",
dr.sSrcTermID,
dr.sDestTermID,
dr.sServiceID,
dr.nMsgLevel,
msg);
if (db.ExecuteSQLEx(strError, sql) != -1){
printf("\n登记成功。");
strError = "";
}
}
if (!strError.IsEmpty()){
printf("\n登记失败,因为数据库错误:%s\n", strError);
LogError(".sql", "sqlError", "/* SQL */\n%s\n/* ERROR: %s */", sql, strError);
}
return;
}
int cngpSubmit(SUBMITINFO &submit, char* szMsgID, int lenMsgID, char szSrcTermId[21 + 1])
{
int nPhsFeeType = -1;
int nMsgFormat = MSG_FORMAT_ASCII;
int nResult = 0;
int nNeedReply = 1; // 0=不要求,1=要求
int nSubType = 2; // 短消息子类型(0=取消订阅,1=订阅或点播请求,2=点播下发,3=订阅下发,其他保留)
int nFeeUserType = 0;
char szFeeType[3], szFeeCode[7];
char szRawMsgID[11];
_ASSERT (strlen(szIcpNbr) + strlen(submit.lpcszFromMobile) <= 19);
sprintf(szSrcTermId, "%s%s", szIcpNbr, submit.lpcszFromMobile);
if (!submit.lpcszFeeMobile) submit.lpcszFeeMobile = "";
if (*submit.lpcszFeeMobile) nFeeUserType = 3;
switch(submit.nFeeType){
case 1:
nPhsFeeType = 0; // 转化成PHS的FeeType
if (!submit.lRelatedMO){
// 由SP发起的MT
nSubType = 3; // 订阅下发
nFeeUserType = 2; // 对SP计费
} else {
// 由MO发起的MT
nSubType = 2; // 点播下发
}
break;
case 2:
nPhsFeeType = 1; // 转化成PHS的FeeType
if (!submit.lRelatedMO){
// 由SP发起的MT
nSubType = 3; // 订阅下发
} else {
// 由MO发起的MT
nSubType = 2; // 点播下发
}
break;
case 3: // 包月扣费请求
nPhsFeeType = 4; // 扣费请求
nSubType = 3; // 订阅下发
break;
default:
return SP_ERROR_INVALID_FEETYPE;
}
for (unsigned i = 0; i < strlen(submit.lpcszMsgContent); i ++){
if ((unsigned char)submit.lpcszMsgContent[i] > 0x80){
nMsgFormat = MSG_FORMAT_GB;
}
}
_ASSERT (nPhsFeeType >= 0 && nPhsFeeType <= 4);
sprintf(szFeeType, "%02d", nPhsFeeType);
_ASSERT (submit.nFeeCode >= 0 && submit.nFeeType <= 999999);
sprintf(szFeeCode, "%06d", submit.nFeeCode);
/*
printf("\nSP企业代码: %s", szCorpId);
printf("\n短消息子类型:%d (0=取消订阅,1=订阅或点播请求,2=点播下发,3=订阅下发)", nSubType);
printf("\n确认报告:%d(0=不要求,1=要求)", nNeedReply);
printf("\n信息级别:%d(0=最低,1=正常,2=紧急,3=十分紧急)", submit.nPriority);
printf("\n业务类型:%s", submit.lpcszServiceType);
printf("\n资费类别:%s", szFeeType);
printf("\n计费用户类型:%d", nFeeUserType);
printf("\n资费代码:%s", szFeeCode);
printf("\n信息格式:%d", nMsgFormat);
printf("\n存活有效期:%s", submit.lpcszExpireTime);
printf("\n定时发送时间:%s", submit.lpcszScheduleTime);
printf("\n源发方号码:%s", szSrcTermId);
printf("\n被计费用户的号码:%s", submit.lpcszFeeMobile);
printf("\n接收方的手机号码:%s", submit.lpcszToMobile);
printf("\n短信长度:%d", submit.nMessageLength);
printf("\n短信内容:%s", submit.lpcszMsgContent);
*/
nResult = _CNGPSubmit(szCorpId, // SP企业代码
nSubType, // 短消息子类型(0=取消订阅,1=订阅或点播请求,2=点播下发,3=订阅下发,其他保留)
nNeedReply, // 是否要求返回状态报告:(0=不要求,1=要求)
submit.nPriority, // 信息级别(0=最低优先级,1=正常,2=紧急,3=十分紧急)
submit.lpcszServiceType, // 业务类型,最长10字节
szFeeType, // 资费类别,最长2字节(01-免费 02-按条 03-包月)
nFeeUserType, // 计费用户类型字段,0:对目的终端计费;1:对源终端计费;2:对SP计费; 3:表示本字段无效,对谁计费参见Fee_terminal_id字段。
szFeeCode, // 资费代码(以分为单位) ,最长6字节
nMsgFormat, // 信息格式
submit.lpcszExpireTime, // 存活有效期
submit.lpcszScheduleTime, // 定时发送时间
szSrcTermId, // 源发方的手机号码或ICP服务编号(特服号+用户自定义标识)
submit.lpcszFeeMobile, // 被计费用户的号码(如本字节填空,则表示本字段无效,对谁计费参见Fee_UserType字段。本字段与Fee_UserType字段互斥),最长21 bytes。
1, // 给多少个用户发
submit.lpcszToMobile, // 接收方的手机号码
submit.nMessageLength, // 短信长度
submit.lpcszMsgContent, // 短信内容
0, // 协议类型 0-缺省
(unsigned char*)szRawMsgID); // 用来取得MSGID (接收返回的短信标识)
memset(szMsgID, 0, lenMsgID);
ProcRawMsgID(szRawMsgID, szMsgID, lenMsgID);
return nResult;
}
// 返回页数,返回0表示页数太多,返回-1表示内存不足,要求释放aMsgPtr[i]内容
int SplitMessage(wchar_t* lpwMsg, int nWordCnt, wchar_t* aMsgPtr[], int nMsgPtr)
{
int nTotal = 0;
LPWSTR lpwBuffer;
// 将所有指针置 NULL
memset(aMsgPtr, 0, nMsgPtr * sizeof(LPWSTR));
if (nWordCnt <= 59){
// 中文和英文都可以一屏发送,故没有问题
lpwBuffer = new WCHAR[1 + nWordCnt];
if (lpwBuffer == NULL) return -1;
lpwBuffer[0] = nWordCnt;
memcpy(&lpwBuffer[1], lpwMsg, nWordCnt * sizeof(WCHAR));
aMsgPtr[0] = lpwBuffer;
return 1;
}
if (nWordCnt <= 112){
// 只有英文与数字或半角符号可以一屏发送,故判断
for (int i = 0; i < nWordCnt; i ++){
if (lpwMsg[i] > 0xFF) break;
}
if (i >= nWordCnt){
// 全是英文与数字或半角符号
lpwBuffer = new WCHAR[nWordCnt + 1];
if (lpwBuffer == NULL) return -1;
lpwBuffer[0] = nWordCnt;
memcpy(&lpwBuffer[1], lpwMsg, nWordCnt * sizeof(WCHAR));
aMsgPtr[0] = lpwBuffer;
return 1;
}
}
// 以下必须分屏显示
int nPageBytes = 112 - 8;
int nStart = 0;
int nLen = 0;
for (int i = 0; i < nWordCnt; i ++){
// 判断加上本字符是否超屏
if ((nLen == nPageBytes) || (lpwMsg[i] > 0xFF && nLen + 1 > 59 - 8)){
// 超过或到达一屏,则拷贝本屏
lpwBuffer = new WCHAR[1 + nLen + 8];
if (lpwBuffer == NULL){
for (int i = 0; i < nTotal; i++) delete aMsgPtr[i];
return -1;
}
lpwBuffer[0] = nLen + 8;
memcpy(&lpwBuffer[1], "(\0i\0/\0n\0)\0\0\0", 5 * sizeof(WCHAR));
lpwBuffer[2] = (nTotal + 1) + '0';
memcpy(&lpwBuffer[1 + 5], lpwMsg + nStart, nLen * sizeof(WCHAR));
memcpy(&lpwBuffer[1 + 5 + nLen], ".\0.\0.\0\0\0", 3 * sizeof(WCHAR));
aMsgPtr[nTotal++] = lpwBuffer;
if (nTotal >= 10){
for (int i = 0; i < nTotal; i++) delete aMsgPtr[i];
return 0;
}
// 重新设置有关初始,开始下一轮
nPageBytes = 112 - 8;
nStart += nLen;
nLen = 0;
}
// 判断当前字符是否为汉字,是则调整页长度
if (lpwMsg[i] > 0xFF) nPageBytes = 70 - 8;
// 并计数
nLen ++;
}
if (nLen > 0){
lpwBuffer = new WCHAR[1 + nLen + 8];
if (lpwBuffer == NULL){
for (int i = 0; i < nTotal; i++) delete aMsgPtr[i];
return -1;
}
lpwBuffer[0] = nLen + 8;
memcpy(&lpwBuffer[1], "(\0i\0/\0n\0)\0\0\0", 5 * sizeof(WCHAR));
lpwBuffer[2] = (nTotal + 1) + '0';
memcpy(&lpwBuffer[1 + 5], lpwMsg + nStart, nLen * sizeof(WCHAR));
memcpy(&lpwBuffer[1 + 5 + nLen], ".\0.\0.\0\0\0", 3 * sizeof(WCHAR));
aMsgPtr[nTotal++] = lpwBuffer;
if (nTotal >= 10){
for (int i = 0; i < nTotal; i++) delete aMsgPtr[i];
return 0;
}
}
for (i = 0; i < nTotal; i ++){
aMsgPtr[i][4] = nTotal + '0';
}
return nTotal;
}
long LoggingSubmitInfo(CMyDatabase& db, SUBMITINFO& submit, int index)
{
CString strError;
char sql[512]; // 196 + 10 + 21 + 21 + 10 + 10 + 10 + 10 + 16 + 16 + 10 + 161
CString msg;
_ASSERT(index <= 9);
_ASSERT(submit.nMessageLength <= 116);
// 将信息拷入msg中,以便处理,因为submit.lpcszMsgContent不一定以\0结尾
try {
LPSTR p = msg.GetBuffer(submit.nMessageLength + 1);
memcpy(p, submit.lpcszMsgContent, submit.nMessageLength);
p[submit.nMessageLength] = '\0';
msg.ReleaseBuffer();
} catch(CMemoryException*){
FatalAppExit(0, "内存不足,无法创建缓冲区。");
}
// 将 ' 变成 ''
msg.Replace("'", "\x3");
msg.Replace("\x3", "''");
long idTimeID = -1;
if (MakeSureDBConnected(db, strError)){
CMyDataSet ds(&db);
sprintf(sql, "SELECT MAX(TIMEID) FROM SMS_SUBMIT WHERE TOMOBILE = '%s' ", submit.lpcszToMobile);
ds.Open(sql);
if (ds.m_nSQLCode == -1){
strError = ds.GetSQLErrText();
} else {
_ASSERT (ds.m_nSQLCode != 100);
idTimeID = ds[0][0];
idTimeID += 1;
sprintf(sql, "INSERT INTO SMS_SUBMIT (TIMEID, FROMMOBILE, TOMOBILE, SERVICETYPE, FEETYPE, FEECODE, PRIORITY, EXPIRETIME, SCHEDULETIME, MSGLENGTH, MSGCONTENT) "
"VALUES (%ld, '%s', '%s', '%s', %d, %d, %d, '%s', '%s', %d, '%s')",
idTimeID, submit.lpcszFromMobile, submit.lpcszToMobile, submit.lpcszServiceType,
submit.nFeeType, submit.nFeeCode, submit.nPriority, submit.lpcszExpireTime,
submit.lpcszScheduleTime, msg.GetLength(), msg);
if (db.ExecuteSQLEx(strError, sql) != -1) strError = "";
}
}
if (!strError.IsEmpty()){
printf("\n数据库错误:%s\n", strError);
LogError(".sql", "sqlError", "/* SQL */\n%s\n/* ERROR: %s */", sql, strError);
}
return idTimeID;
}
void UpdateSubmitInfo(CMyDatabase& db, long lRecordNo, const char *lpcszToMobile, const char *lpcszSrcTermId, bool bStatus, LPCTSTR lpcszMsgID)
{
CString strError;
char sql[256];
sprintf(sql, "UPDATE SMS_SUBMIT SET STATUS = %d, FROMMOBILE='%s', MSGID='%s' WHERE TIMEID = %ld AND TOMOBILE = '%s' ",
(int)bStatus, lpcszSrcTermId, lpcszMsgID, lRecordNo, lpcszToMobile);
if (MakeSureDBConnected(db, strError)){
if (db.ExecuteSQLEx(strError, sql) != -1){
strError = "";
if (db.GetExecRowCount() != 1){
strError = "更改状态失败,找不到要修改的记录。";
}
}
}
if (!strError.IsEmpty()){
printf("\n无法更改ID为 %ld (接收号码为 %s )的数据 - 错误信息:%s\n", lRecordNo, lpcszToMobile, strError);
LogError(".sql", "sqlError", "/* SQL */\n%s\n/* ERROR: %s */", sql, strError);
}
return;
}
bool SubmitSM (
const char * lpcszRecvMobile, // 接收方的手机号
const char * lpcszServiceType, // 业务类别
const char * lpcszSendMobile, // 源发方号码
int nFeeType, // 计费类型 (1-免费 2-按条 3-包月)
int nFeeValue, // 计费费用(单位:分)
int nPriority, // 信息级别(0=最低优先级,1=正常,2=紧急,3=十分紧急)
const char * lpcszFeeMobile, // 收费的手机号
int nMsgLen, // 短信长度
char * lpszMsgTxt, // 短信内容
int *pnErrorCode) // 用来取错误码
{
CMyDatabase db;
const char *aType[] = { "CMCCTEST", "BZEDU", "BZQX", "BZHELP", "EDUJXT", "EDUZLYX", "EDUTJKB", "EDUYJJC", "EDUZXDY", "EDUKJGX", "EDUXTSW" };
int nTypeCnt = sizeof(aType)/sizeof(aType[0]);
LPWSTR lpwMsgContent = NULL;
int nUcs2MsgLen = 0;
LPWSTR aMsgPtr[10];
char Message[161];
int i, nSendCount = 0;
long lRecordNo;
char szMsgID[21 + 1];
// 去掉要发送的信息文本中无效的字符
for(i = 0; i < nMsgLen; i ++){
switch(lpszMsgTxt[i]){
case '\x3': lpszMsgTxt[i] = '\x20'; break;
case '\x4': lpszMsgTxt[i] = '\r'; break;
case '\x5': lpszMsgTxt[i] = '\n'; break;
case '\x6': lpszMsgTxt[i] = '\t'; break;
}
}
// 检查参数合法性
if (strlen(lpcszRecvMobile) < 7){
printf("\n接收方手机号码(%s)长度不对,至少7位。\n", lpcszRecvMobile);
return false;
}
if (memcmp(lpcszRecvMobile, "13", 2) == 0){
printf("\n接收方小灵通号码(%s)不对,不应以13开头。\n", lpcszRecvMobile);
return false;
}
// 下面就可以判断lpcszRecvMobile[2]来决定是联通还是移动
bool bValid = false;
for (i = 0; i < nTypeCnt && !bValid; i ++){
int nOffset = 0;
if (lpcszServiceType[0] == '+' || lpcszServiceType[0] == '-') nOffset = 1;
if (!strcmp(aType[i], lpcszServiceType + nOffset)) bValid = true;
}
if (!bValid){
printf("\n业务类型(%s)非法。\n", lpcszServiceType);
return false;
}
if (strlen(lpcszSendMobile) > 11){
printf("\n源发方号码(%s)长度不对,应不超过11位,可为手机号码或其它标识。\n", lpcszSendMobile);
return false;
}
switch(nFeeType){
case 1:
if (nFeeValue != 0){
printf("\n计费费用值(%06d)不对,应为0。\n", nFeeValue);
return false;
}
break;
case 2:
if (nFeeValue <= 0 || nFeeValue > 200){
printf("\n计费费用值(%06d)不对,应为1到200元,按条计费每条最高不超过2元。\n", nFeeValue);
return false;
}
break;
case 3:
if (nFeeValue <= 0 || nFeeValue > 3000){
printf("\n计费费用值(%06d)不对,应为1到3000元,包月计费每月最高不超过30元。\n", nFeeValue);
return false;
}
break;
default:
printf("\n计费类型(%02d)不对,应为1、2、3,其中1为免费(包月用户下发信息使用)、2为按条收费(用于按条计费用户)、3为包月扣费包。\n", nFeeType);
return false;
}
if (nPriority < 0 || nPriority > 3){
printf("\n短信优先级(%d)不对,应为0到9。\n", nPriority);
return false;
}
// 将要发送的信息进行处理,变成 MSG_FORMAT_UCS2 格式
lpwMsgContent = new WCHAR[nMsgLen + 1];
if (lpwMsgContent == NULL){
printf("\n没有内存转换数据。\n");
return false;
}
memset(lpwMsgContent, 0, (nMsgLen + 1) * sizeof(WCHAR));
nUcs2MsgLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszMsgTxt, nMsgLen, lpwMsgContent, nMsgLen);
if (nUcs2MsgLen <= 0){
delete []lpwMsgContent;
printf("\n转换数据失败。\n");
return false;
}
nSendCount = SplitMessage(lpwMsgContent, nUcs2MsgLen, aMsgPtr, 10);
delete []lpwMsgContent;
switch(nSendCount){
case 0:
printf("\n要发送的信息太长,已达10页。\n");
return false;
case -1:
printf("\n没有内存转换数据。\n");
return false;
}
SUBMITINFO submit;
submit.lpcszFromMobile = lpcszSendMobile;
submit.lpcszToMobile = lpcszRecvMobile;
submit.lpcszServiceType = lpcszServiceType;
submit.nFeeType = nFeeType;
submit.nFeeCode = nFeeValue;
submit.nPriority = nPriority;
submit.lpcszExpireTime = "";
submit.lpcszScheduleTime= "";
submit.lpcszFeeMobile = lpcszFeeMobile;
bool bReturn = true;
char szSrcNumber[21 + 1];
for (i = 0; i < nSendCount && bReturn; i ++){
// 将UNICODE转成MULTIBYTE
submit.nMessageLength = WideCharToMultiByte(CP_ACP, 0, &aMsgPtr[i][1], aMsgPtr[i][0], Message, sizeof(Message), NULL, NULL);
Message[submit.nMessageLength] = 0;
submit.lpcszMsgContent = Message;
printf("\n发送:%s\n", Message);
lRecordNo = LoggingSubmitInfo(db, submit, i);
if (lRecordNo < 0){
*pnErrorCode = -1;
bReturn = false;
break;
}
// 发送它们
printf("\n通过网通短信网关发送短信给%s...", lpcszRecvMobile);
int nResult = cngpSubmit(submit, szMsgID, sizeof(szMsgID), szSrcNumber);
if (nResult != 0){
printf("失败!\n错误码为%d。\n", *pnErrorCode);
bReturn = false;
} else {
printf("成功!\n接方手机号为网通用户:%s MSGID: %s\n", lpcszRecvMobile, szMsgID);
}
UpdateSubmitInfo(db, lRecordNo, submit.lpcszToMobile, szSrcNumber, bReturn, szMsgID);
}
for (i = 0; i < nSendCount; i ++){
if (aMsgPtr[i]){
delete aMsgPtr[i];
}
}
return bReturn;
}
BOOL ProcDelivery(int nTimeOut)
{
char rawmsgid[10];
unsigned char byProValue;
char sRecvTime[34 + 1];
char raworgmsgid[10];
char sSubmitdate[34 + 1];
char sDonedate[34 + 1];
char sStatus[21 + 1];
int iDeliverAckResult = 1;
DELIVERRESP dr;
memset(&dr, 0, sizeof(dr));
dr.uSize = sizeof(dr);
Sleep(nTimeOut);
if (_GetCNGPDeliverSM(
rawmsgid,
(unsigned char*)&dr.nMsgFormat,
sRecvTime,
dr.sSrcTermID,
dr.sDestTermID,
(unsigned char*)&dr.nMsgLen,
dr.sMsgContent,
(unsigned char*)&byProValue,
(unsigned char*)&dr.nIsReply,
raworgmsgid,
sSubmitdate,
sDonedate,
sStatus,
iDeliverAckResult) != 0) return FALSE;
ProcRawMsgID(rawmsgid, dr.sMsgID, sizeof(dr.sMsgID));
char *p = strstr(dr.sDestTermID, szIcpNbr);
if (p != NULL){
if (p != dr.sDestTermID){
memmove(dr.sDestTermID, p, strlen(p) + 1); // 多拷一个0
}
}
if (dr.nMsgLen < 0 || dr.nMsgLen >= sizeof(dr.sMsgContent)){
printf("\n错误:无效的MSGLEN。");
return TRUE;
}
dr.sMsgContent[dr.nMsgLen] = '\0';
if (!dr.nIsReply){
printf("\nDELIVER: MID:%s FMT:%d FRM: %s TO: %s LEN: %d>%s", dr.sMsgID, dr.nMsgFormat, dr.sSrcTermID, dr.sDestTermID, dr.nMsgLen, dr.sMsgContent);
} else {
char orgmsgid[21 + 1];
char stat[21];
ProcRawMsgID(raworgmsgid, orgmsgid, sizeof(orgmsgid));
char *p = strstr(dr.sMsgContent, "stat:");
if (p != NULL){
p += 5;
if (sscanf(p, "%20s", stat) != 1){
memset(stat, 0, sizeof(stat));
}
printf("\nREPORT: MID:%s FMT:%d FRM: %s TO: %s>原始消息标识:%s 状态:%s", dr.sMsgID, dr.nMsgFormat, dr.sSrcTermID, dr.sDestTermID, orgmsgid, stat);
}
}
printf("\n");
// 2003-12-20 前加,用来给客户端返回特服号码
_ASSERT(strlen(szIcpNbr) > 0);
strcpy(dr.sServiceID, szIcpNbr);
LoggingDeliveryInfo(dr); // 网通
return TRUE;
}