import java.io.*;
/**
 * This class can take a variable number of parameters on the command
 * line. Program execution begins with the main() method. The class
 * constructor is not invoked unless an object of type 'Class1'
 * created in the main() method.
 */
public class Sense4Test
{
        public static void main (String[] args)
        {

                JavaSense4 sense4 = new JavaSense4();

                int [] size = new int[1];
                int ret = 0;
                int size1 = 10;
                byte lpInBuffer[] = {0x12, 0x34, 0x56, 0x78};
                byte FileID[] = {0x30, 0x30, 0x30, 0x31, 0x00};
                byte FileID1[] = {0x30, 0x30, 0x30, 0x32, 0x00};

                byte [] lpOutBuffer = new byte[20];
                int [] lpBytesReturned = {0};
                SENSE4_CONTEXT[] s4_context = new SENSE4_CONTEXT[0];

                ret = sense4.S4Startup();

                ret = sense4.S4Enum(null, size);

                s4_context = new SENSE4_CONTEXT[size[0] / 92];
                for (int i = 0;i< size[0] / 92; i++)
                {
                        s4_context[i] = new SENSE4_CONTEXT();
                }

                ret = sense4.S4Enum(s4_context, size);
                if (0 != ret)
                        System.out.print("enumerate SenseLock EL error");
                else
                        System.out.println("enumerate SenseLock EL success");

                S4OPENINFO s4_OpenInfo = new S4OPENINFO();
                s4_OpenInfo.dwS4OpenInfoSize = 8;
                s4_OpenInfo.dwShareMode = JavaSense4.S4_EXCLUSIZE_MODE;

                ret = sense4.S4OpenEx(s4_context[0], s4_OpenInfo);
                if (0 != ret)
                        System.out.print("pen SenseLock EL error");
                else
                        System.out.println("open SenseLock EL success");

                byte [] frequency = {0x04};
                ret = sense4.S4Control(s4_context[0], JavaSense4.S4_LED_WINK, frequency, 1, null, 0, lpBytesReturned);
                if (0 != ret)
                        System.out.print("SenseLock EL LED wink error");
                else
                        System.out.println("SenseLock EL LED wink success");

                byte [] Path = {(byte)'\\', 0x00};
                ret = sense4.S4ChangeDir (s4_context[0], Path);
                if (0 != ret)
                        System.out.print("change dir error");
                else
                        System.out.println("change dir success");

                ret = sense4.S4VerifyPin(s4_context[0], ((String)"123456781234567812345678").getBytes(), 24, JavaSense4.S4_DEV_PIN);
                if (0 != ret)
                        System.out.print("verify dev pin error");
                else
                        System.out.println("verify dev pin success");

                ret = sense4.S4EraseDir(s4_context[0], null);
                if (0 != ret)
                        System.out.print("erase MF error");
                else
                        System.out.println("erase MF success");

                S4CREATEDIRINFO s4_CreateDirInfo = new S4CREATEDIRINFO();
                s4_CreateDirInfo.dwS4CreateDirInfoSize = 12;
                s4_CreateDirInfo.szAtr[0] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[1] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[2] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[3] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[4] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[5] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[6] = (byte)0xFF;
                s4_CreateDirInfo.szAtr[7] = (byte)0xFF;

                ret = sense4.S4CreateDirEx(s4_context[0], Path, 0, JavaSense4.S4_CREATE_ROOT_DIR,s4_CreateDirInfo );
                if (0 != ret)
                        System.out.print("create MF error");
                else
                        System.out.println("create MF success");

                ret = sense4.S4ChangePin(s4_context[0], ((String)"12345678").getBytes (), 8, ((String)"11111111").getBytes (), 8, JavaSense4.S4_USER_PIN );
                if (0 != ret)
                        System.out.print("change user pin error");
                else
                        System.out.println("change user pin success");

                ret = sense4.S4VerifyPin (s4_context[0], ((String)"123456781234567812345678").getBytes (), 24, JavaSense4.S4_DEV_PIN );
                if (0 != ret)
                        System.out.print("verify dev pin error");
                else
                        System.out.println("verify dev pin success");

                File demofile = new File("demo_v20.bin");
                long contentsize = demofile.length ();
                byte [] content = new byte[1];
                try
                {
                        FileInputStream is = new FileInputStream (demofile);
                        content = new byte[(int)contentsize];
                        is.read(content, 0, (int)contentsize);
                        is.close();
                }
                catch(Exception e)
                {
                        System.out.print("read demo_v20.bin error");
                }


                ret = sense4.S4WriteFile (s4_context[0], FileID, 0, content, (int)contentsize, 1000, lpBytesReturned,
                                                                  JavaSense4.S4_CREATE_NEW , (byte)JavaSense4.S4_EXE_FILE );
                if (0 != ret)
                        System.out.print("write demo_v20.bin error");
                else
                        System.out.println("write demo_v20.bin success");

                File demofile1 = new File("demo_v30.bin");
                long cntsize = demofile1.length ();
                byte [] cnt = new byte[1];
                try
                {
                        FileInputStream fIs = new FileInputStream (demofile1);
                        cnt = new byte[(int)cntsize];
                        fIs.read(cnt, 0, (int)cntsize);
                        fIs.close();
                }
                catch(Exception e)
                {
                        System.out.print("read demo_v30.bin error");

                }

                ret = sense4.S4WriteFile (s4_context[0], FileID1, 0, cnt, (int)cntsize, 1000, lpBytesReturned,
                                                                  JavaSense4.S4_CREATE_NEW , (byte)JavaSense4.S4_XA_EXE_FILE );
                if (0 != ret)
                        System.out.print("write demo_v20.bin error");
                else
                        System.out.println("write demo_v30.bin success");

                ret = sense4.S4VerifyPin(s4_context[0], ((String)"11111111").getBytes(), 8, JavaSense4.S4_USER_PIN);
                if (0 != ret)
                        System.out.print("verify user pin error");
                else
                        System.out.println("verify user pin success");

                ret = sense4.S4ExecuteEx(s4_context[0], FileID, JavaSense4.S4_VM_EXE, lpInBuffer, 4, lpOutBuffer, 20, lpBytesReturned);
                if (0 != ret)
                        System.out.print("execute demo_v20.bin error");
                else
                        System.out.println("execute demo_v20.bin success");


                ret = sense4.S4ExecuteEx(s4_context[0], FileID1, JavaSense4.S4_XA_EXE, lpInBuffer, 4, lpOutBuffer, 20, lpBytesReturned);
                if (0 != ret)
                        System.out.print("execute demo_v30.bin error");
                else
                        System.out.println("execute demo_v30.bin success");

                ret = sense4.S4Control (s4_context[0], JavaSense4.S4_LED_DOWN, null, 0, null, 0, lpBytesReturned);
                if (0 != ret)
                        System.out.print("LED down error");
                else
                        System.out.println("LED down success");

                ret = sense4.S4Close(s4_context[0]);
                if (0 != ret)
                        System.out.print("close SenseLock EL error");
                else
                        System.out.print("close SenseLock EL success");

                ret = sense4.S4Cleanup ();
        }
}

