diff --git a/src/Makefile b/src/Makefile index 2226b74..f38afd2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -39,8 +39,10 @@ org_pEp_jniadapter_Message.h: org/pEp/jniadapter/Message.java javah $(subst /,.,$(subst .java,,$<)) org_pEp_jniadapter_AbstractEngine.o: %.o: %.cc %.h throw_pEp_exception.hh jniutils.hh + $(CXX) -std=c++14 $(CXXFLAGS) $< -o $@ org_pEp_jniadapter_Engine.o org_pEp_jniadapter_Message.o: %.o: %.cc %.h + $(CXX) -std=c++14 $(CXXFLAGS) $< -o $@ $(LIBRARY): org_pEp_jniadapter_AbstractEngine.o org_pEp_jniadapter_Engine.o org_pEp_jniadapter_Message.o throw_pEp_exception.o jniutils.o basic_api.o ar -r $@ *.o diff --git a/src/basic_api.cc b/src/basic_api.cc index a7e869c..e7cdf2e 100644 --- a/src/basic_api.cc +++ b/src/basic_api.cc @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #ifndef ANDROID #include @@ -11,6 +12,7 @@ extern "C" { using namespace pEp::JNIAdapter; + using namespace pEp::Adapter; JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords( JNIEnv *env, @@ -18,13 +20,12 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); char *words; size_t wsize; if (_ident->fpr == NULL || _ident->fpr[0] == 0) { - ::update_identity(session, _ident); + ::update_identity(session(), _ident); } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -38,7 +39,7 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords( else lang = "en"; - PEP_STATUS status = ::trustwords(session, _ident->fpr, lang, &words, &wsize, 10); + PEP_STATUS status = ::trustwords(session(), _ident->fpr, lang, &words, &wsize, 10); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return NULL; @@ -53,10 +54,9 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_myself( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); - ::myself(session, _ident); + ::myself(session(), _ident); return from_identity(env, _ident); } @@ -67,10 +67,9 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_updateIdentity( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); - ::update_identity(session, _ident); + ::update_identity(session(), _ident); return from_identity(env, _ident); } @@ -82,11 +81,10 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_setOwnKey( jbyteArray fpr ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); char *_fpr = to_string(env, fpr); - ::set_own_key(session, _ident, _fpr); + ::set_own_key(session(), _ident, _fpr); return from_identity(env, _ident); } @@ -97,11 +95,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyMistrusted( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { - ::update_identity(session, _ident); + ::update_identity(session(), _ident); } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -109,7 +106,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyMistrusted( return; } - ::key_mistrusted(session, _ident); + ::key_mistrusted(session(), _ident); } JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust( @@ -118,11 +115,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { - ::update_identity(session, _ident); + ::update_identity(session(), _ident); } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -130,7 +126,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust( return; } - ::key_reset_trust(session, _ident); + ::key_reset_trust(session(), _ident); } JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey( @@ -139,11 +135,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { - ::update_identity(session, _ident); + ::update_identity(session(), _ident); } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -151,7 +146,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey( return; } - ::trust_personal_key(session, _ident); + ::trust_personal_key(session(), _ident); } JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey( @@ -160,7 +155,6 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey( jbyteArray key ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); char *_key = to_string(env, key); if(_key == NULL){ @@ -169,7 +163,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey( } - PEP_STATUS status = ::import_key(session, _key, strlen(_key), NULL); + PEP_STATUS status = ::import_key(session(), _key, strlen(_key), NULL); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -183,9 +177,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_config_1passive_1mode( jboolean enable ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); - - ::config_passive_mode(session, (bool)enable); + ::config_passive_mode(session(), (bool)enable); } @@ -195,9 +187,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_config_1unencrypted_1subje jboolean enable ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); - - ::config_unencrypted_subject(session, (bool)enable); + ::config_unencrypted_subject(session(), (bool)enable); } JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1add( @@ -206,7 +196,6 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1add( jbyteArray fpr ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); char *_fpr = to_string(env, fpr); if(_fpr == NULL){ @@ -214,7 +203,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1add( return; } - PEP_STATUS status = ::blacklist_add(session, _fpr); + PEP_STATUS status = ::blacklist_add(session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -228,7 +217,6 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1delete( jbyteArray fpr ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); char *_fpr = to_string(env, fpr); if(_fpr == NULL){ @@ -236,7 +224,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1delete( return; } - PEP_STATUS status = ::blacklist_delete(session, _fpr); + PEP_STATUS status = ::blacklist_delete(session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -250,7 +238,6 @@ JNIEXPORT jboolean JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1is_1listed( jbyteArray fpr ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); char *_fpr = to_string(env, fpr); bool _listed = 0; @@ -259,7 +246,7 @@ JNIEXPORT jboolean JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1is_1listed( return 0; } - PEP_STATUS status = ::blacklist_is_listed(session, _fpr, &_listed); + PEP_STATUS status = ::blacklist_is_listed(session(), _fpr, &_listed); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return 0; @@ -275,11 +262,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_accept_1sync_1handshake( ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); PEP_STATUS status = - ::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_ACCEPTED); + ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_ACCEPTED); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); @@ -294,11 +280,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_reject_1sync_1handshake( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); PEP_STATUS status = - ::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_REJECTED); + ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_REJECTED); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); @@ -312,11 +297,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_cancel_1sync_1handshake( jobject ident ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); pEp_identity *_ident = to_identity(env, ident); PEP_STATUS status = - ::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_CANCEL); + ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_CANCEL); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); @@ -331,12 +315,10 @@ JNIEXPORT jbyteArray JNICALL Java_org_pEp_jniadapter_Engine_getCrashdumpLog( jint maxlines ) { - PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle"); - int _maxlines = (int) maxlines; char *_logdata; - PEP_STATUS status = ::get_crashdump_log(session, _maxlines, &_logdata); + PEP_STATUS status = ::get_crashdump_log(session(), _maxlines, &_logdata); if ((status > PEP_STATUS_OK && status < PEP_UNENCRYPTED) || status < PEP_STATUS_OK || status >= PEP_TRUSTWORD_NOT_FOUND) { diff --git a/src/jniutils.hh b/src/jniutils.hh index 55e613c..cb151f5 100644 --- a/src/jniutils.hh +++ b/src/jniutils.hh @@ -18,93 +18,6 @@ #endif namespace pEp { - namespace utility { - using namespace std; - - class mutex { - typedef pthread_mutex_t native_handle_type; - native_handle_type _mutex; - - public: - mutex() { - int result; - do { - result = pthread_mutex_init(&_mutex, NULL); - } while (result == EAGAIN); - } - ~mutex() { - pthread_mutex_destroy(&_mutex); - } - void lock() { - pthread_mutex_lock(&_mutex); - } - void unlock() { - pthread_mutex_unlock(&_mutex); - } - native_handle_type native_handle() { - return _mutex; - } - bool try_lock() { - return pthread_mutex_trylock(&_mutex) == 0; - } - }; - - template class lock_guard { - T& _mtx; - - public: - lock_guard(T& mtx) : _mtx(mtx) { - _mtx.lock(); - } - ~lock_guard() { - _mtx.unlock(); - } - }; - - template class locked_queue - { - mutex _mtx; - list _q; - - public: - T& back() - { - lock_guard lg(_mtx); - return _q.back(); - } - T& front() - { - lock_guard lg(_mtx); - return _q.front(); - } - void pop_back() - { - lock_guard lg(_mtx); - _q.pop_back(); - } - void pop_front() - { - lock_guard lg(_mtx); - _q.pop_front(); - } - void push_back(const T& data) - { - lock_guard lg(_mtx); - _q.push_back(data); - } - void push_front(const T& data) - { - lock_guard lg(_mtx); - _q.push_front(data); - } - size_t size() - { - lock_guard lg(_mtx); - return _q.size(); - } - }; - } - namespace JNIAdapter { jclass findClass(JNIEnv *env, const char *classname); diff --git a/src/org_pEp_jniadapter_AbstractEngine.cc b/src/org_pEp_jniadapter_AbstractEngine.cc index 149aa14..fd7b375 100644 --- a/src/org_pEp_jniadapter_AbstractEngine.cc +++ b/src/org_pEp_jniadapter_AbstractEngine.cc @@ -6,236 +6,134 @@ #include #include #include -#include +#include +#include #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 - ) - { - 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; - } - - assert(session); - - 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; + 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() + { + env()->DeleteLocalRef(clazz()); } - jlong _session = (jlong) session; - env->SetLongField(me, handle, _session); - } - - JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( - JNIEnv *env, - jobject me - ) - { - PEP_SESSION session = NULL; - jfieldID handle; + jobject obj() { return _obj; } - try { - handle = getFieldID(env, "org/pEp/jniadapter/Engine", "handle", "J"); - } - catch (std::exception& ex) { - assert(0); - return; + JavaVM * jvm() + { + if (!_jvm) + _env->GetJavaVM(&_jvm); + return _jvm; } - session = (PEP_SESSION) env->GetLongField(me, handle); - if (session){ - if(sync_session != NULL){ - detach_sync_session(session); + JNIEnv * env() + { + if (!_sync_env) { + #ifdef ANDROID + jvm()->AttachCurrentThread(&_sync_env, nullptr); + #else + jvm()->AttachCurrentThread((void **) &_sync_env, nullptr); + #endif } - release(session); + return _sync_env; } - else - env->SetLongField(me, handle, jlong(0)); - } - - int examine_identity(pEp_identity *ident, void *arg) - { - locked_queue< pEp_identity * > *queue = (locked_queue< pEp_identity * > *) arg; - queue->push_back(identity_dup(ident)); - return 0; - } - - 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; - } - - 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()) { - pEp_identity *ident = queue->front(); - queue->pop_front(); - free_identity(ident); + jclass clazz() + { + 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 - ) - { - 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; + void startup_sync() + { + needsFastPollMethodID = env()->GetMethodID( + clazz(), + "needsFastPollCallFromC", + "(Z)I"); + assert(needsFastPollMethodID); + + notifyHandShakeMethodID = env()->GetMethodID( + clazz(), + "notifyHandshakeCallFromC", + "(Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/SyncHandshakeSignal;)I"); + assert(notifyHandShakeMethodID); } - 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); - - pthread_create(thread, NULL, keyserver_thread_routine, (void *) queue); - } - - 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< 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; + void shutdown_sync() + { + 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_); - - 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_); + jint result = o->env()->CallIntMethod(o->obj(), notifyHandShakeMethodID, me_, partner_, signal_); return (PEP_STATUS) result; } - // called indirectly by decrypt message - int inject_sync_msg(void *msg, void *arg) - { - if(arg == NULL) - return 1; - - locked_queue< sync_msg_t * > *queue = (locked_queue< sync_msg_t * > *) arg; +} - queue->push_back((sync_msg_t *)msg); - return 0; - } +extern "C" { + using namespace pEp; - void *retrieve_next_sync_msg(void *arg, time_t *timeout) + JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_init( + JNIEnv *env, + jobject me + ) { - locked_queue< sync_msg_t * > *queue = (locked_queue< sync_msg_t * > *) arg; + thread_env = env; + thread_obj = me; - time_t now, end; - void *msg; + assert(o == nullptr); + o = new JNISync(env, me); - jboolean needs_fast_poll = (*timeout != 0); + if (!messageClass) + messageClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message"))); - if(timeout && *timeout != 0){ - now = time(NULL); - end = now + *timeout; - } + if (!identityClass) + identityClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity"))); - sync_env->CallIntMethod(sync_obj, needsFastPollMethodID, needs_fast_poll); + if (!signalClass) + signalClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal"))); - while (!queue->size()){ - // TODO: add blocking dequeue - usleep(100000); + if (!engineClass) + engineClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Engine"))); - if(timeout && *timeout != 0){ - now = time(NULL); - if(now > end) - return NULL; - } - } + if (!messageConstructorMethodID) + messageConstructorMethodID = env->GetMethodID(messageClass, "", "(J)V"); - if(timeout && *timeout != 0){ - // put back remaining time in timeout - now = time(NULL); - if(now < end) - *timeout = end - now; - else - *timeout = 0; + if (!messageToSendMethodID) { + messageToSendMethodID = env->GetMethodID( + engineClass, + "messageToSendCallFromC", + "(Lorg/pEp/jniadapter/Message;)I"); + assert(messageToSendMethodID); } - msg = queue->front(); - queue->pop_front(); - return msg; + startup(messageToSend, notifyHandshake, o, &JNISync::startup_sync, &JNISync::shutdown_sync); } - 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) + JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( + JNIEnv *env, + jobject me + ) { - 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); + shutdown(); + delete o; + session(pEp::Adapter::release); + } - messageToSendMethodID = sync_env->GetMethodID( - clazz, - "messageToSendCallFromC", - "(Lorg/pEp/jniadapter/Message;)I"); - assert(messageToSendMethodID); + int examine_identity(pEp_identity *ident, void *arg) + { + 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(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message"))); - identityClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity"))); - signalClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal"))); - messageConstructorMethodID = env->GetMethodID(messageClass, "", "(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" diff --git a/src/pEp.yml2 b/src/pEp.yml2 index 81e690b..88f12fc 100644 --- a/src/pEp.yml2 +++ b/src/pEp.yml2 @@ -8,51 +8,52 @@ decl basic @type @name; namespace pEp { exception Status { - pEp_status_ok > 0 + pEp_status_ok > 0 - pEp_init_cannot_load_gpgme > 0x0110 - pEp_init_gpgme_init_failed > 0x0111 - pEp_init_no_gpg_home > 0x0112 - pEp_init_netpgp_init_failed > 0x0113 + pEp_init_cannot_load_gpgme > 0x0110 + pEp_init_gpgme_init_failed > 0x0111 + pEp_init_no_gpg_home > 0x0112 + pEp_init_netpgp_init_failed > 0x0113 pEp_init_cannot_determine_gpg_version > 0x0114 pEp_init_unsupported_gpg_version > 0x0115 pEp_init_cannot_config_gpg_agent > 0x0116 - pEp_init_sqlite3_without_mutex > 0x0120 - pEp_init_cannot_open_db > 0x0121 - pEp_init_cannot_open_system_db > 0x0122 + pEp_init_sqlite3_without_mutex > 0x0120 + pEp_init_cannot_open_db > 0x0121 + pEp_init_cannot_open_system_db > 0x0122 - pEp_key_not_found > 0x0201 - pEp_key_has_ambig_name > 0x0202 - pEp_get_key_failed > 0x0203 + pEp_key_not_found > 0x0201 + pEp_key_has_ambig_name > 0x0202 + pEp_get_key_failed > 0x0203 pEp_cannot_export_key > 0x0204 pEp_cannot_edit_key > 0x0205 pEp_key_unsuitable > 0x0206 - pEp_cannot_find_identity > 0x0301 - pEp_cannot_set_person > 0x0381 - pEp_cannot_set_pgp_keypair > 0x0382 - pEp_cannot_set_identity > 0x0383 + pEp_cannot_find_identity > 0x0301 + pEp_cannot_set_person > 0x0381 + pEp_cannot_set_pgp_keypair > 0x0382 + pEp_cannot_set_identity > 0x0383 pEp_cannot_set_trust > 0x0384 pEp_key_blacklisted > 0x0385 pEp_cannot_find_person > 0x0386 - + pEp_cannot_find_alias > 0x0391 pEp_cannot_set_alias > 0x0392 - - pEp_unencrypted > 0x0400 - pEp_verified > 0x0401 - pEp_decrypted > 0x0402 - pEp_decrypted_and_verified > 0x0403 - pEp_decrypt_wrong_format > 0x0404 - pEp_decrypt_no_key > 0x0405 - pEp_decrypt_signature_does_not_match > 0x0406 + + pEp_unencrypted > 0x0400 + pEp_verified > 0x0401 + pEp_decrypted > 0x0402 + pEp_decrypted_and_verified > 0x0403 + pEp_decrypt_wrong_format > 0x0404 + pEp_decrypt_no_key > 0x0405 + pEp_decrypt_signature_does_not_match > 0x0406 pEp_verify_no_key > 0x0407 pEp_verified_and_trusted > 0x0408 - pEp_cannot_decrypt_unknown > 0x04ff + pEp_cannot_reencrypt > 0x0409 + pEp_cannot_decrypt_unknown > 0x04ff - pEp_trustword_not_found > 0x0501 - pEp_trustwords_fpr_wrong_length > 0x0502 + pEp_trustword_not_found > 0x0501 + pEp_trustwords_fpr_wrong_length > 0x0502 pEp_trustwords_duplicate_fpr > 0x0503 pEp_cannot_create_key > 0x0601 @@ -60,40 +61,37 @@ namespace pEp { pEp_phrase_not_found > 0x0701 - pEp_send_function_not_registered                > 0x0801 - pEp_contraints_violated                         > 0x0802 - pEp_cannot_encode                               > 0x0803 + pEp_send_function_not_registered > 0x0801 + pEp_contraints_violated > 0x0802 + pEp_cannot_encode > 0x0803 - pEp_sync_no_notify_callback                  > 0x0901 - pEp_sync_illegal_message                        > 0x0902 - pEp_sync_no_inject_callback                     > 0x0903 + pEp_sync_no_notify_callback > 0x0901 + pEp_sync_illegal_message > 0x0902 + pEp_sync_no_inject_callback > 0x0903 + pEp_sync_no_channel > 0x0904 + pEp_sync_cannot_encrypt > 0x0905 - pEp_sequence_violated > 0x0970 pEp_cannot_increase_sequence > 0x0971 - pEp_cannot_set_sequence_value > 0x0972 - pEp_own_sequence > 0x097f - pEp_sync_statemachine_error > 0x0980 - pEp_sync_no_trust > 0x0981 + pEp_statemachine_error > 0x0980 + pEp_no_trust > 0x0981 pEp_statemachine_invalid_state > 0x0982 pEp_statemachine_invalid_event > 0x0983 pEp_statemachine_invalid_condition > 0x0984 pEp_statemachine_invalid_action > 0x0985 pEp_statemachine_inhibited_event > 0x0986 - pEp_commit_failed > 0xff01 + pEp_commit_failed > 0xff01 pEp_message_consume > 0xff02 pEp_message_ignore > 0xff03 - pEp_record_not_found > -6 pEp_cannot_create_temp_file > -5 pEp_illegal_value > -4 pEp_buffer_too_small > -3 - pEp_out_of_memory > -2 - pEp_unknown_error > -1 - - + pEp_out_of_memory > -2 + pEp_unknown_error > -1 + pEp_version_mismatch > -7 };