
/*============================================================================
 Name        : libuserCmd.c
 Author      : atao
 Date  	     : 2015.9
 Copyright   : ZKSoftware Inc.
 Description : Linux C
 ============================================================================*/
#include "serial.h"
#include "libtype.h"
#include "command_fun.h"
#include "libuserCmd.h"
#include "main.h"
#include "zkfpi.h"

TExtDataBuf ExtDataBuffer;
U8 *DATABUFF = NULL;
U8 *DATA_pro = NULL;
U8 *DATA_end = NULL;
FILE *Fp = NULL;
INT SetTime_loop = -1;
INT Err_flag = 0;
VOID *sensor = NULL;

const int PARAMETER_Id[] = {
		SID_SAVE_LOG,
		SID_AUTO_ACK,
		SID_TIMEOUT,
		SID_FW_VER,
		SID_BAUDRATE,
		SID_ENROLL_FP,
		SID_FP_COUNT,
		SID_USER_COUNT,
		SID_LOG_NUM,
		SID_LOG_COUNT,
		SID_BUILD_NUM,
		SID_MODULE_ID
};
const int PARAMETER_Value[] = {
		SID_GPIO_LEVEL,
		SID_SAVE_LOG,
		SID_AUTO_ACK,
		SID_TIMEOUT
};

static VOID SetExtDataBuffer(INT size, U8 *buf)
{
	if(DEBUG)
	{
		fprintf(Fp, "get image size %d bytes\n", size);
	}
	ExtDataBuffer.buffer=buf;
	ExtDataBuffer.bufferSize=size;
	ExtDataBuffer.bufEnd=buf +size;
	ExtDataBuffer.bufPtr=buf;
	ExtDataBuffer.Index=0;
	ExtDataBuffer.PacketNum=0;
	ExtDataBuffer.PacketLen=0;
}

INT Connect(CHAR *dev, INT type)
{
	INT ret = 0;
	switch(type)
	{
		case DEV_USB:			//usb init
			ret = usb.init(USBVID, USBPID);
			if(ret)
			{
				if((ret = ZKFPI_Open(0)))
				{
					//clear the USB buffer data
					Recv_data();
					ret = GetStatus();
				}
			}
			break;
		case DEV_232:
			ret = INIT(dev);//ff232 init
			if(ret)
			{
				ret = GetStatus();
			}
			break;
		default :
			break;
	}
	return ret;
}

INT Final(VOID)
{
	if(DATABUFF != NULL)
	{
		zk_free(DATABUFF);
		DATABUFF = NULL;
	}
	if(DataPackage != NULL)
	{
		zk_free(DataPackage);
		DataPackage = NULL;
	}
	if(Dev_num == DEV_232)
	{
		ff232.free();		//close 232
	}
	else if(Dev_num == DEV_USB)
	{
		ZKFPI_Close();		//close usb
	}
	return SUCCESS;
}

/********************* Parameter select *********************/
INT ParameterSelect(INT flag)
{
	INT i = 0;
	INT parameter_value[] =
	{
			SID_SAVE_LOG,
			SID_AUTO_ACK,
			SID_TIMEOUT,
			SID_FW_VER,
			SID_BAUDRATE,
			SID_ENROLL_FP,
			SID_FP_COUNT,
			SID_USER_COUNT,
			SID_LOG_NUM,
			SID_LOG_COUNT,
			SID_BUILD_NUM,
			SID_MODULE_ID,
			SID_GPIO_LEVEL,
			SID_MODULE_IDENTIFY
	};
	for(i = 0; i < sizeof(parameter_value); i++)
	{
		if(flag == parameter_value[i])
		{
			break;
		}
	}
	if(i >= sizeof(parameter_value))
	{
		//Parameter err...
		return FAILURE;
	}

	return SUCCESS;
}

/****************** User command *****************/

