📄 sendsm.cpp
字号:
// 将信息拷入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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -