|
|
@ -6,236 +6,134 @@ |
|
|
|
#include <pthread.h> |
|
|
|
#include <pEp/keymanagement.h> |
|
|
|
#include <pEp/message_api.h> |
|
|
|
#include <pEp/sync.h> |
|
|
|
#include <pEp/sync_api.h> |
|
|
|
#include <pEp/Adapter.hh> |
|
|
|
|
|
|
|
#include "throw_pEp_exception.hh" |
|
|
|
#include "jniutils.hh" |
|
|
|
|
|
|
|
extern "C" { |
|
|
|
namespace pEp { |
|
|
|
using namespace pEp::JNIAdapter; |
|
|
|
using namespace pEp::utility; |
|
|
|
|
|
|
|
int inject_sync_msg(void *msg, void *arg); |
|
|
|
static PEP_SESSION sync_session = NULL; |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_init( |
|
|
|
JNIEnv *env, |
|
|
|
jobject me |
|
|
|
) |
|
|
|
using namespace pEp::Adapter; |
|
|
|
using namespace utility; |
|
|
|
|
|
|
|
thread_local JNIEnv* thread_env = nullptr; |
|
|
|
thread_local jobject thread_obj = nullptr; |
|
|
|
|
|
|
|
jclass messageClass = nullptr; |
|
|
|
jclass identityClass = nullptr; |
|
|
|
jclass signalClass = nullptr; |
|
|
|
jclass engineClass = nullptr; |
|
|
|
|
|
|
|
jmethodID messageConstructorMethodID = nullptr; |
|
|
|
jmethodID messageToSendMethodID = nullptr; |
|
|
|
jmethodID notifyHandShakeMethodID = nullptr; |
|
|
|
jmethodID needsFastPollMethodID = nullptr; |
|
|
|
|
|
|
|
class JNISync { |
|
|
|
jobject _obj; |
|
|
|
JNIEnv * _env; |
|
|
|
JavaVM * _jvm; |
|
|
|
JNIEnv * _sync_env; |
|
|
|
jclass _clazz; |
|
|
|
|
|
|
|
public: |
|
|
|
JNISync(JNIEnv * env, jobject obj) |
|
|
|
: _env(env), _obj(obj), _jvm(nullptr), _sync_env(nullptr), _clazz(nullptr) { } |
|
|
|
|
|
|
|
~JNISync() |
|
|
|
{ |
|
|
|
PEP_SESSION session = NULL; |
|
|
|
jfieldID handle; |
|
|
|
|
|
|
|
PEP_STATUS status = init(&session); |
|
|
|
assert(status == PEP_STATUS_OK); |
|
|
|
|
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
throw_pEp_Exception(env, status); |
|
|
|
return; |
|
|
|
env()->DeleteLocalRef(clazz()); |
|
|
|
} |
|
|
|
|
|
|
|
assert(session); |
|
|
|
jobject obj() { return _obj; } |
|
|
|
|
|
|
|
if(sync_session != NULL){ |
|
|
|
status = attach_sync_session(session, sync_session); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
throw_pEp_Exception(env, status); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
handle = getFieldID(env, "org/pEp/jniadapter/Engine", "handle", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
jlong _session = (jlong) session; |
|
|
|
env->SetLongField(me, handle, _session); |
|
|
|
} |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( |
|
|
|
JNIEnv *env, |
|
|
|
jobject me |
|
|
|
) |
|
|
|
JavaVM * jvm() |
|
|
|
{ |
|
|
|
PEP_SESSION session = NULL; |
|
|
|
jfieldID handle; |
|
|
|
|
|
|
|
try { |
|
|
|
handle = getFieldID(env, "org/pEp/jniadapter/Engine", "handle", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
session = (PEP_SESSION) env->GetLongField(me, handle); |
|
|
|
if (session){ |
|
|
|
if(sync_session != NULL){ |
|
|
|
detach_sync_session(session); |
|
|
|
} |
|
|
|
release(session); |
|
|
|
} |
|
|
|
else |
|
|
|
env->SetLongField(me, handle, jlong(0)); |
|
|
|
if (!_jvm) |
|
|
|
_env->GetJavaVM(&_jvm); |
|
|
|
return _jvm; |
|
|
|
} |
|
|
|
|
|
|
|
int examine_identity(pEp_identity *ident, void *arg) |
|
|
|
JNIEnv * env() |
|
|
|
{ |
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
queue->push_back(identity_dup(ident)); |
|
|
|
return 0; |
|
|
|
if (!_sync_env) { |
|
|
|
#ifdef ANDROID |
|
|
|
jvm()->AttachCurrentThread(&_sync_env, nullptr); |
|
|
|
#else |
|
|
|
jvm()->AttachCurrentThread((void **) &_sync_env, nullptr); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
pEp_identity *retrieve_next_identity(void *arg) |
|
|
|
{ |
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
|
|
|
|
while (!queue->size()) |
|
|
|
usleep(100000); |
|
|
|
|
|
|
|
pEp_identity *ident = queue->front(); |
|
|
|
queue->pop_front(); |
|
|
|
return ident; |
|
|
|
return _sync_env; |
|
|
|
} |
|
|
|
|
|
|
|
static void *keyserver_thread_routine(void *arg) |
|
|
|
jclass clazz() |
|
|
|
{ |
|
|
|
PEP_STATUS status = do_keymanagement(retrieve_next_identity, arg); |
|
|
|
|
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
|
|
|
|
while (queue->size()) { |
|
|
|
pEp_identity *ident = queue->front(); |
|
|
|
queue->pop_front(); |
|
|
|
free_identity(ident); |
|
|
|
if (!_clazz) |
|
|
|
_clazz = env()->GetObjectClass(obj()); |
|
|
|
return _clazz; |
|
|
|
} |
|
|
|
|
|
|
|
delete queue; |
|
|
|
|
|
|
|
return (void *) status; |
|
|
|
} |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_startKeyserverLookup( |
|
|
|
JNIEnv *env, |
|
|
|
jobject obj |
|
|
|
) |
|
|
|
void startup_sync() |
|
|
|
{ |
|
|
|
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); |
|
|
|
|
|
|
|
pthread_t *thread = NULL; |
|
|
|
locked_queue< pEp_identity * > *queue = NULL; |
|
|
|
|
|
|
|
jfieldID thread_handle; |
|
|
|
jfieldID queue_handle; |
|
|
|
|
|
|
|
try { |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverQueue", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
thread = (pthread_t *) env->GetLongField(obj, thread_handle); |
|
|
|
if (thread) |
|
|
|
return; |
|
|
|
|
|
|
|
thread = (pthread_t *) calloc(1, sizeof(pthread_t)); |
|
|
|
assert(thread); |
|
|
|
env->SetLongField(obj, thread_handle, (jlong) thread); |
|
|
|
|
|
|
|
queue = new locked_queue< pEp_identity * >(); |
|
|
|
env->SetLongField(obj, queue_handle, (jlong) queue); |
|
|
|
|
|
|
|
register_examine_function(session, examine_identity, (void *) queue); |
|
|
|
needsFastPollMethodID = env()->GetMethodID( |
|
|
|
clazz(), |
|
|
|
"needsFastPollCallFromC", |
|
|
|
"(Z)I"); |
|
|
|
assert(needsFastPollMethodID); |
|
|
|
|
|
|
|
pthread_create(thread, NULL, keyserver_thread_routine, (void *) queue); |
|
|
|
notifyHandShakeMethodID = env()->GetMethodID( |
|
|
|
clazz(), |
|
|
|
"notifyHandshakeCallFromC", |
|
|
|
"(Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/SyncHandshakeSignal;)I"); |
|
|
|
assert(notifyHandShakeMethodID); |
|
|
|
} |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_stopKeyserverLookup( |
|
|
|
JNIEnv *env, |
|
|
|
jobject obj |
|
|
|
) |
|
|
|
void shutdown_sync() |
|
|
|
{ |
|
|
|
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); |
|
|
|
|
|
|
|
pthread_t *thread = NULL; |
|
|
|
locked_queue< pEp_identity * > *queue = NULL; |
|
|
|
|
|
|
|
jfieldID thread_handle; |
|
|
|
jfieldID queue_handle; |
|
|
|
|
|
|
|
try { |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverQueue", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
|
return; |
|
|
|
env()->DeleteLocalRef(messageClass); |
|
|
|
jvm()->DetachCurrentThread(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
thread = (pthread_t *) env->GetLongField(obj, thread_handle); |
|
|
|
if (!thread) |
|
|
|
return; |
|
|
|
|
|
|
|
queue = (locked_queue< pEp_identity * > *) env->GetLongField(obj, queue_handle); |
|
|
|
JNISync *o = nullptr; |
|
|
|
|
|
|
|
env->SetLongField(obj, queue_handle, (jlong) 0); |
|
|
|
env->SetLongField(obj, thread_handle, (jlong) 0); |
|
|
|
PEP_STATUS messageToSend(message *msg) |
|
|
|
{ |
|
|
|
jobject msg_ = nullptr; |
|
|
|
|
|
|
|
register_examine_function(session, NULL, NULL); |
|
|
|
msg_ = thread_env->NewObject(messageClass, messageConstructorMethodID, (jlong) msg); |
|
|
|
jint result = thread_env->CallIntMethod(thread_obj, messageToSendMethodID, msg_); |
|
|
|
|
|
|
|
queue->push_front(NULL); |
|
|
|
pthread_join(*thread, NULL); |
|
|
|
free(thread); |
|
|
|
return (PEP_STATUS) result; |
|
|
|
} |
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// Sync message callbacks, queue, and thread
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static jobject sync_obj = NULL; |
|
|
|
static JNIEnv* sync_env = NULL; |
|
|
|
static jmethodID needsFastPollMethodID = NULL; |
|
|
|
static jmethodID notifyHandShakeMethodID = NULL; |
|
|
|
static jmethodID messageToSendMethodID = NULL; |
|
|
|
static jclass messageClass = NULL; |
|
|
|
static jclass identityClass = NULL; |
|
|
|
static jclass signalClass = NULL; |
|
|
|
static jmethodID messageConstructorMethodID = NULL; |
|
|
|
|
|
|
|
// Called by sync thread only
|
|
|
|
PEP_STATUS notify_handshake(void *obj, pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) |
|
|
|
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) |
|
|
|
{ |
|
|
|
jobject me_ = NULL; |
|
|
|
jobject partner_ = NULL; |
|
|
|
jobject me_ = nullptr; |
|
|
|
jobject partner_ = nullptr; |
|
|
|
|
|
|
|
me_ = from_identity(sync_env, me, identityClass); |
|
|
|
partner_ = from_identity(sync_env, partner, identityClass); |
|
|
|
me_ = from_identity(thread_env, me, identityClass); |
|
|
|
partner_ = from_identity(thread_env, partner, identityClass); |
|
|
|
|
|
|
|
jobject signal_ = NULL; |
|
|
|
jobject signal_ = nullptr; |
|
|
|
{ |
|
|
|
assert(signalClass); |
|
|
|
jmethodID method_values = sync_env->GetStaticMethodID(signalClass, "values", |
|
|
|
jmethodID method_values = o->env()->GetStaticMethodID(signalClass, "values", |
|
|
|
"()[Lorg/pEp/jniadapter/SyncHandshakeSignal;"); |
|
|
|
assert(method_values); |
|
|
|
jfieldID field_value = sync_env->GetFieldID(signalClass, "value", "I"); |
|
|
|
jfieldID field_value = o->env()->GetFieldID(signalClass, "value", "I"); |
|
|
|
assert(field_value); |
|
|
|
|
|
|
|
jobjectArray values = (jobjectArray) sync_env->CallStaticObjectMethod(signalClass, |
|
|
|
jobjectArray values = (jobjectArray) o->env()->CallStaticObjectMethod(signalClass, |
|
|
|
method_values); |
|
|
|
assert(values); |
|
|
|
|
|
|
|
jsize values_size = sync_env->GetArrayLength(values); |
|
|
|
jsize values_size = o->env()->GetArrayLength(values); |
|
|
|
for (jsize i = 0; i < values_size; i++) { |
|
|
|
jobject element = sync_env->GetObjectArrayElement(values, i); |
|
|
|
jobject element = o->env()->GetObjectArrayElement(values, i); |
|
|
|
assert(element); |
|
|
|
jint value = sync_env->GetIntField(element, field_value); |
|
|
|
jint value = o->env()->GetIntField(element, field_value); |
|
|
|
if (value == (jint) signal) { |
|
|
|
signal_ = element; |
|
|
|
break; |
|
|
@ -243,154 +141,114 @@ extern "C" { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
jint result = sync_env->CallIntMethod(sync_obj, notifyHandShakeMethodID, me_, partner_, signal_); |
|
|
|
jint result = o->env()->CallIntMethod(o->obj(), notifyHandShakeMethodID, me_, partner_, signal_); |
|
|
|
|
|
|
|
return (PEP_STATUS) result; |
|
|
|
} |
|
|
|
|
|
|
|
// Called by sync thread only
|
|
|
|
PEP_STATUS message_to_send(void *obj, message *msg) |
|
|
|
{ |
|
|
|
jobject msg_ = NULL; |
|
|
|
|
|
|
|
msg_ = sync_env->NewObject(messageClass, messageConstructorMethodID, (jlong) msg); |
|
|
|
} |
|
|
|
|
|
|
|
jint result = sync_env->CallIntMethod(sync_obj, messageToSendMethodID, msg_); |
|
|
|
|
|
|
|
return (PEP_STATUS) result; |
|
|
|
} |
|
|
|
extern "C" { |
|
|
|
using namespace pEp; |
|
|
|
|
|
|
|
// called indirectly by decrypt message
|
|
|
|
int inject_sync_msg(void *msg, void *arg) |
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_init( |
|
|
|
JNIEnv *env, |
|
|
|
jobject me |
|
|
|
) |
|
|
|
{ |
|
|
|
if(arg == NULL) |
|
|
|
return 1; |
|
|
|
|
|
|
|
locked_queue< sync_msg_t * > *queue = (locked_queue< sync_msg_t * > *) arg; |
|
|
|
thread_env = env; |
|
|
|
thread_obj = me; |
|
|
|
|
|
|
|
queue->push_back((sync_msg_t *)msg); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
assert(o == nullptr); |
|
|
|
o = new JNISync(env, me); |
|
|
|
|
|
|
|
void *retrieve_next_sync_msg(void *arg, time_t *timeout) |
|
|
|
{ |
|
|
|
locked_queue< sync_msg_t * > *queue = (locked_queue< sync_msg_t * > *) arg; |
|
|
|
|
|
|
|
time_t now, end; |
|
|
|
void *msg; |
|
|
|
if (!messageClass) |
|
|
|
messageClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message"))); |
|
|
|
|
|
|
|
jboolean needs_fast_poll = (*timeout != 0); |
|
|
|
if (!identityClass) |
|
|
|
identityClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity"))); |
|
|
|
|
|
|
|
if(timeout && *timeout != 0){ |
|
|
|
now = time(NULL); |
|
|
|
end = now + *timeout; |
|
|
|
} |
|
|
|
if (!signalClass) |
|
|
|
signalClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal"))); |
|
|
|
|
|
|
|
sync_env->CallIntMethod(sync_obj, needsFastPollMethodID, needs_fast_poll); |
|
|
|
if (!engineClass) |
|
|
|
engineClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Engine"))); |
|
|
|
|
|
|
|
while (!queue->size()){ |
|
|
|
// TODO: add blocking dequeue
|
|
|
|
usleep(100000); |
|
|
|
if (!messageConstructorMethodID) |
|
|
|
messageConstructorMethodID = env->GetMethodID(messageClass, "<init>", "(J)V"); |
|
|
|
|
|
|
|
if(timeout && *timeout != 0){ |
|
|
|
now = time(NULL); |
|
|
|
if(now > end) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (!messageToSendMethodID) { |
|
|
|
messageToSendMethodID = env->GetMethodID( |
|
|
|
engineClass, |
|
|
|
"messageToSendCallFromC", |
|
|
|
"(Lorg/pEp/jniadapter/Message;)I"); |
|
|
|
assert(messageToSendMethodID); |
|
|
|
} |
|
|
|
|
|
|
|
if(timeout && *timeout != 0){ |
|
|
|
// put back remaining time in timeout
|
|
|
|
now = time(NULL); |
|
|
|
if(now < end) |
|
|
|
*timeout = end - now; |
|
|
|
else |
|
|
|
*timeout = 0; |
|
|
|
startup<JNISync>(messageToSend, notifyHandshake, o, &JNISync::startup_sync, &JNISync::shutdown_sync); |
|
|
|
} |
|
|
|
|
|
|
|
msg = queue->front(); |
|
|
|
queue->pop_front(); |
|
|
|
return msg; |
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( |
|
|
|
JNIEnv *env, |
|
|
|
jobject me |
|
|
|
) |
|
|
|
{ |
|
|
|
shutdown(); |
|
|
|
delete o; |
|
|
|
session(pEp::Adapter::release); |
|
|
|
} |
|
|
|
|
|
|
|
typedef struct _sync_thread_arg_t { |
|
|
|
PEP_SESSION session; |
|
|
|
locked_queue< sync_msg_t * > *queue; |
|
|
|
JavaVM* sync_jvm; |
|
|
|
} sync_thread_arg_t; |
|
|
|
|
|
|
|
|
|
|
|
static void *sync_thread_routine(void *arg) |
|
|
|
int examine_identity(pEp_identity *ident, void *arg) |
|
|
|
{ |
|
|
|
sync_thread_arg_t *a = (sync_thread_arg_t*)arg; |
|
|
|
PEP_SESSION session = (PEP_SESSION) a->session; |
|
|
|
#ifdef ANDROID |
|
|
|
a->sync_jvm->AttachCurrentThread(&sync_env, NULL); |
|
|
|
#else |
|
|
|
a->sync_jvm->AttachCurrentThread((void **) &sync_env, NULL); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
jclass clazz = sync_env->GetObjectClass(sync_obj); |
|
|
|
|
|
|
|
needsFastPollMethodID = sync_env->GetMethodID( |
|
|
|
clazz, |
|
|
|
"needsFastPollCallFromC", |
|
|
|
"(Z)I"); |
|
|
|
assert(needsFastPollMethodID); |
|
|
|
|
|
|
|
notifyHandShakeMethodID = sync_env->GetMethodID( |
|
|
|
clazz, |
|
|
|
"notifyHandshakeCallFromC", |
|
|
|
"(Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/SyncHandshakeSignal;)I"); |
|
|
|
assert(notifyHandShakeMethodID); |
|
|
|
|
|
|
|
messageToSendMethodID = sync_env->GetMethodID( |
|
|
|
clazz, |
|
|
|
"messageToSendCallFromC", |
|
|
|
"(Lorg/pEp/jniadapter/Message;)I"); |
|
|
|
assert(messageToSendMethodID); |
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
queue->push_back(identity_dup(ident)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
sync_env->DeleteLocalRef(clazz); |
|
|
|
pEp_identity *retrieve_next_identity(void *arg) |
|
|
|
{ |
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
|
|
|
|
while (!queue->size()) |
|
|
|
usleep(100000); |
|
|
|
|
|
|
|
PEP_STATUS status = do_sync_protocol(session, a->queue); |
|
|
|
pEp_identity *ident = queue->front(); |
|
|
|
queue->pop_front(); |
|
|
|
return ident; |
|
|
|
} |
|
|
|
|
|
|
|
locked_queue< sync_msg_t * > *queue = (locked_queue< sync_msg_t * > *) arg; |
|
|
|
static void *keyserver_thread_routine(void *arg) |
|
|
|
{ |
|
|
|
PEP_STATUS status = do_keymanagement(retrieve_next_identity, arg); |
|
|
|
locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; |
|
|
|
|
|
|
|
while (queue->size()) { |
|
|
|
sync_msg_t *msg = queue->front(); |
|
|
|
pEp_identity *ident = queue->front(); |
|
|
|
queue->pop_front(); |
|
|
|
free_sync_msg(msg); |
|
|
|
free_identity(ident); |
|
|
|
} |
|
|
|
|
|
|
|
sync_env->DeleteLocalRef(messageClass); |
|
|
|
|
|
|
|
a->sync_jvm->DetachCurrentThread(); |
|
|
|
|
|
|
|
delete queue; |
|
|
|
free(a); |
|
|
|
|
|
|
|
return (void *) status; |
|
|
|
} |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_startSync( |
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_startKeyserverLookup( |
|
|
|
JNIEnv *env, |
|
|
|
jobject obj |
|
|
|
) |
|
|
|
{ |
|
|
|
LOGD("Start Sync"); |
|
|
|
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); |
|
|
|
|
|
|
|
pthread_t *thread = NULL; |
|
|
|
locked_queue< sync_msg_t * > *queue = NULL; |
|
|
|
pthread_t *thread = nullptr; |
|
|
|
locked_queue< pEp_identity * > *queue = nullptr; |
|
|
|
|
|
|
|
jfieldID thread_handle; |
|
|
|
jfieldID queue_handle; |
|
|
|
|
|
|
|
try { |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "syncThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "syncQueue", "J"); |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverQueue", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
@ -405,51 +263,30 @@ extern "C" { |
|
|
|
assert(thread); |
|
|
|
env->SetLongField(obj, thread_handle, (jlong) thread); |
|
|
|
|
|
|
|
queue = new locked_queue< sync_msg_t * >(); |
|
|
|
queue = new locked_queue< pEp_identity * >(); |
|
|
|
env->SetLongField(obj, queue_handle, (jlong) queue); |
|
|
|
|
|
|
|
// for callbacks
|
|
|
|
sync_obj = env->NewGlobalRef(obj); |
|
|
|
sync_thread_arg_t *a = (sync_thread_arg_t*) malloc(sizeof(sync_thread_arg_t)); |
|
|
|
assert(a); |
|
|
|
a->session = session; |
|
|
|
a->queue = queue; |
|
|
|
messageClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message"))); |
|
|
|
identityClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity"))); |
|
|
|
signalClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal"))); |
|
|
|
messageConstructorMethodID = env->GetMethodID(messageClass, "<init>", "(J)V"); |
|
|
|
|
|
|
|
env->GetJavaVM(&a->sync_jvm); |
|
|
|
|
|
|
|
sync_session = session; |
|
|
|
|
|
|
|
register_sync_callbacks(session, |
|
|
|
(void *) queue, |
|
|
|
message_to_send, |
|
|
|
notify_handshake, |
|
|
|
inject_sync_msg, |
|
|
|
retrieve_next_sync_msg); |
|
|
|
|
|
|
|
register_examine_function(session, examine_identity, (void *) queue); |
|
|
|
|
|
|
|
pthread_create(thread, NULL, sync_thread_routine, (void *) a); |
|
|
|
pthread_create(thread, nullptr, keyserver_thread_routine, (void *) queue); |
|
|
|
} |
|
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_stopSync( |
|
|
|
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_stopKeyserverLookup( |
|
|
|
JNIEnv *env, |
|
|
|
jobject obj |
|
|
|
) |
|
|
|
{ |
|
|
|
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); |
|
|
|
|
|
|
|
pthread_t *thread = NULL; |
|
|
|
locked_queue< sync_msg_t * > *queue = NULL; |
|
|
|
pthread_t *thread = nullptr; |
|
|
|
locked_queue< pEp_identity * > *queue = nullptr; |
|
|
|
|
|
|
|
jfieldID thread_handle; |
|
|
|
jfieldID queue_handle; |
|
|
|
|
|
|
|
try { |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "syncThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "syncQueue", "J"); |
|
|
|
thread_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverThread", "J"); |
|
|
|
queue_handle = getFieldID(env, "org/pEp/jniadapter/Engine", "keyserverQueue", "J"); |
|
|
|
} |
|
|
|
catch (std::exception& ex) { |
|
|
|
assert(0); |
|
|
@ -460,28 +297,17 @@ extern "C" { |
|
|
|
if (!thread) |
|
|
|
return; |
|
|
|
|
|
|
|
queue = (locked_queue< sync_msg_t * > *) env->GetLongField(obj, queue_handle); |
|
|
|
queue = (locked_queue< pEp_identity * > *) env->GetLongField(obj, queue_handle); |
|
|
|
|
|
|
|
env->SetLongField(obj, queue_handle, (jlong) 0); |
|
|
|
env->SetLongField(obj, thread_handle, (jlong) 0); |
|
|
|
|
|
|
|
sync_session = NULL; |
|
|
|
|
|
|
|
unregister_sync_callbacks(session); |
|
|
|
env->DeleteGlobalRef(sync_obj); |
|
|
|
env->DeleteGlobalRef(messageClass); |
|
|
|
env->DeleteGlobalRef(identityClass); |
|
|
|
env->DeleteGlobalRef(signalClass); |
|
|
|
register_examine_function(session, nullptr, nullptr); |
|
|
|
|
|
|
|
sync_obj = NULL; |
|
|
|
messageClass = NULL; |
|
|
|
identityClass = NULL; |
|
|
|
signalClass = NULL; |
|
|
|
|
|
|
|
queue->push_front(NULL); |
|
|
|
pthread_join(*thread, NULL); |
|
|
|
queue->push_front(nullptr); |
|
|
|
pthread_join(*thread, nullptr); |
|
|
|
free(thread); |
|
|
|
} |
|
|
|
} // extern "C"
|
|
|
|
|
|
|
|
} // extern "C"
|
|
|
|
|
|
|
|