INT EnrollUserByScan(INT userID)
{
	INT count = 0;
	INT ret = -1;
	INT Param = userID;
	INT Flag = 0;
	U32 timeout = 9000;
	INT len = 0;

	
	//send data
	ret = Cmd.SendCmd(MD_ENROLL_SCAN, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	do
	{
		//recv data
		ret = Cmd.RecvCmd(MD_ENROLL_SCAN, &Flag, &Param, NULL, &len, timeout);
		if(ret < 0)
		{
			return FAILURE;
		}
		count++;
		if(DEBUG)
		{
			fprintf(Fp, "count = %d\r\n", count);
		}
	}while((0x62 == Flag) && (count < 3));

	//Operation OK?
	if((Flag != FLAG_OK))
	{
		Err_flag = Flag;
		return FAILURE;
	}

	if(DEBUG)
	{
		fprintf(Fp, " EnrollUserByScan.....OK!\r\n");
	}
	return SUCCESS;
}

INT GetStatus(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;


	//send data
	ret = Cmd.SendCmd(MD_SYS_STATUS, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_SYS_STATUS, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	if(DEBUG)
	{
		fprintf(Fp, " GetStatus.....OK!\r\n");
	}

	return SUCCESS;
}

INT ReadAllLogs(INT *userID,  CHAR *event, CHAR *verified, U32 *date, U32 *time, CHAR *reserved)
{
	INT ret = 0;
	INT dataSize = 0;
	static INT loop = 0;
	tLog data;

	if(0 == loop)
	{
		if(!GetAllLogs(&dataSize))
		{
			if(DATABUFF != NULL)
			{
				zk_free(DATABUFF);
				DATABUFF = NULL;
			}
			return FAILURE;
		}
	}

	if(DATA_pro < DATA_end)
	{
		memcpy(&data, (pLog)DATA_pro, sizeof(tLog));
		DATA_pro += sizeof(tLog);
		ret = 1;
		loop = 1;
	}
	else
	{
		//Recv Record Over!
		loop = 0;
		ret = 0;
	}

	//return user data
	memcpy(reserved, data.Reserved, sizeof(data.Reserved));
	*time = data.Time;
	*date = data.Date;
	*verified = data.verified;
	*event = data.Event;
	*userID = data.userID;

	if((0 == loop) && (DATABUFF != NULL))
	{
		zk_free(DATABUFF);
		DATABUFF = NULL;
	}
	return ret;
}

INT GetAllLogs(INT *dataSize)
{
	INT ret = -1;
	INT Param = MAX_DATA;
	INT Flag = 0;
	INT len = 0;
	INT size = 0;
	U32 timeout = 150;

	//1. send command
	ret = Cmd.SendCmd(MD_LOAD_LOG_X, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_LOAD_LOG_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	size = Param;

	if(Flag == FLAG_OK)
	{

		timeout = 1000;
		//2. recv extData
		DATABUFF = zk_malloc(size);
		SetExtDataBuffer(size, DATABUFF);
		RecvExtDataPro(MD_LOAD_LOG_X, timeout);		//RECV OK!
	}//if end

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		//Operation failure...
		return FAILURE;
	}
	*dataSize = size;
	DATA_pro = DATABUFF;
	DATA_end = DATABUFF + size;

	return SUCCESS;
}

INT ReadAllUser(INT *userID,  CHAR *name,  CHAR *password, U16 *secLevel,
		U32 *PIN2, U8 *privilege, U8 *fingerprintNum, U8 *Card)
{
	INT ret = 0;
	INT dataSize = 0;
	static INT loop = 0;
	tUser data;

	if(0 == loop)
	{
		if(!GetAllUsers(&dataSize))
		{
			if(DATABUFF != NULL)
			{
				zk_free(DATABUFF);
				DATABUFF = NULL;
			}
			return FAILURE;
		}
	}

	if(DATA_pro < DATA_end)
	{
		memcpy(&data, (pUser)DATA_pro, sizeof(tUser));
		DATA_pro += sizeof(tUser);
		ret = 1;
		loop = 1;
	}
	else
	{
		//Read User Over!
		if(DEBUG)
		{
			fprintf(Fp, "[17]ReadAllUser.....OK!\r\n");
		}
		loop = 0;
		ret = 0;
	}
	//return user data
	memcpy(name, data.Name, sizeof(data.Name));
	memcpy(password, data.Password, sizeof(data.Password));
	memcpy(Card, data.Card, sizeof(data.Card));
	*secLevel = data.SecLevel;
	*PIN2 = data.PIN2;
	*privilege = data.Privilege;
	*fingerprintNum = data.Fpnum;
	*userID = data.userID;

	if(0 == loop)
	{
		if(DATABUFF != NULL)
		{
			zk_free(DATABUFF);
			DATABUFF = NULL;
		}
	}
	return ret;
}

INT GetAllUsers(INT *dataSize)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	INT size = 0;
	U32 timeout = 150;

	//1. send command
	ret = Cmd.SendCmd(MD_LOAD_USER_X, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_LOAD_USER_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	size = Param;

	if(Flag == FLAG_OK)
	{
		timeout = 1000;
		//2. recv extData
		DATABUFF = zk_malloc(size);
		SetExtDataBuffer(size, DATABUFF);
		RecvExtDataPro(MD_LOAD_USER_X, timeout);	//RECV OK!
	}//if end

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	//3. data
	*dataSize = size;
	DATA_pro = DATABUFF;
	DATA_end = DATABUFF + size;
	return SUCCESS;
}

INT ReadTemplates(INT userID, INT index,  INT flag, U8 *data)
{
	INT ret = 0;
	INT dataSize = 0;
	static INT loop = 0;

	if(0 == loop)
	{
		if(!GetTemplates(userID, index, flag, &dataSize))
		{
			if(DATABUFF != NULL)
			{
				zk_free(DATABUFF);
				DATABUFF = NULL;
			}
			if(DEBUG)
			{
				mvwprintw(win1, 1, 1, "GetTemplates err...");
				DebugWin(win1, 2);
			}
			return FAILURE;
		}
	}

	if(DATA_pro < DATA_end)
	{
		memcpy(data, DATA_pro, TEMPLATES_SIZE);
		DATA_pro += TEMPLATES_SIZE;
		ret = 1;
		loop = 1;
	}
	else
	{
		//Recv Templates Over!
		loop = 0;
		ret = 0;
	}

	if((0 == loop) && (DATABUFF != NULL))
	{
		zk_free(DATABUFF);
		DATABUFF = NULL;
	}
	return ret;
}

INT GetTemplates(INT userID, INT index,  INT flag, INT *dataSize)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	INT size = 0;
	INT count = 0;
	U32 timeout = 150;

	if((flag == 0) || (flag == 1))
	{
		Flag = flag;
	}
	else
	{
		return FAILURE;
	}
	//index << 16 | user ID
	Param = ((index << 16) | (userID));

	//1. send command
	ret = Cmd.SendCmd(MD_READ_TMP_X, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_READ_TMP_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	size = Param & 0xff;
	count = (Param >> 8) & 0xff;
	if(count > 0)
	{
		size = TEMPLATES_SIZE * count;
	}

	if(Flag == FLAG_OK)
	{
		timeout = 1000;
		//2. recv extData
		DATABUFF = zk_malloc(size);
		SetExtDataBuffer(size, DATABUFF);
		RecvExtDataPro(MD_READ_TMP_X, timeout);//RECV OK!

	}//if end

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		if(DEBUG)
		{
			mvwprintw(win1, 1, 1, "Operation failure...");
			DebugWin(win1, 2);
		}

		return FAILURE;
	}

	//3. data
	*dataSize = size;
	DATA_pro = DATABUFF;
	DATA_end = DATABUFF + size;

	return SUCCESS;
}

INT ReadAllTemplates(U8 *data)
{
	INT dataSize = 0;
	INT ret = 0;
	static INT loop = 0;

	if(0 == loop)
	{
		if(!GetAllTemplates(&dataSize))
		{
			if(DATABUFF != NULL)
			{
				zk_free(DATABUFF);
				DATABUFF = NULL;
			}
			if(DEBUG)
			{
				mvwprintw(win1, 1, 1, "GetAllTemplates err...");
				DebugWin(win1, 2);
			}
			return FAILURE;
		}
	}

	if(DATA_pro < DATA_end)
	{
		memcpy(data, DATA_pro, TEMPLATES_SIZE);
		DATA_pro += TEMPLATES_SIZE;
		loop = 1;
		ret = 1;
	}
	else if(DATA_pro == DATA_end)
	{
		//Recv Templates Over!
		//Operation is successful!
		loop = 0;
		ret = 1;
	}
	else
	{
		loop = -1;
		ret = 0;
	}

	if((0 == loop) || (-1 == loop) )
	{
		if(DATABUFF != NULL)
		{
			zk_free(DATABUFF);		//memory free OK!
			DATABUFF = NULL;
		}
	}
	return ret;
}

INT GetAllTemplates(INT *dataSize)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	INT size = 0;
	U32 timeout = 150;

	//1. send command
	ret = Cmd.SendCmd(MD_LOAD_TMP_X, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_LOAD_TMP_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	size = Param;
	if(Flag == FLAG_OK)
	{
		timeout = 1000;
		//2. recv extData
		DATABUFF = zk_malloc(size);
		SetExtDataBuffer(size, DATABUFF);
		RecvExtDataPro(MD_LOAD_TMP_X, timeout);	//RECV OK!
	}//if end

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		if(DEBUG)
		{
			mvwprintw(win1, 1, 1, "Operation failure...");
			DebugWin(win1, 2);
		}
		return FAILURE;
	}

	//3. data
	*dataSize = size;
	DATA_pro = DATABUFF;
	DATA_end = DATABUFF + size;

	return SUCCESS;
}

