// Cbip.h: interface for the CCbip class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CBIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_)
#define AFX_CBIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//#define CBIP_3_0          //cmpp属于3.0

/*
#include "Winsock2.h"
#pragma comment(lib, "Ws2_32.lib")
*/
#pragma pack( push )
#pragma pack( 1 )

typedef struct _Cbip_Data_Recv
{
	ULONG       lDataLen;  //应收字节数
	ULONG       lRecvLen;  //已收字节数
	BOOL        bRecvFrame; //是否正在收Frame;
	BYTE      * pRecvFrame; //收到的Frame
}Cbip_Data_Recv;

typedef struct _Cbip_Head
{
	ULONG       totalLength;
	ULONG       commandID;
	LONGLONG    sequenceID;
	ULONG       commandStatus;
}Cbip_Head;

typedef struct _Cbip_Login
{
	ULONG      clientID;
	UCHAR      userName[16];
	UCHAR      password[16];
	UCHAR      loginType;
	UCHAR      version;
}Cbip_Login;
typedef struct _Cbip_Login_Resp
{
	ULONG      Status;
}Cbip_Login_Resp;


typedef struct _Cbip_Submit
{
	LONGLONG clientSeq;
	UCHAR    srcNumber[21];
	UCHAR    messagePriority;
	short    reportType;
	UCHAR    messageFormat;
	LONGLONG overTime;
	LONGLONG sendTime;
	UCHAR    linkID[20];
	ULONG    sendGroupID;
	ULONG    productID;
	UCHAR    messageType;
	short    destMobileCount;
	UCHAR    destMobile[21];
	short    messageLength;
}Cbip_Submit;

typedef struct _Cbip_Submit_Ex
{
	short    signLen;
	short    customLen;
}Cbip_Submit_Ex;

typedef struct _Cbip_Submit_Resp
{
	LONGLONG sysSeq;
	ULONG    Status;
}Cbip_Submit_Resp;
typedef struct _Cbip_Send_List
{
	ULONG       lSendID;         //数据库中记录的SendID
	LONGLONG    lSeq;            //发送cmpp里的序号
	ULONG       lCbipSeq;        //使用cmpp转接的源序号
	ULONG       lSendTime;       //最后一次发送时间
    ULONG       lReSendCount;    //重复发送了多少次
	UCHAR       Msg[512];        //信息内容
	Cbip_Submit Submit;
	Cbip_Submit_Ex SubmitEx;
}Cbip_Send_List;
//发送返回状态
typedef struct _Cbip_Send_Resp
{
	ULONG       lSendID;         //数据库中记录的SendID
	long        lResult;         //返回状态
    ULONG       lReSendCount;    //重复发送了多少次
	UCHAR       lMsgID[32];          //发送成功时有此返回
}Cbip_Send_Resp;

typedef struct _Cbip_Deliver
{
	LONGLONG    sysSeq;
	UCHAR       srcMobile[21];
	UCHAR       destNumber[21];
	UCHAR       messageFormat;
	UCHAR       linkID[20];
	UCHAR       operatorID;
	UCHAR       gatewayID;
	short       messageLength;
}Cbip_Deliver;
typedef struct _Cbip_Deliver_Resp
{
	long        Status;
}Cbip_Deliver_Resp;

typedef struct _Cbip_Deliver_List
{
	ULONG        lSendID;
	Cbip_Deliver deliver;
	UCHAR        szMsg[1024];
}Cbip_Deliver_List;


typedef struct _Cbip_Report
{
	LONGLONG    clientSeq;
	LONGLONG    sysSeq;
	UCHAR       destMobile[21];
	UCHAR       operatorID;
	UCHAR       gatewayID;
	ULONG       status;
	UCHAR       errorCode[8];
	UCHAR       pkTotal;
	UCHAR       pkNumber;
	UCHAR       messageFormat;
	short       contentLen;
}Cbip_Report;
typedef struct _Cbip_Report_Resp
{
	long        Status;
}Cbip_Report_Resp;

typedef struct _Cbip_Report_List
{
	ULONG        lSendID;
	Cbip_Report  report;
	UCHAR        szMsg[256];
}Cbip_Report_List;


#define MAX_CBIPEXCHANGE  50
typedef struct _CbipExchange
{
	char      szNum[32];  //端口号
	SOCKET    sock;       //Socket接口
	long      lIndex;     //序号
	ULONG     lID;        //回复序号
	long      lSendCount; //发送计数
	long      lSendRetCount; //发送返回计数
}CbipExchange;


