refactor: [3/n] Use userdata member in euicc_ctx

This commit is contained in:
Peter Cai 2023-11-18 18:42:59 -05:00
parent 013fe157eb
commit 2707a5f1f8
7 changed files with 45 additions and 74 deletions

View file

@ -2,5 +2,6 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/libs/lpac-jni/src/main/jni/lpac" vcs="Git" />
</component>
</project>

View file

@ -7,5 +7,4 @@ private object LpacJni {
external fun createContext(apduInterface: ApduInterface, httpInterface: HttpInterface): Long
external fun destroyContext(handle: Long)
external fun setCurrentContext(handle: Long)
}

@ -1 +1 @@
Subproject commit 2eaefa6f8d79f68eff6a8c03932b861425767330
Subproject commit c29f1d40f131d955b4867e230da5539ea7cc6149

View file

@ -1,7 +1,6 @@
#include <string.h>
#include <malloc.h>
#include "interface-wrapper.h"
#include "lpac-jni.h"
jmethodID method_apdu_connect;
jmethodID method_apdu_disconnect;
@ -32,86 +31,73 @@ void interface_wrapper_init() {
field_resp_data = (*env)->GetFieldID(env, resp_class, "data", "[B");
}
static int apdu_interface_connect(void) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static int apdu_interface_connect(struct euicc_ctx *ctx) {
LPAC_JNI_SETUP_ENV;
(*env)->CallVoidMethod(env, jni_ctx->apdu_interface, method_apdu_connect);
LPAC_JNI_END(!((*env)->ExceptionCheck(env) == JNI_FALSE));
(*env)->CallVoidMethod(env, LPAC_JNI_CTX(ctx)->apdu_interface, method_apdu_connect);
return (*env)->ExceptionCheck(env) != JNI_FALSE;
}
static void apdu_interface_disconnect(void) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static void apdu_interface_disconnect(struct euicc_ctx *ctx) {
LPAC_JNI_SETUP_ENV;
(*env)->CallVoidMethod(env, jni_ctx->apdu_interface, method_apdu_disconnect);
LPAC_JNI_END0;
(*env)->CallVoidMethod(env, LPAC_JNI_CTX(ctx)->apdu_interface, method_apdu_disconnect);
}
static int apdu_interface_logical_channel_open(const uint8_t *aid, uint8_t aid_len) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static int apdu_interface_logical_channel_open(struct euicc_ctx *ctx, const uint8_t *aid, uint8_t aid_len) {
LPAC_JNI_SETUP_ENV;
jbyteArray jbarr = (*env)->NewByteArray(env, aid_len);
(*env)->SetByteArrayRegion(env, jbarr, 0, aid_len, (const jbyte *) aid);
jint ret = (*env)->CallIntMethod(env, jni_ctx->apdu_interface, method_apdu_logical_channel_open, jbarr);
jint ret = (*env)->CallIntMethod(env, LPAC_JNI_CTX(ctx)->apdu_interface, method_apdu_logical_channel_open, jbarr);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
LPAC_JNI_END(-1);
return -1;
} else {
LPAC_JNI_END(ret);
return ret;
}
}
static void apdu_interface_logical_channel_close(uint8_t channel) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static void apdu_interface_logical_channel_close(struct euicc_ctx *ctx, uint8_t channel) {
LPAC_JNI_SETUP_ENV;
(*env)->CallVoidMethod(env, jni_ctx->apdu_interface, method_apdu_logical_channel_close, channel);
LPAC_JNI_END0;
(*env)->CallVoidMethod(env, LPAC_JNI_CTX(ctx)->apdu_interface, method_apdu_logical_channel_close, channel);
}
static int apdu_interface_transmit(uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len) {
LPAC_JNI_SETUP_ENV;
jbyteArray txArr = (*env)->NewByteArray(env, tx_len);
(*env)->SetByteArrayRegion(env, txArr, 0, tx_len, (const jbyte *) tx);
jbyteArray ret = (jbyteArray) (*env)->CallObjectMethod(env, jni_ctx->apdu_interface, method_apdu_transmit, txArr);
jbyteArray ret = (jbyteArray) (*env)->CallObjectMethod(env, LPAC_JNI_CTX(ctx)->apdu_interface, method_apdu_transmit, txArr);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
LPAC_JNI_END(-1);
return -1;
}
*rx_len = (*env)->GetArrayLength(env, ret);
*rx = malloc(*rx_len * sizeof(uint8_t));
(*env)->GetByteArrayRegion(env, ret, 0, *rx_len, *rx);
LPAC_JNI_END(0);
return 0;
}
static int http_interface_transmit(const char *url, uint32_t *rcode, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len) {
LPAC_JNI_BEGIN;
LPAC_JNI_ASSERT_CTX;
static int http_interface_transmit(struct euicc_ctx *ctx, const char *url, uint32_t *rcode, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len) {
LPAC_JNI_SETUP_ENV;
jstring jurl = (*env)->NewString(env, url, strlen(url));
jbyteArray txArr = (*env)->NewByteArray(env, tx_len);
(*env)->SetByteArrayRegion(env, txArr, 0, tx_len, (const jbyte *) tx);
jobject ret = (*env)->CallObjectMethod(env, jni_ctx->http_interface, method_http_transmit, jurl, txArr);
jobject ret = (*env)->CallObjectMethod(env, LPAC_JNI_CTX(ctx)->http_interface, method_http_transmit, jurl, txArr);
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
LPAC_JNI_END(-1);
return -1;
}
*rcode = (*env)->GetIntField(env, ret, field_resp_rcode);
jbyteArray rxArr = (jbyteArray) (*env)->GetObjectField(env, ret, field_resp_data);
*rx_len = (*env)->GetArrayLength(env, rxArr);
*rx = malloc(*rx_len * sizeof(uint8_t));
(*env)->GetByteArrayRegion(env, rxArr, 0, *rx_len, *rx);
LPAC_JNI_END(0);
return 0;
}
struct euicc_apdu_interface apdu_interface_wrapper = {
.connect = apdu_interface_connect,
.disconnect = apdu_interface_disconnect,
.logic_channel_open = apdu_interface_logical_channel_open,
.logic_channel_close = apdu_interface_logical_channel_close,
.transmit = apdu_interface_transmit
struct euicc_apdu_interface lpac_jni_apdu_interface = {
.connect = &apdu_interface_connect,
.disconnect = &apdu_interface_disconnect,
.logic_channel_open = &apdu_interface_logical_channel_open,
.logic_channel_close = &apdu_interface_logical_channel_close,
.transmit = &apdu_interface_transmit
};
struct euicc_http_interface http_interface_wrapper = {
.transmit = http_interface_transmit
struct euicc_http_interface lpac_jni_http_interface = {
.transmit = &http_interface_transmit
};

View file

@ -2,13 +2,13 @@
#undef NDEBUG
#include <assert.h>
#include <euicc/interface.h>
extern struct euicc_apdu_interface apdu_interface_wrapper;
extern struct euicc_http_interface http_interface_wrapper;
#include "lpac-jni.h"
void interface_wrapper_init();
#define LPAC_JNI_ASSERT_CTX assert(jni_ctx != NULL)
extern struct euicc_apdu_interface lpac_jni_apdu_interface;
extern struct euicc_http_interface lpac_jni_http_interface;
#define LPAC_JNI_SETUP_ENV \
JNIEnv *env; \
(*jvm)->AttachCurrentThread(jvm, &env, NULL)

View file

@ -4,8 +4,6 @@
#include "lpac-jni.h"
#include "interface-wrapper.h"
pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
struct lpac_jni_ctx *jni_ctx = NULL;
JavaVM *jvm = NULL;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
@ -18,32 +16,24 @@ JNIEXPORT jlong JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_createContext(JNIEnv *env, jobject thiz,
jobject apdu_interface,
jobject http_interface) {
LPAC_JNI_BEGIN;
struct euicc_ctx *ctx = malloc(sizeof(struct euicc_ctx));
struct lpac_jni_ctx *_ctx = malloc(sizeof(struct lpac_jni_ctx));
memset(ctx, 0, sizeof(struct lpac_jni_ctx));
memset(_ctx, 0, sizeof(struct lpac_jni_ctx));
_ctx->ctx.interface.apdu = &apdu_interface_wrapper;
_ctx->ctx.interface.http = &http_interface_wrapper;
ctx->interface.apdu = &lpac_jni_apdu_interface;
ctx->interface.http = &lpac_jni_apdu_interface;
_ctx->apdu_interface = (*env)->NewGlobalRef(env, apdu_interface);
_ctx->http_interface = (*env)->NewGlobalRef(env, http_interface);
LPAC_JNI_END((jlong) _ctx);
ctx->userdata = (void *) _ctx;
return (jlong) ctx;
}
JNIEXPORT void JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_destroyContext(JNIEnv *env, jobject thiz, jlong handle) {
LPAC_JNI_BEGIN;
struct lpac_jni_ctx *_ctx = (struct lpac_jni_ctx *) handle;
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct lpac_jni_ctx *_ctx = LPAC_JNI_CTX(ctx);
(*env)->DeleteGlobalRef(env, _ctx->apdu_interface);
(*env)->DeleteGlobalRef(env, _ctx->http_interface);
if (jni_ctx == _ctx) {
jni_ctx = NULL;
}
free(_ctx);
LPAC_JNI_END0;
}
JNIEXPORT void JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_setCurrentContext(JNIEnv *env, jobject thiz, jlong handle) {
LPAC_JNI_BEGIN;
jni_ctx = (struct lpac_jni_ctx *) handle;
LPAC_JNI_END0;
free(ctx);
}

View file

@ -4,15 +4,10 @@
#include <jni.h>
struct lpac_jni_ctx {
struct euicc_ctx ctx;
jobject apdu_interface;
jobject http_interface;
};
extern JavaVM *jvm;
extern pthread_mutex_t global_lock;
extern struct lpac_jni_ctx *jni_ctx;
#define LPAC_JNI_CTX(ctx) ((struct lpac_jni_ctx *) ctx->userdata)
#define LPAC_JNI_BEGIN pthread_mutex_lock(&global_lock)
#define LPAC_JNI_END0 pthread_mutex_unlock(&global_lock)
#define LPAC_JNI_END(ret) LPAC_JNI_END0; return ret
extern JavaVM *jvm;