With the popularity of mobile phones, we have changed from non-smart phones to smart phones, from custom machines without operating systems to smart phones, but the only thing that hasn't changed is the SIM in mobile phones, today we will talk about SIM card-related content on our mobile phone. In daily life, SIM cards are very small cards, but they store very important information. Similarly, Android, as a smartphone operating system, also performs operations on SIM card reading. The following describes the read/write process of the SIM card of android2.2.
In the previous blog, we talked about STK. You can click this link to view it. Android STK implementation principle (1 ). The STK is closely related to the SIM card. When talking about The STK, it is impossible not to mention the SIM card. Let's go back to the topic below.
In the android source code, SIM card-related operations are encapsulated in the framework,
Source code directory
This folder stores all the class files related to mobile phone communication services, including Sim, STK, call, and PS data services. In the above picture, we can see two folders, GSM and CDMA, which are also related to sim cards. If a CDMA card is inserted, use the source code in the CDMA folder. If it is a 2g sim card, or 3G connection cards (that is, GSM/WCDMA) use the GSM folder. When you open the GSM folder, you can see that there is an STK folder containing the source code in the above link. If it is a 2g sim card or a 3G connection card (that is, GSM/WCDMA), the GSM folder is used. When the GSM folder is opened, an STK is displayed.
Folder, which contains the source code in the above link.
SIM card-related classes mainly include the following,
Iccconstants (which records many constants, mainly used to store the location of a field on the SIM card, such as ADN (Phone Book on the SIM card), 6f3a, FDN (fixed dial 6f3b )),
Icccardstatus (record SIM card status, such as absent, ready, unknow, etc ),
Iccfilehandler (What should I do after reading the record on the SIM card ),
Iccrecords (SIM card file content, each field, a record ),
Iccprovider (the database on the mobile phone, all the data read here ),
Iccutils (which is generally a static method and mainly used for code conversion ),
Iccsmsinterfacemanager, icccard (this is an abstract class, automatically starts a simcard or ruimcard according to the above mobile phone system ).
The following uses GSM as an example to describe the read process,
In GSM, there will be their own classes corresponding to the ones mentioned above, such
Simcard,
Simrecords,
Simphonebookinterfacemanager,
1. When the mobile phone starts,
Enter simrecords according to the SIM card type and start to detect the SIM card status, because some SIM cards will be configured with a pin code. If the SIM card has a pin code, the phone will pop up with the input pin code, wait for the user to perform decoding. Note that if the PIN code is not resolved at this time, the mobile phone will not read the SIM card, because the SIM card must be read through the pin, only some special fields can be used. For example, ECC is an emergency call number (usually on a card and customized by the carrier ). At the same time, if the PIN code is not resolved, the SIM card status in the mobile phone is also pin_requried_block,
2. After the PIN code is cleared or the phone does not set a PIN code, the phone will detect that the SIM is in ready status, and the phone will only detect sim ready, to send a read Card request.
[Java]
View plaincopy
- Case event_sim_ready:
- Onsimready ();
- Break;
- Private void onsimready (){
- /* Broadcast intent sim_ready here so that we can make sure
- Ready is sent before imsi ready
- */
- (Gsmphone) Phone). msimcard. broadcasticcstatechangedintent (
- Simcard. intent_value_icc_ready, null );
- Fetchsimrecords ();
- }
If the PIN is verified, a broadcast will be sent to notify other mobile apps that the SIM card is ready.
[Java]
View plaincopy
- Private void fetchsimrecords (){
- Recordsrequested = true;
- Iccfilehandler iccfh = phone. geticcfilehandler ();
- Log. V (log_tag, "simrecords: fetchsimrecords" + recordstoload );
- Phone. mcm. getimsi (obtainmessage (event_get_imsi_done ));
- Recordstoload ++;
- Iccfh. loadeftransparent (ef_iccid, obtainmessage (event_get_iccid_done ));
- Recordstoload ++;
- // Fixme shocould examine EF [msisdn]'s capability Configuration
- // To determine which is the Voice/Data/fax line
- New adnrecordloader (phone). loadfromef (ef_msisdn, ef_ext1, 1,
- Obtainmessage (event_get_msisdn_done ));
- Recordstoload ++;
- // Record number is subscriber Profile
- Iccfh. loadeflinearfixed (ef_mbi, 1, obtainmessage (event_get_mbi_done ));
- Recordstoload ++;
- Iccfh. loadeftransparent (ef_ad, obtainmessage (event_get_ad_done ));
- Recordstoload ++;
- // Record number is subscriber Profile
- Iccfh. loadeflinearfixed (ef_mwis, 1, obtainmessage (event_get_mwis_done ));
- Recordstoload ++;
- // Also load cphs-style voice mail indicator, which stores
- // The same info as EF [MWIs]. If both exist, both are updated
- // But the EF [MWIs] data is preferred
- // Please note this must be loaded after EF [MWIs]
- Iccfh. loadeftransparent (
- Ef_voice_mail_indicator_cphs,
- Obtainmessage (event_get_voice_mail_indicator_cphs_done ));
- Recordstoload ++;
- // Same goes for call forward status indicator: fetch both
- // EF [CFIs] And CPHS-EF, with EF [CFIs] preferred.
- Iccfh. loadeflinearfixed (ef_cfis, 1, obtainmessage (event_get_cfis_done ));
- Recordstoload ++;
- Iccfh. loadeftransparent (ef_cff_cphs, obtainmessage (event_get_cff_done ));
- Recordstoload ++;
- Getspnfsm (true, null );
- Iccfh. loadeftransparent (ef_spdi, obtainmessage (event_get_spdi_done ));
- Recordstoload ++;
- Iccfh. loadeflinearfixed (ef_pnn, 1, obtainmessage (event_get_pnn_done ));
- Recordstoload ++;
- Iccfh. loadeftransparent (ef_sst, obtainmessage (event_get_sst_done ));
- Recordstoload ++;
- Iccfh. loadeftransparent (ef_info_cphs, obtainmessage (event_get_info_cphs_done ));
- Recordstoload ++;
- // XXX shocould seek instead of examining them all
- If (false) {// xxx
- Iccfh. loadeflinearfixedall (ef_sms, obtainmessage (event_get_all_sms_done ));
- Recordstoload ++;
- }
- If (crash_ril ){
- String SMS = "0107912160130310f20404d0110041007030208054832b0120"
- + "Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "Ffffffffffffffffffffffffffff ";
- Byte [] BA = iccutils. hexstringtobytes (SMS );
- Iccfh. updateeflinearfixed (ef_sms, 1, Ba, null,
- Obtainmessage (event_mark_sms_read_done, 1 ));
- }
- }
Here, the first one to start card reading is
Imsi (International Mobile subscriberidentification number) is mainly used to find the carrier's network, including MCC, MNC,
Iccid (Integrate Circuit card identity) uniquely identifies a mobile user.
Then, you can see that there are a lot of functions like this called iccfh. loadeftransparent, which is to call iccfilehandler to read SIM card Fields
[Java]
View plaincopy
- Public void loadeftransparent (INT fileid, message onloaded ){
- Message response = obtainmessage (event_get_binary_size_done,
- Fileid, 0, onloaded );
- Phone. mcm. iccio (command_get_response, fileid, getefpath (fileid ),
- 0, 0, get_response_ef_size_bytes, null, null, response );
- }
We noticed that phone. mcm. iccio, which is our RIL. Java, sent a command to the lower-layer modem to read the SIM card, in RIL. java. Fileid is the address of the field, such as and (6f3a in this example) and FDN (6f3b in this example ).
3. When the Low-layer modem reads the field result, there will be a returned result, because when sending a read request, there is an event informationEvent_get_binary_size_done,When a response is returned, it is directly handed over to iccfilehandler, and then forwarded to simrecords by iccfilehandler. Finally, the operation that should be performed after the field is read. Iccfilehandler is notified by rIL. java. The processing is as follows:
[Java]
View plaincopy
- Case event_get_binary_size_done:
- AR = (asyncresult) msg. OBJ;
- Response = (Message) Ar. userobj;
- Result = (iccioresult) Ar. result;
- If (AR. Exception! = NULL ){
- Sendresult (response, null, ar. Exception );
- Break;
- }
- Iccexception = result. getexception ();
- If (iccexception! = NULL ){
- Sendresult (response, null, iccexception );
- Break;
- }
- Data = result. payload;
- Fileid = msg. arg1;
- If (type_ef! = Data [response_data_file_type]) {
- Throw new iccfiletypemismatch ();
- }
- If (ef_type_transparent! = Data [response_data_structure]) {
- Throw new iccfiletypemismatch ();
- }
- Size = (data [response_data_file_size_1] & 0xff) <8)
- + (Data [response_data_file_size_2] & 0xff );
- Phone. mcm. iccio (command_read_binary, fileid, getefpath (fileid ),
- 0, 0, size, null, null,
- Obtainmessage (event_read_binary_done,
- Fileid, 0, response ));
- Break;
Return to simrecords and process the related operations after the iccid is read. The Code is as follows:
[Java]
View plaincopy
- Case event_get_iccid_done:
- Isrecordloadresponse = true;
- AR = (asyncresult) msg. OBJ;
- Data = (byte []) Ar. result;
- If (AR. Exception! = NULL ){
- Break;
- }
- Iccid = iccutils. bcdtostring (data, 0, Data. Length );
- Log. D (log_tag, "iccid:" + iccid );
- Break;
At this point, a complete SIM card reading process is complete.
PS: Some may ask why
Iccfh. loadeftransparent
Sometimes it is
Iccfh. loadeflinearfixed
This is mainly related to the type of EF to be read. The files on the SIM card are elementary file, delicated file, and cyclic file. EF is divided into linear fixed EF, transparent EF, and cyclic EF, therefore, the reading method is different. For more information, see 3GPP 11.11 and 3GPP 51.011.
OK, tired. If you have any questions, ask below,