API Reference
SIM constraints

This file contains prototype definitions for SIM API.

A subscriber identity module or subscriber identification module (SIM) is an integrated circuit that securely stores the international mobile subscriber identity (IMSI) and related key used to identify and authenticate subscribers on M2M devices.

Most SIM cards can store a number of SMS messages and phone book contacts.

IPC interfaces binding

All the functions of this API are provided by the modemService.

Here's a code sample binding to modem services:

   clientExe.clientComponent.le_sim -> modemService.le_sim

Select a card to use

le_sim_SelectCard() function is used to select the SIM identifier. By default, the SIM in slot 1 is used unless the automatic SIM selection is enabled. See Automatic SIM selection for further details. Additionally, any Legato SIM API with a SIM card identifier passed in parameter, selects that SIM identifier. le_sim_GetSelectedCard() returns the current selected card, not necessarily the one set previously by le_sim_SelectCard().

The SIM selection is not reset persistent; this function has to be called at each start-up.
It is recommended to wait for a SIM handler notification after a new SIM selection before calling le_sim API functions.

A sample code can be seen in the following page:

Automatic SIM selection

This feature is only relevant for modules with an internal SIM card. When enabled, the module automatically selects a SIM slot according to the rule: "If an external SIM is inserted in slot 1 then select it. Otherwise, fall back to the internal SIM card".

Use the following APIs to manage the feature:

Most of le_sim APIs require a SIM identifier in their arguments. If a client application uses a SIM identifier different from the one selected by automatic SIM selection, the feature will be immediately disabled. Thus, in order to use le_sim APIs in automatic SIM selection, client application must use LE_SIM_UNSPECIFIED as a SIM identifier (le_sim_Id_t).

SIM identification information

ICCID: Each SIM is internationally identified by its integrated circuit card identifier (ICCID). ICCIDs are stored in the SIM cards and engraved or printed on the SIM card body. The ICCID is defined by the ITU-T recommendation E.118 as the Primary Account Number. According to E.118, the number is up to 19 digits long, including a single check digit calculated using the Luhn algorithm. However, the GSM Phase 1 (ETSI Recommendation GSM 11.11) defined the ICCID length as 10 octets (20 digits) with operator-specific structure.

le_sim_GetICCID() API reads the identification number (ICCID). le_sim_AddIccidChangeHandler() function registers a handler to be notified when ICCID changes. le_sim_RemoveIccidChangeHandler() function unregisters the handler.

During the initialization phase of the service, each new subscription to the ICCID change event is notified by the last change event. This behavior lasts only for 5 seconds and allows freshly registered clients to receive any ICCID changes that occured during the module start-up phase.

Using this API selects the requested SIM.

IMSI: The International Mobile Subscriber Identity or IMSI is a unique identification associated with all cellular networks. The IMSI is used in any mobile network that connects with other networks. For GSM, UMTS and LTE network, this number is provisioned in the SIM card.

An IMSI is usually presented as a 15 digit long number, but can be shorter. The first 3 digits are the mobile country code (MCC), are followed by the mobile network code (MNC), either 2 digits (European standard) or 3 digits (North American standard). The length of the MNC depends on the value of the MCC. The remaining digits are the mobile subscription identification number (MSIN) within the network's customer base.

EID: The EID (also called eUICCID) is the unique identifier for the embedded Universal Integrated Circuit Card (eUICC). A eUICC is a SIM card with a remote provisioning function, and is designed to not be removed or changed. It is able to store multiple communication profiles but only one is enabled (recognized by the device and used for communication). With conventional SIM cards, the ICCID is used as the unique key to identify the SIM card, but with eUICC, the ICCID is the key used to identify a profile, and a new identifier is defined, called the eUICCID (EID), which is used as the unique key for the embedded SIM. le_sim_GetEID() API reads the EID.

Home Network Name: le_sim_GetHomeNetworkOperator() retrieves the Home Network Name.

le_sim_GetIMSI() API reads the international mobile subscriber identity (IMSI).

Using this API selects the requested SIM.

Phone Number: le_sim_GetSubscriberPhoneNumber() API reads the Phone Number associated to the SIM. If the phone number has not been provisioned, it will return the empty string.

Using this API selects the requested SIM.

