// SDKDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SDKDemo.h"
#include "NetSdkModule.h"

//#include "Security.h"

#ifdef WIN32
#include "time.h"
#endif

extern long g_lLoginID;	//登录ID
extern long g_lLoginID2;	//登录ID




extern long g_Playhandle[32];

extern long g_upgradeHandle = 0;;
OS_EVENT				m_hRecEvt;
COSThread::COSThread()
{
	m_bCreate = FALSE;
#ifdef WIN32
	m_hThread = NULL;
#endif
}

COSThread::~COSThread()
{
	if (m_bCreate)
	{
#ifdef WIN32
		if (m_hThread != NULL)
		{
			CloseHandle(m_hThread);
			m_hThread = NULL;
		}
#endif
		m_bCreate = FALSE;
	}
}

#define DEF_THREAD_STACKSIZE (1024 * 1024)
int  CreateThreadEx(OS_THREAD &thread, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
{
#ifdef WIN32
	thread.m_hThread = CreateThread(NULL, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
	if (thread.m_hThread == NULL)
	{
		thread.m_bCreate = FALSE;
		return -1;
	}
	thread.m_bCreate = TRUE;

	return 0;
#elif defined  MAC
	typedef void* (*ln_start_routine)(LPVOID lpThreadParameter);
	ln_start_routine lpThreadAddress = (ln_start_routine)lpStartAddress;

	if (dwStackSize <= 0)
	{
		dwStackSize = DEF_THREAD_STACKSIZE;
	}
	pthread_attr_t thread_attr = {0};
	int ret = pthread_attr_init(&thread_attr);
	if (ret == 0)
	{
		ret = pthread_attr_setstacksize(&thread_attr, dwStackSize);
	}
	if(ret == 0)
	{
		ret = pthread_create(&thread.m_hThread, &thread_attr, lpThreadAddress, lpParameter);
	}
	if (ret != 0)
	{
		thread.m_bCreate = FALSE;
		return -1;
	}
	thread.m_bCreate = TRUE;

	return 0;
#else
	typedef void* (*ln_start_routine)(LPVOID lpThreadParameter);
	ln_start_routine lpThreadAddress = (ln_start_routine)lpStartAddress;

	int ret = pthread_create(&thread.m_hThread, NULL, lpThreadAddress, lpParameter);
	if (ret != 0)
	{
		thread.m_bCreate = FALSE;
		return -1;
	}
	thread.m_bCreate = TRUE;

	return 0;

#endif
}


void  CloseThreadEx(OS_THREAD &thread)
{
	if (thread.m_bCreate)
	{
#ifdef WIN32
		if (thread.m_hThread != NULL)
		{
			CloseHandle(thread.m_hThread);
			thread.m_hThread = NULL;
		}
#endif
		thread.m_bCreate = FALSE;
	}
}


BOOL  TerminateThreadEx(OS_THREAD &thread, DWORD dwExitCode)
{
	BOOL bRet = FALSE;
	if (thread.m_bCreate)
	{
#ifdef WIN32
		if (thread.m_hThread != NULL)
		{
			bRet = TerminateThread(thread.m_hThread, dwExitCode);
		}
#else
		int ret = pthread_cancel(thread.m_hThread);
		bRet = (ret == 0) ? TRUE:FALSE;
#endif
	}

	return bRet;
}


int main(int argc, char* argv[])
{
	//return TestRtspServer();	// 测试Rtsp服务功能

	unsigned long lRetLen = 0;	//返回的数据长度
	int nRetLen = 0;
	int nRet = 0;		//返回值
	int nChnNum = 1;	//通道号
	int error = 0;
	printf("long=%d\n",sizeof(long) );
	NET_SDK_DEVICEINFO tmpInfo = {0};
	
	//初始化SDK
	int i=0;
	printf("before init sdk\r\n");

	//char szPas[6]={"123456"};
	char dist[32]={0};

//	MD5Encrypt(dist,szPas);
	NET_SDK_Init(DisConnectCBFunc, 0);
	//NET_SDK_InitGlink("TSClient","20141102","1234567890",101,1);
	printf("before login\r\n");

#ifdef WIN32
	TSCreateEventEx(m_hRecEvt, TRUE, FALSE);
#else
	CreateEventEx(m_hRecEvt, TRUE, FALSE);
#endif
	//TestUpgradeFromServer();

#if 0    //设备端SDK登录调用，因为设备不保存明文密码，所以设备上使用SDK 登录时密码直接为加密之后的密码，这样可以直接从设备的配置文件中读取
	int nTYpe = 0; //升级必须为1，否则为0
	g_lLoginID =  NET_SDK_Login("192.168.1.98", 34567, "admin","tlJwpbo6", &tmpInfo,nTYpe, &error,5000,1);
#endif

#if 0  //LIUNX 下SDK
	g_lLoginID =  NET_SDK_Login("192.168.1.54", 34567, "admin","", &tmpInfo,0, &error,5000,1);

	if(g_lLoginID!=0)
	{
		printf("Login SDK ok\r\n");

		TestSwitchVideo();
		//TestCustomOSD();
		//TestGetID();
		//TestDigiEncode();
		//NET_SDK_NetDigitChnConfig  cfg={0};
		//unsigned long lRet=0;

		//int nRetturn = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_NETDECORDER, 0, (char*)&cfg,sizeof(NET_SDK_NetDigitChnConfig), &lRet, 5000);

		//printf("----111-------%s---nrte--%d\n",cfg.vNetDecorderConf[0].Address,nRetturn);
		//printf("----111-------%d---nrte--%d\n",cfg.ConfNum,nRetturn);
		//printf("----111-------%d---nrte--%d\n",cfg.SingleConnId,nRetturn);
		////cfg.ConfNum  =1;

		//nRetturn  = NET_SDK_SetDevConfig(g_lLoginID,NET_SDK_NETDECORDER,0,(char *)&cfg,sizeof(NET_SDK_NetDigitChnConfig),5000);

		//printf("----2222-------%s---nrte--%d\n",cfg.vNetDecorderConf[0].Address,nRetturn);

		//nRetturn = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_NETDECORDER, 0, (char*)&cfg,sizeof(NET_SDK_NetDigitChnConfig), &lRet, 5000);

		//printf("---3333-------%s---nrte--%d\n",cfg.vNetDecorderConf[0].Address,nRetturn);

		//TestModiPsw();
	}
	return 0;

#endif

#if 1
	OS_THREAD d1;
	CreateThreadEx(d1,NULL,(LPTHREAD_START_ROUTINE)Login,NULL,NULL,NULL);
	OS_THREAD d2;
	CreateThreadEx(d2,NULL,(LPTHREAD_START_ROUTINE)Login2,NULL,NULL,NULL);
	//Sleep(0.001);
	g_start=0;
	g_lLoginID =NET_SDK_Login("192.168.1.36", 34567, "admin","", &tmpInfo,0, &error,5000,1);  
#endif
	g_totalCHannel = tmpInfo.byChanNum + tmpInfo.iDigChannel;




//	g_lLoginID2 = NET_SDK_Login("192.168.1.105", 34567, "admin","", &tmpInfo,0, &error,5000,1);
		

 	if (0 == g_lLoginID)
 	{
 		printf("SDK_Login error, error=%d\n", error);
 	}
 	else
 	{
		printf("SDK_LOGIN OK -----%d\n",g_lLoginID);
		//TestMedia();	
		//TestAlarmCallBack();
		TestFDLibBaseCfg();
		TestFDSearchResult();
		TestFaceDetectMsg();
		//TestRcord();
		//TestPlayback();

		//TestUpgrade();
 	}
 	
	EnterKeyContinue("Login Out");	// 按“回车键”退出程序
 //	
 //	if (g_lLoginID != 0)	//登出
 //	{
 //		NET_SDK_Logout(g_lLoginID);
 //	}
	//
	//NET_SDK_Cleanup(); //·´³õÊ¼»¯SDK
	return 0;
}
void Login()
{
	while(1)
	{
		if(g_start)
		{
			NET_SDK_DEVICEINFO tmpInfo = {0};
			int error=0;
			g_lLoginID =  NET_SDK_Login("192.168.1.254", 34567, "admin","admin123", &tmpInfo,0, &error,5000,1);
			break;
		}
	}
}
void Login2()
{
	while(1)
	{
		if(g_start)
		{
			NET_SDK_DEVICEINFO tmpInfo = {0};
			int error=0;
			g_lLoginID =NET_SDK_Login("192.168.1.215", 34567, "admin","admin123", &tmpInfo,0, &error,5000,1); 
			break;
		}
	}
}
////////////////////////////////////¸¨Öúº¯ÊýÊµÏÖ////////////////////////////////////
void EnterKeyContinue(char *szStr)
{
	printf("---------------press \"Enter\" key to ");
	printf(szStr);
	printf("-----------\n");
	getchar();
}

int WriteFile(const char *pFileName, char *pData, int nLenght)
{
	FILE* fp = fopen(pFileName, "ab");
	if (fp != 0)
	{
		fwrite(pData, 1, nLenght, fp);
		fclose(fp);
		return 0;
	}
	
	return -1;
}

////////////////////////////////////回调函数实现//////////////////////////////////////
///< 服务器断开回调原形


int CALL_METHOD PlaybackNetDataCallBack_EX( long lRealHandle, const NET_SDK_PACKET_INFO_EX *pFrame,long dwUser)
{	

	printf("PlaybackNetDataCallback---------------------\r\n");

	if(pFrame->nPacketType==NET_VIDEO_I_FRAME)
	{

		printf("The video width:%d, height:%d \n",pFrame->uWidth,pFrame->uHeight);
		/*static int ijjj=0;
		char szName[16]={0};
		sprintf(szName,"%d.jpg",ijjj);

		FILE* file = fopen(szName,"wb");
		if(file)
		{
			fwrite(pFrame->pAVContent,1,pFrame->dwContentSize,file);
			fclose(file);
		}
		ijjj++;*/

	}
	else
	{
		printf("printf  -------------packetType:%d\n",pFrame->nPacketType);
	}

	/*if(pFrame&&(pFrame->nPacketType==1 || pFrame->nPacketType==3))
	{
		printf("----------------------%d----time:%d_%d_%d %d_%d_%d\n",pFrame->nPacketType,pFrame->nYear,pFrame->nMonth,pFrame->nDay,pFrame->nHour,pFrame->nMinute,pFrame->nSecond);
	}
	WriteFile("2.H264",(char*)pFrame->pAVContent,pFrame->dwContentSize);*/

	return 1;
}
///< 回放录像进度回调原形
void CALL_METHOD DownLoadRecordPosCallback (long lPlayHandle, long lTotalSize, long lDownLoadSize, long dwUser)
{
	printf("----downloadposcallback---------ltotalsize:%d,downsize:%d\n",lTotalSize,lDownLoadSize);

}

void CALL_METHOD DisConnectCBFunc(long lLoginID, char *pchDVRIP, long nDVRPort, unsigned long dwUser)
{
	printf("disConnect logID = %d\n", lLoginID);
}




bool CALL_METHOD AlarmMessCallBack(long lLoginID, char *pBuf, unsigned long dwBufLen, long dwUser)
{	
	
	NET_SDK_AlarmInfo* pAlarm = (NET_SDK_AlarmInfo*)pBuf;
	int nInComand = pAlarm->iEvent;
	int nChannel = pAlarm->nChannel;
	printf("receive alarm message---nInCommand:%d status:%d\n",nInComand,pAlarm->iStatus);
	return true;

	switch (nInComand)
	{
	case NET_SDK_EVENT_CODE_VIDEO_MOTION://运动检测
		{
			printf("motion\r\n");

		}
		break;
	case NET_SDK_EVENT_CODE_LOCAL_ALARM://本地报警
		{
			printf("alarm\r\n");
		}
		break;
	case NET_SDK_EVENT_CODE_NET_ALARM:
		{
			printf("local alarm\r\n");
		}
		break;
	case NET_SDK_EVENT_CODE_VIDEO_LOSS://视频丢失
		{
			printf("video loss\r\n");
		}			
		break;
	case NET_SDK_EVENT_CODE_VIDEO_BLIND://视频遮挡
		{
			printf("blnd\r\n");
		}
		break;
	case NET_SDK_EVENT_CODE_DEC_CONNECT:  //数字通道摄像头上下线
		{
			int nChannel = pAlarm->nChannel;  //报警的通道
			int nStatus  = pAlarm->iStatus;	  //状态的改变，0：摄像头上线， 1： 摄像头下线			
		}
		break;
	default:
		return 0;
	}
	
	return true;
}
typedef enum 
{
	FACE_IMG_TYPE_FACE   = 0xff, //< 仅人脸
	FACE_IMG_TYPE_HEAD_SHOULDER = 0xfd, //< 头肩
	FACE_IMG_TYPE_PANORAME = 0xfe, //< 全景图
	FACE_IMG_TYPE_UPPER_BODY = 0xfc,
	FACE_IMG_TYPE_FULL_BODY = 0xfb,
	FACE_IMG_TYPE_PALM = 0xfa,   //< 手掌
	FACE_IMG_TYPE_PERSON = 0xf9,
	FACE_IMG_TYPE_FIGURE = 0xf8, //< 人形
	FACE_IMG_TYPE_NR = 0xe1, //<0xff-0xe1=0x1e(即最大30)固定,禁止修改!!!
}FACE_IMG_TYPE_E;


void CALL_METHOD FaceDetectCallback(long faceChannel,int channel,int ntype,char* pBuf, unsigned long dwBufLen, long dwUser)
{
	static int ijjj=0;
	printf("channel=%d\n",channel);
	if(ntype==0)
	{
		char FACE_IMG_TYPE = (char)FACE_IMG_TYPE_NR + (char)pBuf[5];
		printf("FACE_IMG_TYPE_E %x %x\n",FACE_IMG_TYPE,pBuf[5]);
		char szNametest[16]={0};
		sprintf(szNametest,"test%d.jpg",ijjj);
		if(dwBufLen>16)
		{
			printf("%s\n",szNametest);
			char *testbuf=new char[dwBufLen-16];
			memcpy(testbuf, pBuf+16,dwBufLen-16);
			FILE *fp = fopen(szNametest, "wb");
			if(fp)
			{
				fwrite(testbuf,dwBufLen-16,1,fp);
				fclose(fp);
			}
			delete testbuf;
		}
	}
	else
	{
		char szNamesimila[16]={0};
		char szNameface[16]={0};
		char szNamefull[16]={0};
		sprintf(szNamesimila,"simila%d.jpg",ijjj);
		sprintf(szNameface,"face%d.jpg",ijjj);
		sprintf(szNamefull,"full%d.jpg",ijjj);

		NET_SDK_FaceMsgHead nZklz;
		memcpy(&nZklz,pBuf,sizeof(NET_SDK_FaceMsgHead));
		char *faceBuf = new char[nZklz.faceLen]; 
		char *simBuf = new char[nZklz.similaLen]; 
		char *fullBuf =new char[nZklz.fullLen];
		NET_SDK_FDMatchAlarm nFaceAttr;
		memcpy(&nFaceAttr,pBuf+nZklz.attrPos,nZklz.attrLen);
		printf("age=%d,genderType=%d,bWithGlasses=%d,bWithHat=%d\n",nFaceAttr.age,nFaceAttr.ageGroup,nFaceAttr.bWithGlasses,nFaceAttr.bWithHat);
		printf("matchInfo.FDID=%d,matchInfo.PID=%s \n",nFaceAttr.matchInfo.FDID,nFaceAttr.matchInfo.PID);
		printf("nZklz.similaLen =%d \n",nZklz.similaLen);
		if (nZklz.similaLen >0)//相似图
		{
			memcpy(simBuf,  pBuf+nZklz.similaPos, nZklz.similaLen);
			printf("%s\n",szNamesimila );
			FILE *fp = fopen(szNamesimila, "wb");
			if(fp)
			{
				fwrite(simBuf,dwBufLen ,1,fp);
				fclose(fp);
			}
		}
		if (nZklz.faceLen >0)//脸图
		{
			memcpy(faceBuf, pBuf+nZklz.facePos+16,nZklz.faceLen-16);
			printf("%s\n",szNameface );
			FILE *fp = fopen(szNameface, "wb");
			if(fp)
			{
				fwrite(faceBuf,nZklz.faceLen ,1,fp);
				fclose(fp);
			}
		}
		if (nZklz.fullLen >0)//全图
		{
			memcpy(fullBuf, pBuf+nZklz.fullPos+16,nZklz.fullLen-16);
			printf("%s\n",szNamefull);
			FILE *fp = fopen(szNamefull, "wb");
			if(fp)
			{
				fwrite(fullBuf,nZklz.fullLen ,1,fp);
				fclose(fp);
			}
		}	 
		delete faceBuf;
		delete fullBuf;
		delete simBuf;
	}
	
	/*{
		int fullLen = 0;
		memcpy(&fullLen,pBuf+dwBufLen,sizeof(fullLen));
		if(fullLen>0)
		{
			char *fullBuf = new char[fullLen]; 
			memcpy(fullBuf,pBuf+dwBufLen+4+16,fullLen-16);
			FILE *fp = fopen(szNamefull, "wb");
			if(fp)
			{
				fwrite(fullBuf,fullLen ,1,fp);
				fclose(fp);
			}
		}
	}*/
	

	ijjj++;
}
/////////////////////²âÊÔÊÓÆµÊµÊ±Ô¤ÀÀ////////////////////////////////////////

int CALL_METHOD RealDataCBFunc(long lRealHandle, long dwDataType, unsigned char *pBuffer,long lbufsize,long dwUser)
{
	printf("rev video data len = %d---handle:%d\n", lbufsize,lRealHandle);

	return 0;
}


int CALL_METHOD RealDataCBFuncEx(long lRealHandle, const NET_SDK_PACKET_INFO_EX *pFrame, long dwUser)
{
	/*if(pFrame->nPacketType==NET_VIDEO_J_FRAME)
	{
		static int ijjj=0;
		char szName[16]={0};
		sprintf(szName,"%d.jpg",ijjj);

		FILE* file = fopen(szName,"wb");
		if(file)
		{
			fwrite(pFrame->pAVContent,1,pFrame->dwContentSize,file);
			fclose(file);
		}
		ijjj++;

	}

	else 
	{
		WriteFile("2.H264",(char*)pFrame->pAVContent,pFrame->dwContentSize);
	}*/

	return 0;
}

void TestMedia()
{
	printf("TestMedia\n");
	NET_SDK_CLIENTINFO clientInfo;
	for(int j=0;j<32;j++)
	{
		g_Playhandle[j]=0;
	}
	//while(1)
	{
		for(int i=1;i<g_totalCHannel;i++)
		{
			printf("start--realplay channel:%d \n",i);
			clientInfo.nChannel = i;
			clientInfo.nStream = 0;
			if ( g_Playhandle[i]==0)
			{				
				g_Playhandle[i] = NET_SDK_RealPlay(g_lLoginID,&clientInfo,0);
				if(g_Playhandle[i]==0)
				{
					int nerror = NET_SDK_GetLastError();
					printf("Realplay Error NO==%d!\n",nerror);
					
				}
				
			}
			else
			{
				//NET_SDK_SetRealDataCallBack(lHandle, RealDataCBFunc, 0);
				NET_SDK_SetRealDataCallBack_EX(g_Playhandle[i],RealDataCBFuncEx,0);
				printf("Realplay OK---------------handle:%d!\n",g_Playhandle[i]);
				//usleep(5000000);
				//EnterKeyContinue();
				//NET_SDK_StopRealPlay(lHandle);
			}
		}
		//Sleep(10);
	}
		//for(int i=0;i<g_totalCHannel;i++)
	//{
	//	clientInfo.nChannel = i;
	//	clientInfo.nStream = 1;
	//	long lHandle = NET_SDK_RealPlay(g_lLoginID2,&clientInfo,0);
	//	if (0 == lHandle)
	//	{
	//		printf("Realplay Error!\n");
	//	}
	//	else
	//	{
	//		NET_SDK_SetRealDataCallBack(lHandle, RealDataCBFunc, 0);
	//		printf("Realplay OK---------------handle:%d!\n",lHandle);
	//		//usleep(5000000);
	//		//EnterKeyContinue();
	//		//NET_SDK_StopRealPlay(lHandle);
	//	}

	//}

	

	//³ÌÐòÔÝÍ£
	EnterKeyContinue();
}

typedef struct  
{
	char *pStr;
	int nLength;
}SString;

bool GetStrings(char *pString, int nChar, SString *pResult, int nMax, int &nCount)
{
	nCount = 0;
	if (!pString || nMax < 1)
	{
		return false;
	}
	
	pResult[nCount++].pStr = pString;
	char *pTemp = pString;
	do
	{
		pTemp = ::strchr(pTemp + 1, nChar);
		if (pTemp)
		{
			pResult[nCount++].pStr = pTemp + 1;
			if(nMax <= nCount)
			{
				break;
			}
		}
	} while (NULL != pTemp);
	
	int nEnd = nCount - 1;
	for(int i = 0; i < nEnd; i++)
	{
		pResult[0].nLength = pResult[i + 1].pStr - pResult[i].pStr; 
	}
	
	const char *pStrEnd = pString + strlen(pString);
	if (pStrEnd == pResult[nEnd].pStr)
	{
		nCount--;
	}
	else
	{
		pResult[nEnd].nLength = pStrEnd - pResult[nEnd].pStr;
	}
	
	return true;
}

//   0      1                              2                          3     4     5      6        7                       8      9
//通道号_开始时间(yyyy-MM-dd-HH-mm-ss)_结束时间(yyyy-MM-dd-HH-mm-ss)_盘号_分区号_簇号_文件序号_文件类型(00录像 01图片)_子类型_文件长度


//录像查询、下载、回放----录像处理参数程序
//录像查询有两种方式
//1、通过SDK_FindFile、SDK_FindNextFile、SDK_FindClose接口实现录像文件的查询通道此接口查，接图片的类型查询图片
//详见SDK_FindFile说明。
//2、通过接口SDK_GetDevConfig函数实现，这种查询方式可以按图片的分类查询，详见libmodel.h中有关RV_NET_FILEINFO说明
//支持这种方式的设备，也同时支持第1种方式。
void TestRcord()			
{
	printf("TestRcord\n");
	{
		long lType = 0;//9表示图片 
		long lRet = 0;
		NET_SDK_FINDINFO  findInfo ;
		memset(&findInfo, 0, sizeof(NET_SDK_FINDINFO));
		findInfo.nFileType = 0;
		findInfo.nStream = 0;
		findInfo.nChannelN0 =0;
		findInfo.startTime.dwYear = 2017;
		findInfo.startTime.dwMonth = 7;
		findInfo.startTime.dwDay = 18;
		findInfo.startTime.dwHour = 0;
		findInfo.startTime.dwMinute = 0;
		findInfo.startTime.dwSecond = 59;
		
		findInfo.endTime.dwYear = 2017;
		findInfo.endTime.dwMonth = 7;
		findInfo.endTime.dwDay =18;
		findInfo.endTime.dwHour = 23;
		findInfo.endTime.dwMinute = 59;
		findInfo.endTime.dwSecond = 59;
		NET_SDK_FILE_DATA* szReceive = new NET_SDK_FILE_DATA[64];
		memset(szReceive,0,sizeof(NET_SDK_FILE_DATA)*64);
		int nNum = 0;		
		long lPlayHandle =  NET_SDK_FindFileByName(g_lLoginID, &findInfo, szReceive, 64, &nNum);
		for(int i=0;i<nNum;i++)
		{
			printf("num:%d,stream:%d filename:%s\n",i,szReceive[i].nstream,szReceive[i].sFileName);
		}

		NET_SDK_SearchByTime find={0};
		find.iSync = false;
		find.nFileType = 0;
		find.nStream =0;
		find.nHighChannel = 0;
		find.nLowChannel = 1;

		find.stBeginTime.year = 2017;
		find.stBeginTime.month = 8;
		find.stBeginTime.day = 1;
		find.stBeginTime.hour = 0;
		find.stBeginTime.minute = 0;
		find.stBeginTime.second = 0;

		find.stEndTime.year = 2017;
		find.stEndTime.month = 8;
		find.stEndTime.day = 1;
		find.stEndTime.hour = 23;
		find.stEndTime.minute = 0;
		find.stEndTime.second =0;
		find.iSync = false;

		NET_SDK_SearchByTimeResult pileData={0};
		long lHandle =  NET_SDK_FindFileByTime(g_lLoginID, &find, &pileData,  10000);
		if (lHandle == 0)
		{
			printf("find file error\n");
		}
		else
		{
			for(int i=0;i<720;i++)
			{
				int ntmp =pileData.ByTimeInfo[0].cRecordBitMap[i];
				if(ntmp!=0)
				{
					printf("-----------the time is :%d\n",ntmp);
					ntmp = 0;

				}
			}
			printf("find file OK-----------nNum=%d\n",pileData.nInfoNum);
		}
	}
}

//云台操作----操作云台参数程序
void TestPTZ()				
{
	printf("TestPTZ\n Enter 'q'=quit;   'u'=Go up; 'd'=Go down; 'l' = Go left; 'r'=Go right;\n");
	char c = getchar();
	while(c != 'q')
	{
		switch (c)
		{
		case 'u':
			NET_SDK_PTZControl(g_lLoginID, 0, NET_TILT_UP, 2, 2,0);
			Sleep(1000);
			NET_SDK_PTZControl(g_lLoginID, 0, NET_TILT_UP, 2, 2,0,true);
			break;
		case 'd':
			NET_SDK_PTZControl(g_lLoginID, 0, NET_TILT_DOWN, 2, 2,0);
			Sleep(1000);
			NET_SDK_PTZControl(g_lLoginID, 0, NET_TILT_DOWN, 2, 2,0,true);
			break;
		case 'l':
			NET_SDK_PTZControl(g_lLoginID, 0, NET_PAN_LEFT, 2, 2,0);
			Sleep(1000);
			NET_SDK_PTZControl(g_lLoginID, 0, NET_PAN_LEFT, 2, 2,0,true);
			break;
		case 'r':
			NET_SDK_PTZControl(g_lLoginID, 0, NET_PAN_RIGHT, 2, 2,0);
			Sleep(1000);
			NET_SDK_PTZControl(g_lLoginID, 0, NET_PAN_RIGHT, 2, 2,0,true);
			break;
		default:
			break;
		}
		c = getchar();
	}
}


/////////////////////测试报警////////////////////////////////////////
void TestAlarmCallBack()	
{
	printf("TestAlarmCallBack\n");
	
	//开始报警监听(SDK_StartListenEx, 比SDK_StartListen监听的报警类型多，详见SDK帮助)
	NET_SDK_SetupAlarmChan(g_lLoginID);		
	NET_SDK_SetDVRMessCallBack(AlarmMessCallBack, 1);  //初始化消息回调.
	
	//程序暂停
	EnterKeyContinue();
	
	//退出报警监听
	NET_SDK_CloseAlarmChan(g_lLoginID);
}

void TestFaceDetectMsg()
{
	printf("TestFaceDetectMsg\n");
	long facehand=NET_SDK_FaceDetectMsg(g_lLoginID,FaceDetectCallback,1);
	printf("facehand=%d\n",facehand);
	EnterKeyContinue();
	NET_SDK_StopFaceMsg(facehand);
}
void TestFDLibBaseCfg()
{
	printf("TestFDLibBaseCfg\n");
	NET_SDK_FDLibBaseCfgList FDList;
	memset(&FDList,0,sizeof(NET_SDK_FDLibBaseCfgList));
	long nRet=0;
	nRet=NET_SDK_GetFDLibBaseCfg(g_lLoginID,&FDList);
	printf("FDNum=%d\n",FDList.FDNum);
	for(int i=0;i<FDList.FDNum;i++)
	{
		printf("FDLibBaseCfg[%d] id:%d \n",i,FDList.FDLibBaseCfg[i].id);
		printf("FDLibBaseCfg[%d] FDID:%d \n",i,FDList.FDLibBaseCfg[i].FDID);
		printf("FDLibBaseCfg[%d] name:%s \n",i,FDList.FDLibBaseCfg[i].name);
		printf("FDLibBaseCfg[%d] thresholdValue:%d \n",i,FDList.FDLibBaseCfg[i].thresholdValue);
		printf("FDLibBaseCfg[%d] customInfo:%s \n",i,FDList.FDLibBaseCfg[i].customInfo);
	}
}
void CALLBACK cbNetDownLoadPosCallBack(long lPlayHandle, long lTotalSize, long lDownLoadSize, long dwUser)
{
	SetEventEx(m_hRecEvt);
}
int nsearch=1;
void TestFDSearchResult()
{
	NET_SDK_FDSearchDescription SearchDescription;
	NET_SDK_FDSearchResult SearchResult;
	memset(&SearchDescription,0,sizeof(NET_SDK_FDSearchDescription));
	memset(&SearchResult,0,sizeof(NET_SDK_FDSearchResult));
	SearchDescription.FDID=-1;
	SearchDescription.maxResults=64;
	int Pos=0;
	while(1)
	{
		SearchDescription.searchResultPosition=Pos;
		long nRet=NET_SDK_FDSearch(g_lLoginID,&SearchDescription,&SearchResult);
		printf("numOfMatches=%d\n",SearchResult.numOfMatches);
		for(int i=0;i<SearchResult.numOfMatches;i++)
		{
			printf("FDMatch[%d] PID:%s \n",i,SearchResult.FDMatch[i].PID);
			printf("FDMatch[%d] FDID:%d \n",i,SearchResult.FDMatch[i].FDID);
			NET_SDK_FILE_DATA file;
			memset(&file,0,sizeof(NET_SDK_FILE_DATA));
			memcpy(file.sFileName,SearchResult.FDMatch[i].PID,64);
			char SaveName[128]={0};
			sprintf(SaveName,"search%d.jpg",nsearch++);
			printf("g_lLoginID %d \n",g_lLoginID);
			long playback_dowload_handle = NET_SDK_GetFileByName(g_lLoginID,&file,SaveName,cbNetDownLoadPosCallBack);
			printf("playback_dowload_handle %d \n",playback_dowload_handle);
			DWORD dwRet = WaitForSingleObjectEx(m_hRecEvt, 5000);
			ResetEventEx(m_hRecEvt);
			if (dwRet != WAIT_OBJECT_0 )
			{  //说明验证失败
				
				printf("error \n");
			}
			else
			{
				printf("0k \n");
			}
			NET_SDK_StopGetFile(playback_dowload_handle);
			/*
			while(playback_dowload_handle)
			{
				int nPos = NET_SDK_GetDownloadPos(playback_dowload_handle);
				printf("Pos = %d",nPos);
				if(nPos<100&&nPos>=0)
				{
					//usleep(10);
				}
				else
				{
					NET_SDK_StopGetFile(playback_dowload_handle);
					break;
				}
			}*/
		}
		Pos+=SearchResult.numOfMatches;
		if(SearchResult.numOfMatches<64)
		{
			break;
		}
	}
}
void CALLBACK cbUpgradenew(long lLoginID, long lUpgradechannel,int nTotalSize, int nSendSize, long dwUser)
{
	if(nSendSize == -1)
	{
		printf("-----update success\n--");
		//升级成功
	}
	else if(nSendSize == -2)
	{
		//升级失败需要调用 NET_SDK_CloseUpgradeHandle 关闭升级，但不能在回调函数中去处理，可以用定时器或者发送消息在其他地方去处理调用
		printf("-----update failed\n--");
	}
	else if(nTotalSize == -1)
	{		
		int pos = nSendSize; //设备升级中 0-100
		printf("-----update run-----percent:%d\n",pos);

	}
	else if(nTotalSize ==100)
	{
		 //通过服务器升级时，TotalSize 100，如果是本地发送数据，totalsize 为文件大小 数据发送进度
		
		printf("-----downloadSize-----percent:%d\n",nSendSize);
	}
}
DWORD CALLBACK  UpgradeThreadProc_New(LPVOID *pPara)
{
	/*
	unsigned char buffer[32768];
	int readlen = 0;
	float nSendTotal = 0.0;
	printf("start upgrade---\n");
	FILE *file = fopen("update.bin", "rb");
	if (file)
	{	
		printf("222222222222222222---\n");
		while (1)
		{

			printf("--------beforeread---------time:%d\n",time(NULL));
			if ((readlen = fread(buffer, 1, 32 * 1024, file)) > 0)
			{
				printf("--------AFTER READ---------time:%d\n",time(NULL));
			//	int nSendLen = NET_SDK_SendUpgradeData(g_lUpchannel,(char*)buffer,readlen);
				printf("--------AFTER UPGRADE---------time:%d\n",time(NULL));
				 
				if(nSendLen>0)
				{
					nSendTotal +=nSendLen;
					float fPer = nSendTotal/g_totalSize;
					printf("-send persent-----send:%f,Total:%d,percent:%f \n", nSendTotal,g_totalSize,fPer);
				}
				else
				{

					NET_SDK_CloseUpgradeHandle(g_lUpchannel);
					g_lUpchannel = 0;
					break;
				}
			}
			//数据以及发送完成，通过回调函数可以得知设备升级的百分比，此处不要去关闭关闭句柄，只是将数据发送完成，设备还需要进行烧写FLASH的操作
			else
			{
				break;
			}
		}

		fclose(file);
		file = 0;
	}
	*/
	

	return 0;
}
void TestUpgrade()
{
	/*
	int error = 0;
	NET_SDK_DEVICEINFO tmpInfo = {0};
	//此处必须重新登录过，登录的类型为 1，表明为升级登录
	long lLoginID =  NET_SDK_Login("192.168.1.54", 34567, "admin","", &tmpInfo,1, &error,5000,1);
	if(lLoginID != 0)
	{
		FILE *file = fopen("update.bin", "rb");
		int nTotalSize = 0;
		if(file)
		{
			fpos_t pos;
			fseek(file, 0, SEEK_END);
			fgetpos(file, &pos);
#ifdef WIN32
			nTotalSize = pos;
#else
			nTotalSize = pos.__pos;
#endif
			g_totalSize = nTotalSize;
			fclose(file);
			file = NULL;
			printf("the totalsize is %d\n",nTotalSize);
		}
		
		EnterKeyContinue();
		g_lUpchannel = NET_SDK_StartUpgrade(lLoginID,nTotalSize,0,cbUpgradenew,1);
		OS_THREAD m_hThread;
		DWORD   dThreadID = 0;
		int ret = CreateThreadEx(m_hThread, 0, (LPTHREAD_START_ROUTINE)UpgradeThreadProc_New, NULL, 0, &dThreadID);
		if (ret >= 0)
		{
			printf("ok");
		}
		EnterKeyContinue();
		while(1)
		{
			//printf("---------before SLEEP,time:%d\n",time(NULL));
			Sleep(1);
		}
	
	
	}
	*/
}

void TestPlayback()
{
	NET_SDK_FINDINFO info;
	memset(&info, 0, sizeof(info));
	info.nChannelN0 =0;
	info.nFileType = 0;
	info.nStream = 1;
	info.startTime.dwYear = 2017;
	info.startTime.dwMonth = 7;
	info.startTime.dwDay = 17;

	info.startTime.dwHour = 0;
	info.startTime.dwMinute = 0;
	info.startTime.dwSecond = 0;
	info.endTime.dwYear = 2017;
	info.endTime.dwMonth = 7;
	info.endTime.dwDay = 17;
	info.endTime.dwHour = 23;
	info.endTime.dwMinute = 8;
	info.endTime.dwSecond = 0;

	printf("-----------g_loginID:%d\n",g_lLoginID);

	long lHandle = NET_SDK_PlayBackByTime_Ex(g_lLoginID, &info, PlaybackNetDataCallBack_EX, (DWORD)1, DownLoadRecordPosCallback, (DWORD)1);

	printf("lhandle------------:%d\n",lHandle);
	if(lHandle <= 0 )
	{

		LONG error = NET_SDK_GetLastError();

		printf("回放失败------------error:%d\n",error);
		return;
	}
		EnterKeyContinue();
}

void TestGetID()
{
	NET_SDK_UMEYE_T1 cfg={0};
	unsigned long lret=0;
	int nreturn = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_NET_UMEYE,0,(char*)&cfg,sizeof(cfg),&lret,4000);
	if(nreturn>=0)
	{
		printf("id:%s \n", cfg.UMID);
	}
}


void TestDigiEncode()
{
	NET_SDK_DIGI_Config digiEncode={0};
	unsigned long lret=0;
	int nreturn = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_DIGIENCODE,0,(char*)&digiEncode,sizeof(NET_SDK_DIGI_Config),&lret,4000);
	if(nreturn>=0)
	{
		printf("compression:%d fps:%d  resolution:%d \n", digiEncode.maincfg.iCompression,digiEncode.maincfg.nFPS,digiEncode.maincfg.iResolution);
	}
	digiEncode.subcfg.iQuality = 3;
	digiEncode.subcfg.nFPS = 6;
	digiEncode.subcfg.iGOP = 25;
	digiEncode.subcfg.nBitRate = 2000;

	nreturn = 	NET_SDK_SetDevConfig(g_lLoginID, NET_SDK_CONFIG_DIGIENCODE, 0, (char *) &digiEncode, sizeof(digiEncode), 4000);
	if(nreturn>=0)
	{		
		nreturn =0;
	}

}
void TestModiPsw()
{
/*	NET_SDK_CONF_MODIFY_PSW psw = {0};
	bool bIPC = true;
	char* pUTF8 = NULL;
	pUTF8 = new char[256];
	if (NULL == pUTF8)
	{	
		return ;
	}
	memset(pUTF8,0,256);
	//IPC
	if(bIPC)
	{
		psw.iEncryptType = PASSWORD_PLAIN;
		strcpy(psw.NewPassword,"123456");  //新密码写明文
		strcpy(psw.sUserName,"admin");
		NET_SDK_MD5ENCODE(pUTF8,(unsigned char*)psw.Password);
		strcpy(psw.Password,pUTF8);  //老密码必须是加密后的密码
		printf("old password--:%s\n",psw.Password);
		
	}
	else //DVR
	{
		strcpy(psw.sUserName,"admin");
		strcpy(psw.NewPassword,"123456");
		psw.iEncryptType = PASSWORD_MD5;

		NET_SDK_MD5ENCODE(pUTF8,(unsigned char*)psw.Password);
		strcpy(psw.Password,pUTF8);  //老密码必须是加密后的密码
		memset(pUTF8,0,256);
		NET_SDK_MD5ENCODE(pUTF8,(unsigned char*)psw.NewPassword); //新密码必须是加密后的密码
		memset(psw.NewPassword,0,SDK_NET_MAX_USER_LENGTH);
		strcpy(psw.NewPassword,pUTF8);
		printf("old password--:%s\n",psw.Password);
		printf("new password--:%s\n",psw.NewPassword);
		
	}
	delete pUTF8;

	int nreturn = NET_SDK_SetDevConfig(g_lLoginID,NET_SDK_CONFIG_MODIFY_PSW,0,(char*)&psw, sizeof(psw), 4000);
	if(nreturn>=0)
	{
		printf("------ok");
	}
	long nerror = NET_SDK_GetLastError();
	printf("-----error---:%d\n",nerror);*/
}


