commit e9f484435240e32139145a44815eb0306d4f26f0 Author: leon <916117771@qq.com> Date: Tue Mar 31 08:51:33 2026 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac5aa98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..a77bebb --- /dev/null +++ b/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49" + channel: "stable" + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + - platform: android + create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..41cc7d8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c2b3b2 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# zhiwen + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/developing-packages/), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter development, view the +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..161bdcd --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..aa75089 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,60 @@ +group = "com.xiarui.zhiwen" +version = "1.0" + +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath("com.android.tools.build:gradle:7.3.0") + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: "com.android.library" + +android { + if (project.android.hasProperty("namespace")) { + namespace = "com.xiarui.zhiwen" + } + + compileSdk = 34 + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + defaultConfig { + minSdk = 21 + } + + sourceSets { + main { + jniLibs.srcDirs = ['libs'] + } + } + + dependencies { + testImplementation("junit:junit:4.13.2") + testImplementation("org.mockito:mockito-core:5.0.0") + } + + testOptions { + unitTests.all { + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + outputs.upToDateWhen {false} + showStandardStreams = true + } + } + } +} diff --git a/android/libs/arm64-v8a/libserial_port.so b/android/libs/arm64-v8a/libserial_port.so new file mode 100644 index 0000000..3659c4c Binary files /dev/null and b/android/libs/arm64-v8a/libserial_port.so differ diff --git a/android/libs/armeabi-v7a/libserial_port.so b/android/libs/armeabi-v7a/libserial_port.so new file mode 100644 index 0000000..9a5aeb9 Binary files /dev/null and b/android/libs/armeabi-v7a/libserial_port.so differ diff --git a/android/libs/armeabi/libserial_port.so b/android/libs/armeabi/libserial_port.so new file mode 100644 index 0000000..15417c6 Binary files /dev/null and b/android/libs/armeabi/libserial_port.so differ diff --git a/android/libs/x86/libserial_port.so b/android/libs/x86/libserial_port.so new file mode 100644 index 0000000..6a1ce79 Binary files /dev/null and b/android/libs/x86/libserial_port.so differ diff --git a/android/libs/x86_64/libserial_port.so b/android/libs/x86_64/libserial_port.so new file mode 100644 index 0000000..bc31e32 Binary files /dev/null and b/android/libs/x86_64/libserial_port.so differ diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..bd3eb06 --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'zhiwen' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..026ef5e --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/android/src/main/java/android_serialport_api/ComBean.java b/android/src/main/java/android_serialport_api/ComBean.java new file mode 100644 index 0000000..48b1f89 --- /dev/null +++ b/android/src/main/java/android_serialport_api/ComBean.java @@ -0,0 +1,21 @@ +package android_serialport_api; + +import java.text.SimpleDateFormat; + +/** + * @author benjaminwan + */ +public class ComBean { + public byte[] bRec=null; + public String sRecTime=""; + public String sComPort=""; + public int nSize = 0; + public ComBean(String sPort,byte[] buffer,int size){ + sComPort=sPort; + bRec=new byte[size]; + System.arraycopy(buffer, 0, bRec, 0, size); + nSize = size; + SimpleDateFormat sDateFormat = new SimpleDateFormat("hh:mm:ss"); + sRecTime = sDateFormat.format(new java.util.Date()); + } +} \ No newline at end of file diff --git a/android/src/main/java/android_serialport_api/SerialHelper.java b/android/src/main/java/android_serialport_api/SerialHelper.java new file mode 100644 index 0000000..ba21b94 --- /dev/null +++ b/android/src/main/java/android_serialport_api/SerialHelper.java @@ -0,0 +1,231 @@ +package android_serialport_api; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidParameterException; + +import com.xiarui.zhiwen.DevComm; + +import android_serialport_api.ComBean; +import android_serialport_api.SerialPort; + + +public abstract class SerialHelper{ + private SerialPort mSerialPort; + private OutputStream mOutputStream; + private InputStream mInputStream; + private ReadThread mReadThread; + private SendThread mSendThread; + private String sPort="/dev/s3c2410_serial0"; + private int iBaudRate=9600; + private boolean _isOpen=false; + private byte[] _bLoopData=new byte[]{0x30}; + private int iDelay=500; + //---------------------------------------------------- + public SerialHelper(String sPort,int iBaudRate){ + this.sPort = sPort; + this.iBaudRate=iBaudRate; + } + public SerialHelper(){ + this("/dev/s3c2410_serial0",9600); + } + public SerialHelper(String sPort){ + this(sPort,9600); + } + public SerialHelper(String sPort,String sBaudRate){ + this(sPort,Integer.parseInt(sBaudRate)); + } + //---------------------------------------------------- + public void open() throws SecurityException, IOException,InvalidParameterException{ + mSerialPort = new SerialPort(new File(sPort), iBaudRate, 0); + mOutputStream = mSerialPort.getOutputStream(); + mInputStream = mSerialPort.getInputStream(); + mReadThread = new ReadThread(); + mReadThread.start(); + mSendThread = new SendThread(); + mSendThread.setSuspendFlag(); + mSendThread.start(); + _isOpen=true; + } + //---------------------------------------------------- + public void close(){ + if (mReadThread != null) + mReadThread.interrupt(); + if (mSerialPort != null) { + mSerialPort.close(); + mSerialPort = null; + } + _isOpen=false; + } + //---------------------------------------------------- + public void send(byte[] bOutArray, int nSize){ + try + { + mOutputStream.write(bOutArray, 0, nSize); + } catch (IOException e) + { + e.printStackTrace(); + } + } + //---------------------------------------------------- + public void sendTxt(String sTxt){ + byte[] bOutArray =sTxt.getBytes(); + send(bOutArray, sTxt.length()); + } + //---------------------------------------------------- + private class ReadThread extends Thread { + @Override + public void run() { + super.run(); + while(!isInterrupted()) { + try + { + if (mInputStream == null) return; + byte[] buffer=new byte[DevComm.MAX_DATA_LEN]; + int size = mInputStream.read(buffer); + if (size > 0){ + ComBean ComRecData = new ComBean(sPort,buffer,size); + onDataReceived(ComRecData); + } + try + { + Thread.sleep(50); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } catch (Throwable e) + { + e.printStackTrace(); + return; + } + } + } + } + //---------------------------------------------------- + private class SendThread extends Thread{ + public boolean suspendFlag = true; + @Override + public void run() { + super.run(); + while(!isInterrupted()) { + synchronized (this) + { + while (suspendFlag) + { + try + { + wait(); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + send(getbLoopData(), 1); + try + { + Thread.sleep(iDelay); + } catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + + public void setSuspendFlag() { + this.suspendFlag = true; + } + + public synchronized void setResume() { + this.suspendFlag = false; + notify(); + } + } + //---------------------------------------------------- + public int getBaudRate() + { + return iBaudRate; + } + public boolean setBaudRate(int iBaud) + { + if (_isOpen) + { + return false; + } else + { + iBaudRate = iBaud; + return true; + } + } + public boolean setBaudRate(String sBaud) + { + int iBaud = Integer.parseInt(sBaud); + return setBaudRate(iBaud); + } + //---------------------------------------------------- + public String getPort() + { + return sPort; + } + public boolean setPort(String sPort) + { + if (_isOpen) + { + return false; + } else + { + this.sPort = sPort; + return true; + } + } + //---------------------------------------------------- + public boolean isOpen() + { + return _isOpen; + } + //---------------------------------------------------- + public byte[] getbLoopData() + { + return _bLoopData; + } + //---------------------------------------------------- + public void setbLoopData(byte[] bLoopData) + { + this._bLoopData = bLoopData; + } + //---------------------------------------------------- + public void setTxtLoopData(String sTxt){ + this._bLoopData = sTxt.getBytes(); + } + //---------------------------------------------------- + public int getiDelay() + { + return iDelay; + } + //---------------------------------------------------- + public void setiDelay(int iDelay) + { + this.iDelay = iDelay; + } + //---------------------------------------------------- + public void startSend() + { + if (mSendThread != null) + { + mSendThread.setResume(); + } + } + //---------------------------------------------------- + public void stopSend() + { + if (mSendThread != null) + { + mSendThread.setSuspendFlag(); + } + } + //---------------------------------------------------- + protected abstract void onDataReceived(ComBean ComRecData); +} \ No newline at end of file diff --git a/android/src/main/java/android_serialport_api/SerialPort.java b/android/src/main/java/android_serialport_api/SerialPort.java new file mode 100644 index 0000000..814d175 --- /dev/null +++ b/android/src/main/java/android_serialport_api/SerialPort.java @@ -0,0 +1,89 @@ +/* + * Copyright 2009 Cedric Priscal + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android_serialport_api; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import android.util.Log; + +public class SerialPort { + + private static final String TAG = "SerialPort"; + + /* + * Do not remove or rename the field mFd: it is used by native method close(); + */ + private final FileDescriptor mFd; + private final FileInputStream mFileInputStream; + private final FileOutputStream mFileOutputStream; + + public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { + + /* Check access permission */ + if (!device.canRead() || !device.canWrite()) { + try { + /* Missing read/write permission, trying to chmod the file */ + Process su; + su = Runtime.getRuntime().exec("/system/bin/su"); + String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + + "exit\n"; + su.getOutputStream().write(cmd.getBytes()); + if ((su.waitFor() != 0) || !device.canRead() + || !device.canWrite()) { + throw new SecurityException(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new SecurityException(); + } + } + + mFd = open(device.getAbsolutePath(), baudrate, flags); + if (mFd == null) { + Log.e(TAG, "native open returns null"); + throw new IOException(); + } + mFileInputStream = new FileInputStream(mFd); + mFileOutputStream = new FileOutputStream(mFd); + } + + // Getters and setters + public InputStream getInputStream() { + return mFileInputStream; + } + + public OutputStream getOutputStream() { + return mFileOutputStream; + } + + // JNI + private native static FileDescriptor open(String path, int baudrate, int flags); + public native void close(); + static { + try { + System.loadLibrary("serial_port"); + } catch (UnsatisfiedLinkError err) { + err.printStackTrace(); + } + } +} diff --git a/android/src/main/java/android_serialport_api/SerialPortFinder.java b/android/src/main/java/android_serialport_api/SerialPortFinder.java new file mode 100644 index 0000000..b8c377e --- /dev/null +++ b/android/src/main/java/android_serialport_api/SerialPortFinder.java @@ -0,0 +1,122 @@ +/* + * Copyright 2009 Cedric Priscal + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android_serialport_api; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.util.Iterator; +import java.util.Vector; + +import android.util.Log; + +public class SerialPortFinder { + + public class Driver { + public Driver(String name, String root) { + mDriverName = name; + mDeviceRoot = root; + } + private final String mDriverName; + private final String mDeviceRoot; + Vector mDevices = null; + public Vector getDevices() { + if (mDevices == null) { + mDevices = new Vector(); + File dev = new File("/dev"); + File[] files = dev.listFiles(); + int i; + for (i=0; i mDrivers = null; + + Vector getDrivers() throws IOException { + if (mDrivers == null) { + mDrivers = new Vector(); + LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers")); + String l; + while((l = r.readLine()) != null) { + // Issue 3: + // Since driver name may contain spaces, we do not extract driver name with split() + String drivername = l.substring(0, 0x15).trim(); + String[] w = l.split(" +"); + if ((w.length >= 5) && (w[w.length-1].equals("serial"))) { + Log.d(TAG, "Found new driver " + drivername + " on " + w[w.length-4]); + mDrivers.add(new Driver(drivername, w[w.length-4])); + } + } + r.close(); + } + return mDrivers; + } + + public String[] getAllDevices() { + Vector devices = new Vector(); + // Parse each driver + Iterator itdriv; + try { + itdriv = getDrivers().iterator(); + while(itdriv.hasNext()) { + Driver driver = itdriv.next(); + Iterator itdev = driver.getDevices().iterator(); + while(itdev.hasNext()) { + String device = itdev.next().getName(); + String value = String.format("%s (%s)", device, driver.getName()); + devices.add(value); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return devices.toArray(new String[devices.size()]); + } + + public String[] getAllDevicesPath() { + Vector devices = new Vector(); + // Parse each driver + Iterator itdriv; + try { + itdriv = getDrivers().iterator(); + while(itdriv.hasNext()) { + Driver driver = itdriv.next(); + Iterator itdev = driver.getDevices().iterator(); + while(itdev.hasNext()) { + String device = itdev.next().getAbsolutePath(); + devices.add(device); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return devices.toArray(new String[devices.size()]); + } +} diff --git a/android/src/main/java/com/idworld/noemhost_and/DevComm.java b/android/src/main/java/com/idworld/noemhost_and/DevComm.java new file mode 100644 index 0000000..c52e13c --- /dev/null +++ b/android/src/main/java/com/idworld/noemhost_and/DevComm.java @@ -0,0 +1,1840 @@ +package com.idworld.noemhost_and; + +import android.app.Activity; +import android.content.Context; +import android.os.SystemClock; +import android.util.Log; +import android.widget.Spinner; +import android.widget.Toast; + +import java.io.IOException; +import java.security.InvalidParameterException; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; + +import android_serialport_api.ComBean; +import android_serialport_api.SerialHelper; + +/** + * Created by KMS on 2016/8/23. + */ +public class DevComm { + public static final int MAX_DATA_LEN = 2048; + public static final int IMAGE_DATA_UNIT = 496; + public static final int ID_NOTE_SIZE = 64; + public static final int MODULE_SN_LEN = 16; + public static final int CHAR_SPLIT_UNIT = 496; + public static final int CHAR_SPLIT_THR = 1024; + public static final int UART_MAX_BUF_SIZE = (500 * 1024); + public static final int UART_READ_TIMEOUT = 5000; + + private static final int SCSI_TIMEOUT = 5000; //ms + private static final int COMM_SLEEP_TIME = 40; //ms + + private static final int CMD_PACKET_LEN = 26; + private static final int RCM_PACKET_LEN = 26; + private static final int RCM_DATA_OFFSET = 10; + + /***************************************************************************/ + /***************************************************************************/ + private static final int CMD_PREFIX_CODE = 0xAA55; + private static final int CMD_DATA_PREFIX_CODE = 0xA55A; + private static final int RCM_PREFIX_CODE = 0x55AA; + private static final int RCM_DATA_PREFIX_CODE = 0x5AA5; + + /*************************************************************************** + * System Code (0x0000 ~ 0x001F, 0x0000 : Reserved) + ***************************************************************************/ + private static final short CMD_TEST_CONNECTION = 0x0001; + private static final short CMD_SET_PARAM = 0x0002; + private static final short CMD_GET_PARAM = 0x0003; + private static final short CMD_GET_DEVICE_INFO = 0x0004; + private static final short CMD_ENTER_ISPMODE = 0x0005; + private static final short CMD_SET_ID_NOTE = 0x0006; + private static final short CMD_GET_ID_NOTE = 0x0007; + private static final short CMD_SET_MODULE_SN = 0x0008; + private static final short CMD_GET_MODULE_SN = 0x0009; + + /*************************************************************************** + * Sensor Code (0x0020 ~ 0x003F) + ***************************************************************************/ + private static final short CMD_GET_IMAGE = 0x0020; + private static final short CMD_FINGER_DETECT = 0x0021; + private static final short CMD_UP_IMAGE = 0x0022; + private static final short CMD_DOWN_IMAGE = 0x0023; + private static final short CMD_SLED_CTRL = 0x0024; + + /*************************************************************************** + * Template Code (0x0040 ~ 0x005F) + ***************************************************************************/ + private static final short CMD_STORE_CHAR = 0x0040; + private static final short CMD_LOAD_CHAR = 0x0041; + private static final short CMD_UP_CHAR = 0x0042; + private static final short CMD_DOWN_CHAR = 0x0043; + private static final short CMD_DEL_CHAR = 0x0044; + private static final short CMD_GET_EMPTY_ID = 0x0045; + private static final short CMD_GET_STATUS = 0x0046; + private static final short CMD_GET_BROKEN_ID = 0x0047; + private static final short CMD_GET_ENROLL_COUNT = 0x0048; + + /*************************************************************************** + * FingerPrint Alagorithm Code (0x0060 ~ 0x007F) + ***************************************************************************/ + private static final short CMD_GENERATE = 0x0060; + private static final short CMD_MERGE = 0x0061; + private static final short CMD_MATCH = 0x0062; + private static final short CMD_SEARCH = 0x0063; + private static final short CMD_VERIFY = 0x0064; + + /*************************************************************************** + * Unknown Command + ***************************************************************************/ + private static final short RCM_INCORRECT_COMMAND = 0x00FF; + + /*************************************************************************** + * Error Code + ***************************************************************************/ + public static final int ERR_SUCCESS = 0; + public static final int ERR_FAIL = 1; + public static final int ERR_CONNECTION = 2; + public static final int ERR_VERIFY = 0x10; + public static final int ERR_IDENTIFY = 0x11; + public static final int ERR_TMPL_EMPTY = 0x12; + public static final int ERR_TMPL_NOT_EMPTY = 0x13; + public static final int ERR_ALL_TMPL_EMPTY = 0x14; + public static final int ERR_EMPTY_ID_NOEXIST = 0x15; + public static final int ERR_BROKEN_ID_NOEXIST = 0x16; + public static final int ERR_INVALID_TMPL_DATA = 0x17; + public static final int ERR_DUPLICATION_ID = 0x18; + public static final int ERR_BAD_QUALITY = 0x19; + public static final int ERR_MERGE_FAIL = 0x1A; + public static final int ERR_NOT_AUTHORIZED = 0x1B; + public static final int ERR_MEMORY = 0x1C; + public static final int ERR_INVALID_TMPL_NO = 0x1D; + public static final int ERR_INVALID_PARAM = 0x22; + public static final int ERR_GEN_COUNT = 0x25; + public static final int ERR_INVALID_BUFFER_ID = 0x26; + public static final int ERR_INVALID_OPERATION_MODE = 0x27; + public static final int ERR_FP_NOT_DETECTED = 0x28; + + /*************************************************************************** + * Parameter Index + ***************************************************************************/ + public static final int DP_DEVICE_ID = 0; + public static final int DP_SECURITY_LEVEL = 1; + public static final int DP_DUP_CHECK = 2; + public static final int DP_BAUDRATE = 3; + public static final int DP_AUTO_LEARN = 4; + + /*************************************************************************** + * Device ID, Security Level + ***************************************************************************/ + public static final int MIN_DEVICE_ID = 1; + public static final int MAX_DEVICE_ID = 255; + public static final int MIN_SECURITY_LEVEL = 1; + public static final int MAX_SECURITY_LEVEL = 5; + + public static final int GD_TEMPLATE_NOT_EMPTY = 0x01; + public static final int GD_TEMPLATE_EMPTY = 0x00; + + //--------------- For Usb Communication ------------// + public int m_nPacketSize; + public byte m_bySrcDeviceID = 1, m_byDstDeviceID = 1; + public byte[] m_abyPacket = new byte[64 * 1024]; + public byte[] m_abyPacket2 = new byte[64 * 1024]; + //--------------------------------------------------// + + private final Context mApplicationContext; + private final Activity m_parentAcitivity; + private static final int VID = 0x2009; + private static final int PID = 0x7638; + + private final UsbController m_usbBase; + + // Serial Port + private final DispQueueThread DispQueue; + private final SerialControl m_SerialPort; + + // uart variables + public byte[] m_pWriteBuffer; + public byte[] m_pReadBuffer; + public byte[] m_pUARTReadBuf; + public int m_nUARTReadPos = 0; + public int m_nUARTReceivePos = 0; + + // Connection + public byte m_nConnected; // 0 : Not Connected, 1 : ttyUART, 2 : USB + + public DevComm(Activity parentActivity, IUsbConnState usbConnState){ + m_parentAcitivity = parentActivity; + mApplicationContext = parentActivity.getApplicationContext(); + + // usb init + m_usbBase = new UsbController(parentActivity, usbConnState, VID, PID); + + // init variables + m_nConnected = 0; + m_nUARTReadPos = 0; + m_nUARTReceivePos = 0; + m_pWriteBuffer = new byte[DevComm.MAX_DATA_LEN]; + m_pReadBuffer = new byte[DevComm.MAX_DATA_LEN]; + m_pUARTReadBuf = new byte[DevComm.UART_MAX_BUF_SIZE]; + + // uart thread initialize + DispQueue = new DispQueueThread(); + DispQueue.start(); + m_SerialPort = new SerialControl(); + } + + public boolean IsInit(){ + if (m_nConnected == 0) + return false; + else if (m_nConnected == 1) + return true; + else if (m_nConnected == 2) + return m_usbBase.IsInit(); + + return false; + } + + public boolean OpenComm(String p_szDevice, int p_nBaudrate){ + if (m_nConnected != 0) + return false; + + if (p_szDevice == "USB") // usb mode + { + if (!m_usbBase.IsInit()) + m_usbBase.init(); + if (!m_usbBase.IsInit()) + return false; + m_nConnected = 2; + } + else // tty uart mode + { + m_SerialPort.setPort(p_szDevice); + m_SerialPort.setBaudRate(p_nBaudrate); + try + { + m_SerialPort.open(); + } catch (SecurityException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } catch (IOException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } catch (InvalidParameterException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } + m_nConnected = 1; + } + + return true; + } + + public boolean CloseComm(){ + if (m_nConnected == 0) { + return false; + } + else if (m_nConnected == 1) { // tty uart mode + m_SerialPort.stopSend(); + m_SerialPort.close(); + } + else { // usb mode + m_usbBase.uninit(); + } + + m_nConnected = 0; + return true; + } + + /************************************************************************/ + /************************************************************************/ + int Run_TestConnection() + { + boolean w_bRet; + + InitCmdPacket(CMD_TEST_CONNECTION, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, (short)0); + + w_bRet = Send_Command(CMD_TEST_CONNECTION); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_SetParam(int p_nParamIndex, int p_nParamValue) + { + boolean w_bRet; + byte[] w_abyData = new byte[5]; + + w_abyData[0] = (byte)p_nParamIndex; + + //memcpy(&w_abyData[1], &p_nParamValue, 4); + w_abyData[1] = (byte)(p_nParamValue & 0x000000ff); + w_abyData[2] = (byte)((p_nParamValue & 0x0000ff00) >> 8); + w_abyData[3] = (byte)((p_nParamValue & 0x00ff0000) >> 16); + w_abyData[4] = (byte)((p_nParamValue & 0xff000000) >> 24); + + InitCmdPacket(CMD_SET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)5); + + w_bRet = Send_Command(CMD_SET_PARAM); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetParam(int p_nParamIndex, int[] p_pnParamValue) + { + boolean w_bRet; + byte[] w_abyData = new byte[1]; + + w_abyData[0] = (byte)p_nParamIndex; + + InitCmdPacket(CMD_GET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)1); + + w_bRet = Send_Command(CMD_GET_PARAM); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memcpy(p_pnParamValue, g_pRcmPacket->m_abyData, 4); + p_pnParamValue[0] = ((m_abyPacket[RCM_DATA_OFFSET+3] << 24) & 0xFF000000) | + ((m_abyPacket[RCM_DATA_OFFSET+2] << 16) & 0x00FF0000) | + ((m_abyPacket[RCM_DATA_OFFSET+1] << 8) & 0x0000FF00) | + (m_abyPacket[RCM_DATA_OFFSET] & 0x000000FF); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetDeviceInfo(String[] p_szDevInfo) + { + int w_nDevInfoLen; + boolean w_bRet; + String w_strTmp; + byte[] w_szDevInfo; + + InitCmdPacket(CMD_GET_DEVICE_INFO, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_GET_DEVICE_INFO); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_nDevInfoLen = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + w_bRet = Receive_DataPacket(CMD_GET_DEVICE_INFO); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + //memcpy(p_szDevInfo, g_pRcmPacket->m_abyData, w_wDevInfoLen); + w_szDevInfo = new byte[w_nDevInfoLen]; + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, w_szDevInfo, 0, w_nDevInfoLen); + w_strTmp = new String(w_szDevInfo); + p_szDevInfo[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SetIDNote(int p_nTmplNo, String p_pstrNote) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[ID_NOTE_SIZE+2]; + byte[] w_abyData2 = new byte[2]; + byte[] w_abyNoteBuf = p_pstrNote.getBytes(); + + //. Assemble command packet + w_abyData2[0] = LOBYTE((short)(ID_NOTE_SIZE + 2)); + w_abyData2[1] = HIBYTE((short)(ID_NOTE_SIZE + 2)); + + InitCmdPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SET_ID_NOTE); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //. Assemble data packet + memset(w_abyData, (byte)0, ID_NOTE_SIZE+2); + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + System.arraycopy(w_abyNoteBuf, 0, w_abyData, 2, w_abyNoteBuf.length); + + InitCmdDataPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, ID_NOTE_SIZE+2); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_SET_ID_NOTE); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetIDNote(int p_nTmplNo, String[] p_pstrNote) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[2]; + String w_strTmp; + + //. Assemble command packet + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + InitCmdPacket(CMD_GET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GET_ID_NOTE); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_bRet = Receive_DataPacket(CMD_GET_ID_NOTE); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memset(m_abyPacket2, (byte)0, ID_NOTE_SIZE+1); + memset(m_abyPacket2, (byte)0, 512); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, ID_NOTE_SIZE); + + w_strTmp = new String(m_abyPacket2); + p_pstrNote[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SetModuleSN(String p_pstrModuleSN) + { + boolean w_bRet = false; + byte[] w_abyData = p_pstrModuleSN.getBytes(); + byte[] w_abyModuleSN = new byte[MODULE_SN_LEN]; + byte[] w_abyData2 = new byte[2]; + + memset(w_abyModuleSN, (byte)0, MODULE_SN_LEN); + System.arraycopy(w_abyData, 0, w_abyModuleSN, 0, w_abyData.length); + + //. Assemble command packet + w_abyData2[0] = LOBYTE((short)(MODULE_SN_LEN)); + w_abyData2[1] = HIBYTE((short)(MODULE_SN_LEN)); + + InitCmdPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SET_MODULE_SN); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //. Assemble data packet + InitCmdDataPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyModuleSN, MODULE_SN_LEN); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_SET_MODULE_SN); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetModuleSN(String[] p_pstrModuleSN) + { + boolean w_bRet = false; + String w_strTmp; + + //. Assemble command packet + InitCmdPacket(CMD_GET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GET_MODULE_SN); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_bRet = Receive_DataPacket(CMD_GET_MODULE_SN); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memset(m_abyPacket2, (byte)0, MODULE_SN_LEN+1); + memset(m_abyPacket2, (byte)0, 512); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, MODULE_SN_LEN); + + w_strTmp = new String(m_abyPacket2); + p_pstrModuleSN[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetImage() + { + boolean w_bRet; + + InitCmdPacket(CMD_GET_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_GET_IMAGE); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_FingerDetect(int[] p_pnDetectResult) + { + boolean w_bRet; + + InitCmdPacket(CMD_FINGER_DETECT, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_FINGER_DETECT); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnDetectResult[0] = m_abyPacket[RCM_DATA_OFFSET]; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_UpImage(int p_nType, byte[] p_pFpData, int[] p_pnImgWidth, int[] p_pnImgHeight) + { + int i, n, r, w, h, size; + boolean w_bRet; + byte[] w_abyData = new byte[1]; + + w_abyData[0] = (byte)p_nType; + + InitCmdPacket(CMD_UP_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 1); + + w_bRet = Send_Command(CMD_UP_IMAGE); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + h = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]); + + size = w * h; + n = size / IMAGE_DATA_UNIT; + r = size % IMAGE_DATA_UNIT; + + if (m_nConnected == 1) { + for (i=0; i 0) + { + w_bRet = Receive_DataPacket(CMD_UP_IMAGE); + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET + 2, p_pFpData, i * IMAGE_DATA_UNIT, r); + } + } + else if (m_nConnected == 2) { + w_bRet = USB_ReceiveImage(p_pFpData, w * h); + if (!w_bRet) + return ERR_CONNECTION; + } + else { + return ERR_CONNECTION; + } + + p_pnImgWidth[0] = w; + p_pnImgHeight[0] = h; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_DownImage(byte[] p_pData, int p_nWidth, int p_nHeight) + { + /* + int i, n, r, w, h; + boolean w_bRet; + BYTE w_abyData[840]; + + w = p_nWidth; + h = p_nHeight; + + w_abyData[0] = LOBYTE(p_nWidth); + w_abyData[1] = HIBYTE(p_nWidth); + w_abyData[2] = LOBYTE(p_nHeight); + w_abyData[3] = HIBYTE(p_nHeight); + + //. Assemble command packet + InitCmdPacket(CMD_DOWN_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + Send_Command(CMD_DOWN_IMAGE, w_bRet, m_bySrcDeviceID, m_byDstDeviceID); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + n = (w*h)/DOWN_IMAGE_DATA_UINT; + r = (w*h)%DOWN_IMAGE_DATA_UINT; + + w_bRet = USB_DownImage(m_hUsbHandle, p_pData, p_nWidth*p_nHeight); + + if(w_bRet == false) + return ERR_CONNECTION; + */ + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SLEDControl(int p_nState) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nState); + w_abyData[1] = HIBYTE((short)p_nState); + + InitCmdPacket(CMD_SLED_CTRL, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + w_bRet = Send_Command(CMD_SLED_CTRL); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_StoreChar(int p_nTmplNo, int p_nRamBufferID, int[] p_pnDupTmplNo) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_STORE_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + //. Send command packet to target + w_bRet = Send_Command(CMD_STORE_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + { + if (GetRetCode() == ERR_DUPLICATION_ID) + p_pnDupTmplNo[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return GetRetCode(); + } + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_LoadChar(int p_nTmplNo, int p_nRamBufferID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_LOAD_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + //. Send command packet to target + w_bRet = Send_Command(CMD_LOAD_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_UpChar(int p_nRamBufferID, byte[] p_pbyTemplate, int[] p_nSize) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[2]; + short w_nTemplateSize = 0; + int w_nRemainSize = 0; + + //. Assemble command packet + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + InitCmdPacket(CMD_UP_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_UP_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_nTemplateSize = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + if (w_nTemplateSize < CHAR_SPLIT_THR) { + w_bRet = Receive_DataPacket(CMD_UP_CHAR); + if (!w_bRet) + return ERR_CONNECTION; + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + //memcpy(p_pbyTemplate, &g_pRcmPacket->m_abyData[0], GD_RECORD_SIZE); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, 0, w_nTemplateSize); + } + else { + w_nRemainSize = w_nTemplateSize; + while (w_nRemainSize > 0) { + w_bRet = Receive_DataPacket(CMD_UP_CHAR); + if (!w_bRet) + return ERR_CONNECTION; + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + if (w_nRemainSize > CHAR_SPLIT_UNIT) { + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, w_nTemplateSize - w_nRemainSize, CHAR_SPLIT_UNIT); + w_nRemainSize -= CHAR_SPLIT_UNIT; + } + else { + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, w_nTemplateSize - w_nRemainSize, w_nRemainSize); + w_nRemainSize -= 0; + } + } + } + + p_nSize[0] = w_nTemplateSize; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_DownChar(int p_nRamBufferID, byte[] p_pbyTemplate, int p_nSize) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[MAX_DATA_LEN+2]; + byte[] w_abyData2 = new byte[2]; + int w_nRemainSize = 0; + int i; + + //. Assemble command packet + if (p_nSize < CHAR_SPLIT_THR) { + w_abyData2[0] = LOBYTE((short)(p_nSize + 2)); + w_abyData2[1] = HIBYTE((short)(p_nSize + 2)); + } + else { + w_abyData2[0] = LOBYTE((short)(p_nSize + 4)); + w_abyData2[1] = HIBYTE((short)(p_nSize + 4)); + } + + InitCmdPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_DOWN_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + SystemClock.sleep(10); + + //. Assemble data packet + if (p_nSize < CHAR_SPLIT_THR) { + w_abyData[0] = LOBYTE((short) p_nRamBufferID); + w_abyData[1] = HIBYTE((short) p_nRamBufferID); + //memcpy(&w_abyData[2], p_pbyTemplate, GD_RECORD_SIZE); + System.arraycopy(p_pbyTemplate, 0, w_abyData, 2, p_nSize); + + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, p_nSize + 2); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_DOWN_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + } + else { + w_nRemainSize = p_nSize; + i = 0; + while (w_nRemainSize > 0) { + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = LOBYTE((short)i); + w_abyData[3] = HIBYTE((short)i); + if (w_nRemainSize > CHAR_SPLIT_UNIT) { + System.arraycopy(p_pbyTemplate, i * CHAR_SPLIT_UNIT, w_abyData, 4, CHAR_SPLIT_UNIT); + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, CHAR_SPLIT_UNIT + 4); + w_nRemainSize -= CHAR_SPLIT_UNIT; + } + else { + System.arraycopy(p_pbyTemplate, i * CHAR_SPLIT_UNIT, w_abyData, 4, w_nRemainSize); + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, w_nRemainSize + 4); + w_nRemainSize -= 0; + } + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_DOWN_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + i++; + } + } + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_DelChar(int p_nSTmplNo, int p_nETmplNo) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_DEL_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_DEL_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetEmptyID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEmptyID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_EMPTY_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_EMPTY_ID); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + p_pnEmptyID[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetStatus(int p_nTmplNo, int[] p_pnStatus) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + + InitCmdPacket(CMD_GET_STATUS, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + w_bRet = Send_Command(CMD_GET_STATUS); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + p_pnStatus[0] = m_abyPacket[RCM_DATA_OFFSET]; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetBrokenID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnCount, int[] p_pnFirstID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_BROKEN_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_BROKEN_ID); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnCount[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + p_pnFirstID[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetEnrollCount(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEnrollCount) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_ENROLL_COUNT, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_ENROLL_COUNT); + + if (!w_bRet) + return ERR_CONNECTION; + + if(GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnEnrollCount[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_Generate(int p_nRamBufferID) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_GENERATE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GENERATE); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Merge(int p_nRamBufferID, int p_nMergeCount) + { + boolean w_bRet; + byte[] w_abyData = new byte[3]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = (byte)p_nMergeCount; + + InitCmdPacket(CMD_MERGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 3); + + w_bRet = Send_Command(CMD_MERGE); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Match(int p_nRamBufferID0, int p_nRamBufferID1) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID0); + w_abyData[1] = HIBYTE((short)p_nRamBufferID0); + w_abyData[2] = LOBYTE((short)p_nRamBufferID1); + w_abyData[3] = HIBYTE((short)p_nRamBufferID1); + + InitCmdPacket(CMD_MATCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_MATCH); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Search(int p_nRamBufferID, int p_nStartID, int p_nSearchCount, int[] p_pnTmplNo, int[] p_pnLearnResult) + { + boolean w_bRet; + byte[] w_abyData = new byte[6]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = LOBYTE((short)p_nStartID); + w_abyData[3] = HIBYTE((short)p_nStartID); + w_abyData[4] = LOBYTE((short)p_nSearchCount); + w_abyData[5] = HIBYTE((short)p_nSearchCount); + + InitCmdPacket(CMD_SEARCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 6); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SEARCH); + + if (!w_bRet) + return ERR_CONNECTION; + + if(GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnTmplNo[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + p_pnLearnResult[0] = m_abyPacket[RCM_DATA_OFFSET+2]; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Verify(int p_nTmplNo, int p_nRamBufferID, int[] p_pnLearnResult) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + //. Assemble command packet + InitCmdPacket(CMD_VERIFY, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_VERIFY); + + if (!w_bRet) + return ERR_CONNECTION; + + p_pnLearnResult[0] = m_abyPacket[RCM_DATA_OFFSET+2]; + + return GetRetCode(); + } + + public boolean GetDeviceInformation(String[] deviceInfo) + { + int[] w_nRecvLen = new int[1]; + byte[] w_abyPCCmd = new byte[6]; + byte[] w_abyData = new byte[32]; + + String w_strTmp; + boolean w_bRet; + + Arrays.fill(w_abyPCCmd, (byte) 0); + + w_abyPCCmd[2] = 0x04; + + w_bRet = SendPackage(w_abyPCCmd, w_abyData); + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, SendPackage ret = " + w_bRet, Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + { + return false; + } + + w_bRet = RecvPackage(w_abyData, w_nRecvLen); + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, RecvPackage : " + w_bRet, Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + { + return false; + } + + w_strTmp = new String(w_abyData); + deviceInfo[0] = w_strTmp; + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, Recv Data : " + w_strTmp, Toast.LENGTH_SHORT).show(); + + return true; + } + + + + private boolean SendPackage(byte[] pPCCmd, byte[] pData) + { + int nDataLen; + + pPCCmd[0] = (byte)0xEF; + pPCCmd[1] = 0x01; + + nDataLen = ((pPCCmd[5] << 8) & 0x0000FF00) | (pPCCmd[4] & 0x000000FF); + + return m_usbBase.UsbSCSIWrite(pPCCmd, 6, pData, nDataLen, 5000); + } + + private boolean RecvPackage(byte[] pData, int[] pLevRen) + { + int w_nLen; + byte[] w_abyPCCmd = new byte[6]; + byte[] w_abyRespond = new byte[4]; + boolean w_bRet; + + w_abyPCCmd[0] = (byte)0xEF; + w_abyPCCmd[1] = 0x02; + w_abyPCCmd[2] = 0; + w_abyPCCmd[3] = 0; + w_abyPCCmd[4] = 0; + w_abyPCCmd[5] = 0; + + // receive status + w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, w_abyRespond, 4, 5000); + + if (!w_bRet) + return false; + + // receive data + //w_nLen = (int)((w_abyRespond[3] << 8) | w_abyRespond[2]); + w_nLen = ((w_abyRespond[3] << 8) & 0x0000FF00) | (w_abyRespond[2] & 0x000000FF); + + if (w_nLen > 0) + { + //w_nTime = SystemClock.elapsedRealtime(); + + w_abyPCCmd[1] = 0x03; + w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, pData, w_nLen, 5000); + + //w_nTime = SystemClock.elapsedRealtime() - w_nTime; + + if (!w_bRet) + return false; + + pLevRen[0] = w_nLen; + } + + return true; + } + + /*************************************************************************** + * Get Return Code + ***************************************************************************/ + private short GetRetCode() + { + return (short)(((m_abyPacket[9] << 8) & 0x0000FF00) | (m_abyPacket[8] & 0x000000FF)); + } + + /*************************************************************************** + * Get Data Length + ***************************************************************************/ + private short GetDataLen() + { + return (short)(((m_abyPacket[7] << 8) & 0x0000FF00) | (m_abyPacket[6] & 0x000000FF)); + } + + /*************************************************************************** + * Set Data Length + ***************************************************************************/ + private void SetDataLen(short p_wDataLen) + { + m_abyPacket[6] = (byte)(p_wDataLen & 0xFF); + m_abyPacket[7] = (byte)(((p_wDataLen & 0xFF00) >> 8) & 0xFF); + } + + /*************************************************************************** + * Set Command Data + ***************************************************************************/ + private void SetCmdData(short p_wData, boolean p_bFirst) + { + if (p_bFirst) + { + m_abyPacket[8] = (byte)(p_wData & 0xFF); + m_abyPacket[9] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF); + } + else + { + m_abyPacket[10] = (byte)(p_wData & 0xFF); + m_abyPacket[11] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF); + } + } + + /*************************************************************************** + * Get Command Data + ***************************************************************************/ + private short GetCmdData(boolean p_bFirst) + { + if (p_bFirst) + { + return (short)(((m_abyPacket[9] << 8) & 0x0000FF00) | (m_abyPacket[8] & 0x000000FF)); + } + else + { + return (short)(((m_abyPacket[11] << 8) & 0x0000FF00) | (m_abyPacket[10] & 0x000000FF)); + } + } + + /*************************************************************************** + * Get 2bytes packet checksum(pDataPkt[0] + pDataPkt[1] + ....) + ***************************************************************************/ + private short CalcChkSumOfPkt(byte[] pDataPkt, int nSize) + { + int i, nChkSum = 0; + + for(i=0;im_wPrefix = CMD_PREFIX_CODE; + m_abyPacket[0] = (byte)(CMD_PREFIX_CODE & 0xFF); + m_abyPacket[1] = (byte)((CMD_PREFIX_CODE >> 8) & 0xFF); + + //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID; + m_abyPacket[2] = bySrcDeviceID; + + //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID; + m_abyPacket[3] = byDstDeviceID; + + //g_pCmdPacket->m_wCMDCode = p_wCMDCode; + m_abyPacket[4] = (byte)(wCMDCode & 0xFF); + m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF); + + //g_pCmdPacket->m_wDataLen = p_wDataLen; + m_abyPacket[6] = (byte)(nDataLen & 0xFF); + m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF); + + if (nDataLen > 0) + //memcpy(g_pCmdPacket->m_abyData, p_pbyData, wDataLen); + System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen); + + w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, CMD_PACKET_LEN-2); + + //g_pCmdPacket->m_wCheckSum = w_wCheckSum; + m_abyPacket[24] = (byte)(w_wCheckSum & 0xFF); + m_abyPacket[25] = (byte)((w_wCheckSum >> 8) & 0xFF); + + m_nPacketSize = CMD_PACKET_LEN; + } + /*************************************************************************** + * Make Data Packet + ***************************************************************************/ + void InitCmdDataPacket(short wCMDCode, byte bySrcDeviceID, byte byDstDeviceID, byte[] pbyData, int nDataLen) + { + short w_wCheckSum; + + //g_pCmdPacket->m_wPrefix = CMD_DATA_PREFIX_CODE; + m_abyPacket[0] = (byte)(CMD_DATA_PREFIX_CODE & 0xFF); + m_abyPacket[1] = (byte)((CMD_DATA_PREFIX_CODE >> 8) & 0xFF); + + //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID; + m_abyPacket[2] = bySrcDeviceID; + + //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID; + m_abyPacket[3] = byDstDeviceID; + + //g_pCmdPacket->m_wCMDCode = p_wCMDCode; + m_abyPacket[4] = (byte)(wCMDCode & 0xFF); + m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF); + + //g_pCmdPacket->m_wDataLen = p_wDataLen; + m_abyPacket[6] = (byte)(nDataLen & 0xFF); + m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF); + + //memcpy(&g_pCmdPacket->m_abyData[0], p_pbyData, p_wDataLen); + System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen); + + //. Set checksum + w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, nDataLen + 8); + + m_abyPacket[nDataLen+8] = (byte)(w_wCheckSum & 0xFF); + m_abyPacket[nDataLen+9] = (byte)((w_wCheckSum >> 8) & 0xFF); + + m_nPacketSize = nDataLen + 10; + } + /*************************************************************************** + * Check Packet + ***************************************************************************/ + boolean CheckReceive( byte[] pbyPacket, int nPacketLen, short wPrefix, short wCMDCode ) + { + short w_wCalcCheckSum, w_wCheckSum, w_wTmp; + + //. Check prefix code + w_wTmp = (short)(((pbyPacket[1] << 8) & 0x0000FF00) | (pbyPacket[0] & 0x000000FF)); + + if (wPrefix != w_wTmp) + { + return false; + } + + //. Check checksum + w_wCheckSum = (short)(((pbyPacket[nPacketLen-1] << 8) & 0x0000FF00) | (pbyPacket[nPacketLen-2] & 0x000000FF)); + + w_wCalcCheckSum = CalcChkSumOfPkt(pbyPacket, nPacketLen-2); + + if (w_wCheckSum != w_wCalcCheckSum) + { + return false; + } + + //. Check Command Code + w_wTmp = (short)(((pbyPacket[5] << 8) & 0x0000FF00) | (pbyPacket[4] & 0x000000FF)); + return wCMDCode == w_wTmp; + } + + //--------------------------- Send, Receive Communication Packet Functions ---------------------// + public boolean Send_Command(short p_wCmd) + { + if (m_nConnected == 1) + return UART_SendCommand(p_wCmd); + else if (m_nConnected == 2) + return USB_SendPacket(p_wCmd); + else + return false; + } + + public boolean Send_DataPacket(short p_wCmd) + { + if (m_nConnected == 1) + return UART_SendDataPacket(p_wCmd); + else if (m_nConnected == 2) + return USB_SendDataPacket(p_wCmd); + else + return false; + } + + public boolean Receive_DataPacket(short p_wCmd) + { + if (m_nConnected == 1) + return UART_ReceiveDataPacket(p_wCmd); + else if (m_nConnected == 2) + return USB_ReceiveDataPacket(p_wCmd); + else + return false; + } + + //-------------------------------- USB Communication Functions --------------------------------// + private boolean USB_SendPacket(short wCMD) + { + byte[] btCDB = new byte[8]; + boolean w_bRet; + + Arrays.fill(btCDB, (byte)0); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x11; btCDB[4] = (byte)m_nPacketSize; + + w_bRet = m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT); + + if (!w_bRet) + { + return false; + } + + return USB_ReceiveAck( wCMD ); + } + + private boolean USB_ReceiveAck(short wCMD) + { + int c, w_nLen, w_nReadCount = 0; + byte[] btCDB = new byte[8]; + byte[] w_abyWaitPacket = new byte[CMD_PACKET_LEN]; + + Arrays.fill(btCDB, (byte)0); + + //w_nReadCount = GetReadWaitTime(p_byCMD); + + c = 0; + Arrays.fill(w_abyWaitPacket, (byte)0xAF); + + do + { + Arrays.fill(m_abyPacket, (byte)0); + + btCDB[0] = (byte)0xEF; btCDB[1] = (byte)0x12; + + w_nLen = RCM_PACKET_LEN; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT)) + { + return false; + } + + SystemClock.sleep(COMM_SLEEP_TIME); + + c++; + + //if ( c > w_nReadCount) + //{ + // return false; + //} + } while (memcmp(m_abyPacket, w_abyWaitPacket, CMD_PACKET_LEN)); + + m_nPacketSize = w_nLen; + + return CheckReceive(m_abyPacket, m_nPacketSize, (short) RCM_PREFIX_CODE, wCMD); + } + + boolean USB_ReceiveDataAck(short wCMD) + { + byte[] btCDB = new byte[8]; + byte[] w_WaitPacket = new byte[10]; + int w_nLen; + + memset(btCDB, (byte)0, 8); + memset(w_WaitPacket, (byte)0xAF, 10); + + do + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x15; + w_nLen = 8; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT)) + { + return false; + } + + SystemClock.sleep(COMM_SLEEP_TIME); + + }while(memcmp(m_abyPacket, w_WaitPacket, 8)); + + //w_nLen = g_pRcmPacket->m_wDataLen + 2; + w_nLen = (short)(((m_abyPacket[7] << 8) & 0x0000FF00) | (m_abyPacket[6] & 0x000000FF)) + 2; + + if (!USB_ReceiveRawData(m_abyPacket2, w_nLen)) + { + return false; + } + + System.arraycopy(m_abyPacket2, 0, m_abyPacket, 8, w_nLen); + + m_nPacketSize = 8 + w_nLen; + + return CheckReceive(m_abyPacket, m_nPacketSize, (short) RCM_DATA_PREFIX_CODE, wCMD); + } + + boolean USB_SendDataPacket(short wCMD) + { + byte[] btCDB = new byte[8]; + + memset(btCDB, (byte)0, 8); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x13; + + btCDB[4] = (byte)(m_nPacketSize & 0xFF); + btCDB[5] = (byte)((m_nPacketSize >> 8) & 0xFF); + + if (!m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT ) ) + return false; + + return USB_ReceiveDataAck(wCMD); + } + + boolean USB_ReceiveDataPacket(short wCMD) + { + return USB_ReceiveDataAck(wCMD); + } + + boolean USB_ReceiveRawData(byte[] pBuffer, int nDataLen) + { + byte[] btCDB = new byte[8]; + + memset(btCDB, (byte)0, 8); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x14; + + return m_usbBase.UsbSCSIRead(btCDB, 8, pBuffer, nDataLen, SCSI_TIMEOUT); + } + + boolean USB_ReceiveImage(byte[] p_pBuffer, int nDataLen ) + { + byte[] btCDB = new byte[8]; + byte[] w_WaitPacket = new byte[8]; + + memset( btCDB, (byte)0, 8 ); + memset( w_WaitPacket, (byte)0xAF, 8 ); + + if (nDataLen < 1024*64) + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; + + return m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen, SCSI_TIMEOUT); + } + else if (nDataLen == 256*288) + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x00; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen/2, SCSI_TIMEOUT)) + return false; + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x01; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket2, nDataLen/2, SCSI_TIMEOUT )) + return false; + + System.arraycopy(m_abyPacket2, 0, p_pBuffer, nDataLen/2, nDataLen/2); + } + + return true; + } + + //-------------------------------- UART Communication Functions --------------------------------// + public boolean UART_SendCommand(short p_wCmd) + { + int w_nResult = 0; + boolean w_bRet = false; + int w_nRetry = 0; + + if (m_nConnected == 1) + { + byte[] w_pData = new byte[m_nPacketSize]; + System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize); + m_SerialPort.send(w_pData, m_nPacketSize); + } + +// do { +// w_bRet = UART_ReceiveAck(p_wCmd); +// if (m_nUARTReceivePos == m_nUARTReadPos) { +// if (w_bRet == true) { +// break; +// } +// else { +// if (w_nRetry > 0) +// break; +// else +// w_nRetry += 1; +// } +// } +// } while (w_bRet == false); + w_bRet = UART_ReceiveAck(p_wCmd); + return w_bRet; + } + + public boolean UART_ReceiveAck(short p_wCmd) + { + if (!UART_ReadDataN(m_abyPacket, 0, CMD_PACKET_LEN)) + return false; + + return CheckReceive(m_abyPacket, CMD_PACKET_LEN, (short) RCM_PREFIX_CODE, p_wCmd); + } + + public boolean UART_ReceiveDataAck(short p_wCmd) + { + if (!UART_ReadDataN(m_abyPacket, 0, 8)) + return false; + + if (!UART_ReadDataN(m_abyPacket, 8, GetDataLen() + 2)) + return false; + + return CheckReceive(m_abyPacket, GetDataLen() + 10, (short)RCM_DATA_PREFIX_CODE, p_wCmd); + } + + public boolean UART_SendDataPacket(short p_wCmd) + { + int w_nSendCnt = 0; + + if (m_nConnected == 1) + { + byte[] w_pData = new byte[m_nPacketSize]; + System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize); + m_SerialPort.send(w_pData, m_nPacketSize); + } + + return UART_ReceiveDataAck(p_wCmd); + } + /***************************************************************************/ + /***************************************************************************/ + public boolean UART_ReceiveDataPacket(short p_wCmd) + { + return UART_ReceiveDataAck(p_wCmd); + } + /***************************************************************************/ + /***************************************************************************/ + public boolean UART_ReceiveData(short p_wCmd, int p_nDataLen, byte[] p_pBuffer) + { + int w_nReceivedCnt; + int w_wPacketDataLen = 0; + + for (w_nReceivedCnt = 0; w_nReceivedCnt < p_nDataLen; w_nReceivedCnt += w_wPacketDataLen) + { + w_wPacketDataLen = p_nDataLen - w_nReceivedCnt; + if (w_wPacketDataLen > MAX_DATA_LEN) w_wPacketDataLen = MAX_DATA_LEN; + if (!UART_ReceiveDataPacket(p_wCmd)) + return false; + System.arraycopy(m_abyPacket, 8, p_pBuffer, w_nReceivedCnt, GetDataLen() + 4); + } + return true; + } + /***************************************************************************/ + /***************************************************************************/ + boolean UART_ReadDataN(byte[] p_pData, int p_nStart, int p_nLen) + { + int w_nTotalRecvLen; + int w_nTmpLen; + int w_nStartPos = 0; + int w_nHeader; + boolean w_bFirstPacket = true; + int w_nReceivedLen = 0; + + int wm_nUARTReceivePos = 0; + int wm_nUARTReadPos = 0; + + long w_nEllapsedTime = 0; + + w_nTotalRecvLen = 0; + w_nEllapsedTime = SystemClock.uptimeMillis(); + + while (w_nTotalRecvLen < p_nLen) + { + wm_nUARTReceivePos = m_nUARTReceivePos; + wm_nUARTReadPos = m_nUARTReadPos; + + if ((wm_nUARTReceivePos <= wm_nUARTReadPos) && (wm_nUARTReadPos - wm_nUARTReceivePos < DevComm.MAX_DATA_LEN)) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (SystemClock.uptimeMillis() - w_nEllapsedTime > UART_READ_TIMEOUT) + return false; + continue; + } + + if (wm_nUARTReceivePos < wm_nUARTReadPos) { + w_nReceivedLen = DevComm.UART_MAX_BUF_SIZE + wm_nUARTReceivePos - wm_nUARTReadPos; + System.arraycopy(m_pUARTReadBuf, wm_nUARTReadPos, m_abyPacket2, 0, DevComm.UART_MAX_BUF_SIZE - wm_nUARTReadPos); + System.arraycopy(m_pUARTReadBuf, 0, m_abyPacket2, DevComm.UART_MAX_BUF_SIZE - wm_nUARTReadPos, wm_nUARTReceivePos); + } + else { + w_nReceivedLen = wm_nUARTReceivePos - wm_nUARTReadPos; + System.arraycopy(m_pUARTReadBuf, wm_nUARTReadPos, m_abyPacket2, 0, w_nReceivedLen); + } + + if (w_bFirstPacket && (p_nLen == 6) && (p_nStart == 0)) { + for (w_nStartPos = 0; w_nStartPos < w_nReceivedLen; w_nStartPos++) { + w_nHeader = MAKEWORD(m_abyPacket2[w_nStartPos], m_abyPacket2[w_nStartPos + 1]); + if ((w_nHeader == CMD_PREFIX_CODE) || (w_nHeader == RCM_PREFIX_CODE) || + (w_nHeader == CMD_DATA_PREFIX_CODE) || (w_nHeader == RCM_DATA_PREFIX_CODE)) + break; + } + + m_nUARTReadPos += w_nStartPos; + w_nReceivedLen -= w_nStartPos; + + w_bFirstPacket = false; + } + else { + w_nStartPos = 0; + } + + if (p_nLen - w_nTotalRecvLen < w_nReceivedLen) { + w_nTmpLen = p_nLen - w_nTotalRecvLen; + } + else { + w_nTmpLen = w_nReceivedLen; + } + + System.arraycopy(m_abyPacket2, w_nStartPos, p_pData, p_nStart + w_nTotalRecvLen, w_nTmpLen); + w_nTotalRecvLen += w_nTmpLen; + m_nUARTReadPos += w_nTmpLen; + + if (m_nUARTReadPos >= DevComm.UART_MAX_BUF_SIZE) + m_nUARTReadPos -= DevComm.UART_MAX_BUF_SIZE; + + w_nEllapsedTime = SystemClock.uptimeMillis(); + } + + return true; + } + + private boolean memcmp(byte[] p1, byte[] p2, int nLen) + { + int i; + + for (i=0; i> 8) & 0xFF); + } + + + // uart control classes ====================================================== + private class SerialControl extends SerialHelper{ + + public SerialControl(){ + } + + @Override + protected void onDataReceived(final ComBean ComRecData) + { + int w_nProcLen = 0; + +// DispQueue.AddQueue(ComRecData); + + // save to receive buffer + if (m_nUARTReceivePos + ComRecData.nSize > DevComm.UART_MAX_BUF_SIZE) { + w_nProcLen = DevComm.UART_MAX_BUF_SIZE - m_nUARTReceivePos; + System.arraycopy(ComRecData.bRec, 0, m_pUARTReadBuf, m_nUARTReceivePos, w_nProcLen); + System.arraycopy(ComRecData.bRec, w_nProcLen, m_pUARTReadBuf, 0, ComRecData.nSize - w_nProcLen); + m_nUARTReceivePos = ComRecData.nSize - w_nProcLen; + } else { + System.arraycopy(ComRecData.bRec, 0, m_pUARTReadBuf, m_nUARTReceivePos, ComRecData.nSize); + m_nUARTReceivePos += ComRecData.nSize; + } + } + } + + private class DispQueueThread extends Thread{ + private final Queue QueueList = new LinkedList(); + @Override + public void run() { + super.run(); +// while(!isInterrupted()) { +// int i; +// i = 0; +// while (m_bBufferHandle) +// { +// i++; +// if (i > 10000) +// break; +// } +// m_bBufferHandle = true; +// while(true) +// { +// final ComBean ComData; +// if ((ComData=QueueList.poll())==null) +// break; +// +// Log.d("NOEM_DEBUG", String.format("DispQueueThread: ComData.nSize = %d, m_nUARTReadLen = %d", +// ComData.nSize, m_nUARTReadLen)); +// System.arraycopy(ComData.bRec, 0, m_pUARTReadBuf, m_nUARTReadLen, ComData.nSize); +// m_nUARTReadLen = m_nUARTReadLen + ComData.nSize; +//// break; +// } +// m_bBufferHandle = false; +// } + } + + public synchronized void AddQueue(ComBean ComData){ + QueueList.add(ComData); + } + } + // ! uart control classes ==================================================== +} diff --git a/android/src/main/java/com/idworld/noemhost_and/IUsbConnState.java b/android/src/main/java/com/idworld/noemhost_and/IUsbConnState.java new file mode 100644 index 0000000..98cffd3 --- /dev/null +++ b/android/src/main/java/com/idworld/noemhost_and/IUsbConnState.java @@ -0,0 +1,12 @@ +package com.idworld.noemhost_and; + +/** + * Created by KMS on 2016/8/23. + */ +public interface IUsbConnState { + void onUsbConnected(); + + void onUsbPermissionDenied(); + + void onDeviceNotFound(); +} diff --git a/android/src/main/java/com/idworld/noemhost_and/MainActivity.java b/android/src/main/java/com/idworld/noemhost_and/MainActivity.java new file mode 100644 index 0000000..38aaf7f --- /dev/null +++ b/android/src/main/java/com/idworld/noemhost_and/MainActivity.java @@ -0,0 +1,1533 @@ +//package com.idworld.noemhost_and; +// +//import android.Manifest; +//import android.content.Intent; +//import android.content.pm.PackageManager; +//import android.graphics.Bitmap; +//import android.graphics.BitmapFactory; +//import android.os.Build; +//import android.os.Environment; +//import android.os.SystemClock; +//import android.support.annotation.Nullable; +//import android.support.v4.app.ActivityCompat; +//import android.support.v4.content.ContextCompat; +//import android.support.v7.app.AppCompatActivity; +//import android.os.Bundle; +//import android.view.KeyEvent; +//import android.view.View; +//import android.widget.AdapterView; +//import android.widget.ArrayAdapter; +//import android.widget.Button; +//import android.widget.EditText; +//import android.widget.ImageView; +//import android.widget.Spinner; +//import android.widget.TextView; +//import android.widget.Toast; +// +//import java.io.File; +//import java.io.FileInputStream; +//import java.io.FileOutputStream; +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.Collections; +//import java.util.List; +// +//import android_serialport_api.SerialPortFinder; +// +//public class MainActivity extends AppCompatActivity implements View.OnClickListener { +// +// // global variables +// int m_nMaxFpCount; +// int m_nUserID, m_nParam, m_nImgWidth, m_nImgHeight; +// long m_nPassedTime; +// String m_strPost; +// boolean m_bCancel = true; +// boolean m_bConCapture; +// +// // communication device variables +// private static DevComm m_devComm; +// int m_nBaudrate; +// String m_szDevice; +// +// // serial port +// SerialPortFinder mSerialPortFinder; +// +// // image variables +// byte[] m_binImage; +// byte[] m_bmpImage; +// +// // control variables +// Button m_btnOpenDevice; +// Button m_btnCloseDevice; +// Button m_btnEnroll; +// Button m_btnVerify; +// Button m_btnIdentify; +// Button m_btnCaptureImage; +// Button m_btnCancel; +// Button m_btnGetUserCount; +// Button m_btnGetEmptyID; +// Button m_btnDeleteID; +// Button m_btnDeleteAll; +// Button m_btnGetTemplate; +// Button m_btnSetTemplate; +// Button m_btnGetMultiTemplate; +// Button m_btnSetMultiTemplate; +// EditText m_editUserID; +// EditText m_editParam; +// TextView m_txtStatus; +// ImageView m_FpImageViewer; +// Spinner m_spFpCount; +// Spinner m_spBaudrate; +// Spinner m_spDevice; +// +// @Override +// protected void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// setContentView(R.layout.activity_main); +// +// // init variables +// m_nMaxFpCount = 80; +// +// // init ui +// InitWidget(); +// SetInitialState(); +// InitDeviceList(); +// +// // request permission +// if (!requestPermission(PERMISSIONS)) { +//// Toast.makeText(this, "Can not work correctly without permissions", Toast.LENGTH_LONG).show(); +// } +// +// // get device name +// m_spDevice.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// m_szDevice = m_spDevice.getItemAtPosition(position).toString(); +// } +// public void onNothingSelected(AdapterView parent) { +// } +// }); +// +// // get baudrate +// m_spBaudrate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// if (position == 0) +// m_nBaudrate = 9600; +// else if (position == 1) +// m_nBaudrate = 19200; +// else if (position == 2) +// m_nBaudrate = 38400; +// else if (position == 3) +// m_nBaudrate = 57600; +// else// if (position == 4) +// m_nBaudrate = 115200; +// } +// public void onNothingSelected(AdapterView parent) { +// } +// }); +// +// // calculate max fp count +// m_spFpCount.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// if (position == 0) +// m_nMaxFpCount = 80; +// else if (position == 1) +// m_nMaxFpCount = 170; +// else if (position == 2) +// m_nMaxFpCount = 200; +// else if (position == 3) +// m_nMaxFpCount = 500; +// else if (position == 4) +// m_nMaxFpCount = 1000; +// else if (position == 5) +// m_nMaxFpCount = 1700; +// else if (position == 6) +// m_nMaxFpCount = 2000; +// else// if (position == 7) +// m_nMaxFpCount = 3000; +// } +// public void onNothingSelected(AdapterView parent) { +// } +// }); +// } +// +// @Override +// protected void onDestroy() { +// super.onDestroy(); +// } +// +// @Override +// protected void onSaveInstanceState(Bundle outState) { +// super.onSaveInstanceState(outState); +// } +// +// @Override +// public void onClick(View view) { +// if(view == m_btnOpenDevice) +// OnOpenDeviceBtn(); +// else if(view == m_btnCloseDevice) +// OnCloseDeviceBtn(); +// else if(view == m_btnEnroll) +// OnEnrollBtn(); +// else if(view == m_btnVerify) +// OnVerifyBtn(); +// else if(view == m_btnIdentify) +// OnIdentifyBtn(); +// else if(view == m_btnCaptureImage) +// OnGetImageBtn(); +// else if(view == m_btnCancel) +// OnCancelBtn(); +// else if(view == m_btnGetUserCount) +// OnGetUserCount(); +// else if(view == m_btnGetEmptyID) +// OnGetEmptyID(); +// else if(view == m_btnDeleteID) +// OnDeleteIDBtn(); +// else if(view == m_btnDeleteAll) +// OnDeleteAllBtn(); +// else if(view == m_btnGetTemplate) +// OnGetTemplate(); +// else if(view == m_btnSetTemplate) +// OnSetTemplate(); +// else if(view == m_btnGetMultiTemplate) +// OnGetMultiTemplate(); +// else if(view == m_btnSetMultiTemplate) +// OnSetMultiTemplate(); +// } +// +// @Override +// public boolean onKeyDown(int KeyCode, KeyEvent event) { +// if (KeyCode == KeyEvent.KEYCODE_BACK) { +// if (event.getRepeatCount() == 0) { +// if (!m_bCancel) { +// Toast toast = Toast.makeText(getApplicationContext(), "Please cancel your command first", 5); +// toast.show(); +// return true; +// } +// if (m_btnCloseDevice.isEnabled()) +// OnCloseDeviceBtn(); +// } +// } +// +// return super.onKeyDown(KeyCode, event); +// } +// +// private void InitWidget() +// { +// m_FpImageViewer = findViewById(R.id.imvImgViewer); +// m_btnOpenDevice = findViewById(R.id.btnOpenDevice); +// m_btnCloseDevice = findViewById(R.id.btnCloseDevice); +// m_btnEnroll = findViewById(R.id.btnEnroll); +// m_btnVerify = findViewById(R.id.btnVerify); +// m_btnIdentify = findViewById(R.id.btnIdentify); +// m_btnCaptureImage = findViewById(R.id.btnCaptureImage); +// m_btnCancel = findViewById(R.id.btnCancel); +// m_btnGetUserCount = findViewById(R.id.btnGetEnrollCount); +// m_btnGetEmptyID = findViewById(R.id.btnGetEmptyID); +// m_btnDeleteID = findViewById(R.id.btnRemoveTemplate); +// m_btnDeleteAll = findViewById(R.id.btnRemoveAll); +// m_btnGetTemplate = findViewById(R.id.btnGetTemplate); +// m_btnSetTemplate = findViewById(R.id.btnSetTemplate); +// m_btnGetMultiTemplate = findViewById(R.id.btnGetMultiTemplate); +// m_btnSetMultiTemplate = findViewById(R.id.btnSetMultiTemplate); +// m_txtStatus = findViewById(R.id.txtStatus); +// m_editUserID = findViewById(R.id.edtUserID); +// m_spFpCount = findViewById(R.id.spnFpCount); +// m_spBaudrate = findViewById(R.id.spnBaudrate); +// m_spDevice = findViewById(R.id.spnDevice); +// +// m_btnOpenDevice.setOnClickListener(this); +// m_btnCloseDevice.setOnClickListener(this); +// m_btnEnroll.setOnClickListener(this); +// m_btnVerify.setOnClickListener(this); +// m_btnIdentify.setOnClickListener(this); +// m_btnCaptureImage.setOnClickListener(this); +// m_btnCancel.setOnClickListener(this); +// m_btnGetUserCount.setOnClickListener(this); +// m_btnGetEmptyID.setOnClickListener(this); +// m_btnDeleteID.setOnClickListener(this); +// m_btnDeleteAll.setOnClickListener(this); +// m_btnGetTemplate.setOnClickListener(this); +// m_btnSetTemplate.setOnClickListener(this); +// m_btnGetMultiTemplate.setOnClickListener(this); +// m_btnSetMultiTemplate.setOnClickListener(this); +// +// if(m_devComm == null){ +// m_devComm = new DevComm(this, m_IConnectionHandler); +// } +// +// m_binImage = new byte[1024*100]; +// m_bmpImage = new byte[1024*100]; +// } +// +// private void EnableCtrl(boolean bEnable) +// { +// m_btnEnroll.setEnabled(bEnable); +// m_btnVerify.setEnabled(bEnable); +// m_btnIdentify.setEnabled(bEnable); +// m_btnCancel.setEnabled(bEnable); +// m_btnGetUserCount.setEnabled(bEnable); +// m_btnGetEmptyID.setEnabled(bEnable); +// m_btnDeleteID.setEnabled(bEnable); +// m_btnDeleteAll.setEnabled(bEnable); +// m_btnCaptureImage.setEnabled(bEnable); +// m_btnGetTemplate.setEnabled(bEnable); +// m_btnSetTemplate.setEnabled(bEnable); +// m_btnGetMultiTemplate.setEnabled(bEnable); +// m_btnSetMultiTemplate.setEnabled(bEnable); +// +// //m_editUserID.setEnabled(bEnable); +// } +// +// private void SetInitialState() +// { +// m_txtStatus.setText("Please open device!"); +// m_btnOpenDevice.setEnabled(true); +// m_btnCloseDevice.setEnabled(false); +// EnableCtrl(false); +// } +// +// private void InitDeviceList() +// { +// // get device list +// mSerialPortFinder= new SerialPortFinder(); +// String[] entryValues = mSerialPortFinder.getAllDevicesPath(); +// List allDevices = new ArrayList(); +// allDevices.add("USB"); +// Collections.addAll(allDevices, entryValues); +// ArrayAdapter aspnDevices = new ArrayAdapter(this, android.R.layout.simple_spinner_item, allDevices); +// m_spDevice.setAdapter(aspnDevices); +// } +// +// private void OnOpenDeviceBtn() { +// String[] w_strInfo = new String[1]; +// +// if(m_devComm != null) +// { +// if (!m_devComm.IsInit()) +// { +// if (!m_devComm.OpenComm(m_szDevice, m_nBaudrate)) { +// m_txtStatus.setText("Failed init device!"); +// return; +// } +// } +// if (m_devComm.Run_TestConnection() == DevComm.ERR_SUCCESS) { +// if (m_devComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText("Open Success!\r\nDevice Info : " + w_strInfo[0]); +// EnableCtrl(true); +// m_btnOpenDevice.setEnabled(false); +// m_btnCloseDevice.setEnabled(true); +// } +// else +// m_txtStatus.setText("Can not connect to device!"); +// } +// else { +// m_txtStatus.setText("Can not connect to device!"); +// m_devComm.CloseComm(); +// } +// } +// } +// +// private void OnCloseDeviceBtn() { +// m_devComm.CloseComm(); +// m_bCancel = true; +// +// SetInitialState(); +// } +// +// private void OnEnrollBtn() { +// int w_nRet; +// int[] w_nState = new int[1]; +// +// if (!m_devComm.IsInit()) +// return; +// +// if (!CheckUserID()) +// return; +// +// // Check if fp is exist +// w_nRet = m_devComm.Run_GetStatus(m_nUserID, w_nState); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// if (w_nState[0] == DevComm.GD_TEMPLATE_NOT_EMPTY) +// { +// m_txtStatus.setText("Template is already exist"); +// return; +// } +// +// m_txtStatus.setText("Press finger : " + m_nUserID); +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_devComm.Run_SLEDControl(1); +// m_bCancel = false; +// +// new Thread(new Runnable() { +// int w_nRet; +// int w_nUserID; +// int w_nEnrollStep = 0; +// final int w_nGenCount = 3; +// final int[] w_nDupID = new int[1]; +// final int[] w_nWidth = new int[1]; +// final int[] w_nHeight = new int[1]; +// +// @Override +// public void run() { +// +// w_nUserID = m_nUserID; +// +// while (w_nEnrollStep < w_nGenCount) +// { +// m_strPost = String.format("Input finger #%d!", w_nEnrollStep+1); +// m_FpImageViewer.post(runShowStatus); +// +// // Capture +// if (Capturing() < 0) +// return; +// +// m_strPost = "Release your finger."; +// m_FpImageViewer.post(runShowStatus); +// +// // Up Cpatured Image +// if (m_devComm.m_nConnected == 2) { +// w_nRet = m_devComm.Run_UpImage(0, m_binImage, w_nWidth, w_nHeight); +// +// if (w_nRet != DevComm.ERR_SUCCESS) { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// +// // Draw image +// m_nImgWidth = w_nWidth[0]; +// m_nImgHeight = w_nHeight[0]; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runDrawImage); +// } +// +// // Create Template +// w_nRet = m_devComm.Run_Generate(w_nEnrollStep); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// if (w_nRet == DevComm.ERR_BAD_QUALITY) +// { +// m_strPost = "Bad quality. Try Again!"; +// m_FpImageViewer.post(runShowStatus); +// continue; +// } +// else +// { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// } +// +// /* +// if(w_nEnrollStep == 0) +// { +// if (w_nGenCount == 3) +// m_strPost = "Two More"; +// else +// m_strPost = "One More"; +// } +// else if(w_nEnrollStep == 1) +// m_strPost = "One More"; +// +// m_FpImageViewer.post(runShowStatus); +// */ +// +// w_nEnrollStep++; +// } +// +// //m_strPost = "Release Finger"; +// //m_FpImageViewer.post(runShowStatus); +// +// // Merge +// if (w_nGenCount != 1) +// { +// //. Merge Template +// w_nRet = m_devComm.Run_Merge(0, w_nGenCount); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// } +// +// //. Store template +// w_nRet = m_devComm.Run_StoreChar(w_nUserID, 0, w_nDupID); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// if (w_nRet == DevComm.ERR_DUPLICATION_ID) +// m_strPost = String.format("Result : Fail\r\nDuplication ID = %d", w_nDupID[0]); +// else +// m_strPost = GetErrorMsg(w_nRet); +// } +// else +// m_strPost = String.format("Result : Success\r\nTemplate No : %d", m_nUserID); +// +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// } +// }).start(); +// } +// +// private void OnVerifyBtn() { +// int w_nRet; +// int[] w_nState = new int[1]; +// +// if (!m_devComm.IsInit()) +// return; +// +// if (!CheckUserID()) +// return; +// +// w_nRet = m_devComm.Run_GetStatus(m_nUserID, w_nState); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// if (w_nState[0] == DevComm.GD_TEMPLATE_EMPTY ) +// { +// m_txtStatus.setText("Template is empty"); +// return; +// } +// +// m_txtStatus.setText("Press finger"); +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_devComm.Run_SLEDControl(1); +// m_bCancel = false; +// +// new Thread(new Runnable() { +// int w_nRet; +// final int[] w_nLearned = new int[1]; +// final int[] w_nWidth = new int[1]; +// final int[] w_nHeight = new int[1]; +// +// @Override +// public void run() { +// +// if (Capturing() < 0) +// return; +// +// m_strPost = "Release your finger."; +// m_FpImageViewer.post(runShowStatus); +// +// // Up Cpatured Image +// if (m_devComm.m_nConnected == 2) { +// w_nRet = m_devComm.Run_UpImage(0, m_binImage, w_nWidth, w_nHeight); +// +// if (w_nRet != DevComm.ERR_SUCCESS) { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// +// // Draw image +// m_nImgWidth = w_nWidth[0]; +// m_nImgHeight = w_nHeight[0]; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runDrawImage); +// } +// +// // Create template +// m_nPassedTime = SystemClock.elapsedRealtime(); +// w_nRet = m_devComm.Run_Generate(0); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// +// // Verify +// w_nRet = m_devComm.Run_Verify(m_nUserID, 0, w_nLearned); +// m_nPassedTime = SystemClock.elapsedRealtime() - m_nPassedTime; +// +// if (w_nRet == DevComm.ERR_SUCCESS) +// m_strPost = String.format("Result : Success\r\nTemplate No : %d, Learn Result : %d\r\nMatch Time : %dms", m_nUserID, w_nLearned[0], m_nPassedTime); +// else +// m_strPost = GetErrorMsg(w_nRet); +// +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// } +// }).start(); +// } +// +// private void OnIdentifyBtn() { +// if (!m_devComm.IsInit()) +// return; +// +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_devComm.Run_SLEDControl(1); +// m_bCancel = false; +// +// m_strPost = ""; +// +// new Thread(new Runnable() { +// int w_nRet; +// final int[] w_nID = new int[1]; +// final int[] w_nLearned = new int[1]; +// final int[] w_nWidth = new int[1]; +// final int[] w_nHeight = new int[1]; +// +// @Override +// public void run() { +// +// while(true) +// { +// if (m_strPost.isEmpty()) +// m_strPost = "Input your finger."; +// else +// m_strPost = m_strPost + "\r\nInput your finger."; +// m_FpImageViewer.post(runShowStatus); +// +// if (Capturing() < 0) +// return; +// +// m_strPost = "Release your finger."; +// m_FpImageViewer.post(runShowStatus); +// +// // Up Cpatured Image +// if (m_devComm.m_nConnected == 2) { +// w_nRet = m_devComm.Run_UpImage(0, m_binImage, w_nWidth, w_nHeight); +// +// if (w_nRet != DevComm.ERR_SUCCESS) { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// +// // Draw image +// m_nImgWidth = w_nWidth[0]; +// m_nImgHeight = w_nHeight[0]; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runDrawImage); +// } +// +// // Create template +// m_nPassedTime = SystemClock.elapsedRealtime(); +// w_nRet = m_devComm.Run_Generate(0); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// +// if (w_nRet == DevComm.ERR_CONNECTION) +// { +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// else +// { +// SystemClock.sleep(1000); +// continue; +// } +// } +// +// // Identify +// w_nRet = m_devComm.Run_Search(0, 1, m_nMaxFpCount, w_nID, w_nLearned); +// m_nPassedTime = SystemClock.elapsedRealtime() - m_nPassedTime; +// +// if (w_nRet == DevComm.ERR_SUCCESS) { +// m_strPost = String.format("Result : Success\r\nTemplate No : %d, Learn Result : %d\r\nMatch Time : %dms", w_nID[0], w_nLearned[0], m_nPassedTime); +// } +// else +// { +// m_strPost = String.format("\r\nMatch Time : %dms", m_nPassedTime); +// m_strPost = GetErrorMsg(w_nRet) + m_strPost; +// } +// } +// } +// }).start(); +// } +// +// public void OnDetectFingerBtn(){ +// /* +// if (!m_devComm.IsInit()) +// return; +// m_devComm.oem_cmos_led(true); +// if (m_devComm.oem_is_press_finger() < 0 ){ +// m_txtStatus.setText("Communication error!"); +// return; +// } +// if (m_devComm.m_wLastAck == DevComm.NACK_INFO ){ +// m_txtStatus.setText(DisplayErr( m_devComm.m_nLastAckParam, 0 )); +// return; +// } +// if( m_devComm.m_nLastAckParam != 0 ){ +// m_txtStatus.setText("Finger is not pressed!"); +// m_devComm.oem_cmos_led(false); +// return; +// } +// +// m_txtStatus.setText("Finger is pressed!"); +// +// m_devComm.oem_cmos_led(false); +// */ +// } +// +// private void OnGetImageBtn() { +// GetConCaptureState(); +// +// if (m_bConCapture){ +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// } +// +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_devComm.Run_SLEDControl(1); +// m_bCancel = false; +// m_txtStatus.setText("Input finger!"); +// +// new Thread(new Runnable() { +// int w_nRet; +// final int[] width = new int[1]; +// final int[] height = new int[1]; +// +// @Override +// public void run() { +// +// if (Capturing() < 0) +// return; +// +// m_strPost = "Release Finger\nUploading Image..."; +// m_FpImageViewer.post(runShowStatus); +// +// w_nRet = m_devComm.Run_UpImage(0, m_binImage, width, height); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_strPost = GetErrorMsg(w_nRet); +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return; +// } +// +// m_nImgWidth = width[0]; m_nImgHeight = height[0]; +// m_strPost = "Get Image OK !"; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runDrawImage); +// m_FpImageViewer.post(runEnableCtrl); +// } +// }).start(); +// } +// +// private void OnCancelBtn() { +// m_bCancel = true; +// } +// +// private void OnGetUserCount() { +// int w_nRet; +// int[] w_nEnrollCount = new int[1]; +// +// if (!m_devComm.IsInit()) +// return; +// +// w_nRet = m_devComm.Run_GetEnrollCount(1, m_nMaxFpCount, w_nEnrollCount); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// m_txtStatus.setText(String.format("Result : Success\r\nEnroll Count = %d", w_nEnrollCount[0])); +// } +// +// private void OnGetEmptyID() { +// int w_nRet; +// int[] w_nEmptyID = new int[1]; +// +// if (!m_devComm.IsInit()) +// return; +// +// w_nRet = m_devComm.Run_GetEmptyID(1, m_nMaxFpCount, w_nEmptyID); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// m_txtStatus.setText(String.format("Result : Success\r\nEmpty ID = %d", w_nEmptyID[0])); +// m_editUserID.setText(String.format("%d", w_nEmptyID[0])); +// } +// +// private void OnDeleteIDBtn() { +// int w_nRet; +// +// if (!m_devComm.IsInit()) +// return; +// +// if (!CheckUserID()) +// return; +// +// w_nRet = m_devComm.Run_DelChar(m_nUserID, m_nUserID); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// m_txtStatus.setText("Delete OK !"); +// } +// +// private void OnDeleteAllBtn() { +// int w_nRet; +// +// if (!m_devComm.IsInit()) +// return; +// +// w_nRet = m_devComm.Run_DelChar(1, m_nMaxFpCount); +// +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// return; +// } +// +// m_txtStatus.setText("Delete all OK !"); +// } +// +// private void OnGetTemplate() { +// int w_nRet; +// byte[] w_pTemplate = new byte[DevComm.MAX_DATA_LEN]; +// int[] w_nSize = new int[1]; +// +// // Check Device Connection +// if (!m_devComm.IsInit()) +// return; +// +// // Check User ID +// if (!CheckUserID()) +// return; +// +// // check permission +// if (!permissionGranted()) { +// requestPermission(); +// return; +// } +// +// do +// { +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// +// // Load Template to Buffer +// w_nRet = m_devComm.Run_LoadChar((short)m_nUserID, 0); +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// break; +// } +// +// // Up Template +// w_nRet = m_devComm.Run_UpChar(0, w_pTemplate, w_nSize); +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet)); +// break; +// } +// +// //////////////////////////////////////////////////////////////////// +// // Save Template (/FPData/01.fpt) +// // Create Directory +// String w_szSaveDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FPData"; +// File w_fpDir = new File(w_szSaveDirPath); +// if (!w_fpDir.exists()) +// w_fpDir.mkdirs(); +// +// // Create Template File +// File w_fpTemplate = new File(w_szSaveDirPath + "/" + m_nUserID + ".fpt"); +// if (!w_fpTemplate.exists()) +// { +// try +// { +// w_fpTemplate.createNewFile(); +// } catch (IOException e) +// { +// e.printStackTrace(); +// } +// } +// +// // Save Template Data +// FileOutputStream w_foTemplate = null; +// try +// { +// w_foTemplate = new FileOutputStream(w_fpTemplate); +// w_foTemplate.write(w_pTemplate, 0, w_nSize[0]); +// w_foTemplate.close(); +// // Show Status +// m_txtStatus.setText(String.format("Result : Get Template Success.\r\nDir : %s", w_szSaveDirPath + "/" + m_nUserID + ".fpt")); +// break; +// } catch (Exception e) +// { +// e.printStackTrace(); +// } +// //////////////////////////////////////////////////////////////////// +// +// m_txtStatus.setText("Result : Get Template Success.\r\nSave Template Failed."); +// } while (false); +// +// EnableCtrl(true); +// m_btnCloseDevice.setEnabled(true); +// m_btnCancel.setEnabled(false); +// } +// +// private void OnSetTemplate() { +// int w_nRet; +// int[] w_nDupTmplNo = new int[1]; +// byte[] w_pTemplate = new byte[DevComm.MAX_DATA_LEN]; +// int w_nTemplateSize = 0; +// +// // Check Device Connection +// if (!m_devComm.IsInit()) +// return; +// +// // Check User ID +// if (!CheckUserID()) +// return; +// +// // check permission +// if (!permissionGranted()) { +// requestPermission(); +// return; +// } +// +// //////////////////////////////////////////////////////////////////// +// // Load Template (/FPData/01.fpt) +// // Check Directory +// String w_szLoadDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FPData"; +// File w_fpDir = new File(w_szLoadDirPath); +// if (!w_fpDir.exists()) +// { +// m_txtStatus.setText(String.format("Result : Can't load template data.\r\nDir : %s", w_szLoadDirPath + "/" + m_nUserID + ".fpt")); +// return; +// } +// +// // Check Template File +// File w_fpTemplate = new File(w_szLoadDirPath + "/" + m_nUserID + ".fpt"); +// if (!w_fpTemplate.exists()) +// { +// m_txtStatus.setText(String.format("Result : Can't load template data.\r\nDir : %s", w_szLoadDirPath + "/" + m_nUserID + ".fpt")); +// return; +// } +// +// // Load Template Data +// FileInputStream w_fiTemplate = null; +// +// try +// { +// w_fiTemplate = new FileInputStream(w_fpTemplate); +// w_nTemplateSize = w_fiTemplate.available(); +// w_fiTemplate.read(w_pTemplate, 0, w_nTemplateSize); +// w_fiTemplate.close(); +// } catch (Exception e) +// { +// e.printStackTrace(); +// m_txtStatus.setText(String.format("Result : Can't load template data.\r\nDir : %s", w_szLoadDirPath + "/" + m_nUserID + ".fpt")); +// return; +// } +// //////////////////////////////////////////////////////////////////// +// +// do +// { +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// +// // Download Template to Buffer +// w_nRet = m_devComm.Run_DownChar(0, w_pTemplate, w_nTemplateSize); +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet) + "Run_DownChar"); +// break; +// } +// +// // Store Template +// w_nRet = m_devComm.Run_StoreChar(m_nUserID, 0, w_nDupTmplNo); +// if (w_nRet != DevComm.ERR_SUCCESS) +// { +// if(w_nRet == DevComm.ERR_DUPLICATION_ID) +// { +// m_txtStatus.setText(String.format("Result : Fail\r\nDuplication ID = %d", w_nDupTmplNo[0])); +// } +// else +// { +// m_txtStatus.setText(GetErrorMsg(w_nRet) + "Run_StoreChar"); +// } +// break; +// } +// +// m_txtStatus.setText(String.format("Result : Set Template Success.\r\nUserID = %d", m_nUserID)); +// } while (false); +// +// EnableCtrl(true); +// m_btnCloseDevice.setEnabled(true); +// m_btnCancel.setEnabled(false); +// } +// +// private void OnGetMultiTemplate() { +// // Check Device Connection +// if (!m_devComm.IsInit()) +// return; +// +// // check permission +// if (!permissionGranted()) { +// requestPermission(); +// return; +// } +// +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_bCancel = false; +// m_strPost = ""; +// +// new Thread(new Runnable() { +// @Override +// public void run() { +// int w_nRet; +// byte[] w_pTemplate = new byte[DevComm.MAX_DATA_LEN]; +// int[] w_nSize = new int[1]; +// int w_nUserId; +// +// for (w_nUserId = 1; w_nUserId <= m_nMaxFpCount; w_nUserId++) +// { +// // Load Template to Buffer +// w_nRet = m_devComm.Run_LoadChar((short)w_nUserId, 0); +// if (w_nRet != DevComm.ERR_SUCCESS) +// continue; +// +// // Up Template +// w_nRet = m_devComm.Run_UpChar(0, w_pTemplate, w_nSize); +// if (w_nRet != DevComm.ERR_SUCCESS) +// continue; +// +// //////////////////////////////////////////////////////////////////// +// // Save Template (/FPData/01.fpt) +// // Create Directory +// String w_szSaveDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FPData"; +// File w_fpDir = new File(w_szSaveDirPath); +// if (!w_fpDir.exists()) +// w_fpDir.mkdirs(); +// +// // Create Template File +// File w_fpTemplate = new File(w_szSaveDirPath + "/" + w_nUserId + ".fpt"); +// if (!w_fpTemplate.exists()) +// { +// try +// { +// w_fpTemplate.createNewFile(); +// } catch (IOException e) +// { +// e.printStackTrace(); +// } +// } +// +// // Save Template Data +// FileOutputStream w_foTemplate = null; +// try +// { +// w_foTemplate = new FileOutputStream(w_fpTemplate); +// w_foTemplate.write(w_pTemplate, 0, w_nSize[0]); +// w_foTemplate.close(); +// // Show Status +// m_strPost = String.format("Result : Get Template Success.\r\nDir : %s", +// w_szSaveDirPath + "/" + w_nUserId + ".fpt"); +// m_FpImageViewer.post(runShowStatus); +// continue; +// } catch (Exception e) +// { +// e.printStackTrace(); +// } +// //////////////////////////////////////////////////////////////////// +// +// m_strPost = "Result : Get Template Success.\r\nSave Template Failed."; +// m_FpImageViewer.post(runShowStatus); +// +// if (m_bCancel){ +// StopOperation(); +// return; +// } +// } +// +// m_strPost = "Get multiple template is finished"; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// } +// }).start(); +// } +// +// private void OnSetMultiTemplate() { +// // Check Device Connection +// if (!m_devComm.IsInit()) +// return; +// +// // check permission +// if (!permissionGranted()) { +// requestPermission(); +// return; +// } +// +// EnableCtrl(false); +// m_btnCloseDevice.setEnabled(false); +// m_btnCancel.setEnabled(true); +// m_bCancel = false; +// m_strPost = ""; +// +// new Thread(new Runnable() { +// @Override +// public void run() { +// int w_nRet; +// int[] w_nDupTmplNo = new int[1]; +// byte[] w_pTemplate = new byte[DevComm.MAX_DATA_LEN]; +// int w_nTemplateSize = 0; +// int w_nUserId; +// +// for (w_nUserId = 1; w_nUserId <= m_nMaxFpCount; w_nUserId++) { +// //////////////////////////////////////////////////////////////////// +// // Load Template (/FPData/01.fpt) +// // Check Directory +// String w_szLoadDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FPData"; +// File w_fpDir = new File(w_szLoadDirPath); +// if (!w_fpDir.exists()) +// continue; +// +// // Check Template File +// File w_fpTemplate = new File(w_szLoadDirPath + "/" + w_nUserId + ".fpt"); +// if (!w_fpTemplate.exists()) { +// continue; +// } +// +// // Load Template Data +// FileInputStream w_fiTemplate = null; +// +// try { +// w_fiTemplate = new FileInputStream(w_fpTemplate); +// w_nTemplateSize = w_fiTemplate.available(); +// w_fiTemplate.read(w_pTemplate, 0, w_nTemplateSize); +// w_fiTemplate.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// continue; +// } +// //////////////////////////////////////////////////////////////////// +// +// // Download Template to Buffer +// w_nRet = m_devComm.Run_DownChar(0, w_pTemplate, w_nTemplateSize); +// if (w_nRet != DevComm.ERR_SUCCESS) { +// m_txtStatus.setText(GetErrorMsg(w_nRet) + "Run_DownChar"); +// break; +// } +// +// // Store Template +// w_nRet = m_devComm.Run_StoreChar(w_nUserId, 0, w_nDupTmplNo); +// if (w_nRet != DevComm.ERR_SUCCESS) { +// if (w_nRet == DevComm.ERR_DUPLICATION_ID) { +// m_strPost = String.format("Result : Fail\r\nDuplication ID = %d", w_nDupTmplNo[0]); +// } else { +// m_strPost = GetErrorMsg(w_nRet) + "Run_StoreChar"; +// } +// m_FpImageViewer.post(runShowStatus); +// break; +// } +// +// m_strPost = String.format("Result : Set Template Success.\r\nUserID = %d", m_nUserID); +// m_FpImageViewer.post(runShowStatus); +// +// if (m_bCancel){ +// StopOperation(); +// return; +// } +// } +// +// m_strPost = "Set multiple template is finished"; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// } +// }).start(); +// } +// +// public boolean CheckUserID(){ +// String str; +// +// str = m_editUserID.getText().toString(); +// +// if(str == "" ) +// { +// m_txtStatus.setText("Please input user id"); +// return false; +// } +// +// try { +// m_nUserID = Integer.parseInt(str); +// } catch (NumberFormatException e) { +// m_txtStatus.setText("Please input correct user id(1~" + m_nMaxFpCount + ")"); +// return false; +// } +// +// if(m_nUserID > (m_nMaxFpCount) || m_nUserID < 1) +// { +// m_txtStatus.setText("Please input correct user id(1~" + m_nMaxFpCount + ")"); +// return false; +// } +// +// return true; +// } +// +// public boolean CheckParam(int nMin, int nMax){ +// String str; +// +// str = m_editParam.getText().toString(); +// +// if(str == "" ) +// { +// m_txtStatus.setText("Please input parameter!"); +// return false; +// } +// +// try { +// m_nParam = Integer.parseInt(str); +// } catch (NumberFormatException e) { +// m_txtStatus.setText(String.format("Please input parameter (%d~%d)!", nMin, nMax)); +// return false; +// } +// +// if (m_nParam > nMax || m_nParam < nMin) +// { +// m_txtStatus.setText(String.format("Please input correct parameter (%d~%d)!", nMin, nMax)); +// return false; +// } +// +// return true; +// } +// +// private void GetConCaptureState(){ +// } +// +// private int Capturing(){ +// int w_nRet; +// while(true){ +// +// w_nRet = m_devComm.Run_GetImage(); +// +// if (w_nRet == DevComm.ERR_CONNECTION) +// { +// m_strPost = "Communication error!"; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// return -1; +// } +// else if (w_nRet == DevComm.ERR_SUCCESS) +// break; +// +// if (m_bCancel){ +// StopOperation(); +// return -1; +// } +// } +// +// return 0; +// } +// +// private void StopOperation(){ +// m_strPost = "Canceled"; +// m_FpImageViewer.post(runShowStatus); +// m_FpImageViewer.post(runEnableCtrl); +// } +// +// private String GetErrorMsg(int nErrorCode) +// { +// String str = ""; +// +// switch(nErrorCode) +// { +// case DevComm.ERR_SUCCESS: +// str = "Succcess"; +// break; +// case DevComm.ERR_VERIFY: +// str = "Verify NG"; +// break; +// case DevComm.ERR_IDENTIFY: +// str = "Identify NG"; +// break; +// case DevComm.ERR_EMPTY_ID_NOEXIST: +// str = "Empty Template no Exist"; +// break; +// case DevComm.ERR_BROKEN_ID_NOEXIST: +// str = "Broken Template no Exist"; +// break; +// case DevComm.ERR_TMPL_NOT_EMPTY: +// str = "Template of this ID Already Exist"; +// break; +// case DevComm.ERR_TMPL_EMPTY: +// str = "This Template is Already Empty"; +// break; +// case DevComm.ERR_INVALID_TMPL_NO: +// str = "Invalid Template No"; +// break; +// case DevComm.ERR_ALL_TMPL_EMPTY: +// str = "All Templates are Empty"; +// break; +// case DevComm.ERR_INVALID_TMPL_DATA: +// str = "Invalid Template Data"; +// break; +// case DevComm.ERR_DUPLICATION_ID: +// str = "Duplicated ID : "; +// break; +// case DevComm.ERR_BAD_QUALITY: +// str = "Bad Quality Image"; +// break; +// case DevComm.ERR_MERGE_FAIL: +// str = "Merge failed"; +// break; +// case DevComm.ERR_NOT_AUTHORIZED: +// str = "Device not authorized."; +// break; +// case DevComm.ERR_MEMORY: +// str = "Memory Error "; +// break; +// case DevComm.ERR_INVALID_PARAM: +// str = "Invalid Parameter"; +// break; +// case DevComm.ERR_GEN_COUNT: +// str = "Generation Count is invalid"; +// break; +// case DevComm.ERR_INVALID_BUFFER_ID: +// str = "Ram Buffer ID is invalid."; +// break; +// case DevComm.ERR_INVALID_OPERATION_MODE: +// str = "Invalid Operation Mode!"; +// break; +// case DevComm.ERR_FP_NOT_DETECTED: +// str = "Finger is not detected."; +// break; +// default: +// str = String.format("Fail, error code=%d", nErrorCode); +// break; +// } +// +// return str; +// } +// +// Runnable runShowStatus = new Runnable() { +// public void run() +// { +// m_txtStatus.setText(m_strPost); +// } +// }; +// +// Runnable runDrawImage = new Runnable() { +// public void run() +// { +// int nSize; +// +// MakeBMPBuf(m_binImage, m_bmpImage, m_nImgWidth, m_nImgHeight); +// +// if ((m_nImgWidth % 4) != 0) +// nSize = m_nImgWidth + (4 - (m_nImgWidth % 4)); +// else +// nSize = m_nImgWidth; +// +// nSize = 1078 + nSize * m_nImgHeight; +// +// //DebugManage.WriteBmp(m_bmpImage, nSize); +// +// Bitmap image = BitmapFactory.decodeByteArray(m_bmpImage, 0, nSize); +// +// m_FpImageViewer.setImageBitmap(image); +// } +// }; +// +// Runnable runEnableCtrl = new Runnable() { +// public void run() +// { +// EnableCtrl(true); +// m_btnOpenDevice.setEnabled(false); +// m_btnCloseDevice.setEnabled(true); +// m_devComm.Run_SLEDControl(0); +// } +// }; +// +// private void MakeBMPBuf(byte[] Input, byte[] Output, int iImageX, int iImageY) +// { +// +// byte[] w_bTemp = new byte[4]; +// byte[] head = new byte[1078]; +// byte[] head2={ +// /***************************/ +// //file header +// 0x42,0x4d,//file type +// //0x36,0x6c,0x01,0x00, //file size*** +// 0x0,0x0,0x0,0x00, //file size*** +// 0x00,0x00, //reserved +// 0x00,0x00,//reserved +// 0x36,0x4,0x00,0x00,//head byte*** +// /***************************/ +// //infoheader +// 0x28,0x00,0x00,0x00,//struct size +// +// //0x00,0x01,0x00,0x00,//map width*** +// 0x00,0x00,0x0,0x00,//map width*** +// //0x68,0x01,0x00,0x00,//map height*** +// 0x00,0x00,0x00,0x00,//map height*** +// +// 0x01,0x00,//must be 1 +// 0x08,0x00,//color count*** +// 0x00,0x00,0x00,0x00, //compression +// //0x00,0x68,0x01,0x00,//data size*** +// 0x00,0x00,0x00,0x00,//data size*** +// 0x00,0x00,0x00,0x00, //dpix +// 0x00,0x00,0x00,0x00, //dpiy +// 0x00,0x00,0x00,0x00,//color used +// 0x00,0x00,0x00,0x00,//color important +// }; +// +// int i,j, num, iImageStep; +// +// Arrays.fill(w_bTemp, (byte)0); +// +// System.arraycopy(head2, 0, head, 0, head2.length); +// +// if ((iImageX % 4) != 0) +// iImageStep = iImageX + (4 - (iImageX % 4)); +// else +// iImageStep = iImageX; +// +// num=iImageX; head[18]= (byte)(num & (byte)0xFF); +// num=num>>8; head[19]= (byte)(num & (byte)0xFF); +// num=num>>8; head[20]= (byte)(num & (byte)0xFF); +// num=num>>8; head[21]= (byte)(num & (byte)0xFF); +// +// num=iImageY; head[22]= (byte)(num & (byte)0xFF); +// num=num>>8; head[23]= (byte)(num & (byte)0xFF); +// num=num>>8; head[24]= (byte)(num & (byte)0xFF); +// num=num>>8; head[25]= (byte)(num & (byte)0xFF); +// +// j=0; +// for (i=54;i<1078;i=i+4) +// { +// head[i]=head[i+1]=head[i+2]=(byte)j; +// head[i+3]=0; +// j++; +// } +// +// System.arraycopy(head, 0, Output, 0, 1078); +// +// if (iImageStep == iImageX){ +// for( i = 0; i < iImageY; i ++){ +// System.arraycopy(Input, i*iImageX, Output, 1078+i*iImageX, iImageX); +// } +// } +// else{ +// iImageStep = iImageStep - iImageX; +// +// for( i = 0; i < iImageY; i ++){ +// System.arraycopy(Input, i*iImageX, Output, 1078+i*(iImageX+iImageStep), iImageX); +// System.arraycopy(w_bTemp, 0, Output, 1078+i*(iImageX+iImageStep)+iImageX, iImageStep); +// } +// } +// } +// +// private final IUsbConnState m_IConnectionHandler = new IUsbConnState() { +// @Override +// public void onUsbConnected() { +// String[] w_strInfo = new String[1]; +// +// if (m_devComm.Run_TestConnection() == DevComm.ERR_SUCCESS) +// { +// if (m_devComm.Run_GetDeviceInfo(w_strInfo) == DevComm.ERR_SUCCESS) +// { +// EnableCtrl(true); +// m_btnOpenDevice.setEnabled(false); +// m_btnCloseDevice.setEnabled(true); +// m_txtStatus.setText("Open Success!\r\nDevice Info : " + w_strInfo[0]); +// } +// } +// else +// m_txtStatus.setText("Can not connect to device!"); +// } +// +// @Override +// public void onUsbPermissionDenied() { +// m_txtStatus.setText("Permission denied!"); +// } +// +// @Override +// public void onDeviceNotFound() { +// m_txtStatus.setText("Can not find usb device!"); +// } +// }; +// +// private final static String[] PERMISSIONS = new String[] { +// Manifest.permission.WRITE_EXTERNAL_STORAGE, +// Manifest.permission.READ_EXTERNAL_STORAGE +// }; +// private final static int REQUEST_CODE_PERMISSION = 1; +// +// private boolean requestPermission(String[] permissions){ +// boolean valid = true; +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { +// List requestPermissions = new ArrayList<>(); +// for (String permission : permissions) { +// if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { +// requestPermissions.add(permission); +// valid = false; +// } +// } +// if (requestPermissions.size() > 0) { +// ActivityCompat.requestPermissions(this, requestPermissions.toArray(new String[requestPermissions.size()]), REQUEST_CODE_PERMISSION); +// } +// } +// return valid; +// } +// +// @Override +// protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { +// super.onActivityResult(requestCode, resultCode, data); +// } +// +// private boolean permissionGranted(){ +// return ContextCompat.checkSelfPermission( +// this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED +// && ContextCompat.checkSelfPermission( +// this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; +// } +// private void requestPermission(){ +// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1); +// } +//} diff --git a/android/src/main/java/com/idworld/noemhost_and/UsbController.java b/android/src/main/java/com/idworld/noemhost_and/UsbController.java new file mode 100644 index 0000000..2881294 --- /dev/null +++ b/android/src/main/java/com/idworld/noemhost_and/UsbController.java @@ -0,0 +1,440 @@ +package com.idworld.noemhost_and; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbConstants; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.hardware.usb.UsbEndpoint; +import android.hardware.usb.UsbInterface; +import android.hardware.usb.UsbManager; +import android.os.SystemClock; +import android.util.Log; +import android.widget.Toast; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; + +/** + * Created by KMS on 2016/8/23. + */ +public class UsbController { + private final Context mApplicationContext; + private final UsbManager mUsbManager; + private final int VID; + private final int PID; + private int m_nEPInSize, m_nEPOutSize; + + private final byte[] m_abyTransferBuf; + private boolean m_bInit = false; + private UsbDeviceConnection m_usbConn = null; + private UsbInterface m_usbIf = null; + private UsbEndpoint m_epIN = null; + private UsbEndpoint m_epOUT = null; + private final IUsbConnState mConnectionHandler; + + protected static final String ACTION_USB_PERMISSION = "ch.serverbox.android.USB"; + + /** + * Activity is needed for onResult + * + * @param parentActivity + */ + public UsbController(Activity parentActivity, IUsbConnState connectionHandler, int vid, int pid){ + mConnectionHandler = connectionHandler; + mApplicationContext = parentActivity.getApplicationContext(); + mUsbManager = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE); + VID = vid; + PID = pid; + m_abyTransferBuf = new byte[512]; + //init(); + } + + public void init(){ + enumerate(new IPermissionListener() { + @Override + public void onPermissionDenied(UsbDevice d) { + UsbManager usbman = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE); + PendingIntent pi = PendingIntent.getBroadcast(mApplicationContext, 0, new Intent(ACTION_USB_PERMISSION), FLAG_IMMUTABLE); + mApplicationContext.registerReceiver(mPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION)); + usbman.requestPermission(d, pi); + } + }); + } + + public void uninit(){ + if (m_usbConn != null) + { + m_usbConn.releaseInterface(m_usbIf); + m_usbConn.close(); + m_usbConn = null; + m_bInit = false; + } + + //stop(); + } + + public void stop() + { + try{ + mApplicationContext.unregisterReceiver(mPermissionReceiver); + }catch(IllegalArgumentException e){}//bravo + } + + public boolean IsInit(){ + return m_bInit; + } + + private void enumerate(IPermissionListener listener) { + boolean bFound = false; + l("enumerating"); + HashMap devlist = mUsbManager.getDeviceList(); + Iterator deviter = devlist.values().iterator(); + + while (deviter.hasNext()) { + UsbDevice d = deviter.next(); + l("Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId())); + + Toast.makeText(mApplicationContext, "Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId()), Toast.LENGTH_SHORT).show(); + + if (d.getVendorId() == VID && d.getProductId() == PID) { + bFound = true; + l("Device under: " + d.getDeviceName()); + if (!mUsbManager.hasPermission(d)) + { + Toast.makeText(mApplicationContext, "enumerate, hasPermission return false" , Toast.LENGTH_SHORT).show(); + listener.onPermissionDenied(d); + } + else{ + Toast.makeText(mApplicationContext, "enumerate, GetConnInerface start" , Toast.LENGTH_SHORT).show(); + //startHandler(d); + GetConnInerface(d); + //TestComm(d); + return; + } + break; + } + } + if (!bFound) + { + Toast.makeText(mApplicationContext, "no more devices found" , Toast.LENGTH_SHORT).show(); + mConnectionHandler.onDeviceNotFound(); + } + } + + private class PermissionReceiver extends BroadcastReceiver { + private final IPermissionListener mPermissionListener; + + public PermissionReceiver(IPermissionListener permissionListener) { + mPermissionListener = permissionListener; + } + + @Override + public void onReceive(Context context, Intent intent) { + mApplicationContext.unregisterReceiver(this); + if (intent.getAction().equals(ACTION_USB_PERMISSION)) { + if (!intent.getBooleanExtra( + UsbManager.EXTRA_PERMISSION_GRANTED, false)) { + mPermissionListener.onPermissionDenied(intent + .getParcelableExtra(UsbManager.EXTRA_DEVICE)); + + mConnectionHandler.onUsbPermissionDenied(); + } else { + l("Permission granted"); + UsbDevice dev = intent + .getParcelableExtra(UsbManager.EXTRA_DEVICE); + if (dev != null) { + if (dev.getVendorId() == VID + && dev.getProductId() == PID) { + //startHandler(dev);// has new thread + GetConnInerface(dev); + //TestComm(dev); + } + } else { + mConnectionHandler.onDeviceNotFound(); + } + } + } + } + } + + private void GetConnInerface(UsbDevice dev){ + int n; + + m_usbConn = mUsbManager.openDevice(dev); + + n = dev.getInterfaceCount(); + + if (n <= 0) + return; + + if (!m_usbConn.claimInterface(dev.getInterface(0), true)) { + return; + } + + m_usbIf = dev.getInterface(0); + + n = m_usbIf.getEndpointCount(); + + if (n < 2) + return; + + for (int i = 0; i < n; i++) { + if (m_usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { + if (m_usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) + m_epIN = m_usbIf.getEndpoint(i); + else + m_epOUT = m_usbIf.getEndpoint(i); + } + } + + m_nEPInSize = m_epIN.getMaxPacketSize(); + m_nEPOutSize = m_epOUT.getMaxPacketSize(); + + m_bInit = true; + + //m_epOUT.getMaxPacketSize(); + + //Toast.makeText(mApplicationContext, "GetConnInerface OK, Out Max Size="+m_nEPOutSize+" In Max Size=" + m_nEPInSize, Toast.LENGTH_SHORT).show(); + mConnectionHandler.onUsbConnected(); + } + + public boolean OperationInternal(byte[] pData, int nDataLen, int nTimeOut, boolean bRead) + { + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = (byte)(nDataLen & 0xFF); + w_abyTmp[9] = (byte)((nDataLen >> 8)& 0xFF); + w_abyTmp[10] = (byte)((nDataLen >> 16)& 0xFF); + w_abyTmp[11] = (byte)((nDataLen >> 24)& 0xFF); + + if(bRead) + w_abyTmp[12] = (byte)0x80; + else + w_abyTmp[12] = 0x00; //cCBWFlags + + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + w_abyTmp[15] = (byte)0xef; + if (bRead) + w_abyTmp[16] = (byte)0xff; + else + w_abyTmp[16] = (byte)0xfe; + + // send 31bytes + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + // read or write real data + if (bRead) + w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut); + else + w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + public boolean UsbSCSIWrite(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut) + { + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + //Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = 0x00; + w_abyTmp[9] = 0x00; + w_abyTmp[10] = 0x00; + w_abyTmp[11] = 0x00; + w_abyTmp[12] = 0x00; //cCBWFlags + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen); + //System.arraycopy(pData, 0, w_abyTmp, 31, nDataLen); + + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + public boolean UsbSCSIRead(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut) + { + long w_nTime; + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + //Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = 0x00; + w_abyTmp[9] = 0x00; + w_abyTmp[10] = 0x00; + w_abyTmp[11] = 0x00; + w_abyTmp[12] = (byte)0x80; //cCBWFlags + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen); + + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + w_nTime = SystemClock.elapsedRealtime(); + + w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut); + + w_nTime = SystemClock.elapsedRealtime() - w_nTime; + + //Toast.makeText(mApplicationContext, "UsbSCSIRead, UsbBulkReceive Time : " + w_nTime , Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + private boolean UsbBulkSend(byte[] pBuf, int nLen, int nTimeOut) + { + int i, n, r, w_nRet; + //byte[] w_abyTmp = new byte[m_nEPOutSize]; + + n = nLen / m_nEPOutSize; + r = nLen % m_nEPOutSize; + + for(i=0; i 0) + { + System.arraycopy(pBuf, i*m_nEPOutSize, m_abyTransferBuf, 0, r); + + w_nRet = m_usbConn.bulkTransfer(m_epOUT, m_abyTransferBuf, r, nTimeOut); + + return w_nRet == r; + } + + return true; + } + + private boolean UsbBulkReceive(byte[] pBuf, int nLen, int nTimeOut) + { + int i, n, r, w_nRet; + //byte[] w_abyTmp = new byte[m_nEPInSize]; + + //w_nRet = m_usbConn.bulkTransfer(m_epIN, pBuf, nLen, nTimeOut); + + //if (w_nRet != nLen) + // return false; + + n = nLen / m_nEPInSize; + r = nLen % m_nEPInSize; + + //Toast.makeText(mApplicationContext, "UsbBulkReceive, Buf Len = " + pBuf.length, Toast.LENGTH_SHORT).show(); + + for(i=0; i 0) + { + w_nRet = m_usbConn.bulkTransfer(m_epIN, m_abyTransferBuf, r, nTimeOut); + + if (w_nRet != r) + return false; + + System.arraycopy(m_abyTransferBuf, 0, pBuf, i*m_nEPInSize, r); + } + + return true; + } + + // END MAIN LOOP + private final BroadcastReceiver mPermissionReceiver = new PermissionReceiver( + new IPermissionListener() { + @Override + public void onPermissionDenied(UsbDevice d) { + l("Permission denied on " + d.getDeviceId()); + } + }); + + private interface IPermissionListener { + void onPermissionDenied(UsbDevice d); + } + + public final static String TAG = "USBController"; + + private void l(Object msg) { + Log.d(TAG, ">==< " + msg.toString() + " >==<"); + } +} diff --git a/android/src/main/java/com/xiarui/zhiwen/DevComm.java b/android/src/main/java/com/xiarui/zhiwen/DevComm.java new file mode 100644 index 0000000..b5f136d --- /dev/null +++ b/android/src/main/java/com/xiarui/zhiwen/DevComm.java @@ -0,0 +1,1842 @@ +package com.xiarui.zhiwen; + +import android.app.Activity; +import android.content.Context; +import android.os.SystemClock; +import android.util.Log; +import android.widget.Spinner; +import android.widget.Toast; + +import java.io.IOException; +import java.security.InvalidParameterException; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; + +import android_serialport_api.ComBean; +import android_serialport_api.SerialHelper; + +import android.util.Log; + +/** + * Created by KMS on 2016/8/23. + */ +public class DevComm { + public static final int MAX_DATA_LEN = 2048; + public static final int IMAGE_DATA_UNIT = 496; + public static final int ID_NOTE_SIZE = 64; + public static final int MODULE_SN_LEN = 16; + public static final int CHAR_SPLIT_UNIT = 496; + public static final int CHAR_SPLIT_THR = 1024; + public static final int UART_MAX_BUF_SIZE = (500 * 1024); + public static final int UART_READ_TIMEOUT = 5000; + + private static final int SCSI_TIMEOUT = 5000; //ms + private static final int COMM_SLEEP_TIME = 40; //ms + + private static final int CMD_PACKET_LEN = 26; + private static final int RCM_PACKET_LEN = 26; + private static final int RCM_DATA_OFFSET = 10; + + /***************************************************************************/ + /***************************************************************************/ + private static final int CMD_PREFIX_CODE = 0xAA55; + private static final int CMD_DATA_PREFIX_CODE = 0xA55A; + private static final int RCM_PREFIX_CODE = 0x55AA; + private static final int RCM_DATA_PREFIX_CODE = 0x5AA5; + + /*************************************************************************** + * System Code (0x0000 ~ 0x001F, 0x0000 : Reserved) + ***************************************************************************/ + private static final short CMD_TEST_CONNECTION = 0x0001; + private static final short CMD_SET_PARAM = 0x0002; + private static final short CMD_GET_PARAM = 0x0003; + private static final short CMD_GET_DEVICE_INFO = 0x0004; + private static final short CMD_ENTER_ISPMODE = 0x0005; + private static final short CMD_SET_ID_NOTE = 0x0006; + private static final short CMD_GET_ID_NOTE = 0x0007; + private static final short CMD_SET_MODULE_SN = 0x0008; + private static final short CMD_GET_MODULE_SN = 0x0009; + + /*************************************************************************** + * Sensor Code (0x0020 ~ 0x003F) + ***************************************************************************/ + private static final short CMD_GET_IMAGE = 0x0020; + private static final short CMD_FINGER_DETECT = 0x0021; + private static final short CMD_UP_IMAGE = 0x0022; + private static final short CMD_DOWN_IMAGE = 0x0023; + private static final short CMD_SLED_CTRL = 0x0024; + + /*************************************************************************** + * Template Code (0x0040 ~ 0x005F) + ***************************************************************************/ + private static final short CMD_STORE_CHAR = 0x0040; + private static final short CMD_LOAD_CHAR = 0x0041; + private static final short CMD_UP_CHAR = 0x0042; + private static final short CMD_DOWN_CHAR = 0x0043; + private static final short CMD_DEL_CHAR = 0x0044; + private static final short CMD_GET_EMPTY_ID = 0x0045; + private static final short CMD_GET_STATUS = 0x0046; + private static final short CMD_GET_BROKEN_ID = 0x0047; + private static final short CMD_GET_ENROLL_COUNT = 0x0048; + + /*************************************************************************** + * FingerPrint Alagorithm Code (0x0060 ~ 0x007F) + ***************************************************************************/ + private static final short CMD_GENERATE = 0x0060; + private static final short CMD_MERGE = 0x0061; + private static final short CMD_MATCH = 0x0062; + private static final short CMD_SEARCH = 0x0063; + private static final short CMD_VERIFY = 0x0064; + + /*************************************************************************** + * Unknown Command + ***************************************************************************/ + private static final short RCM_INCORRECT_COMMAND = 0x00FF; + + /*************************************************************************** + * Error Code + ***************************************************************************/ + public static final int ERR_SUCCESS = 0; + public static final int ERR_FAIL = 1; + public static final int ERR_CONNECTION = 2; + public static final int ERR_VERIFY = 0x10; + public static final int ERR_IDENTIFY = 0x11; + public static final int ERR_TMPL_EMPTY = 0x12; + public static final int ERR_TMPL_NOT_EMPTY = 0x13; + public static final int ERR_ALL_TMPL_EMPTY = 0x14; + public static final int ERR_EMPTY_ID_NOEXIST = 0x15; + public static final int ERR_BROKEN_ID_NOEXIST = 0x16; + public static final int ERR_INVALID_TMPL_DATA = 0x17; + public static final int ERR_DUPLICATION_ID = 0x18; + public static final int ERR_BAD_QUALITY = 0x19; + public static final int ERR_MERGE_FAIL = 0x1A; + public static final int ERR_NOT_AUTHORIZED = 0x1B; + public static final int ERR_MEMORY = 0x1C; + public static final int ERR_INVALID_TMPL_NO = 0x1D; + public static final int ERR_INVALID_PARAM = 0x22; + public static final int ERR_GEN_COUNT = 0x25; + public static final int ERR_INVALID_BUFFER_ID = 0x26; + public static final int ERR_INVALID_OPERATION_MODE = 0x27; + public static final int ERR_FP_NOT_DETECTED = 0x28; + + /*************************************************************************** + * Parameter Index + ***************************************************************************/ + public static final int DP_DEVICE_ID = 0; + public static final int DP_SECURITY_LEVEL = 1; + public static final int DP_DUP_CHECK = 2; + public static final int DP_BAUDRATE = 3; + public static final int DP_AUTO_LEARN = 4; + + /*************************************************************************** + * Device ID, Security Level + ***************************************************************************/ + public static final int MIN_DEVICE_ID = 1; + public static final int MAX_DEVICE_ID = 255; + public static final int MIN_SECURITY_LEVEL = 1; + public static final int MAX_SECURITY_LEVEL = 5; + + public static final int GD_TEMPLATE_NOT_EMPTY = 0x01; + public static final int GD_TEMPLATE_EMPTY = 0x00; + + //--------------- For Usb Communication ------------// + public int m_nPacketSize; + public byte m_bySrcDeviceID = 1, m_byDstDeviceID = 1; + public byte[] m_abyPacket = new byte[64 * 1024]; + public byte[] m_abyPacket2 = new byte[64 * 1024]; + //--------------------------------------------------// + + private final Context mApplicationContext; + private final Activity m_parentAcitivity; + private static final int VID = 0x2009; + private static final int PID = 0x7638; + + private final UsbController m_usbBase; + + // Serial Port + private final DispQueueThread DispQueue; + private final SerialControl m_SerialPort; + + // uart variables + public byte[] m_pWriteBuffer; + public byte[] m_pReadBuffer; + public byte[] m_pUARTReadBuf; + public int m_nUARTReadPos = 0; + public int m_nUARTReceivePos = 0; + + // Connection + public byte m_nConnected; // 0 : Not Connected, 1 : ttyUART, 2 : USB + + public DevComm(Activity parentActivity, IUsbConnState usbConnState){ + m_parentAcitivity = parentActivity; + mApplicationContext = parentActivity.getApplicationContext(); + + // usb init + m_usbBase = new UsbController(parentActivity, usbConnState, VID, PID); + + // init variables + m_nConnected = 0; + m_nUARTReadPos = 0; + m_nUARTReceivePos = 0; + m_pWriteBuffer = new byte[DevComm.MAX_DATA_LEN]; + m_pReadBuffer = new byte[DevComm.MAX_DATA_LEN]; + m_pUARTReadBuf = new byte[DevComm.UART_MAX_BUF_SIZE]; + + // uart thread initialize + DispQueue = new DispQueueThread(); + DispQueue.start(); + m_SerialPort = new SerialControl(); + } + + public boolean IsInit(){ + if (m_nConnected == 0) + return false; + else if (m_nConnected == 1) + return true; + else if (m_nConnected == 2) + return m_usbBase.IsInit(); + + return false; + } + + public boolean OpenComm(String p_szDevice, int p_nBaudrate){ + if (m_nConnected != 0) + return false; + + if (p_szDevice.equals("USB")) // usb mode + { + if (!m_usbBase.IsInit()) + m_usbBase.init(); + if (!m_usbBase.IsInit()) + return false; + m_nConnected = 2; + } + else // tty uart mode + { + m_SerialPort.setPort(p_szDevice); + m_SerialPort.setBaudRate(p_nBaudrate); + try + { + m_SerialPort.open(); + } catch (SecurityException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } catch (IOException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } catch (InvalidParameterException e) { + Toast.makeText(mApplicationContext, "Open ttyUART device failed!", Toast.LENGTH_SHORT).show(); + return false; + } + m_nConnected = 1; + } + + return true; + } + + public boolean CloseComm(){ + if (m_nConnected == 0) { + return false; + } + else if (m_nConnected == 1) { // tty uart mode + m_SerialPort.stopSend(); + m_SerialPort.close(); + } + else { // usb mode + m_usbBase.uninit(); + } + + m_nConnected = 0; + return true; + } + + /************************************************************************/ + /************************************************************************/ + int Run_TestConnection() + { + boolean w_bRet; + + InitCmdPacket(CMD_TEST_CONNECTION, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, (short)0); + + w_bRet = Send_Command(CMD_TEST_CONNECTION); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_SetParam(int p_nParamIndex, int p_nParamValue) + { + boolean w_bRet; + byte[] w_abyData = new byte[5]; + + w_abyData[0] = (byte)p_nParamIndex; + + //memcpy(&w_abyData[1], &p_nParamValue, 4); + w_abyData[1] = (byte)(p_nParamValue & 0x000000ff); + w_abyData[2] = (byte)((p_nParamValue & 0x0000ff00) >> 8); + w_abyData[3] = (byte)((p_nParamValue & 0x00ff0000) >> 16); + w_abyData[4] = (byte)((p_nParamValue & 0xff000000) >> 24); + + InitCmdPacket(CMD_SET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)5); + + w_bRet = Send_Command(CMD_SET_PARAM); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetParam(int p_nParamIndex, int[] p_pnParamValue) + { + boolean w_bRet; + byte[] w_abyData = new byte[1]; + + w_abyData[0] = (byte)p_nParamIndex; + + InitCmdPacket(CMD_GET_PARAM, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, (short)1); + + w_bRet = Send_Command(CMD_GET_PARAM); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memcpy(p_pnParamValue, g_pRcmPacket->m_abyData, 4); + p_pnParamValue[0] = ((m_abyPacket[RCM_DATA_OFFSET+3] << 24) & 0xFF000000) | + ((m_abyPacket[RCM_DATA_OFFSET+2] << 16) & 0x00FF0000) | + ((m_abyPacket[RCM_DATA_OFFSET+1] << 8) & 0x0000FF00) | + (m_abyPacket[RCM_DATA_OFFSET] & 0x000000FF); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetDeviceInfo(String[] p_szDevInfo) + { + int w_nDevInfoLen; + boolean w_bRet; + String w_strTmp; + byte[] w_szDevInfo; + + InitCmdPacket(CMD_GET_DEVICE_INFO, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_GET_DEVICE_INFO); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_nDevInfoLen = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + w_bRet = Receive_DataPacket(CMD_GET_DEVICE_INFO); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + //memcpy(p_szDevInfo, g_pRcmPacket->m_abyData, w_wDevInfoLen); + w_szDevInfo = new byte[w_nDevInfoLen]; + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, w_szDevInfo, 0, w_nDevInfoLen); + w_strTmp = new String(w_szDevInfo); + p_szDevInfo[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SetIDNote(int p_nTmplNo, String p_pstrNote) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[ID_NOTE_SIZE+2]; + byte[] w_abyData2 = new byte[2]; + byte[] w_abyNoteBuf = p_pstrNote.getBytes(); + + //. Assemble command packet + w_abyData2[0] = LOBYTE((short)(ID_NOTE_SIZE + 2)); + w_abyData2[1] = HIBYTE((short)(ID_NOTE_SIZE + 2)); + + InitCmdPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SET_ID_NOTE); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //. Assemble data packet + memset(w_abyData, (byte)0, ID_NOTE_SIZE+2); + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + System.arraycopy(w_abyNoteBuf, 0, w_abyData, 2, w_abyNoteBuf.length); + + InitCmdDataPacket(CMD_SET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, ID_NOTE_SIZE+2); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_SET_ID_NOTE); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetIDNote(int p_nTmplNo, String[] p_pstrNote) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[2]; + String w_strTmp; + + //. Assemble command packet + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + InitCmdPacket(CMD_GET_ID_NOTE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GET_ID_NOTE); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_bRet = Receive_DataPacket(CMD_GET_ID_NOTE); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memset(m_abyPacket2, (byte)0, ID_NOTE_SIZE+1); + memset(m_abyPacket2, (byte)0, 512); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, ID_NOTE_SIZE); + + w_strTmp = new String(m_abyPacket2); + p_pstrNote[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SetModuleSN(String p_pstrModuleSN) + { + boolean w_bRet = false; + byte[] w_abyData = p_pstrModuleSN.getBytes(); + byte[] w_abyModuleSN = new byte[MODULE_SN_LEN]; + byte[] w_abyData2 = new byte[2]; + + memset(w_abyModuleSN, (byte)0, MODULE_SN_LEN); + System.arraycopy(w_abyData, 0, w_abyModuleSN, 0, w_abyData.length); + + //. Assemble command packet + w_abyData2[0] = LOBYTE((short)(MODULE_SN_LEN)); + w_abyData2[1] = HIBYTE((short)(MODULE_SN_LEN)); + + InitCmdPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SET_MODULE_SN); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //. Assemble data packet + InitCmdDataPacket(CMD_SET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, w_abyModuleSN, MODULE_SN_LEN); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_SET_MODULE_SN); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetModuleSN(String[] p_pstrModuleSN) + { + boolean w_bRet = false; + String w_strTmp; + + //. Assemble command packet + InitCmdPacket(CMD_GET_MODULE_SN, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GET_MODULE_SN); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_bRet = Receive_DataPacket(CMD_GET_MODULE_SN); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + //memset(m_abyPacket2, (byte)0, MODULE_SN_LEN+1); + memset(m_abyPacket2, (byte)0, 512); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, m_abyPacket2, 0, MODULE_SN_LEN); + + w_strTmp = new String(m_abyPacket2); + p_pstrModuleSN[0] = w_strTmp; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetImage() + { + boolean w_bRet; + + InitCmdPacket(CMD_GET_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_GET_IMAGE); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_FingerDetect(int[] p_pnDetectResult) + { + boolean w_bRet; + + InitCmdPacket(CMD_FINGER_DETECT, m_bySrcDeviceID, m_byDstDeviceID, m_abyPacket2, 0); + + w_bRet = Send_Command(CMD_FINGER_DETECT); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnDetectResult[0] = m_abyPacket[RCM_DATA_OFFSET]; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_UpImage(int p_nType, byte[] p_pFpData, int[] p_pnImgWidth, int[] p_pnImgHeight) + { + int i, n, r, w, h, size; + boolean w_bRet; + byte[] w_abyData = new byte[1]; + + w_abyData[0] = (byte)p_nType; + + InitCmdPacket(CMD_UP_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 1); + + w_bRet = Send_Command(CMD_UP_IMAGE); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + h = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]); + + size = w * h; + n = size / IMAGE_DATA_UNIT; + r = size % IMAGE_DATA_UNIT; + + if (m_nConnected == 1) { + for (i=0; i 0) + { + w_bRet = Receive_DataPacket(CMD_UP_IMAGE); + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET + 2, p_pFpData, i * IMAGE_DATA_UNIT, r); + } + } + else if (m_nConnected == 2) { + w_bRet = USB_ReceiveImage(p_pFpData, w * h); + if (!w_bRet) + return ERR_CONNECTION; + } + else { + return ERR_CONNECTION; + } + + p_pnImgWidth[0] = w; + p_pnImgHeight[0] = h; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_DownImage(byte[] p_pData, int p_nWidth, int p_nHeight) + { + /* + int i, n, r, w, h; + boolean w_bRet; + BYTE w_abyData[840]; + + w = p_nWidth; + h = p_nHeight; + + w_abyData[0] = LOBYTE(p_nWidth); + w_abyData[1] = HIBYTE(p_nWidth); + w_abyData[2] = LOBYTE(p_nHeight); + w_abyData[3] = HIBYTE(p_nHeight); + + //. Assemble command packet + InitCmdPacket(CMD_DOWN_IMAGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + Send_Command(CMD_DOWN_IMAGE, w_bRet, m_bySrcDeviceID, m_byDstDeviceID); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + n = (w*h)/DOWN_IMAGE_DATA_UINT; + r = (w*h)%DOWN_IMAGE_DATA_UINT; + + w_bRet = USB_DownImage(m_hUsbHandle, p_pData, p_nWidth*p_nHeight); + + if(w_bRet == false) + return ERR_CONNECTION; + */ + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_SLEDControl(int p_nState) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nState); + w_abyData[1] = HIBYTE((short)p_nState); + + InitCmdPacket(CMD_SLED_CTRL, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + w_bRet = Send_Command(CMD_SLED_CTRL); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_StoreChar(int p_nTmplNo, int p_nRamBufferID, int[] p_pnDupTmplNo) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_STORE_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + //. Send command packet to target + w_bRet = Send_Command(CMD_STORE_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + { + if (GetRetCode() == ERR_DUPLICATION_ID) + p_pnDupTmplNo[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return GetRetCode(); + } + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_LoadChar(int p_nTmplNo, int p_nRamBufferID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_LOAD_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + //. Send command packet to target + w_bRet = Send_Command(CMD_LOAD_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_UpChar(int p_nRamBufferID, byte[] p_pbyTemplate, int[] p_nSize) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[2]; + short w_nTemplateSize = 0; + int w_nRemainSize = 0; + + //. Assemble command packet + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + InitCmdPacket(CMD_UP_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_UP_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + w_nTemplateSize = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + if (w_nTemplateSize < CHAR_SPLIT_THR) { + w_bRet = Receive_DataPacket(CMD_UP_CHAR); + if (!w_bRet) + return ERR_CONNECTION; + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + //memcpy(p_pbyTemplate, &g_pRcmPacket->m_abyData[0], GD_RECORD_SIZE); + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, 0, w_nTemplateSize); + } + else { + w_nRemainSize = w_nTemplateSize; + while (w_nRemainSize > 0) { + w_bRet = Receive_DataPacket(CMD_UP_CHAR); + if (!w_bRet) + return ERR_CONNECTION; + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + if (w_nRemainSize > CHAR_SPLIT_UNIT) { + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, w_nTemplateSize - w_nRemainSize, CHAR_SPLIT_UNIT); + w_nRemainSize -= CHAR_SPLIT_UNIT; + } + else { + System.arraycopy(m_abyPacket, RCM_DATA_OFFSET, p_pbyTemplate, w_nTemplateSize - w_nRemainSize, w_nRemainSize); + w_nRemainSize -= 0; + } + } + } + + p_nSize[0] = w_nTemplateSize; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_DownChar(int p_nRamBufferID, byte[] p_pbyTemplate, int p_nSize) + { + boolean w_bRet = false; + byte[] w_abyData = new byte[MAX_DATA_LEN+2]; + byte[] w_abyData2 = new byte[2]; + int w_nRemainSize = 0; + int i; + + //. Assemble command packet + if (p_nSize < CHAR_SPLIT_THR) { + w_abyData2[0] = LOBYTE((short)(p_nSize + 2)); + w_abyData2[1] = HIBYTE((short)(p_nSize + 2)); + } + else { + w_abyData2[0] = LOBYTE((short)(p_nSize + 4)); + w_abyData2[1] = HIBYTE((short)(p_nSize + 4)); + } + + InitCmdPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData2, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_DOWN_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + if( GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + SystemClock.sleep(10); + + //. Assemble data packet + if (p_nSize < CHAR_SPLIT_THR) { + w_abyData[0] = LOBYTE((short) p_nRamBufferID); + w_abyData[1] = HIBYTE((short) p_nRamBufferID); + //memcpy(&w_abyData[2], p_pbyTemplate, GD_RECORD_SIZE); + System.arraycopy(p_pbyTemplate, 0, w_abyData, 2, p_nSize); + + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, p_nSize + 2); + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_DOWN_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + } + else { + w_nRemainSize = p_nSize; + i = 0; + while (w_nRemainSize > 0) { + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = LOBYTE((short)i); + w_abyData[3] = HIBYTE((short)i); + if (w_nRemainSize > CHAR_SPLIT_UNIT) { + System.arraycopy(p_pbyTemplate, i * CHAR_SPLIT_UNIT, w_abyData, 4, CHAR_SPLIT_UNIT); + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, CHAR_SPLIT_UNIT + 4); + w_nRemainSize -= CHAR_SPLIT_UNIT; + } + else { + System.arraycopy(p_pbyTemplate, i * CHAR_SPLIT_UNIT, w_abyData, 4, w_nRemainSize); + InitCmdDataPacket(CMD_DOWN_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, w_nRemainSize + 4); + w_nRemainSize -= 0; + } + + //. Send data packet to target + w_bRet = Send_DataPacket(CMD_DOWN_CHAR); + + if (!w_bRet) + return ERR_CONNECTION; + + i++; + } + } + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_DelChar(int p_nSTmplNo, int p_nETmplNo) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_DEL_CHAR, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_DEL_CHAR); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_GetEmptyID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEmptyID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_EMPTY_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_EMPTY_ID); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + p_pnEmptyID[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetStatus(int p_nTmplNo, int[] p_pnStatus) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + + InitCmdPacket(CMD_GET_STATUS, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + w_bRet = Send_Command(CMD_GET_STATUS); + + if(!w_bRet) + return ERR_CONNECTION; + + if ( GetRetCode() != ERR_SUCCESS ) + return GetRetCode(); + + p_pnStatus[0] = m_abyPacket[RCM_DATA_OFFSET]; + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetBrokenID(int p_nSTmplNo, int p_nETmplNo, int[] p_pnCount, int[] p_pnFirstID) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_BROKEN_ID, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_BROKEN_ID); + + if(!w_bRet) + return ERR_CONNECTION; + + if (GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnCount[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + p_pnFirstID[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET+2], m_abyPacket[RCM_DATA_OFFSET+3]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_GetEnrollCount(int p_nSTmplNo, int p_nETmplNo, int[] p_pnEnrollCount) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nSTmplNo); + w_abyData[1] = HIBYTE((short)p_nSTmplNo); + w_abyData[2] = LOBYTE((short)p_nETmplNo); + w_abyData[3] = HIBYTE((short)p_nETmplNo); + + //. Assemble command packet + InitCmdPacket(CMD_GET_ENROLL_COUNT, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_GET_ENROLL_COUNT); + + if (!w_bRet) + return ERR_CONNECTION; + + if(GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnEnrollCount[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + + return ERR_SUCCESS; + } + /************************************************************************/ + /************************************************************************/ + int Run_Generate(int p_nRamBufferID) + { + boolean w_bRet; + byte[] w_abyData = new byte[2]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + + InitCmdPacket(CMD_GENERATE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 2); + + //. Send command packet to target + w_bRet = Send_Command(CMD_GENERATE); + + if(!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Merge(int p_nRamBufferID, int p_nMergeCount) + { + boolean w_bRet; + byte[] w_abyData = new byte[3]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = (byte)p_nMergeCount; + + InitCmdPacket(CMD_MERGE, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 3); + + w_bRet = Send_Command(CMD_MERGE); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Match(int p_nRamBufferID0, int p_nRamBufferID1) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID0); + w_abyData[1] = HIBYTE((short)p_nRamBufferID0); + w_abyData[2] = LOBYTE((short)p_nRamBufferID1); + w_abyData[3] = HIBYTE((short)p_nRamBufferID1); + + InitCmdPacket(CMD_MATCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_MATCH); + + if (!w_bRet) + return ERR_CONNECTION; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Search(int p_nRamBufferID, int p_nStartID, int p_nSearchCount, int[] p_pnTmplNo, int[] p_pnLearnResult) + { + boolean w_bRet; + byte[] w_abyData = new byte[6]; + + w_abyData[0] = LOBYTE((short)p_nRamBufferID); + w_abyData[1] = HIBYTE((short)p_nRamBufferID); + w_abyData[2] = LOBYTE((short)p_nStartID); + w_abyData[3] = HIBYTE((short)p_nStartID); + w_abyData[4] = LOBYTE((short)p_nSearchCount); + w_abyData[5] = HIBYTE((short)p_nSearchCount); + + InitCmdPacket(CMD_SEARCH, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 6); + + //. Send command packet to target + w_bRet = Send_Command(CMD_SEARCH); + + if (!w_bRet) + return ERR_CONNECTION; + + if(GetRetCode() != ERR_SUCCESS) + return GetRetCode(); + + p_pnTmplNo[0] = MAKEWORD(m_abyPacket[RCM_DATA_OFFSET], m_abyPacket[RCM_DATA_OFFSET+1]); + p_pnLearnResult[0] = m_abyPacket[RCM_DATA_OFFSET+2]; + + return GetRetCode(); + } + /************************************************************************/ + /************************************************************************/ + int Run_Verify(int p_nTmplNo, int p_nRamBufferID, int[] p_pnLearnResult) + { + boolean w_bRet; + byte[] w_abyData = new byte[4]; + + w_abyData[0] = LOBYTE((short)p_nTmplNo); + w_abyData[1] = HIBYTE((short)p_nTmplNo); + w_abyData[2] = LOBYTE((short)p_nRamBufferID); + w_abyData[3] = HIBYTE((short)p_nRamBufferID); + + //. Assemble command packet + InitCmdPacket(CMD_VERIFY, m_bySrcDeviceID, m_byDstDeviceID, w_abyData, 4); + + w_bRet = Send_Command(CMD_VERIFY); + + if (!w_bRet) + return ERR_CONNECTION; + + p_pnLearnResult[0] = m_abyPacket[RCM_DATA_OFFSET+2]; + + return GetRetCode(); + } + + public boolean GetDeviceInformation(String[] deviceInfo) + { + int[] w_nRecvLen = new int[1]; + byte[] w_abyPCCmd = new byte[6]; + byte[] w_abyData = new byte[32]; + + String w_strTmp; + boolean w_bRet; + + Arrays.fill(w_abyPCCmd, (byte) 0); + + w_abyPCCmd[2] = 0x04; + + w_bRet = SendPackage(w_abyPCCmd, w_abyData); + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, SendPackage ret = " + w_bRet, Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + { + return false; + } + + w_bRet = RecvPackage(w_abyData, w_nRecvLen); + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, RecvPackage : " + w_bRet, Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + { + return false; + } + + w_strTmp = new String(w_abyData); + deviceInfo[0] = w_strTmp; + + //Toast.makeText(mApplicationContext, "GetDeviceInformation, Recv Data : " + w_strTmp, Toast.LENGTH_SHORT).show(); + + return true; + } + + + + private boolean SendPackage(byte[] pPCCmd, byte[] pData) + { + int nDataLen; + + pPCCmd[0] = (byte)0xEF; + pPCCmd[1] = 0x01; + + nDataLen = ((pPCCmd[5] << 8) & 0x0000FF00) | (pPCCmd[4] & 0x000000FF); + + return m_usbBase.UsbSCSIWrite(pPCCmd, 6, pData, nDataLen, 5000); + } + + private boolean RecvPackage(byte[] pData, int[] pLevRen) + { + int w_nLen; + byte[] w_abyPCCmd = new byte[6]; + byte[] w_abyRespond = new byte[4]; + boolean w_bRet; + + w_abyPCCmd[0] = (byte)0xEF; + w_abyPCCmd[1] = 0x02; + w_abyPCCmd[2] = 0; + w_abyPCCmd[3] = 0; + w_abyPCCmd[4] = 0; + w_abyPCCmd[5] = 0; + + // receive status + w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, w_abyRespond, 4, 5000); + + if (!w_bRet) + return false; + + // receive data + //w_nLen = (int)((w_abyRespond[3] << 8) | w_abyRespond[2]); + w_nLen = ((w_abyRespond[3] << 8) & 0x0000FF00) | (w_abyRespond[2] & 0x000000FF); + + if (w_nLen > 0) + { + //w_nTime = SystemClock.elapsedRealtime(); + + w_abyPCCmd[1] = 0x03; + w_bRet = m_usbBase.UsbSCSIRead(w_abyPCCmd, 6, pData, w_nLen, 5000); + + //w_nTime = SystemClock.elapsedRealtime() - w_nTime; + + if (!w_bRet) + return false; + + pLevRen[0] = w_nLen; + } + + return true; + } + + /*************************************************************************** + * Get Return Code + ***************************************************************************/ + private short GetRetCode() + { + return (short)(((m_abyPacket[9] << 8) & 0x0000FF00) | (m_abyPacket[8] & 0x000000FF)); + } + + /*************************************************************************** + * Get Data Length + ***************************************************************************/ + private short GetDataLen() + { + return (short)(((m_abyPacket[7] << 8) & 0x0000FF00) | (m_abyPacket[6] & 0x000000FF)); + } + + /*************************************************************************** + * Set Data Length + ***************************************************************************/ + private void SetDataLen(short p_wDataLen) + { + m_abyPacket[6] = (byte)(p_wDataLen & 0xFF); + m_abyPacket[7] = (byte)(((p_wDataLen & 0xFF00) >> 8) & 0xFF); + } + + /*************************************************************************** + * Set Command Data + ***************************************************************************/ + private void SetCmdData(short p_wData, boolean p_bFirst) + { + if (p_bFirst) + { + m_abyPacket[8] = (byte)(p_wData & 0xFF); + m_abyPacket[9] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF); + } + else + { + m_abyPacket[10] = (byte)(p_wData & 0xFF); + m_abyPacket[11] = (byte)(((p_wData & 0xFF00) >> 8) & 0xFF); + } + } + + /*************************************************************************** + * Get Command Data + ***************************************************************************/ + private short GetCmdData(boolean p_bFirst) + { + if (p_bFirst) + { + return (short)(((m_abyPacket[9] << 8) & 0x0000FF00) | (m_abyPacket[8] & 0x000000FF)); + } + else + { + return (short)(((m_abyPacket[11] << 8) & 0x0000FF00) | (m_abyPacket[10] & 0x000000FF)); + } + } + + /*************************************************************************** + * Get 2bytes packet checksum(pDataPkt[0] + pDataPkt[1] + ....) + ***************************************************************************/ + private short CalcChkSumOfPkt(byte[] pDataPkt, int nSize) + { + int i, nChkSum = 0; + + for(i=0;im_wPrefix = CMD_PREFIX_CODE; + m_abyPacket[0] = (byte)(CMD_PREFIX_CODE & 0xFF); + m_abyPacket[1] = (byte)((CMD_PREFIX_CODE >> 8) & 0xFF); + + //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID; + m_abyPacket[2] = bySrcDeviceID; + + //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID; + m_abyPacket[3] = byDstDeviceID; + + //g_pCmdPacket->m_wCMDCode = p_wCMDCode; + m_abyPacket[4] = (byte)(wCMDCode & 0xFF); + m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF); + + //g_pCmdPacket->m_wDataLen = p_wDataLen; + m_abyPacket[6] = (byte)(nDataLen & 0xFF); + m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF); + + if (nDataLen > 0) + //memcpy(g_pCmdPacket->m_abyData, p_pbyData, wDataLen); + System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen); + + w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, CMD_PACKET_LEN-2); + + //g_pCmdPacket->m_wCheckSum = w_wCheckSum; + m_abyPacket[24] = (byte)(w_wCheckSum & 0xFF); + m_abyPacket[25] = (byte)((w_wCheckSum >> 8) & 0xFF); + + m_nPacketSize = CMD_PACKET_LEN; + } + /*************************************************************************** + * Make Data Packet + ***************************************************************************/ + void InitCmdDataPacket(short wCMDCode, byte bySrcDeviceID, byte byDstDeviceID, byte[] pbyData, int nDataLen) + { + short w_wCheckSum; + + //g_pCmdPacket->m_wPrefix = CMD_DATA_PREFIX_CODE; + m_abyPacket[0] = (byte)(CMD_DATA_PREFIX_CODE & 0xFF); + m_abyPacket[1] = (byte)((CMD_DATA_PREFIX_CODE >> 8) & 0xFF); + + //g_pCmdPacket->m_bySrcDeviceID = p_bySrcDeviceID; + m_abyPacket[2] = bySrcDeviceID; + + //g_pCmdPacket->m_byDstDeviceID = p_byDstDeviceID; + m_abyPacket[3] = byDstDeviceID; + + //g_pCmdPacket->m_wCMDCode = p_wCMDCode; + m_abyPacket[4] = (byte)(wCMDCode & 0xFF); + m_abyPacket[5] = (byte)((wCMDCode >> 8) & 0xFF); + + //g_pCmdPacket->m_wDataLen = p_wDataLen; + m_abyPacket[6] = (byte)(nDataLen & 0xFF); + m_abyPacket[7] = (byte)((nDataLen >> 8) & 0xFF); + + //memcpy(&g_pCmdPacket->m_abyData[0], p_pbyData, p_wDataLen); + System.arraycopy(pbyData, 0, m_abyPacket, 8, nDataLen); + + //. Set checksum + w_wCheckSum = CalcChkSumOfPkt(m_abyPacket, nDataLen + 8); + + m_abyPacket[nDataLen+8] = (byte)(w_wCheckSum & 0xFF); + m_abyPacket[nDataLen+9] = (byte)((w_wCheckSum >> 8) & 0xFF); + + m_nPacketSize = nDataLen + 10; + } + /*************************************************************************** + * Check Packet + ***************************************************************************/ + boolean CheckReceive( byte[] pbyPacket, int nPacketLen, short wPrefix, short wCMDCode ) + { + short w_wCalcCheckSum, w_wCheckSum, w_wTmp; + + //. Check prefix code + w_wTmp = (short)(((pbyPacket[1] << 8) & 0x0000FF00) | (pbyPacket[0] & 0x000000FF)); + + if (wPrefix != w_wTmp) + { + return false; + } + + //. Check checksum + w_wCheckSum = (short)(((pbyPacket[nPacketLen-1] << 8) & 0x0000FF00) | (pbyPacket[nPacketLen-2] & 0x000000FF)); + + w_wCalcCheckSum = CalcChkSumOfPkt(pbyPacket, nPacketLen-2); + + if (w_wCheckSum != w_wCalcCheckSum) + { + return false; + } + + //. Check Command Code + w_wTmp = (short)(((pbyPacket[5] << 8) & 0x0000FF00) | (pbyPacket[4] & 0x000000FF)); + return wCMDCode == w_wTmp; + } + + //--------------------------- Send, Receive Communication Packet Functions ---------------------// + public boolean Send_Command(short p_wCmd) + { + if (m_nConnected == 1) + return UART_SendCommand(p_wCmd); + else if (m_nConnected == 2) + return USB_SendPacket(p_wCmd); + else + return false; + } + + public boolean Send_DataPacket(short p_wCmd) + { + if (m_nConnected == 1) + return UART_SendDataPacket(p_wCmd); + else if (m_nConnected == 2) + return USB_SendDataPacket(p_wCmd); + else + return false; + } + + public boolean Receive_DataPacket(short p_wCmd) + { + if (m_nConnected == 1) + return UART_ReceiveDataPacket(p_wCmd); + else if (m_nConnected == 2) + return USB_ReceiveDataPacket(p_wCmd); + else + return false; + } + + //-------------------------------- USB Communication Functions --------------------------------// + private boolean USB_SendPacket(short wCMD) + { + byte[] btCDB = new byte[8]; + boolean w_bRet; + + Arrays.fill(btCDB, (byte)0); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x11; btCDB[4] = (byte)m_nPacketSize; + + w_bRet = m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT); + + if (!w_bRet) + { + return false; + } + + return USB_ReceiveAck( wCMD ); + } + + private boolean USB_ReceiveAck(short wCMD) + { + int c, w_nLen, w_nReadCount = 0; + byte[] btCDB = new byte[8]; + byte[] w_abyWaitPacket = new byte[CMD_PACKET_LEN]; + + Arrays.fill(btCDB, (byte)0); + + //w_nReadCount = GetReadWaitTime(p_byCMD); + + c = 0; + Arrays.fill(w_abyWaitPacket, (byte)0xAF); + + do + { + Arrays.fill(m_abyPacket, (byte)0); + + btCDB[0] = (byte)0xEF; btCDB[1] = (byte)0x12; + + w_nLen = RCM_PACKET_LEN; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT)) + { + return false; + } + + SystemClock.sleep(COMM_SLEEP_TIME); + + c++; + + //if ( c > w_nReadCount) + //{ + // return false; + //} + } while (memcmp(m_abyPacket, w_abyWaitPacket, CMD_PACKET_LEN)); + + m_nPacketSize = w_nLen; + + return CheckReceive(m_abyPacket, m_nPacketSize, (short) RCM_PREFIX_CODE, wCMD); + } + + boolean USB_ReceiveDataAck(short wCMD) + { + byte[] btCDB = new byte[8]; + byte[] w_WaitPacket = new byte[10]; + int w_nLen; + + memset(btCDB, (byte)0, 8); + memset(w_WaitPacket, (byte)0xAF, 10); + + do + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x15; + w_nLen = 8; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket, w_nLen, SCSI_TIMEOUT)) + { + return false; + } + + SystemClock.sleep(COMM_SLEEP_TIME); + + }while(memcmp(m_abyPacket, w_WaitPacket, 8)); + + //w_nLen = g_pRcmPacket->m_wDataLen + 2; + w_nLen = (short)(((m_abyPacket[7] << 8) & 0x0000FF00) | (m_abyPacket[6] & 0x000000FF)) + 2; + + if (!USB_ReceiveRawData(m_abyPacket2, w_nLen)) + { + return false; + } + + System.arraycopy(m_abyPacket2, 0, m_abyPacket, 8, w_nLen); + + m_nPacketSize = 8 + w_nLen; + + return CheckReceive(m_abyPacket, m_nPacketSize, (short) RCM_DATA_PREFIX_CODE, wCMD); + } + + boolean USB_SendDataPacket(short wCMD) + { + byte[] btCDB = new byte[8]; + + memset(btCDB, (byte)0, 8); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x13; + + btCDB[4] = (byte)(m_nPacketSize & 0xFF); + btCDB[5] = (byte)((m_nPacketSize >> 8) & 0xFF); + + if (!m_usbBase.UsbSCSIWrite(btCDB, 8, m_abyPacket, m_nPacketSize, SCSI_TIMEOUT ) ) + return false; + + return USB_ReceiveDataAck(wCMD); + } + + boolean USB_ReceiveDataPacket(short wCMD) + { + return USB_ReceiveDataAck(wCMD); + } + + boolean USB_ReceiveRawData(byte[] pBuffer, int nDataLen) + { + byte[] btCDB = new byte[8]; + + memset(btCDB, (byte)0, 8); + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x14; + + return m_usbBase.UsbSCSIRead(btCDB, 8, pBuffer, nDataLen, SCSI_TIMEOUT); + } + + boolean USB_ReceiveImage(byte[] p_pBuffer, int nDataLen ) + { + byte[] btCDB = new byte[8]; + byte[] w_WaitPacket = new byte[8]; + + memset( btCDB, (byte)0, 8 ); + memset( w_WaitPacket, (byte)0xAF, 8 ); + + if (nDataLen < 1024*64) + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; + + return m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen, SCSI_TIMEOUT); + } + else if (nDataLen == 256*288) + { + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x00; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, p_pBuffer, nDataLen/2, SCSI_TIMEOUT)) + return false; + + btCDB[0] = (byte)0xEF; btCDB[1] = 0x16; btCDB[2] = 0x01; + + if (!m_usbBase.UsbSCSIRead(btCDB, 8, m_abyPacket2, nDataLen/2, SCSI_TIMEOUT )) + return false; + + System.arraycopy(m_abyPacket2, 0, p_pBuffer, nDataLen/2, nDataLen/2); + } + + return true; + } + + //-------------------------------- UART Communication Functions --------------------------------// + public boolean UART_SendCommand(short p_wCmd) + { + int w_nResult = 0; + boolean w_bRet = false; + int w_nRetry = 0; + + if (m_nConnected == 1) + { + byte[] w_pData = new byte[m_nPacketSize]; + System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize); + m_SerialPort.send(w_pData, m_nPacketSize); + } + +// do { +// w_bRet = UART_ReceiveAck(p_wCmd); +// if (m_nUARTReceivePos == m_nUARTReadPos) { +// if (w_bRet == true) { +// break; +// } +// else { +// if (w_nRetry > 0) +// break; +// else +// w_nRetry += 1; +// } +// } +// } while (w_bRet == false); + w_bRet = UART_ReceiveAck(p_wCmd); + return w_bRet; + } + + public boolean UART_ReceiveAck(short p_wCmd) + { + if (!UART_ReadDataN(m_abyPacket, 0, CMD_PACKET_LEN)) + return false; + + return CheckReceive(m_abyPacket, CMD_PACKET_LEN, (short) RCM_PREFIX_CODE, p_wCmd); + } + + public boolean UART_ReceiveDataAck(short p_wCmd) + { + if (!UART_ReadDataN(m_abyPacket, 0, 8)) + return false; + + if (!UART_ReadDataN(m_abyPacket, 8, GetDataLen() + 2)) + return false; + + return CheckReceive(m_abyPacket, GetDataLen() + 10, (short)RCM_DATA_PREFIX_CODE, p_wCmd); + } + + public boolean UART_SendDataPacket(short p_wCmd) + { + int w_nSendCnt = 0; + + if (m_nConnected == 1) + { + byte[] w_pData = new byte[m_nPacketSize]; + System.arraycopy(m_abyPacket, 0, w_pData, 0, m_nPacketSize); + m_SerialPort.send(w_pData, m_nPacketSize); + } + + return UART_ReceiveDataAck(p_wCmd); + } + /***************************************************************************/ + /***************************************************************************/ + public boolean UART_ReceiveDataPacket(short p_wCmd) + { + return UART_ReceiveDataAck(p_wCmd); + } + /***************************************************************************/ + /***************************************************************************/ + public boolean UART_ReceiveData(short p_wCmd, int p_nDataLen, byte[] p_pBuffer) + { + int w_nReceivedCnt; + int w_wPacketDataLen = 0; + + for (w_nReceivedCnt = 0; w_nReceivedCnt < p_nDataLen; w_nReceivedCnt += w_wPacketDataLen) + { + w_wPacketDataLen = p_nDataLen - w_nReceivedCnt; + if (w_wPacketDataLen > MAX_DATA_LEN) w_wPacketDataLen = MAX_DATA_LEN; + if (!UART_ReceiveDataPacket(p_wCmd)) + return false; + System.arraycopy(m_abyPacket, 8, p_pBuffer, w_nReceivedCnt, GetDataLen() + 4); + } + return true; + } + /***************************************************************************/ + /***************************************************************************/ + boolean UART_ReadDataN(byte[] p_pData, int p_nStart, int p_nLen) + { + int w_nTotalRecvLen; + int w_nTmpLen; + int w_nStartPos = 0; + int w_nHeader; + boolean w_bFirstPacket = true; + int w_nReceivedLen = 0; + + int wm_nUARTReceivePos = 0; + int wm_nUARTReadPos = 0; + + long w_nEllapsedTime = 0; + + w_nTotalRecvLen = 0; + w_nEllapsedTime = SystemClock.uptimeMillis(); + + while (w_nTotalRecvLen < p_nLen) + { + wm_nUARTReceivePos = m_nUARTReceivePos; + wm_nUARTReadPos = m_nUARTReadPos; + + if ((wm_nUARTReceivePos <= wm_nUARTReadPos) && (wm_nUARTReadPos - wm_nUARTReceivePos < DevComm.MAX_DATA_LEN)) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + if (SystemClock.uptimeMillis() - w_nEllapsedTime > UART_READ_TIMEOUT) + return false; + continue; + } + + if (wm_nUARTReceivePos < wm_nUARTReadPos) { + w_nReceivedLen = DevComm.UART_MAX_BUF_SIZE + wm_nUARTReceivePos - wm_nUARTReadPos; + System.arraycopy(m_pUARTReadBuf, wm_nUARTReadPos, m_abyPacket2, 0, DevComm.UART_MAX_BUF_SIZE - wm_nUARTReadPos); + System.arraycopy(m_pUARTReadBuf, 0, m_abyPacket2, DevComm.UART_MAX_BUF_SIZE - wm_nUARTReadPos, wm_nUARTReceivePos); + } + else { + w_nReceivedLen = wm_nUARTReceivePos - wm_nUARTReadPos; + System.arraycopy(m_pUARTReadBuf, wm_nUARTReadPos, m_abyPacket2, 0, w_nReceivedLen); + } + + if (w_bFirstPacket && (p_nLen == 6) && (p_nStart == 0)) { + for (w_nStartPos = 0; w_nStartPos < w_nReceivedLen; w_nStartPos++) { + w_nHeader = MAKEWORD(m_abyPacket2[w_nStartPos], m_abyPacket2[w_nStartPos + 1]); + if ((w_nHeader == CMD_PREFIX_CODE) || (w_nHeader == RCM_PREFIX_CODE) || + (w_nHeader == CMD_DATA_PREFIX_CODE) || (w_nHeader == RCM_DATA_PREFIX_CODE)) + break; + } + + m_nUARTReadPos += w_nStartPos; + w_nReceivedLen -= w_nStartPos; + + w_bFirstPacket = false; + } + else { + w_nStartPos = 0; + } + + if (p_nLen - w_nTotalRecvLen < w_nReceivedLen) { + w_nTmpLen = p_nLen - w_nTotalRecvLen; + } + else { + w_nTmpLen = w_nReceivedLen; + } + + System.arraycopy(m_abyPacket2, w_nStartPos, p_pData, p_nStart + w_nTotalRecvLen, w_nTmpLen); + w_nTotalRecvLen += w_nTmpLen; + m_nUARTReadPos += w_nTmpLen; + + if (m_nUARTReadPos >= DevComm.UART_MAX_BUF_SIZE) + m_nUARTReadPos -= DevComm.UART_MAX_BUF_SIZE; + + w_nEllapsedTime = SystemClock.uptimeMillis(); + } + + return true; + } + + private boolean memcmp(byte[] p1, byte[] p2, int nLen) + { + int i; + + for (i=0; i> 8) & 0xFF); + } + + + // uart control classes ====================================================== + private class SerialControl extends SerialHelper{ + + public SerialControl(){ + } + + @Override + protected void onDataReceived(final ComBean ComRecData) + { + int w_nProcLen = 0; + +// DispQueue.AddQueue(ComRecData); + + // save to receive buffer + if (m_nUARTReceivePos + ComRecData.nSize > DevComm.UART_MAX_BUF_SIZE) { + w_nProcLen = DevComm.UART_MAX_BUF_SIZE - m_nUARTReceivePos; + System.arraycopy(ComRecData.bRec, 0, m_pUARTReadBuf, m_nUARTReceivePos, w_nProcLen); + System.arraycopy(ComRecData.bRec, w_nProcLen, m_pUARTReadBuf, 0, ComRecData.nSize - w_nProcLen); + m_nUARTReceivePos = ComRecData.nSize - w_nProcLen; + } else { + System.arraycopy(ComRecData.bRec, 0, m_pUARTReadBuf, m_nUARTReceivePos, ComRecData.nSize); + m_nUARTReceivePos += ComRecData.nSize; + } + } + } + + private class DispQueueThread extends Thread{ + private final Queue QueueList = new LinkedList(); + @Override + public void run() { + super.run(); +// while(!isInterrupted()) { +// int i; +// i = 0; +// while (m_bBufferHandle) +// { +// i++; +// if (i > 10000) +// break; +// } +// m_bBufferHandle = true; +// while(true) +// { +// final ComBean ComData; +// if ((ComData=QueueList.poll())==null) +// break; +// +// Log.d("NOEM_DEBUG", String.format("DispQueueThread: ComData.nSize = %d, m_nUARTReadLen = %d", +// ComData.nSize, m_nUARTReadLen)); +// System.arraycopy(ComData.bRec, 0, m_pUARTReadBuf, m_nUARTReadLen, ComData.nSize); +// m_nUARTReadLen = m_nUARTReadLen + ComData.nSize; +//// break; +// } +// m_bBufferHandle = false; +// } + } + + public synchronized void AddQueue(ComBean ComData){ + QueueList.add(ComData); + } + } + // ! uart control classes ==================================================== +} diff --git a/android/src/main/java/com/xiarui/zhiwen/IUsbConnState.java b/android/src/main/java/com/xiarui/zhiwen/IUsbConnState.java new file mode 100644 index 0000000..aed8d82 --- /dev/null +++ b/android/src/main/java/com/xiarui/zhiwen/IUsbConnState.java @@ -0,0 +1,12 @@ +package com.xiarui.zhiwen; + +/** + * Created by KMS on 2016/8/23. + */ +public interface IUsbConnState { + void onUsbConnected(); + + void onUsbPermissionDenied(); + + void onDeviceNotFound(); +} diff --git a/android/src/main/java/com/xiarui/zhiwen/UsbController.java b/android/src/main/java/com/xiarui/zhiwen/UsbController.java new file mode 100644 index 0000000..12ada17 --- /dev/null +++ b/android/src/main/java/com/xiarui/zhiwen/UsbController.java @@ -0,0 +1,440 @@ +package com.xiarui.zhiwen; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbConstants; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; +import android.hardware.usb.UsbEndpoint; +import android.hardware.usb.UsbInterface; +import android.hardware.usb.UsbManager; +import android.os.SystemClock; +import android.util.Log; +import android.widget.Toast; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; + +/** + * Created by KMS on 2016/8/23. + */ +public class UsbController { + private final Context mApplicationContext; + private final UsbManager mUsbManager; + private final int VID; + private final int PID; + private int m_nEPInSize, m_nEPOutSize; + + private final byte[] m_abyTransferBuf; + private boolean m_bInit = false; + private UsbDeviceConnection m_usbConn = null; + private UsbInterface m_usbIf = null; + private UsbEndpoint m_epIN = null; + private UsbEndpoint m_epOUT = null; + private final IUsbConnState mConnectionHandler; + + protected static final String ACTION_USB_PERMISSION = "ch.serverbox.android.USB"; + + /** + * Activity is needed for onResult + * + * @param parentActivity + */ + public UsbController(Activity parentActivity, IUsbConnState connectionHandler, int vid, int pid){ + mConnectionHandler = connectionHandler; + mApplicationContext = parentActivity.getApplicationContext(); + mUsbManager = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE); + VID = vid; + PID = pid; + m_abyTransferBuf = new byte[512]; + //init(); + } + + public void init(){ + enumerate(new IPermissionListener() { + @Override + public void onPermissionDenied(UsbDevice d) { + UsbManager usbman = (UsbManager) mApplicationContext.getSystemService(Context.USB_SERVICE); + PendingIntent pi = PendingIntent.getBroadcast(mApplicationContext, 0, new Intent(ACTION_USB_PERMISSION), FLAG_IMMUTABLE); + mApplicationContext.registerReceiver(mPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION)); + usbman.requestPermission(d, pi); + } + }); + } + + public void uninit(){ + if (m_usbConn != null) + { + m_usbConn.releaseInterface(m_usbIf); + m_usbConn.close(); + m_usbConn = null; + m_bInit = false; + } + + //stop(); + } + + public void stop() + { + try{ + mApplicationContext.unregisterReceiver(mPermissionReceiver); + }catch(IllegalArgumentException e){}//bravo + } + + public boolean IsInit(){ + return m_bInit; + } + + private void enumerate(IPermissionListener listener) { + boolean bFound = false; + l("enumerating"); + HashMap devlist = mUsbManager.getDeviceList(); + Iterator deviter = devlist.values().iterator(); + + while (deviter.hasNext()) { + UsbDevice d = deviter.next(); + l("Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId())); + +// Toast.makeText(mApplicationContext, "Found device: " + String.format("%04X:%04X", d.getVendorId(), d.getProductId()), Toast.LENGTH_SHORT).show(); + + if (d.getVendorId() == VID && d.getProductId() == PID) { + bFound = true; + l("Device under: " + d.getDeviceName()); + if (!mUsbManager.hasPermission(d)) + { + Toast.makeText(mApplicationContext, "enumerate, hasPermission return false" , Toast.LENGTH_SHORT).show(); + listener.onPermissionDenied(d); + } + else{ +// Toast.makeText(mApplicationContext, "enumerate, GetConnInerface start" , Toast.LENGTH_SHORT).show(); + //startHandler(d); + GetConnInerface(d); + //TestComm(d); + return; + } + break; + } + } + if (!bFound) + { + Toast.makeText(mApplicationContext, "no more devices found" , Toast.LENGTH_SHORT).show(); + mConnectionHandler.onDeviceNotFound(); + } + } + + private class PermissionReceiver extends BroadcastReceiver { + private final IPermissionListener mPermissionListener; + + public PermissionReceiver(IPermissionListener permissionListener) { + mPermissionListener = permissionListener; + } + + @Override + public void onReceive(Context context, Intent intent) { + mApplicationContext.unregisterReceiver(this); + if (intent.getAction().equals(ACTION_USB_PERMISSION)) { + if (!intent.getBooleanExtra( + UsbManager.EXTRA_PERMISSION_GRANTED, false)) { + mPermissionListener.onPermissionDenied(intent + .getParcelableExtra(UsbManager.EXTRA_DEVICE)); + + mConnectionHandler.onUsbPermissionDenied(); + } else { + l("Permission granted"); + UsbDevice dev = intent + .getParcelableExtra(UsbManager.EXTRA_DEVICE); + if (dev != null) { + if (dev.getVendorId() == VID + && dev.getProductId() == PID) { + //startHandler(dev);// has new thread + GetConnInerface(dev); + //TestComm(dev); + } + } else { + mConnectionHandler.onDeviceNotFound(); + } + } + } + } + } + + private void GetConnInerface(UsbDevice dev){ + int n; + + m_usbConn = mUsbManager.openDevice(dev); + + n = dev.getInterfaceCount(); + + if (n <= 0) + return; + + if (!m_usbConn.claimInterface(dev.getInterface(0), true)) { + return; + } + + m_usbIf = dev.getInterface(0); + + n = m_usbIf.getEndpointCount(); + + if (n < 2) + return; + + for (int i = 0; i < n; i++) { + if (m_usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { + if (m_usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) + m_epIN = m_usbIf.getEndpoint(i); + else + m_epOUT = m_usbIf.getEndpoint(i); + } + } + + m_nEPInSize = m_epIN.getMaxPacketSize(); + m_nEPOutSize = m_epOUT.getMaxPacketSize(); + + m_bInit = true; + + //m_epOUT.getMaxPacketSize(); + + //Toast.makeText(mApplicationContext, "GetConnInerface OK, Out Max Size="+m_nEPOutSize+" In Max Size=" + m_nEPInSize, Toast.LENGTH_SHORT).show(); + mConnectionHandler.onUsbConnected(); + } + + public boolean OperationInternal(byte[] pData, int nDataLen, int nTimeOut, boolean bRead) + { + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = (byte)(nDataLen & 0xFF); + w_abyTmp[9] = (byte)((nDataLen >> 8)& 0xFF); + w_abyTmp[10] = (byte)((nDataLen >> 16)& 0xFF); + w_abyTmp[11] = (byte)((nDataLen >> 24)& 0xFF); + + if(bRead) + w_abyTmp[12] = (byte)0x80; + else + w_abyTmp[12] = 0x00; //cCBWFlags + + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + w_abyTmp[15] = (byte)0xef; + if (bRead) + w_abyTmp[16] = (byte)0xff; + else + w_abyTmp[16] = (byte)0xfe; + + // send 31bytes + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + // read or write real data + if (bRead) + w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut); + else + w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + public boolean UsbSCSIWrite(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut) + { + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + //Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = 0x00; + w_abyTmp[9] = 0x00; + w_abyTmp[10] = 0x00; + w_abyTmp[11] = 0x00; + w_abyTmp[12] = 0x00; //cCBWFlags + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen); + //System.arraycopy(pData, 0, w_abyTmp, 31, nDataLen); + + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + w_bRet = UsbBulkSend(pData, nDataLen, nTimeOut); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + public boolean UsbSCSIRead(byte[] pCDB, int nCDBLen, byte[] pData, int nDataLen, int nTimeOut) + { + long w_nTime; + byte[] w_abyTmp = new byte[31]; + byte[] w_abyCSW = new byte[13]; + boolean w_bRet; + + //Arrays.fill(w_abyTmp, (byte)0); + w_abyTmp[0] = 0x55; + w_abyTmp[1] = 0x53; + w_abyTmp[2] = 0x42; + w_abyTmp[3] = 0x43; + w_abyTmp[4] = 0x28; + w_abyTmp[5] = 0x2b; + w_abyTmp[6] = 0x18; + w_abyTmp[7] = (byte)0x89; + w_abyTmp[8] = 0x00; + w_abyTmp[9] = 0x00; + w_abyTmp[10] = 0x00; + w_abyTmp[11] = 0x00; + w_abyTmp[12] = (byte)0x80; //cCBWFlags + w_abyTmp[13] = 0x00; //cCBWlun + w_abyTmp[14] = 0x0a; //cCBWCBLength + + System.arraycopy(pCDB, 0, w_abyTmp, 15, nCDBLen); + + w_bRet = UsbBulkSend(w_abyTmp, 31, nTimeOut); + + if (!w_bRet) + return false; + + w_nTime = SystemClock.elapsedRealtime(); + + w_bRet = UsbBulkReceive(pData, nDataLen, nTimeOut); + + w_nTime = SystemClock.elapsedRealtime() - w_nTime; + + //Toast.makeText(mApplicationContext, "UsbSCSIRead, UsbBulkReceive Time : " + w_nTime , Toast.LENGTH_SHORT).show(); + + if (!w_bRet) + return false; + + // receive csw + w_bRet = UsbBulkReceive(w_abyCSW, 13, nTimeOut); + + return w_bRet; + } + + private boolean UsbBulkSend(byte[] pBuf, int nLen, int nTimeOut) + { + int i, n, r, w_nRet; + //byte[] w_abyTmp = new byte[m_nEPOutSize]; + + n = nLen / m_nEPOutSize; + r = nLen % m_nEPOutSize; + + for(i=0; i 0) + { + System.arraycopy(pBuf, i*m_nEPOutSize, m_abyTransferBuf, 0, r); + + w_nRet = m_usbConn.bulkTransfer(m_epOUT, m_abyTransferBuf, r, nTimeOut); + + return w_nRet == r; + } + + return true; + } + + private boolean UsbBulkReceive(byte[] pBuf, int nLen, int nTimeOut) + { + int i, n, r, w_nRet; + //byte[] w_abyTmp = new byte[m_nEPInSize]; + + //w_nRet = m_usbConn.bulkTransfer(m_epIN, pBuf, nLen, nTimeOut); + + //if (w_nRet != nLen) + // return false; + + n = nLen / m_nEPInSize; + r = nLen % m_nEPInSize; + + //Toast.makeText(mApplicationContext, "UsbBulkReceive, Buf Len = " + pBuf.length, Toast.LENGTH_SHORT).show(); + + for(i=0; i 0) + { + w_nRet = m_usbConn.bulkTransfer(m_epIN, m_abyTransferBuf, r, nTimeOut); + + if (w_nRet != r) + return false; + + System.arraycopy(m_abyTransferBuf, 0, pBuf, i*m_nEPInSize, r); + } + + return true; + } + + // END MAIN LOOP + private final BroadcastReceiver mPermissionReceiver = new PermissionReceiver( + new IPermissionListener() { + @Override + public void onPermissionDenied(UsbDevice d) { + l("Permission denied on " + d.getDeviceId()); + } + }); + + private interface IPermissionListener { + void onPermissionDenied(UsbDevice d); + } + + public final static String TAG = "USBController"; + + private void l(Object msg) { + Log.d(TAG, ">==< " + msg.toString() + " >==<"); + } +} diff --git a/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java b/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java new file mode 100644 index 0000000..c67f95b --- /dev/null +++ b/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java @@ -0,0 +1,1001 @@ +package com.xiarui.zhiwen; + +import androidx.annotation.NonNull; + +import android.app.Activity; +import android.widget.Toast; +import android.util.Log; +import android.os.Handler; +import android.os.Looper; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.embedding.engine.plugins.activity.ActivityAware; +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +import android.os.SystemClock; + +import java.util.Map; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * 智纹指纹识别插件 + * 提供指纹设备的连接、录入、验证、识别等功能 + */ +public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, IUsbConnState { + + // 常量定义 + private static final String TAG = "ZhiwenPlugin"; + private static final String CHANNEL_NAME = "zhiwen"; + private static final int DEFAULT_MAX_FP_COUNT = 3000; + private static final int ENROLL_STEP_COUNT = 3; + private static final int IMAGE_BUFFER_SIZE = 1024 * 100; + + // 响应状态码 + private static final int RESPONSE_SUCCESS = 1; + private static final int RESPONSE_FAIL = -1; + private static final int RESPONSE_NOT_FOUND = 0; + + /// Flutter与Android原生通信的MethodChannel + /// 用于注册插件到Flutter引擎,并在Activity分离时注销 + private MethodChannel channel; + + // 设备通信对象,使用static确保全局唯一 + private static DevComm m_devComm; + + // 设备连接参数 + private int m_nBaudrate; + private String m_szDevice; + private final int maxFpCount = DEFAULT_MAX_FP_COUNT; + + // Activity引用和线程管理 + private Activity activity; + private final ExecutorService executorService = Executors.newCachedThreadPool(); + private final Handler mainHandler = new Handler(Looper.getMainLooper()); + + /** + * 插件附加到Flutter引擎时的回调 + * 初始化MethodChannel并设置方法调用处理器 + */ + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { + channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL_NAME); + channel.setMethodCallHandler(this); + // 注意:这里不应该从ApplicationContext获取Activity,应该等待onAttachedToActivity回调 + } + + /** + * 处理来自Flutter的方法调用 + * 根据方法名分发到对应的处理函数 + */ + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { + try { + switch (call.method) { + case "getPlatformVersion": + result.success("Android " + android.os.Build.VERSION.RELEASE); + break; + + case "openDevice": + String devicePath = call.argument("devicePath"); + Integer baudRate = call.argument("baudRate"); + if (devicePath == null || baudRate == null) { + result.error("INVALID_ARGUMENTS", "devicePath and baudRate are required", null); + return; + } + boolean success = openDevice(devicePath, baudRate); + result.success(success); + break; + + case "closeDevice": + closeDevice(); + result.success(true); + break; + + case "enrollFingerprint": + Integer enrollUserId = call.argument("userId"); + if (enrollUserId == null) { + result.error("INVALID_ARGUMENTS", "userId is required", null); + return; + } + enrollFingerprint(enrollUserId, result); + break; + + case "verifyFingerprint": + Integer verifyUserId = call.argument("userId"); + if (verifyUserId == null) { + result.error("INVALID_ARGUMENTS", "userId is required", null); + return; + } + verifyFingerprint(verifyUserId, result); + break; + + case "deleteAllFingerprint": + Map deleteAllRes = deleteAllFingerprint(); + result.success(deleteAllRes); + break; + + case "identifyFingerprint": + identifyFingerprint(result); + break; + + case "deleteOneFingerprint": + Integer deleteUserId = call.argument("userId"); + if (deleteUserId == null) { + result.error("INVALID_ARGUMENTS", "userId is required", null); + return; + } + Map deleteOneRes = deleteOneFingerprint(deleteUserId); + result.success(deleteOneRes); + break; + + case "getUserCount": + Map countRes = getUserCount(); + result.success(countRes); + break; + + default: + result.notImplemented(); + break; + } + } catch (Exception e) { + Log.e(TAG, "Method call error: " + e.getMessage(), e); + result.error("PLUGIN_ERROR", "Plugin internal error: " + e.getMessage(), null); + } + } + + /** + * 打开指纹识别设备 + * @param device 设备路径,如"/dev/ttyS1"或"USB" + * @param baudrate 波特率,如9600、115200等 + * @return 是否成功打开设备 + */ + private boolean openDevice(String device, int baudrate) { + Log.d(TAG, "尝试打开设备: " + device + ", 波特率: " + baudrate); + + m_szDevice = device; + m_nBaudrate = baudrate; + + try { + // 检查Activity是否可用 + if (activity == null) { + Log.e(TAG, "Activity未初始化,无法打开设备"); + return false; + } + + // 初始化设备通信对象 + if (m_devComm == null) { + m_devComm = new DevComm(activity, this); + Log.d(TAG, "创建DevComm实例"); + } + + // 如果设备未初始化,则尝试打开通信 + if (!m_devComm.IsInit()) { + if (!m_devComm.OpenComm(m_szDevice, m_nBaudrate)) { + Log.e(TAG, "打开设备通信失败: " + device); + return false; + } + Log.d(TAG, "设备通信已建立"); + } + + // 测试设备连接 + String[] deviceInfo = new String[1]; + int testResult = m_devComm.Run_TestConnection(); + + if (testResult == DevComm.ERR_SUCCESS) { + int infoResult = m_devComm.Run_GetDeviceInfo(deviceInfo); + if (infoResult == DevComm.ERR_SUCCESS) { + Log.i(TAG, "设备打开成功,设备信息: " + deviceInfo[0]); + return true; + } else { + Log.e(TAG, "获取设备信息失败: " + GetErrorMsg(infoResult)); + } + } else { + Log.e(TAG, "设备连接测试失败: " + GetErrorMsg(testResult)); + } + + // 连接失败,关闭通信 + m_devComm.CloseComm(); + Log.w(TAG, "设备连接失败,已关闭通信"); + return false; + + } catch (Exception e) { + Log.e(TAG, "打开设备时发生异常: " + e.getMessage(), e); + if (m_devComm != null) { + try { + m_devComm.CloseComm(); + } catch (Exception closeEx) { + Log.e(TAG, "关闭设备通信时发生异常: " + closeEx.getMessage()); + } + } + return false; + } + } + + /** + * 关闭指纹识别设备 + * 释放设备资源和通信连接 + */ + private void closeDevice() { + Log.d(TAG, "关闭设备"); + try { + if (m_devComm != null && m_devComm.IsInit()) { + m_devComm.CloseComm(); + Log.i(TAG, "设备已关闭"); + } else { + Log.d(TAG, "设备未初始化或已关闭"); + } + } catch (Exception e) { + Log.e(TAG, "关闭设备时发生异常: " + e.getMessage(), e); + } + } + + /** + * 录入指纹模板 + * @param userId 用户ID,用于标识指纹模板 + * @param result Flutter回调结果 + */ + private void enrollFingerprint(int userId, Result result) { + Log.d(TAG, "开始录入指纹,用户ID: " + userId); + + // 检查设备是否已初始化 + if (!isDeviceReady()) { + Map errorResult = createErrorResponse("设备未初始化"); + result.success(errorResult); + return; + } + + // 检查指纹模板是否已存在 + int[] templateState = new int[1]; + int statusResult = m_devComm.Run_GetStatus(userId, templateState); + + if (statusResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(statusResult); + Log.e(TAG, "获取模板状态失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + result.success(errorResult); + return; + } + + if (templateState[0] == DevComm.GD_TEMPLATE_NOT_EMPTY) { + String errorMsg = "指纹模板已存在,用户ID: " + userId; + Log.w(TAG, errorMsg); + Map errorResult = createErrorResponse(errorMsg); + result.success(errorResult); + return; + } + + // 开启LED指示灯 + m_devComm.Run_SLEDControl(1); + + // 在后台线程执行指纹录入 + executorService.execute(() -> { + performFingerprintEnrollment(userId, result); + }); + } + + /** + * 执行指纹录入的具体流程 + * @param userId 用户ID + * @param result Flutter回调结果 + */ + private void performFingerprintEnrollment(int userId, Result result) { + byte[] imageBuffer = new byte[IMAGE_BUFFER_SIZE]; + int enrollStep = 0; + final int[] duplicateId = new int[1]; + final int[] imageWidth = new int[1]; + final int[] imageHeight = new int[1]; + + try { + // 录入指定次数的指纹 + while (enrollStep < ENROLL_STEP_COUNT) { + Log.d(TAG, String.format("请放置手指进行第%d次录入", enrollStep + 1)); + + // 显示提示信息 + showToastOnMainThread(String.format("请放置手指 (%d/%d)", enrollStep + 1, ENROLL_STEP_COUNT)); + + // 采集指纹图像 + if (captureFingerprint() < 0) { + Map errorResult = createErrorResponse("指纹采集失败"); + mainHandler.post(() -> result.success(errorResult)); + return; + } + + Log.d(TAG, "请移开手指"); + showToastOnMainThread("请移开手指"); + + // 上传指纹图像(仅USB模式) + if (m_devComm.m_nConnected == 2) { + int uploadResult = m_devComm.Run_UpImage(0, imageBuffer, imageWidth, imageHeight); + if (uploadResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(uploadResult); + Log.e(TAG, "上传指纹图像失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + } + + // 生成指纹特征 + int generateResult = m_devComm.Run_Generate(enrollStep); + if (generateResult != DevComm.ERR_SUCCESS) { + if (generateResult == DevComm.ERR_BAD_QUALITY) { + Log.w(TAG, "指纹质量不佳,请重试"); + showToastOnMainThread("指纹质量不佳,请重试"); + continue; // 重试当前步骤 + } else { + String errorMsg = GetErrorMsg(generateResult); + Log.e(TAG, "生成指纹特征失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + } + + enrollStep++; + } + + // 合并多次录入的特征(如果录入次数大于1) + if (ENROLL_STEP_COUNT > 1) { + int mergeResult = m_devComm.Run_Merge(0, ENROLL_STEP_COUNT); + if (mergeResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(mergeResult); + Log.e(TAG, "合并指纹特征失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + } + + // 存储指纹模板 + int storeResult = m_devComm.Run_StoreChar(userId, 0, duplicateId); + if (storeResult != DevComm.ERR_SUCCESS) { + String errorMsg; + if (storeResult == DevComm.ERR_DUPLICATION_ID) { + errorMsg = String.format("指纹重复,重复ID: %d", duplicateId[0]); + } else { + errorMsg = GetErrorMsg(storeResult); + } + Log.e(TAG, "存储指纹模板失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + + // 录入成功 + Log.i(TAG, String.format("指纹录入成功,用户ID: %d", userId)); + Map successResult = createSuccessResponse("指纹录入成功"); + successResult.put("userId", userId); + mainHandler.post(() -> { + showToastOnMainThread("指纹录入成功"); + result.success(successResult); + }); + + } catch (Exception e) { + Log.e(TAG, "指纹录入过程中发生异常: " + e.getMessage(), e); + Map errorResult = createErrorResponse("录入过程发生异常: " + e.getMessage()); + mainHandler.post(() -> result.success(errorResult)); + } finally { + // 关闭LED指示灯 + try { + m_devComm.Run_SLEDControl(0); + } catch (Exception e) { + Log.e(TAG, "关闭LED失败: " + e.getMessage()); + } + } + } + + /** + * 验证指纹 + * @param userId 用户ID,用于验证指定的指纹模板 + * @param result Flutter回调结果 + */ + private void verifyFingerprint(int userId, Result result) { + Log.d(TAG, "开始验证指纹,用户ID: " + userId); + + // 检查设备是否已初始化 + if (!isDeviceReady()) { + Map errorResult = createErrorResponse("设备未初始化"); + result.success(errorResult); + return; + } + + // 检查指纹模板是否存在 + int[] templateState = new int[1]; + int statusResult = m_devComm.Run_GetStatus(userId, templateState); + + if (statusResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(statusResult); + Log.e(TAG, "获取模板状态失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + result.success(errorResult); + return; + } + + if (templateState[0] == DevComm.GD_TEMPLATE_EMPTY) { + String errorMsg = "指纹模板不存在,用户ID: " + userId; + Log.w(TAG, errorMsg); + Map errorResult = createErrorResponse(errorMsg); + result.success(errorResult); + return; + } + + // 开启LED指示灯 + m_devComm.Run_SLEDControl(1); + + // 在后台线程执行指纹验证 + executorService.execute(() -> { + performFingerprintVerification(userId, result); + }); + } + + /** + * 执行指纹验证的具体流程 + * @param userId 用户ID + * @param result Flutter回调结果 + */ + private void performFingerprintVerification(int userId, Result result) { + byte[] imageBuffer = new byte[IMAGE_BUFFER_SIZE]; + final int[] imageWidth = new int[1]; + final int[] imageHeight = new int[1]; + final int[] matchScore = new int[1]; + + try { + Log.d(TAG, "请放置手指进行验证"); + showToastOnMainThread("请放置手指进行验证"); + + // 采集指纹图像 + if (captureFingerprint() < 0) { + Map errorResult = createErrorResponse("指纹采集失败"); + mainHandler.post(() -> result.success(errorResult)); + return; + } + + Log.d(TAG, "请移开手指"); + showToastOnMainThread("请移开手指"); + + // 上传指纹图像(仅USB模式) + if (m_devComm.m_nConnected == 2) { + int uploadResult = m_devComm.Run_UpImage(0, imageBuffer, imageWidth, imageHeight); + if (uploadResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(uploadResult); + Log.e(TAG, "上传指纹图像失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + } + + // 生成指纹特征 + int generateResult = m_devComm.Run_Generate(0); + if (generateResult != DevComm.ERR_SUCCESS) { + String errorMsg; + if (generateResult == DevComm.ERR_BAD_QUALITY) { + errorMsg = "指纹质量不佳,请重试"; + Log.w(TAG, errorMsg); + } else { + errorMsg = GetErrorMsg(generateResult); + Log.e(TAG, "生成指纹特征失败: " + errorMsg); + } + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> { + showToastOnMainThread(errorMsg); + result.success(errorResult); + }); + return; + } + + // 执行指纹验证 + int verifyResult = m_devComm.Run_Verify(userId, 0, matchScore); + if (verifyResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(verifyResult); + Log.e(TAG, "指纹验证失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> { + showToastOnMainThread("指纹验证失败"); + result.success(errorResult); + }); + return; + } + + // 验证成功 + Log.i(TAG, String.format("指纹验证成功,用户ID: %d,匹配分数: %d", userId, matchScore[0])); + Map successResult = createSuccessResponse("指纹验证成功"); + successResult.put("userId", userId); + successResult.put("matchScore", matchScore[0]); + mainHandler.post(() -> { + showToastOnMainThread("指纹验证成功"); + result.success(successResult); + }); + + } catch (Exception e) { + Log.e(TAG, "指纹验证过程中发生异常: " + e.getMessage(), e); + Map errorResult = createErrorResponse("验证过程发生异常: " + e.getMessage()); + mainHandler.post(() -> result.success(errorResult)); + } finally { + // 关闭LED指示灯 + try { + m_devComm.Run_SLEDControl(0); + } catch (Exception e) { + Log.e(TAG, "关闭LED失败: " + e.getMessage()); + } + } + } + + /** + * 删除所有指纹模板 + * @return 删除结果 + */ + private Map deleteAllFingerprint() { + Log.d(TAG, "开始删除所有指纹模板"); + Map res_data = new HashMap<>(); + + if (!isDeviceReady()) { + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "设备未初始化"); + return res_data; + } + + try { + int deleteResult = m_devComm.Run_DelChar(1, maxFpCount); + if (deleteResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(deleteResult); + Log.e(TAG, "删除所有指纹模板失败: " + errorMsg); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", errorMsg); + return res_data; + } + + Log.i(TAG, "所有指纹模板删除成功"); + res_data.put("code", RESPONSE_SUCCESS); + res_data.put("msg", "所有指纹模板删除成功"); + return res_data; + + } catch (Exception e) { + Log.e(TAG, "删除所有指纹模板过程中发生异常: " + e.getMessage(), e); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "删除过程发生异常: " + e.getMessage()); + return res_data; + } + } + + /** + * 删除指定用户的指纹模板 + * @param userId 用户ID + * @return 删除结果 + */ + private Map deleteOneFingerprint(int userId) { + Log.d(TAG, "开始删除指纹模板,用户ID: " + userId); + Map res_data = new HashMap<>(); + + if (!isDeviceReady()) { + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "设备未初始化"); + return res_data; + } + + try { + int deleteResult = m_devComm.Run_DelChar(userId, userId); + if (deleteResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(deleteResult); + Log.e(TAG, "删除指纹模板失败: " + errorMsg); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", errorMsg); + return res_data; + } + + Log.i(TAG, String.format("指纹模板删除成功,用户ID: %d", userId)); + res_data.put("code", RESPONSE_SUCCESS); + res_data.put("msg", "指纹模板删除成功"); + res_data.put("userId", userId); + return res_data; + + } catch (Exception e) { + Log.e(TAG, "删除指纹模板过程中发生异常: " + e.getMessage(), e); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "删除过程发生异常: " + e.getMessage()); + return res_data; + } + } + + /** + * 识别指纹(1:N搜索) + * @param result Flutter回调结果 + */ + private void identifyFingerprint(Result result) { + Log.d(TAG, "开始识别指纹"); + + // 检查设备是否已初始化 + if (!isDeviceReady()) { + Map errorResult = createErrorResponse("设备未初始化"); + result.success(errorResult); + return; + } + + // 开启LED指示灯 + m_devComm.Run_SLEDControl(1); + + // 在后台线程执行指纹识别 + executorService.execute(() -> { + performFingerprintIdentification(result); + }); + } + + /** + * 执行指纹识别的具体流程 + * @param result Flutter回调结果 + */ + private void performFingerprintIdentification(Result result) { + byte[] imageBuffer = new byte[IMAGE_BUFFER_SIZE]; + final int[] foundUserId = new int[1]; + final int[] imageWidth = new int[1]; + final int[] imageHeight = new int[1]; + final int[] matchScore = new int[1]; + + try { + Log.d(TAG, "请放置手指进行识别"); + showToastOnMainThread("请放置手指进行识别"); + + // 采集指纹图像 + if (captureFingerprint() < 0) { + Map errorResult = createErrorResponse("指纹采集失败"); + mainHandler.post(() -> result.success(errorResult)); + return; + } + + Log.d(TAG, "请移开手指"); + showToastOnMainThread("请移开手指"); + + // 上传指纹图像(仅USB模式) + if (m_devComm.m_nConnected == 2) { + int uploadResult = m_devComm.Run_UpImage(0, imageBuffer, imageWidth, imageHeight); + if (uploadResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(uploadResult); + Log.e(TAG, "上传指纹图像失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> result.success(errorResult)); + return; + } + } + + // 生成指纹特征 + int generateResult = m_devComm.Run_Generate(0); + if (generateResult != DevComm.ERR_SUCCESS) { + String errorMsg; + if (generateResult == DevComm.ERR_BAD_QUALITY) { + errorMsg = "指纹质量不佳,请重试"; + Log.w(TAG, errorMsg); + } else { + errorMsg = GetErrorMsg(generateResult); + Log.e(TAG, "生成指纹特征失败: " + errorMsg); + } + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> { + showToastOnMainThread(errorMsg); + result.success(errorResult); + }); + return; + } + + // 执行指纹搜索 + int searchResult = m_devComm.Run_Search(0, 1, maxFpCount, foundUserId, matchScore); + if (searchResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(searchResult); + Log.e(TAG, "指纹识别失败: " + errorMsg); + Map errorResult = createErrorResponse(errorMsg); + mainHandler.post(() -> { + showToastOnMainThread("未找到匹配的指纹"); + result.success(errorResult); + }); + return; + } + + // 识别成功 + Log.i(TAG, String.format("指纹识别成功,用户ID: %d,匹配分数: %d", foundUserId[0], matchScore[0])); + Map successResult = createSuccessResponse("指纹识别成功"); + successResult.put("userId", foundUserId[0]); + successResult.put("matchScore", matchScore[0]); + mainHandler.post(() -> { + showToastOnMainThread("指纹识别成功"); + result.success(successResult); + }); + + } catch (Exception e) { + Log.e(TAG, "指纹识别过程中发生异常: " + e.getMessage(), e); + Map errorResult = createErrorResponse("识别过程发生异常: " + e.getMessage()); + mainHandler.post(() -> result.success(errorResult)); + } finally { + // 关闭LED指示灯 + try { + m_devComm.Run_SLEDControl(0); + } catch (Exception e) { + Log.e(TAG, "关闭LED失败: " + e.getMessage()); + } + } + } + + /** + * 获取已注册的指纹模板数量 + * @return 获取结果 + */ + private Map getUserCount() { + Log.d(TAG, "开始获取用户数量"); + Map res_data = new HashMap<>(); + + if (!isDeviceReady()) { + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "设备未初始化"); + return res_data; + } + + try { + int[] enrollCount = new int[1]; + int countResult = m_devComm.Run_GetEnrollCount(1, maxFpCount, enrollCount); + + if (countResult != DevComm.ERR_SUCCESS) { + String errorMsg = GetErrorMsg(countResult); + Log.e(TAG, "获取用户数量失败: " + errorMsg); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", errorMsg); + return res_data; + } + + Log.i(TAG, String.format("获取用户数量成功,注册数量: %d", enrollCount[0])); + res_data.put("code", RESPONSE_SUCCESS); + res_data.put("msg", "获取用户数量成功"); + res_data.put("count", enrollCount[0]); + return res_data; + + } catch (Exception e) { + Log.e(TAG, "获取用户数量过程中发生异常: " + e.getMessage(), e); + res_data.put("code", RESPONSE_FAIL); + res_data.put("msg", "获取过程发生异常: " + e.getMessage()); + return res_data; + } + } + + // ==================== 辅助方法 ==================== + + /** + * 检查设备是否准备就绪 + * @return 设备是否已初始化且可用 + */ + private boolean isDeviceReady() { + return m_devComm != null && m_devComm.IsInit(); + } + + /** + * 创建成功响应 + * @param message 成功消息 + * @return 响应Map + */ + private Map createSuccessResponse(String message) { + Map response = new HashMap<>(); + response.put("success", true); + response.put("code", RESPONSE_SUCCESS); + response.put("message", message); + return response; + } + + /** + * 创建错误响应 + * @param message 错误消息 + * @return 响应Map + */ + private Map createErrorResponse(String message) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("code", RESPONSE_FAIL); + response.put("message", message); + return response; + } + + /** + * 在主线程显示Toast消息 + * @param message 要显示的消息 + */ + private void showToastOnMainThread(String message) { + if (activity != null) { + mainHandler.post(() -> { + try { + Toast.makeText(activity, message, Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + Log.w(TAG, "显示Toast失败: " + e.getMessage()); + } + }); + } + } + + /** + * 采集指纹图像(重命名原Capturing方法) + * @return 采集结果,0表示成功,负数表示失败 + */ + private int captureFingerprint() { + return Capturing(); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + Log.d(TAG, "插件从引擎分离"); + + // 清理资源 + if (channel != null) { + channel.setMethodCallHandler(null); + channel = null; + } + + // 关闭设备连接 + if (m_devComm != null && m_devComm.IsInit()) { + try { + m_devComm.CloseComm(); + Log.d(TAG, "设备连接已关闭"); + } catch (Exception e) { + Log.e(TAG, "关闭设备连接时发生异常: " + e.getMessage()); + } + } + + // 关闭线程池 + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + try { + if (!executorService.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS)) { + executorService.shutdownNow(); + } + } catch (InterruptedException e) { + executorService.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + + @Override + public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { + Log.d(TAG, "插件附加到Activity"); + activity = binding.getActivity(); + } + + @Override + public void onDetachedFromActivity() { + Log.d(TAG, "插件从Activity分离"); + activity = null; + } + + @Override + public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { + Log.d(TAG, "插件因配置变更重新附加到Activity"); + onAttachedToActivity(binding); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + Log.d(TAG, "插件因配置变更从Activity分离"); + onDetachedFromActivity(); + } + + private String GetErrorMsg(int nErrorCode) { + String str = ""; + + switch (nErrorCode) { + case DevComm.ERR_SUCCESS: + str = "Succcess"; + break; + case DevComm.ERR_VERIFY: + str = "Verify NG"; + break; + case DevComm.ERR_IDENTIFY: + str = "Identify NG"; + break; + case DevComm.ERR_EMPTY_ID_NOEXIST: + str = "Empty Template no Exist"; + break; + case DevComm.ERR_BROKEN_ID_NOEXIST: + str = "Broken Template no Exist"; + break; + case DevComm.ERR_TMPL_NOT_EMPTY: + str = "Template of this ID Already Exist"; + break; + case DevComm.ERR_TMPL_EMPTY: + str = "This Template is Already Empty"; + break; + case DevComm.ERR_INVALID_TMPL_NO: + str = "Invalid Template No"; + break; + case DevComm.ERR_ALL_TMPL_EMPTY: + str = "All Templates are Empty"; + break; + case DevComm.ERR_INVALID_TMPL_DATA: + str = "Invalid Template Data"; + break; + case DevComm.ERR_DUPLICATION_ID: + str = "Duplicated ID : "; + break; + case DevComm.ERR_BAD_QUALITY: + str = "Bad Quality Image"; + break; + case DevComm.ERR_MERGE_FAIL: + str = "Merge failed"; + break; + case DevComm.ERR_NOT_AUTHORIZED: + str = "Device not authorized."; + break; + case DevComm.ERR_MEMORY: + str = "Memory Error "; + break; + case DevComm.ERR_INVALID_PARAM: + str = "Invalid Parameter"; + break; + case DevComm.ERR_GEN_COUNT: + str = "Generation Count is invalid"; + break; + case DevComm.ERR_INVALID_BUFFER_ID: + str = "Ram Buffer ID is invalid."; + break; + case DevComm.ERR_INVALID_OPERATION_MODE: + str = "Invalid Operation Mode!"; + break; + case DevComm.ERR_FP_NOT_DETECTED: + str = "Finger is not detected."; + break; + default: + str = String.format("Fail, error code=%d", nErrorCode); + break; + } + + return str; + } + + private int Capturing() { + int w_nRet; + while (true) { + + w_nRet = m_devComm.Run_GetImage(); + + if (w_nRet == DevComm.ERR_CONNECTION) { + Log.i("zhiwenPlugin", "Communication error!"); + return -1; + } else if (w_nRet == DevComm.ERR_SUCCESS) + break; + + } + + return 0; + } + + // IUsbConnState接口实现 + + /** + * USB设备连接成功回调 + * 当USB设备成功连接时被调用 + */ + @Override + public void onUsbConnected() { + Log.d(TAG, "USB设备连接成功"); + // 可以在这里添加设备连接成功后的处理逻辑 + } + + /** + * USB权限被拒绝回调 + * 当用户拒绝USB权限请求时被调用 + */ + @Override + public void onUsbPermissionDenied() { + Log.w(TAG, "USB权限被拒绝"); + // 可以在这里添加权限被拒绝后的处理逻辑 + } + + /** + * 设备未找到回调 + * 当无法找到指定的USB设备时被调用 + */ + @Override + public void onDeviceNotFound() { + Log.w(TAG, "未找到USB设备"); + // 可以在这里添加设备未找到后的处理逻辑 + } + +} diff --git a/android/src/main/res/xml/device_filter.xml b/android/src/main/res/xml/device_filter.xml new file mode 100644 index 0000000..595d82e --- /dev/null +++ b/android/src/main/res/xml/device_filter.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/android/src/test/java/com/xiarui/zhiwen/ZhiwenPluginTest.java b/android/src/test/java/com/xiarui/zhiwen/ZhiwenPluginTest.java new file mode 100644 index 0000000..1767acd --- /dev/null +++ b/android/src/test/java/com/xiarui/zhiwen/ZhiwenPluginTest.java @@ -0,0 +1,29 @@ +package com.xiarui.zhiwen; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import org.junit.Test; + +/** + * This demonstrates a simple unit test of the Java portion of this plugin's implementation. + * + * Once you have built the plugin's example app, you can run these tests from the command + * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or + * you can run them directly from IDEs that support JUnit such as Android Studio. + */ + +public class ZhiwenPluginTest { + @Test + public void onMethodCall_getPlatformVersion_returnsExpectedValue() { + ZhiwenPlugin plugin = new ZhiwenPlugin(); + + final MethodCall call = new MethodCall("getPlatformVersion", null); + MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + plugin.onMethodCall(call, mockResult); + + verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE); + } +} diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..29a3a50 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..5b6e5eb --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# zhiwen_example + +Demonstrates how to use the zhiwen plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/android/.gitignore b/example/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle new file mode 100644 index 0000000..3f96b44 --- /dev/null +++ b/example/android/app/build.gradle @@ -0,0 +1,58 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader("UTF-8") { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty("flutter.versionCode") +if (flutterVersionCode == null) { + flutterVersionCode = "1" +} + +def flutterVersionName = localProperties.getProperty("flutter.versionName") +if (flutterVersionName == null) { + flutterVersionName = "1.0" +} + +android { + namespace = "com.xiarui.zhiwen_example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.xiarui.zhiwen_example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutterVersionCode.toInteger() + versionName = flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.debug + } + } +} + +flutter { + source = "../.." +} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d4a363e --- /dev/null +++ b/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/android/app/src/main/java/com/xiarui/zhiwen_example/MainActivity.java b/example/android/app/src/main/java/com/xiarui/zhiwen_example/MainActivity.java new file mode 100644 index 0000000..a2c8f5b --- /dev/null +++ b/example/android/app/src/main/java/com/xiarui/zhiwen_example/MainActivity.java @@ -0,0 +1,6 @@ +package com.xiarui.zhiwen_example; + +import io.flutter.embedding.android.FlutterActivity; + +public class MainActivity extends FlutterActivity { +} diff --git a/example/android/app/src/main/res/drawable-v21/launch_background.xml b/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/main/res/xml/device_filter.xml b/example/android/app/src/main/res/xml/device_filter.xml new file mode 100644 index 0000000..595d82e --- /dev/null +++ b/example/android/app/src/main/res/xml/device_filter.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/build.gradle b/example/android/build.gradle new file mode 100644 index 0000000..d2ffbff --- /dev/null +++ b/example/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties new file mode 100644 index 0000000..3b5b324 --- /dev/null +++ b/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e1ca574 --- /dev/null +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle new file mode 100644 index 0000000..536165d --- /dev/null +++ b/example/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false +} + +include ":app" diff --git a/example/integration_test/plugin_integration_test.dart b/example/integration_test/plugin_integration_test.dart new file mode 100644 index 0000000..14adf64 --- /dev/null +++ b/example/integration_test/plugin_integration_test.dart @@ -0,0 +1,25 @@ +// This is a basic Flutter integration test. +// +// Since integration tests run in a full Flutter application, they can interact +// with the host side of a plugin implementation, unlike Dart unit tests. +// +// For more information about Flutter integration tests, please see +// https://docs.flutter.dev/cookbook/testing/integration/introduction + + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:zhiwen/zhiwen.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('getPlatformVersion test', (WidgetTester tester) async { + final Zhiwen plugin = Zhiwen(); + final String? version = await plugin.getPlatformVersion(); + // The version string depends on the host platform running the test, so + // just assert that some non-empty string is returned. + expect(version?.isNotEmpty, true); + }); +} diff --git a/example/lib/main.dart b/example/lib/main.dart new file mode 100644 index 0000000..b7697aa --- /dev/null +++ b/example/lib/main.dart @@ -0,0 +1,130 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:zhiwen/zhiwen.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({super.key}); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + String _platformVersion = 'Unknown'; + final _zhiwenPlugin = Zhiwen(); + + @override + void initState() { + super.initState(); + initPlatformState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPlatformState() async { + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + // We also handle the message potentially returning null. + try { + platformVersion = + await _zhiwenPlugin.getPlatformVersion() ?? 'Unknown platform version'; + } on PlatformException { + platformVersion = 'Failed to get platform version.'; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _platformVersion = platformVersion; + }); + } + + @override + Widget build(BuildContext context) { + return ScaffoldMessenger( + child: MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Running on: $_platformVersion\n'), + ElevatedButton( + onPressed: () async { + bool result = await _zhiwenPlugin.openDevice("USB", 9600); + }, + child: const Text('打开设备'), + ), + ElevatedButton( + onPressed: () async { + await _zhiwenPlugin.closeDevice(); + }, + child: const Text('关闭设备'), + ), + ElevatedButton( + onPressed: () async { + var random = Random(); + int randomNumber = random.nextInt(100); // 生成 0 到 99 的随机整数 + + Map result = await _zhiwenPlugin.enrollFingerprint(randomNumber); + print(result); + }, + child: const Text('录入指纹'), + ), + ElevatedButton( + onPressed: () async { + int userId = 24; + Map result = await _zhiwenPlugin.verifyFingerprint(userId); + print(result); + }, + child: const Text('验证指纹'), + ), + ElevatedButton( + onPressed: () async { + Map result = await _zhiwenPlugin.deleteAllFingerprint(); + print(result); + }, + child: const Text('删除所有指纹'), + ), + ElevatedButton( + onPressed: () async { + int userId = 2; + Map result = await _zhiwenPlugin.deleteOneFingerprint(userId); + print(result); + }, + child: const Text('删除单个指纹'), + ), + ElevatedButton( + onPressed: () async { + Map result = await _zhiwenPlugin.identifyFingerprint(); + print(result); + }, + child: const Text('识别指纹'), + ), + ElevatedButton( + onPressed: () async { + Map result = await _zhiwenPlugin.getUserCount(); + print(result); + }, + child: const Text('获取指纹总数'), + ), + ], + ), + ), + ), + )); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..9b2a625 --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,283 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + integration_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + url: "https://pub.dev" + source: hosted + version: "3.0.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + url: "https://pub.dev" + source: hosted + version: "0.8.0" + meta: + dependency: transitive + description: + name: meta + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + url: "https://pub.dev" + source: hosted + version: "1.12.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + platform: + dependency: transitive + description: + name: platform + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + process: + dependency: transitive + description: + name: process + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + url: "https://pub.dev" + source: hosted + version: "5.0.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.dev" + source: hosted + version: "14.2.1" + webdriver: + dependency: transitive + description: + name: webdriver + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + zhiwen: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.0.1" +sdks: + dart: ">=3.4.3 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..107f0ef --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,85 @@ +name: zhiwen_example +description: "Demonstrates how to use the zhiwen plugin." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: + sdk: '>=3.4.3 <4.0.0' + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + zhiwen: + # When depending on this package from a real application you should use: + # zhiwen: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.6 + +dev_dependencies: + integration_test: + sdk: flutter + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^3.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart new file mode 100644 index 0000000..51b474a --- /dev/null +++ b/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:zhiwen_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/lib/zhiwen.dart b/lib/zhiwen.dart new file mode 100644 index 0000000..596017f --- /dev/null +++ b/lib/zhiwen.dart @@ -0,0 +1,40 @@ + +import 'zhiwen_platform_interface.dart'; + +class Zhiwen { + Future getPlatformVersion() { + return ZhiwenPlatform.instance.getPlatformVersion(); + } + + Future openDevice(String devicePath, int baudRate) { + return ZhiwenPlatform.instance.openDevice(devicePath, baudRate); + } + + Future closeDevice() { + return ZhiwenPlatform.instance.closeDevice(); + } + + Future> enrollFingerprint(int userId) { + return ZhiwenPlatform.instance.enrollFingerprint(userId); + } + + Future> verifyFingerprint(int userId) { + return ZhiwenPlatform.instance.verifyFingerprint(userId); + } + + Future> deleteAllFingerprint() { + return ZhiwenPlatform.instance.deleteAllFingerprint(); + } + + Future> deleteOneFingerprint(int userId) { + return ZhiwenPlatform.instance.deleteOneFingerprint(userId); + } + + Future> identifyFingerprint() { + return ZhiwenPlatform.instance.identifyFingerprint(); + } + + Future> getUserCount() { + return ZhiwenPlatform.instance.getUserCount(); + } +} diff --git a/lib/zhiwen_method_channel.dart b/lib/zhiwen_method_channel.dart new file mode 100644 index 0000000..097e55e --- /dev/null +++ b/lib/zhiwen_method_channel.dart @@ -0,0 +1,67 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'zhiwen_platform_interface.dart'; + +/// An implementation of [ZhiwenPlatform] that uses method channels. +class MethodChannelZhiwen extends ZhiwenPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('zhiwen'); + + @override + Future getPlatformVersion() async { + final version = await methodChannel.invokeMethod('getPlatformVersion'); + return version; + } + + @override + Future openDevice(String devicePath, int baudRate) async { + final result = await methodChannel.invokeMethod( + 'openDevice', + {'devicePath': devicePath, 'baudRate': baudRate}, + ); + return result ?? false; + } + + @override + Future closeDevice() async { + await methodChannel.invokeMethod('closeDevice'); + } + + @override + Future> enrollFingerprint(int userId) async { + final result = await methodChannel.invokeMethod('enrollFingerprint', {'userId': userId}); + return Map.from(result as Map); + } + + @override + Future> verifyFingerprint(int userId) async { + final result = await methodChannel.invokeMethod('verifyFingerprint', {'userId': userId}); + return Map.from(result as Map); + } + + @override + Future> deleteAllFingerprint() async { + final result = await methodChannel.invokeMethod('deleteAllFingerprint'); + return Map.from(result as Map); + } + + @override + Future> deleteOneFingerprint(int userId) async { + final result = await methodChannel.invokeMethod('deleteOneFingerprint', {'userId': userId}); + return Map.from(result as Map); + } + + @override + Future> identifyFingerprint() async { + final result = await methodChannel.invokeMethod('identifyFingerprint'); + return Map.from(result as Map); + } + + @override + Future> getUserCount() async { + final result = await methodChannel.invokeMethod('getUserCount'); + return Map.from(result as Map); + } +} diff --git a/lib/zhiwen_platform_interface.dart b/lib/zhiwen_platform_interface.dart new file mode 100644 index 0000000..5500956 --- /dev/null +++ b/lib/zhiwen_platform_interface.dart @@ -0,0 +1,38 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'zhiwen_method_channel.dart'; + +abstract class ZhiwenPlatform extends PlatformInterface { + /// Constructs a ZhiwenPlatform. + ZhiwenPlatform() : super(token: _token); + + static final Object _token = Object(); + + static ZhiwenPlatform _instance = MethodChannelZhiwen(); + + /// The default instance of [ZhiwenPlatform] to use. + /// + /// Defaults to [MethodChannelZhiwen]. + static ZhiwenPlatform get instance => _instance; + + Future getPlatformVersion(); + Future openDevice(String devicePath, int baudRate); + Future closeDevice(); + Future> enrollFingerprint(int userId); + Future> verifyFingerprint(int userId); + Future> deleteAllFingerprint(); + Future> deleteOneFingerprint(int userId); + Future> identifyFingerprint(); + Future> getUserCount(); + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [ZhiwenPlatform] when + /// they register themselves. + static set instance(ZhiwenPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + // Future getPlatformVersion() { + // throw UnimplementedError('platformVersion() has not been implemented.'); + // } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..08022e9 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,70 @@ +name: zhiwen +description: "A new Flutter project." +version: 0.0.1 +homepage: + +environment: + sdk: '>=3.4.3 <4.0.0' + flutter: '>=3.3.0' + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.xiarui.zhiwen + pluginClass: ZhiwenPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/test/zhiwen_method_channel_test.dart b/test/zhiwen_method_channel_test.dart new file mode 100644 index 0000000..a829316 --- /dev/null +++ b/test/zhiwen_method_channel_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:zhiwen/zhiwen_method_channel.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + MethodChannelZhiwen platform = MethodChannelZhiwen(); + const MethodChannel channel = MethodChannel('zhiwen'); + + setUp(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( + channel, + (MethodCall methodCall) async { + return '42'; + }, + ); + }); + + tearDown(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null); + }); + + test('getPlatformVersion', () async { + expect(await platform.getPlatformVersion(), '42'); + }); +} diff --git a/test/zhiwen_test.dart b/test/zhiwen_test.dart new file mode 100644 index 0000000..45d1cf1 --- /dev/null +++ b/test/zhiwen_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:zhiwen/zhiwen.dart'; +import 'package:zhiwen/zhiwen_platform_interface.dart'; +import 'package:zhiwen/zhiwen_method_channel.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +class MockZhiwenPlatform + with MockPlatformInterfaceMixin + implements ZhiwenPlatform { + + @override + Future getPlatformVersion() => Future.value('42'); +} + +void main() { + final ZhiwenPlatform initialPlatform = ZhiwenPlatform.instance; + + test('$MethodChannelZhiwen is the default instance', () { + expect(initialPlatform, isInstanceOf()); + }); + + test('getPlatformVersion', () async { + Zhiwen zhiwenPlugin = Zhiwen(); + MockZhiwenPlatform fakePlatform = MockZhiwenPlatform(); + ZhiwenPlatform.instance = fakePlatform; + + expect(await zhiwenPlugin.getPlatformVersion(), '42'); + }); +}