forked from PeterCxy/OpenEUICC
Compare commits
15 commits
316abf0a3d
...
0e3a57f948
Author | SHA1 | Date | |
---|---|---|---|
0e3a57f948 | |||
68f1e370fc | |||
bf36188219 | |||
a43ceea39f | |||
c681e99e47 | |||
0afbece3b5 | |||
b101b01228 | |||
5ab07d6262 | |||
394cad2eac | |||
7f67000074 | |||
7c07db0aab | |||
f073261b60 | |||
87ea017b36 | |||
44b85ffdea | |||
01fc07fd78 |
15 changed files with 292 additions and 274 deletions
10
.idea/deploymentTargetSelector.xml
generated
Normal file
10
.idea/deploymentTargetSelector.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app-unpriv">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
16
.idea/gradle.xml
generated
16
.idea/gradle.xml
generated
|
@ -4,11 +4,20 @@
|
|||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT">
|
||||
<builds>
|
||||
<build path="$PROJECT_DIR$/buildSrc" name="buildSrc">
|
||||
<projects>
|
||||
<project path="$PROJECT_DIR$/buildSrc" />
|
||||
</projects>
|
||||
</build>
|
||||
</builds>
|
||||
</compositeBuild>
|
||||
</compositeConfiguration>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="/usr/share/java/gradle" />
|
||||
<option name="gradleJvm" value="jbr-17" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -23,6 +32,7 @@
|
|||
<option value="$PROJECT_DIR$/libs/lpac-jni" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveExternalAnnotations" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
|
10
.idea/migrations.xml
generated
Normal file
10
.idea/migrations.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -3,6 +3,7 @@ package im.angry.openeuicc.core
|
|||
import android.se.omapi.Channel
|
||||
import android.se.omapi.SEService
|
||||
import android.se.omapi.Session
|
||||
import android.util.Log
|
||||
import im.angry.openeuicc.util.*
|
||||
import net.typeblog.lpac_jni.ApduInterface
|
||||
|
||||
|
@ -10,6 +11,10 @@ class OmapiApduInterface(
|
|||
private val service: SEService,
|
||||
private val port: UiccPortInfoCompat
|
||||
): ApduInterface {
|
||||
companion object {
|
||||
const val TAG = "OmapiApduInterface"
|
||||
}
|
||||
|
||||
private lateinit var session: Session
|
||||
private lateinit var lastChannel: Channel
|
||||
|
||||
|
@ -44,7 +49,17 @@ class OmapiApduInterface(
|
|||
"Unknown channel"
|
||||
}
|
||||
|
||||
return lastChannel.transmit(tx)
|
||||
Log.d(TAG, "OMAPI APDU: ${tx.encodeHex()}")
|
||||
|
||||
try {
|
||||
return lastChannel.transmit(tx).also {
|
||||
Log.d(TAG, "OMAPI APDU response: ${it.encodeHex()}")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "OMAPI APDU exception")
|
||||
e.printStackTrace()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -296,7 +296,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
|
|||
}
|
||||
|
||||
iccid.setOnLongClickListener {
|
||||
requireContext().getSystemService(ClipboardManager::class.java)
|
||||
requireContext().getSystemService(ClipboardManager::class.java)!!
|
||||
.setPrimaryClip(ClipData.newPlainText("iccid", iccid.text))
|
||||
Toast.makeText(requireContext(), R.string.toast_iccid_copied, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
|
|
|
@ -13,7 +13,7 @@ apply {
|
|||
|
||||
android {
|
||||
namespace = "im.angry.openeuicc_deps"
|
||||
compileSdk = 33
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 28
|
||||
|
|
|
@ -193,7 +193,7 @@ internal class IsdrChannelAccessCheck(private val context: Context): Compatibili
|
|||
|
||||
internal class KnownBrokenCheck(private val context: Context): CompatibilityCheck(context) {
|
||||
companion object {
|
||||
val BROKEN_MANUFACTURERS = arrayOf("xiaomi")
|
||||
val BROKEN_MANUFACTURERS = arrayOf("xiaomi", "huawei", "honor")
|
||||
}
|
||||
|
||||
override val title: String
|
||||
|
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
|
||||
android {
|
||||
namespace = "net.typeblog.lpac_jni"
|
||||
compileSdk = 33
|
||||
compileSdk = 34
|
||||
ndkVersion = "26.1.10909125"
|
||||
|
||||
defaultConfig {
|
||||
|
|
|
@ -14,14 +14,14 @@ internal object LpacJni {
|
|||
// es10c
|
||||
// null returns signify errors
|
||||
external fun es10cGetEid(handle: Long): String?
|
||||
external fun es10cGetProfilesInfo(handle: Long): Array<LocalProfileInfo>?
|
||||
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
|
||||
external fun es10cSetNickname(handle: Long, iccid: String, nick: String): Int
|
||||
|
||||
// es10b
|
||||
external fun es10bListNotification(handle: Long): Array<LocalProfileNotification>?
|
||||
external fun es10bListNotification(handle: Long): Long // A native pointer to a linked list. Handle with linked list-related methods below. May be 0 (null)
|
||||
external fun es10bDeleteNotification(handle: Long, seqNumber: Long): Int
|
||||
|
||||
// es9p + es10b
|
||||
|
@ -31,5 +31,39 @@ 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
|
||||
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
|
||||
external fun notificationGetOperationString(curr: Long): String
|
||||
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
|
||||
}
|
|
@ -42,18 +42,85 @@ class LocalProfileAssistantImpl(
|
|||
}
|
||||
|
||||
override val profiles: List<LocalProfileInfo>
|
||||
get() = LpacJni.es10cGetProfilesInfo(contextHandle)?.asList() ?: listOf()
|
||||
get() {
|
||||
val head = LpacJni.es10cGetProfilesInfo(contextHandle)
|
||||
var curr = head
|
||||
val ret = mutableListOf<LocalProfileInfo>()
|
||||
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<LocalProfileNotification>
|
||||
get() =
|
||||
(LpacJni.es10bListNotification(contextHandle) ?: arrayOf())
|
||||
.sortedBy { it.seqNumber }.reversed()
|
||||
get() {
|
||||
val head = LpacJni.es10bListNotification(contextHandle)
|
||||
var curr = head
|
||||
val ret = mutableListOf<LocalProfileNotification>()
|
||||
while (curr != 0L) {
|
||||
ret.add(LocalProfileNotification(
|
||||
LpacJni.notificationGetSeq(curr),
|
||||
LocalProfileNotification.Operation.fromString(LpacJni.notificationGetOperationString(curr)),
|
||||
LpacJni.notificationGetAddress(curr),
|
||||
LpacJni.notificationGetIccid(curr),
|
||||
))
|
||||
curr = LpacJni.notificationsNext(curr)
|
||||
}
|
||||
LpacJni.notificationsFree(head)
|
||||
return ret.sortedBy { it.seqNumber }.reversed()
|
||||
}
|
||||
|
||||
override val eID: String
|
||||
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)
|
||||
}
|
||||
|
||||
val ret = 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()
|
||||
)
|
||||
|
||||
LpacJni.euiccInfo2Free(cInfo)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
override fun enableProfile(iccid: String, refresh: Boolean): Boolean =
|
||||
LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0
|
||||
|
|
|
@ -114,7 +114,7 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
|
|||
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_finalizing);
|
||||
// TODO: Expose error code as Java-side exceptions?
|
||||
ret = es10b_load_bound_profile_package(ctx, &es10b_load_bound_profile_package_result);
|
||||
syslog(LOG_INFO, "es10b_load_bound_profile_package %d", ret);
|
||||
syslog(LOG_INFO, "es10b_load_bound_profile_package %d, reason %d", ret, es10b_load_bound_profile_package_result.errorReason);
|
||||
|
||||
out:
|
||||
euicc_http_cleanup(ctx);
|
||||
|
|
|
@ -12,28 +12,15 @@
|
|||
|
||||
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;
|
||||
jmethodID string_constructor;
|
||||
|
||||
jclass euicc_info2_class;
|
||||
jmethodID euicc_info2_constructor;
|
||||
|
||||
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
jvm = vm;
|
||||
interface_wrapper_init();
|
||||
lpac_download_init();
|
||||
lpac_notifications_init();
|
||||
|
||||
LPAC_JNI_SETUP_ENV;
|
||||
string_class = (*env)->FindClass(env, "java/lang/String");
|
||||
|
@ -41,30 +28,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
|||
string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
|
||||
"([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, "<init>",
|
||||
"(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, "<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);
|
||||
|
@ -145,25 +108,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";
|
||||
|
@ -175,9 +136,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:
|
||||
|
@ -194,51 +159,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_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,
|
||||
|
@ -295,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;
|
||||
struct es10c_ex_euiccinfo2 *info = malloc(sizeof(struct es10c_ex_euiccinfo2));
|
||||
|
||||
if (es10c_ex_get_euiccinfo2(ctx, &info) < 0)
|
||||
goto out;
|
||||
if (es10c_ex_get_euiccinfo2(ctx, info) < 0) {
|
||||
free(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
return (jlong) info;
|
||||
}
|
||||
|
||||
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));
|
||||
});
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_net_typeblog_lpac_1jni_LpacJni_stringDeref(JNIEnv *env, jobject thiz, jlong curr) {
|
||||
return toJString(env, *((char **) 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));
|
||||
});
|
||||
void lpac_jni_euiccinfo2_free(struct es10c_ex_euiccinfo2 *info) {
|
||||
es10c_ex_euiccinfo2_free(info);
|
||||
free(info);
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
|
||||
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;
|
||||
}
|
||||
LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, euiccCiPKIdListForSigning, EuiccCiPKIdListForSigning)
|
||||
LPAC_JNI_STRUCT_GETTER_LONG(struct es10c_ex_euiccinfo2, euiccInfo2, euiccCiPKIdListForVerification, EuiccCiPKIdListForVerification)
|
||||
|
|
|
@ -17,37 +17,42 @@ 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;
|
||||
|
||||
jstring toJString(JNIEnv *env, const char *pat);
|
||||
jstring toJString(JNIEnv *env, const char *pat);
|
||||
|
||||
#define LPAC_JNI_STRUCT_GETTER_LINKED_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; \
|
||||
if (p == NULL) return 0; \
|
||||
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; \
|
||||
if (p == NULL) return; \
|
||||
free_func(p); \
|
||||
}
|
||||
|
||||
#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, 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); \
|
||||
}
|
|
@ -4,88 +4,15 @@
|
|||
#include <malloc.h>
|
||||
#include <syslog.h>
|
||||
|
||||
jclass local_profile_notification_class;
|
||||
jmethodID local_profile_notification_constructor;
|
||||
|
||||
jclass local_profile_notification_operation_class;
|
||||
jmethodID local_profile_notification_operation_from_string;
|
||||
|
||||
void lpac_notifications_init() {
|
||||
LPAC_JNI_SETUP_ENV;
|
||||
|
||||
local_profile_notification_class =
|
||||
(*env)->FindClass(env, "net/typeblog/lpac_jni/LocalProfileNotification");
|
||||
local_profile_notification_class =
|
||||
(*env)->NewGlobalRef(env, local_profile_notification_class);
|
||||
local_profile_notification_constructor =
|
||||
(*env)->GetMethodID(env, local_profile_notification_class, "<init>",
|
||||
"(JLnet/typeblog/lpac_jni/LocalProfileNotification$Operation;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
|
||||
local_profile_notification_operation_class =
|
||||
(*env)->FindClass(env, "net/typeblog/lpac_jni/LocalProfileNotification$Operation");
|
||||
local_profile_notification_operation_class =
|
||||
(*env)->NewGlobalRef(env, local_profile_notification_operation_class);
|
||||
local_profile_notification_operation_from_string =
|
||||
(*env)->GetStaticMethodID(env, local_profile_notification_operation_class, "fromString",
|
||||
"(Ljava/lang/String;)Lnet/typeblog/lpac_jni/LocalProfileNotification$Operation;");
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_net_typeblog_lpac_1jni_LpacJni_es10bListNotification(JNIEnv *env, jobject thiz, jlong handle) {
|
||||
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
||||
struct es10b_notification_metadata_list *info = NULL;
|
||||
struct es10b_notification_metadata_list *curr = NULL;
|
||||
const char *profileManagementOperationStr = NULL;
|
||||
jobject notification = NULL;
|
||||
jobject operation = NULL;
|
||||
jobjectArray ret = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (es10b_list_notification(ctx, &info) < 0)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
count = LPAC_JNI_LINKED_LIST_COUNT(info, curr);
|
||||
|
||||
ret = (*env)->NewObjectArray(env, count, local_profile_notification_class, NULL);
|
||||
|
||||
LPAC_JNI_LINKED_LIST_FOREACH(info, curr, {
|
||||
switch (curr->profileManagementOperation) {
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_INSTALL:
|
||||
profileManagementOperationStr = "install";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DELETE:
|
||||
profileManagementOperationStr = "delete";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_ENABLE:
|
||||
profileManagementOperationStr = "enable";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DISABLE:
|
||||
profileManagementOperationStr = "disable";
|
||||
break;
|
||||
default:
|
||||
profileManagementOperationStr = "unknown";
|
||||
}
|
||||
|
||||
operation =
|
||||
(*env)->CallStaticObjectMethod(env, local_profile_notification_operation_class,
|
||||
local_profile_notification_operation_from_string,
|
||||
toJString(env, profileManagementOperationStr));
|
||||
|
||||
notification =
|
||||
(*env)->NewObject(env, local_profile_notification_class,
|
||||
local_profile_notification_constructor, curr->seqNumber,
|
||||
operation,
|
||||
toJString(env, curr->notificationAddress),
|
||||
toJString(env, curr->iccid));
|
||||
|
||||
(*env)->SetObjectArrayElement(env, ret, i, notification);
|
||||
|
||||
(*env)->DeleteLocalRef(env, operation);
|
||||
(*env)->DeleteLocalRef(env, notification);
|
||||
});
|
||||
|
||||
es10b_notification_metadata_list_free_all(info);
|
||||
return ret;
|
||||
return (jlong) info;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
|
@ -117,4 +44,36 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10bDeleteNotification(JNIEnv *env, jobject
|
|||
jlong seq_number) {
|
||||
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
||||
return es10b_remove_notification_from_list(ctx, (unsigned long) seq_number);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_net_typeblog_lpac_1jni_LpacJni_notificationGetOperationString(JNIEnv *env, jobject thiz,
|
||||
jlong curr) {
|
||||
struct es10b_notification_metadata_list *info = (struct es10b_notification_metadata_list *) curr;
|
||||
const char *profileManagementOperationStr = NULL;
|
||||
switch (info->profileManagementOperation) {
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_INSTALL:
|
||||
profileManagementOperationStr = "install";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DELETE:
|
||||
profileManagementOperationStr = "delete";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_ENABLE:
|
||||
profileManagementOperationStr = "enable";
|
||||
break;
|
||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DISABLE:
|
||||
profileManagementOperationStr = "disable";
|
||||
break;
|
||||
default:
|
||||
profileManagementOperationStr = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return toJString(env, profileManagementOperationStr);
|
||||
}
|
||||
|
||||
LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10b_notification_metadata_list, notifications)
|
||||
LPAC_JNI_STRUCT_FREE(struct es10b_notification_metadata_list, notifications, es10b_notification_metadata_list_free_all)
|
||||
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)
|
||||
|
|
|
@ -2,5 +2,3 @@
|
|||
|
||||
#include <jni.h>
|
||||
#include "lpac-jni.h"
|
||||
|
||||
void lpac_notifications_init();
|
Loading…
Add table
Reference in a new issue