class JavaSense4
{        

        /** file types defintion*/
        public static int S4_RSA_PUBLIC_FILE		=0x00000006;
        public static int S4_RSA_PRIVATE_FILE		=0x00000007;
        public static int S4_EXE_FILE				=0x00000008;
        public static int S4_DATA_FILE				=0x00000009;
        public static int S4_XA_EXE_FILE			=0x0000000b;		

        /** PIN defined */
        public static int S4_USER_PIN				=0x000000a1;
        public static int S4_DEV_PIN				=0x000000a2;
        public static int S4_AUTHEN_PIN				=0x000000a3;

        /** flag defined */
        public static int S4_CREATE_NEW				=0x000000a5;
        public static int S4_UPDATE_FILE			=0x000000a6;
        public static int S4_KEY_GEN_RSA_FILE		=0x000000a7;
        public static int S4_SET_LICENCES			=0x000000a8;
        public static int S4_CREATE_ROOT_DIR		=0x000000ab;
        public static int S4_CREATE_SUB_DIR			=0x000000ac;
        public static int S4_CREATE_MODULE			=0x000000ad;
        public static int S4_FILE_READ_WRITE        =0x00000000;       
        public static int S4_FILE_EXECUTE_ONLY      =0x00000100;       
        public static int S4_CREATE_PEDDING_FILE	=0x00002000;		
        