void TestIPV6()
{
	unsigned long lret=0;
	NET_SDK_SystemFunction sysFuc;

	NET_SDK_NetIPVersionConfig m_NetIPVersion;
	NET_SDK_NetCommonIPv6Config m_NetCommIPv6;	
	int nreturn = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_ABILITY_SYSFUNC,0,(char*)&sysFuc,sizeof(NET_SDK_SystemFunction),&lret,4000);
	if(nreturn>=0)
	{
		printf("GetIPV6=====================================\n");
		NET_SDK_CONFIG_NET_COMMON m_Netcomm;
		if((sysFuc.vOtherFunction[NET_SDK_OTHER_SUPPORT_IPV6/32])&(1<<(NET_SDK_OTHER_SUPPORT_IPV6%32)))
		{		
			int bRet = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_NETIPV6COMMON,0,(char *)&m_NetCommIPv6, sizeof(m_NetCommIPv6),&lret,4000);
			if(bRet>=0)
			{
				printf("ipv6:HostIP:%s \n",m_NetCommIPv6.HostIP);
				bRet = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_NETIPVERSION,0,(char *)&m_NetIPVersion, sizeof(m_NetIPVersion),&lret,4000);
				if(bRet>=0)
				{
					printf("IPVersion:%d \n",m_NetIPVersion.IPVersion);
				}
			}
		}

		int nRet =  NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_SYSNET,0,(char *)&m_Netcomm, sizeof(m_Netcomm),&lret,4000);
		if(nRet >=0)
		{
			printf("ipv4:HostIP:%s \n",m_Netcomm.HostIP.c);
		}

		printf("SetIPV6=====================================\n");
		if((sysFuc.vOtherFunction[NET_SDK_OTHER_SUPPORT_IPV6/32])&(1<<(NET_SDK_OTHER_SUPPORT_IPV6%32)))
		{
			nreturn = 	NET_SDK_SetDevConfig(g_lLoginID, NET_SDK_CONFIG_DIGIENCODE, 0, (char *) &m_NetCommIPv6, sizeof(m_NetCommIPv6), 4000);
			printf("SetIPV6 result:%d \n",nreturn);
		}		
	}	
}

