Implementierung von eSIM

Die integrierte SIM-Technologie (eSIM oder eUICC) ermöglicht es mobilen Benutzern, ein Netzbetreiberprofil herunterzuladen und den Dienst eines Netzbetreibers zu aktivieren, ohne eine physische SIM-Karte zu besitzen. Es handelt sich um eine globale Spezifikation, die von der GSMA gesteuert wird und die Remote-SIM-Bereitstellung (RSP) von jedem mobilen Gerät ermöglicht. Ab Android 9 bietet das Android-Framework Standard-APIs für den Zugriff auf eSIM und die Verwaltung von Abonnementprofilen auf der eSIM. Diese eUICC APIs ermöglichen Dritte ihre eigenen Träger - Anwendungen und lokalen Profilassistenten (LPA) auf eSIM-fähigen Android - Geräte zu entwickeln.

Die LPA ist eine eigenständige System-App, die im Android-Build-Image enthalten sein sollte. Die Verwaltung der Profile auf der eSIM erfolgt in der Regel durch die LPA, da sie als Brücke zwischen dem SM-DP+ (Ferndienst, der Profilpakete vorbereitet, speichert und an Geräte liefert) und dem eUICC-Chip dient. Das LPA-APK kann optional eine UI-Komponente enthalten, die als LPA-UI oder LUI bezeichnet wird, um dem Endbenutzer einen zentralen Ort zur Verwaltung aller eingebetteten Abonnementprofile bereitzustellen. Das Android-Framework erkennt automatisch die beste verfügbare LPA und stellt eine Verbindung zu ihr her und leitet alle eUICC-Vorgänge über eine LPA-Instanz weiter.

Vereinfachte Architektur der Remote-SIM-Bereitstellung (RSP)

Abbildung 1 : Vereinfachtes RSP - Architektur

Mobilfunknetzbetreiber daran interessiert, eine Träger App Erstellung sollte an den APIs in aussehen EuiccManager , die High-Level - Profil - Management - Operationen, wie liefert downloadSubscription() , switchToSubscription() und deleteSubscription() .

Wenn Sie ein Gerät OEM interessiert sind in Ihren eigenen LPA System - App erstellen, müssen Sie erweitern EuiccService für den Android - Framework Ihrer LPA Dienste zu verbinden. Darüber hinaus sollten Sie die APIs in verwenden EuiccCardManager , die auf GSMA RSP v2.0 basierend ES10x Funktionen. Diese Funktionen werden verwendet , um Befehle an den Ausgabe eUICC Chip, wie prepareDownload() , loadBoundProfilePackage() , retrieveNotificationList() und resetMemory() .

Die APIs in EuiccManager erfordern eine ordnungsgemäße Durchführung LPA App - Funktion und die Anrufer von EuiccCardManager APIs muss ein LPA sein. Dies wird durch das Android-Framework erzwungen.

Geräte mit Android 10 oder höher können Geräte mit mehreren eSIMs unterstützen. Weitere Informationen finden Sie Unterstützung mehrerer eSIMs .

Erstellen einer Mobilfunkanbieter-App

Die eUICC-APIs in Android 9 ermöglichen es Mobilfunknetzbetreibern, anbieterspezifische Apps zu erstellen, um ihre Profile direkt zu verwalten. Dies umfasst das Herunterladen und Löschen von Abonnementprofilen, die dem Netzbetreiber gehören, sowie das Wechseln zu einem Profil, das einem Netzbetreiber gehört.

EuiccManager

EuiccManager ist der Haupteinstiegspunkt für Anwendungen mit dem LPA zu interagieren. Dazu gehören Mobilfunkanbieter-Apps, die Abonnements des Mobilfunkanbieters herunterladen, löschen und zu diesen wechseln. Dazu gehört auch die LUI - System - Anwendung, die für die Verwaltung aller Subskriptionen eingebetteten zentrale Lage / UI bereitstellt, und kann eine separate Anwendung von der sein, die ermöglicht EuiccService .

Um die öffentlichen APIs zu verwenden, muss ein Träger App erhalten zunächst die Instanz von EuiccManager durch Context#getSystemService :

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

Sie sollten überprüfen, ob eSIM auf dem Gerät unterstützt wird, bevor Sie eSIM-Vorgänge durchführen. EuiccManager#isEnabled() kehrt im Allgemeinen true , wenn die android.hardware.telephony.euicc Funktion definiert ist und ein LPA - Paket vorhanden ist.

boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
    return;
}

So erhalten Sie Informationen über die eUICC-Hardware und die eSIM-Betriebssystemversion:

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

Viele APIs wie downloadSubscription() und switchToSubscription() , verwenden PendingIntent Rückrufe wie sie Sekunden oder sogar Minuten dauern kann. PendingIntent ist mit einem Ergebniscode in dem gesendeten EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ Raum, der Rahmen definierte Fehlercodes enthält, sowie einen beliebigen detaillierten Ergebniscode von der LPA als propagierte EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE , so dass der Träger für die Protokollierung app / Debugging - Zwecke zu verfolgen. Der PendingIntent Rückruf muss BroadcastReceiver .

