diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..913d49d
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 163d6b4..589fc6c 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,11 +4,20 @@
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app-deps/build.gradle.kts b/app-deps/build.gradle.kts
index 2111436..6cde72d 100644
--- a/app-deps/build.gradle.kts
+++ b/app-deps/build.gradle.kts
@@ -13,7 +13,7 @@ apply {
android {
namespace = "im.angry.openeuicc_deps"
- compileSdk = 33
+ compileSdk = 34
defaultConfig {
minSdk = 28
diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts
index b50a953..7f45177 100644
--- a/libs/lpac-jni/build.gradle.kts
+++ b/libs/lpac-jni/build.gradle.kts
@@ -5,7 +5,7 @@ plugins {
android {
namespace = "net.typeblog.lpac_jni"
- compileSdk = 33
+ compileSdk = 34
ndkVersion = "26.1.10909125"
defaultConfig {
diff --git a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt
index 37406a7..d4ea8b2 100644
--- a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt
+++ b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt
@@ -14,7 +14,7 @@ internal object LpacJni {
// es10c
// null returns signify errors
external fun es10cGetEid(handle: Long): String?
- external fun es10cGetProfilesInfo(handle: Long): Array?
+ external fun es10cGetProfilesInfo(handle: Long): Long
external fun es10cEnableProfile(handle: Long, iccid: String, refresh: Boolean): Int
external fun es10cDisableProfile(handle: Long, iccid: String, refresh: Boolean): Int
external fun es10cDeleteProfile(handle: Long, iccid: String): Int
@@ -34,6 +34,16 @@ internal object LpacJni {
external fun es10cexGetEuiccInfo2(handle: Long): EuiccInfo2?
// C <-> Java struct / linked list handling
+ // Profiles
+ external fun profilesNext(curr: Long): Long
+ external fun profilesFree(head: Long): Long
+ external fun profileGetIccid(curr: Long): String
+ external fun profileGetIsdpAid(curr: Long): String
+ external fun profileGetName(curr: Long): String
+ external fun profileGetNickname(curr: Long): String
+ external fun profileGetServiceProvider(curr: Long): String
+ external fun profileGetStateString(curr: Long): String
+ external fun profileGetClassString(curr: Long): String
// Notifications
external fun notificationsNext(curr: Long): Long
external fun notificationGetSeq(curr: Long): Long
diff --git a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt
index 0b03b64..4515ea6 100644
--- a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt
+++ b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt
@@ -42,7 +42,28 @@ class LocalProfileAssistantImpl(
}
override val profiles: List
- get() = LpacJni.es10cGetProfilesInfo(contextHandle)?.asList() ?: listOf()
+ get() {
+ val head = LpacJni.es10cGetProfilesInfo(contextHandle)
+ var curr = head
+ val ret = mutableListOf()
+ while (curr != 0L) {
+ val state = LocalProfileInfo.State.fromString(LpacJni.profileGetStateString(curr))
+ val clazz = LocalProfileInfo.Clazz.fromString(LpacJni.profileGetClassString(curr))
+ ret.add(LocalProfileInfo(
+ LpacJni.profileGetIccid(curr),
+ state,
+ LpacJni.profileGetName(curr),
+ LpacJni.profileGetNickname(curr),
+ LpacJni.profileGetServiceProvider(curr),
+ LpacJni.profileGetIsdpAid(curr),
+ clazz
+ ))
+ curr = LpacJni.profilesNext(curr)
+ }
+
+ LpacJni.profilesFree(curr)
+ return ret
+ }
override val notifications: List
get() {
diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c
index 561e027..5dcddce 100644
--- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c
+++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c
@@ -12,15 +12,6 @@
JavaVM *jvm = NULL;
-jclass local_profile_info_class;
-jmethodID local_profile_info_constructor;
-
-jclass local_profile_state_class;
-jmethodID local_profile_state_from_string;
-
-jclass local_profile_class_class;
-jmethodID local_profile_class_from_string;
-
jstring empty_string;
jclass string_class;
@@ -40,25 +31,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
string_constructor = (*env)->GetMethodID(env, string_class, "",
"([BLjava/lang/String;)V");
- local_profile_info_class = (*env)->FindClass(env, "net/typeblog/lpac_jni/LocalProfileInfo");
- local_profile_info_class = (*env)->NewGlobalRef(env, local_profile_info_class);
- local_profile_info_constructor = (*env)->GetMethodID(env, local_profile_info_class, "",
- "(Ljava/lang/String;Lnet/typeblog/lpac_jni/LocalProfileInfo$State;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lnet/typeblog/lpac_jni/LocalProfileInfo$Clazz;)V");
-
- local_profile_state_class = (*env)->FindClass(env,
- "net/typeblog/lpac_jni/LocalProfileInfo$State");
- local_profile_state_class = (*env)->NewGlobalRef(env, local_profile_state_class);
- local_profile_state_from_string = (*env)->GetStaticMethodID(env, local_profile_state_class,
- "fromString",
- "(Ljava/lang/String;)Lnet/typeblog/lpac_jni/LocalProfileInfo$State;");
-
- local_profile_class_class = (*env)->FindClass(env,
- "net/typeblog/lpac_jni/LocalProfileInfo$Clazz");
- local_profile_class_class = (*env)->NewGlobalRef(env, local_profile_class_class);
- local_profile_class_from_string = (*env)->GetStaticMethodID(env, local_profile_class_class,
- "fromString",
- "(Ljava/lang/String;)Lnet/typeblog/lpac_jni/LocalProfileInfo$Clazz;");
-
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, "",
@@ -144,25 +116,23 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cGetEid(JNIEnv *env, jobject thiz, jlong
return ret;
}
-jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list *info) {
+JNIEXPORT jlong JNICALL
+Java_net_typeblog_lpac_1jni_LpacJni_es10cGetProfilesInfo(JNIEnv *env, jobject thiz, jlong handle) {
+ struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
+ struct es10c_profile_info_list *info = NULL;
+
+ if (es10c_get_profiles_info(ctx, &info) < 0) {
+ return 0;
+ }
+
+ return (jlong) info;
+}
+
+JNIEXPORT jstring JNICALL
+Java_net_typeblog_lpac_1jni_LpacJni_profileGetStateString(JNIEnv *env, jobject thiz, jlong curr) {
+ struct es10c_profile_info_list *info = (struct es10c_profile_info_list *) curr;
const char *profileStateStr = NULL;
- const char *profileClassStr = NULL;
- jstring serviceProvider = NULL;
- jstring nickName = NULL;
- jstring isdpAid = NULL;
- jstring iccid = NULL;
- jstring name = NULL;
- jobject state = NULL;
- jobject class = NULL;
- jobject jinfo = NULL;
- iccid = toJString(env, info->iccid);
- isdpAid = toJString(env, info->isdpAid);
- name = toJString(env, info->profileName);
- nickName = toJString(env, info->profileNickname);
- serviceProvider = toJString(env, info->serviceProviderName);
-
- // TODO: Maybe we should pass a Java object directly here?
switch (info->profileState) {
case ES10C_PROFILE_STATE_ENABLED:
profileStateStr = "enabled";
@@ -174,9 +144,13 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list
profileStateStr = "unknown";
}
- state = (*env)->CallStaticObjectMethod(env, local_profile_state_class,
- local_profile_state_from_string,
- toJString(env, profileStateStr));
+ return toJString(env, profileStateStr);
+}
+
+JNIEXPORT jstring JNICALL
+Java_net_typeblog_lpac_1jni_LpacJni_profileGetClassString(JNIEnv *env, jobject thiz, jlong curr) {
+ struct es10c_profile_info_list *info = (struct es10c_profile_info_list *) curr;
+ const char *profileClassStr = NULL;
switch (info->profileClass) {
case ES10C_PROFILE_CLASS_TEST:
@@ -193,51 +167,16 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list
break;
}
- class = (*env)->CallStaticObjectMethod(env, local_profile_class_class,
- local_profile_class_from_string,
- toJString(env, profileClassStr));
-
- jinfo = (*env)->NewObject(env, local_profile_info_class, local_profile_info_constructor,
- iccid, state, name, nickName, serviceProvider, isdpAid, class);
-
- (*env)->DeleteLocalRef(env, class);
- (*env)->DeleteLocalRef(env, state);
- (*env)->DeleteLocalRef(env, serviceProvider);
- (*env)->DeleteLocalRef(env, nickName);
- (*env)->DeleteLocalRef(env, name);
- (*env)->DeleteLocalRef(env, isdpAid);
- (*env)->DeleteLocalRef(env, iccid);
-
- return jinfo;
+ return toJString(env, profileClassStr);
}
-JNIEXPORT jobjectArray JNICALL
-Java_net_typeblog_lpac_1jni_LpacJni_es10cGetProfilesInfo(JNIEnv *env, jobject thiz, jlong handle) {
- struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
- struct es10c_profile_info_list *info = NULL;
- struct es10c_profile_info_list *curr = NULL;
- jobjectArray ret = NULL;
- jobject jinfo = NULL;
- int count = 0;
-
- if (es10c_get_profiles_info(ctx, &info) < 0) {
- return NULL;
- }
-
- count = LPAC_JNI_LINKED_LIST_COUNT(info, curr);
-
- ret = (*env)->NewObjectArray(env, count, local_profile_info_class, NULL);
-
- // Convert the native info array to Java
- LPAC_JNI_LINKED_LIST_FOREACH(info, curr, {
- jinfo = profile_info_native_to_java(env, curr);
- (*env)->SetObjectArrayElement(env, ret, i, jinfo);
- (*env)->DeleteLocalRef(env, jinfo);
- });
-
- es10c_profile_info_list_free_all(info);
- return ret;
-}
+LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10c_profile_info_list, profiles)
+LPAC_JNI_STRUCT_LINKED_LIST_FREE(struct es10c_profile_info_list, profiles, es10c_profile_info_list_free_all)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, iccid, Iccid)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, isdpAid, IsdpAid)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, profileName, Name)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, profileNickname, Nickname)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, serviceProviderName, ServiceProvider)
JNIEXPORT jint JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10cEnableProfile(JNIEnv *env, jobject thiz, jlong handle,
diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h
index 4d537ee..d185551 100644
--- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h
+++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h
@@ -66,15 +66,15 @@ jstring toJString(JNIEnv *env, const char *pat);
free_func(p); \
}
-#define LPAC_JNI_STRUCT_GETTER_LONG(st, name, jname) \
- JNIEXPORT jlong JNICALL Java_net_typeblog_lpac_1jni_LpacJni_notificationGet##jname(JNIEnv *env, jobject thiz, jlong raw) { \
+#define LPAC_JNI_STRUCT_GETTER_LONG(st, st_name, name, jname) \
+ JNIEXPORT jlong JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_name##Get##jname(JNIEnv *env, jobject thiz, jlong raw) { \
st *p = (st *) raw; \
if (p == NULL) return 0; \
return (jlong) p->name; \
}
-#define LPAC_JNI_STRUCT_GETTER_STRING(st, name, jname) \
- JNIEXPORT jstring JNICALL Java_net_typeblog_lpac_1jni_LpacJni_notificationGet##jname(JNIEnv *env, jobject thiz, jlong raw) { \
+#define LPAC_JNI_STRUCT_GETTER_STRING(st, st_name, name, jname) \
+ JNIEXPORT jstring JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_name##Get##jname(JNIEnv *env, jobject thiz, jlong raw) { \
st *p = (st *) raw; \
return toJString(env, p->name); \
}
\ No newline at end of file
diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c
index bd4dffd..b2c4825 100644
--- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c
+++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c
@@ -74,6 +74,6 @@ Java_net_typeblog_lpac_1jni_LpacJni_notificationGetOperationString(JNIEnv *env,
LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10b_notification_metadata_list, notifications)
LPAC_JNI_STRUCT_LINKED_LIST_FREE(struct es10b_notification_metadata_list, notifications, es10b_notification_metadata_list_free_all)
-LPAC_JNI_STRUCT_GETTER_LONG(struct es10b_notification_metadata_list, seqNumber, Seq)
-LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notificationAddress, Address)
-LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, iccid, Iccid)
\ No newline at end of file
+LPAC_JNI_STRUCT_GETTER_LONG(struct es10b_notification_metadata_list, notification, seqNumber, Seq)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notification, notificationAddress, Address)
+LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notification, iccid, Iccid)