struct WirelessLocation
{
	char vLocation[32];
};

void Test3GConfig()
{
	NET_SDK_Net3GConfig         m_Net3G;
	NET_SDK_Net3GConfigV2		m_Net3GV2;
	NET_SDK_WirelessLocation	m_3GLocation;
	NET_SDK_WirelessISP			m_3GISP;
	WirelessLocation m_NetInLocation;
	unsigned long lret = 0;
	int nRet = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_ABILITY_LOCATION,0,(char*)&m_3GLocation,sizeof(m_3GLocation),&lret,4000);
	if ( nRet >= 0 )
	{
		strcpy(m_NetInLocation.vLocation,"India");
		nRet = NET_SDK_GetDevConfigV2(g_lLoginID,NET_SDK_CONFIG_ABILITY_ISP,0,(char* )&m_NetInLocation,sizeof(m_NetInLocation),(char*)&m_3GISP,sizeof(m_3GISP),&lret,4000); 
		if(nRet >=0)
		{
			nRet =  NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_NET_3G,0,(char*)&m_Net3GV2,sizeof(m_Net3GV2),&lret,4000);
			if ( nRet >= 0 )
			{
				printf("-------------3G-----OK\n");
			}
		}		
	}
}


// how to switch video from channl by channel. The function can only be used after the channel is really opened by VLC or other player by RTSP
void TestSwitchVideo()
{
	NET_SDK_OperationMonitor  operationMonitor={0};
	operationMonitor.dstChn = 1;
	operationMonitor.srcChn = 0;
	operationMonitor.stream = 0; //--> this paramenter should be the value that you opened by VLC or other player by RTSP. 
	printf("TestSwitchVideo \n");
	int nRet = NET_SDK_SetDevConfig(g_lLoginID,NET_SDK_CONFIG_OPERATIONMONITOR, -1, (char *) &operationMonitor, sizeof(operationMonitor), 4000);
}