Zum Herunterladen einer bestimmten herunterladbaren Abonnement (erstellt von einem Aktivierungscode oder einen QR - Code):

// Register receiver.
static final String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
static final String LPA_DECLARED_PERMISSION
    = "com.your.company.lpa.permission.BROADCAST";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver,
        new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
        LPA_DECLARED_PERMISSION /* broadcastPermission*/,
        null /* handler */);

// Download subscription asynchronously.
DownloadableSubscription sub = DownloadableSubscription
        .forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
        callbackIntent);

So wechseln Sie zu einem Abonnement mit der Abonnement-ID:

// Register receiver.
static final String ACTION_SWITCH_TO_SUBSCRIPTION = "switch_to_subscription";
static final String LPA_DECLARED_PERMISSION
    = "com.your.company.lpa.permission.BROADCAST";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver,
        new IntentFilter(ACTION_SWITCH_TO_SUBSCRIPTION),
        LPA_DECLARED_PERMISSION /* broadcastPermission*/,
        null /* handler */);

// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

Für eine vollständige Liste der EuiccManager APIs und Codebeispiele finden Sie eUICC APIs .

Behebbare Fehler

Es gibt einige Fälle, in denen das System den eSIM-Vorgang nicht abschließen kann, der Fehler jedoch vom Benutzer behoben werden kann. Zum Beispiel downloadSubscription fehlschlagen kann , wenn das Profil Metadaten , dass ein Codeträger Bestätigung anzeigt , ist nicht erforderlich. Oder switchToSubscription kann fehlschlagen , wenn der Träger App Träger Privilegien über das Zielprofil hat (das heißt, Träger besitzt das Profil) , aber nicht über Träger Privilegien über das aktuell aktiviert Profil und damit die Zustimmung der Nutzer erforderlich ist .

Für diese Fälle wird der Rückruf des Anrufers mit genannt EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR . Das Callback - Intent enthält interne Extras , so dass , wenn der Anrufer übergibt sie an EuiccManager#startResolutionActivity , kann die Auflösung durch die LUI angefordert werden. Verwenden Sie den Bestätigungscode zum Beispiel wieder, EuiccManager#startResolutionActivity löst einen LUI - Bildschirm , dass der Benutzer einen Bestätigungscode eingeben können; Nach Eingabe des Codes wird der Download-Vorgang fortgesetzt. Dieser Ansatz bietet der Mobilfunkanbieter-App die volle Kontrolle darüber, wann die Benutzeroberfläche angezeigt wird, gibt der LPA/LUI jedoch eine erweiterbare Methode zum Hinzufügen einer neuen Behandlung von benutzerbehebbaren Problemen in der Zukunft, ohne dass Client-Apps geändert werden müssen.

Android 9 definiert diese auflösbar Fehler in EuiccService , die die LUI behandeln soll:

/**
 * Alert the user that this action will result in an active SIM being
 * deactivated. To implement the LUI triggered by the system, you need to define
 * this in AndroidManifest.xml.
 */
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
        "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
 * Alert the user about a download/switch being done for an app that doesn't
 * currently have carrier privileges.
 */
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
        "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";

/** Ask the user to resolve all the resolvable errors. */
public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
        "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";

Carrier-Privilegien

Wenn Sie ein Träger der Entwicklung Ihrer eigenen Träger App sind die Anrufe EuiccManager zum Download Profile auf ein Gerät, sollten Sie Ihr Profil gehören auch die Regeln Träger Privileg Ihre Träger App in den Metadaten entsprechen. Dies liegt daran, dass Abonnementprofile verschiedener Netzbetreiber in der eUICC eines Geräts koexistieren können und jede Netzbetreiber-App nur auf die Profile zugreifen darf, die diesem Netzbetreiber gehören. Beispielsweise sollte Mobilfunkanbieter A kein Profil von Mobilfunkanbieter B herunterladen, aktivieren oder deaktivieren können.

Um sicherzustellen, dass ein Profil nur für seinen Besitzer zugänglich ist, verwendet Android einen Mechanismus, um der App des Profilbesitzers (d. h. der Mobilfunkanbieter-App) besondere Berechtigungen zu gewähren. Die Android - Plattform lädt Zertifikate in der Zugriffsregeldatei Profil gespeichert (ARF) und die Erlaubnis zu Apps dieser Zertifikate unterzeichnet Anrufe machen EuiccManager APIs. Der High-Level-Prozess wird im Folgenden beschrieben:

  1. Betreiber signiert die Mobilfunkanbieter-App APK; das apksigner Werkzeug misst das Public-Key - Zertifikat an die APK.
  2. Operator/SM-DP+ erstellt ein Profil und seine Metadaten, die eine ARF enthalten, die Folgendes enthält:

    1. Signatur (SHA-1 oder SHA-256) des Public-Key-Zertifikats der Mobilfunkanbieter-App (erforderlich)
    2. Paketname der Spediteur-App (optional)
  3. Träger app versucht , einen Betrieb über eUICC auszuführen EuiccManager API.

  4. Die Android-Plattform überprüft, ob der SHA-1- oder SHA-256-Hash des Zertifikats der Anrufer-App mit der Signatur des Zertifikats übereinstimmt, das aus dem ARF des Zielprofils abgerufen wurde. Wenn der Paketname der Mobilfunkanbieter-App im ARF enthalten ist, muss er auch mit dem Paketnamen der Anrufer-App übereinstimmen.

  5. Nachdem die Signatur und der Paketname (sofern enthalten) verifiziert wurden, wird der Anrufer-App das Betreiberprivileg über das Zielprofil gewährt.

