From e9f484435240e32139145a44815eb0306d4f26f0 Mon Sep 17 00:00:00 2001 From: leon <916117771@qq.com> Date: Tue, 31 Mar 2026 08:51:33 +0800 Subject: [PATCH] init --- .gitignore | 29 + .metadata | 30 + CHANGELOG.md | 3 + LICENSE | 1 + README.md | 15 + analysis_options.yaml | 4 + android/.gitignore | 9 + android/build.gradle | 60 + android/libs/arm64-v8a/libserial_port.so | Bin 0 -> 9760 bytes android/libs/armeabi-v7a/libserial_port.so | Bin 0 -> 13484 bytes android/libs/armeabi/libserial_port.so | Bin 0 -> 13476 bytes android/libs/x86/libserial_port.so | Bin 0 -> 5188 bytes android/libs/x86_64/libserial_port.so | Bin 0 -> 10032 bytes android/settings.gradle | 1 + android/src/main/AndroidManifest.xml | 5 + .../java/android_serialport_api/ComBean.java | 21 + .../android_serialport_api/SerialHelper.java | 231 +++ .../android_serialport_api/SerialPort.java | 89 + .../SerialPortFinder.java | 122 ++ .../com/idworld/noemhost_and/DevComm.java | 1840 ++++++++++++++++ .../idworld/noemhost_and/IUsbConnState.java | 12 + .../idworld/noemhost_and/MainActivity.java | 1533 ++++++++++++++ .../idworld/noemhost_and/UsbController.java | 440 ++++ .../main/java/com/xiarui/zhiwen/DevComm.java | 1842 +++++++++++++++++ .../java/com/xiarui/zhiwen/IUsbConnState.java | 12 + .../java/com/xiarui/zhiwen/UsbController.java | 440 ++++ .../java/com/xiarui/zhiwen/ZhiwenPlugin.java | 1001 +++++++++ android/src/main/res/xml/device_filter.xml | 7 + .../com/xiarui/zhiwen/ZhiwenPluginTest.java | 29 + example/.gitignore | 43 + example/README.md | 16 + example/analysis_options.yaml | 28 + example/android/.gitignore | 13 + example/android/app/build.gradle | 58 + .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 57 + .../xiarui/zhiwen_example/MainActivity.java | 6 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values-night/styles.xml | 18 + .../app/src/main/res/values/styles.xml | 18 + .../app/src/main/res/xml/device_filter.xml | 7 + .../app/src/profile/AndroidManifest.xml | 7 + example/android/build.gradle | 18 + example/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 + example/android/settings.gradle | 25 + .../plugin_integration_test.dart | 25 + example/lib/main.dart | 130 ++ example/pubspec.lock | 283 +++ example/pubspec.yaml | 85 + example/test/widget_test.dart | 27 + lib/zhiwen.dart | 40 + lib/zhiwen_method_channel.dart | 67 + lib/zhiwen_platform_interface.dart | 38 + pubspec.yaml | 70 + test/zhiwen_method_channel_test.dart | 27 + test/zhiwen_test.dart | 29 + 63 files changed, 8950 insertions(+) create mode 100644 .gitignore create mode 100644 .metadata create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 android/.gitignore create mode 100644 android/build.gradle create mode 100644 android/libs/arm64-v8a/libserial_port.so create mode 100644 android/libs/armeabi-v7a/libserial_port.so create mode 100644 android/libs/armeabi/libserial_port.so create mode 100644 android/libs/x86/libserial_port.so create mode 100644 android/libs/x86_64/libserial_port.so create mode 100644 android/settings.gradle create mode 100644 android/src/main/AndroidManifest.xml create mode 100644 android/src/main/java/android_serialport_api/ComBean.java create mode 100644 android/src/main/java/android_serialport_api/SerialHelper.java create mode 100644 android/src/main/java/android_serialport_api/SerialPort.java create mode 100644 android/src/main/java/android_serialport_api/SerialPortFinder.java create mode 100644 android/src/main/java/com/idworld/noemhost_and/DevComm.java create mode 100644 android/src/main/java/com/idworld/noemhost_and/IUsbConnState.java create mode 100644 android/src/main/java/com/idworld/noemhost_and/MainActivity.java create mode 100644 android/src/main/java/com/idworld/noemhost_and/UsbController.java create mode 100644 android/src/main/java/com/xiarui/zhiwen/DevComm.java create mode 100644 android/src/main/java/com/xiarui/zhiwen/IUsbConnState.java create mode 100644 android/src/main/java/com/xiarui/zhiwen/UsbController.java create mode 100644 android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java create mode 100644 android/src/main/res/xml/device_filter.xml create mode 100644 android/src/test/java/com/xiarui/zhiwen/ZhiwenPluginTest.java create mode 100644 example/.gitignore create mode 100644 example/README.md create mode 100644 example/analysis_options.yaml create mode 100644 example/android/.gitignore create mode 100644 example/android/app/build.gradle create mode 100644 example/android/app/src/debug/AndroidManifest.xml create mode 100644 example/android/app/src/main/AndroidManifest.xml create mode 100644 example/android/app/src/main/java/com/xiarui/zhiwen_example/MainActivity.java create mode 100644 example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 example/android/app/src/main/res/drawable/launch_background.xml create mode 100644 example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 example/android/app/src/main/res/values-night/styles.xml create mode 100644 example/android/app/src/main/res/values/styles.xml create mode 100644 example/android/app/src/main/res/xml/device_filter.xml create mode 100644 example/android/app/src/profile/AndroidManifest.xml create mode 100644 example/android/build.gradle create mode 100644 example/android/gradle.properties create mode 100644 example/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 example/android/settings.gradle create mode 100644 example/integration_test/plugin_integration_test.dart create mode 100644 example/lib/main.dart create mode 100644 example/pubspec.lock create mode 100644 example/pubspec.yaml create mode 100644 example/test/widget_test.dart create mode 100644 lib/zhiwen.dart create mode 100644 lib/zhiwen_method_channel.dart create mode 100644 lib/zhiwen_platform_interface.dart create mode 100644 pubspec.yaml create mode 100644 test/zhiwen_method_channel_test.dart create mode 100644 test/zhiwen_test.dart 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 0000000000000000000000000000000000000000..3659c4cdb4e3b4011ad98cf760c6b3f4d28c26bb GIT binary patch literal 9760 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 BecJ#4 literal 0 HcmV?d00001 diff --git a/android/libs/armeabi-v7a/libserial_port.so b/android/libs/armeabi-v7a/libserial_port.so new file mode 100644 index 0000000000000000000000000000000000000000..9a5aeb957c852dc56e3feff47ced814afb15807a GIT binary patch literal 13484 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 HirM`S^3Vp0 literal 0 HcmV?d00001 diff --git a/android/libs/armeabi/libserial_port.so b/android/libs/armeabi/libserial_port.so new file mode 100644 index 0000000000000000000000000000000000000000..15417c6104041f7ffbdaeb034aec746e0f53b916 GIT binary patch literal 13476 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 PD7h1M0~Cpegx&uD+!c#9 literal 0 HcmV?d00001 diff --git a/android/libs/x86/libserial_port.so b/android/libs/x86/libserial_port.so new file mode 100644 index 0000000000000000000000000000000000000000..6a1ce7970312688f0d5c91d5d9ee01df4c060565 GIT binary patch literal 5188 zcmcIoZERE589qr27zlQNtb;I3m=Ikw0P{Pr~@@4 zdMsuDqzx_dL^#s(MEHmni;G9Jel4se^i(pYha1w-R7{KaB~wPYLFh`>4rIfN(8D~h$SGTQ&fW%gUTCixaO=^w#?*%Ocu|8S5 z#6q$8_0I{h0E#?00^B4=kXz&k^bR?K&5|S7ZE^&#&a>jIvoe#pYhsNFT9k| zcGY8M_FuOwj!-i>8?4*~bqF9NP79HHRy~2fKih|O8QdLOk7e>_(*T%; zf9xc5nc0Lt`y^Io+&|U`b!N8FpM3!qnb}?b>@3!IWYRy<2R_}du7`stq+tgCP|H?7 zqHTh$f9x43Lc+TMf+hsx{QYCg;1v?Tseo_;tU@ANh3-`;{WH8qRytuTu*ikg3=6-| zjsyNT}mQGfoCKjN3Ok|pye%s}QXbfyl2XHD4o$Hq9X z$KSjIg6A1yD0?@$4U8d9Ek%sePK(Sp%gblw*9s4O|a+uLSkWPF8;*_V9$-kM_PjE+*mSR z+H&*FF7?6D4%F4pmfl2Nb*bLbCKZB!HU4AxNH{vw9XSe8FK zfsXBcSDAM!yzx|?iY_d1m)bnKMU^2if&9ZxWR}@VK1I9QGOVl3wg0joF{7(nKB99a zoS|sHFbKsKwQlmSmX*0wzZluV%vwY@i54IbK-!VBRR>vE6j-$@oRGO)#gM$ z5i^AhB9Yd37O62OzC&@l^NcVXEH^ubDrFL2q#{-a*1(Qp?d_8ZQ z=$uEG)xqe-B|HiIBR3gGSK|l15kBM`Tgc&hz6%QHKg2oHFUt&93sE>*#2m0NQN&24 zC}fIwF?UJ21XCX=;wtJpi`Y-xR>alB8;h9rSh%-{J=8BR;swN2Ha0VxoJ26MPImHd zy)UaF?~@rRyvH-tJ~PeC4%pxL9j(obK;QAf(s}d0gkQsCVY+C~{P;ND1S-+&tJq|`rli`i-?yOaV2q85#tmUg@2&Xo%vyv zMd3|g`8@7}+wUj&zIX+XIXv|SiUQSeJ!h!(DAFdm3G9tAVCLjTnU=-uZkF6jOf^fn zL#;M*Q$#!|0_~B9Sx{Ud0sNeuRCIlQ$vJmP{Op zbsxoLty{6>wv7?#jvAU_qyp;{-UXw&Fe2%4(Km5H+z?A{*an04XgZRL^%=>O2&{Wd zY>6de#+SrSp%>*l6aBb$>dIm5sGh>5Q(g}_fUbm;I$d;pa=gu=cbjhC9|Ml*I;`s+ zJW$!RmAbU@t(eiH9Eoe)X{G*H-7$f$6uVVCwNF$Gcq>*_dpswQPRe;hYDUtQ)1=*3 zv)kv9vL?V=?^>2hd8^NxsodjJ_W8W6Q$7!Uxu=h@D?YcuF3D1hT25B^_b)K^~qcmO_U067`>r)3S%*XP~ltA514*zg<^U%qqm zeU0iGirFewRc-z`js@N-_QU=vu3R(V*C<2IE`bNY1>`;83it`|7Vzi5yTC7D%RUD# z1O7jL+{7X_&(Im%v3XWAN1p}lfUp*PsYA`c{9fbQuon1iI53m+;d0a>H_S2hJY%i{ z^IfqBoI~A$A-duci2RDf-*EWb4*wfC-zl>o-fsErz2uvDo<8%dv2Z zB^mpFZSuR>aXO9X{0Zn~&_&Q6KyQKG1qlVTy{+wwN?`l$N7pG$!H1N_`i4#Q4UHR> zKwm1FipHZ_I?BDr`SC0#hq35R#&xA3*w6qhg6W>LkutQyBB&ovq>uO7+(?OFkCyHc zK?I`4?)1eC5yS^5ep5;LwHJ)`gpZ`O-l&-Cg?n^(0|$xCruiar=m+^~NG1 z*quZa`~+oCI~cwkMKF@=?TzAlG>DTh8thISg;iXCpg)>Q$C3$7`qMSm0EuZM4Uu-B@9G(kbPtI6rX6dQ#QG?;V-4L0qTN;y zYn;TIryc806_tEG09M_|O+yww;<5+AHAolAC&}g^T?#f^4NY8^xmQ$>U9nT}Tx#QB7W4dhz M?9RIYoO-r@0~WOL=Kufz literal 0 HcmV?d00001 diff --git a/android/libs/x86_64/libserial_port.so b/android/libs/x86_64/libserial_port.so new file mode 100644 index 0000000000000000000000000000000000000000..bc31e32c90197f79efff09ec9b25951687277373 GIT binary patch literal 10032 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 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'); + }); +}