#include "stdafx.h"
#include "USBModule.h"
#include "DataCenter.h"
#include "zkfpi.h"
CUSBModule::CUSBModule( IMsgListener *pListener )
: m_pListener(pListener)
, m_hCom(INVALID_HANDLE_VALUE)
, m_ComBaudRate(115200)
, m_ComNum(1)
, m_ModuleState(0)
, m_ConnectOK(0)
, m_Readlen(0)
, m_BlockTransport(0)
, m_StartRead(0)
, m_connectType(0)
, m_sensor(NULL)
, m_SinkDataLen(0)
{
	memset(m_ComOutBuf, 0, 200*1024);
	memset(m_ComInBuf, 0, 200*1024);
	memset(&m_Options, 0, sizeof(TOptions));
	memset(&m_Write_OS, 0, sizeof(OVERLAPPED));
	memset(&m_READ_OS, 0, sizeof(OVERLAPPED));
	StartReadData();
}	

CUSBModule::~CUSBModule()
{
	StopReadData();
}

void CUSBModule::HeartBeat_Imp()
{
	m_queMutex.acquire();
	int size = m_pduQueue.size();
	if (size == 0)
	{
		m_queMutex.release();
		return;
	}
	CInterProtocl *pdu = m_pduQueue.front();
	m_pduQueue.pop_front();
	m_queMutex.release();
	
	switch (pdu->m_eventType)
	{
	case EVENT_REQUEST:
		{
			DealOneRequestMsg(pdu);
		}
		break;
	case EVENT_RESPONSE:
		{
			DealOneResponseMsg(pdu);
		}
		break;
	}
	pdu->recycleITP();
	Sleep(50);
}

void CUSBModule::DealOneRequestMsg( CInterProtocl *pITP )
{
	CInterProtocl *pRes = CDataCenter::GetInstance()->GetITP();
	if (pRes == NULL)
	{
		return;
	}
	int begTime = GetTickCount();
	switch (pITP->m_operation)
	{
	case OP_CONNECT:
		{
			ConnectToModule(pITP, pRes);
		}
		break;
	case OP_DIS_CONNECT:
		{
			DisConnectToModule(pITP, pRes);
		}
		break;
	/*case OP_START_READ_DATA:
		{
			StartReadData(pITP, pRes);
		}
		break;*/
	case OP_READ_DATA:
		{
			ReadData(pITP, pRes);
		}
		break;
	/*case OP_STOP_READ_DATA:
		{
			StopReadData(pITP, pRes);
		}
		break;*/
	case OP_ENROLL:
		{
			Enroll(pITP, pRes);
		}
		break;
	case OP_VERIFY:
		{
			Verify(pITP, pRes);
		}
		break;
	case OP_DEL_TMP:
		{
			DelTmp(pITP, pRes);
		}
		break;
	case OP_DEL_USER:
		{
			DelUser(pITP, pRes);
		}
		break;
	case OP_DEL_DB:
		{
			DelDB(pITP, pRes);
		}
		break;
	case OP_DEL_LOG:
		{
			DelLog(pITP, pRes);
		}
		break;
	case OP_ENROLL_IMAGE:
		{
			EnrollImage(pITP, pRes);
		}
		break;
	case OP_SCAN_IMAGE:
		{
			ScanFpImage(pITP, pRes);
			int d = 0;
		}
		break;
	case OP_LOAD_LOG:
		{
			LoadLog(pITP, pRes);
		}
		break;
	case OP_SET_TIME:
		{
			SetTime(pITP, pRes);
		}
		break;
	case OP_GET_TIME:
		{
			GetTime(pITP, pRes);
		}
		break;
	case OP_SYS_READ_PARAM:
		{
			ReadParam(pITP, pRes);
		}
		break;
	case OP_SYS_WRITE_PARAM:
		{
			WriteParam(pITP, pRes);
		}
		break;
	case OP_SYS_SAVE_PARAM:
		{
			SaveParam(pITP, pRes);
		}
		break;
	case OP_ADD_USER:
		{
			AddUser(pITP, pRes);
		}
		break;
	case OP_READ_USER:
		{
			ReadUser(pITP, pRes);
		}
		break;
	case OP_LOAD_USER:
		{
			LoadUser(pITP, pRes);
		}
		break;
	case OP_ENROLL_TMP:
		{
			EnrollTmp(pITP, pRes);
		}
		break;
	case OP_READ_TMP:
		{
			ReadTmp(pITP, pRes);
		}
		break;
	case OP_LOAD_TMP:
		{
			LoadTmp(pITP, pRes);
		}
		break;
	case OP_UPDATA:
		{
			Updata(pITP, pRes);
		}
		break;
	case OP_RESET:
		{
			Reset(pITP, pRes);
		}
		break;
	case OP_SCAN_TMP:
		{
			ScanTmp(pITP, pRes);
		}
		break;
	}
	pRes->m_nParam3 = GetTickCount() - begTime;
	if (pITP->m_operation != OP_READ_DATA)
	{
		CDataCenter::GetInstance()->setResponseITP(pITP, pRes);
		m_pListener->onMsgPdu(pRes);
	}
}

void CUSBModule::DealOneResponseMsg( CInterProtocl *pITP )
{
	
}



/************************************************************************/
/*                                                                      */
/************************************************************************/


void CUSBModule::ConnectToModule( CInterProtocl *pReq, CInterProtocl *pRes )
{
	m_connectType = pReq->m_nParam1;
	int iRes = Result_OK;
	if (m_connectType == 0)    //串口
	{
		iRes = connectSerial();
	}
	else
	{
		iRes = connectUSB();
	}

	if (iRes == Result_OK)
	{
		m_ConnectOK = 1;
		m_ModuleState = MS_IDLE;
	}
	pRes->m_Reslut = (OP_Result)iRes;
}

