382 lines
14 KiB
C
382 lines
14 KiB
C
/**
|
|
* copyright (2017) Baidu Inc. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#define TAG "lightduer_jni_utils"
|
|
|
|
#include "lightduer_jni.h"
|
|
#include "lightduer_jni_utils.h"
|
|
#include "lightduer_jni_log.h"
|
|
#include "lightduer_lib.h"
|
|
#include "lightduer_memory.h"
|
|
|
|
static jclass s_lightduerContextClass = NULL;
|
|
static jclass s_lightduerMessageClass = NULL;
|
|
static jclass s_lightduerAddressClass = NULL;
|
|
|
|
int duer_jni_utils_init(JNIEnv *jenv)
|
|
{
|
|
int result = DUER_ERR_FAILED;
|
|
|
|
if (s_lightduerAddressClass == NULL) {
|
|
jclass lightduerAddressClass = (*jenv)->FindClass(jenv, PACKAGE"/utils/LightduerAddress");
|
|
if (lightduerAddressClass == NULL) {
|
|
LOGE("lightduerAddressClass find fail!");
|
|
return result;
|
|
}
|
|
s_lightduerAddressClass = (jclass)(*jenv)->NewGlobalRef(jenv, lightduerAddressClass);
|
|
(*jenv)->DeleteLocalRef(jenv, lightduerAddressClass);
|
|
}
|
|
|
|
if (s_lightduerContextClass == NULL) {
|
|
jclass lightduerContextClass = (*jenv)->FindClass(jenv, PACKAGE"/utils/LightduerContext");
|
|
if (lightduerContextClass == NULL) {
|
|
LOGE("lightduerContextClass find fail!");
|
|
return result;
|
|
}
|
|
s_lightduerContextClass = (jclass)(*jenv)->NewGlobalRef(jenv, lightduerContextClass);
|
|
(*jenv)->DeleteLocalRef(jenv, lightduerContextClass);
|
|
}
|
|
|
|
if (s_lightduerMessageClass == NULL) {
|
|
jclass lightduerMessageClass = (*jenv)->FindClass(jenv, PACKAGE"/utils/LightduerMessage");
|
|
if (lightduerMessageClass == NULL) {
|
|
LOGE("lightduerMessageClass find fail!");
|
|
return result;
|
|
}
|
|
s_lightduerMessageClass = (jclass)(*jenv)->NewGlobalRef(jenv, lightduerMessageClass);
|
|
(*jenv)->DeleteLocalRef(jenv, lightduerMessageClass);
|
|
}
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
jobject duer_jni_get_object_LightduerContext(JNIEnv *jenv, duer_context ctx)
|
|
{
|
|
jobject context = NULL;
|
|
jmethodID constructorContext = NULL;
|
|
|
|
do {
|
|
if (s_lightduerContextClass == NULL) {
|
|
LOGE("s_lightduerContextClass is NULL!");
|
|
break;
|
|
}
|
|
|
|
constructorContext =
|
|
(*jenv)->GetMethodID(jenv, s_lightduerContextClass, "<init>", "(J)V");
|
|
if (constructorContext == NULL) {
|
|
LOGE("get constructorContext failed");
|
|
break;
|
|
}
|
|
|
|
context = (*jenv)->NewObject(jenv, s_lightduerContextClass, constructorContext, (jlong) ctx);
|
|
} while (0);
|
|
|
|
return context;
|
|
}
|
|
|
|
jobject duer_jni_get_object_LightduerMessage(JNIEnv *jenv, duer_msg_t *msg)
|
|
{
|
|
char *c_path = NULL;
|
|
char *c_query = NULL;
|
|
jobject message = NULL;
|
|
jmethodID constructorMessage = NULL;
|
|
jbyteArray token_array = NULL;
|
|
jstring path = NULL;
|
|
jstring query = NULL;
|
|
jbyteArray payload_array = NULL;
|
|
|
|
do {
|
|
if (s_lightduerMessageClass == NULL) {
|
|
LOGE("s_lightduerMessageClass is NULL!");
|
|
break;
|
|
}
|
|
|
|
constructorMessage =
|
|
(*jenv)->GetMethodID(
|
|
jenv,
|
|
s_lightduerMessageClass,
|
|
"<init>",
|
|
"(SSIIIII[BLjava/lang/String;Ljava/lang/String;[B)V");
|
|
if (constructorMessage == NULL) {
|
|
LOGE("get constructorMessage failed");
|
|
break;
|
|
}
|
|
|
|
jbyte *token_byte = (jbyte *)msg->token;
|
|
token_array = (*jenv)->NewByteArray(jenv, msg->token_len);
|
|
(*jenv)->SetByteArrayRegion(jenv, token_array, 0, msg->token_len, token_byte);
|
|
LOGD("token_len:%d \n", msg->token_len);
|
|
//for (int i =0; i < msg->token_len; ++i) {
|
|
// LOGD("token[%d]: 0x%x \n", i, msg->token[i]);
|
|
//}
|
|
|
|
c_path = (char *)DUER_MALLOC(msg->path_len + 1);
|
|
if (c_path == NULL) {
|
|
LOGE("alloc c_path fail!");
|
|
break;
|
|
}
|
|
LOGD("path_len:%d \n", msg->path_len);
|
|
DUER_MEMCPY(c_path, msg->path, msg->path_len);
|
|
c_path[msg->path_len] = 0;
|
|
LOGD("c_path:%s \n", c_path);
|
|
path = (*jenv)->NewStringUTF(jenv, c_path);
|
|
|
|
c_query = (char *)DUER_MALLOC(msg->query_len + 1);
|
|
if (c_query == NULL) {
|
|
LOGE("alloc c_query fail!");
|
|
break;
|
|
}
|
|
LOGD("query_len:%d\n", msg->query_len);
|
|
DUER_MEMCPY(c_query, msg->query, msg->query_len);
|
|
c_query[msg->query_len] = 0;
|
|
LOGD("query:%s\n", c_query);
|
|
query = (*jenv)->NewStringUTF(jenv, c_query);
|
|
|
|
jbyte *payload_byte = (jbyte *)msg->payload;
|
|
payload_array = (*jenv)->NewByteArray(jenv, msg->payload_len);
|
|
(*jenv)->SetByteArrayRegion(jenv, payload_array, 0, msg->payload_len, payload_byte);
|
|
|
|
LOGI("msg_type:%d, msg_code:%d, msg_id:%d \n", msg->msg_type, msg->msg_code, msg->msg_id);
|
|
message = (*jenv)->NewObject(jenv, s_lightduerMessageClass, constructorMessage,
|
|
msg->msg_type, msg->msg_code, msg->msg_id,
|
|
msg->token_len, msg->path_len, msg->query_len, msg->payload_len,
|
|
token_array, path, query, payload_array);
|
|
|
|
|
|
} while (0);
|
|
|
|
if (payload_array) {
|
|
(*jenv)->DeleteLocalRef(jenv, payload_array);
|
|
payload_array = NULL;
|
|
}
|
|
if (query) {
|
|
(*jenv)->DeleteLocalRef(jenv, query);
|
|
query = NULL;
|
|
}
|
|
if (path) {
|
|
(*jenv)->DeleteLocalRef(jenv, path);
|
|
path = NULL;
|
|
}
|
|
if (token_array) {
|
|
(*jenv)->DeleteLocalRef(jenv, token_array);
|
|
token_array = NULL;
|
|
}
|
|
|
|
if (c_path) {
|
|
DUER_FREE(c_path);
|
|
c_path = NULL;
|
|
}
|
|
if (c_query) {
|
|
DUER_FREE(c_query);
|
|
c_query = NULL;
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
jobject duer_jni_get_object_LightduerAddress(JNIEnv *jenv, duer_addr_t *addr)
|
|
{
|
|
char *c_host = NULL;
|
|
jobject address = NULL;
|
|
|
|
do {
|
|
if (s_lightduerAddressClass == NULL) {
|
|
LOGE("s_lightduerAddressClass is NULL!");
|
|
break;
|
|
}
|
|
|
|
jmethodID constructorAddress =
|
|
(*jenv)->GetMethodID(jenv, s_lightduerAddressClass, "<init>", "(SILjava/lang/String;)V");
|
|
if (constructorAddress == NULL) {
|
|
LOGE("get constructorAddress failed");
|
|
break;
|
|
}
|
|
|
|
c_host = (char *)DUER_MALLOC(addr->host_size + 1);
|
|
if (c_host == NULL) {
|
|
LOGE("alloc host fail!");
|
|
break;
|
|
}
|
|
//LOGD("host size: %lu \n", addr->host_size);
|
|
DUER_MEMCPY(c_host, addr->host, addr->host_size);
|
|
c_host[addr->host_size] = 0;
|
|
LOGD("host: %s \n", c_host);
|
|
jstring host = (*jenv)->NewStringUTF(jenv, c_host);
|
|
address = (*jenv)->NewObject(jenv, s_lightduerAddressClass, constructorAddress,
|
|
addr->type, addr->port, host);
|
|
} while (0);
|
|
|
|
if (c_host) {
|
|
DUER_FREE(c_host);
|
|
c_host = NULL;
|
|
}
|
|
|
|
return address;
|
|
}
|
|
|
|
int duer_jni_get_native_duer_message(JNIEnv *jenv, jobject message, duer_msg_t *msg)
|
|
{
|
|
int result = DUER_ERR_FAILED;
|
|
char *newPath = NULL;
|
|
char *newQuery = NULL;
|
|
jbyte *newToken = NULL;
|
|
jbyte *newPayload = NULL;
|
|
|
|
do {
|
|
if (s_lightduerMessageClass == NULL) {
|
|
LOGE("s_lightduerMessageClass is NULL!\n");
|
|
break;
|
|
}
|
|
|
|
jfieldID fieldtype = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "msgType", "S");
|
|
if (fieldtype == NULL) {
|
|
LOGE("get field type failed!\n");
|
|
break;
|
|
}
|
|
jshort typeValue = (*jenv)->GetShortField(jenv, message, fieldtype);
|
|
msg->msg_type = typeValue;
|
|
|
|
jfieldID fieldcode = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "msgCode", "S");
|
|
if (fieldcode == NULL) {
|
|
LOGE("get field code failed!\n");
|
|
break;
|
|
}
|
|
jshort codeValue = (*jenv)->GetShortField(jenv, message, fieldcode);
|
|
msg->msg_code = codeValue;
|
|
|
|
jfieldID fieldId = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "msgId", "I");
|
|
if (fieldId == NULL) {
|
|
LOGE("get field id failed!\n");
|
|
break;
|
|
}
|
|
jint idValue = (*jenv)->GetIntField(jenv, message, fieldId);
|
|
msg->msg_id = idValue;
|
|
|
|
jfieldID fieldtokenLen = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "tokenLen", "I");
|
|
if (fieldtokenLen == NULL) {
|
|
LOGE("get field tokenLen failed!\n");
|
|
break;
|
|
}
|
|
LOGI("response msg id:%d, code:%d, type:%d\n",
|
|
msg->msg_id, msg->msg_code, msg->msg_type);
|
|
jint tokenLenValue = (*jenv)->GetIntField(jenv, message, fieldtokenLen);
|
|
msg->token_len = tokenLenValue;
|
|
jfieldID fieldpathLen = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "pathLen", "I");
|
|
if (fieldpathLen == NULL) {
|
|
LOGE("get field pathLen failed!\n");
|
|
break;
|
|
}
|
|
jint pathLenValue = (*jenv)->GetIntField(jenv, message, fieldpathLen);
|
|
msg->path_len = pathLenValue;
|
|
jfieldID fieldquerylen = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "querylen", "I");
|
|
if (fieldquerylen == NULL) {
|
|
LOGE("get field querylen failed!\n");
|
|
break;
|
|
}
|
|
jint queryLenValue = (*jenv)->GetIntField(jenv, message, fieldquerylen);
|
|
msg->query_len = queryLenValue;
|
|
jfieldID fieldpayloadLen = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "payloadLen", "I");
|
|
if (fieldpayloadLen == NULL) {
|
|
LOGE("get field payloadLen failed!\n");
|
|
break;
|
|
}
|
|
jint payloadLenValue = (*jenv)->GetIntField(jenv, message, fieldpayloadLen);
|
|
msg->payload_len = payloadLenValue;
|
|
LOGI("response: tokenlen:%d, query_len:%d, path_len:%d, payload_len:%d \n",
|
|
msg->token_len, msg->query_len,
|
|
msg->path_len, msg->payload_len);
|
|
|
|
jfieldID fieldPath = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "path", "Ljava/lang/String;");
|
|
if (fieldPath == NULL) {
|
|
LOGE("get field path failed!\n");
|
|
break;
|
|
}
|
|
jstring path = (jstring)(*jenv)->GetObjectField(jenv, message, fieldPath);
|
|
//const char* c_path = (*jenv)->GetStringUTFChars(jenv, path, NULL);
|
|
//LOGI("c_path:%s", c_path);
|
|
//(*jenv)->ReleaseStringUTFChars(jenv, path, c_path);
|
|
jsize pathLength = (*jenv)->GetStringUTFLength(jenv, path);
|
|
newPath = (char *) DUER_MALLOC(pathLength + 1);
|
|
if (newPath == NULL) {
|
|
LOGE("alloc path fail!\n");
|
|
break;
|
|
}
|
|
(*jenv)->GetStringUTFRegion(jenv, path, 0, pathLength, newPath);
|
|
newPath[pathLength] = 0;
|
|
msg->path = (duer_u8_t *)newPath;
|
|
LOGD("path:%s, len1:%d, len2:%d;(len1 == len2)\n", newPath, pathLength, msg->path_len);
|
|
jfieldID fieldQuery = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "query", "Ljava/lang/String;");
|
|
if (fieldQuery == NULL) {
|
|
LOGE("get field query failed!\n");
|
|
break;
|
|
}
|
|
jstring query = (jstring)(*jenv)->GetObjectField(jenv, message, fieldQuery);
|
|
jsize queryLength = (*jenv)->GetStringUTFLength(jenv, query);
|
|
newQuery = (char *) DUER_MALLOC(queryLength + 1);
|
|
if (newQuery == NULL) {
|
|
LOGE("alloc query fail!\n");
|
|
break;
|
|
}
|
|
(*jenv)->GetStringUTFRegion(jenv, query, 0, queryLength, newQuery);
|
|
newQuery[queryLength] = 0;
|
|
msg->query = (duer_u8_t *)newQuery;
|
|
LOGD("query:%s, len1:%d, len2:%d;(len1 == len2)\n",
|
|
newQuery, queryLength, msg->query_len);
|
|
|
|
jfieldID fieldToken = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "token", "[B");
|
|
if (fieldToken == NULL) {
|
|
LOGE("get field token failed!\n");
|
|
break;
|
|
}
|
|
jbyteArray token = (jbyteArray)(*jenv)->GetObjectField(jenv, message, fieldToken);
|
|
jsize tokenLength = (*jenv)->GetArrayLength(jenv, token);
|
|
newToken = (jbyte *) DUER_MALLOC(tokenLength);
|
|
if (newToken == NULL) {
|
|
LOGE("newToken alloc fail!\n");
|
|
break;
|
|
}
|
|
LOGD("newToken: %p, tokenLength:%d, token_len:%d (tokenLength == token_len)\n",
|
|
newToken, tokenLength, msg->token_len);
|
|
(*jenv)->GetByteArrayRegion(jenv, token, 0, tokenLength, newToken);
|
|
msg->token = (duer_u8_t *)newToken;
|
|
//for(int i =0; i < tokenLength; ++i) {
|
|
// LOGD("token[%d]: 0x%x \n", i, msg->token[i]);
|
|
//}
|
|
jfieldID fieldPayload = (*jenv)->GetFieldID(jenv, s_lightduerMessageClass, "payload", "[B");
|
|
if (fieldPayload == NULL) {
|
|
LOGE("get field payload failed!\n");
|
|
break;
|
|
}
|
|
jbyteArray payload = (jbyteArray)(*jenv)->GetObjectField(jenv, message, fieldPayload);
|
|
jsize payloadLength = (*jenv)->GetArrayLength(jenv, payload);
|
|
newPayload = (jbyte *) DUER_MALLOC(payloadLength);
|
|
if (newPayload == NULL) {
|
|
LOGE("newPayload alloc fail!\n");
|
|
break;
|
|
}
|
|
LOGD("newPayload: %p, payloadLength:%d, payload_len:%d (payloadLength == payload_len)\n",
|
|
newPayload, payloadLength, msg->payload_len);
|
|
(*jenv)->GetByteArrayRegion(jenv, payload, 0, payloadLength, newPayload);
|
|
msg->payload = (duer_u8_t *)newPayload;
|
|
|
|
result = DUER_OK;
|
|
} while (0);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|