SIM, USIM, and UIM cards used in existing mobile phones are collectively referred to as UICC-Universal Integrated Circuit Card;
There are some differences in the data structure between these cards. Let's first look at the SIM card file structure.
Sim File System Data Structure 1 Sim card File System
SIM card file system structure:
2. File structure
MF: The root level of the file system is known as the Master file.
DF: Directories are known as Dedicated files and are of a fixed size.
EF: Individual recZ tables? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> keys + keys/keys + o7o8L3A + keys + NDQtcSjrM/keys + s/keys/NDCtcQ8L3A + CjxwPtfWvdrK/keys/ gttS12Na3oa4wMDAwoa + examples/examples + oaghotu7foxlz + examples/examples + 6 + examples/qLv5sb7OxLz + examples IFVJQ0O/release + tdo01_2neitcrvsundspzaqko6yv2 + release/yvNy0 + release/8rzcwOC1w73hubnNvKO6PC9zdHJvbmc + release "http://www.bkjia.com/uploadfile/Collfiles/20140111/2014011114104238.jpg" alt = "\"
Different classes correspond to different cards. The functions of these classes are as follows:
UiccController: Control Interface for UICC-related information; monitor SIM status changes;
UiccCard:The abstraction corresponding to the UICC card code;
IccCardStatus: Maintain the status of the UICC card: CardState & PinState;
UiccCardApplication: A specific UICC application. It is responsible for unlocking Pin Puk password settings, reading and storing data;
CatService: Responsible for SIM Toolkit;
IccConstants: SIM File Address; the field Address used to store different data on SIM cards; base classes such as SIMRecords;
SIMRecords/RuimRecords:Record the data on the SIM card;
IccFileHandler: Read SIM data and receive read results;
2 UICC framework Execution Process
UICC status monitoring is performed in UiccController;
UiccController constructor:
Private UiccController (Context c, CommandsInterface ci) {mCi = ci; // register the UICC card to listen for the status change of the mCi. registerForIccStatusChanged (this, EVENT_ICC_STATUS_CHANGED, null); // registers the RADIO status change listener for mCi. registerForOn (this, EVENT_ICC_STATUS_CHANGED, null); mCi. registerForAvailable (this, EVENT_ICC_STATUS_CHANGED, null); mCi. registerForNotAvailable (this, EVENT_RADIO_UNAVAILABLE, null );}
Processing of UICC Card status changes:
Public void handleMessage (Message msg) {switch (msg. what) {case EVENT_ICC_STATUS_CHANGED: // UICC status change to obtain the UICC status mCi. getIccCardStatus (obtainMessage (messages); break; case EVENT_GET_ICC_STATUS_DONE: // UICC status change, get UICC status, return processing AsyncResult ar = (AsyncResult) msg. obj; onGetIccCardStatusDone (ar); break ;}}
UICC Card processing status changes:
Private synchronized void onGetIccCardStatusDone (AsyncResult ar) {// The returned data structure IccCardStatus status = (IccCardStatus) ar. result; // update the Uicc Card status. if the UiccCard is not created, the UiccCard is also created. Call UiccCard @ update if (mUiccCard = null) {// Create new card mUiccCard = new UiccCard (mContext, mCi, status);} else {// Update already existing card mUiccCard. update (mContext, mCi, status );}}
UICC Card status update:
Public void update (Context c, CommandsInterface ci, IccCardStatus ics) {synchronized (mLock) {mCardState = ics. mCardState; mUniversalPinState = ics. mUniversalPinState; // update applications UiccApplications construction. Create a new one. // The new one is consistent with the update process. for (int I = 0; I <mUiccApplications. length; I ++) {if (mUiccApplications [I] = null) {// Create newly added Applications if (I <ics. mApplications. length) {mUiccApplications [I] = new UiccCardApplication (this, ics. mApplications [I], mContext, mCi) ;}} else if (I> = ics. mApplications. length) {// Delete removed applications mUiccApplications [I]. dispose (); mUiccApplications [I] = null;} else {// Update the rest mUiccApplications [I]. update (ics. mApplications [I], mContext, mCi) ;}// STK-related createAndUpdateCatService ();}}
Uicc Applications updated:
Void update (IccCardApplicationStatus as, Context c, CommandsInterface ci) {synchronized (mLock) {// update type state pin ...... AppType oldAppType = mAppType; AppState oldAppState = mAppState; mAppType = as. app_type; mAppState = as. app_state ;...... // Update if (mAppType! = OldAppType) {if (mIccFh! = Null) {mIccFh. dispose ();} if (mIccRecords! = Null) {mIccRecords. dispose ();} mIccFh = createIccFileHandler (. app_type); mIccRecords = createIccRecords (. app_type, c, ci) ;}// if (mAppState! = OldAppState) {// If the app state turns to APPSTATE_READY, then query FDN status, // as it might have failed in earlier attempt. if (mAppState = AppState. APPSTATE_READY) {// FDN query queryFdn (); // PIN query queryPin1State ();} // notification of PIN status yypinlockedregistrantsifneeded (null ); // UICC Ready status notification notifyReadyRegistrantsIfNeeded (null );}}}
Next operations will be performed based on the UICC status:
If the UICC requires a PIN to unlock, A notification will be sent that requires a Pin lock; the UICC pin is entered to unlock, And the status changes,
Continue to update UICC Card, Uicc Applications until UICC status Ready;
If the UICC has ready, The UICC Ready notification is issued;
The status update process is as follows:
3 UICC Data Reading Process
The UICC Ready notification is sent in UiccApplications,
After receiving the UICC Ready notification, you can read and write UICC data;
This operation is performed in the IccRecords class. Take SimRecors as an example:
Public SIMRecords (UiccCardApplication app, Context c, CommandsInterface ci) {super (app, c, ci); // call number adnCache = new AdnRecordCache (mFh ); // listen to UiccApplications and send Sim Ready notifications to mParentApp. registerForReady (this, EVENT_APP_READY, null );}
SIMRecords message processing:
Public void handleMessage (Message msg) {switch (msg. what) {case EVENT_APP_READY: onReady (); break; // IO events reads SIM data through IccFileHandler data, and returns the result to process case EVENT_GET_IMSI_DONE :...... Break; case EVENT_GET_MBI_DONE :...... Break; case EVENT_GET_AD_DONE: case EVENT_GET_SPN_DONE: break ;...... }}
Listening to SIM Ready messages:
Public void onReady () {fetchSimRecords ();} protected void fetchSimRecords () {// message mFh that reads data is sent to RIL through IccFileHandler. loadEFTransparent (EF_ICCID, obtainMessage (EVENT_GET_ICCID_DONE); recordsToLoad ++; // Record number is subscriber profile mFh. loadEFLinearFixed (EF_MBI, 1, obtainMessage (EVENT_GET_MBI_DONE); recordsToLoad ++; mFh. loadEFTransparent (EF_AD, obtainMessage (EVENT_GET_AD_DONE); recordsToLoa D ++; // Record number is subscriber profile mFh. loadEFLinearFixed (EF_MWIS, 1, obtainMessage (EVENT_GET_MWIS_DONE); recordsToLoad ++ ;...... }
IccFileHandler data reading:
public void loadEFTransparent(int fileid, Message onLoaded) { Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, fileid, 0, onLoaded); mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); }
LoadEFTransparent and loadEFLinearFixed are different file formats,
Actually, RIL_JAVA is called:
void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, String aid, Message result) { …… }
The parameter meaning of the RIL_iccIOForApp function:
Command: Read/write updates ...... Operation Command
Final int COMMAND_READ_BINARY = 0xb0;
Final int COMMAND_UPDATE_BINARY = 0xd6;
Final int COMMAND_READ_RECORD = 0xb2;
Final int COMMAND_UPDATE_RECORD = 0xdc;
Final int COMMAND_SEEK = 0xa2;
Final int COMMAND_GET_RESPONSE = 0xc0;
......
Fileid: Address of the data field in the SIM File System: for example, Plmn: 0x6F30
Path: All directory addresses at the upper level of this data field:
For example, Plmn Path: MF + DF_GSM = "0x3F000x7F20"
The address field must be determined based on the UICC file system structure and address.
P1:
P2:
P3:
Data:
Pin2:
Aid:Passed by UICC
Result: Callback Message
From the 3GPP SIM-related protocols, we can see the meanings of these parameters, such as P1, P2, and P3:
S: stands for data sent by the ME
R: stands for data stored ed by the ME
Offset is coded on 2 bytes where P1 gives thehigh order byte and P2 the low order byte.
'00 00' means no offset and reading/updating starts with the first byte
'00 01' means that reading/updating starts with the second byte.