Home Network Information:

A sample code can be seen in the following page:

SIM Authentication

le_sim_EnterPIN() enters the PIN (Personal Identification Number) code that's required before any Mobile equipment functionality can be used.

Using this API selects the requested SIM.

le_sim_GetRemainingPINTries() returns the number of remaining PIN entry attempts before the SIM will become blocked.

Using this API selects the requested SIM.

le_sim_GetRemainingPUKTries() returns the number of remaining PUK entry attempts before the SIM will become blocked.

Using this API selects the requested SIM.

le_sim_ChangePIN() must be called to change the PIN code.

Using this API selects the requested SIM.

le_sim_Lock() locks the SIM card: it enables requests for the PIN code.

Using this API selects the requested SIM.

le_sim_Unlock() unlocks the SIM card: it disables requests for the PIN code.

Using this API selects the requested SIM.

le_sim_Unblock() unblocks the SIM card. The SIM card is blocked after X unsuccessful attempts to enter the PIN. le_sim_Unblock() requires the PUK (Personal Unblocking) code to set a new PIN code.

A sample code can be seen in the following page:

SIM states

le_sim_IsPresent() API advises the SIM is inserted (and locked) or removed.

Using this API selects the requested SIM.

le_sim_IsReady() API advises the SIM is ready (PIN code correctly entered or not required).

Using this API selects the requested SIM.

The le_sim_GetState() API retrieves the SIM state:

  • LE_SIM_INSERTED : SIM card is inserted and locked.
  • LE_SIM_ABSENT : SIM card is absent.
  • LE_SIM_READY : SIM card is inserted and unlocked.
  • LE_SIM_BLOCKED : SIM card is blocked.
  • LE_SIM_BUSY : SIM card is busy.
  • LE_SIM_POWER_DOWN : SIM card is powered down.
  • LE_SIM_STATE_UNKNOWN : Unknown SIM state.

Using this API selects the requested SIM.

A handler function must be registered to receive SIM's state notifications. le_sim_AddNewStateHandler() API allows the User to register that handler.

The handler must satisfy the following prototype: typedef void(*le_sim_NewStateHandlerFunc_t)(le_sim_Id_t simId, le_sim_States_t simState);

When a new SIM's state is notified, the handler is called.

Call le_sim_GetState() to retrieve the new state of the SIM.

If two (or more) applications have registered a handler function for notifications, they will all receive it and will be passed the same SIM.

The application can uninstall the handler function by calling le_sim_RemoveNewStateHandler() API.

Your platform might need a reboot to detect a SIM insertion or removal. Please refer to the SIM constraints page or your platform documentation for further details.

A sample code can be seen in the following page:

le_sim_SetPower() powers up or down the current SIM card.

SIM profile switch

As soon as there are several subscriptions/profiles in the eUICC (multi-profile), and one of them is dedicated to emergency calls (ex: eCall, ERA-Glonass), local swap is needed to swap as quickly as possible to the emergency profile in case of need.

“Local swap” means that the User's application must be able to directly request the eUICC to swap to Emergency Call Subscription (ECS).

Local swap puts the eUICC in a temporary state, meaning the commercial subscription is replaced by emergency subscription for a limited time, event triggering the swap back to commercial subscription being controlled by the User's application.

The le_sim_LocalSwapToEmergencyCallSubscription() function requests the multi-profile eUICC to swap to ECS and to refresh. The User's application must wait for eUICC reboot to be finished and network connection available.

The le_sim_LocalSwapToCommercialSubscription() function requests the multi-profile eUICC to swap back to commercial subscription and to refresh. The User's application must wait for eUICC reboot to be finished and network connection available.

eUICC allows support of multiple SIM profiles. These profiles can also be managed remotely from a Subscription Manager Server. Changing the SIM profile remotely may impact the customer application especially if there is an ongoing data transmission. To prevent any data loss, switching SIM profiles is subject to a user agreement. This way, the customer application will be able to properly finalize its current procedure (emergency call for instance) before accepting the SIM swap.

The application can subscribe a handler using le_sim_AddProfileUpdateHandler() to monitor SIM profile change requests. Thus, the application can choose to accept or reject the SIM profile swap procedure using le_sim_AcceptSimToolkitCommand() or le_sim_RejectSimToolkitCommand().

