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

Registration

因为TI的代码中是定义了GPRS的,当有GMM模块时,网络的注册是和单纯只有MM模块是不一样的,我们先只看当没有GMM时,MM是如何进行网络注册的。

MMI最后会调用GLOBAL SHORT psaMM_Registrate ( void )来进行网络注册。


GLOBAL SHORT psaMM_Registrate ( void )

{

psaMM_SetRegMode ( MODE_AUTO );

PALLOC (mmr_reg_req, MMR_REG_REQ);

//根据sim的状态来决定当前的网络服务。

if (simShrdPrm.imei_blocked EQ TRUE)

{

mmr_reg_req->service_mode = SERVICE_MODE_LIMITED;

}

else

{

mmr_reg_req->service_mode = SERVICE_MODE_FULL;

}

//以下代码实现了向MM发送了一个MMR_REG_REQ原语。

PSENDX (MM, mmr_reg_req);

}

frstFlg = FALSE;

return 0;

}

MMR_REG_REQ原语在MM的处理函数是reg_mmr_reg_req。这个函数中只有一个调用

mm_func_mmgmm_reg_req (mmr_reg_req->service_mode, 

REG_GPRS_INACTIVE,

MMGMM_CLASS_CC);

因为我们跟踪的代码是GSM only,所以现在的网络类型是MMGMM_CLASS_CC即GSM only

网络的类型定义如下:


#define VAL_MOBILE_CLASS___DEF (0x0) /* Combined GPRS attach */

#define MMGMM_CLASS_A (0x1) /* Combined GPRS */

#define MMGMM_CLASS_B (0x2) /* GPRS and GSM */

#define MMGMM_CLASS_BC (0x3) /* Combined GPRS if possible, otherwise GSM only */

#define MMGMM_CLASS_BG (0x4) /* Combined GPRS if possible, otherwise GPRS only */

#define MMGMM_CLASS_CC (0x5) /* GSM-only */

#define MMGMM_CLASS_CG (0x6) /* GPRS-only */

mm_func_mmgmm_reg_req函数中如果是GSM only则会调用 mm_reg_gsm_only_req (service_mode);


LOCAL void mm_reg_gsm_only_req (UBYTE service_mode)

{

mm_data->reg.full_service_indicated = FALSE;

/* 

* If SIM is inserted, make it valid for MM if 

* IMSI is present and full service required,

* otherwise invalidate SIM for MM

*/

switch (service_mode)

{

case SERVICE_MODE_FULL:

if (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES)

{

mm_data->reg.op.sim_ins = SIM_INSRT;

mm_data->limited_cause = MMCS_INT_NOT_PRESENT;

}

break;

case SERVICE_MODE_LIMITED:

if (mm_data->reg.op.sim_ins NEQ SIM_NO_INSRT)

{

mm_data->reg.op.sim_ins = SIM_NO_INSRT;

mm_data->limited_cause = MMCS_SIM_REMOVED; /* MMCS_SIM_INVAL_MMIREQ */

}

break;

default:

TRACE_ERROR (UNEXPECTED_PARAMETER);

break;

}

if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)

{

/*

* No valid SIM inserted

*/

mm_data->reg.bcch_encode = FALSE;

mm_data->reg.op.v_op = V_OP_PRES;

mm_data->reg.op.m = M_AUTO;

mm_mmr_reg_req (FUNC_LIM_SERV_ST_SRCH);

}

else

{

/* 

* Valid SIM inserted

*/

if (mm_data->reg.op.m EQ M_AUTO)

{

mm_auto_net_reg ();

} 

else

{

/*

* PLMN search in manual mode: Request PLMN list from RR

*/

// Patch HM >>>

mm_data->plmn_scan_mmi = TRUE;

// Patch HM <<<

mm_mmr_reg_req (FUNC_NET_SRCH_BY_MMI);

EM_START_REGISTRATION_MANUAL_MODE;

}

}

}

从这个函数中我们可以看出,注册的类型也是有不同情况的。比如开机时无SIM,手动选择注册网络或者自动搜索注册这些不同的类型。

不同情况的网络注册最后都会调用mm_mmr_reg_req这个函数,只不过传入的参数和当前的注册状态不一样而已。

自动注册函数mm_auto_net_reg中主要对PLMN进行了处理,然后也调用了

mm_mmr_reg_req (FUNC_PLMN_SRCH);

传入的类型是FUNC_PLMN_SRCH。

在mm_mmr_reg_req函数中,会根据当前MM的状态同传入的function来进行不同的处理。

此时现在注册时的MM状态


switch (GET_STATE (STATE_MM))

{

case MM_NULL:

case MM_IDLE_NORMAL_SERVICE:

case MM_IDLE_ATTEMPT_TO_UPDATE:

case MM_IDLE_LIMITED_SERVICE:

case MM_IDLE_NO_IMSI:

case MM_IDLE_NO_CELL_AVAILABLE:

#ifdef GPRS

case MM_IDLE_LUP_NEEDED:

case MM_LOCATION_UPDATING_PENDING:

case MM_IMSI_DETACH_PENDING:

#endif /* GPRS */

if (func EQ FUNC_NET_SRCH_BY_MMI)

mm_start_net_req ();

else

{

mm_rr_act_req ();

SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE);

}

break;

mm_start_net_req中将

mm_data->reg.op.func = FUNC_NET_SRCH_BY_MMI;

mm_rr_act_req ();

同时根据当前MM状态改变MM为新的状态如

SET_STATE (STATE_MM, MM_IDLE_PLMN_SEARCH);


/* PURPOSE : This function activates the RR sublayer*/

GLOBAL void mm_rr_act_req (void)

{

//分配一个RR_ACTIVATE_REQ原语。

PALLOC (rr_activate_req, RR_ACTIVATE_REQ); 

TIMERSTOP (T3211);

TIMERSTOP (T3213);

mm_data->t3213_restart = 0;

memcpy (&rr_activate_req->op, &mm_data->reg.op, sizeof (T_op));

rr_activate_req->op.service = 0; /* not used */

rr_activate_req->cell_test = mm_data->reg.cell_test;

然后根据rr_activate_req->op.func来填充RR_ACTIVATE_REQ需要的参数


typedef struct

{

T_plmn plmn; /*< 0: 8> PLMN identification */

T_op op; /*< 8: 8> operation mode */

U8 cksn; /*< 16: 1> ciphering key sequence number */

U8 _align0; /*< 17: 1> alignment */

U8 _align1; /*< 18: 1> alignment */

U8 _align2; /*< 19: 1> alignment */

T_kcv kcv; /*< 20: 20> kc - Value */

U16 accc; /*< 40: 2> access control classes */

U8 _align3; /*< 42: 1> alignment */

U8 _align4; /*< 43: 1> alignment */

T_imsi_struct imsi_struct; /*< 44: 24> mobile identity */

T_tmsi_struct tmsi_struct; /*< 68: 24> mobile identity */

U8 thplmn; /*< 92: 1> HPLN time */

U8 _align5; /*< 93: 1> alignment */

U8 _align6; /*< 94: 1> alignment */

U8 _align7; /*< 95: 1> alignment */

T_bcch_info bcch_info; /*< 96: 20> BCCH information */

U8 cell_test; /*<116: 1> cell test operation */

U8 gprs_indication; /*<117: 1> GPRS indicator */

U8 _align8; /*<118: 1> alignment */

U8 _align9; /*<119: 1> alignment */

T_eq_plmn_list eq_plmn_list; /*<120: 20> Equivalent plmn List */

} T_RR_ACTIVATE_REQ;

在func为FUNC_PLMN_SRCH是会填充MM当前的对应变量。同时会根据SIM的状态来填充原语的参数。

最后想RR发送原语。

PSENDX (RR, rr_activate_req);

}

当RR完成向下网络段的交互后会返回RR_ACTIVATE_CNF消息通知MM register的结果。