diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java index 1b83797..4e78492 100644 --- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java +++ b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java @@ -1011,4 +1011,75 @@ public class OlmSessionTest { assertTrue(bobSession.isReleased()); } + @Test + public void test07AliceBobSessionDescribe() { + // creates alice & bob accounts + OlmAccount aliceAccount = null; + OlmAccount bobAccount = null; + try { + aliceAccount = new OlmAccount(); + bobAccount = new OlmAccount(); + } catch (OlmException e) { + fail(e.getMessage()); + } + + // test accounts creation + assertTrue(0 != bobAccount.getOlmAccountId()); + assertTrue(0 != aliceAccount.getOlmAccountId()); + + // CREATE ALICE SESSION + + OlmSession aliceSession = null; + try { + aliceSession = new OlmSession(); + } catch (OlmException e) { + fail("Exception Msg=" + e.getMessage()); + } + assertTrue(0 != aliceSession.getOlmSessionId()); + + // CREATE ALICE SESSION + OlmSession bobSession = null; + try { + bobSession = new OlmSession(); + } catch (OlmException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + assertTrue(0 != bobSession.getOlmSessionId()); + + String aliceSessionDescribe = null; + try { + aliceSessionDescribe = aliceSession.sessionDescribe(); + } catch (Exception e) { + fail(e.getMessage()); + } + + assertNotNull(aliceSessionDescribe); + + String bobSessionDescribe = null; + try { + bobSessionDescribe = bobSession.sessionDescribe(); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(bobSessionDescribe); + + // must be the same for both ends of the conversation + assertEquals(aliceSessionDescribe, bobSessionDescribe); + + assertEquals( + "sender chain index: 0 receiver chain indices: skipped message keys:", + aliceSessionDescribe + ); + + aliceAccount.releaseAccount(); + bobAccount.releaseAccount(); + assertTrue(aliceAccount.isReleased()); + assertTrue(bobAccount.isReleased()); + + bobSession.releaseSession(); + aliceSession.releaseSession(); + assertTrue(bobSession.isReleased()); + assertTrue(aliceSession.isReleased()); + } } diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java index 26da005..51bbfbc 100644 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java +++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java @@ -60,6 +60,7 @@ public class OlmException extends IOException { public static final int EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE = 404; public static final int EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE = 405; public static final int EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER = 406; + public static final int EXCEPTION_CODE_SESSION_SESSION_DESCRIBE = 407; public static final int EXCEPTION_CODE_UTILITY_CREATION = 500; public static final int EXCEPTION_CODE_UTILITY_VERIFY_SIGNATURE = 501; diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java index 3c5ce49..5669ba1 100644 --- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java +++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java @@ -223,6 +223,23 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { */ private native byte[] getSessionIdentifierJni(); + public String sessionDescribe() throws OlmException { + try { + byte[] buffer = olmSessionDescribeJni(); + + if (null != buffer) { + return new String(buffer, "UTF-8"); + } + } catch (Exception e) { + Log.e(LOG_TAG, "## sessionDescribe(): " + e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_SESSION_DESCRIBE, e.getMessage()); + } + + return null; + } + + private native byte[] olmSessionDescribeJni(); + /** * Checks if the PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message is for this in-bound session.
* This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). diff --git a/android/olm-sdk/src/main/jni/olm_session.cpp b/android/olm-sdk/src/main/jni/olm_session.cpp index 15ad4fe..fe2ab31 100644 --- a/android/olm-sdk/src/main/jni/olm_session.cpp +++ b/android/olm-sdk/src/main/jni/olm_session.cpp @@ -798,6 +798,58 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, return returnValue; } +JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(olmSessionDescribeJni(JNIEnv *env, jobject thiz)) +{ + const char* errorMessage = NULL; + jbyteArray returnValue = 0; + + LOGD("## olmSessionDescribeJni(): IN "); + + OlmSession *sessionPtr = getSessionInstanceId(env, thiz); + + if (!sessionPtr) + { + LOGE("## olmSessionDescribeJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; + } + else + { + int maxLength = 600; + char* describePtr = NULL; + describePtr = (char*) malloc(maxLength * sizeof *describePtr); + if (!describePtr) + { + LOGE("## olmSessionDescribeJni(): failure - describe allocation OOM"); + errorMessage = "describe allocation OOM"; + } + else + { + olm_session_describe(sessionPtr, describePtr, maxLength); + int length = strlen(describePtr); + if (length == 0) + { + LOGE("## olmSessionDescribeJni(): failure - get session describe"); + } + else + { + LOGD("## olmSessionDescribeJni(): success - describe=%.*s", (char*)describePtr); + + returnValue = env->NewByteArray(length); + env->SetByteArrayRegion(returnValue, 0, length, (jbyte*)describePtr); + } + + free(describePtr); + } + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + + return returnValue; +} + /** * Serialize and encrypt session instance.
* An exception is thrown if the operation fails. diff --git a/android/olm-sdk/src/main/jni/olm_session.h b/android/olm-sdk/src/main/jni/olm_session.h index 534e830..0f3e7f7 100644 --- a/android/olm-sdk/src/main/jni/olm_session.h +++ b/android/olm-sdk/src/main/jni/olm_session.h @@ -47,6 +47,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobjec JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz); +JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(olmSessionDescribeJni)(JNIEnv *env, jobject thiz); // serialization JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey);