一、代码流程图
CM REG MM
1.cmregprx_inactive_ph_stat_chgd_hdlr()
||
\/ CM_SIM_AVAILABLE_REQ
2.cmregprx_send_reg_sim_avail_req() --------------------> 3.reg_state_main()
||
\/
4.process_cm_sim_available_req()
||
\/
5.reg_sim_load_card_mode() MMR_SIM_AVAILABLE_REQ
6.reg_send_mmr_sim_available_req() ---------------------> 7.mmcoord_process_mmr_sim_available_req()
||
\/
8.mmcoord_process_subsription_ready()
||
\/
9.mm_load_sim_data()
10.emm_send_sim_update()
MMR_SIM_AVAILABLE_CNF emm_send_rrc_system_update()
12.reg_state_main() <------------------------- 11.mm_send_mmr_sim_available_cnf()
||
\/
13.process_mmr_sim_available_cnf()
||
CM_SIM_AVAILABLE_CNF \/
15.cmregprx_rpt_proc() <-------------------------- 14.reg_send_cm_sim_available_cnf()
||
\/
16.cmregprx_sim_avail_cnf_hdlr()
||
\/
17.cmregprx_inactive_sim_avail_cnf_hdlr()
18.cmph_send_sim_available_ph_event()
二、代码流程
1.cmregprx_inactive_ph_stat_chgd_hdlr()
函数描述:This function handles the Phone status changed command from MMoC in INACTIVE RegProxy's state.
函数处理:
If the chg_type = PROT_PH_STAT_CHG_SUBSC
the RegProxy will send the cm_sim_available_req() or cm_sim_not_available_req()
这里主要是调用cmregprx_send_reg_sim_avail_req()来发送CM_SIM_AVAILABLE_REQ;
关键日志打印:
CMREGPRX_MSG_HIGH_5_EXT("CMREG->NAS: sub %d, Send SIM_AVAILABLE_REQ, gwl_subs_avail %d, mode_pref %d, session_type %d, nv_context %d",
cmd_ptr->param.gw_ph_stat_cmd.as_id,
gwl_subs_avail,
reg_ptr->cmd.cm_sim_available_req.mode_pref,
cmd_ptr->param.gw_ph_stat_cmd.session_type,
cmd_ptr->param.gw_ph_stat_cmd.nv_context,
cmd_ptr->param.gw_ph_stat_cmd.as_id);
2.cmregprx_send_reg_sim_avail_req()
主要是发送CM_SIM_AVAILABLE_REQ
3.reg_state_main()
接收CM_SIM_AVAILABLE_REQ命令,并分到相应函数处理
case CM_SIM_AVAILABLE_REQ:
if ( cm_sim_available_req_is_valid(&(reg_cmd_p->cmd.cm_sim_available_req)) )
{
#if defined FEATURE_DUAL_SIM
REG_LOG_LF_HIGH(REG_TAG, REG_SUB, "=REG= CM_SIM_AVAILABLE_REQ mode_pref:%d, session_type:%d nv_index:%d",reg_cmd_p->cmd.cm_sim_available_req.mode_pref,
reg_cmd_p->cmd.cm_sim_available_req.session_type,reg_cmd_p->cmd.cm_sim_available_req.nv_context_id);
#else
REG_LOG_HF_HIGH(REG_TAG, REG_SUB, "=REG= CM_SIM_AVAILABLE_REQ");
#endif
reg_state_cm_transaction_id = reg_cmd_p->cmd.cm_sim_available_req.transaction_id;
reg_state_next_p = reg_state_curr_p->process_cm_sim_available_req
(
&(reg_cmd_p->cmd.cm_sim_available_req)
);
}
4.process_cm_sim_available_req()
处理CM_SIM_AVAILABLE_REQ,主要是调用reg_sim_load_card_mode(),成功后再调用reg_send_mmr_sim_available_req():
……
{
reg_debug_cm_sim_available_status = REG_DEBUG_SIM_AVAILABLE_MMGSDI_SESSION_AVAILABLE;
if (reg_sim_load_card_mode())
{
reg_debug_cm_sim_available_status = REG_DEBUG_SIM_AVAILABLE_LOAD_CARD_MODE_SUCCESS;
……
reg_mode_enhanced_hplmn_srch_init();
reg_send_mmr_sim_available_req
(
#if defined FEATURE_DUAL_SIM
msg_p->mode_pref,
reg_sim_mmgsdi_info.client_id,
msg_p->session_type,
reg_nv_context_id
#else
reg_sim_mmgsdi_info.client_id
#endif
);
}
5.reg_sim_load_card_mode()
主要操作是:
1)、refresh相关文件:
(MMGSDI_USIM_HPLMN
MMGSDI_USIM_7F66_PROP1_ACT_HPLMN
MMGSDI_USIM_FPLMN
MMGSDI_USIM_HPLMNWACT
MMGSDI_USIM_RPLMNACT
MMGSDI_USIM_LOCI
MMGSDI_USIM_PSLOCI
MMGSDI_USIM_OCSGL
MMGSDI_USIM_OPLMNWACT
MMGSDI_USIM_ROUTING_IND)
/* Populate reg_sim_refresh_file_list */
reg_sim_populate_sim_refresh_file_list(&refresh_files);
#ifdef FEATURE_REL7_STEERING_OF_ROAMING
mmgsdi_status = mmgsdi_session_register_for_refresh_with_steering (
reg_sim_mmgsdi_info.session_id,
refresh_files,
TRUE,
reg_sim_mmgsdi_generic_cb,
0
);
#else
mmgsdi_status = mmgsdi_session_register_for_refresh(
reg_sim_mmgsdi_info.session_id,
refresh_files,
TRUE, /* vote_for_init */
reg_sim_mmgsdi_generic_cb,
0
);
#endif /*FEATURE_REL7_STEERING_OF_ROAMING*/
2)、读HPLMN:
/*
** To update the global reg_sim_hplmn.
*/
(void)reg_sim_read_hplmn();
3)、读EHPLMN:
** Read EHPLMN list and update global reg_sim_ehplmn_list.
** The reg_sim_ehplmn_list will be populated either from the card
** or from the NV.
*/
(void)reg_sim_read_ehplmn_list();
4)、读sim_imsi、nv_imsi:
reg_sim_changed = FALSE;
sim_read_status = reg_sim_read_imsi(&sim_imsi);
#if defined(FEATURE_DUAL_SIM)
NAS_ENTER_CRIT_SECT(mm_sim_swap_crit_sec);
#endif
nv_read_status = reg_nv_read_imsi(&nv_imsi);
#if defined(FEATURE_DUAL_SIM)
NAS_EXIT_CRIT_SECT(mm_sim_swap_crit_sec);
#endif
REG_LOG_HF_HIGH(REG_TAG, REG_SUB, "=REG= sim_read_status=%d, nv_read_status=%d", sim_read_status, nv_read_status);
5)、读sim_rplmn:
/* If RPLMN has invalid digits, invalidate the RPLMN RAT Search Order too */
sim_rplmn = reg_sim_read_sim_rplmn(SYS_SRV_DOMAIN_PS_ONLY);
6)、从NV读rplmnact:
/*
** Initialize the value of rplmn_rat_search_order using the value stored
** in NVRAM.
*/
reg_nv_read_rplmnact(&rplmnact);
if ( rplmnact.act[1] & 0x80 )
{
reg_sim_rplmn_rat_search_order = REG_SIM_MODE_PREF_GSM_RADIO_ACCESS_PREFERRED;
}
else if ( rplmnact.act[0] & 0x80 )
{
reg_sim_rplmn_rat_search_order = REG_SIM_MODE_PREF_UMTS_RADIO_ACCESS_PREFERRED;
}
#ifdef FEATURE_LTE
else if ( rplmnact.act[0] & 0x40 )
{
reg_sim_rplmn_rat_search_order = REG_SIM_MODE_PREF_LTE_RADIO_ACCESS_PREFERRED;
}
#endif/*FEATURE_LTE*/
#ifdef FEATURE_NR5G_SA
else if ( rplmnact.act[0] & 0x08 )
{
reg_sim_rplmn_rat_search_order = REG_SIM_MODE_PREF_NR5G_RADIO_ACCESS_PREFERRED;
}
#endif
7)、从NV读PPLMN:
/* Read prefererd plmn list from NV*/
reg_nv_read_preferred_plmn_list();
6.reg_send_mmr_sim_available_req()
发送MMR_SIM_AVAILABLE_REQ
7.mmcoord_process_mmr_sim_available_req()
处理MMR_SIM_AVAILABLE_REQ
主要是:
/* ----------------------------------
** Alert MM/GMM to read SIM data and send to RR(C)
** ---------------------------------- */
mmcoord_process_subsription_ready();
8.mmcoord_process_subsription_ready()
如调用前的注释mmcoord_process_subsription_ready()的主要作用:
1)读取卡信息
status = mm_load_sim_data();
2)发送卡插入请求到RRC
if( status )
{
if (mm_wcdma_supported &&
mm_sub_is_rat_enabled(SYS_RAT_UMTS_RADIO_ACCESS))
{
/* Send SIM insertion event to WCDMA RRC */
mm_send_rrc_sim_inserted_req( SYS_RAT_UMTS_RADIO_ACCESS);
}
if (mm_tdscdma_supported &&
mm_sub_is_rat_enabled(SYS_RAT_TDS_RADIO_ACCESS))
{
/* Send SIM insertion event to TD-SCDMA RRC */
mm_send_rrc_sim_inserted_req( SYS_RAT_TDS_RADIO_ACCESS);
}
#ifdef FEATURE_GSM
mm_send_rr_sim_inserted_req();
#endif
#ifdef FEATURE_LTE
if(mm_sub_is_rat_enabled(SYS_RAT_LTE_RADIO_ACCESS) == TRUE)
{
/* Send sim insert to E-RRC*/
emm_send_sim_update(emm_ctrl_data_ptr,TRUE) ;
emm_send_rrc_system_update(emm_ctrl_data_ptr) ;
}
#endif
#ifdef FEATURE_NR5G_SA if(mm_sub_is_rat_enabled(SYS_RAT_NR5G_RADIO_ACCESS) == TRUE)
{
mm5g_send_rrc_sim_update_req(TRUE, FALSE);
mm5g_send_rrc_system_update();
}
#endif
3)调用:mm_send_mmr_sim_available_cnf()
#ifdef FEATURE_LTE
MM_LOG_HF_HIGH(MM_TAG, MM_SUB, "=MM= lte accepted VPLMN [%x %x %x]",
emm_ctrl_data_ptr->emm_lte_accepted_vplmn.identity[0],
emm_ctrl_data_ptr->emm_lte_accepted_vplmn.identity[1],
emm_ctrl_data_ptr->emm_lte_accepted_vplmn.identity[2]);
#endif
mm_send_mmr_sim_available_cnf();
9.mm_load_sim_data()
主要是读取卡信息,
如:(
MMGSDI_USIM_IMSI
MMGSDI_USIM_UST
MMGSDI_USIM_LOCI
MMGSDI_USIM_ACC
MMGSDI_USIM_AD)
/* Step 1: Read the IMSI from card. Read the IMSI from NV.
If the two do not match, update the NV with the one
from card.
Delete any security contexts saved in NV.
*/
status = mm_sim_read( sim_file_name_imsi,
(byte *) &imsi_data,
MMGSDI_IMSI_LEN
);
/* Step 2: Read the Service table
*/
mmgsdi_status = (mmgsdi_session_read_cache_file_size (mm_sim_mmgsdi_info.session_id,
sim_file_name_sst,
&file_length) == MMGSDI_SUCCESS);
/* Step 3: Initialize the LOCI.
PS LOCI and EPS LOCI are read later
*/
status = mm_sim_read( sim_file_name_loci,
sim_loci,
MMGSDI_LOCI_LEN
);
/* Step 4: Read the UE access class information */
/* Cache the UE access class information */
mmgsdi_status = mm_sim_read(sim_file_name_access_class, access_class, 2);
/* Step 5: Read ADMIN Data from SIM */
#ifdef FEATURE_GAN
#error code not present
#else
mmgsdi_status = mm_sim_read(sim_file_name_admin, &ms_opmode, 1);
10.emm_send_sim_update(emm_ctrl_data_ptr,TRUE)
emm_send_rrc_system_update(emm_ctrl_data_ptr) ;
主要是发送卡插入请求到RRC,流程图中只取了LTE的部分,其它如下:
if( status )
{
if (mm_wcdma_supported &&
mm_sub_is_rat_enabled(SYS_RAT_UMTS_RADIO_ACCESS))
{
/* Send SIM insertion event to WCDMA RRC */
mm_send_rrc_sim_inserted_req( SYS_RAT_UMTS_RADIO_ACCESS);
}
if (mm_tdscdma_supported &&
mm_sub_is_rat_enabled(SYS_RAT_TDS_RADIO_ACCESS))
{
/* Send SIM insertion event to TD-SCDMA RRC */
mm_send_rrc_sim_inserted_req( SYS_RAT_TDS_RADIO_ACCESS);
}
#ifdef FEATURE_GSM
mm_send_rr_sim_inserted_req();
#endif
#ifdef FEATURE_LTE
if(mm_sub_is_rat_enabled(SYS_RAT_LTE_RADIO_ACCESS) == TRUE)
{
/* Send sim insert to E-RRC*/
emm_send_sim_update(emm_ctrl_data_ptr,TRUE) ;
emm_send_rrc_system_update(emm_ctrl_data_ptr) ;
}
#endif
#ifdef FEATURE_NR5G_SA if(mm_sub_is_rat_enabled(SYS_RAT_NR5G_RADIO_ACCESS) == TRUE)
{
mm5g_send_rrc_sim_update_req(TRUE, FALSE);
mm5g_send_rrc_system_update();
}
#endif
}
11、mm_send_mmr_sim_available_cnf()
发送MMR_SIM_AVAILABLE_CNF
12.reg_state_main()
接收MMR_SIM_AVAILABLE_CNF并分到相应函数处理:
case MMR_SIM_AVAILABLE_CNF:
if ( mmr_sim_available_cnf_is_valid(&(reg_cmd_p->cmd.mmr_sim_available_cnf)) )
{
reg_state_next_p = reg_state_curr_p->process_mmr_sim_available_cnf
(
&(reg_cmd_p->cmd.mmr_sim_available_cnf)
);
}
13.process_mmr_sim_available_cnf()
处理MMR_SIM_AVAILABLE_CNF:
static reg_state_p_type process_mmr_sim_available_cnf
(
mmr_sim_available_cnf_s_type* msg_p
)
{
(void) msg_p;
reg_send_cm_sim_available_cnf
(
reg_state_cm_transaction_id_get()
);
return (®_state_inactive);
}
14.reg_send_cm_sim_available_cnf()
发送CM_SIM_AVAILABLE_CNF
15.cmregprx_rpt_proc()
接收CM_SIM_AVAILABLE_CNF并分到相应函数处理:
case CM_SIM_AVAILABLE_CNF:
case CM_SIM_NOT_AVAILABLE_CNF:
cmregprx_sim_avail_cnf_hdlr( cm_rpt_ptr,
cmregprx_info_ptr
);
break;
16.cmregprx_sim_avail_cnf_hdlr()
处理CM_SIM_AVAILABLE_CNF:
CMREGPRX_MSG_HIGH_2("NAS->CMREG: sub %d stk %d, SIM_AVAILABLE_CNF",
cnf_as_id,
cmregprx_stack_info_ptr->mm_id.stk_id);
/* Invoke the appropriate state specific event handlers.
*/
switch (cmregprx_stack_info_ptr->state)
{
case CMREGPRX_STATE_INACTIVE:
cmregprx_inactive_sim_avail_cnf_hdlr( rpt_ptr,
cmregprx_stack_info_ptr
);
break;
……
if ( rpt_ptr->hdr.cmd == CM_SIM_AVAILABLE_CNF )
{
/* Notify this event to ATCOP */
cmph_send_sim_available_ph_event();
/* get HPLMN */
cmregprx_get_hplmn(cmregprx_stack_info_ptr->mm_id.asubs_id);
}
17.cmregprx_inactive_sim_avail_cnf_hdlr()
函数描述
This function handles the SIM available cnf report from REG in INACTIVE
RegProxy's state.
主要处理:
In this state handler function, the RegProxy will
1) Validate if the sim avail cnf report was expected.
2) If validated correctly, the RegProxy will send the phone status cnf
report to MMoC.
18.cmph_send_sim_available_ph_event()
发送CM_PH_EVENT_SIM_AVAILABLE
void cmph_send_sim_available_ph_event()
{
cmph_s_type *ph_ptr = cmph_ptr();
CM_MSG_HIGH_0("sending SIM_AVAILABLE_EVENT");
cmph_event( CM_PH_EVENT_SIM_AVAILABLE);
}
三、主要日志打印:
[ 42/ 0/2] QTRACE 10:03:56.533799 MMODE/STRM/High/CM [ cmregprx.c 5008] CMREG->NAS: sub 0, Send SIM_AVAILABLE_REQ, gwl_subs_avail 1, mode_pref -1, session_type 0, nv_context 0 1
[ 47/ 0/2] QTRACE 10:03:56.533842 MM/LowFreq/High/REG [ reg_state.c 11639] DS: SUB 0 =REG= CM_SIM_AVAILABLE_REQ mode_pref:-1, session_type:0 nv_index:0 1
[ 47/ 1/2] QTRACE 10:03:56.533849 MM/HighFreq/High/REG [ reg_sim.c 2292] DS: SUB 0 =REG= reg_sim_load_card_mode called 1
[ 47/ 1/2] QTRACE 10:03:56.536453 MM/HighFreq/High/REG [ reg_send.c 2231] DS: SUB 0 =REG= MMR_SIM_AVAILABLE_REQ 1
[ 47/ 0/2] QTRACE 10:03:56.536472 MM/LowFreq/High/MM [ mmcoord.c 2110] DS: SUB 0 =MM= MM received MMR_SIM_AVAILABLE_REQ DS:1, Overall Feature: 1, Device Mode:1 1
[ 47/ 1/2] QTRACE 10:03:56.536481 MM/HighFreq/High/MM [ mmsim.c 1544] DS: SUB 0 =MM= mm_load_sim_data called 1
[ 47/ 1/2] QTRACE 10:03:56.540209 MM/HighFreq/High/MM [ mmcoord.c 1512] DS: SUB 0 =MM= Sending RR_SIM_INSERTED_REQ to RR 1
[ 47/ 1/2] QTRACE 10:03:56.540503 MM/HighFreq/High/MM [ mmcoord.c 2068] DS: SUB 0 =MM= lte accepted VPLMN [ff ff ff] 1
[ 47/ 0/2] QTRACE 10:03:56.540532 MM/LowFreq/High/REG [ reg_send.c 1045] DS: SUB 0 =REG= CM_SIM_AVAILABLE_CNF 1
[ 42/ 0/2] QTRACE 10:03:56.540559 MMODE/STRM/High/CM [ cmregprx.c 14766] NAS->CMREG: sub 0 stk 0, SIM_AVAILABLE_CNF
[ 42/ 0/2] QTRACE 10:03:56.553496 MMODE/STRM/High/CM [ cmph.c 36923] sending SIM_AVAILABLE_EVENT