#include #include #include #include #include "common/serial_port.h" #include "jni_log.h" #include "common/net.h" #include "common/apptimer.h" #include "rtk_platform/parse_net.h" #include "native-lib.h" #include "Geometry.h" #include "rtk_platform/platform.h" #include "rtk_module/rtk.h" #include "mcu/mcu_if.h" #include "driver_test.h" static JavaVM *sg_jvm = NULL; static jobject sg_obj = NULL; const char *RTK_PLATFORM_IP = "47.93.80.84"; const int RTK_PLATFORM_PORT = 12125; const uint8_t phone[] = {0x20,0x19,0x10,0x15,0x00,0x00,0x00,0x02}; #define IMEI_LENGTH 15 char * GetImei(void) { JNIEnv *env; static char imei[IMEI_LENGTH + 1] = {0}; LOGD("JNI_GetImei"); if (strlen(imei) == 0) { bool ready_in_java_env = false; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return imei; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "javaGetImei", "()Ljava/lang/String;"); jstring ret = (jstring) env->CallObjectMethod(sg_obj, fun); if (ret != NULL) { const char *pret = env->GetStringUTFChars(ret, JNI_FALSE); strcpy(imei, pret); } env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); return imei; } } } return imei; } int DESEncrypt(const uint8_t *key, int key_length, const uint8_t *plaintext, int plaintext_length, uint8_t **ciphertext) { JNIEnv *env; bool ready_in_java_env = false; int ciphertext_length = 0; *ciphertext = NULL; LOGD("JNI_DESEncrypt"); if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return 0; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "javaDESEncrypt", "([B[B)[B"); jbyteArray jni_key = env->NewByteArray(key_length); jbyteArray jni_plaintext = env->NewByteArray(plaintext_length); env->SetByteArrayRegion(jni_key, 0, key_length, (jbyte *) key); env->SetByteArrayRegion(jni_plaintext, 0, plaintext_length, (jbyte *) plaintext); jbyteArray jni_ciphertext = (jbyteArray) env->CallObjectMethod(sg_obj, fun, jni_plaintext, jni_key); if (jni_ciphertext != NULL) { ciphertext_length = env->GetArrayLength(jni_ciphertext); uint8_t *buffer = (uint8_t *)malloc(ciphertext_length); env->GetByteArrayRegion(jni_ciphertext, 0, ciphertext_length, (jbyte *) buffer); *ciphertext = buffer; } env->DeleteLocalRef(jni_key); env->DeleteLocalRef(jni_plaintext); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } return ciphertext_length; } void SetPlatformKey(const uint8_t *key, int length) { JNIEnv *env; bool ready_in_java_env = false; LOGD("JNI_SetPlatformKey"); if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jbyteArray jni_cmd = env->NewByteArray(length); env->SetByteArrayRegion(jni_cmd, 0, length, (jbyte *) key); jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "SetPlatformKey", "([B)V"); env->CallVoidMethod(sg_obj, fun, jni_cmd); env->DeleteLocalRef(jni_cmd); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } void DelPlatformKey(void) { JNIEnv *env; bool ready_in_java_env = false; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "DeletePlatformKey", "()V"); env->CallVoidMethod(sg_obj, fun); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } int GetPlatformKey(uint8_t *pkey) { JNIEnv *env; bool ready_in_java_env = false; uint8_t key[64] = {0}; int key_len = 0; LOGD("JNI_GetPlatformKey"); if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return 0; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "GetPlatformKey", "()[B"); jbyteArray jni_cmd = (jbyteArray) env->CallObjectMethod(sg_obj, fun); if (jni_cmd != NULL) { key_len = env->GetArrayLength(jni_cmd); if (key_len <= sizeof(key)) { env->GetByteArrayRegion(jni_cmd, 0, key_len, (jbyte *) key); memcpy(pkey, key, key_len); } else { key_len = 0; } } env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } return key_len; } void SetSharedValue(const char *key, int value) { JNIEnv *env; bool ready_in_java_env = false; LOGD("JNI_SetSharedValue"); if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "SetSharedValue", "(Ljava/lang/String;I)V"); env->CallVoidMethod(sg_obj, fun, env->NewStringUTF(key), value); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } int GetSharedValue(const char *key) { JNIEnv *env; bool ready_in_java_env = false; int value = 0; LOGD("JNI_GetSharedValue"); if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return value; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "GetSharedValue", "(Ljava/lang/String;)I"); value = env->CallIntMethod(sg_obj, fun, env->NewStringUTF(key)); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } return value; } void TextSpeak(const char *text) { JNIEnv *env; bool ready_in_java_env = false; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "TextSpeak", "(Ljava/lang/String;)V"); std::string cstext = text; env->CallVoidMethod(sg_obj, fun, env->NewStringUTF(cstext.c_str())); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } void TextOsd(int type, const char *text) { JNIEnv *env; bool ready_in_java_env = false; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "TextOsd", "(ILjava/lang/String;)V"); std::string cstext = text; env->CallVoidMethod(sg_obj, fun, type, env->NewStringUTF(cstext.c_str())); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } void DrawScreen(const Polygon *map, const Polygon *car) { JNIEnv *env; bool ready_in_java_env = false; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "DrawMap", "([[D[[D)V"); jclass doubleArrCls = env->FindClass("[D"); jobjectArray retmap = env->NewObjectArray(map->num, doubleArrCls, NULL); jobjectArray retcar = env->NewObjectArray(car->num, doubleArrCls, NULL); for (int i = 0; i < map->num; ++i) { jdoubleArray doubleArr = env->NewDoubleArray(2); jdouble tmp[2] = {map->point[i].X, 0 - map->point[i].Y}; env->SetDoubleArrayRegion(doubleArr, 0, 2, tmp); env->SetObjectArrayElement(retmap, i, doubleArr); env->DeleteLocalRef(doubleArr); } for (int i = 0; i < car->num; ++i) { jdoubleArray doubleArr = env->NewDoubleArray(2); jdouble tmp[2] = {car->point[i].X, 0 - car->point[i].Y}; env->SetDoubleArrayRegion(doubleArr, 0, 2, tmp); env->SetObjectArrayElement(retcar, i, doubleArr); env->DeleteLocalRef(doubleArr); } env->CallVoidMethod(sg_obj, fun, retmap, retcar); env->DeleteLocalRef(retmap); env->DeleteLocalRef(retcar); env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } void DisplayText(const char *string) { DEBUG("DisplayText: %s", string); } void CCL(int who) { JNIEnv *env; bool ready_in_java_env = false; static int c[2] = {0}; if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { // Attach主线程 if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return; } } else { ready_in_java_env = true; } jclass cls = env->GetObjectClass(sg_obj); jmethodID fun = env->GetMethodID(cls, "CCL", "(II)V"); env->CallVoidMethod(sg_obj, fun, c[who], who); c[who] = !c[who]; env->DeleteLocalRef(cls); if (!ready_in_java_env) { //Detach主线程 if (sg_jvm->DetachCurrentThread() != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } } } extern "C" JNIEXPORT void JNICALL Java_com_anyun_exam_lib_RemoteService_startNative(JNIEnv *env, jobject thiz) { // TODO: implement startNative() // 保存全局JVM以便在子线程中使用 env->GetJavaVM(&sg_jvm); // 不能直接赋值(g_obj = ojb) sg_obj = env->NewGlobalRef(thiz); AppTimer_Init(); ConfigMCU(); DriverTestInit(); ConfigRTKModule(); InitPlatform(phone, RTK_PLATFORM_IP, RTK_PLATFORM_PORT); }