/******************************************************************************
*	if 
*	if SECUOTP_ERROR_CONNECTDBFAILED return by secuotp_importtoken 
*	or secuotp_importuser, please check the following situation:
*	1. Database is running
*	2. Database is accessable for the request connection(firewall setting)
*	3. if error code SECUOTP_ERROR_CONNECTDBFAILED received, call function 
*		secuotp_geterrorcode() to get details. if error code10048(windows server) 
*		received, you should add registry item in path
*		HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
*		create two REG_DWORD item as follow:
*		keyname: TcpTimedWaitDelay	values:1	//system default value 240s
*		keyname: MaxUserPort		values:65535
*******************************************************************************/

#ifndef __OTP_COREC32_H__
#define __OTP_COREC32_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned long _U32, U32;



#ifndef MAX_PATH
#define MAX_PATH 260
#endif
#define MAXLEN_56 56
#define MAXLEN_32 32
#define MAXLEN_10 10
#define MAX_DATEBUF_LEN 56
#define COUNTER_SIZE 8
///Error Code**********************************
#define SECUOTP_ERROR_SUCCESS 0

//alloc/free ODBC Handle failed
#define SECUOTP_ERROR_ALLOCHANDLE_FAILED	11 //Alloc ODBC handle failed
#define SECUOTP_ERROR_FREEHANDLE_FAILED		12 //Free handle failed
#define SECUOTP_ERROR_SETENVATTR_FAILED		13 //set ODBC attribute failed
#define SECUOTP_ERROR_GETCONFIGFAILED		14 //get configurations failed,a invalid configuration file path or bad configuration file always cause this error
#define SECUOTP_ERROR_CONNECTDBFAILED		15 //connect to database failed
#define SECUOTP_ERROR_SQLEXFAILED			16 //SQL execute failed
#define SECUOTP_ERROR_NORELATEITEM			17 //no related record in the database
#define SECUOTP_ERROR_GETUSERINFO_FAILED	18 //failed in getting user infomation from database
#define SECUOTP_ERROR_USERREGLOST			19 //the user has registered lost
#define SECUOTP_ERROR_USERLOCKED			20 //user is locked
#define SECUOTP_ERROR_UNLOCK_FAILED			21 //unlock a user failed
#define SECUOTP_ERROR_UPDATEUSEDATE_FAILED  22 //update user information failed
#define SECUOTP_ERROR_UNKNOWNTKTYPE			23 //unknown token type
#define SECUOTP_ERROR_UPCHALLENG_FAILED		24 //update challenge code failed
#define SECUOTP_ERROR_INVALID_PASSWORD		25 //invalid password
#define SECUOTP_ERROR_SYNCHRONIZE_FAILED	26 //synchronize failed
#define SECUOTP_ERROR_INVALID_OLDPWD		27 //invalid old password
#define SECUOTP_ERROR_INVALID_AUTHTYPE		28 //invalid authentication type
#define SECUOTP_ERROR_USEREXIST				29 //username is invalid for the username is in use
#define SECUOTP_ERROR_INVALID_TOKEN			30 //invalid token
#define SECUOTP_ERROR_INVALID_PARAM			31 //invalid parameter
#define SECUOTP_ERROR_ADDUSER_FAILED		32 //add user failed
#define SECUOTP_ERROR_UPDATETOKEN_FAILED	33 //update token failed
#define SECUOTP_ERROR_DELETETOKEN_FAILED	34 //delete token failed
#define SECUOTP_ERROR_GETTOKENSTATE_FAILED	35 //get token status failed
#define SECUOTP_ERROR_TOKENINUSE			36 //the token is in use
#define SECUOTP_ERROR_INVALIDKEY			37 //invalid key for decrypt
#define SECUOTP_ERROR_OPENTOKENFILE_FAILED	38 //failed to open token file
#define SECUOTP_ERROR_AESMKKEY_FAILED		39 //make key failed
#define SECUOTP_ERROR_AESDECRYPT_FAILED		40 //decrypt file failed
#define SECUOTP_ERROR_AESGETPLAIN_FAILED	41 //get plain failed
#define SECUOTP_ERROR_AUTHSUCCESS_WITHINFO	42 //auth succeed with info
#define SECUOTP_ERROR_UPDATEKEYINFO_FAILED	43 //update counter failed
#define SECUOTP_ERROR_NOTNEEDSYNCHRONIZE	44 //challenge -response need not synchronize
#define SECUOTP_ERROR_SETUSERPIN_FAILED		45 //set pin for user fail
#define SECUOTP_ERROR_UPDATEPIN_FAILED		46
#define SECUOTP_ERROR_SUCCESS_WITHINFO		47 //error information return
#define SECUOTP_ERROR_OPENUSERFILE_FAILED	48 //open userinformation file failed
#define SECUOTP_ERROR_GETFILESIZE_FAILED	49 //get file size failed

