Browse Source

refactor: lpac-jni: Move EuiccInfo2 handling to Kotlin too

Peter Cai 1 year ago
parent
commit
bf36188219

+ 16 - 1
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt

@@ -31,9 +31,12 @@ internal object LpacJni {
     external fun handleNotification(handle: Long, seqNumber: Long): Int
 
     // es10cex (actually part of es10b)
-    external fun es10cexGetEuiccInfo2(handle: Long): EuiccInfo2?
+    external fun es10cexGetEuiccInfo2(handle: Long): Long
 
     // C <-> Java struct / linked list handling
+    // C String arrays
+    external fun stringArrNext(curr: Long): Long
+    external fun stringDeref(curr: Long): String
     // Profiles
     external fun profilesNext(curr: Long): Long
     external fun profilesFree(head: Long): Long
@@ -51,4 +54,16 @@ internal object LpacJni {
     external fun notificationGetAddress(curr: Long): String
     external fun notificationGetIccid(curr: Long): String
     external fun notificationsFree(head: Long)
+    // EuiccInfo2
+    external fun euiccInfo2Free(info: Long)
+    external fun euiccInfo2GetProfileVersion(info: Long): String
+    external fun euiccInfo2GetEuiccFirmwareVersion(info: Long): String
+    external fun euiccInfo2GetGlobalPlatformVersion(info: Long): String
+    external fun euiccInfo2GetSasAcreditationNumber(info: Long): String
+    external fun euiccInfo2GetPpVersion(info: Long): String
+    external fun euiccInfo2GetFreeNonVolatileMemory(info: Long): Long
+    external fun euiccInfo2GetFreeVolatileMemory(info: Long): Long
+    // C String Arrays
+    external fun euiccInfo2GetEuiccCiPKIdListForSigning(info: Long): Long
+    external fun euiccInfo2GetEuiccCiPKIdListForVerification(info: Long): Long
 }

+ 30 - 1
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt

@@ -87,7 +87,36 @@ class LocalProfileAssistantImpl(
         get() = LpacJni.es10cGetEid(contextHandle)!!
 
     override val euiccInfo2: EuiccInfo2?
-        get() = LpacJni.es10cexGetEuiccInfo2(contextHandle)
+        get() {
+            val cInfo = LpacJni.es10cexGetEuiccInfo2(contextHandle)
+            if (cInfo == 0L) return null
+
+            val euiccCiPKIdListForSigning = mutableListOf<String>()
+            var curr = LpacJni.euiccInfo2GetEuiccCiPKIdListForSigning(cInfo)
+            while (curr != 0L) {
+                euiccCiPKIdListForSigning.add(LpacJni.stringDeref(curr))
+                curr = LpacJni.stringArrNext(curr)
+            }
+
+            val euiccCiPKIdListForVerification = mutableListOf<String>()
+            curr = LpacJni.euiccInfo2GetEuiccCiPKIdListForVerification(cInfo)
+            while (curr != 0L) {
+                euiccCiPKIdListForVerification.add(LpacJni.stringDeref(curr))
+                curr = LpacJni.stringArrNext(curr)
+            }
+
+            return EuiccInfo2(
+                LpacJni.euiccInfo2GetProfileVersion(cInfo),
+                LpacJni.euiccInfo2GetEuiccFirmwareVersion(cInfo),
+                LpacJni.euiccInfo2GetGlobalPlatformVersion(cInfo),
+                LpacJni.euiccInfo2GetSasAcreditationNumber(cInfo),
+                LpacJni.euiccInfo2GetPpVersion(cInfo),
+                LpacJni.euiccInfo2GetFreeNonVolatileMemory(cInfo).toInt(),
+                LpacJni.euiccInfo2GetFreeVolatileMemory(cInfo).toInt(),
+                euiccCiPKIdListForSigning.toTypedArray(),
+                euiccCiPKIdListForVerification.toTypedArray()
+            )
+        }
 
     override fun enableProfile(iccid: String, refresh: Boolean): Boolean =
         LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0

+ 33 - 61
libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c

@@ -17,9 +17,6 @@ jstring empty_string;
 jclass string_class;
 jmethodID string_constructor;
 
-jclass euicc_info2_class;
-jmethodID euicc_info2_constructor;
-
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     jvm = vm;
     interface_wrapper_init();
@@ -31,11 +28,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
                                              "([BLjava/lang/String;)V");
 
-    euicc_info2_class = (*env)->FindClass(env, "net/typeblog/lpac_jni/EuiccInfo2");
-    euicc_info2_class = (*env)->NewGlobalRef(env, euicc_info2_class);
-    euicc_info2_constructor = (*env)->GetMethodID(env, euicc_info2_class, "<init>",
-                                                  "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II[Ljava/lang/String;[Ljava/lang/String;)V");
-
     const char _unused[1];
     empty_string = (*env)->NewString(env, _unused, 0);
     empty_string = (*env)->NewGlobalRef(env, empty_string);
@@ -233,58 +225,38 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cDeleteProfile(JNIEnv *env, jobject thiz
     return ret;
 }
 
-JNIEXPORT jobject JNICALL
+JNIEXPORT jlong JNICALL
 Java_net_typeblog_lpac_1jni_LpacJni_es10cexGetEuiccInfo2(JNIEnv *env, jobject thiz, jlong handle) {
     struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
-    struct es10c_ex_euiccinfo2 info = {0};
-    jobjectArray euiccCiPKIdListForVerification = NULL;
-    jobjectArray euiccCiPKIdListForSigning = NULL;
-    jstring sas_accreditation_number = NULL;
-    jstring global_platform_version = NULL;
-    jstring euicc_firmware_version = NULL;
-    jstring profile_version = NULL;
-    jstring pp_version = NULL;
-    jobject ret = NULL;
-    char **curr = NULL;
-    int count = 0;
-
-    if (es10c_ex_get_euiccinfo2(ctx, &info) < 0)
-        goto out;
-
-    profile_version = toJString(env, info.profileVersion);
-    euicc_firmware_version = toJString(env, info.euiccFirmwareVer);
-    global_platform_version = toJString(env, info.globalplatformVersion);
-    sas_accreditation_number = toJString(env, info.sasAcreditationNumber);
-    pp_version = toJString(env, info.ppVersion);
-
-    count = LPAC_JNI_NULL_TERM_LIST_COUNT(info.euiccCiPKIdListForSigning, curr);
-    euiccCiPKIdListForSigning = (*env)->NewObjectArray(env, count, string_class, NULL);
-    LPAC_JNI_NULL_TERM_LIST_FOREACH(info.euiccCiPKIdListForSigning, curr, {
-        (*env)->SetObjectArrayElement(env, euiccCiPKIdListForSigning, i, toJString(env, *curr));
-    });
-
-    count = LPAC_JNI_NULL_TERM_LIST_COUNT(info.euiccCiPKIdListForVerification, curr);
-    euiccCiPKIdListForVerification = (*env)->NewObjectArray(env, count, string_class, NULL);
-    LPAC_JNI_NULL_TERM_LIST_FOREACH(info.euiccCiPKIdListForVerification, curr, {
-        (*env)->SetObjectArrayElement(env, euiccCiPKIdListForVerification, i,
-                                      toJString(env, *curr));
-    });
-
-    ret = (*env)->NewObject(env, euicc_info2_class, euicc_info2_constructor,
-                            profile_version, euicc_firmware_version,
-                            global_platform_version,
-                            sas_accreditation_number, pp_version,
-                            info.extCardResource.freeNonVolatileMemory,
-                            info.extCardResource.freeVolatileMemory,
-                            euiccCiPKIdListForSigning,
-                            euiccCiPKIdListForVerification);
-
-    out:
-    (*env)->DeleteLocalRef(env, profile_version);
-    (*env)->DeleteLocalRef(env, euicc_firmware_version);
-    (*env)->DeleteLocalRef(env, global_platform_version);
-    (*env)->DeleteLocalRef(env, sas_accreditation_number);
-    (*env)->DeleteLocalRef(env, pp_version);
-    es10c_ex_euiccinfo2_free(&info);
-    return ret;
-}
+    struct es10c_ex_euiccinfo2 *info = malloc(sizeof(struct es10c_ex_euiccinfo2));
+
+    if (es10c_ex_get_euiccinfo2(ctx, info) < 0) {
+        free(info);
+        return 0;
+    }
+
+    return (jlong) info;
+}
+
+JNIEXPORT jstring JNICALL
+Java_net_typeblog_lpac_1jni_LpacJni_stringDeref(JNIEnv *env, jobject thiz, jlong curr) {
+    return toJString(env, *((char **) curr));
+}
+
+void lpac_jni_euiccinfo2_free(struct es10c_ex_euiccinfo2 *info) {
+    es10c_ex_euiccinfo2_free(info);
+    free(info);
+}
+
+LPAC_JNI_STRUCT_GETTER_NULL_TERM_LIST_NEXT(char*, stringArr)
+LPAC_JNI_STRUCT_FREE(struct es10c_ex_euiccinfo2, euiccInfo2, lpac_jni_euiccinfo2_free)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_ex_euiccinfo2, euiccInfo2, profileVersion, ProfileVersion)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_ex_euiccinfo2, euiccInfo2, euiccFirmwareVer, EuiccFirmwareVersion)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_ex_euiccinfo2, euiccInfo2, globalplatformVersion, GlobalPlatformVersion)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_ex_euiccinfo2, euiccInfo2, sasAcreditationNumber, SasAcreditationNumber)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_ex_euiccinfo2, euiccInfo2, ppVersion, PpVersion)
+LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, extCardResource.freeNonVolatileMemory, FreeNonVolatileMemory)
+LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, extCardResource.freeVolatileMemory, FreeVolatileMemory)
+
+LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, euiccCiPKIdListForSigning, EuiccCiPKIdListForSigning)
+LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, euiccCiPKIdListForVerification, EuiccCiPKIdListForVerification)