INT ModifyUser(INT userID,  CHAR *name,  CHAR *password, U16 secLevel,
		U32 PIN2, U8 privilege,	U8 fingerprintNum, U8 *Card)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0x61;
	U32 timeout = 1000;
	INT len = sizeof(tUser);
	tUser user;

	user.userID = userID;
	user.Fpnum = fingerprintNum;
	user.PIN2 = PIN2;
	user.Privilege = privilege;
	user.SecLevel = secLevel;
	memcpy(user.Name, name, sizeof(user.Name));
	memcpy(user.Password, password, sizeof(user.Password));
	memcpy(user.Card, Card, sizeof(user.Card));

	//send data
	ret = Cmd.SendCmd(MD_ADD_USER, Param, Flag, (U8 *)&user, len);
	if(ret < 0)
	{
		return FAILURE;
	}

	//recv data
	ret = Cmd.RecvCmd(MD_ADD_USER, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " ModifyUser.....OK!\r\n");
	}
	return SUCCESS;
}

INT GetFingerImage(INT *width, INT *height, U8 * data)
{
	INT ret = -1;
	INT Param = 0;		//0 -> 4k
	INT Flag = 0;
	INT len = 0;
	U32 timeout = 9000;

	SHORT Index = 0;
	SHORT PacketNum = 0;
	PImage image = NULL;
	U8 buff[1024];

	memset(buff, 0, sizeof(buff));
	image = (PImage)buff;

	//1. send command
	ret = Cmd.SendCmd(MD_SCAN_IMAGE_X, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	if(Dev_num == DEV_232)
	{
		timeout = 7000;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_SCAN_IMAGE_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//2. recv image data info
	if(Flag == FLAG_OK)
	{
		timeout = 9000;
		if(Dev_num == DEV_232)
		{
			timeout = 5000;
		}
		//recv data
		ret = Cmd.extRecvCmd(MD_SCAN_IMAGE_X, &Flag, &PacketNum, &Index, buff, &len, timeout);
		*width = image->width;
		*height = image->height;

		fprintf(Fp, "width = %d    height = %d\r\n", *width, *height);
		if(DATABUFF != NULL)
		{
			zk_free(DATABUFF);
			DATABUFF = NULL;
		}
		DATABUFF = (U8 *)malloc(image->img_len);
		if (NULL == DATABUFF)
		{
			//malloc Err
			Flag = ERR_DATA_ERROR;
			Cmd.extSendCmd(MD_SCAN_IMAGE_X, Flag, PacketNum, Index, NULL, 0);
			return FAILURE;
		}
		else
		{
			Flag = DATA_OK;
			ret = Cmd.extSendCmd(MD_SCAN_IMAGE_X, Flag, PacketNum, Index, NULL, 0);
		}

		if(Dev_num == DEV_232)
		{
			timeout = 1000;
		}
		//3. recv extData
		memset(DATABUFF, 0, image->img_len);
		SetExtDataBuffer(image->img_len, DATABUFF);
		if (RecvExtDataPro(MD_SCAN_IMAGE_X, timeout) > 0)	//image OK!
		{
			memcpy(data, DATABUFF, (image->img_len));
			Flag = FLAG_OK;
		}
	}//if end
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " GetFingerImage.....OK!\r\n");
	}
	if(DATABUFF != NULL)
	{
		zk_free(DATABUFF);
		DATABUFF = NULL;
		//memory free OK!
	}
	return SUCCESS;
}