#define SECUOTP_ERROR_SRVIPNULL				50	//authentication server ip need
#define SECUOTP_ERROR_GETERRINFOBUF_FAILED	51	//malloc function failed

#define SECUOTP_ERROR_GETFILECONT_FAILED	52	//get file content failed

#define SECUOTP_ERROR_UPDATEUSERBINDINFO_FAILED	53 //user rebind failed for reset user's token infomation failed
#define SECUOTP_ERROR_UPDATENEWTKSTATE_FAILED	54 //update new token for user failed

#define SECUOTP_ERROR_CHALLENGE				100 //you should response the challenge from Authentication Server


//operation type defination
#define AUTH				1
#define ADD_USER			11
#define DELETE_USER			12
#define TOKEN_SYNCHRONIZE	13
#define SET_USER_PIN		15
#define SET_USER_AUTHTYPE	16
#define SET_USER_INVALID	17
#define SET_USER_LOCK		18

#define USER_IMPORT			23
#define TOKEN_IMPORT		25
#define TOKEN_DELETE		26







///Error Code**********************************

/***************************************************************
* function: secuotp_initenv		//do some initialization work
* params:	 char *pszConfpath	//configuration file path
* return :  int 	0 -- succeed others -- failed
****************************************************************/
int secuotp_initenv(char *pszConfpath);//do initialization(databse and ODBC)

/***************************************************************
* function: secuotp_cleanup		//free all resources allocate by SDK
* return :  int 	0 -- succeed others -- failed
****************************************************************/
int secuotp_cleanup();//



/************************************************************************/
/* function: secuotp_getlasterror
/* return  : U32 -- error detail code for latest error
/************************************************************************/
U32 secuotp_getlasterror();


/***************************************************************
* function: secuotp_auth  //authentication
* params:	 char *pszUsername	-- username
* 		 char *pszPwd		-- OTP[PIN]
* return :  int 	SECUOTP_ERROR_SUCCESS -- succeed SECUOTP_ERROR_CHALLENGE -- challenge others -- failed
***************************************************************/
int secuotp_auth(char *pszUsername, char *pszPwd, unsigned int *pChallenge);


/***************************************************************
* function: secuotp_synchronize  //synchronize the token and the authentication server
* params:	 char *pszUsername	-- username
*		 char *pszOtp1		-- the first OTP
*		 char *pszOtp2		-- the next OTP
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_synchronize(char *pszUsername, char *pszOtp1, char *pszOtp2);




/***************************************************************
* function: secuotp_setuserpin  	//set PIN code for user 
* params:	 char *pszUsername	-- username
* 		 char *pszPin		-- PIN to use
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_setuserpin(char *pszUsername, char *pszPin);



/***************************************************************
* function: secuotp_resetpin		//reset PIN
* params:	 char *pszUsername	-- username
*		 char *pszOldpin		-- OLDPIN
*		 char *pszNewpin		-- NEWPIN
* return :  int 	0 -- succeed others -- failed
*************************************************************/
int secuotp_resetpin(char *pszUsername, char *pszOldpin, char *pszNewpin);


/***************************************************************
* function: secuotp_setauthtype		//authentication type  1--OTP only  2--OTP+PIN
* params:	 char *pszUsername	-- username
*		 int nAuthtype		-- 1(OTP only)
*					-- 2(OTP + PIN)
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_setauthtype(char *pszUsername, int nAuthtype);

/***************************************************************
* function: secuotp_adduser  	//add a user
* params:	 char *pszUsername	-- username(max length:20)
* 		 char *pszUserid		-- userid(max length:20)
*		 char *pszContacttel   -- contact telnumber(max length:20)
*		 char *pszSerialnum	-- serial number of the token assigned to the user(max length:20)
*		 char *pszRemark		-- remark (max length:260)
*		 char *pszEmail		-- Email(max length:30)
*		 char *pszDomain		-- /reserved, always set it NULL
*		 char *pszPin			-- userPIN(max length:20)
*		 char *pszPreusedate	--user added time. if NULL is given use current
*									datetime(recommend)
*		 int nAuthtype		-- authentication type(1--otp only 2--otp+pin)
* return :  int 	0 -- succeed others -- failed
***************************************************************/
int secuotp_adduser(char *pszUsername, char *pszUserid,
 char *pszContacttel, char *pszSerialnum,
 char *pszRemark, char *pszEmail,
 char *pszDomain, char *pszPin,
 char *pszPreusedate,
 int nAuthtype
);


/***************************************************************
* function: secuotp_deleteuser  	//delete a user
* params:	 char *pszUsername	-- username
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_deleteuser(char *pszUsername);



/***************************************************************
* function: secuotp_setuserinvalid  	//set user validation status
* params:	 char *pszUsername	-- username
* 		 int   nvalid			-- status	 0 - invalid  1 - valid
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_setuserinvalid(char *pszUsername, int nvalid);


/***************************************************************
* function: secuotp_setuserlock  	//change user lock status
* params:	 char *pszUsername	-- username
* 		 int   nvalid			-- lock status 0 - unlocked  1 - locked
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_setuserlock(char *pszUsername, int nlock);




/***************************************************************
* function: secuotp_tokenimport  	//import tokens
* params:	 char *pszTokenfile	-- token file path
* 		 char *pszSecret		-- decrypt secret
*		 char **pstrErrinfo		--out pointer to a buffer contains error information.
*						--you should call secuotp_free() to free the buffer if you do not need to use the buffer any more
* return :  int 	0 -- succeed others -- failed
* remark :	if SECUOTP_ERROR_SUCCESS_WITHINFO returned, you have to 
*			call the secuotp_free to free memory
**************************************************************/
int secuotp_tokenimport(char *pszTokenfile, char *pszSecret, char **pstrErrinfo);

/***************************************************************
* function: secuotp_free
* params:	void **pbuf	--- pbuf to be free
* remark: if SECUOTP_ERROR_SUCCESS_WITHINFO returned by function
*		  secuotp_tokenimport, secuotp_free should be called to 
*		  avoid memory leak. 
***************************************************************/
void secuotp_free(void **spsbuf);

/**************************************************************************************************************
* function: secuotp_userimport  	//import users
* params:	 char *pszUserfile 	-- user file
* 		 char *pszSecret	-- decrypt secret(if the user information in the user file is plain you should set this parameter NULL.
*					    in this version you should always set it NULL)
*		 char **pstrErrinfo	-- out pointer to a buffer which contains error information
*
* return :  int 	0 -- succeed others -- failed
* remark: if a error item line which stored in the memory with *pstrErrinfo as the beginning address
*		  end with '*'--the current line is added into DB succeed but failed in updating correspond token status.
*		  end with '#'--the current line is not useable for it conflicts with item already exist in the DB
*		  end with '$'--the current item uses an invalid token
*****************************************************************************************************************/
int secuotp_userimport(char *pszUserfile, char *pszSecret, char **pstrErrinfo);


/****************************************************************************************************************
* function: secuotp_tokendelete  	//delete a token
* params:	 char *pszTokenserialnum	-- serial number to the token to be deleted
* return :  int 	0 -- succeed others -- failed
*****************************************************************************************************************/
int secuotp_tokendelete(char *pszTokenserialnum);


/***************************************************************
* function: secuotp_makelog  	//make log information
* params:	 int nLoglev			-- loglev
* 		 char *pszOperator		-- operator
*		 int nOptype			-- operate type
*		 char *pszContent		-- log content
* return :  int 	0 -- succeed others -- failed
**************************************************************/
int secuotp_makelog(int nLoglev, char *pszOperator,  int  nOptype,  char *pszContent, char *pszSrvip);

unsigned long secuotp_geterrorcode();


/******************************************************************************
* function: secuotp_tkrebind
* params: char *pszUsername--Name of user to be operated 
*		  char *pszNewserialnum--new serialnum to be used in user-token rebind
* return: SECUOTP_ERROR_SUCCESS(0)--succeed others-failed
*******************************************************************************/
int secuotp_rebind(char *pszUseername, char *pszNewserialnum);


#ifdef __cplusplus
}
#endif
#endif//__OTP_COREC32_H__