Da Profilmetadaten außerhalb des Profils selbst verfügbar sein können (damit LPA die Profilmetadaten von SM-DP+ abrufen kann, bevor das Profil heruntergeladen wird, oder von ISD-R, wenn das Profil deaktiviert ist), sollte es die gleichen Betreiberberechtigungsregeln enthalten wie im Profil.

Die eUICC OS und SM-DP + muss ein eigenes Tag unterstützen BF76 im Profil Metadaten. Der Tag - Inhalt sollten die gleichen Träger Rechte - Regeln, wie sie durch die Zugriffsregel Applet (ARA) , die in zurück UICC Träger Privilegien :

RefArDo ::= [PRIVATE 2] SEQUENCE {  -- Tag E2
    refDo [PRIVATE 1] SEQUENCE {  -- Tag E1
        deviceAppIdRefDo [PRIVATE 1] OCTET STRING (SIZE(20|32)),  -- Tag C1
        pkgRefDo [PRIVATE 10] OCTET STRING (SIZE(0..127)) OPTIONAL  -- Tag CA
    },
    arDo [PRIVATE 3] SEQUENCE {  -- Tag E3
        permArDo [PRIVATE 27] OCTET STRING (SIZE(8))  -- Tag DB
    }
}

Für weitere Informationen über App Unterzeichnung finden Sie Ihre App anmelden . Einzelheiten zu den Trägerberechtigungen finden UICC Träger Privilegien .

Erstellen einer LPA-App

Sie können Ihr eigenes LPA implementieren, das mit den Android Euicc-APIs verbunden werden muss. Die folgenden Abschnitte geben einen kurzen Überblick über die Erstellung einer LPA-App und deren Integration in das Android-System.

Hardware-/Modemanforderungen

Die LPA und das eSIM-Betriebssystem auf dem eUICC-Chip müssen mindestens GSMA RSP (Remote SIM Provisioning) v2.0 oder v2.2 unterstützen. Sie sollten auch planen, SM-DP+- und SM-DS-Server zu verwenden, die über eine entsprechende RSP-Version verfügen. Für detaillierte RSP - Architektur finden GSMA SGP.21 RSP Architecture Specification .

Darüber hinaus sollte das Gerätemodem zur Integration mit den eUICC-APIs in Android 9 Terminalfunktionen mit codierter Unterstützung für eUICC-Funktionen senden (lokale Profilverwaltung und Profildownload). Es muss auch die folgenden Methoden implementieren:

  • IRadio HAL v1.1: setSimPower
  • IRadio HAL v1.2: getIccCardStatus

  • IRadioConfig HAL v1.0: getSimSlotsStatus

Das Modem sollte die eSIM mit aktiviertem Standard-Boot-Profil als gültige SIM erkennen und die SIM-Karte eingeschaltet lassen.

Für Geräte mit Android 10 muss ein nicht entfernbares eUICC-Slot-ID-Array definiert werden. Siehe zum Beispiel arrays.xml .

<resources>
   <!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
        e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
        eUICC, then the value of this array should be:
            <integer-array name="non_removable_euicc_slots">
                <item>1</item>
            </integer-array>
        If a device has three physical slots and slot 1 and 2 are eUICCs, then the value of
        this array should be:
            <integer-array name="non_removable_euicc_slots">
               <item>1</item>
               <item>2</item>
            </integer-array>
        This is used to differentiate between removable eUICCs and built in eUICCs, and should
        be set by OEMs for devices which use eUICCs. -->

   <integer-array name="non_removable_euicc_slots">
       <item>1</item>
   </integer-array>
</resources>

Für eine vollständige Liste der Modemanforderungen finden Sie Modemanforderungen für eSIM Unterstützung .

EuiccService

Eine LPA besteht aus zwei separaten Komponenten (können beide in derselben APK implementiert sein): dem LPA-Back-End und der LPA-UI oder LUI.

Um den LPA - Backend zu implementieren, müssen Sie erweitern EuiccService und diesen Service in Ihrer Manifest - Datei deklarieren. Der Dienst muss die erfordern android.permission.BIND_EUICC_SERVICE System die Erlaubnis , um sicherzustellen , dass das System nur an sie binden können. Der Dienst muss auch einen Intent - Filter mit der umfassen android.service.euicc.EuiccService Aktion. Die Priorität des Intent-Filters sollte auf einen Wert ungleich Null gesetzt werden, falls mehrere Implementierungen auf dem Gerät vorhanden sind. Zum Beispiel:

