Browse Source

more...

JNI-88
Volker Birk 7 years ago
parent
commit
b971de7a78
  1. 2
      src/Makefile
  2. 66
      src/basic_api.cc
  3. 87
      src/jniutils.hh
  4. 506
      src/org_pEp_jniadapter_AbstractEngine.cc
  5. 86
      src/pEp.yml2

2
src/Makefile

@ -39,8 +39,10 @@ org_pEp_jniadapter_Message.h: org/pEp/jniadapter/Message.java
javah $(subst /,.,$(subst .java,,$<)) javah $(subst /,.,$(subst .java,,$<))
org_pEp_jniadapter_AbstractEngine.o: %.o: %.cc %.h throw_pEp_exception.hh jniutils.hh 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 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 $(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 ar -r $@ *.o

66
src/basic_api.cc

@ -1,6 +1,7 @@
#include <pEp/keymanagement.h> #include <pEp/keymanagement.h>
#include <pEp/blacklist.h> #include <pEp/blacklist.h>
#include <pEp/sync.h> #include <pEp/sync_api.h>
#include <pEp/Adapter.hh>
#ifndef ANDROID #ifndef ANDROID
#include <string.h> #include <string.h>
@ -11,6 +12,7 @@
extern "C" { extern "C" {
using namespace pEp::JNIAdapter; using namespace pEp::JNIAdapter;
using namespace pEp::Adapter;
JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords( JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords(
JNIEnv *env, JNIEnv *env,
@ -18,13 +20,12 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
char *words; char *words;
size_t wsize; size_t wsize;
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
::update_identity(session, _ident); ::update_identity(session(), _ident);
} }
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
@ -38,7 +39,7 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_trustwords(
else else
lang = "en"; 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) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
return NULL; return NULL;
@ -53,10 +54,9 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_myself(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
::myself(session, _ident); ::myself(session(), _ident);
return from_identity(env, _ident); return from_identity(env, _ident);
} }
@ -67,10 +67,9 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_updateIdentity(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
::update_identity(session, _ident); ::update_identity(session(), _ident);
return from_identity(env, _ident); return from_identity(env, _ident);
} }
@ -82,11 +81,10 @@ JNIEXPORT jobject JNICALL Java_org_pEp_jniadapter_Engine_setOwnKey(
jbyteArray fpr jbyteArray fpr
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
char *_fpr = to_string(env, fpr); char *_fpr = to_string(env, fpr);
::set_own_key(session, _ident, _fpr); ::set_own_key(session(), _ident, _fpr);
return from_identity(env, _ident); return from_identity(env, _ident);
} }
@ -97,11 +95,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyMistrusted(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
::update_identity(session, _ident); ::update_identity(session(), _ident);
} }
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
@ -109,7 +106,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyMistrusted(
return; return;
} }
::key_mistrusted(session, _ident); ::key_mistrusted(session(), _ident);
} }
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust( JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust(
@ -118,11 +115,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
::update_identity(session, _ident); ::update_identity(session(), _ident);
} }
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
@ -130,7 +126,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyResetTrust(
return; return;
} }
::key_reset_trust(session, _ident); ::key_reset_trust(session(), _ident);
} }
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey( JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey(
@ -139,11 +135,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
::update_identity(session, _ident); ::update_identity(session(), _ident);
} }
if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
@ -151,7 +146,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_trustPersonalKey(
return; return;
} }
::trust_personal_key(session, _ident); ::trust_personal_key(session(), _ident);
} }
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey( JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey(
@ -160,7 +155,6 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey(
jbyteArray key jbyteArray key
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
char *_key = to_string(env, key); char *_key = to_string(env, key);
if(_key == NULL){ 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) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
return; return;
@ -183,9 +177,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_config_1passive_1mode(
jboolean enable 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 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( 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 jbyteArray fpr
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
char *_fpr = to_string(env, fpr); char *_fpr = to_string(env, fpr);
if(_fpr == NULL){ if(_fpr == NULL){
@ -214,7 +203,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1add(
return; return;
} }
PEP_STATUS status = ::blacklist_add(session, _fpr); PEP_STATUS status = ::blacklist_add(session(), _fpr);
if (status != PEP_STATUS_OK) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
return; return;
@ -228,7 +217,6 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1delete(
jbyteArray fpr jbyteArray fpr
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
char *_fpr = to_string(env, fpr); char *_fpr = to_string(env, fpr);
if(_fpr == NULL){ if(_fpr == NULL){
@ -236,7 +224,7 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1delete(
return; return;
} }
PEP_STATUS status = ::blacklist_delete(session, _fpr); PEP_STATUS status = ::blacklist_delete(session(), _fpr);
if (status != PEP_STATUS_OK) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
return; return;
@ -250,7 +238,6 @@ JNIEXPORT jboolean JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1is_1listed(
jbyteArray fpr jbyteArray fpr
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
char *_fpr = to_string(env, fpr); char *_fpr = to_string(env, fpr);
bool _listed = 0; bool _listed = 0;
@ -259,7 +246,7 @@ JNIEXPORT jboolean JNICALL Java_org_pEp_jniadapter_Engine_blacklist_1is_1listed(
return 0; 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) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
return 0; 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_identity *_ident = to_identity(env, ident);
PEP_STATUS status = PEP_STATUS status =
::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_ACCEPTED); ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_ACCEPTED);
if (status != PEP_STATUS_OK) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
@ -294,11 +280,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_reject_1sync_1handshake(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
PEP_STATUS status = PEP_STATUS status =
::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_REJECTED); ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_REJECTED);
if (status != PEP_STATUS_OK) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
@ -312,11 +297,10 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_cancel_1sync_1handshake(
jobject ident jobject ident
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
pEp_identity *_ident = to_identity(env, ident); pEp_identity *_ident = to_identity(env, ident);
PEP_STATUS status = PEP_STATUS status =
::deliverHandshakeResult(session, _ident, SYNC_HANDSHAKE_CANCEL); ::deliverHandshakeResult(session(), _ident, SYNC_HANDSHAKE_CANCEL);
if (status != PEP_STATUS_OK) { if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status); throw_pEp_Exception(env, status);
@ -331,12 +315,10 @@ JNIEXPORT jbyteArray JNICALL Java_org_pEp_jniadapter_Engine_getCrashdumpLog(
jint maxlines jint maxlines
) )
{ {
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
int _maxlines = (int) maxlines; int _maxlines = (int) maxlines;
char *_logdata; 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) || if ((status > PEP_STATUS_OK && status < PEP_UNENCRYPTED) ||
status < PEP_STATUS_OK || status < PEP_STATUS_OK ||
status >= PEP_TRUSTWORD_NOT_FOUND) { status >= PEP_TRUSTWORD_NOT_FOUND) {

87
src/jniutils.hh

@ -18,93 +18,6 @@
#endif #endif
namespace pEp { 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 { namespace JNIAdapter {
jclass findClass(JNIEnv *env, const char *classname); jclass findClass(JNIEnv *env, const char *classname);

506
src/org_pEp_jniadapter_AbstractEngine.cc

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

86
src/pEp.yml2

@ -8,51 +8,52 @@ decl basic @type @name;
namespace pEp { namespace pEp {
exception Status { exception Status {
pEp_status_ok > 0 pEp_status_ok > 0
pEp_init_cannot_load_gpgme > 0x0110 pEp_init_cannot_load_gpgme > 0x0110
pEp_init_gpgme_init_failed > 0x0111 pEp_init_gpgme_init_failed > 0x0111
pEp_init_no_gpg_home > 0x0112 pEp_init_no_gpg_home > 0x0112
pEp_init_netpgp_init_failed > 0x0113 pEp_init_netpgp_init_failed > 0x0113
pEp_init_cannot_determine_gpg_version > 0x0114 pEp_init_cannot_determine_gpg_version > 0x0114
pEp_init_unsupported_gpg_version > 0x0115 pEp_init_unsupported_gpg_version > 0x0115
pEp_init_cannot_config_gpg_agent > 0x0116 pEp_init_cannot_config_gpg_agent > 0x0116
pEp_init_sqlite3_without_mutex > 0x0120 pEp_init_sqlite3_without_mutex > 0x0120
pEp_init_cannot_open_db > 0x0121 pEp_init_cannot_open_db > 0x0121
pEp_init_cannot_open_system_db > 0x0122 pEp_init_cannot_open_system_db > 0x0122
pEp_key_not_found > 0x0201 pEp_key_not_found > 0x0201
pEp_key_has_ambig_name > 0x0202 pEp_key_has_ambig_name > 0x0202
pEp_get_key_failed > 0x0203 pEp_get_key_failed > 0x0203
pEp_cannot_export_key > 0x0204 pEp_cannot_export_key > 0x0204
pEp_cannot_edit_key > 0x0205 pEp_cannot_edit_key > 0x0205
pEp_key_unsuitable > 0x0206 pEp_key_unsuitable > 0x0206
pEp_cannot_find_identity > 0x0301 pEp_cannot_find_identity > 0x0301
pEp_cannot_set_person > 0x0381 pEp_cannot_set_person > 0x0381
pEp_cannot_set_pgp_keypair > 0x0382 pEp_cannot_set_pgp_keypair > 0x0382
pEp_cannot_set_identity > 0x0383 pEp_cannot_set_identity > 0x0383
pEp_cannot_set_trust > 0x0384 pEp_cannot_set_trust > 0x0384
pEp_key_blacklisted > 0x0385 pEp_key_blacklisted > 0x0385
pEp_cannot_find_person > 0x0386 pEp_cannot_find_person > 0x0386
pEp_cannot_find_alias > 0x0391 pEp_cannot_find_alias > 0x0391
pEp_cannot_set_alias > 0x0392 pEp_cannot_set_alias > 0x0392
pEp_unencrypted > 0x0400 pEp_unencrypted > 0x0400
pEp_verified > 0x0401 pEp_verified > 0x0401
pEp_decrypted > 0x0402 pEp_decrypted > 0x0402
pEp_decrypted_and_verified > 0x0403 pEp_decrypted_and_verified > 0x0403
pEp_decrypt_wrong_format > 0x0404 pEp_decrypt_wrong_format > 0x0404
pEp_decrypt_no_key > 0x0405 pEp_decrypt_no_key > 0x0405
pEp_decrypt_signature_does_not_match > 0x0406 pEp_decrypt_signature_does_not_match > 0x0406
pEp_verify_no_key > 0x0407 pEp_verify_no_key > 0x0407
pEp_verified_and_trusted > 0x0408 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_trustword_not_found > 0x0501
pEp_trustwords_fpr_wrong_length > 0x0502 pEp_trustwords_fpr_wrong_length > 0x0502
pEp_trustwords_duplicate_fpr > 0x0503 pEp_trustwords_duplicate_fpr > 0x0503
pEp_cannot_create_key > 0x0601 pEp_cannot_create_key > 0x0601
@ -60,40 +61,37 @@ namespace pEp {
pEp_phrase_not_found > 0x0701 pEp_phrase_not_found > 0x0701
pEp_send_function_not_registered                > 0x0801 pEp_send_function_not_registered > 0x0801
pEp_contraints_violated                         > 0x0802 pEp_contraints_violated > 0x0802
pEp_cannot_encode                               > 0x0803 pEp_cannot_encode > 0x0803
pEp_sync_no_notify_callback                  > 0x0901 pEp_sync_no_notify_callback > 0x0901
pEp_sync_illegal_message                        > 0x0902 pEp_sync_illegal_message > 0x0902
pEp_sync_no_inject_callback                     > 0x0903 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_increase_sequence > 0x0971
pEp_cannot_set_sequence_value > 0x0972
pEp_own_sequence > 0x097f
pEp_sync_statemachine_error > 0x0980 pEp_statemachine_error > 0x0980
pEp_sync_no_trust > 0x0981 pEp_no_trust > 0x0981
pEp_statemachine_invalid_state > 0x0982 pEp_statemachine_invalid_state > 0x0982
pEp_statemachine_invalid_event > 0x0983 pEp_statemachine_invalid_event > 0x0983
pEp_statemachine_invalid_condition > 0x0984 pEp_statemachine_invalid_condition > 0x0984
pEp_statemachine_invalid_action > 0x0985 pEp_statemachine_invalid_action > 0x0985
pEp_statemachine_inhibited_event > 0x0986 pEp_statemachine_inhibited_event > 0x0986
pEp_commit_failed > 0xff01 pEp_commit_failed > 0xff01
pEp_message_consume > 0xff02 pEp_message_consume > 0xff02
pEp_message_ignore > 0xff03 pEp_message_ignore > 0xff03
pEp_record_not_found > -6 pEp_record_not_found > -6
pEp_cannot_create_temp_file > -5 pEp_cannot_create_temp_file > -5
pEp_illegal_value > -4 pEp_illegal_value > -4
pEp_buffer_too_small > -3 pEp_buffer_too_small > -3
pEp_out_of_memory > -2 pEp_out_of_memory > -2
pEp_unknown_error > -1 pEp_unknown_error > -1
pEp_version_mismatch > -7 pEp_version_mismatch > -7
}; };

Loading…
Cancel
Save