// 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 <stdlib.h>
#include <stdio.h>
#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 ; i<CBIP_SMS_MAX_LIST;i++ )
	{
		Cbip_Send_List * pSend = &m_pSendList[i];
		if ( pSend->lSendID == 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 && lDelay<m_lSendInterval+5 )
						//Sleep_Lu(lDelay-lDelay/15);
						Sleep_Lu(lDelay);
				}
				m_dwEndSocketSendTime = GetTickCount();  //���ڿ��Ʒ����ٶ�
				m_dwEndSendSmsTime = GetTickCount();

				Socket_SendSms(pSend);
				lCount ++;

			}
		}
	}
}catch(...)
{
}
LeaveCriticalSection(&m_CriSendSms);   //��ֹ��ͻ
	return lCount;
}

BOOL CCbip::Socket_SendSms(Cbip_Send_List *pSend)
{
	long messageLength=pSend->Submit.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 ; i<CBIP_SMS_MAX_LIST;i++ )
	{
		pSendSms = &m_pSendList[i];
		if ( pSendSms->lSendID!=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 ; 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 CCbip::Process_Active(Cbip_Head head, BYTE *pData, long lLen)
{
	m_dwTestCount = 0;  //�յ�activeָ�������Ϊ0
	return 1;
}

long CCbip::Process_Deliver(Cbip_Head head, BYTE *pData, long lLen)
{
	Cbip_Deliver * pDeliver = (Cbip_Deliver *)pData;

	pDeliver->sysSeq = 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 ; i<m_lCbipExchange;i++ )
		{
			if ( strlen(m_pCbipExchange[i].szNum)>0 &&
				!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 ; i<m_lCbipExchange;i++ )
		{
		if ( strlen(m_pCbipExchange[i].szNum)>0 &&
		!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 ; 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 CCbip::Cbip_Exit()
{
	m_bInitCbip = false;   //�ѳ�ʼ��
	LONGLONG lSeq=0;
	SendFrame(m_CriSendFrame,m_hSocket,m_lID,m_dwEndSendTime,CbipLogout,NULL,0,lSeq);

	Stop();   //ֹͣ
	return true;

}
void CCbip::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 CCbip::SendResp_Add(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_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 CCbip::Deliver_Add(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_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 CCbip::Cbip_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_bInitCbip )
		return -1;   //�ӿ�δ��ʼ������ʱ�Ͽ�����

	//m_lSendID ++; //����ID��1
	m_lSendID = lSendID;  //ʹ�ô�������ID
	Cbip_Send_List list={0};
	list.lSendID = m_lSendID;  //SendID

	list.SubmitEx.signLen=0;
	list.SubmitEx.customLen=0;

	list.Submit.clientSeq    = lSendID;
	strcpy( (char*)list.Submit.srcNumber , SendNo );
	list.Submit.messagePriority = 1;  //���ȼ�
	list.Submit.reportType = 1;  //��Ҫ״̬����
	//list.Submit.messageFormat = 0;
	list.Submit.overTime = 0;
	list.Submit.sendTime = 0;
	strcpy( (char*)list.Submit.linkID,"");
	list.Submit.sendGroupID = atol(Service_Id);
	list.Submit.productID  = atol(Service_Id);;
	list.Submit.messageType= 0;
	list.Submit.destMobileCount = 1;
	strcpy( (char*)list.Submit.destMobile , RecvNo );

	
	list.Submit.messageFormat = 15;  //GBK
	if ( _tcslen((TCHAR*)Msg)>70 )
		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<lSrcLen ; i++ )
			{
				pusTag[i] = htons(pusSrc[i]);
			}

			//wcscpy((WCHAR*)pMsgOK,(WCHAR*)pMsgSrc);
			//((WCHAR*)pMsgOK)[70]=0;

			list.Submit.messageLength = (UCHAR)(lSrcLen*2+ludhiLen);
		}
		else
		{
			if ( bHandFree )
				list.Submit.messageFormat = 0x10;//7Bit����
			else
				list.Submit.messageFormat = 0;//7Bit����
			char szBuf[1024]={0};
			UCS2ToAscii((WCHAR*)pMsgSrc,szBuf);
			char * pMsg = (char*)szBuf;
			pMsg[160]=0;  //��ֹ���ų���
			list.Submit.messageLength = (UCHAR)(strlen((char*)pMsg)+ludhiLen);
			strcpy((char*)pMsgOK,(char*)pMsg);
		}
	}
	else
	{
		list.Submit.messageFormat    = (unsigned char)Msg_Fmt;//hex����
		if ( list.Submit.messageFormat == 4 ) //Hex����
		{
			list.Submit.messageLength = (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.messageLength = (UCHAR)(lSrcLen*2+ludhiLen);
		}
	}

	*/

	list.Submit.clientSeq = hl64ton(list.Submit.clientSeq);
	list.Submit.reportType = htons(list.Submit.reportType);
	list.Submit.overTime = hl64ton(list.Submit.overTime);
	list.Submit.sendTime = hl64ton(list.Submit.sendTime);
	list.Submit.sendGroupID = htonl(list.Submit.sendGroupID);
	list.Submit.productID = htonl(list.Submit.productID);
	list.Submit.destMobileCount = htons(list.Submit.destMobileCount);
	//list.Submit.messageLength = htonl(list.Submit.messageLength);

	return SendSms(list);   //���뷢���б�
/*
	//���¼�ⷢ�ͷ���
	DWORD dwTime = ::GetTickCount();
	while ( ::GetTickCount()-dwTime < CBIP_SENDSMS_TIMEOUT + 5000 )
	{
		Cbip_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 CCbip::GetMobilePhoneTON(const char *pSrc, char *pOrg)
{
	char szTemp[32]={0};
	long lBegin = 0;
	long lLen = 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 CBIP_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 CCbip::isChinese(const TCHAR *pSrc, long lSrcLen)
{
	long lLen = lSrcLen;
	if ( lLen <=0 )
		lLen  = _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 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 ; i<m_lStatusList; 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;
		}
	}
	m_lStatusList = 0;
LeaveCriticalSection(&m_CriStatusList);   //��ֹ��ͻ
	return false;
}

BOOL CCbip::Status_Add(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_pStatusList[i] = Report;
LeaveCriticalSection(&m_CriStatusList);   //��ֹ��ͻ
			return true;
		}
	}
	//�ӿ�ͷ����ǰ��
	for ( i=0 ; i<m_lStatusList; i++ )
	{
		if ( m_pStatusList[i].lSendID == 0 ) //�����0ʱ����Ϊ��λ��Ϊ��
		{
			m_pStatusList[i] = Report;
LeaveCriticalSection(&m_CriStatusList);   //��ֹ��ͻ
			return true;
		}
	}
LeaveCriticalSection(&m_CriStatusList);   //��ֹ��ͻ
	return false;
}

long CCbip::Cbip_Get(TCHAR *SendNo,TCHAR * RecvNo, BYTE *Msg, TCHAR *Msg_Fmt, TCHAR *Msg_Length,long & lLongMsgRand ,long & lLongMsgAll, long & lLongMsgIndex)
{
	Cbip_Deliver_List deliver={0};

	if ( GetDeliver(deliver) )
	{
		_tcsncpy( SendNo , CA2W((char*)deliver.deliver.srcMobile ),21);
		_tcsncpy( RecvNo , CA2W((char*)deliver.deliver.destNumber ),21);
		BYTE * pMsg = (BYTE *)deliver.szMsg;
		long   lMsgLen=deliver.deliver.messageLength;

		//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.messageFormat == 15 )  //gbk����
			{
				_tcscpy((WCHAR*)Msg,CA2W((char*)pMsg));
			}
			else
			{
				if (deliver.deliver.messageFormat & 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]);
					}
				}
				else
				{
					if (deliver.deliver.messageFormat & 4 )// hex����
					{
						_tcscpy((TCHAR*)Msg,_T("HEX16:"));
						if ( deliver.deliver.messageLength>70 )
							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 ; i<m_lCbipExchangeRespList; 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;
		}
	}
	m_lRespList = 0;
LeaveCriticalSection(&m_CriCbipExchangeResp);   //��ֹ��ͻ
	return false;
}

BOOL CCbip::CbipExchangeResp_Add(CbipExchangeResp resp)
{
EnterCriticalSection(&m_CriCbipExchangeResp);   //��ֹ��ͻ
	//�ӵ�ǰ�㵽��β
	for ( int i=m_lCbipExchangeRespList ; i< CBIP_SMS_MAX_CBIPEXCHANGERESP; i++ )
	{
		if ( m_pCbipExchangeResp[i].lLen == 0 ) //�����0ʱ����Ϊ��λ��Ϊ��
		{
			m_pCbipExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriCbipExchangeResp);   //��ֹ��ͻ
			return true;
		}
	}
	//�ӿ�ͷ����ǰ��
	for ( i=0 ; i<m_lCbipExchangeRespList; i++ )
	{
		if ( m_pCbipExchangeResp[i].lLen == 0 ) //�����0ʱ����Ϊ��λ��Ϊ��
		{
			m_pCbipExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriCbipExchangeResp);   //��ֹ��ͻ
			return true;
		}
	}
LeaveCriticalSection(&m_CriCbipExchangeResp);   //��ֹ��ͻ
	return false;
}

void CCbip::SetCbipExchangeNum(CmppExchange * pCbipExchange , long lCbipExchange)
{
	m_pCbipExchange = pCbipExchange;
	m_lCbipExchange = lCbipExchange;
}

void CCbip::SetSendSpeed(long lSpeed)
{
	if ( lSpeed==0 )
		m_lSendInterval = 0;
	else
		m_lSendInterval = 1000/lSpeed;
}

long CCbip::GetWFSms()
{
	long lWF=0;
	//�ӵ�ǰ�㵽��β
	for ( int i=0 ; i< CBIP_SMS_MAX_LIST; i++ )
	{
		if ( m_pSendList[i].lSendID != 0 ) //�����0ʱ����Ϊ��λ��Ϊ��
		{
			lWF++;
		}
	}
	return lWF;
}

TCHAR * CCbip::PrintMsgID(TCHAR *pMsgID, UCHAR lMsgID[])
{
	for ( int i=0 ; i<10 ; i++ )
	{
		_stprintf(pMsgID+i*2 , _T("%02X") , lMsgID[i]);
	}
	return pMsgID;
}

long CCbip::GetReportSms()
{
	long lReport=0;
	//�ӵ�ǰ�㵽��β
	for ( int i=0 ; i< CBIP_SMS_MAX_STATUS; i++ )
	{
		if ( m_pStatusList[i].lSendID != 0 ) //�����0ʱ����Ϊ��λ��Ϊ��
		{
			lReport++;
		}
	}
	return lReport;
}


CString CCbip::GetErrMsg()
{
	EnterCriticalSection(&m_CriErrMsg);   //��ֹ��ͻ

	CString strRet;
	if ( m_strErrMsg.GetLength()>0 )
	{
		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;   

}