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. Implement ResponseCallback interface to receive subsystem initialization status
1.1 Implement ResponseCallback interface to receive SimProfile Manager subsystem initialization status
std::promise<telux::common::ServiceStatus> cbSimProfileProm = std::promise<telux::common::ServiceStatus>();
void initResponseCb(telux::common::ServiceStatus status) {
if (subSystemsStatus == SERVICE_AVAILABLE) {
std::cout << SIM Profile subsystem is ready << std::endl;
} else if(subSystemsStatus == SERVICE_FAILED) {
std::cout << SIM Profile subsystem initialization failed << std::endl;
}
cbSimProfileProm.set_value(status);
}
1.2 Implement ResponseCallback interface to receive Card Manager subsystem initialization status
std::promise<telux::common::ServiceStatus> cbCardProm = std::promise<telux::common::ServiceStatus>();
void initResponseCb(telux::common::ServiceStatus status) {
if (subSystemsStatus == SERVICE_AVAILABLE) {
std::cout << Card Manager subsystem is ready << std::endl;
} else if(subSystemsStatus == SERVICE_FAILED) {
std::cout << Card Manager subsystem initialization failed << std::endl;
}
cbCardProm.set_value(status);
}
2. Get phone factory, SIM profile manager and Card manager instance
auto &phoneFactory = telux::tel::PhoneFactory::getInstance();
auto simProfileManager = phoneFactory.getSimProfileManager(cbSimProfileProm);
if (simProfileManager == NULL) {
std::cout << " Failed to get SIMProfile Manager instance" << std::endl;
return -1;
}
auto cardManager = phoneFactory.getCardManager(cbCardProm);
if (cardManager == NULL) {
std::cout << " Failed to get Card Manager instance" << std::endl;
return -1;
}
3. Check if SIM profile subsystem is ready
telux::common::ServiceStatus status = simProfileManager.getServiceStatus();
3.1 If SIM profile manager subsystem is not ready, wait for it to be ready
telux::common::ServiceStatus status = cbSimProfileProm.get_future().get();
if (status != SERVICE_AVAILABLE) {
std::cout << Unable to initialize SIMProfile Manager subsystem << std::endl;
return -1;
}
4. Check if card subsystem is ready
telux::common::ServiceStatus status = cardManager.getServiceStatus();
4.1 If card manager subsystem is not ready, wait for it to be ready
telux::common::ServiceStatus status = cbCardProm.get_future().get();
if (status != SERVICE_AVAILABLE) {
std::cout << Unable to initialize Card Manager subsystem << std::endl;
return -1;
}
5. Return/Exit the application, if SIM profile and card manager subsystem can not be initialized
if((status == SERVICE_AVAILABLE) {
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;
}
6. Instantiate and register RspListener
std::shared_ptr<ISimProfileListener> listener = std::make_shared<RspListener>();
simProfileManager.registerListener(listener);
6.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 {
}
7. 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);
8. 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);
8.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 {
}
8.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 {
}
8.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 {
}
9. 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);
10. 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);
11. 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);
12. 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);
13. 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);
14. 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);
15. 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);