FXSend/Cmpp3/Cmpp3.cpp
2025-02-28 17:05:50 +08:00

2027 lines
50 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Cmpp3.cpp: implementation of the CCmpp3 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Cmpp3.h"
//#include "MCmpp3.h"
/*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include "..\..\..\public\md53\\md5_L.h"
CCmpp3::CCmpp3()
{
m_hSocket = INVALID_SOCKET;
memset( m_szIP , 0 , sizeof(m_szIP) );
m_lPort = 0;
m_bQuitThread = false;
m_dwEndSendTime = 0;
m_dwEndRecvTime = 0;
m_dwTestCount = 0;
m_bRecvFrame = false;
m_lID = 1;
m_pRecvProc = NULL;
m_bConnect = false;
m_bLoginCmpp3= -1;
m_bInitCmpp3 = false;
memset(m_szCmpp3IP ,0,sizeof(m_szCmpp3IP));
memset(m_szCmpp3User ,0,sizeof(m_szCmpp3User));
memset(m_szCmpp3Passwd,0,sizeof(m_szCmpp3Passwd));
memset(m_szCmpp3CorpID,0,sizeof(m_szCmpp3CorpID));
WSADATA wsaData; //用于初始化socket的结构
//以下为初始化SOCKET环境
int iTemp=WSAStartup(0x0101,&wsaData); //初始化socket环境
InitializeCriticalSection(&m_CriSendSms);
InitializeCriticalSection(&m_CriRespList);
InitializeCriticalSection(&m_CriDeliverList);
InitializeCriticalSection(&m_CriStatusList);
InitializeCriticalSection(&m_CriCmpp3ExchangeResp);
InitializeCriticalSection(&m_CriErrMsg);
InitializeCriticalSection(&m_CriSendFrame);
//定义队列
m_lSendID = 1;
m_pSendList = new Cmpp3_Send_List[CMPP3_SMS_MAX_LIST];
m_pRespList = new Cmpp3_Send_Resp[CMPP3_SMS_MAX_RESP];
m_pDeliverList = new Cmpp3_Deliver_List[CMPP3_SMS_MAX_DELIVER];
m_pStatusList = new Cmpp3_Deliver_List[CMPP3_SMS_MAX_STATUS];
m_pCmpp3ExchangeResp = new Cmpp3ExchangeResp[CMPP3_SMS_MAX_CMPP3EXCHANGERESP];
memset(m_pSendList,0,sizeof(Cmpp3_Send_List)* CMPP3_SMS_MAX_LIST);
memset(m_pRespList,0,sizeof(Cmpp3_Send_Resp)* CMPP3_SMS_MAX_RESP);
memset(m_pDeliverList,0,sizeof(Cmpp3_Deliver_List)* CMPP3_SMS_MAX_DELIVER);
memset(m_pStatusList,0,sizeof(Cmpp3_Deliver_List) * CMPP3_SMS_MAX_STATUS);
memset(m_pCmpp3ExchangeResp,0,sizeof(Cmpp3ExchangeResp)* CMPP3_SMS_MAX_CMPP3EXCHANGERESP);
m_lSendList = 0;
m_lRespList = 0;
m_lDeliverList=0;
m_lStatusList=0;
m_lCmpp3ExchangeRespList=0;
m_pCmppExchange = NULL;
m_lCmppExchange = 0;
m_bAdc = false;
m_dwEndSocketSendTime = 0;
m_lSendInterval = 0;
m_lSendIntervalCount = 1;
m_lSendIntervalIndex = 0;
m_hThread = INVALID_HANDLE_VALUE;
m_hThread_Send = INVALID_HANDLE_VALUE;
}
CCmpp3::~CCmpp3()
{
Stop();
//删除数据
if ( m_pSendList )
{delete m_pSendList;m_pSendList=NULL;}
if ( m_pRespList )
{delete m_pRespList;m_pRespList=NULL;}
if ( m_pDeliverList )
{delete m_pDeliverList;m_pDeliverList=NULL;}
if ( m_pStatusList )
{delete m_pStatusList;m_pStatusList=NULL;}
if ( m_pCmpp3ExchangeResp )
{delete m_pCmpp3ExchangeResp;m_pCmpp3ExchangeResp=NULL;}
DeleteCriticalSection(&m_CriSendSms);
DeleteCriticalSection(&m_CriRespList);
DeleteCriticalSection(&m_CriDeliverList);
DeleteCriticalSection(&m_CriStatusList);
DeleteCriticalSection(&m_CriCmpp3ExchangeResp);
DeleteCriticalSection(&m_CriErrMsg);
DeleteCriticalSection(&m_CriSendFrame);
//退出Socket
WSACleanup();
}
BOOL CCmpp3::Connect(const char *pAddr, long lPort, BOOL bReConnect)
{
if ( !bReConnect && m_hSocket!=INVALID_SOCKET) //已连接,并且无需重连
{
return true;
}
this->Stop(); //重新连接,先让原来的线程停止
strcpy( m_szIP,pAddr );
m_lPort = lPort;
sockaddr_in sAddr;
m_hSocket=socket(AF_INET,SOCK_STREAM,0);
sAddr.sin_family=AF_INET;
sAddr.sin_port=0;
sAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
return false;
}
sAddr.sin_port=htons((unsigned short)lPort);
sAddr.sin_addr.s_addr=inet_addr(pAddr);
if (sAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(pAddr);
if (lphost != NULL)
sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
Close();
return false;
}
}
if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
Close();
return false;
}
//设置Socket
u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET
//u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET
ioctlsocket( m_hSocket,FIONBIO,&ulTemp );
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
m_bQuitThread = false;
DWORD dwTemp;
m_hThread=CreateThread(NULL,0,SocketRecv,(LPVOID)this,0,&dwTemp);
// if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) )
if ( m_hThread == INVALID_HANDLE_VALUE )
{
Close();
return false;
}
m_hThread_Send=CreateThread(NULL,0,SocketSend,(LPVOID)this,0,&dwTemp);
// if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) )
if ( m_hThread_Send == INVALID_HANDLE_VALUE )
{
Close();
return false;
}
//SetThreadPriority(m_hThread,THREAD_PRIORITY_LOWEST); //设置优先级
m_bConnect = true;
return true;
}
BOOL CCmpp3::Connect2()
{
sockaddr_in sAddr;
m_hSocket=socket(AF_INET,SOCK_STREAM,0);
sAddr.sin_family=AF_INET;
sAddr.sin_port=0;
sAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
return false;
}
sAddr.sin_port=htons((unsigned short)m_lPort);
sAddr.sin_addr.s_addr=inet_addr(m_szIP);
if (sAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(m_szIP);
if (lphost != NULL)
sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
Close();
return false;
}
}
if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
Close();
return false;
}
//设置Socket
u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET
//u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET
ioctlsocket( m_hSocket,FIONBIO,&ulTemp );
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
return true;
}
BOOL CCmpp3::isConnect()
{
return m_bConnect;
}
void CCmpp3::Stop()
{
m_bQuitThread = true;
if (m_hThread != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread,2000) == WAIT_TIMEOUT ) //等待5秒让线程退出
{
TerminateThread(m_hThread,0); //如果退出超时,强制结束线程
}
m_hThread = INVALID_HANDLE_VALUE;
if (m_hThread_Send != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread_Send,2000) == WAIT_TIMEOUT ) //等待5秒让线程退出
{
TerminateThread(m_hThread_Send,0); //如果退出超时,强制结束线程
}
m_hThread_Send = INVALID_HANDLE_VALUE;
Close();
}
BOOL CCmpp3::isSocketClose(SOCKET s)
{
BOOL bConnDropped = FALSE;
INT iRet = 0;
BOOL bOK = TRUE;
if (s == INVALID_SOCKET)
return TRUE;
struct timeval timeout = { 0, 0 };
fd_set readSocketSet;
FD_ZERO(&readSocketSet);
FD_SET(s, &readSocketSet);
iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
bOK = (iRet > 0);
if(bOK)
{
bOK = FD_ISSET(s, &readSocketSet);
}
if(bOK)
{
CHAR szBuffer[1] = "";
iRet = recv(s, szBuffer, 1, MSG_PEEK);
bOK = (iRet > 0);
if(!bOK)
{
INT iError = WSAGetLastError();
bConnDropped = (( iError == WSAENETRESET) ||
(iError == WSAECONNABORTED) ||
(iError == WSAECONNRESET) ||
(iError == WSAEINVAL) ||
(iRet == 0));
}
}
return(bConnDropped);
}
void CCmpp3::Close()
{
if ( m_hSocket == INVALID_SOCKET )
return;
if ( m_hSocket != INVALID_SOCKET )
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
m_bConnect = false;
//m_dwEndSendTime=0;
//m_dwEndRecvTime=0;
}
long CCmpp3::Send(SOCKET sock,BYTE *pData, long lLen)
{
#define SOCKET_SEND_TIMEOUT 10000 //10秒发送超时
if ( sock == INVALID_SOCKET )
return 0;
long lSended = 0;
DWORD lTimeOut = ::GetTickCount();
while ( 1 )
{
long lRet = send(sock,(char*)(pData+lSended), lLen-lSended,0);
if ( lRet == SOCKET_ERROR ) //发送错误
{
if ( GetLastError() != WSAEWOULDBLOCK ) //绶区已满
return SOCKET_ERROR;
}
if ( lRet > 0 )
{
lSended += lRet;
if ( lSended >= lLen )
break;
}
else
{
Sleep_Lu( 20 ); //绶冲区已满,稍等
}
if ( ::GetTickCount() - lTimeOut > SOCKET_SEND_TIMEOUT )
break;
}
return lSended;
}
DWORD WINAPI CCmpp3::SocketSend(LPVOID lParam)
{
CCmpp3 * pNet = (CCmpp3 *)lParam;
while ( !pNet->m_bQuitThread )
{
//发送短信
long lCount = pNet->Back_Send();
if ( lCount>0 )
Sleep_Lu(1);
else
Sleep_Lu(15);
}
return 1;
}
DWORD WINAPI CCmpp3::SocketRecv(LPVOID lParam)
{
CCmpp3 * pNet = (CCmpp3 *)lParam;
Cmpp3_Data_Recv Drecv={0};
pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
DWORD dwEndSend=GetTickCount();
while ( !pNet->m_bQuitThread )
{
BOOL bReConnect=false;
if ( isSocketClose(pNet->m_hSocket) )
{
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
if ( pNet->m_bInitCmpp3 ) //原已连接的,重新连接
{
bReConnect = true;
}
else
{
pNet->m_bLoginCmpp3 = -4; //对端断开连接,登录失败
}
}
if ( ReadFrame(pNet->m_hSocket,&Drecv) ) //判断是否有接收到新的Frame
{
pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
pNet->m_bRecvFrame = true;
pNet->RecvFrame(Drecv); //处理接收到的帧
Drecv.lDataLen = 0;
delete Drecv.pRecvFrame;
Drecv.pRecvFrame = NULL;
}
//判断接收是否超时
//if ( pNet->m_dwEndSendTime > 0 && !pNet->m_bRecvFrame)
if ( pNet->m_dwEndSendTime>0 && ::GetTickCount() - pNet->m_dwEndRecvTime >CMPP3_ACTIVE_TIMEOUT*2 ) //接收超时
{
pNet->m_dwEndRecvTime = ::GetTickCount()-CMPP3_ACTIVE_TIMEOUT; //如果接收超时,重新计数
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
bReConnect = true;
}
//判断是否应该发送Active_Test指令
if ( pNet->m_dwEndSendTime > 0 )
{
if ( ::GetTickCount() - pNet->m_dwEndSendTime > CMPP3_ACTIVE_TESTTIME ) //重新连接
{
ULONG lSeq=0;
pNet->SendFrame(pNet->m_hSocket,pNet->m_lID,pNet->m_dwEndSendTime, CMPP3_ACTIVE_TEST , NULL , 0 ,lSeq );
}
}
//发送短信
//pNet->Back_Send();
if ( bReConnect )
{
for ( int i=0 ; i<30 && !pNet->m_bQuitThread; i++ ) //延时5秒
{
Sleep_Lu(100);
}
pNet->SetErrMsg(_T("Cmpp3消息:正在重连网关..."));
if ( !pNet->m_bQuitThread )
pNet->InitCmpp32(); //重新连接到服务器
}
//Sleep_Lu(1);
}
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
pNet->Close();
return 1;
}
void CCmpp3::SetRecvProc(RECVPROC_Cmpp3 proc)
{
m_pRecvProc = proc;
}
BOOL CCmpp3::ReadFrame(SOCKET s, Cmpp3_Data_Recv *pRecv)
{
ULONG nBytes=0;
ioctlsocket(s,FIONREAD, &nBytes);
if (nBytes <= 0 )
{
Sleep_Lu(1); //没有数据,等待一段时间
return false;
}
if ( pRecv->lDataLen <= 0 && nBytes<= sizeof(pRecv->lDataLen) ) //未收够长度信息
{
Sleep_Lu(1); //没有数据,等待一段时间
return false;
}
long lRet;
if (pRecv->lDataLen <= 0 ) //未收到数据,现在开始接收
{
lRet = recv(s, (char*)&pRecv->lDataLen,sizeof(pRecv->lDataLen),0);
if ( lRet > 0 )
{
pRecv->lDataLen = ntohl(pRecv->lDataLen);
if ( pRecv->lDataLen > 0 )
{
if ( pRecv->pRecvFrame )
{
delete pRecv->pRecvFrame;
pRecv->pRecvFrame = NULL;
}
pRecv->pRecvFrame = new BYTE[pRecv->lDataLen];
*((long*)pRecv->pRecvFrame) = pRecv->lDataLen; //存好前4个字节
pRecv->lRecvLen = sizeof(pRecv->lDataLen);
}
}
}
else
{
//计算需要接收的总字节数
ULONG lBeRecv = pRecv->lDataLen-pRecv->lRecvLen;
lRet = recv(s,(char*)pRecv->pRecvFrame+pRecv->lRecvLen , lBeRecv ,0);
if ( lRet > 0 )
pRecv->lRecvLen += lRet ;
if ( pRecv->lRecvLen == pRecv->lDataLen ) //Frame 已收满
{
pRecv->lDataLen = 0; //重新开始接收
return true;
}
}
return false;
}
BOOL CCmpp3::RecvFrame(Cmpp3_Data_Recv &Drecv)
{
Cmpp3_Head * pHead=(Cmpp3_Head *)Drecv.pRecvFrame;
if ( pHead->Total_Length != Drecv.lRecvLen )
return false;
pHead->Command_Id = ntohl(pHead->Command_Id);
pHead->Sequence_Id= ntohl(pHead->Sequence_Id);
BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(Cmpp3_Head));
long lLen = pHead->Total_Length-sizeof(Cmpp3_Head);
long lRet = 0;
switch( pHead->Command_Id )
{
case CMPP3_CONNECT_RESP:
lRet = Process_Connect(*pHead,pData,lLen);
break;
case CMPP3_SUBMIT_RESP:
lRet = Process_Submit(*pHead,pData,lLen);
break;
case CMPP3_ACTIVE_TEST:
lRet = Process_Active(*pHead,pData,lLen);
break;
case CMPP3_DELIVER:
lRet = Process_Deliver(*pHead,pData,lLen);
break;
default:
break;
}
return lRet;
}
long CCmpp3::Cmpp3_Init(const char *pIP,long lPort, const char *pUser, const char *pPasswd,const char * pCorpID)
{
if ( !Connect(pIP,lPort) )
{
return -1; //连接服务器失败
}
//记录信息
strcpy(m_szCmpp3IP,pIP);
strcpy(m_szCmpp3User,pUser);
strcpy(m_szCmpp3Passwd,pPasswd);
strcpy(m_szCmpp3CorpID,pCorpID);
//生成Auth
UCHAR Auth[64]={0};
long lAdd=0;
strcpy((char*)Auth,pUser);
lAdd += (long)strlen(pUser);
lAdd += 9;
strcpy((char*)(Auth+lAdd),pPasswd);
lAdd += (long)strlen(pPasswd);
char str[256]={0};
SYSTEMTIME t;GetLocalTime(&t);
sprintf( str,"%02d%02d%02d%02d%02d",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
strcpy((char*)(Auth+lAdd),str);
lAdd += (long)strlen(str);
MD5_L md5;
BYTE bMd5[64]={0};
memcpy(bMd5 , md5.MD5Byte(Auth,lAdd),16);
Cmpp3_Connect connect={0};
strcpy(connect.Source_Addr,pUser);
//if ( atol(pUser)>=100000 && atol(pUser)<200000 ) //连接到短信易cmpp协议时不用加密
//memcpy(connect.AuthenticatorSource,pPasswd,strlen(pPasswd)<16?strlen(pPasswd):16);
if ( lPort == CMPP3_EXCHANGE_PORT || lPort == CMPP3_EXCHANGE_PORT2 ) //连接中转时,不用加密
;
else
memcpy(connect.AuthenticatorSource,bMd5,16);
connect.Version = 0x30;
connect.Timestamp = atol(str);
connect.Timestamp = htonl(connect.Timestamp);
m_bLoginCmpp3 = -1;
ULONG lSeq=0;
if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_CONNECT,(UCHAR*)&connect,sizeof(connect),lSeq) )
{
m_bQuitThread = true;
return -2; //发送数据失败
}
long lTime = ::GetTickCount();
while ( m_bLoginCmpp3 == -1 )
{
if ( ::GetTickCount()-lTime > 30000 ) //超时了
break;
Sleep_Lu(20);
}
if ( m_bLoginCmpp3==0 )
{
m_bInitCmpp3 = true; //已初始化
return m_bLoginCmpp3; //返回成功
}
if ( m_bLoginCmpp3 == -1 )
{
m_bQuitThread = true;
return -3; //登录超时
}
else
{
m_bQuitThread = true;
return m_bLoginCmpp3; //登录返回成功,具体请看错误码
}
m_bQuitThread = true;
return -4; //其它错误
}
long CCmpp3::SendFrame(SOCKET sock,ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR *pData, long lDataLen,ULONG & lSeq )
{
//EnterCriticalSection(&m_CriSendFrame); //防止冲突
Cmpp3_Head head={0};
long lAllLen;
head.Total_Length = sizeof(head)+lDataLen;
lAllLen = head.Total_Length;
head.Command_Id = lCommandID;
if ( lID >= 0xF000000 ) //重新开始序号
lID = 1;
if ( lSeq > 0 )
head.Sequence_Id = lSeq; //直接使用相同序号的发送
else
head.Sequence_Id = lID++;
lSeq = head.Sequence_Id; //返回
head.Total_Length = htonl(head.Total_Length);
head.Command_Id = htonl(head.Command_Id);
head.Sequence_Id = htonl(head.Sequence_Id);
dwEndSendTime = ::GetTickCount(); //记录最后发送时间
BYTE * pSData = new BYTE[lAllLen];
memcpy(pSData,&head,sizeof(head));
memcpy(pSData+sizeof(head),pData,lDataLen);
BOOL bOK = Send(sock,(BYTE*)pSData , lAllLen );
delete pSData;
long lRet = 0;
if ( bOK )
lRet = head.Sequence_Id;
//LeaveCriticalSection(&m_CriSendFrame); //防止冲突
return lRet;
}
long CCmpp3::Process_Connect(Cmpp3_Head head,BYTE *pData, long lLen)
{
Cmpp3_Connect_Resp * pResp = (Cmpp3_Connect_Resp *)pData;
#ifdef CMPP3_3_0
pResp->Status = ntohl(pResp->Status);
#endif
if ( m_bInitCmpp3 && pResp->Status != 0 ) //需要重新登录
{
//InitCmpp32();
//登录不成功,关闭连接
this->Close();
}
CString str;
str.Format(_T("Cmpp3消息:连接网关返回代码:%d") , pResp->Status );
SetErrMsg(str);
m_bLoginCmpp3 = pResp->Status;
return 1;
}
BOOL CCmpp3::SendSms(Cmpp3_Send_List sms)
{
for (int j = 0; j < 200; j++)
{
if (Sms_Add(sms))
return sms.lSendID;
/*
//从当前点到结尾
EnterCriticalSection(&m_CriSendSms); //防止冲突
for ( int i=0 ; i< SMS_MAX_LIST; i++ )
{
if ( m_pSendList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
sms.lSendTime = 0;
sms.lReSendCount = 0;
m_pSendList[i] = sms;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return sms.lSendID;
break;
}
}
LeaveCriticalSection(&m_CriSendSms); //防止冲突
*/
Sleep_Lu(20); //延时10秒
}
return false;
}
BOOL CCmpp3::InitCmpp32()
{
m_bLoginCmpp3 = -1;
if ( !Connect2() )
{
return false; //连接服务器失败
}
//生成Auth
UCHAR Auth[64]={0};
long lAdd=0;
strcpy((char*)Auth,m_szCmpp3User);
lAdd += (long)strlen(m_szCmpp3User);
lAdd += 9;
strcpy((char*)(Auth+lAdd),m_szCmpp3Passwd);
lAdd += (long)strlen(m_szCmpp3Passwd);
char str[256]={0};
SYSTEMTIME t;GetLocalTime(&t);
sprintf( str,"%02d%02d%02d%02d%02d",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
strcpy((char*)(Auth+lAdd),str);
lAdd += (long)strlen(str);
MD5_L md5;
BYTE bMd5[64]={0};
memcpy(bMd5 , md5.MD5Byte(Auth,lAdd),16);
Cmpp3_Connect connect={0};
strcpy(connect.Source_Addr,m_szCmpp3User);
//if ( atol(m_szCmpp3User)>=100000 && atol(m_szCmpp3User)<200000 ) //连接到短信易cmpp协议时不用加密
//memcpy(connect.AuthenticatorSource,m_szCmpp3Passwd,strlen(m_szCmpp3Passwd)<16?strlen(m_szCmpp3Passwd):16);
if ( m_lPort == CMPP3_EXCHANGE_PORT || m_lPort == CMPP3_EXCHANGE_PORT2 )
;
else
memcpy(connect.AuthenticatorSource,bMd5,16);
connect.Version = 0x30;
connect.Timestamp = atol(str);
connect.Timestamp = htonl(connect.Timestamp);
m_bLoginCmpp3 = -1;
ULONG lSeq=0;
if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_CONNECT,(UCHAR*)&connect,sizeof(connect),lSeq) )
return -2; //发送数据失败
//重新连接时,需要重发短信
// memset(m_pSendList,0,sizeof(Cmpp3_Send_List)*CMPP3_SMS_MAX_LIST);
/*
for ( int i=0 ; i< CMPP3_SMS_MAX_LIST ;i++ )
{
if ( m_pSendList[i].lSendID > 0 )
{
m_pSendList[i].lReSendCount = 0;
m_pSendList[i].lSendTime = 0;
m_pSendList[i].lSeq = 0;
}
}
*/
return -4; //其它错误
}
long CCmpp3::Back_Send()
{
/*
//因为上层会判断超时,即使网关断线情况下仍要继续发送
if ( m_bLoginCmpp3 != 0 ) //还没登录成功,不能发短信
{
return 0;
}
*/
long lCount = 0;
for (int i = 0; i < 100; i++)
{
Cmpp3_Send_List* pSend = 0;
if (Sms_Get(pSend) && pSend)
{
BOOL bSend = false;
if (pSend->lReSendCount > 0) //前已发送过,看是否到达重发时间
{
if (::GetTickCount() - pSend->lSendTime > CMPP3_SENDSMS_TIMEOUT)
bSend = true;
else
bSend = false;
}
else
{
bSend = true; //第一次发送
}
if (bSend)
{
if (pSend->lReSendCount >= CMPP3_SENDSMS_RECOUNT) //发送失败
{
//插入发送返回
Cmpp3_Send_Resp Resp = { 0 };
Resp.lSendID = pSend->lSendID;
Resp.lReSendCount = pSend->lReSendCount;
Resp.lResult = -1; //发送失败
SendResp_Add(Resp);
pSend->lSendID = 0; //已删除
}
else
{
if (m_lSendInterval > 0) //控制发送速度
{
m_lSendIntervalIndex++;
if (m_lSendIntervalIndex >= m_lSendIntervalCount)
{
Sleep_Lu(m_lSendInterval);
m_lSendIntervalIndex = 0;
}
}
m_dwEndSocketSendTime = GetTickCount(); //用于控制发送速度
//以下为群发
//sendList.AddTail(pSend);
//lCount ++;
//以下为单发
if (Socket_SendSms(pSend))
lCount++;
}
}
}
else
{
break;
}
}
/*
if ( m_bLoginCmpp3 != 0 ) //还没登录成功,不能发短信
return 0;
CSendList_Cmpp3 sendList;
EnterCriticalSection(&m_CriSendSms); //防止冲突
long lCount = 0;
for ( int i=0 ; i< CMPP3_SMS_MAX_LIST;i++ )
{
Cmpp3_Send_List * pSend = &m_pSendList[i];
if ( pSend->lSendID == 0 )
continue;
BOOL bSend = false;
if ( pSend->lReSendCount > 0 ) //前已发送过,看是否到达重发时间
{
if ( ::GetTickCount()-pSend->lSendTime>CMPP3_SENDSMS_TIMEOUT )
bSend = true;
else
bSend = false;
}
else
{
bSend = true; //第一次发送
}
if ( bSend )
{
if ( pSend->lReSendCount >= CMPP3_SENDSMS_RECOUNT ) //发送失败
{
//插入发送返回
Cmpp3_Send_Resp Resp={0};
Resp.lSendID = pSend->lSendID;
Resp.lReSendCount = pSend->lReSendCount;
Resp.lResult = -1; //发送失败
SendResp_Add(Resp);
pSend->lSendID = 0 ; //已删除
}
else
{
if (m_lSendInterval>0 ) //控制发送速度
{
long lDelay=m_lSendInterval-(long)(GetTickCount()-m_dwEndSocketSendTime);
if ( lDelay>0 && lDelay<m_lSendInterval+5 )
//Sleep_Lu(lDelay-lDelay/15);
Sleep_Lu(lDelay);
}
m_dwEndSocketSendTime = GetTickCount(); //用于控制发送速度
//以下为群发
//sendList.AddTail(pSend);
//lCount ++;
//以下为单发
if ( Socket_SendSms(pSend) )
lCount ++;
}
}
}
LeaveCriticalSection(&m_CriSendSms); //防止冲突
//以下为群发开始发送
/*
if ( sendList.IsEmpty() )
return lCount;
lCount = sendList.GetCount();
long lSize = (sizeof(Cmpp3_Head)+sizeof(Cmpp3_Submit)+200)*lCount;
BYTE * pData = new BYTE[lSize];
memset(pData,0,lSize);
//生成短信包
long lSmsPickLen=0;
while(!sendList.IsEmpty())
{
Cmpp3_Send_List * pSend = sendList.RemoveHead();
#ifdef CMPP3_3_0
long lDataLen = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+20; //计算发送信息的总长度
#else
long lDataLen = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+8; //计算发送信息的总长度
#endif
Cmpp3_Head head={0};
long lAllLen;
ULONG lSeq=0;
head.Total_Length = sizeof(head)+lDataLen;
lAllLen = head.Total_Length;
head.Command_Id = CMPP3_SUBMIT;
if ( m_lID >= 0xF000000 ) //重新开始序号
m_lID = 1;
if ( lSeq > 0 )
head.Sequence_Id = lSeq; //直接使用相同序号的发送
else
head.Sequence_Id = m_lID++;
lSeq = head.Sequence_Id; //返回
head.Total_Length = htonl(head.Total_Length);
head.Command_Id = htonl(head.Command_Id);
head.Sequence_Id = htonl(head.Sequence_Id);
m_dwEndSendTime = ::GetTickCount(); //记录最后发送时间
//BYTE * pSData = new BYTE[lAllLen];
//添加头
memcpy(pData+lSmsPickLen,&head,sizeof(head));lSmsPickLen = lSmsPickLen + sizeof(head);
//submit头
memcpy(pData+lSmsPickLen,(void*)&pSend->Submit,sizeof(Cmpp3_Submit));lSmsPickLen = lSmsPickLen + sizeof(Cmpp3_Submit);
//短信内容
memcpy(pData+lSmsPickLen,pSend->Msg,pSend->Submit.Msg_Length);lSmsPickLen = lSmsPickLen + pSend->Submit.Msg_Length;
#ifdef CMPP3_3_0
lSmsPickLen += 20;
#else
lSmsPickLen += 8;
#endif
pSend->lReSendCount ++;
pSend->lSendTime = ::GetTickCount();
pSend->lSeq = lSeq;
}
EnterCriticalSection(&m_CriSendFrame); //防止冲突
BOOL bOK = Send(m_hSocket,(BYTE*)pData , lSmsPickLen );
LeaveCriticalSection(&m_CriSendFrame); //防止冲突
delete pData;
*/
return lCount;
}
BOOL CCmpp3::Socket_SendSms(Cmpp3_Send_List *pSend)
{
#ifdef CMPP3_3_0
long lSize = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+20; //计算发送信息的总长度
#else
long lSize = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+8; //计算发送信息的总长度
#endif
BYTE * pData = new BYTE[lSize];
memset(pData,0,lSize);
Cmpp3_Submit * pSubmit = (Cmpp3_Submit*)pData;
BYTE * pMsg = (BYTE*)(pData+sizeof(Cmpp3_Submit));
*pSubmit = pSend->Submit;
memcpy(pMsg,pSend->Msg,pSend->Submit.Msg_Length);
ULONG lSeq=0;
BOOL b = SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_SUBMIT,pData,lSize,lSeq);
//if ( b )
//{
pSend->lReSendCount ++;
pSend->lSendTime = ::GetTickCount();
pSend->lSeq = lSeq;
//}
delete pData;
return b;
}
long CCmpp3::Process_Submit(Cmpp3_Head head,BYTE *pData, long lLen)
{
Cmpp3_Submit_Resp * pResp = (Cmpp3_Submit_Resp *)pData;
/*
CString str;
str.Format( "提交短信返回代码:%d" , pResp->Result );
AfxMessageBox(str);
*/
#ifdef CMPP3_3_0
pResp->Result = ntohl(pResp->Result);
#endif
//收到发送返回,在队列中查找发送信息
Cmpp3_Send_List * pSendSms = NULL;
BOOL bFind = false;
ULONG lSeq = head.Sequence_Id;
for ( int i=0 ; i< CMPP3_SMS_MAX_LIST;i++ )
{
pSendSms = &m_pSendList[i];
if ( pSendSms->lSendID!=0 && pSendSms->lSeq == lSeq )
{
bFind = true;
break;
}
}
if ( bFind )
{
if ( pSendSms->lSendID <= MAX_CMPP3EXCHANGE+10 ) //小于-100表示cmpp转接所发
{
Cmpp3ExchangeResp resp={0};
resp.lType = 0;
resp.lSendID = pSendSms->lSendID;
resp.lLen = lLen;
resp.lCmd = head.Command_Id;
resp.lSeq = pSendSms->lCmpp3Seq;
memcpy(resp.Data , pData , lLen );
Cmpp3ExchangeResp_Add(resp);
pSendSms->lSendID = 0; //删除此记录
}
else
{
Cmpp3_Send_Resp Resp={0};
Resp.lSendID = pSendSms->lSendID;
Resp.lReSendCount = pSendSms->lReSendCount;
ULONG * lMsgID1 = (ULONG*)&pResp->Msg_ID;
ULONG * lMsgID2 = (ULONG*)((char*)&pResp->Msg_ID+sizeof(long));
ULONG * lMsgID21= (ULONG*)&Resp.lMsgID;
ULONG * lMsgID22= (ULONG*)((char*)&Resp.lMsgID+sizeof(long));
//取ID
*lMsgID21 = ntohl(*lMsgID2);
*lMsgID22 = ntohl(*lMsgID1);
//pSend->lMsgID = pResp->Msg_ID;
Resp.lResult = pResp->Result;
SendResp_Add(Resp);
pSendSms->lSendID = 0; //删除此记录
}
}
return 1;
}
BOOL CCmpp3::GetSendResp(Cmpp3_Send_Resp &resp)
{
EnterCriticalSection(&m_CriRespList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lRespList ; i< CMPP3_SMS_MAX_RESP; i++ )
{
if ( m_pRespList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lRespList = i+1;
resp = m_pRespList[i];
m_pRespList[i].lSendID = 0;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lRespList; i++ )
{
if ( m_pRespList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lRespList = i+1;
resp = m_pRespList[i];
m_pRespList[i].lSendID = 0;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
m_lRespList = 0;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return false;
}
long CCmpp3::Process_Active(Cmpp3_Head head, BYTE *pData, long lLen)
{
m_dwTestCount = 0; //收到active指令检测次数为0
Cmpp_Active_Test_Resp resp = { 0 };
resp.Reserved = 0;
ULONG lReq = head.Sequence_Id;
SendFrame(m_hSocket, m_lID, m_dwEndSendTime, CMPP_ACTIVE_TEST_RESP, (BYTE*)&resp, sizeof(resp), lReq);
return 1;
}
long CCmpp3::Process_Deliver(Cmpp3_Head head, BYTE *pData, long lLen)
{
Cmpp3_Deliver * pDeliver = (Cmpp3_Deliver *)pData;
BYTE * pMsgData = pData+sizeof(Cmpp3_Deliver);
//判断是否cmpp转接的短信内容
BOOL bExchange=false;
if ( m_pCmppExchange )
{
long lExNum=0;
if ( m_bAdc /*&& pDeliver->Registered_Delivery*/ ) //只转发状态报告,上行短信不转发
{
char szTemp[32]={0};
strcpy( szTemp , (char*)pDeliver->Dest_Id+10 );
szTemp[4]=0;
lExNum = atol(szTemp);
if ( lExNum>=3800 && lExNum<4499 && lExNum!=4474 )
{
strcpy(szTemp , (char*)pDeliver->Dest_Id+14 );
szTemp[6]=0;
sprintf((char*)pDeliver->Dest_Id , "1065710055%s",szTemp ); //这类特殊的转换直接使用总端口
}
}
for ( int i=0 ; i<m_lCmppExchange;i++ )
{
if (m_pCmppExchange[i].sock != 0 && m_pCmppExchange[i].sock != INVALID_SOCKET &&
strlen(m_pCmppExchange[i].szNum) &&
!strncmp((char*)pDeliver->Dest_Id,m_pCmppExchange[i].szNum,strlen(m_pCmppExchange[i].szNum) ) )
{
Cmpp3ExchangeResp resp={0};
resp.lType = 1;
strcpy(resp.szNum , m_pCmppExchange[i].szNum );
resp.lExNum = lExNum; //adc特殊转发时用到
resp.lLen = lLen;
resp.lCmd = head.Command_Id;
resp.lSeq = head.Sequence_Id;
memcpy(resp.Data , pData , lLen );
Cmpp3ExchangeResp_Add(resp);
bExchange = true;
break;
}
}
}
if ( !bExchange)
{
Cmpp3_Deliver_List Deliver={0};
Deliver.lSendID = 1;
//取ID
ULONG * lMsgID1 = (ULONG*)&pDeliver->Msg_ID;
ULONG * lMsgID2 = (ULONG*)((char*)&pDeliver->Msg_ID+sizeof(long));
ULONG * lMsgID21= (ULONG*)&Deliver.deliver.Msg_ID;
ULONG * lMsgID22= (ULONG*)((char*)&Deliver.deliver.Msg_ID+sizeof(long));
*lMsgID21 = ntohl(*lMsgID2);
*lMsgID22 = ntohl(*lMsgID1);
strcpy((char*)Deliver.deliver.Dest_Id , (char*)pDeliver->Dest_Id);
strcpy((char*)Deliver.deliver.Service_Id , (char*)pDeliver->Service_Id);
Deliver.deliver.TP_pid = pDeliver->TP_pid;
Deliver.deliver.TP_udhi = pDeliver->TP_udhi;
Deliver.deliver.Msg_Fmt = pDeliver->Msg_Fmt;
strcpy((char*)Deliver.deliver.Src_terminal_Id,(char*)pDeliver->Src_terminal_Id);
Deliver.deliver.Registered_Delivery = pDeliver->Registered_Delivery;
Deliver.deliver.Msg_Length = pDeliver->Msg_Length;
memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容
/*
if ( pMsgData[0] == 0x59 && pMsgData[1] == 0x4E && (pMsgData[2] >= 0x01 && pMsgData[2] <= 0x04) && (pMsgData[3] >= 0x01 && pMsgData[3] <= 0x31) )
{
if ( Deliver.deliver.Msg_Length > 70 )
Deliver.deliver.Msg_Length = 70;
AsciiToHex((char*)pMsgData,(TCHAR*)Deliver.szMsg,Deliver.deliver.Msg_Length); //转换成hex码
Deliver.deliver.Msg_Length= Deliver.deliver.Msg_Length*2;
Deliver.deliver.Msg_Fmt = 0; //改变编码
//memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length );
}
else
{
memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容
}
*/
memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容
if ( Deliver.deliver.Registered_Delivery ) //是状态报告
{
memcpy(&Deliver.status,pMsgData,sizeof(Deliver.status));
/*
CString str;
str.Format( "状态报告返回代码:%s" , Deliver.status.Stat );
AfxMessageBox(str);
*/
//取ID
LONGLONG lTemp;
ULONG * lMsgID1 = (ULONG*)&Deliver.status.Msg_ID;
ULONG * lMsgID2 = (ULONG*)((char*)&Deliver.status.Msg_ID+sizeof(long));
ULONG * lMsgID21= (ULONG*)&lTemp;
ULONG * lMsgID22= (ULONG*)((char*)&lTemp+sizeof(long));
*lMsgID21 = ntohl(*lMsgID2);
*lMsgID22 = ntohl(*lMsgID1);
Deliver.status.Msg_ID = lTemp;
Status_Add(Deliver); //添加到列表
}
else
{
/*
if (Deliver.deliver.Msg_Fmt == 8 ) //ucs2,要编码
{
memset(Deliver.szMsg,0,sizeof(Deliver.szMsg));
UCS2ToAscii2((char*)pMsgData,(char*)Deliver.szMsg,Deliver.deliver.Msg_Length);
}
*/
Deliver_Add(Deliver); //添加到列表
}
}
//发送返回
Cmpp3_Deliver_Resp resp={0};
resp.Msg_ID = pDeliver->Msg_ID;
resp.Result = 0;
ULONG lReq=head.Sequence_Id;
SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_DELIVER_RESP,(BYTE*)&resp,sizeof(resp),lReq);
return true;
}
BOOL CCmpp3::GetDeliver(Cmpp3_Deliver_List &deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lDeliverList ; i< CMPP3_SMS_MAX_DELIVER; i++ )
{
if ( m_pDeliverList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lDeliverList = i+1;
deliver = m_pDeliverList[i];
m_pDeliverList[i].lSendID = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lDeliverList; i++ )
{
if ( m_pDeliverList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lDeliverList = i+1;
deliver = m_pDeliverList[i];
m_pDeliverList[i].lSendID = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
m_lDeliverList = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
BOOL CCmpp3::Cmpp3_Exit()
{
m_bInitCmpp3 = false; //已初始化
ULONG lSeq=0;
SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_TERMINATE,NULL,0,lSeq);
Stop(); //停止
return true;
}
void CCmpp3::UCS2ToAscii2(char *pUCS2, char *pAscii, long lSrcLen)
{
UINT nLen = 0;
for(int i = 0; i < lSrcLen/2; i++)
*((unsigned short*)pUCS2 + i) = ntohs(*((unsigned short*)pUCS2 + i));
nLen = WideCharToMultiByte(936, WC_COMPOSITECHECK,
(WCHAR*)pUCS2, lSrcLen/2, pAscii,lSrcLen, NULL, NULL);
}
BOOL CCmpp3::SendResp_Add(Cmpp3_Send_Resp resp)
{
EnterCriticalSection(&m_CriRespList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lRespList ; i< CMPP3_SMS_MAX_RESP; i++ )
{
if ( m_pRespList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pRespList[i] = resp;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lRespList; i++ )
{
if ( m_pRespList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pRespList[i] = resp;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriRespList); //防止冲突
return false;
}
BOOL CCmpp3::Deliver_Add(Cmpp3_Deliver_List Deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lDeliverList ; i< CMPP3_SMS_MAX_DELIVER; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lDeliverList; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
long CCmpp3::Cmpp3_SendSms(const char * SendNo , const char * RecvNo,long Msg_Fmt,long udhi,long Msg_Length,BOOL bHandFree,const BYTE * Msg ,const char * Service_Id,long Fee_UserType,const char * FeeType, const char * FeeCode ,long Registered_Delivery,const char *ValId_Time,const char *At_Time,long lSendID,char * MsgID, BOOL bNo86)
{
if ( !m_bInitCmpp3 )
return -1; //接口未初始化或暂时断开连接
//m_lSendID ++; //发送ID加1
m_lSendID = lSendID; //使用传过来的ID
Cmpp3_Send_List list={0};
list.lSendID = m_lSendID; //SendID
list.Submit.Pk_total = 1; //*相同Msg_id的消息总条数从1开始*/
list.Submit.Pk_number = 1; /*相同Msg_id的消息序号从1开始*/
list.Submit.Registered_Delivery =(unsigned char )Registered_Delivery;//状态报告
list.Submit.Msg_level = 0; //信息级别
strcpy((char*)list.Submit.Service_Id,Service_Id); //业务类型
list.Submit.Fee_UserType = (unsigned char )Fee_UserType; /*计费用户类型2对SP计费*/
//list.Submit.Fee_terminal_Id /*计费用户终端*/
list.Submit.TP_pId = 0; /*协议类型缺省为0。*/
list.Submit.TP_udhi = (UCHAR)udhi; /*用于长短消息表示UserData是否是结构,0,正常,1结构*/
list.Submit.Msg_Fmt = 0; //编码类型
strcpy((char*)list.Submit.Msg_src , m_szCmpp3CorpID ); //企业ID
strcpy((char*)list.Submit.FeeType , FeeType );
strcpy((char*)list.Submit.FeeCode , FeeCode );
list.Submit.DestUsr_tl = 1; //接收用户数量
//取原地址类型并转换
strcpy( (char*)list.Submit.Src_Id , SendNo );
if (bNo86)
{
strcpy((char*)list.Submit.Dest_terminal_Id, RecvNo);
}
else
{
//取目标地址类型并转换
if (RecvNo[0] == '0') //小灵通不用加86
strcpy((char*)list.Submit.Dest_terminal_Id, RecvNo);
else
GetMobilePhoneTON(RecvNo, (char*)list.Submit.Dest_terminal_Id);
//strcpy( (char*)list.Submit.Fee_terminal_Id , (char*)list.Submit.Dest_terminal_Id );
//strcpy( (char*)list.Submit.Dest_terminal_Id , _T("8676986585118" ) );
}
//定时时间
if ( At_Time )
{
//040916165000032+
sprintf( (char*)list.Submit.At_Time , At_Time);
}
//超时时间
if ( ValId_Time )
{
//040916165000032+
sprintf( (char*)list.Submit.ValId_Time , ValId_Time);
}
char * pMsgSrc= (char*)Msg;
char * pMsgOK = (char*)list.Msg;
long ludhiLen=0;
if ( list.Submit.TP_udhi == 1 )
{
memcpy(pMsgOK,pMsgSrc,6); //原字节头
list.Submit.Pk_total = pMsgOK[4]; //*相同Msg_id的消息总条数从1开始*/
list.Submit.Pk_number = pMsgOK[5]; /*相同Msg_id的消息序号从1开始*/
pMsgSrc = pMsgSrc+6;
pMsgOK = pMsgOK+6; //采用6位数的短信分隔
ludhiLen = 6;
}
if ( Msg_Fmt==0 && Msg_Length==0 )
{
//取编码方式
//if ( isChinese((char*)pMsgSrc,strlen((char*)pMsgSrc) ) )
if ( true )
{
if ( bHandFree )
list.Submit.Msg_Fmt = 0x18;//UCS2编码
else
list.Submit.Msg_Fmt = 8;//UCS2编码
//list.Submit.Msg_Fmt = 25;//UCS2编码
unsigned short * pusSrc = (unsigned short *)pMsgSrc;
unsigned short * pusTag = (unsigned short *)pMsgOK;
long lSrcLen = (long)wcslen((WCHAR*)pMsgSrc);
if ( lSrcLen>(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2);
for ( int i=0 ; i<lSrcLen ; i++ )
{
pusTag[i] = htons(pusSrc[i]);
}
//wcscpy((WCHAR*)pMsgOK,(WCHAR*)pMsgSrc);
//((WCHAR*)pMsgOK)[70]=0;
list.Submit.Msg_Length = (UCHAR)(lSrcLen*2+ludhiLen);
}
else
{
if ( bHandFree )
list.Submit.Msg_Fmt = 0x10;//7Bit编码
else
list.Submit.Msg_Fmt = 0;//7Bit编码
char szBuf[1024]={0};
UCS2ToAscii((WCHAR*)pMsgSrc,szBuf);
char * pMsg = (char*)szBuf;
pMsg[160]=0; //防止短信超界
list.Submit.Msg_Length = (UCHAR)(strlen((char*)pMsg)+ludhiLen);
strcpy((char*)pMsgOK,(char*)pMsg);
}
}
else
{
list.Submit.Msg_Fmt = (unsigned char)Msg_Fmt;//hex编码
if ( list.Submit.Msg_Fmt == 4 ) //Hex编码
{
list.Submit.Msg_Length = (unsigned char)(Msg_Length/2);
HexToAscii((const char*)pMsgSrc,(char*)pMsgOK);
//memcpy(list.Msg,Msg,Msg_Length);
}
else
{
unsigned short * pusSrc = (unsigned short *)pMsgSrc;
unsigned short * pusTag = (unsigned short *)pMsgOK;
long lSrcLen = (long)wcslen((WCHAR*)pMsgSrc);
if ( lSrcLen>(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2);
for ( int i=0 ; i<lSrcLen ; i++ )
{
pusTag[i] = htons(pusSrc[i]);
}
//wcscpy((WCHAR*)pMsgOK,(WCHAR*)pMsgSrc);
//((WCHAR*)pMsgOK)[70]=0;
list.Submit.Msg_Length = (UCHAR)(lSrcLen*2+ludhiLen);
}
}
return SendSms(list); //加入发送列表
/*
//以下检测发送返回
DWORD dwTime = ::GetTickCount();
while ( ::GetTickCount()-dwTime < CMPP3_SENDSMS_TIMEOUT + 5000 )
{
Send_Resp resp={0};
if ( GetSendResp(resp) &&
resp.lSendID == m_lSendID)
{
sprintf( MsgID , "%I64u" , resp.lMsgID );
return resp.lResult; //发送成功返回cmpp的返回参数
}
Sleep_Lu( 100 );
}
return -3; //发送超时
*/
}
unsigned char CCmpp3::GetMobilePhoneTON(const char *pSrc, char *pOrg)
{
char szTemp[32]={0};
long lBegin = 0;
long lLen = (long)strlen( pSrc );
unsigned lTON = 2; //2,国内号码,1,国际号码
if ( pSrc[0] == '+')
lBegin = 1; //去除"+"号
if ( pSrc[lBegin] == '0' && pSrc[lBegin+1] == '0' )
lBegin += 2; //去除"00"
strcpy( szTemp , pSrc+lBegin ); //复制去除"+"号与"00"的号码
if ( szTemp[0]=='8' && szTemp[1] =='6' ) //所有号码都要加86开头
{
strcpy( pOrg,szTemp);
}
else
{
#ifdef CMPP3_3_0
sprintf( pOrg , "%s",szTemp);
#else
sprintf( pOrg , "86%s",szTemp);
#endif
}
// if ( pSrc[lBegin]=='8' && pSrc[lBegin+1] =='6' ) //因为86开头号码为国际码
// lTON = 1; //国际编码
return lTON;
}
BOOL CCmpp3::isChinese(const TCHAR *pSrc, long lSrcLen)
{
long lLen = lSrcLen;
if ( lLen <=0 )
lLen = (long)_tcslen(pSrc);
#ifdef _UNICODE
for ( long i=0 ; i<lLen ; i++ )
{
if ( (BYTE)pSrc[i]>128 )
{
return true;
}
}
return false;
#else
char szBuf[4096];
long l = MultiByteToWideChar( CP_ACP,NULL,pSrc,lLen, (LPWSTR)szBuf , sizeof(szBuf) );
if ( l == lLen )
return false;
else
return true;
#endif
}
long CCmpp3::AsciiToUCS2(const char *pAscii, WCHAR *pUCS2)
{
long lLen = (long)strlen( pAscii );
long l = MultiByteToWideChar( CP_ACP,NULL,pAscii,lLen, pUCS2 , 4096 );
pUCS2[l]=0;
return l;
}
void CCmpp3::HexToAscii(const char *pszOrgRandom, char *pszDesRandom)
{
char Buf[4];
char *pDes = (char *)pszDesRandom;
char *pOrg = (char *)pszOrgRandom;
long lLen = (long)strlen( pOrg);
long lTemp;
int i=0;
for( i = 0; i < lLen/2; ++i )
{
memcpy( Buf , pOrg+i*2 , 2 );
Buf[2] = 0;
lTemp = CharHex(Buf[0])*16 + CharHex(Buf[1]);
pDes[i] = (char)lTemp;
}
pDes[i] = 0;
}
void CCmpp3::ExchangeUniCode(char *pData)
{
char pEx[4];
long lLen = (long)strlen( pData );
for ( int i = 0 ; i< lLen/4 ; i++ )
{
memcpy( pEx , pData+i*4 , 2 );
memcpy( pData+i*4 , pData+i*4+2 , 2 );
memcpy( pData+i*4+2 , pEx , 2 );
}
}
void CCmpp3::AsciiToHex(const char *pszOrgRandom, TCHAR *pszDesRandom, long lLen)
{
#ifdef _UNICODE
TCHAR *p = (TCHAR *)pszDesRandom;
//long lLen = lstrlen( (char*)pszOrgRandom);
for( long i = 0; i < lLen; ++i )
{
_stprintf(p, _T("%02X"), (BYTE)pszOrgRandom[i] );
p += 2;
}
*p=0;
#else
char *p = (char *)pszDesRandom;
//long lLen = lstrlen( (char*)pszOrgRandom);
for( long i = 0; i < lLen; ++i )
{
sprintf(p, "%02X", (BYTE)pszOrgRandom[i] );
p += 2;
}
*p=0;
#endif
}
int CCmpp3::CharHex(char ch)
{
//if( isdigit( ch ) ) return( atoi( &ch) );
if( ch >='0' && ch <= '9' ) return( atoi( &ch) );
else {
if( ch == 'a' || ch == 'A' ) return( 10 );
if( ch == 'b' || ch == 'B' ) return( 11 );
if( ch == 'c' || ch == 'C' ) return( 12 );
if( ch == 'd' || ch == 'D' ) return( 13 );
if( ch == 'e' || ch == 'E' ) return( 14 );
if( ch == 'f' || ch == 'F' ) return( 15 );
}
return( 0 );
}
BOOL CCmpp3::GetStatus(Cmpp3_Deliver_List &deliver)
{
EnterCriticalSection(&m_CriStatusList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lStatusList ; i< CMPP3_SMS_MAX_STATUS; i++ )
{
if ( m_pStatusList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lStatusList = i+1;
deliver = m_pStatusList[i];
m_pStatusList[i].lSendID = 0;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lStatusList; i++ )
{
if ( m_pStatusList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lStatusList = i+1;
deliver = m_pStatusList[i];
m_pStatusList[i].lSendID = 0;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
m_lStatusList = 0;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return false;
}
BOOL CCmpp3::Status_Add(Cmpp3_Deliver_List Deliver)
{
EnterCriticalSection(&m_CriStatusList); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lStatusList ; i< CMPP3_SMS_MAX_STATUS; i++ )
{
if ( m_pStatusList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pStatusList[i] = Deliver;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lStatusList; i++ )
{
if ( m_pStatusList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pStatusList[i] = Deliver;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return false;
}
long CCmpp3::Cmpp3_Get(TCHAR *SendNo,TCHAR * RecvNo, BYTE *Msg, TCHAR *Msg_Fmt, TCHAR *Msg_Length ,long & lLongMsgRand ,long & lLongMsgAll, long & lLongMsgIndex)
{
Cmpp3_Deliver_List deliver={0};
if ( GetDeliver(deliver) )
{
#ifdef _UNICODE
_tcsncpy( SendNo , CA2W((char*)deliver.deliver.Src_terminal_Id),21 );
_tcsncpy( RecvNo , CA2W((char*)deliver.deliver.Dest_Id),21 );
#else
_tcsncpy( SendNo , (char*)deliver.deliver.Src_terminal_Id, 21);
_tcsncpy( RecvNo , (char*)deliver.deliver.Dest_Id, 21);
#endif
BYTE * pMsg = (BYTE *)deliver.szMsg;
long lMsgLen=deliver.deliver.Msg_Length;
//if ( deliver.deliver.TP_udhi == 1 ) //判断是否长短信
//{
if ( pMsg[0]==5 && pMsg[1]==0 && pMsg[2]==3 )
{
lLongMsgRand = pMsg[3];
lLongMsgAll = pMsg[4];
lLongMsgIndex = pMsg[5];
pMsg = pMsg+6;
lMsgLen -=6;
}
if ( pMsg[0]==6 && pMsg[1]==8 && pMsg[2]==4 )
{
lLongMsgRand = pMsg[3]*100+pMsg[4];
lLongMsgAll = pMsg[5];
lLongMsgIndex = pMsg[6];
pMsg = pMsg+7;
lMsgLen -=7;
}
//}
if ( Msg_Fmt==NULL && Msg_Length==NULL ) //自动取内容
{
if (deliver.deliver.Msg_Fmt == 15 ) //gbk编码
{
_tcscpy((WCHAR*)Msg,CA2W((char*)pMsg));
}
else
{
if (deliver.deliver.Msg_Fmt & 8 ) //ucs2,要编码
{
unsigned short * pusSrc = (unsigned short *)pMsg;
unsigned short * pusTag = (unsigned short *)Msg;
long lSrcLen = lMsgLen/2;
for ( int i=0 ; i<lSrcLen ; i++ )
{
pusTag[i] = ntohs(pusSrc[i]);
}
//UCS2ToAscii2((char*)pMsg,(char*)Msg,lMsgLen);
}
else
{
if (deliver.deliver.Msg_Fmt & 4 )// hex编码
{
_tcscpy((TCHAR*)Msg,_T("HEX16:"));
if ( deliver.deliver.Msg_Length>70 )
deliver.deliver.Msg_Length=70;
AsciiToHex((const char*)pMsg,((TCHAR*)Msg)+6,lMsgLen);
//AsciiToHex((const char*)pMsg,(char*)Msg+6,lMsgLen);
}
else
{
_tcscpy((WCHAR*)Msg,CA2W((char*)pMsg));
//AsciiToUCS2((const char*)pMsg , (TCHAR*)Msg);
//memcpy(Msg,pMsg,lMsgLen);
}
}
}
return 0;
}
else
{
AsciiToHex((const char*)deliver.szMsg,(TCHAR*)Msg,deliver.deliver.Msg_Length); //转换成Hex编码
//memcpy(Msg,deliver.szMsg,deliver.deliver.Msg_Length);
if ( Msg_Fmt )
_stprintf( Msg_Fmt , _T("%d") , deliver.deliver.Msg_Fmt );
if ( Msg_Length )
_stprintf( Msg_Length , _T("%d") , deliver.deliver.Msg_Length*2 );
return 0;
}
}
return -1; //没有信息
}
long CCmpp3::Cmpp3_GetReport(TCHAR *No, TCHAR *Stat, TCHAR *Done_time, TCHAR *MsgID)
{
Cmpp3_Deliver_List deliver={0};
if ( GetStatus(deliver) )
{
_tcscpy( No , CA2W((char*)deliver.status.Dest_terminal_Id) );
//strcpy( Stat , (char*)deliver.status.Stat );
_tcsncpy( Stat , CA2W((char*)deliver.status.Stat) , 7 );
//strcpy( Done_time , (char*)deliver.status.Done_time );
_tcsncpy( Done_time , CA2W((char*)deliver.status.Done_time) , 10 );
_stprintf( MsgID , _T("%I64u") , deliver.status.Msg_ID );
return 0;
}
return -1; //没有信息
}
BOOL CCmpp3::GetCmpp3ExchangeResp(Cmpp3ExchangeResp &resp)
{
EnterCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lCmpp3ExchangeRespList ; i< CMPP3_SMS_MAX_CMPP3EXCHANGERESP; i++ )
{
if ( m_pCmpp3ExchangeResp[i].lLen != 0 ) //其等于0时认为此位置为空
{
m_lCmpp3ExchangeRespList = i+1;
resp = m_pCmpp3ExchangeResp[i];
m_pCmpp3ExchangeResp[i].lLen = 0;
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lCmpp3ExchangeRespList; i++ )
{
if ( m_pCmpp3ExchangeResp[i].lLen != 0 ) //其等于0时认为此位置为空
{
m_lCmpp3ExchangeRespList = i+1;
resp = m_pCmpp3ExchangeResp[i];
m_pCmpp3ExchangeResp[i].lLen = 0;
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return true;
}
}
m_lRespList = 0;
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return false;
}
BOOL CCmpp3::Cmpp3ExchangeResp_Add(Cmpp3ExchangeResp resp)
{
EnterCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
//从当前点到结尾
int i=0;
for ( i=m_lCmpp3ExchangeRespList ; i< CMPP3_SMS_MAX_CMPP3EXCHANGERESP; i++ )
{
if ( m_pCmpp3ExchangeResp[i].lLen == 0 ) //其等于0时认为此位置为空
{
m_pCmpp3ExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lCmpp3ExchangeRespList; i++ )
{
if ( m_pCmpp3ExchangeResp[i].lLen == 0 ) //其等于0时认为此位置为空
{
m_pCmpp3ExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突
return false;
}
void CCmpp3::SetCmpp3ExchangeNum(CmppExchange * pCmppExchange , long lCmppExchange)
{
m_pCmppExchange = pCmppExchange;
m_lCmppExchange = lCmppExchange;
}
void CCmpp3::SetSendSpeed(long lSpeed)
{
if (lSpeed <= 0)
{
m_lSendInterval = 0;
m_lSendIntervalCount = 1;
m_lSendIntervalIndex = 0;
}
else
{
double dwInterval = ((double)1000 / (double)lSpeed) * 0.9f;
m_lSendInterval = (long)(dwInterval + 0.5f);
if (m_lSendInterval >= 15)
{
m_lSendIntervalCount = 1;
m_lSendIntervalIndex = 0;
}
else
{
m_lSendInterval = 15;
m_lSendIntervalCount = (int)((double)m_lSendInterval / dwInterval + 0.5f);
if (m_lSendIntervalCount * dwInterval > m_lSendInterval)
m_lSendInterval = (int)(m_lSendIntervalCount * dwInterval + 0.5f);
}
}
}
long CCmpp3::GetWFSms()
{
long lWF=0;
//从当前点到结尾
for ( int i=0 ; i< CMPP3_SMS_MAX_LIST; i++ )
{
if ( m_pSendList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
lWF++;
}
}
return lWF;
}
long CCmpp3::GetReportSms()
{
long lReport=0;
//从当前点到结尾
for ( int i=0 ; i< CMPP3_SMS_MAX_STATUS; i++ )
{
if ( m_pStatusList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
lReport++;
}
}
return lReport;
}
CString CCmpp3::GetErrMsg()
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
CString strRet;
if ( m_strErrMsg.GetLength()>0 )
{
strRet = m_strErrMsg;
m_strErrMsg = CString(_T(""));
}
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
return strRet;
}
void CCmpp3::SetErrMsg(CString str)
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
m_strErrMsg = str;
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
}
BOOL CCmpp3::isConnectGateWay()
{
if ( m_bLoginCmpp3 == 0 )
{
return true;
}
return false;
}
long CCmpp3::UCS2ToAscii( const WCHAR * pUCS2 , char * pAscii)
{
long lLen = (long)wcslen( pUCS2 );
long l = WideCharToMultiByte(CP_ACP,NULL,pUCS2,lLen, pAscii , 4096 ,NULL,NULL);
pAscii[l]=0;
return l;
}
BOOL CCmpp3::Sms_Get(Cmpp3_Send_List*& pSms)
{
EnterCriticalSection(&m_CriSendSms); //防止冲突
//从当前点到结尾
int i = 0;
for (i = m_lSendList; i < CMPP3_SMS_MAX_LIST; i++)
{
if (m_pSendList[i].lSendID != 0) //其等于0时认为此位置为空
{
m_lSendList = i + 1;
pSms = &m_pSendList[i];
//m_pSendList[i].lSendID = 0;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return true;
}
}
//从开头到当前点
for (i = 0; i < m_lSendList; i++)
{
if (m_pSendList[i].lSendID != 0) //其等于0时认为此位置为空
{
m_lSendList = i + 1;
pSms = &m_pSendList[i];
//m_pSendList[i].lSendID = 0;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return true;
}
}
m_lSendList = 0;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return false;
}
BOOL CCmpp3::Sms_Add(Cmpp3_Send_List sms)
{
EnterCriticalSection(&m_CriSendSms); //防止冲突
//从当前点到结尾
int i = 0;
for (i = m_lSendList; i < CMPP3_SMS_MAX_LIST; i++)
{
if (m_pSendList[i].lSendID == 0) //其等于0时认为此位置为空
{
m_pSendList[i] = sms;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return true;
}
}
//从开头到当前点
for (i = 0; i < m_lSendList; i++)
{
if (m_pSendList[i].lSendID == 0) //其等于0时认为此位置为空
{
m_pSendList[i] = sms;
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriSendSms); //防止冲突
return false;
}