int CUSBModule::SendCommand( int Command,int Param,int Size, char Flag, char* databuf,int datalen )
{
	unsigned int size = 0;
	int ret = 0;
	PRSHeader cmd;
	CString databuffer;
	int checksum = 0;

	if((m_ConnectOK == 0)&&(Command != MD_SYS_STATUS))
	{
		return 0;
	}
	if((Command != MD_SYS_STATUS) && (Command != MD_CANCEL_OP))
	{
		if((m_ModuleState == MS_ENROLL)&&(MD_CONTINUE != Flag))
		{
			return 0;		
		}
		if(m_ModuleState == MS_VERIFY)
		{
			return 0;	
		}
	}
	if((Command == MD_CANCEL_OP)&&(m_ModuleState != MS_IDLE))
	{
		m_ModuleState = MS_IDLE;
	}

	cmd = (PRSHeader)m_ComOutBuf;
	size = sizeof(TRSHeader);//13

	cmd->Command = Command;
	cmd->Param = Param;
	cmd->Size = Size;
	cmd->Flag = Flag;
	cmd->Startcode = 0x70;
	cmd->Endcode = 0x0a;

	if(databuf)
	{
		memcpy(cmd+1, databuf, datalen);
		size+=datalen;

		checksum = MData_chksum((unsigned char*)databuf, datalen);
		*((int*)(m_ComOutBuf+size)) = checksum;

		size += 4;
		cmd->Size = cmd->Size + 4;
	}

	cmd->CheckSum = Header_chksum(m_ComOutBuf);
	if (m_connectType == 0)
	{
		ret = RS_SendDataPack(m_hCom, (char*)cmd, size);
	}
	else
	{
		ret = ZKFPI_Send(m_sensor, (char*)cmd, size);
	}

	int len = size>64?64:size;
	SaveData("send", (char*)cmd, len);

	m_BlockTransport = 1;
	return ret;
}

char* CUSBModule::WaitACKData( int timeout )
{
	char* p = NULL;
	if (m_connectType == 0)
	{
		int count = timeout / 40 + 1;
		for(int i=0; i<count; i++)
		{
			p = SinkDataFromCom();
			if(p)
				break;
			Sleep(40);
		}
	}
	else
	{
		m_SinkDataLen = 0;
		int ret = ZKFPI_Read(m_sensor, m_ComInBuf, 200*1024, timeout);
		//int ret = ZKFPI_Read(m_sensor, m_ComInBuf, sizeof(TRSHeader), timeout);
		if (ret > 0)
		{
			p = m_ComInBuf;                       
			m_SinkDataLen = ret;
		}
	}
	if (m_SinkDataLen > 0)
	{
		int len = m_SinkDataLen>64?64:m_SinkDataLen;
		SaveData("recv", m_ComInBuf, len);
	}
	return p;
}

int CUSBModule::MData_chksum( unsigned char*p, int len )
{
	int i,sum=0;
	for(i=0;i<len;i++)
	{
		sum+=p[i];
	}
	return sum;
}

char CUSBModule::Header_chksum( char *p )
{
	int i,sum=0;
	char checksum=0;
	for(i=0;i<11;i++)
	{
		sum+=p[i];
	}
	checksum=(sum%256);
	return checksum;
}

int CUSBModule::RS_SendDataPack( HANDLE hCom, char *buf, int size )
{
	int ret=0;
	if(m_Options.AscII==0x31)
	{
		char* SendBuf=new char[size*2];
		ChangeDataToASCII(buf,size, SendBuf,1);
		WriteCommBlock(hCom,SendBuf,size*2);
		delete SendBuf;
	}
	else
	{
		WriteCommBlock(hCom,buf,size);
	}
	return 1;
}

void CUSBModule::ChangeDataToASCII( char*Sbuf,int Size, char*Destbuf,int Flag )
{
	int i,cnt;
	char tmp,c ;
	if(Destbuf == NULL)
	{
		return;
	}
	
	if(Flag)   //change data to ASCII 
	{
		cnt=0;
		for(i=0;i<Size;i++)
		{
			tmp=Sbuf[i];
			if((tmp&0xf )>9)
				Destbuf[cnt+1]=0x37+(tmp&0xf);
			else
				Destbuf[cnt+1]=0x30+(tmp&0xf);

			tmp>>=4;
			if((tmp&0xf) >9)
				Destbuf[cnt]=0x37+(tmp&0xf);
			else
				Destbuf[cnt]=0x30+(tmp&0xf);			
			cnt+=2;
		}
	}
	else  // change ASCII to data
	{
		cnt=0;
		if(Size%2)
		{
			Size/=2;
			Size++;
		}
		else
			Size/=2;
		for(i=0;i<Size;i++)
		{
			if(Sbuf[cnt]>='A')
				tmp=Sbuf[cnt]-0x37;
			else
				tmp=Sbuf[cnt]-0x30;
			tmp<<=4;
			tmp&=0xf0;
			cnt++;

			if(Sbuf[cnt]>='A')
				c=Sbuf[cnt]-0x37;
			else
				c=Sbuf[cnt]-0x30;
			c&=0x0f;
			Destbuf[i]= (tmp|c);
			cnt++;
		}
	}
}

BOOL CUSBModule::WriteCommBlock( HANDLE hCom, char *buf, unsigned int size )
{
	BOOL fWriteStat ;
	DWORD dwBytesWritten ;
	DWORD dwErrorFlags;
	DWORD dwError;
	DWORD dwBytesSent = 0;
	COMSTAT ComStat;
	CString databuffer;
	fWriteStat = WriteFile( hCom, buf, size, &dwBytesWritten, &m_Write_OS );

	if (!fWriteStat)
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			while(!GetOverlappedResult( hCom, &m_Write_OS, &dwBytesWritten, TRUE ))
			{
				dwError = GetLastError();
				if(dwError == ERROR_IO_INCOMPLETE)
				{
					dwBytesSent += dwBytesWritten;
					continue;
				}
				else
				{
					ClearCommError(hCom, &dwErrorFlags, &ComStat );
					break;
				}
			}
			dwBytesSent += dwBytesWritten;
		}
		else
		{
			ClearCommError( hCom, &dwErrorFlags, &ComStat );
			return ( FALSE );
		}
	}
	return TRUE;
}

