1, Background introduction
1.1 INTRODUCTION
The lock card is SIMLock. When the mobile phone is turned on or inserted into the SIM card, the configuration information preset in NV on the modem side of the mobile phone will be compared with the information in the SIM card to detect whether it matches. If it matches, the SIM card can be used normally. If it does not match, the relevant functions of the SIM card cannot be used normally, such as making calls, sending text messages and surfing the Internet; Or you can only register 2G networks, not 4G.
Like pattern lock, digital code lock, PIN code lock and PUK lock, SIMLock lock is a lock in Keyguard module.
1.2 purpose
Some operators require to control the use of certain types of cards to protect their own interests (operators customize machines)
2, Lock card introduction
2.1 card locking requirements
There are 7 kinds of lock card demand modes, including NP lock, NS lock, CP lock, SP lock, etc;
From the perspective of Android machines, the most commonly used is SP lock (MCC/MNC). This paper will analyze the locking process of SP lock;
2.2 card locking process analysis
1. First, the modem side detects the configuration information of the SIM card and compares it with it. If it matches, continue to load the SIM card. If it does not match, report the locking information
2. The RIL layer detects the locking information reported by the modem, and then sends it to the framework layer. Finally, the event is monitored at the AP layer:
3. The AP layer displays the card locking interface and requires the user to enter the unlocking code to unlock
2.2. 1 locking process
2.2. 2 unlocking process
III. code analysis
The MTK platform already supports the SIMLock function, but it can only write fixed MCC/MNC in the code and cannot be configured flexibly. That is, a set of codes can only correspond to a set of corresponding lock card configuration information. For mobile phone manufacturers, it obviously does not meet the demand. The shipping countries are all over the world, the lock card configuration information is different, and there are too many code versions to manage. Therefore, this set of SIMLock function of MTK must be abandoned.
3.1 customization of modem side
3.1. 1 code files involved
custom/modem/common/ps/custom_nvram_extra.c custom/modem/common/ps/customer_at_command.c custom/service/nvram/custom_nvram_sec.c custom/service/nvram/custom_nvram_sec.h interface/service/nvram/nvram_data_items.h service/nvram/src/nvram_factory_config.c service/nvram/src/nvram_main.c
3.1. 2. Number of groups of extended lock card configuration information
Modified file: custom_nvram_sec.h
#define SML_MAX_SUPPORT_CAT_N 50
When initializing the array, you need to add the corresponding default configuration information
const nvram_sml_context_struct NVRAM_EF_SML_DEFAULT = { SML_MAGIC_HEAD_VALUE, {{SML_STATE_UNLOCK,SML_RETRY_COUNT_N_CAT,0,0}, /* Category N */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_NS_CAT ,0,0}, /* Category NS */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_SP_CAT ,0,0}, /* Category SP */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_C_CAT ,0,0}, /* Category C */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_SIM_CAT ,0,0}, /* Category SIM */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_NS_CAT ,0,0}, /* Link NS-SP */ {SML_STATE_UNLOCK,SML_RETRY_COUNT_C_CAT ,0,0}}, /* Link SIM-C */ {{SML_KEY_SET,{0x21,0x43,0x65,0x87,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_SET,{0x65,0x87,0x21,0x43,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_SET,{0x11,0x22,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_EMPTY,{0x33,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_EMPTY,{0x55,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_SET,{0x77,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}, {SML_KEY_SET,{0x99,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}}, /* Category N code */ {0x73,0x00,0x1F,0x73,0x00,0x2F,0x73,0x00,0x3F,0x73,0x00,0x4F,0x73,0x00,0x5F, 0x73,0x00,0x6F,0x73,0x00,0x7F,0x73,0x00,0x8F,0x73,0x00,0x9F,0x73,0x01,0x0F, 0x73,0x01,0x1F,0x73,0x09,0x9F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00}, /* Category NS code */ {0xc2,0xc2,0xc2,0xc2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00}, /* Category SP code */ {0xc3,0xc3,0xc3,0xc3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00}, /* Category C code */ {0xc4,0xc4,0xc4,0xc4,0xc4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00}, /* Category SIM code */ {0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* Link Category NS-SP */ {0xc6,0xc6,0xc6,0xc6,0xc6,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00}, /* Link Category SIM-C */ {0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFF,0xFF}, SML_MAGIC_TAIL_VALUE };
3.1. 3. Modify the remaining unlocking times
Modify file: custom_nvram_sec.h
#define SML_MAX_RETRY_COUNT 10
3.1. 4. Expand customized lock NV item
For example, the lock card NV item generated by MTK source can be viewed and modified through tools, so that the lock card can be easily cracked. Customize your own lock card NV item. Even if the MTK source is cracked, the SIMLock function still works normally.
However, from Android 6.0, MTK has been processed on the modem side, and the NV item cannot be viewed and modified using the tool.
(1) define NV item first
(2) initialize the NV item by referring to the generated by the source;
3.1. 5. Special requirements for expansion lock card (associated lock card, etc.)
Since the original AT instruction cannot query the lock status information, it can be realized by expanding the AT instruction;
The following code is the instruction of extended AT+QSIM1. The queried information includes card locking status, card locking configuration information, remaining times, etc;
if (strcmp(cmd_name, "QSIM1") == 0) { extern void simlock_query_sml_info(kal_uint8 sim_id, sml_context_struct* sml_static_buffer); char info_buffer[MAX_UART_LEN+1]; int NumOfPlmn,i; int isLocked = -1; sml_context_struct sml_static_buffer; memset(&sml_static_buffer,0x00,sizeof(sml_context_struct)); simlock_query_sml_info(1, &sml_static_buffer); kal_prompt_trace(MOD_SIM, "[sim1]: receive full_cmd_string =%s", full_cmd_string); sml_cat_enum cat = 0xff; for(cat = SML_CAT_N; cat < SML_CAT_SIZE; cat++) { if(sml_static_buffer.cat[cat].state == 0x01) { isLocked = 1; break; } } if(isLocked == 1) { NumOfPlmn = sml_static_buffer.cat[cat].num; NumOfPlmn = 1; sprintf(info_buffer, "+QSIM1:%02x;",sml_static_buffer.cat[cat].state); sprintf(info_buffer+strlen(info_buffer), "%02x;",NumOfPlmn); //#define SML_SIZE_OF_CAT_N 3 /* MCC/MNC */ //#define SML_SIZE_OF_CAT_NS 4 /* MCC/MNC + HLR */ //#define SML_SIZE_OF_CAT_SP 4 /* MCC/MNC + GID1 */ //#define SML_SIZE_OF_CAT_C 5 /* MCC/MNC + GID1 + GID2 */ //#define SML_SIZE_OF_CAT_SIM 8 /* IMSI */ //#define SML_SIZE_OF_LINK_NS_SP 5 /* MCC/MNC + HLR+ GID1 */ //#define SML_SIZE_OF_LINK_SIM_C 10 /* IMSI + GID1 + GID2 */ if(cat == SML_CAT_N) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_CAT_N; i=i+SML_SIZE_OF_CAT_N) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x;",sml_static_buffer.code_cat_n[i], sml_static_buffer.code_cat_n[i + 1],sml_static_buffer.code_cat_n[i + 2]); } //sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.key[cat].key[4], // sml_static_buffer.key[cat].key[5],sml_static_buffer.key[cat].key[6],sml_static_buffer.key[cat].key[7]); //kal_prompt_trace(MOD_SIM, " receive cmd =%s ; flag is %x ", cmd_name, read_buffer); } else if(cat == SML_CAT_NS) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_CAT_NS; i=i+SML_SIZE_OF_CAT_NS) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x;",sml_static_buffer.code_cat_ns[i], sml_static_buffer.code_cat_ns[i + 1],sml_static_buffer.code_cat_ns[i + 2],sml_static_buffer.code_cat_ns[i + 3]); } } else if(cat == SML_CAT_SP) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_CAT_SP; i=i+SML_SIZE_OF_CAT_SP) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x;",sml_static_buffer.code_cat_sp[i], sml_static_buffer.code_cat_sp[i + 1],sml_static_buffer.code_cat_sp[i + 2],sml_static_buffer.code_cat_sp[i + 3]); } } else if(cat == SML_CAT_C) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_CAT_C; i=i+SML_SIZE_OF_CAT_C) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.code_cat_c[i], sml_static_buffer.code_cat_c[i + 1],sml_static_buffer.code_cat_c[i + 2],sml_static_buffer.code_cat_c[i + 3]); sprintf(info_buffer+strlen(info_buffer), "%02x;",sml_static_buffer.code_cat_c[i + 4]); } } else if(cat == SML_CAT_SIM) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_CAT_SIM; i=i+SML_SIZE_OF_CAT_SIM) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.code_cat_sim[i], sml_static_buffer.code_cat_sim[i + 1],sml_static_buffer.code_cat_sim[i + 2],sml_static_buffer.code_cat_sim[i + 3]); sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x;",sml_static_buffer.code_cat_sim[i + 4], sml_static_buffer.code_cat_sim[i + 5],sml_static_buffer.code_cat_sim[i + 6], sml_static_buffer.code_cat_sim[i + 7]); } } else if(cat == SML_CAT_NS_SP) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_LINK_NS_SP; i=i+SML_SIZE_OF_LINK_NS_SP) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.code_cat_ns_sp[i], sml_static_buffer.code_cat_ns_sp[i + 1],sml_static_buffer.code_cat_ns_sp[i + 2],sml_static_buffer.code_cat_ns_sp[i + 3]); sprintf(info_buffer+strlen(info_buffer), "%02x;",sml_static_buffer.code_cat_ns_sp[i + 4]); } } else if(cat == SML_CAT_SIM_C) { for(i = 0; i < NumOfPlmn*SML_SIZE_OF_LINK_SIM_C; i=i+SML_SIZE_OF_LINK_SIM_C) { sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.code_cat_sim_c[i], sml_static_buffer.code_cat_sim_c[i + 1],sml_static_buffer.code_cat_sim_c[i + 2], sml_static_buffer.code_cat_sim_c[i + 3]); sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.code_cat_sim_c[i + 4], sml_static_buffer.code_cat_sim_c[i + 5],sml_static_buffer.code_cat_sim_c[i + 6], sml_static_buffer.code_cat_sim_c[i + 7]); sprintf(info_buffer+strlen(info_buffer), "%02x%02x;",sml_static_buffer.code_cat_sim_c[i + 8], sml_static_buffer.code_cat_sim_c[i + 9]); } } sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x",sml_static_buffer.key[cat].key[0], sml_static_buffer.key[cat].key[1],sml_static_buffer.key[cat].key[2],sml_static_buffer.key[cat].key[3]); sprintf(info_buffer+strlen(info_buffer), "%02x%02x%02x%02x;",sml_static_buffer.key[cat].key[4], sml_static_buffer.key[cat].key[5],sml_static_buffer.key[cat].key[6],sml_static_buffer.key[cat].key[7]); sprintf(info_buffer+strlen(info_buffer), "%02x;",sml_static_buffer.cat[cat].retry_count); sprintf(info_buffer+strlen(info_buffer), "%02x;",cat); } else { sprintf(info_buffer, "+QSIM1:%02x;",0x00); } //kal_prompt_trace(MOD_NVRAM, "[sim1]: info_buffer is === >> %s", info_buffer); rmmi_write_to_uart((kal_uint8*)info_buffer, strlen(info_buffer), KAL_FALSE); sprintf(buffer, "OK"); rmmi_write_to_uart((kal_uint8*)buffer, strlen(buffer), KAL_TRUE); return KAL_TRUE; }
3.2 customization at AP side
SIMLock customized chemical production is mainly concentrated on the modem side, and the AP side is mainly interface display and AT command interaction;
3.2. 1. Interaction of at commands
Query SIM card status
Query card locking status information: whether to lock the card, card locking configuration information (MCC/MNC), remaining times of unlocking, etc;
Send PASSWORD to RIL side to analyze the return information of whether the unlocking is successful;
3.2. 2 display of user interface
(1) prompt the user to enter the unlocking code;
(2) prompt the remaining unlocking times;
(3) prompt that you can continue to input the unlocking code in the remaining time;
(4) prompt that the SIM card is permanently locked;
reference:
Reference: Analysis of SIMLock card locking function_ a906778690 blog - CSDN blog