⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendsm.cpp

📁 小灵通(网通)短信接口程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// 将信息拷入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 + -