INT IdentifyByImage(INT imageSize, INT *userID, INT *index, U8 * data)
{
	INT ret = -1;
	INT Param = imageSize;
	INT Flag = 0;
	INT len = 0;
	U32 timeout = 150;

	//1. send command
	ret = Cmd.SendCmd(MD_IDENTIFY_IMAGE_X, Param, Flag, NULL, 0);
	if(ret < 0)
	{
		return FAILURE;
	}
	if(Dev_num == DEV_USB)
	{
		timeout = 5000;
	}
	ret = Cmd.RecvCmd(MD_IDENTIFY_IMAGE_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//2. send image
	if(Flag == FLAG_OK)
	{
		timeout = 9000;
		if(Dev_num == DEV_232)
		{
			timeout = 1000;
		}
		SendExtDataPro(MD_IDENTIFY_IMAGE_X, &Param, &Flag, timeout, data, imageSize);
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	//return info
	*userID = (Param & 0xffff);
	*index = (Param >> 16) & 0x0f;

	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " IdentifyByImage.....OK!\r\n");
	}
	return SUCCESS;
}

INT EnrollTemplateByImage (INT userID, U8 *data, INT dataSize)
{
	INT ret = -1;
	INT Param = userID;
	INT Flag = 0;
	INT len = 4;
	U32 timeout = 2000;	//2s
	INT size = dataSize;
	//1. send command

	ret = Cmd.SendCmd(MD_ENROLL_IMAGE_X, Param, Flag, (U8 *)&size, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	ret = Cmd.RecvCmd(MD_ENROLL_IMAGE_X, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//2. send data
	if(Flag == FLAG_OK)
	{
		timeout = 9000;
		if(Dev_num == DEV_232)
		{
			timeout = 1000;
		}
		SendExtDataPro(MD_ENROLL_IMAGE_X, &Param, &Flag, timeout, data, dataSize);
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " EnrollTemplateByImage.....OK!\r\n");
	}
	return SUCCESS;
}

INT GetUser(INT userID,  CHAR *name,  CHAR *password, U16 *secLevel,
		U32 *PIN2, U8 *privilege, U8 *fingerprintNum, U8 *Card)
{
	INT ret = -1;
	INT Param = userID;
	INT Flag = 0;
	INT len = sizeof(tUser);
	U32 timeout = 300;
	pUser data = NULL;
	SHORT PacketNum = 0;
	SHORT Index = 0;

	//send data
	ret = Cmd.SendCmd(MD_READ_USER, Param, Flag, NULL, 0);
	if(ret < 0)
	{
		return FAILURE;
	}
	if(data != NULL)
	{
		zk_free(data);
		data = NULL;
	}
	data = (pUser)malloc(sizeof(tUser));
	if(NULL == data)
	{
		//malloc Err
		return FAILURE;
	}

	//recv data
	ret = Cmd.extRecvCmd(MD_READ_USER, &Flag, &PacketNum, &Index, (U8 *)data, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	memcpy(name, data->Name, sizeof(data->Name));
	memcpy(password, data->Password, sizeof(data->Password));
	memcpy(Card, data->Card, sizeof(data->Card));
	*secLevel = data->SecLevel;
	*PIN2 = data->PIN2;
	*privilege = data->Privilege;
	*fingerprintNum = data->Fpnum;

	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " GetUser.....OK!\r\n");
	}
	if(data != NULL)
	{
		zk_free(data);
		data = NULL;
	}
	return SUCCESS;
}

