| 帮同学宣传一下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的结果。
















