帮同学宣传一下http://shop57644665.taobao.com/

GLOBAL const void mm_rr_activate_cnf (T_RR_ACTIVATE_CNF *rr_activate_cnf)

{

mm_data->rf_power = rr_activate_cnf->power;

mm_data->reg.new_cell_ind = TRUE;

//如果mnc和mcc是请求的则复制plmn。

if (reg_plmn_equal_eqv (&rr_activate_cnf->plmn, &mm_data->reg.actual_plmn))

{

mm_data->reg.actual_plmn = rr_activate_cnf->plmn; /* Struct copy */

}

//此时MM的状态如果是MM_WAIT_FOR_RR_ACTIVE,同时(mm_data->reg.op.func EQ rr_activate_cnf->op.func)

//rr_activate_cnf->op.service中返回了当前的service类型是LIMITED_SERVICE或FULL_SERVICE。

//当时FULL_SERVICE时会进行如下的操作。

//将mm_info,lai,lac,cid,gprs_indication赋值到MM对应的变量中。

mm_copy_rr_act_cnf_data (rr_activate_cnf);

//此时会判断需不需要location updating,判读函数如下

mm_normal_upd_needed()

if (mm_data->reg.update_stat EQ MS_UPDATED AND

mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai))

return FALSE;

return TRUE;

mm_attach_upd_needed()

if (mm_data->mm.mm_info.att EQ ATT_ALLOW AND mm_data->first_attach) 

return TRUE;

return FALSE;

mm_periodic_upd_needed (void)

if (mm_data->t3212_timeout AND mm_data->mm.mm_info.t3212 NEQ 0)

return TRUE;

return FALSE;

当不需要location updating时

{

TIMERSTOP (T3213);

mm_data->t3213_restart = 0;

mm_change_t3212();

//然后向GMM发送MMGMM_REG_CNF原语

reg_mm_success (FULL_SERVICE);

//向SIM发送 SIM_MM_UPDATE_REQ 原语 其中主要需要更新的有loc_info,bcch_info,forb_plmns,kc。

reg_build_sim_update (); /* Update cell id */

//同时如果不是gsm only此时还要向GMM发送MMGMM_ACTIVATE_IND。传递的参数有plmn,lac,cid,status, gprs_indicator,同时3212timer时间如下设置

if (mm_data->t3212_cfg_counter NEQ 0 AND 

mm_data->mm.mm_info.t3212 NEQ 0)

mmgmm_activate_ind->t3212_val = mm_data->t3212_cfg_counter * 10000;

else

mmgmm_activate_ind->t3212_val = mm_data->mm.mm_info.t3212 * 360000;

mm_mmgmm_activate_ind (MMGMM_FULL_SERVICE);

/* Back to MM_IDLE_NORMAL_SERVICE */

mm_data->idle_entry = RRCS_INT_NOT_PRESENT;

/* Remember MM doesn't need any IMSI ATTACH anymore */

if (mm_lup_allowed_by_gmm() AND mm_data->first_attach )

{

mm_data->first_attach_mem = mm_data->first_attach;

mm_data->first_attach = FALSE;

}

mm_data->t3212_timeout = FALSE;

mm_data->loc_upd_type.lut = NOT_RUNNING;

SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);

/* Check HPLMN timer state */

reg_check_hplmn_tim (mm_data->reg.thplmn);

USE_STORED_ENTRIES();

//当需要location updating时进行如下操作。

reg_mm_cell_selected ();//gsm only情况下

mm_data->attempt_cnt = 0;

//然后判断mm_normal_upd_needed()还是mm_attach_upd_needed()还是其他

if (mm_normal_upd_needed())

{

/*

* If updating is allowed by GMM, start procedure,

* otherwise enter state MM_IDLE_LUP_NEEDED.

*/

mm_normal_loc_upd ();

//如果GMM允许location update,此时会向RR发送RR_ESTABLISH_REQ原语,当然此时需要一个RR的连接。

mm_rr_est_req (ESTCS_SERV_REQ_BY_MM, NO_CM_SERVICE, 0);

TIMERSTOP (T3211);

TIMERSTOP (T3213);

mm_data->t3213_restart = 0;

SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_LUP);

}

else if (mm_attach_upd_needed())

{

/*

* If updating is allowed by GMM, start procedure,

* otherwise enter state MM_IDLE_LUP_NEEDED.

*/

mm_attach_loc_upd ();

//此时同mm_normal_upd_needed一样,只是mm_start_loc_upd的参数由NORMAL_LUP变为了IMSI_ATTACH_LUP,依然是发送RR_ESTABLISH_REQ原语

}

//除了mm_normal_upd_needed和mm_attach_upd_needed其他情况mm_start_loc_upd的参数变为了PERIODIC_LUP。

//最后也会进行如下调用

mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);

}

总的从代码中看来,当MM接收到从RR传送过来的RR_ACTIVATE_CNF原语后,MM会存储RR传过来的一些诸如plmn,lac,mm_info等信息,同时会通知SIM更新plmn,bcch,kc等等信息,如果此时不需要location update,MM会向GMM发送MMGMM_ACTIVATE_IND,此时是MMGMM_FULL_SERVICE。当需要location update时,根据update的类型,向RR发送RR_ESTABLISH_REQ原语。

MM接收到该原语后会根据自己当前的状态进行状态的更新,MM_IDLE_NORMAL_SERVICE或MMGMM_WAIT_FOR_UPDATE,或者没有sim或sim无效的MM_IDLE_LIMITED_SERVICE,MM_IDLE_NO_IMSI。