<service
    android:name=".EuiccServiceImpl"
    android:permission="android.permission.BIND_EUICC_SERVICE">
    <intent-filter android:priority="100">
        <action android:name="android.service.euicc.EuiccService" />
    </intent-filter>
</service>

Intern bestimmt das Android-Framework die aktive LPA und interagiert bei Bedarf damit, um die Android eUICC-APIs zu unterstützen. PackageManager ist für alle Anwendungen mit der abgefragten android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS Erlaubnis, die für die einen Dienst gibt android.service.euicc.EuiccService Aktion. Der Dienst mit der höchsten Priorität wird ausgewählt. Wenn kein Dienst gefunden wird, wird die LPA-Unterstützung deaktiviert.

Um die LUI zu implementieren, müssen Sie eine Aktivität für die folgenden Aktionen bereitstellen:

  • android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
  • android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION

Wie bei dem Service muss jede Aktivität , die erfordert android.permission.BIND_EUICC_SERVICE System Genehmigung. Jeder sollte einen Intent - Filter mit der entsprechenden Wirkung hat, die android.service.euicc.category.EUICC_UI Kategorie und eine Nicht-Null Priorität. Eine ähnliche Logik wird die Implementierungen für diese Aktivitäten als mit Kommissionierung die Umsetzung zu holen verwendet EuiccService . Zum Beispiel:

<activity android:name=".MyLuiActivity"
          android:exported="true"
          android:permission="android.permission.BIND_EUICC_SERVICE">
    <intent-filter android:priority="100">
        <action android:name="android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
        <action android:name="android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.service.euicc.category.EUICC_UI" />
    </intent-filter>
</activity>

Dies bedeutet , dass die Benutzeroberfläche diese Bildschirme Implementierung von einer anderen APK von der man , dass Geräte kommen kann EuiccService . Ob eine einzelne APK oder mehrere APKs haben (zum Beispiel ein , dass Geräte EuiccService und eine , die LUI - Aktivitäten bietet) ist eine Designwahl.

EuiccCardManager

EuiccCardManager ist die Schnittstelle mit dem eSIM Chip zur Kommunikation. Es bietet ES10-Funktionen (wie in der GSMA RSP-Spezifikation beschrieben) und verarbeitet die Low-Level-APDU-Anforderungs-/Antwortbefehle sowie das ASN.1-Parsing. EuiccCardManager ist ein System API und kann nur von System-privilegierten Anwendungen aufgerufen werden.

Mobilfunkanbieter-Apps, LPA und Euicc-APIs

Figur 2. Beide Träger app und LPA Verwendung eUICC APIs

Die Profiloperation APIs durch EuiccCardManager erfordert die Anrufer ein LPA zu sein. Dies wird durch das Android-Framework erzwungen. Das heißt , der Anrufer muss verlängern EuiccService und in der Manifest - Datei deklariert werden, wie in den vorhergehenden Abschnitten beschrieben.

Ähnlich wie EuiccManager , verwenden , um die EuiccCardManager APIs, Ihre LPA muss die Instanz des ersten erhalten EuiccCardManager durch Context#getSystemService :

EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);

Um dann alle Profile in der eUICC zu erhalten:

ResultCallback<EuiccProfileInfo[]> callback =
       new ResultCallback<EuiccProfileInfo[]>() {
           @Override
           public void onComplete(int resultCode,
                   EuiccProfileInfo[] result) {
               if (resultCode == EuiccCardManagerReflector.RESULT_OK) {
                   // handle result
               } else {
                   // handle error
               }
           }
       };

cardMgr.requestAllProfiles(eid, AsyncTask.THREAD_POOL_EXECUTOR, callback);

Intern EuiccCardManager bindet an EuiccCardController (die im Telefon Prozess läuft) durch eine AIDL Schnittstelle, und jedes EuiccCardManager Verfahren erhalten seinen Rückruf vom Telefonprozess durch einen anderen, gewidmet AIDL Schnittstelle. Bei der Verwendung von EuiccCardManager APIs, muss der Anrufer (LPA) , um ein liefern Executor Objekt , durch die der Rückruf aufgerufen wird. Dieses Executor Objekt kann auf einem einzigen Thread oder auf einem Thread - Pool Ihrer Wahl läuft.

Die meisten EuiccCardManager APIs haben die gleiche Nutzungsmuster. Um beispielsweise ein gebundenes Profilpaket auf die eUICC zu laden:

...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

So wechseln Sie zu einem anderen Profil mit einer bestimmten ICCID:

...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

So erhalten Sie die Standard-SM-DP+-Adresse vom eUICC-Chip:

...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
        callback);

So rufen Sie eine Liste mit Benachrichtigungen zu den angegebenen Benachrichtigungsereignissen ab:

