diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..eca4d23
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,48 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ namespace 'com.example.test6'
+ compileSdk 33
+
+ defaultConfig {
+ applicationId "com.example.test6"
+ minSdk 30
+ targetSdk 33
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ externalNativeBuild {
+ cmake {
+ path file('src/main/cpp/CMakeLists.txt')
+ version '3.22.1'
+ }
+ }
+ buildFeatures {
+ viewBinding true
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'com.google.android.material:material:1.5.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..f2304b9
--- /dev/null
+++ b/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.test6;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.example.test6", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e2a9db8
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..2c898fe
--- /dev/null
+++ b/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,53 @@
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html
+
+# Sets the minimum version of CMake required to build the native library.
+
+cmake_minimum_required(VERSION 3.22.1)
+
+# Declares and names the project.
+
+project("chip")
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+
+add_library( # Sets the name of the library.
+ chip
+
+ # Sets the library as a shared library.
+ SHARED
+
+ # Provides a relative path to your source file(s).
+ chip.cpp
+ GPIOControl.cpp
+ NrsecPort.cpp
+ SpiPort.cpp
+ native-lib.cpp
+ )
+
+# Searches for a specified prebuilt library and stores the path as a
+# variable. Because CMake includes system libraries in the search path by
+# default, you only need to specify the name of the public NDK library
+# you want to add. CMake verifies that the library exists before
+# completing its build.
+
+find_library( # Sets the name of the path variable.
+ log-lib
+
+ # Specifies the name of the NDK library that
+ # you want CMake to locate.
+ log)
+
+# Specifies libraries CMake should link to your target library. You
+# can link multiple libraries, such as libraries you define in this
+# build script, prebuilt third-party libraries, or system libraries.
+
+target_link_libraries( # Specifies the target library.
+ chip
+
+ # Links the target library to the log library
+ # included in the NDK.
+ ${log-lib})
\ No newline at end of file
diff --git a/app/src/main/cpp/GPIOControl.cpp b/app/src/main/cpp/GPIOControl.cpp
new file mode 100644
index 0000000..187f7e3
--- /dev/null
+++ b/app/src/main/cpp/GPIOControl.cpp
@@ -0,0 +1,134 @@
+//
+// Created by Matthew on 2023/12/27.
+//
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "GPIOControl.h"
+
+#ifdef _DEBUG
+#include
+#endif
+
+#define IOT_PARAM_WRITE 0xAE
+#define IOT_PARAM_READ 0xAF
+#define MAX_STRING_LEN 32
+
+typedef struct
+{
+ int cmd;
+ int value;
+ int result;
+ long value2;
+ char str[MAX_STRING_LEN];
+}IOT_PARAM;
+
+void GpioControl::setInt(int cmd, int value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value = value;
+ // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
+ if( fd > 0 )
+ {
+ int res = ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+ close(fd);
+ }
+ return;
+}
+
+int GpioControl::getInt(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+#ifdef _DEBUG
+ ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
+#endif
+ close(fd);
+ return param.value;
+ }
+ return -1;
+}
+
+void GpioControl::setLong(int cmd, long value)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ IOT_PARAM param;
+ param.cmd = cmd;
+ param.value2 = value;
+ // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2);
+
+ if( fd > 0 )
+ {
+ ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
+ close(fd);
+ }
+}
+
+long GpioControl::getLong(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+ // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
+ close(fd);
+ return param.value2;
+ }
+ return -1;
+}
+
+void GpioControl::setString(int cmd, const std::string& value)
+{
+ IOT_PARAM param;
+ // char *pval = jstringToChars(env, value);
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
+
+ param.cmd = cmd;
+ memset(param.str, 0, MAX_STRING_LEN);
+ memcpy(param.str, value.c_str(), len);
+ // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
+ if( fd > 0 )
+ {
+ ioctl(fd, IOT_PARAM_WRITE, ¶m);
+ // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
+ close(fd);
+ }
+ return;
+}
+
+std::string GpioControl::getString(int cmd)
+{
+ int fd = open("/dev/mtkgpioctrl", O_RDONLY);
+ // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
+ if( fd > 0 )
+ {
+ IOT_PARAM param;
+ param.cmd = cmd;
+ ioctl(fd, IOT_PARAM_READ, ¶m);
+ // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
+ close(fd);
+ return std::string(param.str);
+ }
+ return "";
+}
diff --git a/app/src/main/cpp/GPIOControl.h b/app/src/main/cpp/GPIOControl.h
new file mode 100644
index 0000000..83e5a29
--- /dev/null
+++ b/app/src/main/cpp/GPIOControl.h
@@ -0,0 +1,166 @@
+//
+// Created by Matthew on 2023/12/27.
+//
+
+#ifndef MICROPHOTO_GPIOCONTROL_H
+#define MICROPHOTO_GPIOCONTROL_H
+
+#include
+
+#define CMD_GET_LIGHT_ADC 101
+#define CMD_SET_LIGHT_ADC 102
+#define CMD_GET_KEY_LOCKSTATE 103
+#define CMD_GET_BAT_ADC 104
+#define CMD_SET_FLASH_LED 105
+#define CMD_SET_NETWORK_STATE 106
+#define CMD_SET_OTG_STATE 107
+#define CMD_GET_OTG_STATE 108
+#define CMD_GET_CHARGING_VOL_STATE 110
+#define CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE 111
+#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112
+#define CMD_GET_CHARGING_POWER_STATE 113
+#define CMD_GET_CHARGING_CURRENT_STATE 114
+#define CMD_GET_BAT_VOL_STATE 115
+#define CMD_GET_BAT_SHUNT_VOLTAGE_STATE 116
+#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117
+#define CMD_GET_BAT_POWER_STATE 118
+#define CMD_GET_BAT_CURRENT_STATE 119
+#define CMD_SET_485_STATE 121
+#define CMD_SET_SPI_MODE 123
+#define CMD_SET_SPI_BITS_PER_WORD 124
+#define CMD_SET_SPI_MAXSPEEDHZ 125
+#define CMD_SET_PWM_BEE_STATE 126
+#define CMD_SET_ALM_MODE 128
+#define CMD_SET_SPI_POWER 129
+#define CMD_SET_485_EN_STATE 131
+#define CMD_SET_CAM_3V3_EN_STATE 132
+#define CMD_SET_12V_EN_STATE 133
+#define CMD_SET_SYSTEM_RESET 202
+
+class GpioControl
+{
+public:
+
+ static void setInt(int cmd, int value);
+ static int getInt(int cmd);
+ static void setLong(int cmd, long value);
+ static long getLong(int cmd);
+ static void setString(int cmd, const std::string& value);
+ static std::string getString(int cmd);
+
+ static void setOtgState(bool on)
+ {
+ setInt(CMD_SET_OTG_STATE, on ? 1 : 0);
+ }
+
+ static bool getOtgState()
+ {
+ return getInt(CMD_SET_OTG_STATE) != 0;
+ }
+
+ static void setCam3V3Enable(bool enabled)
+ {
+ setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0);
+ }
+
+ static void reboot()
+ {
+ setInt(CMD_SET_SYSTEM_RESET, 1);
+ }
+
+ static void setLightAdc(int i)
+ {
+ setInt(CMD_SET_LIGHT_ADC, i);
+ }
+
+ static int getLightAdc()
+ {
+ return getInt(CMD_GET_LIGHT_ADC);
+ }
+
+ static int getChargingVoltage()
+ {
+ return getInt(CMD_GET_CHARGING_VOL_STATE);
+ }
+
+ static int getChargingShuntVoltage()
+ {
+ return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE);
+ }
+
+ static int getChargingBusVoltage() {
+ return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE);
+ }
+
+ static int getChargingPower() {
+ return getInt(CMD_GET_CHARGING_POWER_STATE);
+ }
+
+ static int getChargingCurrent() {
+ return getInt(CMD_GET_CHARGING_CURRENT_STATE);
+ }
+
+ static int getBatteryVoltage() {
+ return getInt(CMD_GET_BAT_VOL_STATE);
+ }
+
+ static int getBatteryShuntVoltage() {
+ return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE);
+ }
+
+ static int getBatteryBusVoltage() {
+ return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE);
+ }
+
+ static int getBatteryPower() {
+ return getInt(CMD_GET_BAT_POWER_STATE);
+ }
+
+ static int getBatteryCurrent() {
+ return getInt(CMD_GET_BAT_CURRENT_STATE);
+ }
+
+ static void set485WriteMode() {
+ setInt(CMD_SET_485_STATE, 1);
+ }
+
+ static void set485ReadMode() {
+ setInt(CMD_SET_485_STATE, 0);
+ }
+
+ static void setSpiMode(int i) {
+ setInt(CMD_SET_SPI_MODE, i);
+ }
+
+ static void setSpiBitsPerWord(int i) {
+ setInt(CMD_SET_SPI_BITS_PER_WORD, i);
+ }
+
+ static void setSpiMaxSpeedHz(long j) {
+ setLong(CMD_SET_SPI_MAXSPEEDHZ, j);
+ }
+
+ static void setBeeOn(bool z) {
+ setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0);
+ }
+
+ static void setJidianqiState(bool z) {
+ setInt(CMD_SET_ALM_MODE, z ? 1 : 0);
+ }
+
+ static void setSpiPower(bool on) {
+ setInt(CMD_SET_SPI_POWER, on ? 1 : 0);
+ }
+
+ static void setRS485Enable(bool z) {
+ setInt(CMD_SET_485_EN_STATE, z ? 1 : 0);
+ }
+
+ static void set12VEnable(bool z) {
+ setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0);
+ }
+
+};
+
+
+#endif //MICROPHOTO_GPIOCONTROL_H
diff --git a/app/src/main/cpp/NrsecPort.cpp b/app/src/main/cpp/NrsecPort.cpp
new file mode 100644
index 0000000..5f1eb64
--- /dev/null
+++ b/app/src/main/cpp/NrsecPort.cpp
@@ -0,0 +1,1310 @@
+#include "NrsecPort.h"
+#ifdef __ANDROID__
+#include
+#endif
+
+#define RE_SUC 0x01
+#define RE_ERROR 0x00
+
+#define TAG_SPI "SPI"
+
+const uint8_t EK_CMD[5] = { 0x80,0xd4,0x01,0x00,0x10 };
+const uint8_t AK_CMD[5] = { 0x80,0xd4,0x02,0x00,0x10 };
+const uint8_t IV_CMD[5] = { 0x80,0xd4,0x04,0x00,0x10 };
+uint8_t SM1Encrypt_CMD[5] = { 0xa0,0xe0,0x80,0xff,0xff };
+uint8_t SM1decoder_CMD[5] = { 0xa0,0xe0,0x81,0xff,0xff };
+uint8_t SM2Keypair_CMD[5] = { 0x80,0xb2,0x00,0xff,0x00 };
+uint8_t SM2OutPub_CMD[5] = { 0x80,0xb8,0x01,0xff,0x40 };
+uint8_t SM2OutPri_CMD[5] = { 0x80,0xb8,0x02,0xff,0x20 };
+uint8_t SM2InPub_CMD[5] = { 0x80,0xba,0x01,0xff,0x40 };
+uint8_t SM2InPri_CMD[5] = { 0x80,0xba,0x02,0xff,0x20 };
+uint8_t SM3Hash_CMD[5] = { 0x80,0xb5,0x00,0xff,0xff };
+uint8_t SM2Sign_CMD[5] = { 0x80,0xb4,0x00,0xff,0x20 };
+uint8_t SM2VerifySign_CMD[5] = { 0x80,0xb6,0x00,0xff,0x60 };
+uint8_t SM2encrypt_CMD[5] = { 0x80,0xb3,0x01,0xff,0x20 };
+uint8_t SM2decoder_CMD[5] = { 0x80,0xb3,0x81,0xff,0x80 };
+uint8_t SM2cert_CMD[5] = { 0x80,0xb7,0xff,0xff,0xff };
+uint8_t Random_CMD[5] = { 0x00,0x84,0x00,0x00,0xff };
+const uint8_t Version_CMD[5] = { 0x00,0x5b,0x00,0x00,0x40 };
+const uint8_t Indentify_CMD[5] = { 0x80,0xb3,0x01,0x04,0x20 };
+
+uint8_t NrsecPort::CalcCRC7(const uint8_t *buff, int len)
+{
+ const static uint8_t crc7_table[256] = {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
+ 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
+ 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
+ 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
+ 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
+ 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
+ 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
+ 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
+ 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
+ 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
+ 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
+ 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
+ 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
+ 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
+ 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+ };
+
+ uint8_t crc7_accum = 0;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ crc7_accum =
+ crc7_table[(crc7_accum << 1) ^ buff[i]];
+ }
+ return crc7_accum;
+}
+
+void NrsecPort::SendCMD(uint8_t* cmd, uint8_t* rxbuf)
+{
+ int i = 0;
+ int retval;
+
+#if defined (CONFIG_ATMEL_SPI_DEBUG)
+ printf("tx %1d bytes: ", CMD_HEAD_SIZE);
+ for (i = 0; i < CMD_HEAD_SIZE; i++)
+ {
+ printf(" %02x", cmd[i]);
+ }
+ printf("\n");
+#endif
+
+ /* send five command header */
+ for (i = 0; i < CMD_HEAD_SIZE; i++)
+ {
+ retval = spi_transfer(cmd + i, rxbuf + i, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "cmd[%d]=%x,rxbuf[%d]=%x", i, *(cmd + i), i, *(rxbuf + i));
+#endif
+ delay(20);
+ }
+
+ cmd[0] = 0xaa; //for response
+}
+
+void NrsecPort::RcvINS(uint8_t* txbuf, uint8_t* buf, uint8_t ins)
+{
+ int retval;
+ int cnt = 5000;
+ /* receive ins */
+INS:
+ txbuf[0] = 0xaa;
+ //delay(1000);
+ while (cnt--)
+ {
+ retval = spi_transfer(txbuf, buf, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RcvINS txbuf=%x,buf=%x", *txbuf, *buf);
+#endif
+ if (*buf == ins)
+ {
+ return;
+ break;
+ }
+ else
+ {
+ delay(1000);
+ }
+ }
+}
+
+void NrsecPort::RcvLEN(uint8_t* txbuf, uint8_t* buf, uint8_t len)
+{
+ int retval;
+ /* receive length */
+LEN:
+ for (int i = 0; i < len; i++) {
+ txbuf[0] = 0xaa;
+ retval = spi_transfer(txbuf, buf + i, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RecvLEN txbuf=%x,rxbuf=%x", *txbuf, *(buf + i));
+#endif
+ }
+}
+
+//Rcvdata
+void NrsecPort::RcvData(uint8_t*txbuf, uint8_t* buf)
+{
+ int len = *(buf - 1);
+ RcvData(txbuf, buf, len);
+}
+
+void NrsecPort::RcvData(uint8_t*txbuf, uint8_t*buf, int len)
+{
+ int i;
+ int retval;
+
+ for (i = 0; i < len; i++)
+ {
+ *(txbuf + i) = 0xaa;
+ }
+
+ /* receive data and crc */
+ for (i = 0; i < len; i++)
+ {
+ retval = spi_transfer(txbuf, buf + i, 1);
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RcvData data[%d]=%x", i, *(buf + i));
+ }
+
+}
+
+//RcvSW
+bool NrsecPort::RcvSW(uint8_t*txbuf, uint8_t*buf, uint8_t sw)
+{
+ int i;
+ int retval;
+ int cnt = 3000;
+ bool flag =false;
+
+
+SW90:
+ /* receive state word */
+ delay(1000);//20
+ while (cnt--)
+ {
+ retval = spi_transfer(txbuf, buf, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RecvSW txbuf=%x,buf=%x", *txbuf, *buf);
+#endif
+ if (*buf != sw)
+ {
+ goto SW90;
+ }
+ else{
+ flag = true;
+ break;
+ }
+ }
+ retval = spi_transfer(txbuf, buf + 1, 1);
+ return flag;
+
+}
+
+void NrsecPort::SendEnd(uint8_t* txbuf, uint8_t* buf)
+{
+ int retval;
+ txbuf[0] = 0xaa;
+ retval = spi_transfer(txbuf, buf, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendEnd txbuf=%x,rxbuf=%hhu", *txbuf, *buf);
+#endif
+}
+
+void NrsecPort::SendId(uint8_t* txbuf, uint8_t* buf, uint8_t id)
+{
+ int retval;
+ txbuf[0] = id;
+ retval = spi_transfer(txbuf, buf, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendID txbuf=%x,rxbuf=%hhu", *txbuf, *buf);
+#endif
+}
+
+void NrsecPort::SendData(uint8_t* data, uint8_t* rxbuf, int data_size)
+{
+ int i = 0;
+ int retval;
+ uint8_t crc[1];
+ crc[0] = CalcCRC7(data, data_size);
+
+ for (i = 0; i < data_size; i++)
+ {
+ retval = spi_transfer(data + i, rxbuf + i, 1);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendData i=%d,txbuf=%x,rxbuf=%x", i, *(data + i), *(rxbuf + i));
+#endif
+ delay(20);
+ }
+ retval = spi_transfer(crc, rxbuf, 1);
+}
+
+int NrsecPort::SM1ImportKey(const uint8_t* ek, const uint8_t* ak)
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ int ret=0;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *)EK_CMD, sizeof(EK_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, ek, 16);
+// txbuf[16] = CalcCRC7(ek, 16);
+
+ SendData(txbuf, rxbuf, 16);
+
+ if (!RcvSW(txbuf, rxbuf, 0x90))
+ {
+ return 0;
+ }
+
+ memcpy(txbuf, (const void *)AK_CMD, sizeof(AK_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, ak, 16);
+// txbuf[16] = CalcCRC7(ak, 16);
+
+ SendData(txbuf, rxbuf, 16);//senddata函数中已经包含crc了
+
+ SendEnd(txbuf, rxbuf);
+
+ ret = RcvSW(txbuf, rxbuf, 0x90);
+
+ return ret;
+}
+
+int NrsecPort::ImportIV(const uint8_t* iv, uint8_t ivLength)
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ int ret=0;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)IV_CMD, sizeof(IV_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, iv, ivLength);
+// txbuf[ivLength] = CalcCRC7(iv, ivLength);
+
+ SendData(txbuf, rxbuf, ivLength);
+
+ SendEnd(txbuf, rxbuf);
+
+ ret = RcvSW(txbuf, rxbuf, 0x90);
+
+ return ret;
+}
+
+int NrsecPort::SM1Encrypt(const uint8_t* data, uint16_t dataLen, uint8_t* encryptedData, uint16_t* bufferLen)
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[2048];
+ uint8_t rxbuf[2048];
+
+ int retval;
+ int msglen;
+
+ int ret=0;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM1Encrypt_CMD, sizeof(SM1Encrypt_CMD));
+
+ txbuf[3] = dataLen >> 8;
+ txbuf[4] = dataLen & 0xFF;
+
+ SendCMD(txbuf, rxbuf);
+
+ //SendEnd(txbuf,rxbuf);//遇到长度的0xe0数据
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf,data,dataLen);
+
+ SendData(txbuf,rxbuf,dataLen);
+
+ SendEnd(txbuf,rxbuf);
+
+ RcvINS(txbuf,rxbuf,0xe0);
+
+ RcvLEN(txbuf, rxbuf + 1, 2); //长度 多加一个字节的 CRC
+
+// uint8_t len = *(rxbuf + 1);
+ uint16_t len =(*(rxbuf+1)<<8) + (*(rxbuf+2));
+
+ RcvData(txbuf, rxbuf + 3, len);
+
+ ret = RcvSW(txbuf, rxbuf + 3 + len, 0x90);
+
+ if(ret == 1)
+ {
+ //计算接收到数据的CRC
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Calcac = %x", CalcCRC7(rxbuf + 3, len-1));
+ if (CalcCRC7(rxbuf + 3, len-1) != rxbuf[len + 2])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ ret =0;
+ printf("ERROR\n");
+ return ret;
+ }
+ }
+
+ // printf("rx %1d bytes: ", rxbuf[1] + 4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+
+ memcpy(encryptedData, rxbuf + 3, len-1);
+ //memcpy(&bufferLen, &len-1, 1);
+ * bufferLen = len -1;
+ }
+ return ret;
+}
+
+int NrsecPort::SM1Decrypt(const uint8_t* encryptedData, uint16_t encryptedDataLen, uint8_t* data, uint16_t* bufferLen)
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[2048];//256
+ uint8_t rxbuf[2048];//256
+
+ int retval;
+ int msglen;
+
+ int ret =0;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+
+ CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM1decoder_CMD, sizeof(SM1decoder_CMD));
+
+ txbuf[3] = encryptedDataLen >> 8;
+ txbuf[4] = encryptedDataLen & 0xFF;
+
+ SendCMD(txbuf, rxbuf);
+
+ //SendEnd(txbuf,rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf,encryptedData,encryptedDataLen);
+
+ SendData(txbuf,rxbuf,encryptedDataLen);
+
+ SendEnd(txbuf,rxbuf);
+
+ RcvINS(txbuf,rxbuf,0xe0);
+
+ RcvLEN(txbuf, rxbuf + 1, 2); //长度 多加一个字节的 CRC
+
+// uint8_t len = *(rxbuf + 1);
+ uint16_t len =(*(rxbuf+1)<<8) + (*(rxbuf+2));
+
+ RcvData(txbuf, rxbuf + 3, len);
+
+ ret = RcvSW(txbuf, rxbuf + 3 + len, 0x90);
+
+ if(ret == 1)
+ {
+ //计算接收到数据的CRC
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Calcac = %x", CalcCRC7(rxbuf + 3, len-1));
+ if (CalcCRC7(rxbuf + 3, len-1) != rxbuf[len + 2])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ ret = 0;
+ printf("ERROR\n");
+ return ret;
+ }
+ }
+
+ // printf("rx %1d bytes: ", rxbuf[1] + 4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+
+ memcpy(data, rxbuf + 3, len-1);
+ //memcpy(&bufferLen, &len-1, 1);
+ * bufferLen = len -1;
+ }
+
+ return ret;
+}
+
+int NrsecPort::Random(uint8_t* output, uint8_t length)
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ int ret = 0;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)Random_CMD, sizeof(Random_CMD));
+
+ txbuf[4] = length;
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC
+
+ uint8_t len = *(rxbuf + 1);
+
+ RcvData(txbuf, rxbuf + 2, len);
+
+ ret = RcvSW(txbuf, rxbuf + 2 + len, 0x90);
+
+ if(ret ==1)
+ {
+ //计算接收到数据的CRC
+ if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ printf("ERROR\n");
+ ret=0;
+ return ret;
+ }
+ }
+
+ // printf("rx %1d bytes: ", rxbuf[1] + 4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+ memcpy(output, rxbuf + 2, len-1);
+ }
+
+ return ret;
+}
+
+std::string NrsecPort::Version()
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, Version_CMD, sizeof(Version_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ // txbuf[4] = 0xAA;
+ RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC
+
+ int dataLen = *(rxbuf + 1);
+
+ RcvData(txbuf, rxbuf + 2, dataLen);
+
+ RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //计算接收到数据的CRC
+ if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ printf("ERROR\n");
+ }
+ }
+
+ //printf("rx %1d bytes: ", rxbuf[1]+4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+ std::string version = "";
+ char output[16] = { 0 };
+ for (i = 0; i < dataLen-1; i++) {
+ if (*(rxbuf + 2 + i) == 0) {
+ break;
+ }
+ snprintf(output, sizeof(output), "%c", *(rxbuf + 2 + i));
+ version += output;
+ }
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Version: %s", version.c_str());
+#endif
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf);
+ // printf("\n");
+
+
+ return version;
+}
+
+int NrsecPort::SM2keypair(int index)//产生密钥
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ SM2Keypair_CMD[3] = index;
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2Keypair_CMD, sizeof(SM2Keypair_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvSW(txbuf, rxbuf, 0x90);
+
+
+
+ return 0;
+}
+
+int NrsecPort::SM2ExportPublicKey(int index, uint8_t result[], uint8_t * len)//导出公钥
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int ret=0;
+
+ int retval;
+ int msglen;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ SM2OutPub_CMD[3] = index;
+
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2OutPub_CMD, sizeof(SM2OutPub_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC
+
+ RcvData(txbuf, rxbuf + 2);
+
+ ret = RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ if(ret == 1) {
+ //计算接收到数据的CRC
+ if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1]) {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3) {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ } else {
+ ret = 0;
+ printf("ERROR\n");
+ return ret;
+ }
+ }
+
+
+ //printf("rx %1d bytes: ", rxbuf[1]+4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+ memcpy(result, rxbuf + 2, rxbuf[1] - 1);
+ *len = rxbuf[1] - 1;
+ }
+ return ret;
+}
+
+int NrsecPort::SM2ExportPrivateKey(int index, uint8_t result[],uint8_t * len)//导出私钥
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ cnt = 0;
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ SM2OutPri_CMD[3] = index;
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2OutPri_CMD, sizeof(SM2OutPri_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC
+
+ RcvData(txbuf, rxbuf + 2);
+
+ RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //计算接收到数据的CRC
+ if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1])
+ {
+ //CRC Error 命令重发,超过3次,结束
+ if (cnt < 3)
+ {
+ cnt++;
+ goto CMD_RESEND;
+ printf("cnt over\n");
+ }
+ else
+ {
+ printf("ERROR\n");
+ }
+ }
+
+ //printf("rx %1d bytes: ", rxbuf[1]+4);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+
+ memcpy(result, rxbuf + 2, rxbuf[1]-1);
+ * len = rxbuf[1]-1;
+ return 0;
+}
+
+int NrsecPort::SM2ImportPublicKey(int index, const uint8_t new_key[])//外部公钥导入存放在01
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ SM2InPub_CMD[3] = index;
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2InPub_CMD, sizeof(SM2InPub_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, new_key, 64);
+
+ SendData(txbuf, rxbuf, 64);
+
+ SendEnd(txbuf, rxbuf);
+
+ RcvSW(txbuf, rxbuf + 1, 0x90);
+
+ std::string result = "InPub: success";
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s", result.c_str());
+#endif
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf);
+ // printf("\n");
+
+
+ return 0;
+}
+
+int NrsecPort::SM2ImportPrivateKey(int index, const uint8_t new_key[])//导入私钥 没测试
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ SM2InPri_CMD[3] = index;
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2InPri_CMD, sizeof(SM2InPri_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]); // 指令
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, new_key, 32);
+
+ SendData(txbuf, rxbuf, 32);
+
+ SendEnd(txbuf, rxbuf);
+
+ RcvSW(txbuf, rxbuf + 1, 0x90);
+
+ std::string result = "InPri: success";
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s", result.c_str());
+#endif
+
+
+ return 0;
+}
+
+int NrsecPort::SM3Hash(uint8_t *to_hash, int len, uint8_t *out_hash)//原始哈希 跑通了,没有验证
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[1536];
+ uint8_t rxbuf[1536];
+
+ int retval;
+ int msglen;
+
+ int ret=0;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+
+ SM3Hash_CMD[3] = len >> 8;
+ SM3Hash_CMD[4] = len & 0xFF;
+
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, "len", "len=%x", len);
+#endif
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM3Hash_CMD, sizeof(SM3Hash_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, to_hash, len);
+
+ SendData(txbuf, rxbuf, len);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM3Hash_CMD, sizeof(SM3Hash_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 1);
+
+ RcvData(txbuf, rxbuf + 2);
+
+ ret = RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+
+ if(ret ==1)
+ {
+ memcpy(out_hash, rxbuf + 2, rxbuf[1]-1);
+ }
+ return ret;
+}
+
+int NrsecPort::SM3Hash(uint8_t *in, int inl, uint8_t *out, uint8_t *pubkey, uint8_t* pucID, int idl)
+{
+ int nRet, l;
+ uint8_t *Z = NULL;
+ int entl = 0;
+ uint8_t tmpm[32];
+ uint8_t abxy[32 * 4] = {
+ 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFC,
+ 0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,/* b */
+ 0x9E,0x4B,0xCF,0x65,0x09,0xA7,0xF3,0x97,0x89,0xF5,
+ 0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94,
+ 0x0E,0x93,
+ 0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,/* x */
+ 0x04,0x46,0x6A,0x39,0xC9,0x94,0x8F,0xE3,0x0B,0xBF,
+ 0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C,
+ 0x74,0xC7,
+ 0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,/* y */
+ 0xCE,0xE3,0x6B,0x69,0x21,0x53,0xD0,0xA9,0x87,0x7C,
+ 0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39,
+ 0xF0,0xA0
+ };
+ l = 2 + idl + 32 * 6;
+ Z = (uint8_t *)malloc(l);
+ if (!Z)
+ return -1;
+ entl = idl * 8;
+ memset(Z + 1, entl & 0xFF, 1);
+ entl >>= 8;
+ memset(Z, entl & 0xFF, 1);
+ memcpy(Z + 2, pucID, idl);
+ memcpy(Z + 2 + idl, abxy, 32 * 4);
+ memcpy(Z + 2 + idl + 4 * 32, pubkey, 32);
+ memcpy(Z + 2 + idl + 5 * 32, pubkey + 32, 32);
+ nRet = SM3Hash(Z, l, tmpm);
+ if (nRet == 0)
+ goto quit;
+ free(Z);
+ l = inl + 32;
+ Z = (uint8_t *)malloc(l);
+ if (!Z) {
+ nRet = -1;
+ goto quit;
+ }
+ memcpy(Z, tmpm, 32);
+ memcpy(Z + 32, in, inl);
+ nRet = SM3Hash(Z, l, out);
+quit:
+ if (Z)
+ free(Z);
+ return nRet;
+}//用于签名的处理哈希值,用户标识01*16
+
+int NrsecPort::SM2Sign(int index, const uint8_t *to_sign, uint8_t *out_sign)//SM2签名 所使用的哈希值应该来源于sm3hash_tosm2
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+
+ int ret=0;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2Sign_CMD[3] = index;
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2Sign_CMD, sizeof(SM2Sign_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, to_sign, 32);
+
+ SendData(txbuf, rxbuf, 32);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM2Sign_CMD, sizeof(SM2Sign_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 1);
+
+ RcvData(txbuf, rxbuf + 2);
+
+ ret=RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+ if(ret == 1)
+ {
+ memcpy(out_sign, rxbuf + 2, rxbuf[1]-1);
+ }
+ return ret;
+}
+
+int NrsecPort::SM2VerifySign(int index, uint8_t *hash, uint8_t *vs)//SM2验签
+{
+ uint8_t txbuf[256];
+ uint8_t rxbuf[256];
+
+ int retval;
+ int msglen;
+ int ret=0;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2VerifySign_CMD[3] = index;
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2VerifySign_CMD, sizeof(SM2VerifySign_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, hash, 32);
+ memcpy(txbuf + 32, vs, 64);
+
+ SendData(txbuf, rxbuf, 96);
+
+ SendEnd(txbuf, rxbuf);
+
+ ret=RcvSW(txbuf, rxbuf, 0x90);
+#ifdef __ANDROID__
+ __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1] + 4);
+#endif
+
+ return ret;
+}
+
+int NrsecPort::SM2Encrypt(int index, uint8_t *to_encrypt, uint8_t *out_encrypt)//加密
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[512];
+ uint8_t rxbuf[512];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2encrypt_CMD[3] = index;
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2encrypt_CMD, sizeof(SM2encrypt_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, to_encrypt, 32);
+
+ SendData(txbuf, rxbuf, 32);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM2encrypt_CMD, sizeof(SM2encrypt_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 1);
+
+ RcvData(txbuf, rxbuf + 2);
+
+ RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ memcpy(out_encrypt, rxbuf + 2, rxbuf[1]-1);
+
+ return 0;
+}
+int NrsecPort::SM2Decrypt(int index, uint8_t *to_decoder, uint8_t *out_decoder)//解密
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[512];
+ uint8_t rxbuf[512];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+ SM2decoder_CMD[3] = index;
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, to_decoder, 128);
+
+ SendData(txbuf, rxbuf, 128);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 1);
+
+ RcvData(txbuf, rxbuf + 2);
+
+ RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ memcpy(out_decoder, rxbuf + 2, rxbuf[1]-1);
+
+ return 0;
+}
+
+int NrsecPort::SM2cert(int type, int index, string cert, uint8_t *out_cert, uint16_t *len)//证书
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[512];
+ uint8_t rxbuf[1024];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+
+ int certlen = cert.length();
+
+ SM2cert_CMD[2] = type;
+ SM2cert_CMD[3] = index;
+ SM2cert_CMD[4] = certlen;
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)SM2cert_CMD, sizeof(SM2cert_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, cert.c_str(), certlen);
+
+ SendData(txbuf, rxbuf, certlen);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM2cert_CMD, sizeof(SM2cert_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 2);
+
+ uint16_t outlen =(*(rxbuf+1)<<8)+(*(rxbuf+2));
+
+ RcvData(txbuf, rxbuf + 3, outlen);
+
+ RcvSW(txbuf, rxbuf + 3 + outlen, 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+
+ memcpy(out_cert, rxbuf + 3, outlen-1);
+
+ *len =outlen -1;
+
+ return 0;
+}
+int NrsecPort::Indentify(uint8_t *to_idt, uint8_t *out_idt)//安全认证
+{
+ int i;
+ int cnt;
+ uint8_t txbuf[512];
+ uint8_t rxbuf[512];
+
+ int retval;
+ int msglen;
+
+ msglen = 5;
+ memset(rxbuf, 0, sizeof(rxbuf));
+ memset(txbuf, 0, sizeof(txbuf));
+
+ //printf("tx %1d bytes: ", msglen);
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen);
+
+CMD_RESEND:
+
+ memcpy(txbuf, (const void *)Indentify_CMD, sizeof(Indentify_CMD));
+
+ SendCMD(txbuf, rxbuf);
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ SendId(txbuf, rxbuf, 0x55);
+
+ memcpy(txbuf, to_idt, 32);
+
+ SendData(txbuf, rxbuf, 32);
+
+ SendEnd(txbuf, rxbuf);
+
+ memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD));
+
+ RcvINS(txbuf, rxbuf, txbuf[1]);
+
+ RcvLEN(txbuf, rxbuf + 1, 1);
+
+ RcvData(txbuf, rxbuf + 2);
+
+ RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90);
+
+ //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4);
+ memcpy(out_idt, rxbuf + 2, rxbuf[1]-1);
+
+ return 0;
+}
diff --git a/app/src/main/cpp/NrsecPort.h b/app/src/main/cpp/NrsecPort.h
new file mode 100644
index 0000000..71a5828
--- /dev/null
+++ b/app/src/main/cpp/NrsecPort.h
@@ -0,0 +1,58 @@
+#ifndef __NRSECPORT_H__
+#define __NRSECPORT_H__
+
+#include "SpiPort.h"
+#include
+
+
+#define CMD_HEAD_SIZE 5
+using namespace std;
+typedef uint8_t uint8_t;
+
+class NrsecPort : public SpiPort {
+public:
+
+ int SM1ImportKey(const uint8_t* ek, const uint8_t* ak);
+ int ImportIV(const uint8_t* iv, uint8_t ivLength);
+
+ int SM1Encrypt(const uint8_t* data, uint16_t dataLen, uint8_t* encryptedData, uint16_t *bufferLen);
+ int SM1Decrypt(const uint8_t* encryptedData, uint16_t encryptedDataLen, uint8_t* data, uint16_t* bufferLen);
+
+ int Random(uint8_t* output, uint8_t length);
+ std::string Version();
+ int Indentify(uint8_t *to_idt, uint8_t *out_idt);
+ int SM2keypair(int index);
+ int SM2ExportPublicKey(int index, uint8_t result[] ,uint8_t * len);
+ int SM2ExportPrivateKey(int index, uint8_t result[] ,uint8_t * len);
+ int SM2ImportPublicKey(int index, const uint8_t new_key[]);
+ int SM2ImportPrivateKey(int index, const uint8_t new_key[]);
+ int SM3Hash(uint8_t *to_hash, int len, uint8_t *out_hash);
+ int SM3Hash(uint8_t *in, int inl, uint8_t *out, uint8_t *pubkey, uint8_t *pucID, int idl);
+ int SM2Sign(int index, const uint8_t *to_sign, uint8_t *out_sign);
+ int SM2VerifySign(int index, uint8_t *hash, uint8_t * vs);
+ int SM2Encrypt(int index, uint8_t *to_encrypt, uint8_t * out_encrypt);
+ int SM2Decrypt(int index, uint8_t *to_decoder, uint8_t *out_decoder);
+ int SM2cert(int type, int index, string cert, uint8_t *out_cert, uint16_t *len);
+
+protected:
+
+ uint8_t CalcCRC7(const uint8_t *buff, int len);
+ void SendCMD(uint8_t *cmd, uint8_t *rxbuf);
+ void RcvINS(uint8_t *txbuf, uint8_t *buf, uint8_t ins);
+ void RcvLEN(uint8_t *txbuf, uint8_t *buf, uint8_t len);
+ void RcvData(uint8_t *txbuf, uint8_t *buf);
+ void RcvData(uint8_t *txbuf, uint8_t *buf, int len);
+ bool RcvSW(uint8_t *txbuf, uint8_t *buf, uint8_t sw);
+ void SendEnd(uint8_t *txbuf, uint8_t *buf);
+ void SendId(uint8_t *txbuf, uint8_t *buf, uint8_t id);
+ void SendData(uint8_t *data, uint8_t *rxbuf, int data_size);
+
+protected:
+ std::mutex m_mutex;
+
+};
+
+
+
+
+#endif // __NRSECPORT_H__
diff --git a/app/src/main/cpp/SpiPort.cpp b/app/src/main/cpp/SpiPort.cpp
new file mode 100644
index 0000000..5cb529e
--- /dev/null
+++ b/app/src/main/cpp/SpiPort.cpp
@@ -0,0 +1,207 @@
+#include "SpiPort.h"
+#ifdef _WIN32
+#include
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#ifdef __ANDROID__
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#endif
+
+//typedef unsigned char u8;
+
+#define RE_SUC 0x01
+#define RE_ERROR 0x00
+
+#define TAG_SPI "SPI"
+
+SpiPort::SpiPort()
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+ : m_fd(INVALID_HANDLE_VALUE)
+#endif
+#else
+ : m_fd(0)
+#endif
+{
+}
+
+SpiPort::~SpiPort()
+{
+ Close();
+}
+
+bool SpiPort::Open(const char *path)
+{
+ m_path = path;
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+ CW2T utf8Path(CA2W(path, CP_UTF8));
+ // m_fd = _open(path, O_RDWR);
+ m_fd = CreateFile(utf8Path, //port name
+ GENERIC_READ | GENERIC_WRITE, //Read/Write
+ 0, // No Sharing
+ NULL, // No Security
+ OPEN_EXISTING,// Open existing port only
+ 0, // Non Overlapped I/O
+ NULL); // Null for Comm Devices
+ if (m_fd == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+#endif
+ return false;
+#else
+ m_fd = open(path, O_RDWR);
+
+ if (m_fd < 0) {
+ perror("open");
+ return false;
+ }
+#endif
+ spi_master_init();
+
+ return true;
+}
+
+void SpiPort::Close()
+{
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+ if (m_fd != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(m_fd);
+ m_fd = INVALID_HANDLE_VALUE;
+ }
+#endif
+#else
+ if (m_fd > 0)
+ {
+ close(m_fd);
+ m_fd = 0;
+ }
+#endif
+}
+
+bool SpiPort::IsOpened() const
+{
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+ return m_fd != INVALID_HANDLE_VALUE;
+#else
+ return false;
+#endif
+#else
+ return m_fd > 0;
+#endif
+}
+
+int SpiPort::spi_transfer(uint8_t *txbuf, uint8_t *rxbuf, int bytes)
+{
+ int status = 0;
+
+#ifdef _WIN32
+
+ // BOOL res = DeviceIoControl();
+ // status = res ? 0 : -1;
+#else
+
+#if 0
+ struct spi_ioc_transfer xfer[2];
+ memset(xfer, 0, sizeof(xfer));
+ xfer[0].tx_buf = (__u64)txbuf;
+ xfer[0].rx_buf = (__u64)rxbuf;
+ xfer[0].len = bytes;
+ xfer[0].delay_usecs = 2;
+
+ status = ioctl(m_fd, SPI_IOC_MESSAGE(1), xfer);
+#else
+ struct spi_ioc_transfer xfer;
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.tx_buf = (__u64)txbuf;
+ xfer.rx_buf = (__u64)rxbuf;
+ xfer.len = bytes;
+ xfer.delay_usecs = 2;
+
+ status = ioctl(m_fd, SPI_IOC_MESSAGE(1), &xfer);
+#endif
+ if (status < 0)
+ {
+ perror("SPI_IOC_MESSAGE");
+ return -1;
+ }
+#endif
+
+ return status;
+}
+
+void SpiPort::spi_master_init()
+{
+ uint8_t mode = 3;
+ uint8_t lsb = 0;
+ uint8_t bits = 8;
+ //uint32_t speed = 30000000;
+ uint32_t speed = 2000000;
+ //uint32_t speed = 2000000;
+ //uint32_t speed = 33000000;
+
+ // SPI_IOC_WR_MODE
+ int res = 0;
+
+#ifdef __ANDROID__
+ res = ioctl(m_fd, SPI_IOC_WR_MODE, &mode);
+ res = ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+ res = ioctl(m_fd, SPI_IOC_WR_LSB_FIRST, &lsb);
+
+ if (ioctl(m_fd, SPI_IOC_RD_MODE, &mode) < 0)
+ {
+ perror("SPI rd_mode");
+ return;
+ }
+
+ if (ioctl(m_fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
+ {
+ perror("SPI rd_lsb_fist");
+ return;
+ }
+
+ if (ioctl(m_fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
+ {
+ perror("SPI rd bits_per_word");
+ return;
+ }
+
+ if (ioctl(m_fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
+ {
+ perror("SPI rd max_speed_hz");
+ return;
+ }
+
+ __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s: spi mode %d, %d bits %sper word, %d Hz max\n", m_path.c_str(), mode, bits, lsb ? "(lsb first) " : "", speed);
+#endif
+
+ //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+ // name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+int SpiPort::delay(int x)
+{
+#ifdef _WIN32
+ std::this_thread::sleep_for(std::chrono::milliseconds(x));
+#else
+ usleep(x);
+#endif
+ return 0;
+}
diff --git a/app/src/main/cpp/SpiPort.h b/app/src/main/cpp/SpiPort.h
new file mode 100644
index 0000000..a04f6d5
--- /dev/null
+++ b/app/src/main/cpp/SpiPort.h
@@ -0,0 +1,44 @@
+#ifndef TESTCOMM_SPIPORT_H
+#define TESTCOMM_SPIPORT_H
+
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+#include
+#include
+#endif
+#else
+#include
+#endif
+#include
+using namespace std;
+
+class SpiPort {
+public:
+
+ SpiPort();
+ virtual ~SpiPort();
+
+ bool Open(const char* path);
+ void Close();
+ bool IsOpened() const;
+
+ int spi_transfer(uint8_t *txbuf, uint8_t *rxbuf, int bytes);
+ void spi_master_init();
+ static int delay(int x);
+
+protected:
+ std::string m_path;
+
+#ifdef _WIN32
+#ifdef TERMINAL_SERVER
+ HANDLE m_fd;
+#endif
+#else
+ int m_fd;
+#endif
+};
+
+
+
+
+#endif //TESTCOMM_SPIPORT_H
diff --git a/app/src/main/cpp/chip.cpp b/app/src/main/cpp/chip.cpp
new file mode 100644
index 0000000..ee7f9f8
--- /dev/null
+++ b/app/src/main/cpp/chip.cpp
@@ -0,0 +1,153 @@
+#include "chip.h"
+#include "NrsecPort.h"
+#include "GPIOControl.h"
+
+/* 生成动态库名称为libchip.so*/
+
+#define SPI_NODE "/dev/spidev0.0"
+NrsecPort m_nrsec;
+bool nrsec_flag= false;
+/*
+ * 打开设备,初始化资源...
+ * 成功返回1,错误返回0
+ */
+
+int chip_init()
+{
+ GpioControl::setCam3V3Enable(true);
+ GpioControl::setSpiPower(true);
+ if(nrsec_flag==false)
+ {
+ bool ret = m_nrsec.Open(SPI_NODE);
+ if (ret == 1)
+ {
+ nrsec_flag = true;
+ }
+ return ret;
+
+ }
+ else{
+ return 0;
+ }
+}
+
+/*
+ * 关闭设备,释放资源...
+ */
+void chip_finish()
+{
+ m_nrsec.Close();
+ GpioControl::setSpiPower(false);
+ GpioControl::setCam3V3Enable(false);
+ nrsec_flag=false;
+}
+
+/*
+ * 调用芯片完成sm2签名运算,输入32字节,已HASH,输出64字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm2_sign(unsigned char *from, unsigned int flen,
+ unsigned char *to, unsigned int *tlen)
+{
+ int ret = m_nrsec.SM2Sign(0,from,to);
+ if(ret ==1)
+ {
+ *tlen =64;
+ }
+ else{
+ *tlen =0;
+ }
+ return ret;
+}
+
+/*
+ * 调用芯片完成sm2验签运算,输入from 32字节,已HASH,输入sig 64字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm2_verify(unsigned char *from, unsigned int flen,
+ unsigned char *sig, unsigned int siglen)
+{
+ int ret =m_nrsec.SM2VerifySign(0,from,sig);
+
+ return ret;
+}
+
+/*
+ * 调用芯片完成sm3运算,输入d,输入长度n,输出md,32字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm3(const unsigned char *d, unsigned int n, unsigned char *md)
+{
+ uint8_t * cert = NULL;
+ uint8_t len = 0;
+ cert = (uint8_t *) malloc(64);
+ memset(cert,0,64);
+ int ret = m_nrsec.SM2ExportPublicKey(0,cert,&len);
+ if( ret == 0)
+ {
+ free(cert);
+ return ret;
+ }
+ uint8_t * pucID = NULL;
+ pucID = (uint8_t *) malloc(16);
+ memset(pucID,0,16);
+ memset(pucID,1,16);
+
+ ret = m_nrsec.SM3Hash((uint8_t*)d,len,md,cert,pucID,16);
+
+ free(pucID);
+ free(cert);
+ return ret;
+}
+
+/*
+ * 调用芯片生成随机数,输入n,表示需要生成的随机数的长度,输出random
+ * 成功返回1,错误返回0
+ */
+int chip_rand(unsigned int n, unsigned char *random)
+{
+ int ret =m_nrsec.Random(random,n);
+
+ return ret;
+}
+
+/*
+ * 调用芯片完成sm1运算,加解密模式CBC
+ * 输入key 16字节,输入iv 16字节,
+ * 输入enc,1表示加密,0表示解密
+ * 输入in,16倍数,输入长度inlen,输出out
+ * 成功返回1,错误返回0
+ */
+int chip_sm1(unsigned char *key, unsigned char *iv, int enc,
+ unsigned char *in, unsigned int inlen, unsigned char *out)
+{
+ unsigned char ak[16]={0};
+ int ret =m_nrsec.SM1ImportKey(key,ak);
+ if(ret == 0)
+ {
+ return ret;
+ }
+ ret =m_nrsec.ImportIV(iv,16);
+ if(ret == 0)
+ {
+ return ret;
+ }
+ uint16_t outlen;
+ if(enc==1)
+ {
+ ret = m_nrsec.SM1Encrypt(in,inlen,out, &outlen);
+ if(ret == 0)
+ {
+ return ret;
+ }
+
+ }
+ else{
+ ret = m_nrsec.SM1Decrypt(in,inlen,out, &outlen);
+ if(ret == 0)
+ {
+ return ret;
+ }
+ }
+ return ret;
+}
\ No newline at end of file
diff --git a/app/src/main/cpp/chip.h b/app/src/main/cpp/chip.h
new file mode 100644
index 0000000..e4d2224
--- /dev/null
+++ b/app/src/main/cpp/chip.h
@@ -0,0 +1,64 @@
+#ifndef __CHIP_H__
+#define __CHIP_H__
+
+/* 生成动态库名称为libchip.so*/
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+/*
+ * 打开设备,初始化资源...
+ * 成功返回1,错误返回0
+ */
+int chip_init();
+
+/*
+ * 关闭设备,释放资源...
+ */
+void chip_finish();
+
+/*
+ * 调用芯片完成sm2签名运算,输入32字节,已HASH,输出64字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm2_sign(unsigned char *from, unsigned int flen,
+ unsigned char *to, unsigned int *tlen);
+
+/*
+ * 调用芯片完成sm2验签运算,输入from 32字节,已HASH,输入sig 64字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm2_verify(unsigned char *from, unsigned int flen,
+ unsigned char *sig, unsigned int siglen);
+
+/*
+ * 调用芯片完成sm3运算,输入d,输入长度n,输出md,32字节
+ * 成功返回1,错误返回0
+ */
+int chip_sm3(const unsigned char *d, unsigned int n, unsigned char *md);
+
+/*
+ * 调用芯片生成随机数,输入n,表示需要生成的随机数的长度,输出random
+ * 成功返回1,错误返回0
+ */
+int chip_rand(unsigned int n, unsigned char *random);
+
+/*
+ * 调用芯片完成sm1运算,加解密模式CBC
+ * 输入key 16字节,输入iv 16字节,
+ * 输入enc,1表示加密,0表示解密
+ * 输入in,16倍数,输入长度inlen,输出out
+ * 成功返回1,错误返回0
+ */
+int chip_sm1(unsigned char *key, unsigned char *iv, int enc,
+ unsigned char *in, unsigned int inlen, unsigned char *out);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+
+#endif /* __DS_NRSEC_STRUCT_H__ */
diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp
new file mode 100644
index 0000000..e690488
--- /dev/null
+++ b/app/src/main/cpp/native-lib.cpp
@@ -0,0 +1,73 @@
+#include
+#include
+#include "chip.h"
+#include
+#include
+#include
+
+#define TAG_Test "TESTCHIP"
+
+using namespace std;
+
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_example_test3_MainActivity_stringFromJNI(
+ JNIEnv* env,
+ jobject /* this */) {
+
+ int ret = chip_init();
+ __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_init status %d", ret);
+
+ sleep(1);
+
+ vector data(32,1);
+ vector hash(32,1);
+ vector sign(64,0);
+ //uint8_t pbdata[64]={0x64,0x3c,0xd1,0x20,0x7f,0x42,0xcd,0xc7,0xac,0xa1,0xe8,0x12,0x92,0x24,0x58,0x76,0x2f,0x40,0xc5,0x1f,0xd8,0x18,0x78,0x69,0x2b,0xca,0x4c,0x8a,0x8e,0x75,0xcb,0xda,0xda,0x22,0x2f,0xb9,0x7d,0xb8,0x67,0x16,0x0d,0x81,0x39,0x8d,0xf1,0x09,0x4f,0xcf,0x51,0xf9,0xdc,0x71,0x20,0x40,0xe5,0x4d,0x52,0xb5,0xc5,0x74,0x85,0xe6,0xbb,0x65};
+ vector pucid(16,1);
+
+ unsigned int len=1;
+
+ ret = chip_sm3(&data[0],32,&hash[0]);
+ __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm3_all status %d ", ret);
+ sleep(1);
+
+
+ ret = chip_sm2_sign(&hash[0],32,&sign[0],&len);
+ __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm2_sign status %d,len=%d", ret,len);
+ for(int i=0;i data(16,0);
+ //ret = chip_rand(16,&data[0]);
+ //__android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_rand %d", ret);
+
+ vector DK(16,1);
+ vector IV(16,1);
+ data.clear();
+ data.resize(16,2);
+ vector edata(16,0);
+ ret = chip_sm1(&DK[0],&IV[0],1,&data[0],16,&edata[0]);
+
+ sleep(1);
+ vector edata2(16,0);
+ ret = chip_sm1(&DK[0],&IV[0],0,&edata[0],16,&edata2[0]);
+
+ for(int i=0;i<16;i++)
+ {
+ __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm1 %d value %d ", i, edata2[i]);
+ }
+
+
+
+ chip_finish();
+
+ std::string hello = "Hello from C++";
+ return env->NewStringUTF(hello.c_str());
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/test6/MainActivity.java b/app/src/main/java/com/example/test6/MainActivity.java
new file mode 100644
index 0000000..cb261b4
--- /dev/null
+++ b/app/src/main/java/com/example/test6/MainActivity.java
@@ -0,0 +1,36 @@
+package com.example.test6;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.widget.TextView;
+
+import com.example.test6.databinding.ActivityMainBinding;
+
+public class MainActivity extends AppCompatActivity {
+
+ // Used to load the 'test6' library on application startup.
+ static {
+ System.loadLibrary("test6");
+ }
+
+ private ActivityMainBinding binding;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ binding = ActivityMainBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ // Example of a call to a native method
+ TextView tv = binding.sampleText;
+ tv.setText(stringFromJNI());
+ }
+
+ /**
+ * A native method that is implemented by the 'test6' native library,
+ * which is packaged with this application.
+ */
+ public native String stringFromJNI();
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..0fdf985
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..68a771f
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..5ae26d2
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ test6
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..a95bd39
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/example/test6/ExampleUnitTest.java b/app/src/test/java/com/example/test6/ExampleUnitTest.java
new file mode 100644
index 0000000..f798211
--- /dev/null
+++ b/app/src/test/java/com/example/test6/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.test6;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..41532d1
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.0.0' apply false
+ id 'com.android.library' version '8.0.0' apply false
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..3e927b1
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..02a7256
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Aug 01 15:31:22 CST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.0-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# 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
+#
+# https://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.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..4b75153
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,18 @@
+pluginManagement {
+ repositories {
+ maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
+ maven { url 'https://maven.aliyun.com/repository/google' }
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "test6"
+include ':app'