Browse Source

more...

JNI-88
Volker Birk 4 years ago
parent
commit
b971de7a78
5 changed files with 234 additions and 513 deletions
  1. +2
    -0
      src/Makefile
  2. +24
    -42
      src/basic_api.cc
  3. +0
    -87
      src/jniutils.hh
  4. +166
    -340
      src/org_pEp_jniadapter_AbstractEngine.cc
  5. +42
    -44
      src/pEp.yml2

+ 2
- 0
src/Makefile View File

@ -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


+ 24
- 42
src/basic_api.cc View File

@ -1,6 +1,7 @@
#include <pEp/keymanagement.h>
#include <pEp/blacklist.h>
#include <pEp/sync.h>
#include <pEp/sync_api.h>
#include <pEp/Adapter.hh>
#ifndef ANDROID
#include <string.h>
@ -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) {


+ 0
- 87
src/jniutils.hh View File

@ -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 T> class lock_guard {
T& _mtx;
public:
lock_guard(T& mtx) : _mtx(mtx) {
_mtx.lock();
}
~lock_guard() {
_mtx.unlock();
}
};
template<class T> class locked_queue
{
mutex _mtx;
list<T> _q;
public:
T& back()
{
lock_guard<mutex> lg(_mtx);
return _q.back();
}
T& front()
{
lock_guard<mutex> lg(_mtx);
return _q.front();
}
void pop_back()
{
lock_guard<mutex> lg(_mtx);
_q.pop_back();
}
void pop_front()
{
lock_guard<mutex> lg(_mtx);
_q.pop_front();
}
void push_back(const T& data)
{
lock_guard<mutex> lg(_mtx);
_q.push_back(data);
}
void push_front(const T& data)
{
lock_guard<mutex> lg(_mtx);
_q.push_front(data);
}
size_t size()
{
lock_guard<mutex> lg(_mtx);
return _q.size();
}
};
}
namespace JNIAdapter {
jclass findClass(JNIEnv *env, const char *classname);


+ 166
- 340
src/org_pEp_jniadapter_AbstractEngine.cc View File

@ -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
)
{
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<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message")));
if(timeout && *timeout != 0){
now = time(NULL);
end = now + *timeout;
}
if (!identityClass)
identityClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity")));
sync_env->CallIntMethod(sync_obj, needsFastPollMethodID, needs_fast_poll);
if (!signalClass)
signalClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal")));
while (!queue->size()){
// TODO: add blocking dequeue
usleep(100000);
if (!engineClass)
engineClass = reinterpret_cast<jclass>(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, "<init>", "(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<JNISync>(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<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"

+ 42
- 44
src/pEp.yml2 View File

@ -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
};


Loading…
Cancel
Save