Sample code for SIM access

//--------------------------------------------------------------------------------------------------
/**
* Test: SIM access.
*
*/
//--------------------------------------------------------------------------------------------------
void simTest_SimAccess
(
)
{
//========================================
// 1. Read IMSI using le_sim_SendApdu API
//========================================
 
uint8_t selectDfAdfApdu[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0x7F, 0xFF};
uint8_t selectApdu[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0x6F, 0x07};
uint8_t readApdu[] = {0x00, 0xB0, 0x00, 0x00, 0x09};
uint8_t rspImsi[SIM_RSP_LEN];
size_t rspImsiLen = SIM_RSP_LEN;
 
// Select ADF Dedicated File (DF_ADF)
selectDfAdfApdu,
sizeof(selectDfAdfApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
// Select the EF(IMSI)
rspImsiLen = SIM_RSP_LEN;
selectApdu,
sizeof(selectApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
// Read the EF(IMSI)
rspImsiLen = SIM_RSP_LEN;
readApdu,
sizeof(readApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
//=====================================================================================
// 2. Read IMSI using le_sim_SendSimCommand API, and check value get by le_sim_SendApdu
//======================================================================================
 
size_t rspImsiLen2 = SIM_RSP_LEN;
uint8_t rspImsi2[SIM_RSP_LEN];
uint8_t swi1, swi2;
char dfGsmPath[]="3F007FFF";
 
// Read EF(IMSI) using the le_sim_SendSimCommand API.
"6F07",
0,
0,
0,
NULL,
0,
dfGsmPath,
&swi1,
&swi2,
rspImsi2,
&rspImsiLen2);
 
if (LE_UNSUPPORTED == res)
{
LE_WARN("le_sim_SendCommand() API not supported by the platform");
return;
}
 
if (res != LE_OK)
{
strcpy(dfGsmPath, "3F007F20");
 
// Check backward compatibility
res = le_sim_SendCommand(simId,
"6F07",
0,
0,
0,
NULL,
0,
dfGsmPath,
&swi1,
&swi2,
rspImsi2,
&rspImsiLen2);
}
 
LE_ASSERT(res == LE_OK);
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
PrintApdu(rspImsi2, rspImsiLen2);
 
// Check both IMSI results
LE_ASSERT(0 == memcmp(rspImsi, rspImsi2, rspImsiLen2));
 
size_t rspLen = SIM_RSP_LEN;
uint8_t rsp[rspLen];
 
//==================================================================================
// 3. Check read and write record elementary file
// Write the 5th entry in EF(ADN): equivalent to AT+CPBW=5,"01290917",129,"Jacky"
// Then, read the written data and check
//==================================================================================
 
// Write EF(ADN) using the le_sim_SendSimCommand API.
uint8_t dataAdn[] = {0x4A, 0x61, 0x63, 0x6B, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x81, 0x10, 0x92, 0x90, 0x71,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
 
"6F3A",
5,
0,
0,
dataAdn,
sizeof(dataAdn),
"3F007F10",
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
 
// Read EF(ADN) using the le_sim_SendSimCommand API.
rspLen = SIM_RSP_LEN;
"6F3A",
5,
0,
0,
NULL,
0,
"3F007F10",
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
PrintApdu(rsp, rspLen);
 
LE_ASSERT(rspLen == sizeof(dataAdn));
LE_ASSERT(0 == memcmp(rsp, dataAdn, rspLen));
 
//==================================================================================
// 4. Check read and write transparent elementary file
// - Read language indication file
// - Erase first entry of the file
// - Check that it is really erased (by reading again)
// - Re-write the initial value
// - Check that the initial value is correct (read again)
//==================================================================================
 
// Read binary EF(6F05) Language indication
size_t rspLenLi = SIM_RSP_LEN;
uint8_t rspLi[rspLenLi];
 
"6F05",
0,
0,
0,
NULL,
0,
dfGsmPath,
&swi1,
&swi2,
rspLi,
&rspLenLi));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
PrintApdu(rspLi, rspLenLi);
 
uint8_t dataLi[] = {0xFF, 0xFF};
// Erase first Language entry
rspLen = 0;
"6F05",
0,
0,
0,
dataLi,
sizeof(dataLi),
dfGsmPath,
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
 
// Read again...
rspLen = SIM_RSP_LEN;
"6F05",
0,
0,
0,
NULL,
0,
dfGsmPath,
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
PrintApdu(rsp, rspLen);
 
// Check it is correctly erased
LE_ASSERT(0 == memcmp(rsp, dataLi, sizeof(dataLi)));
 
// Re-write initial values
rspLen = 0;
"6F05",
0,
0,
0,
rspLi,
rspLenLi,
dfGsmPath,
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
 
// And read again...
rspLen = SIM_RSP_LEN;
"6F05",
0,
0,
0,
NULL,
0,
dfGsmPath,
&swi1,
&swi2,
rsp,
&rspLen));
 
LE_INFO("swi1=0x%02X, swi2=0x%02X", swi1, swi2);
PrintApdu(rsp, rspLen);
 
// Check it is correctly erased
LE_ASSERT(0 == memcmp(rsp, rspLi, sizeof(rspLenLi)));
 
//=====================================================================================
// 5. Read IMSI using a dedicated logical channel
// Note that a SIM card supporting logical channels is necessary for this test.
//======================================================================================
 
uint8_t channel = 0;
 
// Open a logical channel
LE_ASSERT(channel);
 
// Select ADF Dedicated File (DF_ADF)
selectDfAdfApdu[0] = channel;
channel,
selectDfAdfApdu,
sizeof(selectDfAdfApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
// Select the EF(IMSI)
rspImsiLen = SIM_RSP_LEN;
selectApdu[0] = channel;
channel,
selectApdu,
sizeof(selectApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
// Read the EF(IMSI)
rspImsiLen = SIM_RSP_LEN;
readApdu[0] = channel;
channel,
readApdu,
sizeof(readApdu),
rspImsi,
&rspImsiLen));
PrintApdu(rspImsi, rspImsiLen);
 
// Close the logical channel
 
LE_INFO("SIM access test OK");
}