#ifndef INTERFACE_H
#define INTERFACE_H
#ifdef _PLATFORM_ANDROID
#include <stdbool.h>
#else
#ifndef __cplusplus
typedef enum BOOL {
	false = 0,
	true = !false
}bool;
#else
#endif
#endif

#define Token_Arguments_Bad      0x26
#define Token_Error_No_Device      0x27
#define Token_Error_Password       0x16
#define Token_Erro_No_key	   0x49
#define Token_Erro_Crypt	   0x47
#define Token_NoError_API          0x00
#define Token_TIME_OUT				0x57
#define Token_sign_err				0x58
#define Token_sign_cancel			0x59

#define S_OK					0
#define S_DEVICE_FAILURE		-1
#define S_INVALID_PASSWORD		-2
#define S_DEVICE_LOCK			-3
#define S_NOT_ENOUGH_MEMORY		-4
#define S_INVALID_CERTIFICATE	-5
#define S_INVALID_ALGORITHM		-6
#define S_INVALID_PARAMETER		-7
#define S_UNKOWN_ERROR			-8
#define S_USER_CANCEL			-9


#define PUBKEY_DATA_LEN			140
#define PUBKEY_HASH_LEN			20
#define ENCRYPTED_MAX_LENGTH	128
#define CERT_MAX_COUNT			2
#define CERT_MAX_LENGTH			2000
#define SN_MAX_LEN				20

typedef unsigned char byte;
typedef byte* pbyte;

#ifdef __cplusplus
extern "C" {
#endif

//////////////////////////////////////////////////////////////////////////
/* 1. Device Connection Status
 * [out] bConnected		Device connection status
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PARAMETER	
 *	S_UNKOWN_ERROR
 */
long IsConnected(bool* bConnected);
//////////////////////////////////////////////////////////////////////////
/* 2. Generate a Key-pair
 *  [in]  pPassword		Device Password
 *  [in]  lPublicKeyLen	Specify public key length: 1024 or 2048
 *  [out] ppPublicKey		Public key of the generated key-pair (format comply with the coding specification described in this document, contained n and e)
 * 
 * Returns:
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 */
long CreateRSAKey(char* pPassword, long lPublicKeyLen, pbyte ppPublicKey);

//////////////////////////////////////////////////////////////////////////
/* 3. Import Public Key Certificate
 * [in]	pCertificateDer		Public key X.509 encoding
 * [in]	lCertificateLen		Public key length
 *  
 * Returns:
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_CERTIFICATE
 *	S_INVALID_PARAMETER	
 *	S_UNKOWN_ERROR
 */
long ImportX509Certificate(pbyte pCertificate, long lCertificateLen);

//////////////////////////////////////////////////////////////////////////
/* 4. Digital Sign
 * [in]  pCertificate		Public key certificate corresponding to private key, and if RSA key pairs are just generated, use the public key value returned from createRSAkey function.
 * [in]  lCertificateLen	Public key length
 * [in]  pPassword			Device password
 * [in]  pSrcData			Source data to be signed
 * [in]  pSrcDataLen		length of source data to be signed
 * [in]  pHashOIDHash		Algorithm ID
 * [out] ppOutData			Signed data（PKCS1 format）
 * [out] lpOutDataLen		length of signed data（PKCS1 format）
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_INVALID_ALGORITHM
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 *	S_USER_CANCEL
 */
long SignData(pbyte pCertificate, long lCertificateLen, char* pPassword,
		pbyte pSrcData, long lSrcDataLen, char* pHashOID, pbyte ppOutData,
		long* lpOutDataLen);

//////////////////////////////////////////////////////////////////////////
/* 5. Decrypt Digital Envelope(Invalid now)
 * [in]  pCertificate		Public key certificate corresponding to the private key, which is the decrypting certificate
 * [in]  lCertificateLen	Public key length
 * [in]  pPassword			Device password
 * [in]  pInData			Ciphertext of digital envelope(include PKCS7 format and CMS format）
 * [in]  lInDataLen			length of ciphertext of digital envelope
 * [out] ppOutData			Original data of digital envelope
 * [out] lOutDataLen		length of original data of digital envelope
 *
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 */
long DecryptEnvelopeData(pbyte pCertificate, long lCertificateLen,
		char* pPassword, pbyte pIndata, long lInDataLen, pbyte ppOutData,
		long* lOutDataLen);

//////////////////////////////////////////////////////////////////////////
/* 6. Change Password
 * [in]  pCertificate		Public key certificate, and if it’s device password, ignore this parameter.
 * [in]  lCertificateLen	Public key length, and if it’s device password, ignore this parameter
 * [in]  pOldPwd			Old password
 * [in]  pNewPwd			New Password
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 *	If there is no certificate password, it changes device password.
 */
long ChangePassword(pbyte pCertificate, long lCertificateLen, char* pOldPwd,
		char* pNewPwd);

//////////////////////////////////////////////////////////////////////////
/* 7. Get DER Code of Public Key Certificate
 * [in,out]	ipCertificates		Number of certificates(the return value of the function when it is called at the first time )
 * [in,out]	lppCertificateLen	Length of every certificate(the return value of function when it is called at the second time)
 * [out]	ppCertificates		The two-dimension array of certificate DER encoding(the return value of the function that is called at the third time)
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 */
long GetX509Certificates(int* ipCertificates, long* lppCertificateLen,
		pbyte* ppCertificates);

//////////////////////////////////////////////////////////////////////////
/* 8. Get the Remaining Number of Password Attempts
 * [in]  pCertificate		Public key certificate, and if it’s device password, ignore this parameter.
 * [in]  lCertificateLen	Public key length, and if it’s device password, ignore this parameter
 * [out] ipRemaining		Number of password attempts
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 */
long GetPwdCanRetries(pbyte pCertificate, long lCertificateLen,
		int* ipRemaining);

//////////////////////////////////////////////////////////////////////////
/* 9. Get device Serial Number (the unique device serial number)
 * [out] ppDeviceSN			Device serial number
 * [out] lpDeviceSNLen		length of device serial number
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 */
long GetDeviceSerialNumber(char* ppDeviceSN, long* lpDeviceSNLen);

//////////////////////////////////////////////////////////////////////////
/* 10. Reset password function
 * [in] pNewPwd new password
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_INVALID_PARAMETER
 *	S_UNKOWN_ERROR
 *	If there is no certificate password, it changes device password
 */
long ResetPassword(char* pNewPwd);

//////////////////////////////////////////////////////////////////////////
/* 11. Verify PIN
 * [in,out] pOldPwd Old password, the first byte of the output records the remaining number of password attempts
 * 
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_INVALID_PASSWORD
 *	S_DEVICE_LOCK
 *	S_UNKOWN_ERROR
 */
long VerifyPassword(char* pOldPwd);

//////////////////////////////////////////////////////////////////////////
/* 12. Get random password
 * [in] randomLen the length of random number to be generated
 * [out] random Buffer
 * Returns: 
 *	S_OK
 *	S_DEVICE_FAILURE
 *	S_UNKOWN_ERROR
 */
long GetRandomNumber(int randomLen, char* random);

#ifdef __cplusplus
}
#endif

#endif  /* INTERFACE_H */