...
cardMgr.listNotifications(eid,
        EuiccNotification.Event.INSTALL
              | EuiccNotification.Event.DELETE /* events */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

Aktivieren eines eSIM-Profils über eine Mobilfunkanbieter-App

Auf Geräten mit Android 9 oder höher können Sie eine Mobilfunkanbieter-App verwenden, um die eSIM zu aktivieren und Profile herunterzuladen. Der Träger App kann profiles herunterladen durch den Aufruf downloadSubscription direkt oder durch einen Aktivierungscode an den LPA bereitstellt.

Wenn ein Träger App ein Profil lädt durch den Aufruf downloadSubscription , dass der Anruf setzt die App das Profil durch einen verwalten kann BF76 Metadatentag dass Encodierungen Träger Rechte - Regeln für das Profil. Wenn ein Profil hat keine BF76 - Tag oder , wenn sein BF76 - Tag des anrufenden Träger App Signatur nicht übereinstimmt, wird der Download zurückgewiesen.

Im folgenden Abschnitt wird die Aktivierung einer eSIM über eine Mobilfunkanbieter-App mithilfe eines Aktivierungscodes beschrieben.

eSIM mit einem Aktivierungscode aktivieren

Bei Verwendung eines Aktivierungscodes zur Aktivierung eines eSIM-Profils ruft der LPA einen Aktivierungscode von der Mobilfunkanbieter-App ab und lädt das Profil herunter. Dieser Flow kann vom LPA initiiert werden und der LPA kann den gesamten UI-Flow steuern, d. h., es wird keine Benutzeroberfläche der Betreiber-App angezeigt. Dieser Ansatz umgeht die BF76 - Tag zu überprüfen, und Netzbetreiber müssen nicht das gesamte zur Umsetzung eSIM Aktivierung UI fließen einschließlich Herunterladen eines eSIM Profil und Fehlerbehandlung.

Definieren des eUICC-Bereitstellungsdienstes des Netzbetreibers

Die LPA und Träger app kommunizieren über zwei AIDL Schnittstellen: ICarrierEuiccProvisioningService und IGetActivationCodeCallback . Der Träger App muss eine Implementierung ICarrierEuiccProvisioningService Schnittstelle und es in seinen aussetzen manifestieren Erklärung . Die LPA muss binden ICarrierEuiccProvisioningService und implementieren IGetActivationCodeCallback . Weitere Informationen darüber , wie eine AIDL Schnittstelle zu implementieren und zu belichten, siehe Definition und AIDL Schnittstelle .

Um die AIDL-Schnittstellen zu definieren, erstellen Sie die folgenden AIDL-Dateien sowohl für die LPA- als auch für die Mobilfunkanbieter-App.

  • ICarrierEuiccProvisioningService.aidl

    package android.service.euicc;
    
    import android.service.euicc.IGetActivationCodeCallback;
    
    oneway interface ICarrierEuiccProvisioningService {
        // The method to get the activation code from the carrier app. The caller needs to pass in
        // the implementation of IGetActivationCodeCallback as the parameter.
        void getActivationCode(in IGetActivationCodeCallback callback);
    
        // The method to get the activation code from the carrier app. The caller needs to pass in
        // the activation code string as the first parameter and the implementation of
        // IGetActivationCodeCallback as the second parameter. This method provides the carrier
        // app the device EID which allows a carrier to pre-bind a profile to the device's EID before
        // the download process begins.
        void getActivationCodeForEid(in String eid, in IGetActivationCodeCallback callback);
    }
    
    
  • IGetActivationCodeCallback.aidl

    package android.service.euicc;
    
    oneway interface IGetActivationCodeCallback {
        // The call back method needs to be called when the carrier app gets the activation
        // code successfully. The caller needs to pass in the activation code string as the
        // parameter.
        void onSuccess(String activationCode);
    
        // The call back method needs to be called when the carrier app failed to get the
        // activation code.
        void onFailure();
    }
    

Beispiel für eine LPA-Implementierung

Um binden an die der Träger App ICarrierEuiccProvisioningService Implementierung muss die LPA sowohl kopieren ICarrierEuiccProvisioningService.aidl und IGetActivationCodeCallback.aidl zum Projekt und implementieren ServiceConnection .

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}

Nach Bindung an den Träger App ICarrierEuiccProvisioningService Implementierung, die LPA Anrufe entweder getActivationCode oder getActivationCodeForEid erhalten den Aktivierungscode von der Träger App durch die Umsetzung der vorbei IGetActivationCodeCallback Stub - Klasse.

Der Unterschied zwischen getActivationCode und getActivationCodeForEid ist , dass getActivationCodeForEid einen Träger ermöglicht Pre-bind ein Profil auf das EID des Geräts vor dem Download - Prozess beginnt.

void getActivationCodeFromCarrierApp() {
    IGetActivationCodeCallback.Stub callback =
            new IGetActivationCodeCallback.Stub() {
                @Override
                public void onSuccess(String activationCode) throws RemoteException {
                    // Handle the case LPA success to get activation code from a carrier app.
                }

                @Override
                public void onFailure() throws RemoteException {
                    // Handle the case LPA failed to get activation code from a carrier app.
                }
            };
    
    try {
        mCarrierProvisioningService.getActivationCode(callback);
    } catch (RemoteException e) {
        // Handle Remote Exception
    }
}