INT SetTemplates(INT userID, INT flag, U8 *data, INT dataSize)
{
	INT ret = -1;
	INT Param = userID;
	INT Flag = 0;
	INT len = dataSize;
	U32 timeout = 1000;	//1s

	switch(flag)
	{
		case 0:
			Flag = 0;
			break;
		case 1:
			Flag = 0x84;
			break;
		default:
			//Parameter err...
			return FAILURE;
	}
	if(NULL == data)
	{
		//Data is null...
		return FAILURE;
	}

	//send data
	ret = Cmd.SendCmd(MD_ENROLL_TMP, Param, Flag, data, len);
	if(ret < 0)
	{
		return FAILURE;
	}

	//recv data
	ret = Cmd.RecvCmd(MD_ENROLL_TMP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	return SUCCESS;
}

INT GetTime (INT *Year, INT *Month, INT *Day,  INT *Hour, INT *Minute, INT *Second)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	INT time = 0;
	U32 timeout = 150;

	//date init
	*Year = *Month = *Day = *Hour = *Minute = *Second = 0;
	//1. send data
	ret = Cmd.SendCmd(MD_GET_TIME, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}

	//2. recv data
	ret = Cmd.RecvCmd(MD_GET_TIME, &Flag, &Param, (U8*)&time, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//3. Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	//4. return time
	*Year = (Param & 0xff);
	Param >>= 8;
	*Month = (Param & 0xff);
	Param >>= 8;
	*Day = (Param & 0xff);

	*Hour = (time & 0xff);
	time >>= 8;
	*Minute = (time & 0xff);
	time >>= 8;
	*Second = (time & 0xff);

	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, "GetTime.....OK!\r\n");
	}
	return SUCCESS;
}

