//
// ObjectARX defined commands
#include "StdAfx.h"
#include "StdArx.h"
#include "Sense4.h"
#include <assert.h>

#define ASSERT(x) assert(x)
#define VM_BIN_LENGTH 372
#define XA_BIN_LENGTH 253

//demo_v20.bin and Demo_v30.bin should be put in C:\.
static char sBin[] = "C:\\demo_v20.bin";
static char sBin1[] = "C:\\demo_v30.bin";

#define printf(x) acutPrintf(x)

BOOL ReadFile(char* filename, BYTE* pbBuffer, DWORD dwLen)
{
	FILE *filein = NULL;
	
	if(!pbBuffer) return FALSE;
	
	if((filein = fopen(filename, "rb")) == NULL)
	{
		return FALSE;
	}
	else
	{
		if( fread( pbBuffer, 1, dwLen, filein ) <= 0)
		{
			return FALSE;
		}
		else
		{
			fclose(filein);
			return TRUE;
		}
	}
}

DWORD S4TestInit()
{
	
	DWORD dwRet = S4_ERROR_UNKNOWN;
	DWORD ulSize = 0;
	BYTE pbInBuffer[] = "\x31\x32\x33\x34";
	SENSE4_CONTEXT * pstS4Ctx = NULL;
	BYTE * pbBuffer = NULL;
	BYTE *pbOutBuffer = NULL;
	DWORD dwOutLen = 4;
	DWORD dwReturnLen = 0;
		
	dwRet = S4Enum(NULL, &ulSize);	
	
	pstS4Ctx = (SENSE4_CONTEXT *)malloc(ulSize);
	if(S4_SUCCESS != (dwRet = S4Enum(pstS4Ctx, &ulSize)))
		goto Err;
	else
	{
		printf("Enumerate device success!\n");
	}
	
	S4OPENINFO s4OpenInfo;
	s4OpenInfo.dwS4OpenInfoSize = sizeof(S4OPENINFO);
	s4OpenInfo.dwShareMode = S4_EXCLUSIZE_MODE;
	if(S4_SUCCESS != (dwRet = S4OpenEx(pstS4Ctx,&s4OpenInfo)))
	{
		acutPrintf("S4Open return 0x%08X", dwRet);
		goto Err;
	}
	else
	{
		printf("Open device success!\n");
	}
	
	dwRet = S4ChangeDir(pstS4Ctx, "\\");
	if(S4_SUCCESS == (dwRet = S4VerifyPin(pstS4Ctx, (unsigned char *)"123456781234567812345678", 24, S4_DEV_PIN)))
	{

		printf("Verify Dev PIN success!\n");
		if (S4_SUCCESS == (dwRet = S4EraseDir(pstS4Ctx, NULL)))
		{
			printf("Erase root dir success!\n");
		}
	}	
	
	S4CREATEDIRINFO s4CreateDirInfo;
	s4CreateDirInfo.dwS4CreateDirInfoSize = sizeof(S4CREATEDIRINFO);
	memcpy(s4CreateDirInfo.szAtr, "SENSE400", 8);
	if(S4_SUCCESS != (dwRet = S4CreateDirEx(pstS4Ctx, "\\", 0, S4_CREATE_ROOT_DIR, &s4CreateDirInfo)))
		goto Err;
	else
	{
		printf("Create MF success!\n");
	}	
	
	if (S4_SUCCESS != (dwRet = S4ChangePin(pstS4Ctx, (unsigned char *)"12345678", 8, (unsigned char *)"11111111", 8, S4_USER_PIN)))
		goto Err;
	else
	{
		printf("Change User PIN success!\n");
	}
	

	if (S4_SUCCESS != (dwRet = S4VerifyPin(pstS4Ctx, (unsigned char *)"123456781234567812345678", 24, S4_DEV_PIN)))
		goto Err;
	else
	{
		printf("Verify Dev PIN success!\n");
	}
	
	pbBuffer = (BYTE *)malloc(VM_BIN_LENGTH);
	if(!ReadFile(sBin, pbBuffer, VM_BIN_LENGTH))
	{
		printf("Read demo_v20.bin Error!\n");
		goto Err;
	}
	
	dwRet = S4WriteFile(pstS4Ctx, "1001", 0, pbBuffer, VM_BIN_LENGTH, 1000, &dwReturnLen, S4_CREATE_NEW, S4_EXE_FILE);
	ASSERT(dwRet == S4_SUCCESS);
	ASSERT(dwReturnLen == VM_BIN_LENGTH);
	printf("Write file 1001 success!\n");

	if (NULL != pbBuffer)
		free(pbBuffer);
	pbBuffer = NULL;

	pbBuffer = (BYTE *)malloc(XA_BIN_LENGTH);
	if(!ReadFile(sBin1, pbBuffer, XA_BIN_LENGTH))
	{
		printf("Read demo_v30.bin Error!\n");
		goto Err;
	}

	
	dwRet = S4WriteFile(pstS4Ctx, "1002", 0, pbBuffer, XA_BIN_LENGTH, 1000, &dwReturnLen, S4_CREATE_NEW, S4_XA_EXE_FILE);
	ASSERT(dwRet == S4_SUCCESS);
	ASSERT(dwReturnLen == XA_BIN_LENGTH);
	printf("Write file 1002 success!\n");
	

	pbOutBuffer = (BYTE *)malloc(4);
	
	dwRet = S4VerifyPin(pstS4Ctx, (unsigned char*)"11111111", 8, S4_USER_PIN);
	ASSERT(S4_SUCCESS == dwRet);
	
	dwReturnLen = 0;
	dwRet = S4ExecuteEx(pstS4Ctx, "1001", S4_VM_EXE, pbInBuffer, 4, pbOutBuffer, dwOutLen, &dwReturnLen);
	ASSERT(dwRet == S4_SUCCESS);
	ASSERT(pbOutBuffer[1] == 0x63);
	ASSERT(pbOutBuffer[3] == 0x67);
	printf("Execute file 1001 success!\n");

	dwRet = S4ExecuteEx(pstS4Ctx, "1002", S4_XA_EXE, pbInBuffer, 4, pbOutBuffer, dwOutLen, &dwReturnLen);
	ASSERT(dwRet == S4_SUCCESS);
	ASSERT(pbOutBuffer[0] == 0x63);
	ASSERT(pbOutBuffer[2] == 0x67);
	printf("Execute file 1002 success!\n");
	
	if(S4_SUCCESS != (dwRet = S4VerifyPin(pstS4Ctx, (unsigned char *)"123456781234567812345678", 24, S4_DEV_PIN)))
		goto Err;
	else
	{
		printf("Verify Dev PIN success!\n");
	}
	
	
	if(S4_SUCCESS != (dwRet = S4EraseDir(pstS4Ctx, NULL)))
		goto Err;
	else
	{
		printf("Erase root dir success!\n");
	}
	
	if(S4_SUCCESS != (dwRet = S4Close(pstS4Ctx)))
		goto Err;
	else
	{
		printf("Close device!\n");
	}	
	
Err:
	if(S4_SUCCESS == (dwRet = S4Close(pstS4Ctx)))
	{
		printf("Close device!\n");
	}

	if(pstS4Ctx)
	{
		free(pstS4Ctx);
		pstS4Ctx = NULL;
	}
	if (pbBuffer)
	{
		free(pbBuffer);
		pbBuffer = NULL;
	}
	if (pbOutBuffer)
	{
		free(pbOutBuffer);
		pbOutBuffer = NULL;
	}
	return dwRet;
	
}


// This is command 'TEST'
void S4TEST()
{
	// TODO: Implement the command
	
	S4TestInit();
}