Beispielimplementierung für Mobilfunkanbieter-App

Für die LPA zu binden an den Trägern App muss der Träger App sowohl kopieren ICarrierEuiccProvisioningService.aidl und IGetActivationCodeCallback.aidl zu einem Projekt und den erklärt ICarrierEuiccProvisioningService Dienst in der AndroidManifest.xml Datei. Der Dienst muss die erfordern android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS System der Erlaubnis , um sicherzustellen , dass nur die LPA, ein system privilegierten app, daran binden kann. Der Dienst muss auch einen Intent - Filter mit der umfassen android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE Aktion.

AndroidManifest.xml

<application>
  ...
  <service
      android:name=".CarrierEuiccProvisioningService"
      android:exported="true"
      android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS">
    <intent-filter>
      <action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/>
    </intent-filter>
  </service>
  ...
</application>

Um die AIDL Träger App Dienst zu implementieren, erstellen Sie einen Dienst, erweitern die Stub - Klasse und implementieren die getActivationCode und getActivationCodeForEid Methoden. Der LPA kann dann beide Methoden aufrufen, um den Profilaktivierungscode abzurufen. Der Träger App sollte durch den Aufruf reagiert IGetActivationCodeCallback#onSuccess mit dem Aktivierungscode , wenn der Code von der Fluggesellschaft Server erfolgreich geholt wurde. Wenn dies nicht erfolgreich, sollte der Träger App mit reagieren IGetActivationCodeCallback#onFailure .

CarrierEuiccProvisioningService.java

import android.service.euicc.ICarrierEuiccProvisioningService;
import android.service.euicc.ICarrierEuiccProvisioningService.Stub;
import android.service.euicc.IGetActivationCodeCallback;

public class CarrierEuiccProvisioningService extends Service {
    private final ICarrierEuiccProvisioningService.Stub binder =
        new Stub() {
            @Override
            public void getActivationCode(IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary to get an activation code (HTTP requests to carrier server, fetch from storage, etc.)
                callback.onSuccess(activationCode);
            }

            @Override
            public void getActivationCodeForEid(String eid, IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary (HTTP requests, fetch from storage, etc.)
                callback.onSuccess(activationCode);
            }
      }
}

Starten der Benutzeroberfläche der Mobilfunkanbieter-App im LPA-Aktivierungsablauf

Auf Geräten mit Android 11 und höher kann der LPA die Benutzeroberfläche einer Mobilfunkanbieter-App starten. Dies ist nützlich, da eine Mobilfunkanbieter-App möglicherweise zusätzliche Informationen vom Benutzer benötigt, bevor sie dem LPA einen Aktivierungscode zur Verfügung stellt. Mobilfunkanbieter können beispielsweise verlangen, dass sich Benutzer anmelden, um ihre Telefonnummern zu aktivieren oder andere Portierungsdienste durchzuführen.

