#ifndef _udx_api_h_
#define _udx_api_h_

#ifdef __cplusplus
extern "C" {
#endif


#ifdef  BUILD_UDXDLL
#define UDX_EXPORT  extern "C" __declspec(dllexport)
#else
#define UDX_EXPORT /* extern "C" __declspec(dllimport)*/
#endif


#if defined(WIN32) && !defined(__MINGW32__)
#pragma pack( push, 1 )
#ifndef UDXAPIPACKED
#define UDXAPIPACKED 
#endif
#else
#ifndef UDXAPIPACKED
#define UDXAPIPACKED	__attribute__((packed, aligned(1)))
#endif
#endif


typedef void* UDXLISTENER;
typedef unsigned short UDXSOCKET;
typedef void* UDXINTERNAL;

#ifndef UINT64
#if defined(WIN32) && !defined(__MINGW32__)
typedef unsigned __int64 UINT64;
#else
typedef unsigned long long UINT64;
#endif
#endif

typedef int (_UDXPRC)(UINT64 dwuser);
typedef _UDXPRC *LP_UDXPRC;

//UDX�¼�
typedef enum
{
	//���ӽ����ɹ�
	UdxEvent_ConnectOK,
	//���ӽ���ʧ��
	UdxEvent_ConnectErro,
	//��
	UdxEvent_StreamRead,
	//�Ͽ�
	UdxEvent_StreamBroken,
	//P2Pʧ��
	UdxEvent_P2pFailed,
	//�ļ����俪ʼ
	UdxEvent_FileTrandBegin,
	//�ļ��������
	UdxEvent_FileTransEnd,
	//�ļ������м���¼�
	UdxEvent_FileTransRead,
	//�ļ������м�д�¼�
	UdxEvent_FileTransWrite,
	//P2P��ʱ������ת�е�P2P���¼�
	UdxEvent_TsLinkChangedToP2p,

}UdxEventType;

typedef enum
{
	//rtt
	UdxOption_Delay,//int
	UdxOption_SendSpeed,//long
	UdxOption_ReadSpeed,//long
	UdxOption_AVGSendSpeed,//long
	UdxOption_AVGReadSpeed,//long
	UdxOption_Lost,//float
	UdxOption_LinkType,//long
	UdxOption_RegisterSN,//char
	UdxOption_P2pPass,//char
	UdxOption_LinkNotCheckDataSize,//unsigned long
	UdxOption_SetFixed_Speed,//unsigned long long,bytes per second
	UdxOption_SetMax_Speed,//unsigned long long,bytes per second
	UdxOption_SetMin_Speed,//unsigned long long,bytes per second
	UdxOption_GetSuggess_Bitrat,//int,bytes per second
	UdxOption_SetLinkTimeOut,//int,second
}UdxOptionType;

//�������ӵ�����
typedef enum
{
	UdxLink_Normal,//int
	UdxLink_P2P_REGISTER,//int
	UdxLink_P2P_CONNECTION	,//UDX P2P ��������
	UdxLink_Mult_Path	,//UDX ��·�� ��������
}UdxLinkInternalType;


typedef struct UdxEventCtx
{
	UDXINTERNAL in;//�ڲ�Ҫʹ�õ�ָ�룬��getevent��Ҫ�����˴�
	UdxEventType e;
	UDXSOCKET s;//��ǰ�¼����������Ӷ���
	unsigned short srcid;//���ӵ�id
	unsigned short desid;//���ӵĶԷ�id
	unsigned short linktype;//��������ʱ�����õ�link���ԣ�����Ӧ�ò�ҵ��
	unsigned short linkindex;//��������ʱ�����õ�link���ԣ�����Ӧ�ò�ҵ��
	unsigned short linkinternaltype;//��������ʱ��UDX�ڲ�link����
	unsigned short p2pindex;
	unsigned char reconnect;//����
	unsigned char erronum;//������,��P2Pʧ�ܵ�ʱ��Ϊ1
	unsigned char direct;//���ӷ���
	unsigned char bSend;//���ͷ�
	int nEventDataLen;//��Ϊread�¼�ʱ�����ݳ���
	void * userdata;	//��ǰ���ӹ������û�����
}UDXAPIPACKED UdxEventCtx;

typedef struct UdxAddr
{
	char addr[128];
}UDXAPIPACKED UdxAddr;

//��Ƶļ򵥵�1��1ͨ��
typedef struct UdxObj
{
	UDXLISTENER s ;
	UDXSOCKET c;
}UDXAPIPACKED UdxObj;

typedef struct UdxCB
{
	int (*OnInitOk)(UdxObj*pObj);
	int (*OnBroken)(UdxObj*pObj);
	int (*OnRead)(UdxObj*pObj,unsigned char*pData,int len);
}UDXAPIPACKED UdxCB;

typedef struct UdxLinkCfg
{
	int wndsize;//��ʼ����
	int fec;//FEC����
	int gamemode;//��Ϸģʽ
	int reconnect;//�Ƿ�֧������
}UDXAPIPACKED UdxLinkCfg;

typedef struct UdxBuff
{
	int len;
	unsigned char* pData;
	UDXINTERNAL _buff;
}UDXAPIPACKED UdxBuff;


#if defined(WIN32) && !defined(__MINGW32__)
#pragma pack( pop )
#endif

UDX_EXPORT unsigned int UdxGetVer();
//��ֹ��ſ���ӡ1�ſ���0��ֹ��ӡ
UDX_EXPORT void UdxLogEnable(int bEnable);

//��ӡ
UDX_EXPORT void UdxLog(const char*szInfo,...);

//����udx����㣬 �����ߣ�blocksize,udpsend��Ϊ�ͻ���ʱ��һ������1���ɡ���Ϊ�����ʱ���ʵ�����������bocksize 2~4, udpsend 2~4
//����NULL��ʾ��ʧ��
UDX_EXPORT UDXLISTENER UdxSocket(char* szIP,unsigned short port,int blocksize,int udpsend);

//ͨ�������ߣ�����һ���µ����ӣ�linktype,��linkindex,�Ǹ�Ӧ�ò��ʶ��;��,��szName��Ϊ�ձ�ʾע�ᵽP2p������,szPass����Ч
UDX_EXPORT int UdxConnect(UDXLISTENER sListen,char* szIP,unsigned short port,char* szInitDat,int len,unsigned short linktype,unsigned short linkindex,unsigned char beRecon,unsigned char conSecons,int bSyn,UDXSOCKET *nRetSocket);

//���յ��¼���ͨ���˷�����ȡ���ݣ�ÿһ�����¼�����һ��������֡,��pData == NULLʱ���أ���ǰ֡���ܳ��ȣ��ٴε���udxrecv��ȡ����
UDX_EXPORT int UdxRecv(UdxEventCtx* pEvent,unsigned char* pData,int len);

//�����ӹ���һ���û�ָ��
UDX_EXPORT void UdxSetUserData(UDXLISTENER sListen,UDXSOCKET s,void * userdata);
//��ȡ���ӹ���һ���û�ָ��
UDX_EXPORT void * UdxGetUserData(UDXLISTENER sListen,UDXSOCKET s);

//��⵱ǰ�Ƿ�ɷ�������,����-1����ʾ���ɷ�������1����ʾ���Է��ͣ�����0��ʾ���������Ժ��ٳ��Է�
UDX_EXPORT int UdxIsableToSend(UDXLISTENER sListen,UDXSOCKET s);

//�������ݣ����Ȳ����޵�����������intȡֵ��Χ,type 0һ�㷢�ͣ�1���ӵ��ڲ����Ͷ�β��2��������ر�����
UDX_EXPORT int UdxSend(UDXLISTENER sListen,UDXSOCKET s,unsigned char* pData,int len,int type);

//��ȡs�л�û�б�ȷ�ϵ����ݳ���
UDX_EXPORT int UdxGetRemainNumber(UDXLISTENER sListen,UDXSOCKET s);

//�����������ݣ����Ȳ����޵�����������intȡֵ��Χ��ֱ��������ɲŻ᷵�أ�������� -1��ʾ���ӶϿ����ɹ�����len
UDX_EXPORT int UdxBlockSend(UDXLISTENER sListen,UDXSOCKET s,unsigned char* pData,int len);

//AUDIOFRAME_A	0//��Ƶ֡
//VIDEOFRAME_I	1//I֡
//VIDEOFRAME_P	2//P֡
//DATAFRAME_I	3//����֡

//����֡��ʽ������,
UDX_EXPORT int UdxSendFrame(UDXLISTENER sListen,UDXSOCKET s,int bVideo,int fType,unsigned char* pData,int len,int subtype);

//����֡��ʽ������,����-1��һ���ǻ��峤�Ȳ���
UDX_EXPORT int UdxRecvFrame(UdxEventCtx* pEvent,int *bVideo,int *fType,unsigned char* pData,int len,int *subtype);

////���N���¼�,msΪ��ʱʱ�䣬����,���� �¼�����
UDX_EXPORT int UdxGetEvent(UDXLISTENER sListen,UdxEventCtx* pEvent,int maxEventCount,int ms);

//���ڴ��¼������ڲ����벢������������ļ������ƣ���Ҫ���ô˽ӿڶ�ȡ�����¼������ͷ�
UDX_EXPORT int UdxEventFree(UdxEventCtx* pEvent);


//��ȡ���ذ󶨵�ַ
UDX_EXPORT void UdxGetLocalAddr(UDXLISTENER sListen,UdxAddr* pLocal);

//Զ�̵�ַ
UDX_EXPORT int UdxGetRemoteAddr(UDXLISTENER sListen,UDXSOCKET s,UdxAddr* pRemote);

//��ȡ�Զ˿������Լ��ĵ�ַ
UDX_EXPORT int UdxGet3WAddr(UDXLISTENER sListen,UDXSOCKET s,UdxAddr* p3Waddr);

//�رտ���fec
UDX_EXPORT void UdxEnableFec(UDXLISTENER sListen,UDXSOCKET s,int bEnable);
//����Ϸģʽ
UDX_EXPORT void UdxSetGameMode(UDXLISTENER sListen,UDXSOCKET s);

//char* szOutInitDat �������� ,int inlen ��������С
//�������ӳ�ʼ�����ݼ�����
UDX_EXPORT int UdxGetRemoteInitData(UDXLISTENER sListen,UDXSOCKET s,char* szOutInitDat,int inlen);

//��ĳ��s,��һ�οɷ���ʱ���ڲ��пɷ�״̬ʱ����������
UDX_EXPORT int UdxWaitForSend(UDXLISTENER sListen,UDXSOCKET s,int ms);

//�����ļ�
UDX_EXPORT int UdxSendFile(UDXLISTENER sListen,UDXSOCKET s,char* szFilePathName);

//��ȡ�ļ��¼��е���Ϣ��szFilePathNameΪ��С��512�ֽڵĻ�������ȡ�ļ�����*bSend = 1,��ʾ���ͣ�0��ʾ����,��ǰ����/���յİٷֱȺ����ļ���С
UDX_EXPORT int UdxGetFileInfo(UDXLISTENER sListen,UdxEventCtx* pEvent,char* szFilePathName,int*bSend,float *fper,UINT64* pTotalLen);


//ͨ�������ߣ�szIDע�ᵽP2p������,szPass����
UDX_EXPORT int UdxP2pRegister(UDXLISTENER sListen,char* szRegisterIP,unsigned short regport,
	char* szP2pIP,unsigned short p2pport,
	char* szTsIP,unsigned short tsport,char* szID,
	char* szInitDat,int len,unsigned short linktype,unsigned short linkindex,char* szPass);

//����һ��P2P����,����ֵΪ�˴��������ţ�Ψһ��ʶ
UDX_EXPORT int UdxP2pConnect(UDXLISTENER sListen,UDXSOCKET s,char*szName,unsigned short linktype,unsigned short linkindex,int p2ptype,char* szInitDat,int len);////0 p2p+ts,1 ,p2p,2,ts

//�Ͽ�����
UDX_EXPORT int UdxClose(UDXLISTENER sListen,UDXSOCKET s);

//��ѯ��Ϣ
UDX_EXPORT int UdxGetOption(UDXLISTENER sListen,UDXSOCKET s,int type,void* Info,int iInfoLen);

//ȡ�����ڷ��������
UDX_EXPORT void UdxCancelConnecting(UDXLISTENER sListen);

//�ͷ�udx
UDX_EXPORT void UdxShutDown(UDXLISTENER sListen);

///////////////��������////////////////////
//����UDX�ڴ���������ڴ�
UDX_EXPORT UDXINTERNAL UdxNew(int len,unsigned char** pBuff);

//�ͷ��ڴ�
UDX_EXPORT void UdxDelete(UDXINTERNAL pMem);

//����һ���̼߳�����
UDX_EXPORT int UdxThreadCreate(int bSyn,int StackSize,char*szThName,LP_UDXPRC cb,UINT64 dwUser);

UDX_EXPORT void UdxApiSleep(int ms);

UDX_EXPORT unsigned long UdxGetTick();

//��ȡ��ǰtcp�����Ƿ�����״̬
UDX_EXPORT int UdxIsConnected(UDXLISTENER sListen,UDXSOCKET s);
//��ȡ��ǰtcp����0. p2p 1. trans
UDX_EXPORT int UdxGetLinkType(UDXLISTENER sListen,UDXSOCKET s);

//��ȡ��ǰ������
UDX_EXPORT int UdxGetClientsCount(UDXLISTENER sListen);
//��ȡ��ǰת��������
UDX_EXPORT int UdxGetTransFormLinksCount(UDXLISTENER sListen);

//������
UDX_EXPORT UDXINTERNAL UdxLockCreate();
UDX_EXPORT void UdxLock(UDXINTERNAL pLock);
UDX_EXPORT void UdxUnLock(UDXINTERNAL pLock);
//ɾ����
UDX_EXPORT void UdxLockDestroy(UDXINTERNAL pLock);

//����
UDX_EXPORT UDXINTERNAL UdxListCreate();
//��������������
UDX_EXPORT void UdxListAddBuff(UDXINTERNAL pList,unsigned char* pData,int len);
//ȡ����
UDX_EXPORT int UdxListGetBuff(UDXINTERNAL pList,UdxBuff* pBuff);
//����ȡ
UDX_EXPORT int UdxListTryGetBuff(UDXINTERNAL pList,UdxBuff* pBuff);
//ȡ�ܳ���
UDX_EXPORT int UdxListGetSize(UDXINTERNAL pList);
//ȡ�ܸ���
UDX_EXPORT int UdxListGetCount(UDXINTERNAL pList);
//ɾ������
UDX_EXPORT void UdxListPopFront(UDXINTERNAL pList);
//ɾ������
UDX_EXPORT void UdxListDestroy(UDXINTERNAL pList);
//ɾ��ȡ���������ݽ��
UDX_EXPORT void UdxBuffDestroy(UdxBuff* pBuff);

//������־�ļ�
UDX_EXPORT void UdxSetUdxFileLogParam(int bEnable,char*szDir,char*szPrefix);


/////////////////��һͨ���ӿ�˵��////////////////////////////////////////////
//��ʼ��һ��ͨ����
//int bServer�ͻ������
//char* szLocalIp,int localport,����ռ�õ�IP,��PORT
//char*szRemoteIp,int iRemotePort,�����Ϊ�ͻ���ʱ��ָ����Զ�̵�IP,PORT
//UdxCB cb,�ص��¼�����
//���Ӿ߱���һЩ���ã�����fec,���ڴ�С����Ϸģʽ��

UDX_EXPORT UdxObj* UdxChannelInit(int bServer,char* szLocalIp,int localport,char*szRemoteIp,int iRemotePort,UdxCB cb,UdxLinkCfg cfg);

//��������,sendtype 0.��ʾ��ͨ���ͣ�1.��ʾ�ӵ����Ͷ��У������Ƿ��ͳɹ���2��ʾ��������Զ��ر�
//���ͨ���������ģ�����>=0,������0ʱ����ʾ��������С��0������ͨ��û�н������Ѿ��Ͽ�
UDX_EXPORT int	 UdxChannelSendData(UdxObj*pObj,unsigned char* pData,int len,int sendtype);

//��ͨ��
UDX_EXPORT void UdxChannelUninit(UdxObj* pObj);

#ifdef __cplusplus
}
#endif


#endif