#include <jni.h>
|
#include <string>
|
#include <pthread.h>
|
#include <unistd.h>
|
#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);
|
}
|