So starten Sie die Benutzeroberfläche einer Mobilfunkanbieter-App im LPA:

  1. Die LPA startet den Aktivierungsfluss des Trägers app durch das Senden android.service.euicc.action.START_CARRIER_ACTIVATION Absicht zu dem Träger App Paket der Aktion enthält. (Der Träger App - Empfänger muss in der Manifest - Deklaration mit geschützt werden android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" zu vermeiden Absichten von nicht-LPA - Anwendungen zu empfangen.)

    String packageName = // The carrier app's package name
    
    Intent carrierAppIntent =
        new Intent(“android.service.euicc.action.START_CARRIER_ACTIVATION”)
            .setPackage(packageName);
    
    ResolveInfo activity =
        context.getPackageManager().resolveActivity(carrierAppIntent, 0);
    
    carrierAppIntent
        .setClassName(activity.activityInfo.packageName, activity.activityInfo.name);
    
    startActivityForResult(carrierAppIntent, requestCode);
    
  2. Die Carrier-App erledigt ihre Arbeit über eine eigene Benutzeroberfläche. Zum Beispiel das Anmelden des Benutzers oder das Senden von HTTP-Anfragen an das Back-End des Spediteurs.

  3. Die Träger App reagiert auf die LPA durch den Aufruf setResult(int, Intent) und finish() .

    1. Wenn der Träger mit app reagiert RESULT_OK setzt die LPA die Aktivierungsstroms. Wenn der Träger App feststellt, dass der Benutzer einen QR - Code , anstatt die LPA zu lassen bindet die Träger App-Dienst scannen, reagiert der Träger App auf die LPA mit setResult(int, Intent) mit RESULT_OK und eine Intent - Instanz des Booleschen zusätzlichen enthält android.telephony.euicc.extra.USE_QR_SCANNER auf true . Die LPA prüft dann die extra und startet den QR - Scanner anstelle der Bindung der der Träger App ICarrierEuiccProvisioningService Umsetzung.
    2. Wenn der Träger app abstürzt oder antwortet mit RESULT_CANCELED (dies ist der Standardantwortcode), bricht die LPA der eSIM Aktivierungsstroms.
    3. Wenn der Träger App antwortet mit etwas anderes als RESULT_OK oder RESULT_CANCELED , der LPA behandelt es als Fehler.

    Aus Sicherheitsgründen sollte die LPA nicht direkt einen Aktivierungscode akzeptiert im Ergebnis geliefert Absicht , dass die Nicht-LPA Anrufer , um sicherzustellen , kann nicht einen Aktivierungscode von den Trägern App erhalten.

Starten des LPA-Aktivierungsablaufs in einer Mobilfunkanbieter-App

Ab Android 11 können Mobilfunkanbieter-Apps eUICC-APIs verwenden, um eine LUI für die eSIM-Aktivierung zu starten. Bei dieser Methode wird die Benutzeroberfläche des eSIM-Aktivierungsflusses des LPA angezeigt, um das eSIM-Profil zu aktivieren. Der LPA sendet dann eine Rundsendung, wenn die Aktivierung des eSIM-Profils abgeschlossen ist.

  1. Die LPA muss eine Aktivität mit einem Intent - Filter mit denen erklärt android.service.euicc.action.START_EUICC_ACTIVATION Aktion. Die Priorität des Intent-Filters sollte auf einen Wert ungleich Null gesetzt werden, falls mehrere Implementierungen auf dem Gerät vorhanden sind. Zum Beispiel:

    <application>
      ...
    <activity
        android:name=".CarrierAppInitActivity"
        android:exported="true">
    
        <intent-filter android:priority="100">
            <action android:name="android.service.euicc.action.START_EUICC_ACTIVATION" />
        </intent-filter>
    </activity>
      ...
    </application>
    
  2. Die Carrier-App erledigt ihre Arbeit über eine eigene Benutzeroberfläche. Zum Beispiel das Anmelden des Benutzers oder das Senden von HTTP-Anfragen an das Back-End des Spediteurs.

  3. An dieser Stelle muss der Träger App bereit sein , einen Aktivierungscode durch seine Versorgung ICarrierEuiccProvisioningService Umsetzung. Der Träger App startet die LPA durch den Aufruf startActivityForResult(Intent, int) mit der android.telephony.euicc.action.START_EUICC_ACTIVATION Aktion. Die LPA prüft auch die boolean zusätzlichen android.telephony.euicc.extra.USE_QR_SCANNER . Wenn der Wert true , auf der LPA startet die QR - Scanner den Benutzer Scan - Profil QR - Code lassen.

  4. Auf der Seite LPA, die die LPA bindet an den Träger app ICarrierEuiccProvisioningService Implementierung den Aktivierungscode zu holen , und das entsprechende Profil herunterladen. Der LPA zeigt während des Downloads alle notwendigen UI-Elemente an, wie z. B. einen Ladebildschirm.

  5. Wenn der LPA Aktivierungsfluss abgeschlossen ist, reagiert die LPA an den Träger app mit einem Ergebniscode, der der Träger app Griffe in onActivityResult(int, int, Intent) .

    1. Wenn der LPA gelingt es , das neue eSIM Profil beim Herunterladen, antwortet er mit RESULT_OK .
    2. Wenn der Benutzer die Aktivierung eSIM Profil in der LPA storniert, antwortet er mit RESULT_CANCELED .
    3. Wenn die LPA antwortet mit etwas anderes als RESULT_OK oder RESULT_CANCELED , die Träger App behandelt dies als Fehler.

    Aus Sicherheitsgründen wird der LPA keinen Aktivierungscode direkt in der Absicht geliefert akzeptieren , dass nicht-LPA Anrufer , um sicherzustellen , kann nicht den Aktivierungscode von den Trägern App erhalten.

Unterstützung mehrerer eSIMs

Für laufende Geräte Android 10 oder höher, die EuiccManager Klasse unterstützt Geräte mit mehreren eSIMs. Geräte mit einem einzigen eSIM , die Modernisierung von 10 bis Android sind keine Änderungen an der LPA Implementierung erfordern als die Plattform automatisch die zuordnet EuiccManager Instanz mit dem Standard eUICC. Der Standard-eUICC wird von der Plattform für Geräte mit Funk-HAL-Version 1.2 oder höher und von der LPA für Geräte mit Funk-HAL-Versionen niedriger als 1.2 bestimmt.

Anforderungen

Um mehrere eSIMs zu unterstützen, muss das Gerät über mehr als einen eUICC verfügen. Dies kann entweder ein integrierter eUICC oder ein physischer SIM-Steckplatz sein, in den entfernbare eUICCs eingesetzt werden können.

Radio HAL Version 1.2 oder höher ist erforderlich, um mehrere eSIMs zu unterstützen. Radio HAL Version 1.4 und RadioConfig HAL Version 1.2 werden empfohlen.

Implementierung

Zur Unterstützung mehrerer eSIMs (einschließlich entfernbare eUICCs oder programmierbare SIMS), muss der LPA implementieren EuiccService , die den Schlitz ID empfängt an den Anrufer-ID - Karte versehen entspricht.

Die non_removable_euicc_slots Ressource in spezifizierten arrays.xml ist ein Array von ganzen Zahlen, die das Schlitz - IDs von einem Gerät integrierte in eUICCs repräsentieren. Sie müssen diese Ressource angeben, damit die Plattform feststellen kann, ob eine eingefügte eUICC entfernbar ist oder nicht.

Mobilfunkanbieter-App für Gerät mit mehreren eSIMs

Wenn ein Träger app für ein Gerät mit mehreren eSIMs machen, verwenden , um die createForCardId Verfahren in EuiccManager ein erstellen EuiccManager Objekt , das auf eine gegebene Karte ID verstiftet ist. Die Karten-ID ist ein ganzzahliger Wert, der eine UICC oder eine eUICC auf dem Gerät eindeutig identifiziert.

Um die Karte ID für das Gerät des Standard eUICC zu erhalten, verwenden Sie die getCardIdForDefaultEuicc Methode in TelephonyManager . Diese Methode liefert UNSUPPORTED_CARD_ID wenn die Funk HAL - Version niedriger als 1.2 ist und kehrt UNINITIALIZED_CARD_ID , wenn das Gerät die eUICC nicht gelesen hat.

Sie können auch Karten - IDs Suche von getUiccCardsInfo und getUiccSlotsInfo (System API) in TelephonyManager und getCardId in SubscriptionInfo .

Wenn ein EuiccManager Objekt mit einer bestimmten ID - Karte instanziiert worden ist , werden alle Operationen auf die eUICC mit dieser Karte ID gerichtet. Wenn die eUICC nicht mehr erreichbar ist (zum Beispiel, wenn es ausgeschaltet ist oder entfernt) EuiccManager nicht mehr funktioniert.

Sie können die folgenden Codebeispiele verwenden, um eine Mobilfunkanbieter-App zu erstellen.

Beispiel 1: Get aktives Abonnement und instantiate EuiccManager

// Get the active subscription and instantiate an EuiccManager for the eUICC which holds
// that subscription
SubscriptionManager subMan = (SubscriptionManager)
        mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int cardId = subMan.getActiveSubscriptionInfo().getCardId();
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
            .createForCardId(cardId);

Beispiel 2: Iterate durch UICCs und instantiate EuiccManager für einen abnehmbaren eUICC

// On a device with a built-in eUICC and a removable eUICC, iterate through the UICC cards
// to instantiate an EuiccManager associated with a removable eUICC
TelephonyManager telMan = (TelephonyManager)
        mContext.getSystemService(Context.TELEPHONY_SERVICE);
List<UiccCardInfo> infos = telMan.getUiccCardsInfo();
int removableCardId = -1; // valid cardIds are 0 or greater
for (UiccCardInfo info : infos) {
    if (info.isRemovable()) {
        removableCardId = info.getCardId();
        break;
    }
}
if (removableCardId != -1) {
    EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
            .createForCardId(removableCardId);
}

Validierung

AOSP wird nicht mit einer LPA-Implementierung geliefert und es wird nicht erwartet, dass ein LPA auf allen Android-Builds verfügbar ist (nicht jedes Telefon unterstützt eSIM). Aus diesem Grund gibt es keine durchgängigen CTS-Testfälle. In AOSP sind jedoch grundlegende Testfälle verfügbar, um sicherzustellen, dass die bereitgestellten eUICC-APIs in Android-Builds gültig sind.

Sie sollten sicherstellen, die Builds folgende CTS Testfälle passieren (für öffentliche APIs): / platform / cts / Tests / Prüfungen / Telefonie / Strom / src / android / Telefonie / eUICC / cts .

Spediteure, die eine Spediteur-App implementieren, sollten ihre normalen internen Qualitätssicherungszyklen durchlaufen, um sicherzustellen, dass alle implementierten Funktionen wie erwartet funktionieren. Zumindest sollte die Mobilfunkanbieter-App in der Lage sein, alle Abonnementprofile desselben Betreibers aufzulisten, ein Profil herunterzuladen und zu installieren, einen Dienst für das Profil zu aktivieren, zwischen Profilen zu wechseln und Profile zu löschen.

Wenn Sie Ihr eigenes LPA erstellen, sollten Sie viel strengere Tests durchführen. Sie sollten mit Ihrem Modemanbieter, eUICC-Chip- oder eSIM-Betriebssystemanbieter, SM-DP+-Anbietern und Netzbetreibern zusammenarbeiten, um Probleme zu lösen und die Interoperabilität Ihres LPA innerhalb der RSP-Architektur sicherzustellen. Eine gute Menge manueller Tests ist unvermeidlich. Für optimale Testabdeckung, sollten Sie die folgen GSMA SGP.23 RSP Testplan .