typedef struct _CbipExchangeResp
{
	long  lType;     //0 Submit rest  , 1 deliver
	long  lSendID;   //发送ID , lType==0时有效
	char  szNum[32]; //目标号码, lType==1时有效
	long  lExNum;    //adc特殊转发时用到
	long  lLen;
	ULONG lCmd;
	ULONG lSeq;
	BYTE  Data[512];
}CbipExchangeResp;


#pragma pack( pop )

typedef void (*CBIP_PRECVPROC)(Cbip_Data_Recv * pDataRecv);

#define      CBIP_PORT       3058   //cmpp端口号
#define      CBIP_EXCHANGE_PORT 3059
#define      CBIP_EXCHANGE_PORT2 3057  //adc下,采用此端口

#define      CbipLogin		         0x00000101  //请求连接
#define      CbipLoginResp	         0x80000101  //请求连接应答
#define      CbipSubmit              0x00000105  //提交短信
#define      CbipSubmitResp          0x80000105  //提交短信应答
#define      CbipDeliver             0x00000104  //短信下发
#define      CbipDeliverResp         0x80000104  //下发短信应答
#define      CbipActive              0x00000103  //链路检测
#define      CbipActiveResp          0x80000103  //下发短信应答
#define      CbipReport              0x00000107  //消息前转
#define      CbipReportResp          0x80000107  //消息前转应答
#define      CbipLogout  			 0x00000102  //激活测试
#define      CbipLogoutResp          0x80000102  //激活测试应答



#define      CBIP_LOGINTYPE_SEND        0  //登录类型,发送
#define      CBIP_LOGINTYPE_RECV        1  //登录类型,接收
#define      CBIP_LOGINTYPE_SENDRECV    2  //登录类型,收、发

#ifdef CBIP_3_0
#define      CBIP_SMS_MAX_LIST          256         //最大的队列数
#else
#define      CBIP_SMS_MAX_LIST          256         //最大的队列数
#endif
#define      CBIP_SMS_MAX_RESP          2048        //最大的队列数
#define      CBIP_SMS_MAX_DELIVER       2048        //最大的队列数
#define      CBIP_SMS_MAX_STATUS        2048        //最大的队列数
#define      CBIP_SMS_MAX_CBIPEXCHANGERESP          2048        //最大的队列数

#define      CBIP_ACTIVE_TESTTIME  45000      //多长时间进行链路检测
#define      CBIP_ACTIVE_TIMEOUT   35000      //链路检测超时时间
#define      CBIP_ACTIVE_COUNTOUT  3          //链路检测超过次数
#define      CBIP_SENDSMS_TIMEOUT  40000      //发送短信超时时间
#define      CBIP_SENDSMS_RECOUNT  1          //发送短信重试次数

//typedef CTypedPtrList<CPtrList, Cbip_Send_List*>  CSendList;
//typedef CTypedPtrList<CPtrList, Cbip_Send_Resp*>  CSendResp;
//typedef CTypedPtrList<CPtrList, Cbip_Deliver_List*>  CDeliverList;
class CCbip  
{
public:
	SOCKET       m_hSocket;
	char         m_szIP[64];
	long         m_lPort;
	long         m_lLoginType;
	BOOL         m_bQuitThread;
	DWORD        m_dwEndSendTime;
	DWORD        m_dwEndRecvTime;
	long         m_dwEndSendSmsTime;
	long         m_dwEndSendSmsRetTime;

	DWORD        m_dwTestCount;
	BOOL         m_bRecvFrame;
	BOOL         m_bConnect;
	long         m_bLoginCbip;
	//CSendList    m_SendList;
	//CSendResp    m_SendResp;
	//CDeliverList m_DeliverList;

	ULONG          m_lSendID;
	Cbip_Send_List *    m_pSendList;
	Cbip_Send_Resp *    m_pRespList;
	Cbip_Deliver_List*  m_pDeliverList;
	Cbip_Report_List*   m_pStatusList;
	CbipExchangeResp * m_pCbipExchangeResp;

	CmppExchange * m_pCbipExchange;
	long           m_lCbipExchange;

	long           m_lSendList;
	long           m_lRespList;
	long           m_lDeliverList;
	long           m_lStatusList;
	long           m_lCbipExchangeRespList;

	char         m_szCbipIP[32];
	char         m_szCbipUser[32];
	char         m_szCbipPasswd[32];
	char         m_szCbipCorpID[32];