// How to set the own OSD
void TestCustomOSD()
{
	NET_SDK_CustomTitleConfigAll customTileConfigAll;
	unsigned long lret = 0;
	int nRet = NET_SDK_GetDevConfig(g_lLoginID,NET_SDK_CONFIG_CUSTOM_TITLE,-1,(char *)&customTileConfigAll,sizeof(customTileConfigAll),&lret,10000);
	char strTemp[64] = "DDDDDDD";
	customTileConfigAll.vCustomTitleConfigAll[0].customTitle.rcRelativePos.left= 1024;
	customTileConfigAll.vCustomTitleConfigAll[0].customTitle.rcRelativePos.right= 1024;
	customTileConfigAll.vCustomTitleConfigAll[0].customTitle.bEncodeBlend = true;
	customTileConfigAll.vCustomTitleConfigAll[0].textAlign = 1;
	strcpy(customTileConfigAll.vCustomTitleConfigAll[0].strText[0],strTemp);
	nRet = NET_SDK_SetDevConfig(g_lLoginID, NET_SDK_CONFIG_CUSTOM_TITLE, -1, (char *)&customTileConfigAll,sizeof(customTileConfigAll), 4000);
}

void TestUpgradeFromServer()
{
	int error = 0;
	g_upgradeHandle = 0;
	NET_SDK_DEVICEINFO tmpInfo = {0};
	//此处必须重新登录过，登录的类型为 1，表明为升级登录
	long lLoginID =  NET_SDK_Login("192.168.1.146", 34567, "admin","tlJwpbo6", &tmpInfo,1, &error,5000,1);
	if(lLoginID != 0)
	{
		printf("Login ok\n");
		EnterKeyContinue();
		NET_SDK_ServerUpgradeInfo info ={0};
		int nRet = NET_SDK_CheckUpgradeFromServer(lLoginID,&info,8000);
		if(nRet==0)
		{
			printf("The loginFilename is :%s \n The FileDate is :%s \n The Level is:%d\n The Log:%s \n",info.szfileName,info.szfiledate,info.nFileLevel,info.szChanngeLog);
			EnterKeyContinue();
			long lHandle = NET_SDK_StartUpgradeFromServer(lLoginID,&info,cbUpgradenew,1);
			if(lHandle!=0)
			{
				g_upgradeHandle = lHandle;
				printf("Handle OK,close handle after upgrade OK\n");
			}
		}		
		EnterKeyContinue();

		printf("clode upgradeHandle\n");
		NET_SDK_CloseUpgradeHandle(g_upgradeHandle);

	}

}
