SIMLock鎖卡功能解析

来源:http://www.cnblogs.com/Daniel-android/archive/2016/12/09/6114482.html
-Advertisement-
Play Games

一、鎖卡背景介紹 鎖卡即SIMLock,當手機開機啟動或者插入SIM卡時,手機modem側預置在NV項中的配置信息會與SIM卡中的信息做比對,檢測是否匹配。若匹配,則SIM卡可以正常使用。若不匹配,則SIM卡相關功能均無法正常使用,例如撥打電話、發送簡訊及上網等;或者是只能註冊2G網,不能註冊4G。 ...


一、鎖卡背景介紹

  鎖卡即SIMLock,當手機開機啟動或者插入SIM卡時,手機modem側預置在NV項中的配置信息會與SIM卡中的信息做比對,檢測是否匹配。若匹配,則SIM卡可以正常使用。若不匹配,則SIM卡相關功能均無法正常使用,例如撥打電話、發送簡訊及上網等;或者是只能註冊2G網,不能註冊4G。

  鎖卡的目的:一些運營商會要求控制某一類卡的使用,從而保護自己的利益(運營商定製機)

  SIMLock鎖和圖案鎖,數字密碼鎖,PIN碼鎖,PUK鎖一樣,是Keyguard模塊中的一種鎖。

二、鎖卡的需求

  鎖卡的需求方式有7種之多,常見的有NP鎖,NS鎖,CP鎖,SP鎖等

  從安卓機器來看,目前最常用的是SP鎖(MCC/MNC),本文將解析SP鎖的加鎖流程

三、鎖卡流程解析

  1.首先modem側檢測SIM卡的配置信息並與之作比對,若匹配則繼續載入SIM卡,若不匹配,則上報加鎖信息

  2.RIL層檢測到modem上報的加鎖信息,然後發送給framework層,最終在AP層監測到事件:

  3.AP層顯示出鎖卡界面,要求用戶輸入解鎖碼進行解鎖

四、相關流程圖

1.加鎖流程圖

2.解鎖流程圖

五、代碼解析

  MTK平臺已經支持SIMLock功能,但只能在代碼中寫固定的MCC/MNC,不能靈活配置。即一套代碼只能對應一套對應的鎖卡配置信息,對於手機廠商來說,顯然不滿足需求,發貨國家遍佈全球,鎖卡配置信息均不同,代碼版本太多無法管理,故肯定要廢棄MTK的這套SIMLock功能。

(1)modem側客制化

  涉及的代碼文件:

  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

 

  a.擴展鎖卡配置信息的組數

  custom_nvram_sec.h

  #define SML_MAX_SUPPORT_CAT_N       50
  初始化數組的時候,需要添加對應的預設配置信息

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		
};

  b.修改剩餘解鎖次數

  custom_nvram_sec.h

      #define SML_MAX_RETRY_COUNT 10

  c.擴展客制化的鎖卡NV項

  例如MTK源生的鎖卡NV項已經可以通過工具查看及修改,這樣鎖卡就容易被破解。客制化自己的鎖卡NV項,即使MTK源生的被破解了,SIMLock功能依舊正常工作。

  不過從Android 6.0來看,MTK已經在modem側做了處理,使用工具無法查看及修改該NV項了。

  (1)先定義NV項

  (2)對該NV項進行對應的初始化,參考源生的即可

  d.擴展鎖卡的特殊需求(關聯鎖卡等)

  由於源生的AT指令不能查詢鎖卡狀態信息,可以通過擴展AT指令來實現

  如下代碼為擴展的AT+QSIM1的指令,查詢的信息包括鎖卡狀態,鎖卡配置信息,剩餘次數等

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;
    }

(2)AP側客制化

  SIMLock客制化工作量主要集中在modem側,AP側主要為界面顯示及AT指令的交互

  a.AT指令的交互

    查詢SIM卡狀態

    查詢鎖卡狀態信息:是否鎖卡,鎖卡的配置信息(MCC/MNC),解鎖剩餘次數等

    發送PASSWORD到RIL側,解析解鎖是否成功的返回信息

  b.用戶界面的顯示

    提示用戶輸入解鎖碼

    提示剩餘解鎖次數

    提示剩餘時間可以繼續輸入解鎖碼

    提示SIM卡永久被鎖

 

 

 

 

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Android打電話有兩種實現方法: 第一種方法,撥打電話跳轉到撥號界面。源代碼如下: Intent intent = new Intent(Intent.ACTION_DIAL); Uri data = Uri.parse("tel:" + "135xxxxxxxx"); intent.setDa ...
  • 在iOS開發過程中經常需要通過網路請求載入圖片,有時,需要在創建UIImageView或UIButton來顯示圖片之前需要提前知道圖片的尺寸,根據圖片尺寸創建對應大小的控制項。但是對於網路圖片來說,要想通過最優的方法獲得尺寸就略微有點困難,大體思路就是下麵這種: 如果有使用SDWebImage,則首先 ...
  • 由於我是在win7的環境下,在這裡就以win7系統為例進行講解了。 首先需要在nodejs官網下載最新版的node.js,下載完畢直接安裝即可,安裝成功後在cmd命令行中執行node指令,如下結果就說明安裝成功 node安裝成功後會自動安裝npm(包管理器,編譯源代碼安裝需要手動安裝),這是Node ...
  • 前提: 1.安裝Android Studio(過程略) 2.官網下載OpenCV for Android 網址:http:opencv.org/downloads.html 我下載的是下圖的版本 3.將下載好的OpenCV for Android解壓到固定文件夾 4.新建一個android項目(就新 ...
  • 最近新項目需要編譯64位的動態庫,這裡記錄如何配置。 在jni目錄下加入Android.mk和Application.mk文件。 Application.mk Android.mk 加上這兩個mk文件後,編譯就會生成armeabi、armeabi-v7a、arm64-v8a的庫文件。 補充: And ...
  • 通過項目學習收穫更大。 1、基於Android平臺實戰愛簡訊項目 下載地址:http://pan.baidu.com/s/1hr8CEry 2、Android平臺實戰CRM客戶關係管理(AChartEngine統計圖表、非同步任務、系統性能優化) 下載地址: http://pan.baidu.com/ ...
  • 有的時候會碰到軟鍵盤不好關閉,然後就去調界面代碼,發現不行,說到底還是對軟鍵盤不熟悉的原因,軟鍵盤windowSoftInputMode有很多種 如果你預設的activity的模式為預設的,或者stateHidden|adjustPan等,那你在某些情況下是關不了( hideSoftInputFro ...
  • 最近在做一個活動頁面:用戶上傳一張圖片進行縮放、旋轉後點擊下一步填寫內容後生成圖片! 做好後經過各種測試是沒有問題的,基本沒有什麼明顯BUG,流程都能走通,但是嵌入到APP後,問題就來了! 在IOS上基本還可以,在Android上有明顯問題,下麵就是我要講的: 在Android中,當我們通過WebV ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...