char* CUSBModule::SinkDataFromCom( void )
{
	if(m_hCom == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}
	
	PRSHeader pch;
	int ret = 1;
	unsigned int sum = 0;
	int tmplen = 0;
	char buffer[5000] = {0};
	char *p;
	int sinkcount = 1;
	int j = 0,i = 0;
	char* SinkBuf = NULL;

	memset(buffer, 0, sizeof(buffer));
	memset(m_ComInBuf, 0, sizeof(m_ComInBuf));
	tmplen = ReadCommBlock(m_hCom, buffer, 5000);
	if(tmplen <= 0)
		return NULL;

	// buffer
	pch = (PRSHeader)m_ComInBuf;


	if(m_Options.AscII == 0x31)
	{
		SinkBuf = new char[5000*2];
		p = SinkBuf;
	}
	else
	{
		p = m_ComInBuf;
	}

	m_Readlen = tmplen;
	memcpy(p, &buffer, tmplen);
	p += tmplen;

	if(m_BlockTransport)
	{
		sinkcount = 2;
	}
		
	while(1)
	{
		j = 0;
		while(1)
		{
			Sleep(10);
			tmplen=ReadCommBlock(m_hCom, buffer, 5000); // 从串口读数据
			break;
		}

		if(tmplen > 0)
		{
			m_Readlen += tmplen;
			if(m_Readlen <= 5000)
			{
				memcpy(p, &buffer, tmplen);
				p += tmplen;
			}
			continue;
		}
		else
			break;
	}

	m_BlockTransport = 0;

	if(m_Options.AscII == 0x31)
	{
		ChangeDataToASCII(SinkBuf, m_Readlen, m_ComInBuf,0);
		m_Readlen /= 2;
		delete SinkBuf;
	}


	for(i=0; i<13; i++) {
		_RPT1(_CRT_WARN,"0x%02x ", m_ComInBuf[i]);
	}
	_RPT0(_CRT_WARN, "\r\n");

	// Error
	if((m_Readlen < HEADER_NUM)|| (m_ComInBuf[0] != 0x70)||(m_ComInBuf[12] != 0x0A))
	{
		return NULL;
	}

	if(pch->CheckSum == Header_chksum(m_ComInBuf))
	{
		if(pch->Command == 0)
		{
			if(m_Readlen > HEADER_NUM)
			{
				pch = (PRSHeader)(m_ComInBuf+HEADER_NUM);
				m_Readlen -= HEADER_NUM;
			}
			else
			{
				return NULL; //(char*)pch;
			}
		}
		m_SinkDataLen = m_Readlen;
		return (char*)pch;
	}
	else
	{
		return NULL;
	}	
}

int CUSBModule::ReadCommBlock( HANDLE hCom, char *buf, unsigned int size )
{
	BOOL fReadStat ;
	COMSTAT ComStat;
	DWORD dwErrorFlags, tmplen = 0;
	DWORD dwLength;
	DWORD dwError;
	CString databuffer;

	ClearCommError( hCom, &dwErrorFlags, &ComStat ) ;
	dwLength = min( (DWORD) size, ComStat.cbInQue ) ;
	if (dwLength > 0)
	{
		fReadStat = ReadFile( hCom, buf,dwLength, &dwLength, &m_READ_OS ) ;
		if (!fReadStat)
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				while(!GetOverlappedResult( hCom ,&m_READ_OS, &dwLength, TRUE ))
				{
					dwError = GetLastError();
					if(dwError == ERROR_IO_INCOMPLETE)
						continue;// normal result if not finished
					else
					{
						//Resultdata += databuffer;
						ClearCommError( hCom , &dwErrorFlags, &ComStat ) ;
						break;
					}
				}
			}
			else
			{
				dwLength = 0 ;
				ClearCommError( hCom , &dwErrorFlags, &ComStat ) ;
			}
		}
	}
	return dwLength;
}

void CUSBModule::CloseCOM()
{
	if(m_hCom != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hCom);
		m_hCom = INVALID_HANDLE_VALUE;
	}
}	

