You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.4 KiB
277 lines
8.4 KiB
package Sense4; |
|
|
|
import java.io.File; |
|
import java.io.FileInputStream; |
|
|
|
import Sense4.Sense32.S4CREATEDIRINFO; |
|
import Sense4.Sense32.S4OPENINFO; |
|
import Sense4.Sense32.SENSE4_CONTEXT; |
|
|
|
import com.sun.jna.ptr.IntByReference; |
|
|
|
/** |
|
* @author Lanlan |
|
* @date 2018/11/25 |
|
*/ |
|
public class EliteLockIO32 implements EliteLockIO { |
|
public static final int MAX_BUFF_SIZE = 0xf0; |
|
public static final byte WRITE = 0; |
|
public static final byte READ = 1; |
|
|
|
public SENSE4_CONTEXT ctx= new SENSE4_CONTEXT();//[] = new Sense4.SENSE4_CONTEXT[2]; |
|
|
|
public Sense32 lib = Sense32.instance; |
|
|
|
public EliteLockIO32() {} |
|
|
|
public void initS4(boolean changeDir) { |
|
IntByReference pSize = new IntByReference(0); |
|
|
|
int ret = lib.S4Enum(ctx, pSize); |
|
ret = lib.S4Enum(ctx, pSize); |
|
if(ret!=0) |
|
{ |
|
System.out.println("列举设备失败!"); |
|
} |
|
|
|
ret = lib.S4Open(ctx); |
|
if(ret!=0) |
|
{ |
|
System.out.println("打开设备失败!"); |
|
} |
|
|
|
if (changeDir) { |
|
ret = lib.S4ChangeDir(ctx, "\\"); |
|
if(ret!=0) |
|
{ |
|
System.out.println("切换目录失败!"); |
|
lib.S4Close(ctx); |
|
} |
|
|
|
ret = lib.S4VerifyPin(ctx, "12345678", 8, lib.S4_USER_PIN); |
|
if(ret!=0) |
|
{ |
|
System.out.println("校验用户pin失败!"); |
|
lib.S4Close(ctx); |
|
} |
|
} |
|
|
|
} |
|
|
|
public void closeS4() { |
|
int ret = lib.S4Close(ctx); |
|
|
|
if(ret!=0) |
|
{ |
|
System.out.println("关闭设备失败!"); |
|
} |
|
} |
|
|
|
public boolean write_internal_file(int offset, int write_len, byte[] write_bytes) { |
|
int write_offset = offset; |
|
int old_offset = write_offset; |
|
|
|
byte inBuffer[]=new byte[0xf8]; |
|
byte outBuffer[]=new byte[0xf8]; |
|
IntByReference pdwByteOut = new IntByReference(0); |
|
|
|
inBuffer[0]=WRITE; |
|
|
|
while (write_len > 0) { |
|
old_offset = write_offset; |
|
|
|
inBuffer[2]=(byte)((write_offset >> 8) & 0xFF); |
|
inBuffer[3]=(byte)(write_offset & 0xFF); |
|
|
|
if (write_len <= MAX_BUFF_SIZE) { |
|
System.arraycopy(write_bytes, old_offset - offset, inBuffer, 4, write_len); |
|
inBuffer[1] = (byte)(write_len & 0xFF); |
|
write_len = 0; |
|
write_offset += write_len; |
|
} else { |
|
System.arraycopy(write_bytes, old_offset - offset, inBuffer, 4, MAX_BUFF_SIZE); |
|
inBuffer[1] = (byte)MAX_BUFF_SIZE; |
|
write_len -= MAX_BUFF_SIZE; |
|
write_offset += MAX_BUFF_SIZE; |
|
} |
|
|
|
int ret = lib.S4Execute(ctx,"ef21",inBuffer,0xf8,outBuffer,0xf8, pdwByteOut); |
|
if(ret!=0) |
|
{ |
|
System.out.println("执行锁内程序失败!"); |
|
lib.S4Close(ctx); |
|
|
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public byte[] read_internal_file(int offset, int read_len) { |
|
if (read_len < 0) { |
|
throw new IllegalArgumentException(); |
|
} |
|
|
|
int read_offset = offset; |
|
int old_offset = read_offset; |
|
|
|
byte[] out = new byte[read_len]; |
|
IntByReference pdwByteOut = new IntByReference(0); |
|
byte inBuffer[]=new byte[0xf8]; |
|
byte outBuffer[]=new byte[0xf8]; |
|
inBuffer[0]=READ; |
|
|
|
while (read_len > 0) { |
|
old_offset = read_offset; |
|
|
|
// big-edian |
|
inBuffer[2]=(byte)((read_offset >> 8) & 0xFF); |
|
inBuffer[3]=(byte)(read_offset & 0xFF); |
|
|
|
if (read_len <= MAX_BUFF_SIZE) { |
|
inBuffer[1] = (byte)read_len; |
|
read_len = 0; |
|
read_offset += read_len; |
|
} else { |
|
inBuffer[1] = (byte)MAX_BUFF_SIZE; |
|
read_len -= MAX_BUFF_SIZE; |
|
read_offset += MAX_BUFF_SIZE; |
|
} |
|
|
|
int ret = lib.S4Execute(ctx, "ef21",inBuffer,0xf8,outBuffer,0xf8,pdwByteOut); |
|
if(ret!=0 || pdwByteOut.getValue() < inBuffer[1]) |
|
{ |
|
System.out.println("执行锁内程序失败!"); |
|
lib.S4Close(ctx); |
|
} else { |
|
System.arraycopy(outBuffer, 0, out, old_offset - offset, pdwByteOut.getValue()); |
|
} |
|
} |
|
|
|
return out; |
|
} |
|
|
|
public boolean uploadHexExeFile() { |
|
Sense32 lib = Sense32.instance; |
|
|
|
IntByReference pSize = new IntByReference(0); |
|
int ret = 0; |
|
long errorCount = 0; |
|
|
|
IntByReference lpBytesReturned = new IntByReference(0); |
|
SENSE4_CONTEXT[] s4_context = new SENSE4_CONTEXT[0]; |
|
|
|
ret = lib.S4Enum(null, pSize); |
|
|
|
s4_context = new SENSE4_CONTEXT[pSize.getValue() / 92]; |
|
for (int i = 0;i< pSize.getValue() / 92; i++){ |
|
s4_context[i] = new SENSE4_CONTEXT(); |
|
} |
|
|
|
ret = lib.S4Enum(s4_context[0], pSize); |
|
checkS4ExceptionResult(ret, "Enumerate Sense4"); |
|
errorCount += ret; |
|
|
|
S4OPENINFO s4_OpenInfo = new S4OPENINFO(); |
|
s4_OpenInfo.dwS4OpenInfoSize = 8; |
|
s4_OpenInfo.dwShareMode = lib.S4_EXCLUSIZE_MODE; |
|
|
|
ret = lib.S4OpenEx(s4_context[0], s4_OpenInfo); |
|
checkS4ExceptionResult(ret, "Open Sense4"); |
|
errorCount += ret; |
|
|
|
byte [] frequency = {0x04}; |
|
ret = lib.S4Control(s4_context[0], lib.S4_LED_WINK, frequency, 1, null, 0, lpBytesReturned); |
|
checkS4ExceptionResult(ret, "Sense4 LED wink"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4ChangeDir (s4_context[0], "\\"); |
|
checkS4ExceptionResult(ret, "Change Dir"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4VerifyPin(s4_context[0], "123456781234567812345678", 24, lib.S4_DEV_PIN); |
|
checkS4ExceptionResult(ret, "Verify dev pin"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4EraseDir(s4_context[0], null); |
|
checkS4ExceptionResult(ret, "Erase MF"); |
|
errorCount += ret; |
|
|
|
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 = lib.S4CreateDirEx(s4_context[0], "\\", 0, lib.S4_CREATE_ROOT_DIR,s4_CreateDirInfo); |
|
checkS4ExceptionResult(ret, "Create MF"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4VerifyPin (s4_context[0], "123456781234567812345678", 24, lib.S4_DEV_PIN ); |
|
checkS4ExceptionResult(ret, "Verify Dev Pin"); |
|
errorCount += ret; |
|
|
|
// write bin file ef21 |
|
File demofile = new File("ReadData.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.println("error: read hex bing file "); |
|
} |
|
|
|
ret = lib.S4WriteFile (s4_context[0], "ef21", 0, content, (int)contentsize, (int)contentsize + 20, lpBytesReturned, |
|
lib.S4_CREATE_NEW , lib.S4_EXE_FILE ); |
|
checkS4ExceptionResult(ret, "Write hex bin file"); |
|
errorCount += ret; |
|
|
|
// write data file bf21 |
|
byte[] data_file = new byte[0x6000]; |
|
|
|
ret = lib.S4WriteFile (s4_context[0], "bf21", 0, data_file, (int)data_file.length, (int)data_file.length + 20, lpBytesReturned, |
|
lib.S4_CREATE_NEW , lib.S4_DATA_FILE ); |
|
checkS4ExceptionResult(ret, "Write data file"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4Control (s4_context[0], lib.S4_LED_DOWN, null, 0, null, 0, lpBytesReturned); |
|
checkS4ExceptionResult(ret, "LED Down"); |
|
errorCount += ret; |
|
|
|
ret = lib.S4Close(s4_context[0]); |
|
checkS4ExceptionResult(ret, "Close Sense4"); |
|
errorCount += ret; |
|
|
|
return errorCount == 0; |
|
} |
|
|
|
public byte[] readEliteSerial() { |
|
byte[] serial = new byte[8]; |
|
int ret = lib.S4Control(ctx, lib.S4_GET_SERIAL_NUMBER, null, 0, serial, 8, null); |
|
if (ret != 0) { |
|
System.out.println("S4_GET_SERIAL_NUMBER: " + ret); |
|
} |
|
|
|
return serial; |
|
} |
|
|
|
private static void checkS4ExceptionResult(int ret, String info) { |
|
if (ret != 0) { |
|
System.out.println("Error Code: " + ret + " Info:" + info); |
|
} else { |
|
System.out.println("Success: " + info); |
|
} |
|
} |
|
}
|
|
|