// Cbip.cpp: implementation of the CCbip class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Cbip.h" //#include "MCbip.h" /* #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif */ ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #include #include #include "..\..\..\public\md53\\md5_L.h" CCbip::CCbip() { m_hSocket = INVALID_SOCKET; memset( m_szIP , 0 , sizeof(m_szIP) ); m_lPort = 0; m_bQuitThread = false; m_dwEndSendTime = 0; m_dwEndRecvTime = 0; m_dwEndSendSmsTime = 0; m_dwEndSendSmsRetTime = 0; m_dwTestCount = 0; m_bRecvFrame = false; m_lID = 1; m_pRecvProc = NULL; m_bConnect = false; m_bLoginCbip= -1; m_bInitCbip = false; m_lLoginType = 0; memset(m_szCbipIP ,0,sizeof(m_szCbipIP)); memset(m_szCbipUser ,0,sizeof(m_szCbipUser)); memset(m_szCbipPasswd,0,sizeof(m_szCbipPasswd)); memset(m_szCbipCorpID,0,sizeof(m_szCbipCorpID)); WSADATA wsaData; //用于初始化socket的结构 //以下为初始化SOCKET环境 int iTemp=WSAStartup(0x0101,&wsaData); //初始化socket环境 InitializeCriticalSection(&m_CriSendFrame); InitializeCriticalSection(&m_CriSendSms); InitializeCriticalSection(&m_CriRespList); InitializeCriticalSection(&m_CriDeliverList); InitializeCriticalSection(&m_CriStatusList); InitializeCriticalSection(&m_CriCbipExchangeResp); InitializeCriticalSection(&m_CriErrMsg); //定义队列 m_lSendID = 1; m_pSendList = new Cbip_Send_List[CBIP_SMS_MAX_LIST]; m_pRespList = new Cbip_Send_Resp[CBIP_SMS_MAX_RESP]; m_pDeliverList = new Cbip_Deliver_List[CBIP_SMS_MAX_DELIVER]; m_pStatusList = new Cbip_Report_List[CBIP_SMS_MAX_STATUS]; m_pCbipExchangeResp = new CbipExchangeResp[CBIP_SMS_MAX_CBIPEXCHANGERESP]; memset(m_pSendList,0,sizeof(Cbip_Send_List)*CBIP_SMS_MAX_LIST); memset(m_pRespList,0,sizeof(Cbip_Send_Resp)*CBIP_SMS_MAX_RESP); memset(m_pDeliverList,0,sizeof(Cbip_Deliver_List)*CBIP_SMS_MAX_DELIVER); memset(m_pStatusList,0,sizeof(Cbip_Report_List)*CBIP_SMS_MAX_STATUS); memset(m_pCbipExchangeResp,0,sizeof(CbipExchangeResp)*CBIP_SMS_MAX_CBIPEXCHANGERESP); m_lSendList = 0; m_lRespList = 0; m_lDeliverList=0; m_lStatusList=0; m_lCbipExchangeRespList=0; m_pCbipExchange = NULL; m_lCbipExchange = 0; m_bAdc = false; m_dwEndSocketSendTime = 0; m_lSendInterval = 0; m_hThread = INVALID_HANDLE_VALUE; } CCbip::~CCbip() { 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_pCbipExchangeResp ) {delete m_pCbipExchangeResp;m_pCbipExchangeResp=NULL;} DeleteCriticalSection(&m_CriSendFrame); DeleteCriticalSection(&m_CriSendSms); DeleteCriticalSection(&m_CriRespList); DeleteCriticalSection(&m_CriDeliverList); DeleteCriticalSection(&m_CriStatusList); DeleteCriticalSection(&m_CriCbipExchangeResp); DeleteCriticalSection(&m_CriErrMsg); //退出Socket WSACleanup(); } BOOL CCbip::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; HANDLE 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; } SetThreadPriority(m_hThread,THREAD_PRIORITY_LOWEST); //设置优先级 m_bConnect = true; return true; } BOOL CCbip::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 CCbip::isConnect() { return m_bConnect; } void CCbip::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; Close(); } BOOL CCbip::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 CCbip::Close() { if ( m_hSocket == INVALID_SOCKET ) return; if ( m_hSocket != INVALID_SOCKET ) closesocket(m_hSocket); m_hSocket = INVALID_SOCKET; m_bConnect = false; } long CCbip::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 CCbip::SocketRecv(LPVOID lParam) { CCbip * pNet = (CCbip *)lParam; Cbip_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_bInitCbip ) //原已连接的,重新连接 { bReConnect = true; } else { pNet->m_bLoginCbip = -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 >CBIP_ACTIVE_TIMEOUT*2 ) //接收超时 { pNet->m_dwEndRecvTime = ::GetTickCount()-CBIP_ACTIVE_TIMEOUT; //如果接收超时,重新计数 pNet->Close(); //重新接收数据 if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; memset(&Drecv,0,sizeof(Drecv)); if ( pNet->m_bInitCbip ) //原已连接的,重新连接 bReConnect = true; } if ( pNet->m_dwEndSendSmsTime>0 && pNet->m_dwEndSendSmsRetTime>0 && (pNet->m_dwEndSendSmsTime - pNet->m_dwEndSendSmsRetTime)>CBIP_SENDSMS_TIMEOUT ) //接收超时 { pNet->m_dwEndSendSmsTime = 0; pNet->m_dwEndSendSmsRetTime = 0; //如果接收超时,重新计数 pNet->Close(); //重新接收数据 if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; memset(&Drecv,0,sizeof(Drecv)); if ( pNet->m_bInitCbip ) //原已连接的,重新连接 bReConnect = true; } //判断是否应该发送Active_Test指令 if ( pNet->m_dwEndSendTime > 0 ) { if ( ::GetTickCount() - pNet->m_dwEndSendTime > CBIP_ACTIVE_TESTTIME ) //重新连接 { LONGLONG lSeq=0; pNet->SendFrame(pNet->m_CriSendFrame,pNet->m_hSocket,pNet->m_lID,pNet->m_dwEndSendTime, CbipActive , NULL , 0 ,lSeq ); } } if ( bReConnect ) { for ( int i=0 ; i<30 && !pNet->m_bQuitThread; i++ ) //延时5秒 { Sleep_Lu(100); } pNet->SetErrMsg("Cbip消息:正在重连网关..."); if ( !pNet->m_bQuitThread ) pNet->InitCbip2(); //重新连接到服务器 } //发送短信 long lCount2 = pNet->Back_Send(); //if ( lCount2>0 ) // Sleep_Lu(2); //else // Sleep_Lu(20); } if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; pNet->Close(); return 1; } void CCbip::SetRecvProc(CBIP_PRECVPROC proc) { m_pRecvProc = proc; } BOOL CCbip::ReadFrame(SOCKET s, Cbip_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 = 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 CCbip::RecvFrame(Cbip_Data_Recv &Drecv) { Cbip_Head * pHead=(Cbip_Head *)Drecv.pRecvFrame; if ( pHead->totalLength != Drecv.lRecvLen ) return false; pHead->commandID = ntohl(pHead->commandID); pHead->sequenceID= ntohl64(pHead->sequenceID); BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(Cbip_Head)); long lLen = pHead->totalLength-sizeof(Cbip_Head); long lRet = 0; switch( pHead->commandID ) { case CbipLoginResp: lRet = Process_Connect(*pHead,pData,lLen); break; case CbipSubmitResp: lRet = Process_Submit(*pHead,pData,lLen); break; case CbipActiveResp: lRet = Process_Active(*pHead,pData,lLen); break; case CbipDeliver: lRet = Process_Deliver(*pHead,pData,lLen); break; case CbipReport: lRet = Process_Report(*pHead,pData,lLen); break; default: break; } return lRet; } long CCbip::Cbip_Init(const char *pIP,long lPort, const char *pUser, const char *pPasswd,const char * pCorpID,long lLoginType) { if ( !Connect(pIP,lPort) ) { return -1; //连接服务器失败 } //记录信息 strcpy(m_szCbipIP,pIP); m_lPort = lPort; strcpy(m_szCbipUser,pUser); strcpy(m_szCbipPasswd,pPasswd); strcpy(m_szCbipCorpID,pCorpID); m_lLoginType = lLoginType; Cbip_Login connect={0}; ULONG lClientID = atol(m_szCbipCorpID); connect.clientID = htonl(lClientID); strcpy((char*)connect.userName,pUser); strcpy((char*)connect.password,pPasswd); connect.loginType = (UCHAR)m_lLoginType; connect.version = 2; m_bLoginCbip = -1; m_bInitCbip = false; LONGLONG lSeq=0; if ( !SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipLogin,(UCHAR*)&connect,sizeof(connect),lSeq) ) return -2; //发送数据失败 long lTime = ::GetTickCount(); while ( m_bLoginCbip == -1 ) { if ( ::GetTickCount()-lTime > 30000 ) //超时了 break; Sleep_Lu(20); } if ( m_bLoginCbip==0 ) m_bInitCbip = true; //已初始化 if ( m_bLoginCbip == -1 ) return -3; //登录超时 else return m_bLoginCbip; //登录返回成功,具体请看错误码 return -4; //其它错误 } LONGLONG CCbip::SendFrame(CRITICAL_SECTION &CriSendFrame,SOCKET sock,ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR *pData, long lDataLen,LONGLONG & lSeq ) { EnterCriticalSection(&CriSendFrame); //防止冲突 try { Cbip_Head head={0}; long lAllLen; head.totalLength = sizeof(head)+lDataLen; lAllLen = head.totalLength; head.commandID = lCommandID; if ( lID >= 0xF000000 ) //重新开始序号 lID = 1; if ( lSeq > 0 ) head.sequenceID = lSeq; //直接使用相同序号的发送 else head.sequenceID = lID++; lSeq = head.sequenceID; //返回 head.totalLength = htonl(head.totalLength); head.commandID = htonl(head.commandID); head.sequenceID = hl64ton(head.sequenceID); 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; LeaveCriticalSection(&CriSendFrame); //防止冲突 if ( bOK ) return head.sequenceID; else return 0; return 0; } catch(...) { LeaveCriticalSection(&CriSendFrame); //防止冲突 return 0; } } long CCbip::Process_Connect(Cbip_Head head,BYTE *pData, long lLen) { Cbip_Login_Resp * pResp = (Cbip_Login_Resp *)pData; pResp->Status = ntohl(pResp->Status); if ( m_bInitCbip && pResp->Status != 0 ) //需要重新登录 { //登录不成功,关闭连接 this->Close(); } CString str; str.Format(_T("Cbip消息:连接网关返回代码:%d") , pResp->Status ); SetErrMsg(str); m_bLoginCbip = pResp->Status; return 1; } long CCbip::SendSms(Cbip_Send_List sms) { m_dwEndSendSmsTime = GetTickCount(); //记下最新发送时间 for ( int j=0 ; j< 200 ; j++ ) { //从当前点到结尾 EnterCriticalSection(&m_CriSendSms); //防止冲突 try { for ( int i=0 ; i< CBIP_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; } } } catch(...) { } LeaveCriticalSection(&m_CriSendSms); //防止冲突 Sleep_Lu(20); //延时10秒 } return false; } BOOL CCbip::InitCbip2() { m_bLoginCbip = -1; if ( !Connect2() ) { return false; //连接服务器失败 } Cbip_Login connect={0}; ULONG lClientID = atol(m_szCbipCorpID); connect.clientID = htonl(lClientID); strcpy((char*)connect.userName,m_szCbipUser); strcpy((char*)connect.password,m_szCbipPasswd); connect.loginType = (UCHAR)m_lLoginType; connect.version = 2; m_bLoginCbip = -1; LONGLONG lSeq=0; if ( !SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipLogin,(UCHAR*)&connect,sizeof(connect),lSeq) ) return -2; //发送数据失败 //重新连接时,需要重发短信 memset(m_pSendList,0,sizeof(Cbip_Send_List)*CBIP_SMS_MAX_LIST); /* for ( int i=0 ; i< CBIP_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 CCbip::Back_Send() { if ( m_bLoginCbip != 0 ) //还没登录成功,不能发短信 return 0; EnterCriticalSection(&m_CriSendSms); //防止冲突 long lCount = 0; try { for ( int i=0 ; ilSendID == 0 ) continue; BOOL bSend = false; if ( pSend->lReSendCount > 0 ) //前已发送过,看是否到达重发时间 { if ( ::GetTickCount()-pSend->lSendTime>CBIP_SENDSMS_TIMEOUT ) bSend = true; else bSend = false; } else { bSend = true; //第一次发送 } if ( bSend ) { if ( pSend->lReSendCount >= CBIP_SENDSMS_RECOUNT ) //发送失败 { //插入发送返回 Cbip_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 && lDelaySubmit.messageLength; //网络字序转换 pSend->Submit.messageLength = htons(pSend->Submit.messageLength); long lSize = sizeof(pSend->Submit)+messageLength+sizeof(pSend->SubmitEx); //计算发送信息的总长度 BYTE * pData = new BYTE[lSize]; memset(pData,0,lSize); Cbip_Submit * pSubmit = (Cbip_Submit*)pData; BYTE * pMsg = (BYTE*)(pData+sizeof(Cbip_Submit)); Cbip_Submit_Ex * pSubmitEx = (Cbip_Submit_Ex*)(pData+sizeof(Cbip_Submit)+messageLength); //拷贝实际内容。 *pSubmit = pSend->Submit; memcpy(pMsg,pSend->Msg,messageLength); *pSubmitEx = pSend->SubmitEx; LONGLONG lSeq=0; BOOL b = SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipSubmit,pData,lSize,lSeq); //if ( b ) //{ pSend->lReSendCount ++; pSend->lSendTime = ::GetTickCount(); pSend->lSeq = lSeq; //} delete pData; return b; } long CCbip::Process_Submit(Cbip_Head head,BYTE *pData, long lLen) { Cbip_Submit_Resp * pResp = (Cbip_Submit_Resp *)pData; pResp->sysSeq = ntohl64(pResp->sysSeq); pResp->Status = ntohl(pResp->Status); m_dwEndSendSmsRetTime = GetTickCount(); //收到发送返回,在队列中查找发送信息 Cbip_Send_List * pSendSms = NULL; BOOL bFind = false; LONGLONG lSeq = head.sequenceID; for ( int i=0 ; ilSendID!=0 && pSendSms->lSeq == lSeq ) { bFind = true; break; } } if ( bFind ) { if ( pSendSms->lSendID <= MAX_CMPPEXCHANGE+10 ) //小于-100表示cmpp转接所发 { CbipExchangeResp resp={0}; resp.lType = 0; resp.lSendID = pSendSms->lSendID; resp.lLen = lLen; resp.lCmd = head.commandID; resp.lSeq = pSendSms->lCbipSeq; memcpy(resp.Data , pData , lLen ); CbipExchangeResp_Add(resp); pSendSms->lSendID = 0; //删除此记录 } else { Cbip_Send_Resp Resp={0}; Resp.lSendID = pSendSms->lSendID; Resp.lReSendCount = pSendSms->lReSendCount; sprintf((char*)Resp.lMsgID,"%I64d",pResp->sysSeq); Resp.lResult = pResp->Status; SendResp_Add(Resp); pSendSms->lSendID = 0; //删除此记录 } } return 1; } BOOL CCbip::GetSendResp(Cbip_Send_Resp &resp) { EnterCriticalSection(&m_CriRespList); //防止冲突 //从当前点到结尾 for ( int i=m_lRespList ; i< CBIP_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 ; isysSeq = ntohl64(pDeliver->sysSeq); pDeliver->messageLength = ntohs(pDeliver->messageLength); BYTE * pMsgData = pData+sizeof(Cbip_Deliver); //判断是否cmpp转接的短信内容 BOOL bExchange=false; if ( m_pCbipExchange ) { long lExNum=0; for ( int i=0 ; i0 && !strncmp((char*)pDeliver->destNumber,m_pCbipExchange[i].szNum,strlen(m_pCbipExchange[i].szNum) ) ) { CbipExchangeResp resp={0}; resp.lType = 1; strcpy(resp.szNum , m_pCbipExchange[i].szNum ); resp.lExNum = lExNum; //adc特殊转发时用到 resp.lLen = lLen; resp.lCmd = head.commandID; resp.lSeq = head.sequenceID; memcpy(resp.Data , pData , lLen ); CbipExchangeResp_Add(resp); bExchange = true; break; } } } if ( !bExchange) { Cbip_Deliver_List Deliver={0}; Deliver.lSendID = 1; Deliver.deliver = *pDeliver; //Deliver.deliver.MsgFormat = pDeliver->MsgFormat; //strcpy((char*)Deliver.deliver.SrcTermID,(char*)pDeliver->SrcTermID); //Deliver.deliver.IsReport = pDeliver->IsReport; //Deliver.deliver.MsgLength = pDeliver->MsgLength; memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.messageLength ); //取信息内容 Deliver_Add(Deliver); //添加到列表 } //发送返回 Cbip_Deliver_Resp resp={0}; resp.Status = 0; LONGLONG lReq=head.sequenceID; SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipDeliverResp,(BYTE*)&resp,sizeof(resp),lReq); return true; } long CCbip::Process_Report(Cbip_Head head, BYTE *pData, long lLen) { Cbip_Report * pReport = (Cbip_Report *)pData; pReport->sysSeq = ntohl64(pReport->sysSeq); pReport->clientSeq = ntohl64(pReport->clientSeq); pReport->status = ntohl(pReport->status); pReport->contentLen = ntohs(pReport->contentLen); BYTE * pMsgData = pData+sizeof(Cbip_Report); if (pReport->pkTotal == pReport->pkNumber ) { //如果序号不同,不是最后一条状态报告,丢弃 //判断是否cmpp转接的短信内容 BOOL bExchange=false; /* if ( m_pCbipExchange ) { long lExNum=0; for ( int i=0 ; i0 && !strncmp((char*)pDeliver->destNumber,m_pCbipExchange[i].szNum,strlen(m_pCbipExchange[i].szNum) ) ) { CbipExchangeResp resp={0}; resp.lType = 1; strcpy(resp.szNum , m_pCbipExchange[i].szNum ); resp.lExNum = lExNum; //adc特殊转发时用到 resp.lLen = lLen; resp.lCmd = head.commandID; resp.lSeq = head.sequenceID; memcpy(resp.Data , pData , lLen ); CbipExchangeResp_Add(resp); bExchange = true; break; } } } */ if ( !bExchange) { Cbip_Report_List Report={0}; Report.lSendID = 2; Report.report = *pReport; memcpy(Report.szMsg,pMsgData,Report.report.contentLen ); //取信息内容 Status_Add(Report); //添加到列表 } } //发送返回 Cbip_Report_Resp resp={0}; resp.Status = 0; LONGLONG lReq=head.sequenceID; SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipReportResp,(BYTE*)&resp,sizeof(resp),lReq); return true; } BOOL CCbip::GetDeliver(Cbip_Deliver_List &deliver) { EnterCriticalSection(&m_CriDeliverList); //防止冲突 //从当前点到结尾 for ( int i=m_lDeliverList ; i< CBIP_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 ; i70 ) list.Submit.messageFormat=32; //长短信要用此编码 strcpy((char*)list.Msg,CW2A((TCHAR*)Msg)); list.Submit.messageLength = strlen((char*)list.Msg); /* char * pMsgSrc= (char*)Msg; char * pMsgOK = (char*)list.Msg; long ludhiLen=0; if ( udhi == 1 ) { memcpy(pMsgOK,pMsgSrc,6); //原字节头 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.messageFormat = 0x18;//UCS2编码 else list.Submit.messageFormat = 8;//UCS2编码 //list.Submit.messageFormat = 25;//UCS2编码 if ( ludhiLen>0 ) list.Submit.messageFormat = 32; 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(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2); for ( int i=0 ; i128 ) { 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 CCbip::UCS2ToAscii( const WCHAR * pUCS2 , char * pAscii) { long lLen = wcslen( pUCS2 ); long l = WideCharToMultiByte(CP_ACP,NULL,pUCS2,lLen, pAscii , 4096 ,NULL,NULL); pAscii[l]=0; return l; } long CCbip::AsciiToUCS2(const char *pAscii, WCHAR *pUCS2) { long lLen = strlen( pAscii ); long l = MultiByteToWideChar( CP_ACP,NULL,pAscii,lLen, pUCS2 , 4096 ); pUCS2[l]=0; return l; // szName2[l*2]=0; /* AsciiToHex( szName2 , pUCS2 , l*2); ExchangeUniCode( pUCS2 ); */ } void CCbip::HexToAscii(const char *pszOrgRandom, char *pszDesRandom) { char Buf[4]; char *pDes = (char *)pszDesRandom; char *pOrg = (char *)pszOrgRandom; long lLen = strlen( pOrg); long lTemp; for( int 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 CCbip::ExchangeUniCode(char *pData) { char pEx[4]; long lLen = 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 CCbip::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 CCbip::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 CCbip::GetStatus(Cbip_Report_List &report) { EnterCriticalSection(&m_CriStatusList); //防止冲突 //从当前点到结尾 for ( int i=m_lStatusList ; i< CBIP_SMS_MAX_STATUS; i++ ) { if ( m_pStatusList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { m_lStatusList = i+1; report = m_pStatusList[i]; m_pStatusList[i].lSendID = 0; LeaveCriticalSection(&m_CriStatusList); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; i70 ) deliver.deliver.messageLength=70; AsciiToHex((const char*)pMsg,((TCHAR*)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.messageLength); //转换成Hex编码 //memcpy(Msg,deliver.szMsg,deliver.deliver.Msg_Length); if ( Msg_Fmt ) _stprintf( Msg_Fmt , _T("%d") , deliver.deliver.messageFormat ); if ( Msg_Length ) _stprintf( Msg_Length , _T("%d") , deliver.deliver.messageLength*2 ); return 0; } } return -1; //没有信息 } long CCbip::Cbip_GetReport(TCHAR *No, TCHAR *Stat, TCHAR *Done_time, TCHAR *MsgID) { Cbip_Report_List report={0}; if ( GetStatus(report) ) { _tcscpy( No , CA2W((char*)report.report.destMobile) ); //strcpy( Stat , (char*)deliver.status.Stat ); if ( report.report.status ==0 ) _tcscpy( Stat , _T("DELIVRD") ); else _tcsncpy( Stat , CA2W((char*)report.report.errorCode) , 8 ); //strcpy( Done_time , (char*)deliver.status.Done_time ); //_tcsncpy( Done_time , CA2W((char*)deliver.status.done_date) , 10 ); _stprintf(MsgID,_T("%I64d"),report.report.sysSeq); return 0; } return -1; //没有信息 } BOOL CCbip::GetCbipExchangeResp(CbipExchangeResp &resp) { EnterCriticalSection(&m_CriCbipExchangeResp); //防止冲突 //从当前点到结尾 for ( int i=m_lCbipExchangeRespList ; i< CBIP_SMS_MAX_CBIPEXCHANGERESP; i++ ) { if ( m_pCbipExchangeResp[i].lLen != 0 ) //其等于0时,认为此位置为空 { m_lCbipExchangeRespList = i+1; resp = m_pCbipExchangeResp[i]; m_pCbipExchangeResp[i].lLen = 0; LeaveCriticalSection(&m_CriCbipExchangeResp); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; i0 ) { strRet = m_strErrMsg; m_strErrMsg = CString(_T("")); } LeaveCriticalSection(&m_CriErrMsg); //防止冲突 return strRet; } void CCbip::SetErrMsg(CString str) { EnterCriticalSection(&m_CriErrMsg); //防止冲突 m_strErrMsg = str; LeaveCriticalSection(&m_CriErrMsg); //防止冲突 } BOOL CCbip::isConnectGateWay() { if ( m_bLoginCbip == 0 ) { return true; } return false; } LONGLONG CCbip::hl64ton(LONGLONG host) { LONGLONG ret = 0; ULONG high,low; low = host & 0xFFFFFFFF; high = (host >> 32) & 0xFFFFFFFF; low = htonl(low); high = htonl(high); ret = low; ret <<= 32; ret |= high; return ret; } //network to host long 64 LONGLONG CCbip::ntohl64(LONGLONG host) { LONGLONG ret = 0; ULONG high,low; low = host & 0xFFFFFFFF; high = (host >> 32) & 0xFFFFFFFF; low = ntohl(low); high = ntohl(high); ret = low; ret <<= 32; ret |= high; return ret; }