|
|
@@ -1,5 +1,6 @@
|
|
|
#include <euicc/es9p.h>
|
|
|
#include <euicc/es10b.h>
|
|
|
+#include <euicc/es8p.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
#include <syslog.h>
|
|
|
@@ -12,6 +13,12 @@ jobject download_state_downloading;
|
|
|
jobject download_state_finalizing;
|
|
|
|
|
|
jmethodID on_state_update;
|
|
|
+jmethodID on_confirm_metadata;
|
|
|
+jclass remote_profile_info_class;
|
|
|
+jmethodID remote_profile_info_constructor;
|
|
|
+jobject profile_class_testing;
|
|
|
+jobject profile_class_provisioning;
|
|
|
+jobject profile_class_operational;
|
|
|
|
|
|
void lpac_download_init() {
|
|
|
LPAC_JNI_SETUP_ENV;
|
|
|
@@ -54,6 +61,77 @@ void lpac_download_init() {
|
|
|
"net/typeblog/lpac_jni/ProfileDownloadCallback");
|
|
|
on_state_update = (*env)->GetMethodID(env, download_callback_class, "onStateUpdate",
|
|
|
"(Lnet/typeblog/lpac_jni/ProfileDownloadState;)V");
|
|
|
+ on_confirm_metadata = (*env)->GetMethodID(env, download_callback_class, "onConfirmMetadata",
|
|
|
+ "(Lnet/typeblog/lpac_jni/RemoteProfileInfo;)Z");
|
|
|
+
|
|
|
+ jclass profile_class_class = (*env)->FindClass(env, "net/typeblog/lpac_jni/ProfileClass");
|
|
|
+ jfieldID profile_class_testing_field = (*env)->GetStaticFieldID(env, profile_class_class,
|
|
|
+ "Testing",
|
|
|
+ "Lnet/typeblog/lpac_jni/ProfileClass;");
|
|
|
+ profile_class_testing = (*env)->GetStaticObjectField(env, profile_class_class,
|
|
|
+ profile_class_testing_field);
|
|
|
+ profile_class_testing = (*env)->NewGlobalRef(env, profile_class_testing);
|
|
|
+ jfieldID profile_class_provisioning_field = (*env)->GetStaticFieldID(env, profile_class_class,
|
|
|
+ "Provisioning",
|
|
|
+ "Lnet/typeblog/lpac_jni/ProfileClass;");
|
|
|
+ profile_class_provisioning = (*env)->GetStaticObjectField(env, profile_class_class,
|
|
|
+ profile_class_provisioning_field);
|
|
|
+ profile_class_provisioning = (*env)->NewGlobalRef(env, profile_class_provisioning);
|
|
|
+ jfieldID profile_class_operational_field = (*env)->GetStaticFieldID(env, profile_class_class,
|
|
|
+ "Operational",
|
|
|
+ "Lnet/typeblog/lpac_jni/ProfileClass;");
|
|
|
+ profile_class_operational = (*env)->GetStaticObjectField(env, profile_class_class,
|
|
|
+ profile_class_operational_field);
|
|
|
+ profile_class_operational = (*env)->NewGlobalRef(env, profile_class_operational);
|
|
|
+
|
|
|
+ jclass _remote_profile_info_class = (*env)->FindClass(env,
|
|
|
+ "net/typeblog/lpac_jni/RemoteProfileInfo");
|
|
|
+ remote_profile_info_class = (*env)->NewGlobalRef(env, _remote_profile_info_class);
|
|
|
+ remote_profile_info_constructor = (*env)->GetMethodID(env, remote_profile_info_class, "<init>",
|
|
|
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lnet/typeblog/lpac_jni/ProfileClass;)V");
|
|
|
+}
|
|
|
+
|
|
|
+static jobject profile_class_from_es10c_profile_class(enum es10c_profile_class profile_class) {
|
|
|
+ switch (profile_class) {
|
|
|
+ case ES10C_PROFILE_CLASS_TEST:
|
|
|
+ return profile_class_testing;
|
|
|
+ case ES10C_PROFILE_CLASS_PROVISIONING:
|
|
|
+ return profile_class_provisioning;
|
|
|
+ case ES10C_PROFILE_CLASS_OPERATIONAL:
|
|
|
+ default:
|
|
|
+ // In es10c profiles are considered operational if the field is missing (null).
|
|
|
+ return profile_class_operational;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static jobject create_remote_profile_info(JNIEnv *env,
|
|
|
+ struct es8p_metadata *profile_metadata) {
|
|
|
+ jobject profile_class = NULL;
|
|
|
+ jstring metadata_iccid = NULL;
|
|
|
+ jstring metadata_profile_name = NULL;
|
|
|
+ jstring metadata_provider_name = NULL;
|
|
|
+ jobject remote_profile_info = NULL;
|
|
|
+
|
|
|
+ metadata_iccid = toJString(env, profile_metadata->iccid);
|
|
|
+ metadata_profile_name = toJString(env, profile_metadata->profileName);
|
|
|
+ metadata_provider_name = toJString(env, profile_metadata->serviceProviderName);
|
|
|
+ profile_class = profile_class_from_es10c_profile_class(profile_metadata->profileClass);
|
|
|
+
|
|
|
+ remote_profile_info = (*env)->NewObject(env, remote_profile_info_class,
|
|
|
+ remote_profile_info_constructor,
|
|
|
+ metadata_iccid,
|
|
|
+ metadata_profile_name,
|
|
|
+ metadata_provider_name,
|
|
|
+ profile_class);
|
|
|
+
|
|
|
+ if (metadata_iccid != NULL)
|
|
|
+ (*env)->DeleteLocalRef(env, metadata_iccid);
|
|
|
+ if (metadata_profile_name != NULL)
|
|
|
+ (*env)->DeleteLocalRef(env, metadata_profile_name);
|
|
|
+ if (metadata_provider_name != NULL)
|
|
|
+ (*env)->DeleteLocalRef(env, metadata_provider_name);
|
|
|
+
|
|
|
+ return remote_profile_info;
|
|
|
}
|
|
|
|
|
|
JNIEXPORT jint JNICALL
|
|
|
@@ -62,11 +140,14 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
|
|
|
jstring imei, jstring confirmation_code,
|
|
|
jobject callback) {
|
|
|
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
|
|
+ struct es8p_metadata *profile_metadata = NULL;
|
|
|
struct es10b_load_bound_profile_package_result es10b_load_bound_profile_package_result;
|
|
|
const char *_confirmation_code = NULL;
|
|
|
const char *_matching_id = NULL;
|
|
|
const char *_smdp = NULL;
|
|
|
const char *_imei = NULL;
|
|
|
+ jobject remote_profile_info = NULL;
|
|
|
+ jboolean confirmed = JNI_FALSE;
|
|
|
int ret;
|
|
|
|
|
|
if (confirmation_code != NULL)
|
|
|
@@ -109,6 +190,34 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ if (ctx->http._internal.prepare_download_param != NULL &&
|
|
|
+ ctx->http._internal.prepare_download_param->b64_profileMetadata != NULL) {
|
|
|
+ ret = es8p_metadata_parse(&profile_metadata,
|
|
|
+ ctx->http._internal.prepare_download_param->b64_profileMetadata);
|
|
|
+ if (ret < 0) {
|
|
|
+ ret = -ES10B_ERROR_REASON_UNDEFINED;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ remote_profile_info = create_remote_profile_info(env, profile_metadata);
|
|
|
+ if (remote_profile_info == NULL) {
|
|
|
+ ret = -ES10B_ERROR_REASON_UNDEFINED;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ confirmed = (*env)->CallBooleanMethod(env, callback, on_confirm_metadata, remote_profile_info);
|
|
|
+
|
|
|
+ if (remote_profile_info != NULL) {
|
|
|
+ (*env)->DeleteLocalRef(env, remote_profile_info);
|
|
|
+ remote_profile_info = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!confirmed) {
|
|
|
+ ret = -ES10B_ERROR_REASON_UNDEFINED;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_downloading);
|
|
|
ret = es10b_prepare_download(ctx, _confirmation_code);
|
|
|
syslog(LOG_INFO, "es10b_prepare_download %d", ret);
|
|
|
@@ -141,6 +250,10 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
|
|
|
(*env)->ReleaseStringUTFChars(env, smdp, _smdp);
|
|
|
if (_imei != NULL)
|
|
|
(*env)->ReleaseStringUTFChars(env, imei, _imei);
|
|
|
+ if (remote_profile_info != NULL)
|
|
|
+ (*env)->DeleteLocalRef(env, remote_profile_info);
|
|
|
+ if (profile_metadata != NULL)
|
|
|
+ es8p_metadata_free(&profile_metadata);
|
|
|
return ret;
|
|
|
}
|
|
|
|