INT SetTime(INT Year, INT Month, INT Day,  INT Hour, INT Minute, INT Second)
{
	INT ret = -1;
	INT time = 0;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 4;

	//1. time data
	if(timeCheck(Year, Month, Day, Hour, Minute, Second) < 0)
	{
		if(DEBUG)
		{
			mvwprintw(win1, 1, 1, "Time Parameter err...");
			DebugWin(win1, 2);
		}
		return FAILURE;
	}

	/**
	 * DD<<16 | MM<<8 | YY    ss<<16 | mm<<8 | hh
	 **/
	Year -= 2000;
	Param |= (Day & 0xff);
	Param <<= 8;
	Param |= (Month & 0xff);
	Param <<= 8;
	Param |= (Year & 0xff);

	time |= (Second & 0xff);
	time <<= 8;
	time |= (Minute & 0xff);
	time <<= 8;
	time |= (Hour & 0xff);

	SetTime_loop = 1;//1:output setTime datapack  [on]
	//2. send data
	ret = Cmd.SendCmd(MD_SET_TIME, Param, Flag, (U8*)&time, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	SetTime_loop = 0;//1:output setTime datapack [off]
	//3. recv data
	ret = Cmd.RecvCmd(MD_SET_TIME, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//4. Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, "SetTime.....OK!\r\n");
	}
	return SUCCESS;
}

INT DeleteTemplates(INT userID, INT index, INT flag)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;

	switch(flag)
	{
		case 0:
			Flag = 0;
			break;
		case 1:
			Flag = 0x77;
			break;
		default:
			if(DEBUG)
			{
				mvwprintw(win1, 1, 1, "flag Parameter err...");
				DebugWin(win1, 2);
			}
			return FAILURE;
	}
	if((index < 0) || (index > 9))
	{
		if(DEBUG)
		{
			mvwprintw(win1, 1, 1, "index Parameter err...");
			DebugWin(win1, 2);
		}
		return FAILURE;
	}
	else
	{
		Param = (userID & 0xFFFF) | ((index & 0x0F) << 16);
	}

	//send data
	ret = Cmd.SendCmd(MD_DEL_TMP, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}

	//recv data
	ret = Cmd.RecvCmd(MD_DEL_TMP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " DeleteTemplates.....OK!\r\n");
	}
	return SUCCESS;
}