        public static int S4_EXCLUSIZE_MODE			=0;
        public static int S4_SHARE_MODE				=1;

        /**  ctlCode definition for S4Control*/
        public static int S4_GET_DEVICE_TYPE		=0x00000025;	
        public static int S4_GET_VM_TYPE			=0x00000027;	
        public static int S4_RESET_DEVICE           =0x00000002;	
        public static int S4_DF_AVAILABLE_SPACE     =0x00000031;	
        public static int S4_EF_INFO                =0x00000032;	
        public static int S4_LED_UP					=0x00000004;	
        public static int S4_LED_DOWN				=0x00000008;	
        public static int S4_LED_WINK				=0x00000028;	
        public static int S4_GET_SERIAL_NUMBER		=0x00000026;	
        public static int S4_GET_DEVICE_USABLE_SPACE=0x00000029;	
        public static int S4_SET_DEVICE_ID			=0x0000002a;	


        //device type definition
        public static int S4_LOCAL_DEVICE			=0x00;		
        public static int S4_MASTER_DEVICE			=0x80;		
        public static int S4_SLAVE_DEVICE			=0xc0;		

        /** VM type definition
        public static int S4_VM_51					=0x00;		/** VM51 */
        public static int S4_VM_251_BINARY			=0x01;		/** VM251 binary */
        public static int S4_VM_251_SOURCE	    	=0X02;		/** VM251 source */


        
        public static int S4_VM_EXE					=0x00000000;		
        public static int S4_XA_EXE					=0x00000001;		


        /**	Return	Code */
        public static int S4_SUCCESS				=0x00000000;		/** success */
        public static int S4_UNPOWERED				=0x00000001;
        public static int S4_INVALID_PARAMETER		=0x00000002;
        public static int S4_COMM_ERROR				=0x00000003;
        public static int S4_PROTOCOL_ERROR			=0x00000004;
        public static int S4_DEVICE_BUSY			=0x00000005;
        public static int S4_KEY_REMOVED			=0x00000006;
        public static int S4_INSUFFICIENT_BUFFER	=0x00000011;
        public static int S4_NO_LIST				=0x00000012;
        public static int S4_GENERAL_ERROR			=0x00000013;
        public static int S4_UNSUPPORTED			=0x00000014;
        public static int OPEN_LOG_FILE_ERROR		=0x00000015;
        public static int S4_DEVICE_TYPE_MISMATCH	=0x00000020;
        public static int S4_FILE_SIZE_CROSS_7FFF	=0x00000021;
        public static int S4_DEVICE_UNSUPPORTED		=0x00006a81;
        public static int S4_FILE_NOT_FOUND			=0x00006a82;
        public static int S4_INSUFFICIENT_SECU_STATE=0x00006982;
        public static int S4_DIRECTORY_EXIST		=0x00006901;
        public static int S4_FILE_EXIST				=0x00006a80;
        public static int S4_INSUFFICIENT_SPACE		=0x00006a84;
        public static int S4_OFFSET_BEYOND			=0x00006B00;
        public static int S4_PIN_BLOCK				=0x00006983;
        public static int S4_FILE_TYPE_MISMATCH		=0x00006981;
        public static int S4_CRYPTO_KEY_NOT_FOUND	=0x00009403;
        public static int S4_APPLICATION_TEMP_BLOCK	=0x00006985;
        public static int S4_APPLICATION_PERM_BLOCK	=0x00009303;
        public static int S4_DATA_BUFFER_LENGTH_ERROR=0x00006700;
        public static int S4_CODE_RANGE				=0x00010000;
        public static int S4_CODE_RESERVED_INST		=0x00020000;
        public static int S4_CODE_RAM_RANGE			=0x00040000;
        public static int S4_CODE_BIT_RANGE			=0x00080000;
        public static int S4_CODE_SFR_RANGE			=0x00100000;
        public static int S4_CODE_XRAM_RANGE		=0x00200000;
        public static int S4_ERROR_UNKNOWN			=0xffffffff;

