// Sgip.h: interface for the CSgip class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SGIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_)
#define AFX_SGIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_

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

//#define SGIP_3_0          //cmpp属于3.0

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

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

typedef struct _Sgip_SeqID
{
	ULONG       Node_Id;
	ULONG       Time;
	ULONG       Sequence_Id;
}Sgip_SeqID;
typedef struct _Sgip_Head
{
	ULONG       Total_Length;
	ULONG       Command_Id;
	Sgip_SeqID  SeqID;
}Sgip_Head;

typedef struct _Sgip_Bind
{
	UCHAR      LoginType;
	char       LoginName[16];
	char       LoginPasswd[16];
	char       Reserve[8];
}Sgip_Bind;
typedef struct _Sgip_Bind_Resp
{
	UCHAR      Result;
	char       Reserve[8];
}Sgip_Bind_Resp;


typedef struct _Sgip_Submit
{
	UCHAR    SPNumber[21];
	UCHAR    ChargeNumber[21];
	UCHAR    UserCount;
	UCHAR    UserNumber[21];
	UCHAR    CorpId[5];
	UCHAR    ServiceType[10];
	UCHAR    FeeType;
	UCHAR    FeeValue[6];
	UCHAR    GivenValue[6];
	UCHAR    AgentFlag;
	UCHAR    MorelatetoMTFlag;
	UCHAR    Priority;
	UCHAR    ExpireTime[16];
	UCHAR    ScheduleTime[16];
	UCHAR    ReportFlag;
	UCHAR    TP_pid;
	UCHAR    TP_udhi;
	UCHAR    MessageCoding;
	UCHAR    MessageType;
	ULONG    MessageLength;
}Sgip_Submit;
typedef struct _Sgip_Submit_Resp
{
	UCHAR      Result;
	char       Reserve[16];
}Sgip_Submit_Resp;
typedef struct _Sgip_Send_List
{
	ULONG       lSendID;         //数据库中记录的SendID
	Sgip_SeqID       lSeq;            //发送cmpp里的序号
	Sgip_SeqID       lSgipSeq;        //使用cmpp转接的源序号
	ULONG       lSendTime;       //最后一次发送时间
    ULONG       lReSendCount;    //重复发送了多少次
	UCHAR       Msg[512];        //信息内容
	Sgip_Submit Submit;
}Sgip_Send_List;
//发送返回状态
typedef struct _Sgip_Send_Resp
{
	ULONG       lSendID;         //数据库中记录的SendID
	ULONG       lResult;         //返回状态
    ULONG       lReSendCount;    //重复发送了多少次
	Sgip_SeqID    lMsgID;          //发送成功时有此返回
}Sgip_Send_Resp;

typedef struct _Sgip_Deliver
{
	UCHAR    UserNumber[21];
	UCHAR    SPNumber[21];
	UCHAR    TP_pid;
	UCHAR    TP_udhi;
	UCHAR    MessageCoding;
	ULONG    MessageLength;
}Sgip_Deliver;


typedef struct _Sgip_Deliver_Resp
{
	UCHAR    Result;
	CHAR     Reserve[8];
}Sgip_Deliver_Resp;



typedef struct _Sgip_Report
{
	Sgip_SeqID lMsgID;
	UCHAR    ReportType;
	UCHAR    UserNumber[21];
	UCHAR    State;
	UCHAR    ErrorCode;
	CHAR     Reserve[8];
}Sgip_Report;
typedef struct _Sgip_Report_Resp
{
	UCHAR    Result;
	CHAR     Reserve[8];
}Sgip_Report_Resp;

typedef struct _Sgip_Deliver_List
{
	ULONG        lSendID;
	Sgip_SeqID   lMsgID;
	Sgip_Deliver deliver;
	Sgip_Report  status;
	UCHAR        szMsg[512];
}Sgip_Deliver_List;


#define MAX_SGIPEXCHANGE  50
typedef struct _SgipExchange
{
	char      szNum[32];  //端口号
	SOCKET    sock;       //Socket接口
	long      lIndex;     //序号
	ULONG     lID;        //回复序号
	ULONG     lExID;      //用于区分状态报告的ID
	long      lSendCount; //发送计数
	long      lSendRetCount; //发送返回计数
	char      szIP[32];
	ULONG     lNodeID;
	ULONG     Sequence_Id;
}SgipExchange;


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

typedef struct _Sgip_Recv_ProcessT
{
	LPVOID  p;
	SOCKET  sock;
}Sgip_Recv_ProcessT;

#pragma pack( pop )

typedef void (*RECVPROC)(Data_Recv * pDataRecv);

#define      SGIP_PORT       8801   //cmpp端口号
#define      SGIP_EXCHANGE_PORT 9901
#define      SGIP_EXCHANGE_PORT2 9902  //adc下,采用此端口
#define      SGIP_EXCHANGE_TPORT 6602  //状态报告推送的端口

#define      SGIP_BIND	         0x00000001  //请求连接
#define      SGIP_BIND_RESP	     0x80000001  //请求连接应答
#define      SGIP_UNBIND	     0x00000002  //终止连接
#define      SGIP_UNBIND_RESP	 0x80000002  //终止连接应答
#define      SGIP_SUBMIT             0x00000003  //提交短信
#define      SGIP_SUBMIT_RESP        0x80000003  //提交短信应答
#define      SGIP_DELIVER            0x00000004  //短信下发
#define      SGIP_DELIVER_RESP       0x80000004  //下发短信应答
#define      SGIP_REPORT             0x00000005  //状态报告
#define      SGIP_REPORT_RESP        0x80000005  //状态报告
#define      SGIP_QUERY              0x00000006  //发送短信状态查询
#define      SGIP_QUERY_RESP         0x80000006  //发送短信状态查询应答
#define      SGIP_CANCEL             0x00000007  //删除短信
#define      SGIP_CANCEL_RESP        0x80000007  //删除短信应答
#define      SGIP_ACTIVE_TEST        0x00000008  //激活测试
#define      SGIP_ACTIVE_TEST_RESP   0x80000008  //激活测试应答
#define      SGIP_FWD                0x00000009  //消息前转
#define      SGIP_FWD_RESP           0x80000009  //消息前转应答
#define      SGIP_MT_ROUTE           0x00000010  //MT路由请求
#define      SGIP_MT_ROUTE_RESP      0x80000010  //MT路由请求应答
#define      SGIP_MO_ROUTE           0x00000011  //MO路由请求
#define      SGIP_MO_ROUTE_RESP      0x80000011  //MO路由请求应答
#define      SGIP_GET_ROUTE          0x00000012  //获取路由请求
#define      SGIP_GET_ROUTE_RESP     0x80000012  //获取路由请求应答
#define      SGIP_MT_ROUTE_UPDATE    0x00000013  //MT路由更新
#define      SGIP_MT_ROUTE_UPDATE_RESP       0x80000013  //MT路由更新应答
#define      SGIP_MO_ROUTE_UPDATE            0x00000014  //MO路由更新
#define      SGIP_MO_ROUTE_UPDATE_RESP       0x80000014  //MO路由更新应答
#define      SGIP_PUSH_MT_ROUTE_UPDATE       0x00000015  //MT路由更新
#define      SGIP_PUSH_MT_ROUTE_UPDATE_RESP  0x80000015  //MT路由更新应答
#define      SGIP_PUSH_MO_ROUTE_UPDATE       0x00000016  //MO路由更新
#define      SGIP_PUSH_MO_ROUTE_UPDATE_RESP  0x80000016  //MO路由更新应答

#define      SGIP_SMS_MAX_LIST          256         //最大的队列数

#define      SGIP_SMS_MAX_RESP          4096        //最大的队列数
#define      SGIP_SMS_MAX_DELIVER       4096        //最大的队列数
#define      SGIP_SMS_MAX_STATUS        4096        //最大的队列数
#define      SGIP_SMS_MAX_SGIPEXCHANGERESP          4096        //最大的队列数

#define      SGIP_ACTIVE_TESTTIME  70000      //多长时间进行链路检测
#define      SGIP_ACTIVE_TIMEOUT   50000      //链路检测超时时间
#define      SGIP_ACTIVE_COUNTOUT  3          //链路检测超过次数
#define      SGIP_SENDSMS_TIMEOUT  30000      //发送短信超时时间
#define      SGIP_SENDSMS_RECOUNT  1          //发送短信重试次数

//typedef CTypedPtrList<CPtrList, Sgip_Send_List*>  CSendList;
//typedef CTypedPtrList<CPtrList, Sgip_Send_Resp*>  CSendResp;
//typedef CTypedPtrList<CPtrList, Sgip_Deliver_List*>  CDeliverList;
class CSgip  
{
public:
	SOCKET       m_hSocket;
	char         m_szIP[64];
	long         m_lPort;
	long         m_lLocalPort;
	ULONG        m_lNodeID;
	BOOL         m_bQuitThread;
	DWORD        m_dwEndSendTime;
	DWORD        m_dwEndRecvTime;
	DWORD        m_dwTestCount;
	BOOL         m_bRecvFrame;
	BOOL         m_bConnect;
	long         m_bLoginSgip;
	//CSendList    m_SendList;
	//CSendResp    m_SendResp;
	//CDeliverList m_DeliverList;

	ULONG          m_lSendID;
	Sgip_Send_List *    m_pSendList;
	Sgip_Send_Resp *    m_pRespList;
	Sgip_Deliver_List*  m_pDeliverList;
	Sgip_Deliver_List*  m_pStatusList;
	SgipExchangeResp * m_pSgipExchangeResp;

	CmppExchange * m_pSgipExchange;
	long           m_lSgipExchange;

	long           m_lSendList;
	long           m_lRespList;
	long           m_lDeliverList;
	long           m_lStatusList;
	long           m_lSgipExchangeRespList;

	char         m_szSgipIP[32];
	char         m_szSgipUser[32];
	char         m_szSgipPasswd[32];
	char         m_szSgipCorpID[32];

	BOOL         m_bInitSgip;

	CRITICAL_SECTION m_CriSendSms;
	CRITICAL_SECTION m_CriRespList;
	CRITICAL_SECTION m_CriDeliverList;
	CRITICAL_SECTION m_CriStatusList;
	CRITICAL_SECTION m_CriSgipExchangeResp;

	BOOL        m_bAdc;


	ULONG        m_lID;
	RECVPROC     m_pRecvProc;

	//用于接收信息
	SOCKET       m_hRecv_Socket;
	char         m_szRecvIP[32];
	long         m_lRecvPort;
	BOOL         m_bRecvInit;
	BOOL         m_bQuitThread_Recv;

	//用于控制发送速度
	DWORD        m_dwEndSocketSendTime; //最后短信发出间隔
	long         m_lSendInterval; //发送间隔时间
	long         m_lSendIntervalCount;  //发送间隔数量
	long         m_lSendIntervalIndex;  //发送间隔统计

	HANDLE       m_hThread;
	HANDLE       m_hThread_Recv;
	HANDLE       m_hThread_Send;

	CRITICAL_SECTION m_CriErrMsg;
	CString          m_strErrMsg;

public:
	BOOL Sms_Get(Sgip_Send_List*& pSms);
	BOOL Sms_Add(Sgip_Send_List sms);
	long GetWFSms();
	BOOL isConnectGateWay();
	void SetErrMsg(CString str);
	CString GetErrMsg();

	long GetReportSms();
	void SetSendSpeed(long lSpeed);
	BOOL Sgip_Recv_Exit();
	static UINT Sgip_Recv_Process(LPVOID sParam);
	static UINT Sgip_Recv_Accept(LPVOID sParam);
	long Sgip_Recv(const char *pIP,long lPort);
	void SetSgipExchangeNum(CmppExchange * pSgipExchange , long lSgipExchange);
	BOOL SgipExchangeResp_Add(SgipExchangeResp resp);
	BOOL GetSgipExchangeResp(SgipExchangeResp &resp);
	long Sgip_GetReport(TCHAR * No ,TCHAR * Stat , TCHAR * Done_time,TCHAR * MsgID );
	long Sgip_Get(TCHAR *SendNo,TCHAR * RecvNo, BYTE *Msg, TCHAR *Msg_Fmt, TCHAR *Msg_Length ,long & lLongMsgRand ,long & lLongMsgAll, long & lLongMsgIndex);
	BOOL Status_Add(Sgip_Deliver_List Deliver);
	BOOL GetStatus(Sgip_Deliver_List &deliver);
	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 Sgip_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(Sgip_Deliver_List Deliver);
	BOOL SendResp_Add(Sgip_Send_Resp resp);
	void UCS2ToAscii2( char * pUCS2 , char * pAscii , long lSrcLen );
	BOOL Sgip_Exit();
	BOOL GetDeliver(Sgip_Deliver_List &deliver);
	long Process_Report(SOCKET sock,Sgip_Head head,BYTE *pData, long lLen);
	long Process_Deliver(SOCKET sock,Sgip_Head head,BYTE *pData, long lLen);
	long Process_Active(Sgip_Head head,BYTE *pData, long lLen);
	BOOL GetSendResp( Sgip_Send_Resp & resp );
	long Process_Submit(Sgip_Head head,BYTE *pData, long lLen);
	BOOL Socket_SendSms(Sgip_Send_List * pSend );
	long Back_Send();
	BOOL InitSgip2();
	BOOL SendSms(Sgip_Send_List sms );
	long Process_Bind(Sgip_Head head, BYTE * pData , long lLen );
	static long SendFrame(SOCKET sock,ULONG lNodeID , ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR * pData , long lDataLen,Sgip_SeqID & lSeq );
	long Sgip_Init(const char *pIP,long lPort,long lLocalPort, const char *pUser, const char *pPasswd,const char * pCorpID,const char * pNodeID);
	BOOL RecvFrame(Sgip_Data_Recv &Drecv);
	static BOOL ReadFrame(SOCKET s, Sgip_Data_Recv *pRecv);
	void SetRecvProc(RECVPROC proc);
	static DWORD WINAPI SocketRecv( LPVOID lParam );
	static DWORD WINAPI SocketSend(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 );
	CSgip();
	virtual ~CSgip();

};

#endif // !defined(AFX_SGIP_H__7DF8EA3F_89A5_4FC9_8D87_131385D01734__INCLUDED_)