void CUSBModule::DisConnectToModule( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	if (SendCommand(MD_DISCONNECT, 0, 0, 0, 0, 0) != 0)
	{
		if ((buf = WaitACKData(2000)) == NULL)
		{
			SaveData("DisConnectToModule:recv nothing");
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader header = (PRSHeader)buf;
		if (header->Flag != MD_SUCCESS)
		{
			CString str;
			str.Format("DisConnectToModule: recv flag=%d", header->Flag);
			SaveData(str.GetBuffer());
			pRes->m_Reslut = Result_Error;
			return;
		}
	}

	if (m_connectType == 0)
	{
		CloseCOM();
	}
	else
	{
		ZKFPI_Close(m_sensor);
		m_sensor = NULL;
	}
	m_ConnectOK = 0;
}

void CUSBModule::Enroll( CInterProtocl *pReq, CInterProtocl *pRes )
{
	int pin = pReq->m_nParam1;
	int flag = pReq->m_nParam2;
	if (SendCommand(MD_ENROLL_SCAN, pin, 0, flag, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		SaveData("Enroll:send fail");
	}
	else
	{
		m_ModuleState = MS_ENROLL;
	}
	pRes->m_nParam1 = pin;
}

void CUSBModule::StartReadData()
{
	m_StartRead = 1;
	CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
	pITP->m_eventType = EVENT_REQUEST;
	pITP->m_srcModule = USB_MODULE;
	pITP->m_desModule = USB_MODULE;
	pITP->m_operation = OP_READ_DATA;
	pushMsg(pITP);
}

void CUSBModule::ReadData( CInterProtocl *pReq, CInterProtocl *pRes )
{
	static int iCount = 0;
	//if (iCount == 0)
	{
		char* buf = NULL;
		buf = WaitACKData(100);
		if (buf)
		{
			AnalysisBuffer(buf);
		}
		iCount = 0;
	}
	//iCount++;
	CDataCenter::GetInstance()->setResponseITP(pReq, pRes);
	pRes->m_eventType = EVENT_REQUEST;
	if (m_StartRead == 1)
	{
		m_pListener->onMsgPdu(pRes);
	}
}

//void CUSBModule::StopReadData( CInterProtocl *pReq, CInterProtocl *pRes )
//{
//	m_StartRead = 0;
//	CDataCenter::GetInstance()->setResponseITP(pReq, pRes);
//	m_pListener->onMsgPdu(pRes);
//}

void CUSBModule::StopReadData()
{
	m_StartRead = 0;
}

void CUSBModule::AnalysisBuffer( char *buf )
{
	PRSHeader chdr=(PRSHeader)buf;
	if (chdr->Flag == MD_SUCCESS)
	{
		DealSuccessFlag(chdr);
	}
	else
	{
		DealFailureFlag(chdr);
	}
}

void CUSBModule::DealSuccessFlag( PRSHeader header )
{
	int command = header->Command & 0xff;
	switch (command)
	{
	case MD_ENROLL_SCAN:
		{
			m_ModuleState = MS_IDLE;
			CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
			pITP->m_eventType = EVENT_NOTICE;
			pITP->m_srcModule = USB_MODULE;
			pITP->m_desModule = USER_MODULE;
			pITP->m_operation = OP_ENROLL_SUCCESS;
			m_pListener->onMsgPdu(pITP);
		}
		break;
	case MD_IDENTIFY_FREE:
		{
			CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
			pITP->m_eventType = EVENT_NOTICE;
			pITP->m_srcModule = USB_MODULE;
			pITP->m_desModule = USER_MODULE;
			pITP->m_operation = NOTICE_IDENTIFY;
			pITP->m_nParam1 = header->Param;
			m_pListener->onMsgPdu(pITP);
		}
		break;
	case MD_READ_USER:
		{
			CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
			pITP->m_eventType = EVENT_NOTICE;
			pITP->m_srcModule = USB_MODULE;
			pITP->m_desModule = USER_MODULE;
			pITP->m_operation = OP_READ_USER;

			PUser user=(PUser)(header+1);

			pITP->PushData((char*)user, sizeof(TUser));
			m_pListener->onMsgPdu(pITP);
		}
		break;
	}
}

void CUSBModule::DealFailureFlag( PRSHeader header )
{
	int command = header->Command & 0xff;
	switch (command)
	{
	case MD_ENROLL_SCAN:
		{
			m_ModuleState = MS_IDLE;
			CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
			pITP->m_eventType = EVENT_NOTICE;
			pITP->m_srcModule = USB_MODULE;
			pITP->m_desModule = USER_MODULE;
			pITP->m_operation = OP_ENROLLING;
			m_pListener->onMsgPdu(pITP);
		}
		break;
	case MD_IDENTIFY_FREE:
		{
			CInterProtocl *pITP = CDataCenter::GetInstance()->GetITP();
			pITP->m_eventType = EVENT_NOTICE;
			pITP->m_srcModule = USB_MODULE;
			pITP->m_desModule = USER_MODULE;
			pITP->m_operation = NOTICE_IDENTIFY;
			pITP->m_nParam1 = 0;
			m_pListener->onMsgPdu(pITP);
		}
		break;
	}
}

BOOL CUSBModule::connectSerial()
{
	CString databuffer;
	int erreur = 0;
	DCB  dcb;
	static int ComNumTemp = 0;
	static int baudrate = 0;

	if (m_hCom != INVALID_HANDLE_VALUE && ComNumTemp==m_ComNum && baudrate==m_ComBaudRate)
	{
		return Result_hasOpened;
	}
	CloseHandle(m_hCom);
	COMMTIMEOUTS cto = { 0, 4100, 10, 10, 2000 };
	memset(&dcb, 0, sizeof(dcb));

	// set DCB to configure the serial port
	dcb.DCBlength       = sizeof(dcb);                   
	dcb.BaudRate		= m_ComBaudRate;

	dcb.Parity			= NOPARITY;
	dcb.fParity			= 0;
	dcb.StopBits        = ONESTOPBIT;
	dcb.ByteSize        = 8;
	dcb.fOutxCtsFlow    = 0;
	dcb.fOutxDsrFlow    = 0;
	dcb.fDtrControl     = DTR_CONTROL_DISABLE;
	dcb.fDsrSensitivity = 0;
	dcb.fRtsControl     = RTS_CONTROL_DISABLE;
	dcb.fOutX           = 0;
	dcb.fInX            = 0;

	/* ----------------- misc parameters ----- */
	dcb.fErrorChar      = 0;
	dcb.fBinary         = 1;
	dcb.fNull           = 0;
	dcb.fAbortOnError   = 0;
	//    dcb.wReserved       = 0;
	dcb.XonLim          = 2;
	dcb.XoffLim         = 4;
	dcb.XonChar         = 0x13;
	dcb.XoffChar        = 0x19;
	dcb.EvtChar         = 0;

	databuffer.Format(_T("COM%d"), m_ComNum);

	m_hCom = CreateFile(databuffer, GENERIC_READ | GENERIC_WRITE,
		0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);

	SetCommMask(m_hCom, EV_RXCHAR|EV_TXEMPTY);//设置事件驱动的类型   
	SetupComm(m_hCom, 5000, 5000);   //设置输入、输出缓冲区的大小   
	PurgeComm(m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);   //清干净输入、输出缓冲区  

	if (m_hCom != INVALID_HANDLE_VALUE)
	{
		if(!SetCommMask(m_hCom, 0))
		{
			erreur = 1;
		}
		if(!SetCommTimeouts(m_hCom, &cto)) // set timeouts
		{
			erreur = 2;
		}
		if(!SetCommState(m_hCom, &dcb))	//set DCB 串口参数配置 
		{
			erreur = 4;
		}
	}
	else
	{	
		erreur = 8;
	}

	if (erreur != 0)
	{
		CloseHandle(m_hCom);
		m_hCom = INVALID_HANDLE_VALUE;
		return Result_Error;
	}
	else
	{
		ComNumTemp = m_ComNum;
		baudrate = m_ComBaudRate;
	}

	if (SendCommand(MD_SYS_STATUS, 0, 0, 0, NULL, 0) == 0)
	{
		m_hCom = INVALID_HANDLE_VALUE;
		return Result_Error;
	}
	char *buf = WaitACKData(1000);
	if (buf == NULL)
	{
		m_hCom = INVALID_HANDLE_VALUE;
		return Result_Error;
	}
	return Result_OK;
}

int CUSBModule::connectUSB()
{
	int ret = 0;
	char *buf = NULL;
	//ret = ZKFPI_Init(0x1B55, 0x0824);
	ret = ZKFPI_Init(0x1B55, 0x0121);
	if (ret == 0)
	{
		SaveData("ZKFPI_Init Fail!");
		return Result_Error;
	}
	ret = ZKFPI_Open(0, &m_sensor);
	if (ret != 0)
	{
		SaveData("ZKFPI_Open Fail!");
		return Result_hasOpened;
	}
	buf = WaitACKData(100);
	if (SendCommand(MD_SYS_STATUS, 0, 0, 0, NULL, 0) == 0)
	{
		SaveData("connectUSB:send MD_SYS_STATUS fail");
		return Result_SendFail;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		SaveData("connectUSB:recv nothing");
		return Result_NoReply;
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		CString str;
		str.Format("connectUSB:recv flag=%d", header->Flag);
		SaveData(str.GetBuffer());
		return Result_NoSuccess;
	}
	return Result_OK;
}

void CUSBModule::ScanFpImage( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if (SendCommand(MD_SCAN_IMAGE_X, 0, 0, 0, NULL, 0) == 0)
	{
		SaveData("ScanFpImage:send fail");
		pRes->m_Reslut = Result_SendFail;
		return;
	}
	int tmp = sizeof(TExtHeader);
	PExtHeader chdr = NULL;
	TImage image;
	int width =0, heigh = 0;
	char* p=(char*)&image;
	char* buf = m_ComOutBuf;
	buf = WaitACKData(10000);
	if (buf == NULL)
	{
		SaveData("ScanFpImage:recv nothing");
		pRes->m_Reslut = Result_NoReply;
		return;
	}
	PRSHeader pch;
	pch = (PRSHeader)buf;

	if(pch->Command == 0)
	{
		if(m_SinkDataLen > tmp)
		{
			buf += tmp;
			pch = (PRSHeader)buf;
		}
		else
		{
			buf = WaitACKData(10000);
			if(buf == NULL)
			{
				SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
				WaitACKData(40);
				pRes->m_Reslut = Result_Error;
				return;
			}
		}
		pch = (PRSHeader)buf;
	}

	if(pch->Flag != MD_SUCCESS)
	{
		SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
		WaitACKData(40);
		pRes->m_Reslut = Result_NoSuccess;
		
		CString str;
		str.Format("ScanFpImage:recv flag=%d", pch->Flag);
		SaveData(str.GetBuffer());
		return;
	}

	if(m_SinkDataLen > tmp)
	{
		chdr = (PExtHeader)(buf+tmp);
		buf+=tmp;
	}
	else
	{
		buf = WaitACKData(10000);
		if(buf==NULL)
		{
			SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
			WaitACKData(400);
			pRes->m_Reslut = Result_Error;
			SaveData("ScanFpImage:wait first packet nothing");
			return;
		}
		chdr = (PExtHeader)buf;
	}
	int count = chdr->PacketNum;
	if (chdr->Flag == MD_DATA_ERROR)
	{
		pRes->m_Reslut = Result_DataError;
		SaveData("ScanFpImage:recv first pack exheader flag = MD_DATA_ERROR");
		return;
	}
	if (count == 0)
	{
		pRes->m_Reslut = Result_PackNumError;
		SaveData("ScanFpImage:recv first pack exheader count = 0");
		return;
	}
	int i = 0;
	for(i=chdr->Index; i<count; i++)
	{
		int dataSize = chdr->Size - 4;
		int size = tmp + dataSize;
		int sum =* ((int*)(buf+size));
		if(sum != MData_chksum((unsigned char*)(chdr+1),dataSize))
		{
			pRes->m_Reslut = Result_CheckSum;
			SaveData("ScanFpImage:checkSum error");
			return;
		}
		memcpy(p, chdr+1, dataSize);
		p += dataSize;
		if (width == 0)
		{
			width = image.width;
			heigh = image.heigth;
		}
		chdr->Flag = MD_DATA_OK;
		chdr->Size = 0;//dsl
		// 发送数据
		chdr->CheckSum = Header_chksum(buf);
		if (m_connectType == 0)
		{
			RS_SendDataPack(m_hCom, (char*)chdr, tmp);
		}
		else
		{
			ZKFPI_Send(m_sensor, (char*)chdr, tmp);
		}
		
		
		if(chdr->PacketNum == chdr->Index+1)
		{
			break;
		}
			
		buf = WaitACKData(30000);
		if(buf==NULL)
		{
			SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
			WaitACKData(400);
			pRes->m_Reslut = Result_Error;
			pRes->m_nParam1 = 8;
			return;
		}
		else
		{
			chdr = (PExtHeader)buf;
			int d = 0;
			int flag = chdr->Flag & 0xFF;
			if (flag == MD_DATA_ERROR)
			{
				pRes->m_Reslut = Result_Error;
				pRes->m_nParam1 = 9;
				return;
			}
			if (chdr->PacketNum == 0)
			{
				pRes->m_Reslut = Result_Error;
				pRes->m_nParam1 = 10;
				return;
			}
		}
	}
	if (image.img_len > 0)
	{
		pRes->PushData(image.ImageBuf, image.img_len);
		pRes->m_nParam1 = image.width;
		pRes->m_nParam2 = image.heigth;
	}
	else
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::GetTime( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	if (SendCommand(MD_GET_TIME, 0, 0, 0, 0, 0) == 0)
	{
		pRes->m_Reslut = Result_SendFail;
		return;
	}
	if ((buf = WaitACKData(6000)) == NULL)
	{
		pRes->m_Reslut = Result_NoReply;
		return;
	}
	if (m_SinkDataLen < 21)
	{
		if ((buf = WaitACKData(6000)) == NULL)
		{
			pRes->m_Reslut = Result_NoReply;
			return;
		}
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_NoSuccess;
	}
	pRes->m_nParam1 = header->Param;
	pRes->m_nParam2 = *(int *)(header+1);

	//if(SendCommand(MD_GET_TIME, 0, 0, 0, 0, 0))
	//{
	//	char *buf = WaitACKData(6000); //wait 20s
	//	if(buf)
	//	{
	//		if (m_SinkDataLen < 21)
	//		{
	//			buf = WaitACKData(1000);
	//			if (buf == NULL)
	//			{
	//				pRes->m_Reslut = Result_Error;
	//				return;
	//			}
	//		}
	//		PRSHeader header = (PRSHeader)buf;
	//		if (header->Flag != MD_SUCCESS)
	//		{
	//			pRes->m_Reslut = Result_NoSuccess;
	//		}
	//		pRes->m_nParam1 = header->Param;
	//		pRes->m_nParam2 = *(int *)(header+1);
	//	}
	//	else
	//	{
	//		pRes->m_Reslut = Result_Error;
	//	}
	//}
}

void CUSBModule::SetTime( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	int date = pReq->m_nParam1;
	int time = pReq->m_nParam2;
	if (SendCommand(MD_SET_TIME, date, 4, 0, (char*)&time, 4) == 0)
	{
		pRes->m_Reslut = Result_Error;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::ReadParam( CInterProtocl *pReq, CInterProtocl *pRes )
{
	PRSHeader header;
	DevParam param;
	char *buf = NULL;
	if (SendCommand(MD_SYS_RP, 0, 0, SID_SAVE_LOG, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.saveLog = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_TIMEOUT, NULL, 0) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.timeOut = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_AUTO_ACK, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.autoACK = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_FW_VER, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.fwVer = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_BAUDRATE, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.baudrate = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_ENROLL_FP, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(4000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.enrollFp = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_FP_COUNT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.fpCount = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_USER_COUNT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.userCount = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_LOG_NUM, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.logNum = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_LOG_COUNT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.logCount = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_BUILD_NUM, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.buildTime = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_MODULE_ID, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.moduleID = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_WORKMODE, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.workMode = header->Param;

	if (SendCommand(MD_SYS_RP, 0, 0, SID_TEMPLATEFMT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
	param.tmpFormat = header->Param;
	pRes->PushData((char*)&param, sizeof(DevParam));
}

void CUSBModule::WriteParam( CInterProtocl *pReq, CInterProtocl *pRes )
{
	SetParam dataParam;
	memcpy(&dataParam, pReq->m_data, pReq->m_len);
	PRSHeader header;
	char *buf = NULL;
	//int param = 0;

	int gpio = 0;
	gpio = dataParam.iLampTime + (dataParam.iLampColor << 8);
	if (SendCommand(MD_SYS_WP, gpio, 0, SID_GPIO_LEVEL, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}

	//param = 0x30;
	if (SendCommand(MD_SYS_WP, dataParam.iSaveLog, 0, SID_SAVE_LOG, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}

	//param = 0x31;
	if (SendCommand(MD_SYS_WP, dataParam.iAutoAck, 0, SID_AUTO_ACK, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}

	//param = 79;
	if (SendCommand(MD_SYS_WP, dataParam.iTimeout, 0, SID_TIMEOUT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}

	if (SendCommand(MD_SYS_WP, dataParam.iWorkMode, 0, SID_WORKMODE, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}

	if (SendCommand(MD_SYS_WP, dataParam.iTmpFormat, 0, SID_TEMPLATEFMT, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::SaveParam( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	if (SendCommand(MD_SYS_SP, 0, 0, 0, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(5000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::AddUser( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	TUser user;
	memcpy(&user, pReq->m_data, pReq->m_len);
	pRes->m_nParam1 = user.PIN;
	pRes->PushData(user.Name, 8);
	if (SendCommand(MD_ADD_USER, 0, pReq->m_len, 0, pReq->m_data, pReq->m_len) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(6000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::ReadUser( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf  = NULL;
	int pin = pReq->m_nParam1;
	if (SendCommand(MD_READ_USER, pin, 0, 0, 0, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(6000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
	}

	PRSHeader chdr = (PRSHeader)buf;
	int command = chdr->Command & 0xFF;
	int flag = chdr->Flag & 0xFF;
	if (flag == MD_SUCCESS)
	{
		pRes->PushData(buf+sizeof(TRSHeader), sizeof(TUser));
		pRes->m_nParam1 = sizeof(TUser);
	}
	else if (flag == MD_NOT_FIND)
	{
		pRes->m_Reslut = Result_NoFind;
	}
	else 
	{
		pRes->m_Reslut = Result_NoSuccess;
	}
	
}

void CUSBModule::LoadUser( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if (SendCommand(MD_LOAD_USER_X, 4096, 0, 0, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_SendFail;
		return;
	}
	int size = 0;
	int param = 0;
	char *buf = SinkExtData(size, param, 1, 1);
	if (buf)
	{
		pRes->PushData(buf, size);
	}
	else
	{
		pRes->m_Reslut = Result_NoReply;
	}
	delete []buf;
}	

char* CUSBModule::SinkExtData( int& SinkLen,int& Param ,int flag,int type )
{
	char* SinkBuffer = NULL;
	char* p;
	char* buf = NULL;
	PRSHeader pch;

	int size = 0,count = 0,sum, ret = 0;
	int i = 0, dataSize = 0;

	int tmp = sizeof(TExtHeader);
	PExtHeader chdr = (PExtHeader)buf;

	SinkLen = 0;
	i = 0;
	while(i++ < 20)  //4min
	{
		buf=WaitACKData(1000); //2s
		if(buf)
		{
			break;
		}
	} 

	if(buf == NULL)
	{
		SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
		WaitACKData(40);
		return 0;
	}
	else
	{
		pch = (PRSHeader)buf;
		if(pch->Flag != MD_SUCCESS)
		{
			SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
			WaitACKData(40);
			return 0;
		}
		else 
		{
			SinkLen = pch->Param;
			if(Param == MD_READ_TMP_X)
			{
				Param = SinkLen;
				Param >>= 16;
				Param &= 0xf;
				SinkLen &= 0xffff;
				SinkLen *= Param;
			}
			if(SinkLen == 0)
			{
				SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
				WaitACKData(40);
				return NULL;
			}
		}
	}

	if(m_SinkDataLen > tmp)
	{
		buf += tmp;
	}
	else
	{
		buf = WaitACKData(10000);
		if(buf == NULL)
		{
			SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
			WaitACKData(40);
			return 0;
		}
	}

	SinkBuffer = new char[SinkLen];
	p = SinkBuffer;
	chdr = (PExtHeader)buf;
	count = chdr->PacketNum;

	for(i=chdr->Index; i<count; i++)
	{
		chdr = (PExtHeader)buf;
		dataSize = chdr->Size - 4;
		size = tmp + dataSize;
		sum =* ((int*)(buf+size));
		if(sum != MData_chksum((unsigned char*)(chdr+1),dataSize))
		{
			chdr->Flag=MD_DATA_ERROR;
			// 发送数据
			chdr->CheckSum=Header_chksum(buf);
			//RS_SendDataPack(hCom,(char*)chdr,tmp);
			if (m_connectType == 0)
			{
				RS_SendDataPack(m_hCom, (char*)chdr, tmp);
			}
			else
			{
				ZKFPI_Send(m_sensor, (char*)chdr, tmp);
			}
			break;
		}
		else
		{
			memcpy(p,chdr+1,dataSize);
			p+=dataSize;

			chdr->Flag=MD_DATA_OK;
			// 发送数据
			chdr->Size = 0;
			chdr->CheckSum=Header_chksum(buf);
			//RS_SendDataPack(hCom,(char*)chdr,tmp);
			if (m_connectType == 0)
			{
				RS_SendDataPack(m_hCom, (char*)chdr, tmp);
			}
			else
			{
				ZKFPI_Send(m_sensor, (char*)chdr, tmp);
			}

			if(chdr->PacketNum == chdr->Index+1)
			{
				ret=1;
				break;
			}

			buf=WaitACKData(500);
			if(buf==NULL)
			{
				SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
				WaitACKData(40);
				break;
			}
		}
	}

	return SinkBuffer;
}

void CUSBModule::EnrollTmp( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = m_ComInBuf;
	PRSHeader chdr = (PRSHeader)buf;
	int pin = pReq->m_nParam1;
	if ((SendCommand(MD_ENROLL_TMP, pin, pReq->m_len, 0x71, pReq->m_data, pReq->m_len)) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}

	if ((buf = WaitACKData(10000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	chdr = (PRSHeader)buf;
	if(chdr->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
		pRes->m_nParam2 = chdr->Flag;
	}
	pRes->m_nParam1 = pin;
}

void CUSBModule::ReadTmp( CInterProtocl *pReq, CInterProtocl *pRes )
{
	int pin = pReq->m_nParam1;
	if ((SendCommand(MD_READ_TMP_X, pin, 0, 0, 0, 0)) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	int Param = MD_READ_TMP_X;
	int size = 0;
	char *buf = SinkExtData(size, Param, 0, 0);
	if (buf)
	{
		pRes->PushData(buf, size);
	}
	else
	{
		pRes->m_Reslut = Result_Error;
	}
	delete []buf;
	
}

void CUSBModule::LoadTmp( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if ((SendCommand(MD_LOAD_TMP_X, 4096, 0, 0, NULL, 0)) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	int Param = 0;
	int tmpsize = 0;
	char *buftemp=SinkExtData(tmpsize, Param, 0, 1);
	if (buftemp)
	{
		pRes->PushData(buftemp, tmpsize);
	}
	else
	{
		pRes->m_Reslut = Result_Error;
	}
	delete []buftemp;
}

void CUSBModule::DelLog( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if(SendCommand(MD_DEL_ALOG, 0, 0, 0, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	char *buf = WaitACKData(6000); //wait 2s
	if(buf)
	{
		PRSHeader chdr = (PRSHeader)buf;
		if (chdr->Flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}
	else
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::Verify( CInterProtocl *pReq, CInterProtocl *pRes )
{
	int pin = pReq->m_nParam1;
	if (pin == 0)	//指纹照片识别
	{
		if ((SendCommand(MD_IDENTIFY_IMAGE_X, pReq->m_len, 0, 0, NULL, 0)) == 0)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		char *buf = NULL;
		if ((buf = WaitACKData(2000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader chdr = (PRSHeader)buf;
		if (chdr->Flag == MD_SUCCESS)
		{
			if (SendExtData(pReq->m_data, pReq->m_len, MD_IDENTIFY_IMAGE_X) != 1)
			{
				pRes->m_Reslut = Result_Error;
				return;
			}
		}
		else
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
	}
	else
	{
		if(SendCommand(MD_VERIFY_SCAN, pin, 0, 0, NULL, 0) == 0)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		char *buf = NULL;
		if ((buf = WaitACKData(2000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader chdr = (PRSHeader)buf;
		if (chdr->Flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}		
}

void CUSBModule::LoadLog( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if (SendCommand(MD_LOAD_LOG_X, 4096, 0, 0, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	int SinkLen = 0;
	int Param = 0;
	char *buf = SinkExtData(SinkLen, Param, 0, 0);
	if(buf)
	{
		pRes->PushData(buf, SinkLen);
	}
	else
	{
		pRes->m_Reslut = Result_Error;
	}
	delete []buf;
}

int CUSBModule::SendExtData( char* SendBuffer, int SendLen,int Command )
{
	int size = 0, count = 0, sum;
	int i, idx = 0;
	int ret = 0;
	char* buf = m_ComOutBuf;
	char* p = SendBuffer;
	int tmp = sizeof(TExtHeader);
	PExtHeader chdr = (PExtHeader)buf;

	count = SendLen/EXTDATA_LEN;
	if(SendLen%EXTDATA_LEN)
	{
		count += 1;
	}
		
	for(i=0; i<count;i++)
	{
		if(SendLen <= EXTDATA_LEN)
		{
			size = SendLen;
		}	
		else
		{
			size = EXTDATA_LEN;
		}
			
		SendLen -= size;

		chdr->Startcode = 0x70;
		chdr->Command = Command;
		chdr->EndCode = 0x0A;
		chdr->Flag = 0;
		chdr->Index = count;
		chdr->PacketNum = i;
		chdr->Size = size+4;//body size+checksum

		memcpy(chdr+1, p, size);
		p += size;

		sum = MData_chksum((unsigned char*)(chdr+1),size);
		size += tmp;
		*((int*)(buf+size)) = sum;
		size += 4;

		// 发送数据
		chdr->CheckSum = Header_chksum(buf);
		//RS_SendDataPack(m_hCom, (char*)chdr, size);
		if (m_connectType == 0)
		{
			RS_SendDataPack(m_hCom, (char*)chdr, size);
		}
		else
		{
			//ZKFPI_Write(m_sensor, (char*)chdr, size, 30000);
			ZKFPI_Send(m_sensor, (char*)chdr, size);
		}
		buf = WaitACKData(10000);

		if(buf == NULL)
		{
			break;
		}
		else
		{
			chdr = (PExtHeader)buf;
			sum = chdr->Flag;
			sum &= 0xff;
			if(MD_DATA_OK == sum)
			{
				//_RPT1(_CRT_WARN,"anser packetnum=%d\r\n", chdr->PacketNum+1);
				if((count == i+1)&&(0 == SendLen))
				{
					ret = 1;
					break;
				}
				continue;
			}
			else
			{
				break;
			}
		}
	}

	if (ret == 0)
	{
		SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
		WaitACKData(400);
	}
	else
	{
		PRSHeader pch=NULL;
		if(m_SinkDataLen >= 2*tmp)		
		{
			pch = (PRSHeader)(buf+tmp);
			buf += tmp;
		}
		else if(Command != MD_VERIFY_TMP_H_X)
		{
			buf = WaitACKData(30000);
			if(buf)
				pch=(PRSHeader)(buf);
		}

		if(pch)
		{
			//	pch=(PRSHeader)buf;
			if(pch->Flag == MD_SUCCESS)
			{
				//TopRunCommand(buf);
				return 1;
			}
			else
			{
				//TopRunErrorCommand(buf);
				return -1;
			}
			return 1;
		}
		else
			return 2;
	}
	return 0;
}

void CUSBModule::EnrollImage( CInterProtocl *pReq, CInterProtocl *pRes )
{
	int pin = pReq->m_nParam1;
	char buff[8] = {0};
	memcpy(buff, &pReq->m_len, 4);
	if (SendCommand(MD_ENROLL_IMAGE_X, pin, 4, 0x71, buff, 4) == 0)
	{
		SaveData("EnrollImage:send fail");
		pRes->m_Reslut = Result_Error;
		return;
	}
	char *buf = NULL;
	if ((buf = WaitACKData(10000)) == NULL)
	{
		SaveData("EnrollImage:recv nothing");
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader chdr=(PRSHeader)buf;
	int flag = (unsigned char)chdr->Flag;
	if (flag == MD_SUCCESS || flag == MD_DATA_OK)
	{
		if (SendExtData(pReq->m_data, pReq->m_len, MD_ENROLL_IMAGE_X) != 1)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
	}
	else
	{
		CString str;
		str.Format("EnrollImage:recv flag=%d", flag);
		SaveData(str.GetBuffer());
		pRes->m_Reslut = Result_Error;
	}
	pRes->m_nParam1 = pin;
}

void CUSBModule::DelTmp( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	int pin = pReq->m_nParam1;
	if (pin == 0)
	{
		if (SendCommand(MD_DEL_ALL_TMP, 0, 0, 0, 0, 0) == 0)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		if ((buf = WaitACKData(20000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader header = (PRSHeader)buf;
		if (header->Flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}
	else
	{
		pRes->m_nParam1 = pin;
		if (SendCommand(MD_DEL_TMP, pin, 0, DELETE_ONLY_ONE, 0, 0) == 0)
		{
			pRes->m_Reslut = Result_Error;
		}
		if ((buf = WaitACKData(20000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
		    	return;
		}
		PRSHeader header = (PRSHeader)buf;
		if (header->Flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}
}

void CUSBModule::DelDB( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	if (SendCommand(MD_DEL_DB, 0, 0, 0, 0, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(20000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}

void CUSBModule::DelUser( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *buf = NULL;
	int pin = pReq->m_nParam1;
	pRes->m_nParam1 = pin;
	if (pin == 0)
	{
		if (SendCommand(MD_DEL_ALL_USER, 0, 0, 0, 0, 0) == 0)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		if ((buf = WaitACKData(6000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader header = (PRSHeader)buf;
		if (header->Flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}
	else
	{
		if (SendCommand(MD_DELETE_USER, pin, 0, 0, 0, 0) == 0)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		if ((buf = WaitACKData(2000)) == NULL)
		{
			pRes->m_Reslut = Result_Error;
			return;
		}
		PRSHeader chdr = (PRSHeader)buf;
		int flag = chdr->Flag & 0xFF;
		int command = chdr->Command & 0xFF;
		if (flag != MD_SUCCESS)
		{
			pRes->m_Reslut = Result_Error;
		}
	}
}

void CUSBModule::Updata( CInterProtocl *pReq, CInterProtocl *pRes )
{
	char *data = NULL;
	int len = 0;
	if (pReq->m_lenEx != 0)
	{
		data = pReq->m_dataEx;
		len = pReq->m_lenEx;
	}
	else
	{
		data = pReq->m_data;
		len = pReq->m_len;
	}
	//第一个文件
	if (SendCommand(MD_UPDATA, len, 0, 0, 0, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	char *buf = WaitACKData(1000);
	if (buf == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader chdr = (PRSHeader)buf;
	int flag = chdr->Flag & 0xFF;

	if (flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if (SendExtData(data, len, MD_UPDATA) != 1)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
}

void CUSBModule::ScanTmp( CInterProtocl *pReq, CInterProtocl *pRes )
{
	if (SendCommand(MD_SCAN_TEMPLATE, pReq->m_len, 0, 0, 0, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	char *buf = WaitACKData(10000);
	if (buf == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	PRSHeader chdr = (PRSHeader)buf;
	int headerLen = sizeof(TRSHeader);
	int flag = chdr->Flag & 0xFF;

	if (flag != MD_SUCCESS)
	{
		SendCommand(MD_CANCEL_OP, 0, 0, 0, NULL, 0);
		WaitACKData(40);
		pRes->m_Reslut = Result_Error;
		return;
	}
	if (chdr->Size != m_SinkDataLen-headerLen)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if (chdr->Size > 4)
	{
		pRes->m_nParam1 = chdr->Size - 4;
		pRes->PushData(buf+headerLen, chdr->Size-4);
	}
}

//void CUSBModule::SaveData( int type, char *data, int len, int param1, int param2 )
//{
//	/*switch (type)
//	{
//	case 1:		//send
//		break;
//	case 2:		//recv
//		break;
//	case 3:		//send fail
//		break;
//	case 4:		//recv nothing
//		break;
//	case 5:		//flag no success
//		break;
//	}*/
//	
//}

//void CUSBModule::SaveData( CString &str, char *data /*= NULL*/, int len /*= 0*/ )
//{
//	CInterProtocl *pdu = CDataCenter::GetInstance()->GetITP();
//	pdu->m_eventType = EVENT_REQUEST;
//	pdu->m_srcModule = USB_MODULE;
//	pdu->m_desModule = FILE_MODULE;
//	pdu->m_operation = OP_WRITE_DATA;
//
//	pdu->m_nParam1 = str.GetLength();
//	pdu->PushData(str.GetBuffer(), str.GetLength());
//	if (data)
//	{
//		int strlen = str.GetLength();
//		memcpy(pdu->m_data+strlen, data, len);
//		pdu->m_len += len;
//	}
//	m_pListener->onMsgPdu(pdu);
//}

void CUSBModule::SaveData( char *str, char *data /*= NULL*/, int len /*= 0*/ )
{
	CInterProtocl *pdu = CDataCenter::GetInstance()->GetITP();
	pdu->m_eventType = EVENT_REQUEST;
	pdu->m_srcModule = USB_MODULE;
	pdu->m_desModule = FILE_MODULE;
	pdu->m_operation = OP_WRITE_DATA;

	pdu->m_nParam1 = strlen(str);
	pdu->PushData(str, pdu->m_nParam1);
	if (data)
	{
		int strlen = pdu->m_nParam1;
		memcpy(pdu->m_data+strlen, data, len);
		pdu->m_len += len;
	}
	m_pListener->onMsgPdu(pdu);

}
void CUSBModule::Reset( CInterProtocl *pReq, CInterProtocl *pRes )
{
	PRSHeader header;
	char *buf = NULL;
	if (SendCommand(MD_RESET, 0, 0, 0, NULL, 0) == 0)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	if ((buf = WaitACKData(2000)) == NULL)
	{
		pRes->m_Reslut = Result_Error;
		return;
	}
	header = (PRSHeader)buf;
	if (header->Flag != MD_SUCCESS)
	{
		pRes->m_Reslut = Result_Error;
	}
}