        /** functions */
        public native int S4Startup();

        public native int S4Cleanup();

        public native int S4Enum(SENSE4_CONTEXT[] s4_context,
                                                         int[] size);

        public native int S4Open(SENSE4_CONTEXT s4_context);

        public native int S4OpenEx(SENSE4_CONTEXT s4_context,
                                                           S4OPENINFO S4OpenInfo);

        public native int S4Close(SENSE4_CONTEXT s4_context);

        public native int S4Control(SENSE4_CONTEXT s4_context,
                                                                int ctlCode,
                                                                byte[] inBuff,
                                                                int inBuffLen,
                                                                byte[] outBuff,
                                                                int outBuffLen,
                                                                int[] bytesReturned);

        public native int S4CreateDir(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpszDirID,
                                                                  int dwDirSize,
                                                                  int dwFlags);

        public native int S4CreateDirEx(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpszDirID,
                                                                  int dwDirSize,
                                                                  int dwFlags,
                                                                  S4CREATEDIRINFO CreateDirInfo);

        public native int S4ChangeDir(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpszPath);

        public native int S4EraseDir(SENSE4_CONTEXT s4_context,
                                                                 byte[] lpszDirID);

        public native int S4VerifyPin(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpPin,
                                                                  int dwPinLen,
                                                                  int dwPinType);

        public native int S4ChangePin(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpOldPin,
                                                                  int dwOldPinLen,
                                                                  byte[] lpNewPin,
                                                                  int dwNewPinLen,
                                                                  int dwPinType);

        public native int S4WriteFile(SENSE4_CONTEXT s4_context,
                                                                  byte[] lpszFileID,
                                                                  int dwOffset,
                                                                  byte[] byteBuffer,
                                                                  int dwBufferSize,
                                                                  int dwFileSize,
                                                                  int[] lpBytesWritten,
                                                                  int dwFlags,
                                                                  byte bFileType);

        public native int S4Execute(SENSE4_CONTEXT s4_context,
                                                                byte[] lpszFileID,
                                                                byte[] lpInbuffer,
                                                                int dwInbufferSize,
                                                                byte[] lpOutBuffer,
                                                                int dwOutBufferSize,
                                                                int[] lpBytesReturned);

        public native int S4ExecuteEx(SENSE4_CONTEXT s4_context,
                                                                byte[] lpszFileID,
                                                                int    dwFlag,
                                                                byte[] lpInbuffer,
                                                                int dwInbufferSize,
                                                                byte[] lpOutBuffer,
                                                                int dwOutBufferSize,
                                                                int[] lpBytesReturned);

        static {
                System.loadLibrary("JavaSense4");
        }
}


class SENSE4_CONTEXT
{
        public int dwIndex;
        public int dwVersion;
        public int hLock;
        public byte[] reserve;
        public byte[] bAtr;
        public byte[] bID;
        public int dwAtrLen;
        SENSE4_CONTEXT()
        {
                reserve = new byte[12];
                bAtr = new byte[56];
                bID = new byte[8];
        }
}

class EFINFO
{
        public short EfID;
        public byte EfType;
        public short EfSize;
}

class S4OPENINFO
{
        public int dwS4OpenInfoSize;
        public int dwShareMode;
}

class S4CREATEDIRINFO
{
        public int dwS4CreateDirInfoSize;
        byte [] szAtr;
        S4CREATEDIRINFO()
        {
                szAtr = new byte[8];
        }
}




