This sample app demonstrates how to use the Remote SIM Provisioning API for performing SIM profile management operations on the eUICC such as add profile, enable/disable profile, delete profile, query profile list, configure server address and perform memory reset.
1. Get phone factory, SIM profile manager and Card manager instance
auto &phoneFactory = telux::tel::PhoneFactory::getInstance();
auto simProfileManager = phoneFactory.getSimProfileManager();
auto cardManager = phoneFactory.getCardManager();
2. Check if SIM profile subsystem is ready
bool subSystemStatus = simProfileManager->isSubsystemReady();
2.1 If SIM profile manager subsystem is not ready, wait for it to be ready
if(!subSystemsStatus) {
std::cout << "SIM profile manager subsystem is not ready" << std::endl;
std::cout << "wait unconditionally for it to be ready " << std::endl;
std::future<bool> f = simProfileManager->onSubsystemReady();
subSystemsStatus = f.get();
}
3. Check if card subsystem is ready
bool subSystemStatus = cardManager->isSubsystemReady();
3.1 If card manager subsystem is not ready, wait for it to be ready
if(!subSystemsStatus) {
std::cout << "Card manager subsystem is not ready" << std::endl;
std::cout << "wait unconditionally for it to be ready " << std::endl;
std::future<bool> f = cardManager->onSubsystemReady();
subSystemsStatus = f.get();
}
4. Exit the application, if SIM profile and card manager subsystem can not be initialized
if(subSystemsStatus) {
std::cout << " *** SIM profile manager subsystem and Card manager ready *** " << std::endl;
} else {
std::cout << " *** ERROR - Unable to initialize SIM profile manager/Card manager subsystem"
<< std::endl;
}
5. Instantiate and register RspListener
std::shared_ptr<ISimProfileListener> listener = std::make_shared<RspListener>();
simProfileManager.registerListener(listener);
5.1 Implementation of ISimProfileListener interface for receiving Remote SIM provisioning notifications
class RspListener : public telux::tel::ISimProfileListener {
public:
void onDownloadStatus(SlotId slotId, telux::tel::DownloadStatus status,
telux::tel::DownloadErrorCause cause) override {
}
void onUserDisplayInfo(SlotId slotId, bool userConsentRequired,
telux::tel::PolicyRuleMask mask) override {
}
void onConfirmationCodeRequired(SlotId slotId, std::string profileName) override {
}
6. Request EID of the eUICC
auto respCb = [&](std::string eid, telux::common::ErrorCode errorCode)
{ eidCallback(eid, errorCode); };
void eidCallback(std::string eid, telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "requestEid failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "requestEid succeeded." << std::endl;
}
auto card = cardManager->getCard(SlotId::DEFAULT_SLOT_ID, &status);
status = card->requestEid(respCb);
7. Add profile on the eUICC
auto respCb = [&](telux::common::ErrorCode errorCode) { addProfileCallback(errorCode); };
void addProfileCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "addProfile failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "addProfile succeeded." << std::endl;
}
status = simProfileManager->addProfile(SlotId::DEFAULT_SLOT_ID, activationCode,
confirmationCode, isUserConsentSupported, respCb);
7.1 If user consent is required for downloading the profile, the registered listener of client will be notified by invoking onUserDisplayInfo API
Client is expected to invoke ISimProfileManager::provideUserConsent API in order to proceed further for downloading the profile.
void onUserDisplayInfo(SlotId slotId, bool userConsentRequired,
telux::tel::PolicyRuleMask mask) override {
}
7.2 If confirmation code is required for downloading the profile, the registered listener of client will be notified by invoking onConfirmationCodeRequired API
Client is expected to invoke ISimProfileManager::provideConfirmationCode API in order to proceed further for downloading the profile.
void onConfirmationCodeRequired(SlotId slotId, std::string profileName) override {
}
7.3 When the download of profile completes or fails, the client is notified about download status
void onDownloadStatus(SlotId slotId, telux::tel::DownloadStatus status,
telux::tel::DownloadErrorCause cause) override {
}
8. Delete profile on the eUICC
auto respCb = [&](telux::common::ErrorCode errorCode) { deleteProfileCallback(errorCode); };
void deleteProfileCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "deleteProfile failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "deleteProfile succeeded." << std::endl;
}
status = simProfileManager->deleteProfile(SlotId::DEFAULT_SLOT_ID, profileId, respCb);
9. Request profile list on the eUICC
auto respCb = [&](const std::vector<std::shared_ptr<telux::tel::SimProfile>> &profiles,
telux::common::ErrorCode errorCode) { profileListCallback(profiles, errorCode); };
void profileListCallback(const std::vector<std::shared_ptr<telux::tel::SimProfile>> &profiles,
telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "profileList failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "profileList succeeded." << std::endl;
}
status = simProfileManager->requestProfileList(SlotId::DEFAULT_SLOT_ID, respCb);
10. Enable/disable profile on the eUICC
auto respCb = [&](telux::common::ErrorCode errorCode) { setProfileCallback(errorCode); };
void setProfileCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "setProfile failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "setProfile succeeded." << std::endl;
}
status = simProfileManager->setProfile(SlotId::DEFAULT_SLOT_ID, profileId, enable, respCb);
11. Update Nickname of the profile
auto respCb = [&](telux::common::ErrorCode errorCode) { updateNicknameCallback(errorCode); };
void updateNicknameCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "updateNickname failed with error" << static_cast<int>(error) <<
std::endl;
return;
}
std::cout << "updateNickname succeeded." << std::endl;
}
status = simProfileManager->updateNickName(SlotId::DEFAULT_SLOT_ID, profileId, nickname, respCb);
12. Set SMDP+ server address on the eUICC
auto respCb = [&](telux::common::ErrorCode errorCode) { setServerAddressCallback(errorCode); };
void setServerAddressCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "setServerAddress failed with error" << static_cast<int>(error) <<
std::endl;
return;
}
std::cout << "setServerAddress succeeded." << std::endl;
}
status = simProfileManager->setServerAddress(SlotId::DEFAULT_SLOT_ID, smdpAddress, respCb);
13. Get SMDP+ and SMDS server address from the eUICC
auto respCb = [&](std::string smdpAddress,
std::string smdsAddress, telux::common::ErrorCode errorCode) {
requestServerAddressCallback(smdpAddress, smdsAddress, errorCode); };
void requestServerAddressCallback(std::string smdpAddress,
std::string smdsAddress, telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "requestServerAddress failed with error" << static_cast<int>(error) <<
std::endl;
return;
}
std::cout << "requestServerAddress succeeded." << std::endl;
}
status = simProfileManager->requestServerAddress(SlotId::DEFAULT_SLOT_ID, respCb);
14. Memory reset on the eUICC
auto respCb = [&](telux::common::ErrorCode errorCode) { memoryResetCallback(errorCode); };
void memoryResetCallback(telux::common::ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "memoryReset failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "memoryReset succeeded." << std::endl;
}
status = simProfileManager->memoryReset(SlotId::DEFAULT_SLOT_ID, resetmask, respCb);