+ 8 - 30
libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h

@@ -17,36 +17,6 @@ struct lpac_jni_ctx {
     JNIEnv *env; \
     (*jvm)->AttachCurrentThread(jvm, &env, NULL)
 
-#define __LPAC_JNI_LINKED_LIST_FOREACH(list, curr, body, after) { \
-    int i = 0;                                                    \
-    curr = list;                                                  \
-    while (curr != NULL) {                                        \
-        body;                                                     \
-        curr = curr->next;                                        \
-        i++;                                                      \
-    };                                                             \
-    after;                                                        \
-}
-#define LPAC_JNI_LINKED_LIST_FOREACH(list, curr, body) \
-    __LPAC_JNI_LINKED_LIST_FOREACH(list, curr, body, {})
-#define LPAC_JNI_LINKED_LIST_COUNT(list, curr) \
-    (__LPAC_JNI_LINKED_LIST_FOREACH(list, curr, {}, i))
-
-#define __LPAC_JNI_NULL_TERM_LIST_FOREACH(list, curr, body, after) { \
-    int i = 0;                                                       \
-    curr = list;                                                     \
-    while (*curr != NULL) {                                           \
-        body;                                                        \
-        curr++;                                                      \
-        i++;                                                         \
-    };                                                               \
-    after;                                                           \
-}
-#define LPAC_JNI_NULL_TERM_LIST_FOREACH(list, curr, body) \
-    __LPAC_JNI_NULL_TERM_LIST_FOREACH(list, curr, body, {})
-#define LPAC_JNI_NULL_TERM_LIST_COUNT(list, curr) \
-    (__LPAC_JNI_NULL_TERM_LIST_FOREACH(list, curr, {}, i))
-
 extern JavaVM *jvm;
 extern jclass string_class;
 
@@ -59,6 +29,14 @@ jstring toJString(JNIEnv *env, const char *pat);
             return (jlong) p->next;                   \
         }
 
+#define LPAC_JNI_STRUCT_GETTER_NULL_TERM_LIST_NEXT(st, st_jname) \
+        JNIEXPORT jlong JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_jname##Next(JNIEnv *env, jobject thiz, jlong raw) { \
+            st *p = (st *) raw;                     \
+            p++;                                      \
+            if (*p == NULL) return 0;                 \
+            return (jlong) p;                         \
+        }
+
 #define LPAC_JNI_STRUCT_FREE(st, st_jname, free_func) \
         JNIEXPORT void JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_jname##Free(JNIEnv *env, jobject thiz, jlong raw) { \
             st *p = (st *) raw;                       \