INT SetParameter (INT value, INT flag)
{
	INT ret = -1;
	INT Param = value;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;

	if(!ParameterSelect(flag))
	{
		return FAILURE;
	}
	Flag = flag;
	//send data
	ret = Cmd.SendCmd(MD_SYS_WP, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_SYS_WP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " SetParameter.....OK!\r\n");
	}
	return SUCCESS;
}

INT GetParameter(INT flag, INT *value)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;

	if(!ParameterSelect(flag))
	{
		return FAILURE;
	}
	Flag = flag;

	//send data
	ret = Cmd.SendCmd(MD_SYS_RP, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_SYS_RP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	*value = Param;
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " GetParameter.....OK!\r\n");
	}
	return SUCCESS;
}

INT DeleteUser(INT userID)
{
	INT ret = -1;
	INT Param = userID;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;

	//send data
	ret = Cmd.SendCmd(MD_DELETE_USER, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DELETE_USER, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " DeleteUser.....OK!\r\n");
	}
	return SUCCESS;
}

INT DeleteAllUsers(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;

	//send data
	ret = Cmd.SendCmd(MD_DEL_ALL_USER, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DEL_ALL_USER, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " DeleteAllUsers.....OK!\r\n");
	}
	return SUCCESS;
}

INT SaveParameter(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;

	//send data
	ret = Cmd.SendCmd(MD_SYS_SP, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_SYS_SP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " SaveParameter.....OK!\r\n");
	}
	return SUCCESS;
}

INT ClearDB (VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;
	
	//send data
	ret = Cmd.SendCmd(MD_DEL_DB, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DEL_DB, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		//Operation failure...
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " ClearDB.....OK!\r\n");
	}
	return SUCCESS;
}

INT DeleteAllTemplates(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;

	//send data
	ret = Cmd.SendCmd(MD_DEL_ALL_TMP, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DEL_ALL_TMP, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " DeleteAllTemplates.....OK!\r\n");
	}
	return SUCCESS;
}

INT Verify (INT userID)
{
	INT ret = -1;
	INT Param = userID;
	INT Flag = FLAG_OK;
	U32 timeout = 5000;
	INT len = 0;
	
	//send data
	ret = Cmd.SendCmd(MD_VERIFY_SCAN, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}

	//recv data
	ret = Cmd.RecvCmd(MD_VERIFY_SCAN, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}

	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " Verify.....OK!\r\n");
	}
	return SUCCESS;
}


INT DeleteAllLogs (VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 1000;
	INT len = 0;
	
	//send data
	ret = Cmd.SendCmd(MD_DEL_ALOG, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DEL_ALOG, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " DeleteAllLogs.....OK!\r\n");
	}
	return SUCCESS;
}

VOID TimeAnalyse(U32 date, U32 time, INT *Year, INT *Month, INT *Day,  INT *Hour, INT *Minute, INT *Second)
{
	*Year = (date & 0xff);
	date >>= 8;
	*Month = (date & 0xff);
	date >>= 8;
	*Day = (date & 0xff);

	*Hour = (time & 0xff);
	time >>= 8;
	*Minute = (time & 0xff);
	time >>= 8;
	*Second = (time & 0xff);
}

INT ScanTemplate(U8 *data)
{
	INT i = 0;
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	U32 timeout = 2000;
	U8 *buffer = NULL;

	buffer = zk_malloc(TEMPLATES_SIZE);
	//1. send command
	ret = Cmd.SendCmd(MD_SCAN_TEMPLATE, Param, Flag, NULL, len);
	if (ret < 0) {
		return FAILURE;
	}
	//recv command
	ret = Cmd.RecvCmd(MD_SCAN_TEMPLATE, &Flag, &Param, buffer, &len, timeout);
	if (ret < 0) {
		return FAILURE;
	}

	//Operation OK?
	if (Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//return data
	memcpy(data, buffer, len);

	//Operation is successful!
	//output data
	if(DEBUG)
	{
		for(i = 0; i < len; i++)
		{
			if (i > 0 && !(i%256))
			{
				fprintf(Fp, "\r\n");
			}
			fprintf(Fp, "0x%x ", buffer[i]);
		}
		fprintf(Fp, "\r\nScanTemplate.....OK!\r\n");
	}
	if(buffer != NULL)
	{
		zk_free(buffer);
		buffer = NULL;
	}
	return SUCCESS;
}

INT Disconnect(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	INT len = 0;
	U32 timeout = 150;


	//send data
	ret = Cmd.SendCmd(MD_DISCONNECT, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DISCONNECT, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	if(DEBUG)
	{
		fprintf(Fp, " Disconnect_Interface.....OK!\r\n");
	}
	sleep(1);
	//free cache and close interface
	if(Final())
	{
		mvwprintw(win1, 1, 1, "Final OK!");
		fprintf(Fp, " Final.....OK!\r\n");
	}
	return SUCCESS;
}

INT Reset(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;


	//send data
	ret = Cmd.SendCmd(MD_RESET, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_RESET, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	if(DEBUG)
	{
		fprintf(Fp, " Reset.....OK!\r\n");
	}

	return SUCCESS;
}

INT DisableDevice(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;


	//send data
	ret = Cmd.SendCmd(MD_DISABLEDEVICE, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_DISABLEDEVICE, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	if(DEBUG)
	{
		fprintf(Fp, " Disable_Device.....OK!\r\n");
	}

	return SUCCESS;
}

INT EnableDevice(VOID)
{
	INT ret = -1;
	INT Param = 0;
	INT Flag = 0;
	U32 timeout = 150;
	INT len = 0;


	//send data
	ret = Cmd.SendCmd(MD_ENABLEDEVICE, Param, Flag, NULL, len);
	if(ret < 0)
	{
		return FAILURE;
	}
	//recv data
	ret = Cmd.RecvCmd(MD_ENABLEDEVICE, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}

	if(DEBUG)
	{
		fprintf(Fp, " Disable_Device.....OK!\r\n");
	}

	return SUCCESS;
}

INT Upgrade (U8 *fw, INT size)
{
	INT ret = -1;
	INT Param = size;
	INT Flag = 0;
	INT len = 0;
	U32 timeout = 150;

	//1. send command
	ret = Cmd.SendCmd(MD_UPDATE_FW, Param, Flag, NULL, 0);
	if(ret < 0)
	{
		return FAILURE;
	}
	if(Dev_num == DEV_USB)
	{
		timeout = 5000;
	}
	ret = Cmd.RecvCmd(MD_UPDATE_FW, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//2. send image
	if(Flag == FLAG_OK)
	{
		timeout = 9000;
		if(Dev_num == DEV_232)
		{
			timeout = 150;
		}
		SendExtDataPro(MD_UPDATE_FW, &Param, &Flag, timeout, fw, size);
	}
	if(Dev_num == DEV_232)
	{
		pd_msleep(10);
		timeout = 150;
	}
	ret = Cmd.RecvCmd(MD_UPDATE_FW, &Flag, &Param, NULL, &len, timeout);
	if(ret < 0)
	{
		return FAILURE;
	}
	//Operation OK?
	if(Flag != FLAG_OK)
	{
		Err_flag = Flag;
		return FAILURE;
	}
	//Operation is successful!
	if(DEBUG)
	{
		fprintf(Fp, " Upgrade.....OK!\r\n");
	}
	return SUCCESS;
}