	BOOL         m_bInitCbip;

	
	CRITICAL_SECTION m_CriSendFrame;
	CRITICAL_SECTION m_CriSendSms;
	CRITICAL_SECTION m_CriRespList;
	CRITICAL_SECTION m_CriDeliverList;
	CRITICAL_SECTION m_CriStatusList;
	CRITICAL_SECTION m_CriCbipExchangeResp;

	BOOL        m_bAdc;


	ULONG        m_lID;
	CBIP_PRECVPROC     m_pRecvProc;
	//用于控制发送速度
	DWORD        m_dwEndSocketSendTime; //最后短信发出间隔
	long         m_lSendInterval; //发送间隔

	HANDLE       m_hThread;

	CRITICAL_SECTION m_CriErrMsg;
	CString          m_strErrMsg;

public:
	static LONGLONG  ntohl64(LONGLONG   host);
	static LONGLONG  hl64ton(LONGLONG   host);
	BOOL isConnectGateWay();
	void SetErrMsg(CString str);
	CString GetErrMsg();

	long GetReportSms();
	static TCHAR * PrintMsgID( TCHAR * pMsgID , UCHAR lMsgID[]);
	long GetWFSms();
	void SetSendSpeed(long lSpeed);
	void SetCbipExchangeNum(CmppExchange * pCbipExchange , long lCbipExchange);
	BOOL CbipExchangeResp_Add(CbipExchangeResp resp);
	BOOL GetCbipExchangeResp(CbipExchangeResp &resp);
	long Cbip_GetReport(TCHAR * No ,TCHAR * Stat , TCHAR * Done_time,TCHAR * MsgID );
	long Cbip_Get(TCHAR *SendNo,TCHAR * RecvNo, BYTE *Msg, TCHAR *Msg_Fmt, TCHAR *Msg_Length,long & lLongMsgRand ,long & lLongMsgAll, long & lLongMsgIndex);
	BOOL Status_Add(Cbip_Report_List Report);
	BOOL GetStatus(Cbip_Report_List &report);
	int CharHex(char ch);
	void AsciiToHex(const char *pszOrgRandom , TCHAR *pszDesRandom , long lLen);
	void ExchangeUniCode( char * pData );
	void HexToAscii(const char *pszOrgRandom , char *pszDesRandom );
	long AsciiToUCS2(const char * pAscii , WCHAR * pUCS2);
	long UCS2ToAscii( const WCHAR * pUCS2 , char * pAscii);
	BOOL isChinese(const TCHAR *pSrc, long lSrcLen);
	unsigned char GetMobilePhoneTON(const char *pSrc, char *pOrg);
	long 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);
	BOOL Deliver_Add(Cbip_Deliver_List Deliver);
	BOOL SendResp_Add(Cbip_Send_Resp resp);
	void UCS2ToAscii2( char * pUCS2 , char * pAscii , long lSrcLen );
	BOOL Cbip_Exit();
	BOOL GetDeliver(Cbip_Deliver_List &deliver);
	long Process_Report(Cbip_Head head, BYTE *pData, long lLen);
	long Process_Deliver(Cbip_Head head,BYTE *pData, long lLen);
	long Process_Active(Cbip_Head head,BYTE *pData, long lLen);
	BOOL GetSendResp( Cbip_Send_Resp & resp );
	long Process_Submit(Cbip_Head head,BYTE *pData, long lLen);
	BOOL Socket_SendSms(Cbip_Send_List * pSend );
	long Back_Send();
	BOOL InitCbip2();
	long SendSms(Cbip_Send_List sms );
	long Process_Connect(Cbip_Head head, BYTE * pData , long lLen );
	static LONGLONG SendFrame(CRITICAL_SECTION &CriSendFrame,SOCKET sock,ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR * pData , long lDataLen,LONGLONG & lSeq );
	long Cbip_Init( const char * pIP,long lPort,const char * pUser,const char * pPasswd,const char * pCorpID,long lLoginType );
	BOOL RecvFrame(Cbip_Data_Recv &Drecv);
	static BOOL ReadFrame(SOCKET s, Cbip_Data_Recv *pRecv);
	void SetRecvProc(CBIP_PRECVPROC proc);
	static DWORD WINAPI SocketRecv( LPVOID lParam );
	static long Send(SOCKET sock,BYTE *pData, long lLen);
	void Close();
	static BOOL isSocketClose(SOCKET s);
	void Stop();
	BOOL isConnect();
	BOOL Connect2();
	BOOL Connect( const char * pAddr , long lPort , BOOL bReConnect = true );
	CCbip();
	virtual ~CCbip();

};

#endif // !defined(AFX_CBIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_)