If there is no subscribed handler, the SIM service automatically accepts any SIM profile swap request.

The User's application can install a handler with le_sim_AddNewStateHandler() to receive eUICC's state notifications.

  • If you use a Morpho or Oberthur card, the SIM_REFRESH PRO-ACTIVE command must be accepted with le_sim_AcceptSimToolkitCommand() in order to complete the profile swap procedure.
  • If you use a Giesecke & Devrient (G&D) card, be sure that your platform has disabled security restrictions for channel management APDU commands, otherwise local SIM profile switch could not work.

The le_sim_IsEmergencyCallSubscriptionSelected() function must be called to get the current subscription.

There is no standard method to interrogate the current selected subscription. The returned value of this function is based on the last executed local swap command. This means that this function will always return LE_NOT_FOUND error at Legato startup.

A sample code can be seen in the following page:

SIM Reset

The le_sim_Reset() function resets the SIM card.

Read / Write FPLMN List from SIM

The le_sim_CreateFPLMNList() function creates the empty FPLMN list.

The le_sim_AddFPLMNOperator() function adds the FPLMN network into FPLMN list.

The le_sim_WriteFPLMNList() function writes FPLMN list into the SIM.

The le_sim_ReadFPLMNList() function reads the FPLMN list from the SIM card.

The le_sim_GetFirstFPLMNOperator() function fetches the first FPLMN operator from FPLMN list.

The le_sim_GetNextFPLMNOperator() function fetches the next FPLMN operator from FPLMN list.

The le_sim_DeleteFPLMNList() function releases all allocated resources associated with the List object.

Some platforms do not support FPLMN APIs. Please refer to the SIM constraints page or your platform documentation for further details.

SIM Toolkit

The SIM application Toolkit allows the SIM card to initiate commands or asking input from the modem to accept/reject SIM operations.

One of the use case is the remote provisioning of an embedded UICC (eUICC): the eUICC format supports multiple subscription profiles, which can be remotely provisioned, updated or selected through SIM Toolkit procedures (Bearer Independent Protocol BIP, SIM refresh).

It is mainly used for in-vehicle emergency call service (eCall).

An eUICC can be remotely managed to change the Mobile Network Operator subscription.

The le_sim_AddSimToolkitEventHandler() API registers a handler to be notified of SIM Toolkit events. The le_sim_RemoveSimToolkitEventHandler() API unregisters the handler.

The last received SIM Toolkit command can:

In case the last SIM Toolkit command is a Refresh command (LE_SIM_REFRESH), additional information can be retrieved:

A sample code using the SIM Toolkit APIs can be seen in the following page:

Information related to SIM Toolkit platform constraints can be found in the SIM Toolkit platform constraints page.

SIM access

The SIM card content can be accessed and/or modified by several methods.


The application can send an APDU (Application Protocol Data Unit) to the SIM using le_sim_SendApdu() API. The user must encode the APDU as specified by in recommendation 3GPP 11.11, 3GPP 51.011, 3GPP 31.102, 3GPP 31.103 or ETSI TS 102 221.

Between two successive calls to le_sim_SendApdu() API, there is no locking protection. In this situation, some command types and parameters can modify SIM files incorrectly.


Using le_sim_SendCommand(), the application has easier but more limited access to the SIM database. The command is transmitted to the SIM, which gives information through swi1 and swi2 about the execution of the command (see 3GPP recommendation previously mentioned for their coding). Some parameters are platform dependent, see SIM constraints for their coding.

Logical channels

Logical channels are specified by the standard ETSI TS 102 221 in the section 8.7. If they are supported by the SIM card, logical channels allow to send independent APDUs on the different channels. In this case:

  • the basic channel 0 is always available and opened.
  • upon request, the card assigns a number to open a new channel. This channel remains open until it is explicitly closed or the SIM card is deactivated.

Use le_sim_OpenLogicalChannel() API to open a logical channel on the SIM card. APDUs can then be sent to the SIM card with le_sim_SendApduOnChannel(). When the logical channel is not needed anymore, it can be closed using le_sim_CloseLogicalChannel().

Sample code

A sample code can be seen in the following page: