选网

来源:互联网 发布:二级代理软件下载 编辑:程序博客网 时间:2024/04/28 07:10

/*红字为log

ds3gcmif.c 03720Rx'ed CM_CALL_CONNECTED_CMD

ds3gi_process_cm_call_connected_cmd

ds_3gpp_pdn_context.c 08954 Setting up TypeIP V4 PS Iface

调用ds_pdn_cntxt_setup_ipv4_ps_iface

ps_iface.c 02256 Setting iface 0x8004:0 IPAddress to 10.44.84.90

ps_iface_set_v4_addr

ds_3gpp_pdn_context.c Setting up Type PDP-IP stack

ds_pdn_cntxt_setupIPv6PSIface

 

ps_ifacei_event.c00359 Phys link evt 2 on iface=0x8004:0

ps_ifacei_phys_link_event_cback .这个函数会再次调用ps_ifacei_invoke_event_cbacks来调用事件回调处理函数

event=2= IFACE_PHYS_LINK_UP_EV

0x8004是iface的名字,即UMTS_IFACE

:0表示instance0或者1

 

ps_flow.c00994 FLOW ACTIVATE IND 0x2F121D14, state 0x1, info code 0

ps_flow_activate_ind()

 

 

ps_ifacei_event.c02284 IFACE UP IND 0x8004:0, state 4

ps_iface_up_ind

state 4= IFACE_COMING_UP表示当前的iface的状态

 

ds3gcmif.c03798 Data call connected

ds3gi_process_cm_call_connected_cmd

这个函数和最上面的第一条log是对应的,因为那个函数处理之后一直跳转到其他函数去处理里,在这个地方菜真正返回到原来的函数

此时ds3gi_call_info[call_inst].call_state =DS3G_CALL_ACTIVE_CALL_STATE;

 

桥接上rm

ps_iface.c01899 bridging iface 0x8008:0 in state 4 to iface 0x8004:0

ps_iface_set_bridge

8008=SIO_IFACE是要桥接的iface的名字

8004=UMTS_IFACE桥接iface的名字

 

ps_ifacei_event.c02448 IFACE PHYS LINK UP IND 0x8008:0, state 4

ps_iface_phys_link_up_ind

 

ds_qmi_wds.c20481 Sending call status Client 4 (wds_sp) 2f899ef0

 */

前面注释了


http://www.doc88.com/p-978197088893.html:gsm 搜网流程log

搜网相关的专业词汇解释

LCF:last camped freq

rrccsp: rrc cell selection procedure

rrcmcm :  rrc mode controll module

rrcllc :  RRC Lower Layer Controller Interface

Addl chl:additional channel

oos:OUT_OF_SERVICE_AREA_SCAN

oc:ordered_config

pscan:power scan

ARFCN :绝对无线频道编号 (Absolute Radio Frequency Channel Number 

#define RRC_UL_BAND_A_UARFCN_MIN 9612 //每个band对应的频点号的范围在此定义


#define  RRC_CSP_PCS_BAND              0x0001 //1900 MHz ,band的定义

选网NAS层

start_plmn_selection(rplmn)

NAS层有很多的模块,每个模块对应一个文件夹,根据发给nas不同的模块来选择不同的处理函数

如发给nas层的mm模块的命令处理函数入口为mm_process_messages(...)---》mmcoord_route_mm_message(...)

在这个函数里会根据message->cmd.hdr.message_set消息集分配给不同的处理模块。如选网时,nas层的reg模块会调用reg_send_mmr_reg_req函数给MM发消息集是MS_MM_REG,且message->cmd.hdr.message_id=MMR_REG_REQ

则调用mmcoord_process_mmr_reg_req( message );。所以先通过消息集过滤,在通过id号

mmcoord_process_mmr_reg_req_now在这个函数里会检查mm_rat_change_pending和mm_serv_change_pending是否为1,即rat技术是否改变或者请求的服务域是否变化,跟踪到的mm_serv_change_pending=1,所以会走下面三步:

    mm_handle_message ( message );    gmm_handle_message( message );    /* ------------------------------------------------------------------------    ** Continue with Registration if RAT change or service domain change is    ** not requested. Otherwise the RAT/Service change is performed first and    ** the LU procedure is initiated.    ** -----------------------------------------------------------------------*/    mmcoord_process_lu_procedure( message );

mm_handle_message--mm_handle_registration
由于mm_serv_change_pending=1,所以执行mm_handle_rat_change,此时mm_serving_plmn.info.reg_service_domain=SYS_SRV_DOMAIN_NO_SRV

所以执行mm_change_service_domain--mmcoord_process_lu_procedure,此时还没有附着上网,所以进入mm_substate_control( MM_STD_PLMN_SEARCH )函数处理

此时mm_idle_substate=MM_NO_IMSI,所以next_substate=MM_PLMN_SEARCH

mm_serving_plmn.ms_op_mode=SYS_SRV_DOMAIN_CS_PS,所以gmm_set_substate(GMM_PLMN_SEARCH);但gmm_state == GMM_NULL所以不会改变状态

然后mm_send_service_req(...)里面包含了请求的参数SYS_RAT_GSM_RADIO_ACCESS或者SYS_RAT_UMTS_RADIO_ACCESS。这个函数通过函数rrc_get_mm_cmd_buf往rrc层发的命令参数是:

rrc_cmd->cmd_hdr.cmd_id = <span style="color:#cc0000;">RRC_SERVICE_REQ</span>rrc_cmd->cmd.rrc_service_req.requested_plmn.plmn_type =RRC_GSM_MAP_ANY_PLMN_REQ;message->cmd.mmr_reg_req.new_scan=1rrc_cmd->cmd.rrc_service_req.use_timer=1rrc_cmd->cmd.rrc_service_req.wcdma_scan_time = message->cmd.mmr_reg_req.scan_time=1000
 (void) rex_set_sigs(&rrc_tcb, RRC_MM_CMD_Q_SIG);


下面写的是rrc层对这个命令的处理

rrc层的命令接受入口点在文件rrc_task.c文件里的rrc_task(...)->rrc_dispatcher(...),整个循环都在rrc_dispatcher里面

1、wcdma选网流程

从NAS层的MM通过mm_send_service_req函数发送RRC_SERVICE_REQ命令给rrc层,接下来在rrc里面处理这个命令。由于是mm层送下来的命令,所以派遣函数调用

rrc_dispatch_mm_commands->rrcmcm_event_handler

此时rrcmcm_state=RRCMCM_INITIAL 所以执行rrcmcm_initial_substate_event_handler,且rrc_mode=RRC_MODE_INACTIVE

          rrcmcm_cmd_store.rrcmcm_mm_req_cmd = *cmd_ptr;          /* Send a Start WCDMA mode request to L1 */          rrcmcm_send_start_wcdma_req();          rrcmcm_cmd_store.rrcmcm_cmd_flag = RRCMCM_CMD_SERVICE_REQ;          rrcmcm_state = RRCMCM_WAIT_START_CNF;

给L1层发Start WCDMA mode相关的命令,且保存当前RRC_SERVICE_REQ这个未处理完的命令,改变rrcmcm的状态。

之后便等待从L1层返回RRC_CPHY_START_WCDMA_MODE_CNF命令。

如果此时已经是RRC_MODE_ACTIVE状态,则直接开始cell selection,通过调用rrc_cell_selection_procedure函数。

 

   当从L1返回后,L1会给rrc发回一个RRC_CPHY_START_WCDMA_MODE_CNF的确认命令。由于是L1层返回的命令,所以调用的是

rrc_dispatch_l1_commands->rrcmcm_event_handler-rrcmcm_wait_start_cnf_substate_event_handler,此时的

cmd_ptr->cmd_hdr.cmd_id = RRC_CPHY_START_WCDMA_MODE_CNF

接下来处理之前未处理完保存起来的RRC_SERVICE_REQ命令。主要包括几步操作

       rrcmcm_update_mode(RRC_MODE_ACTIVE);将rrc_mode状态变为RRC_MODE_ACTIVE       rrc_dual_mode_enabled=1     /* Forward inter-RAT PLMN search request to CSP */       rrc_cell_selection_procedure((rrc_cmd_type*)&rrcmcm_cmd_store.rrcmcm_mm_req_cmd);开始选cell        /* Start the RSSI reporting timer */        rrctmr_start_timer( RRCTMR_RSSI_BER_TIMER,                            RRCTMR_RSSI_BER_REPORT_TIME );       rrcmcm_init_data(INIT_ALL);

    rrcmcm_state = RRCMCM_INITIAL; 改变mcm的状态为initial    stop_cause = RRC_RAT_CHANGE;    rrcmcm_est_req_saved_flag = FALSE;    rrcmcm_send_stop_cnf_to_mm_flag = FALSE;
    memset(&rrcmcm_cmd_store,0,sizeof(rrcmcm_cmd_store));    rrcmcm_cmd_store.rrcmcm_abort_flag = RRCMCM_RR_ABORT_NONE;     rrcmcm_cmd_store.rrcmcm_cmd_flag = RRCMCM_CMD_NONE;  //指示是否有命令等待处理    rrcmcm_cmd_store.rrcmcm_change_mode_req.mode = RRC_MODE_MAX;

小区选择程序

 上面

rrc_cell_selection_procedure((rrc_cmd_type*)&rrcmcm_cmd_store.rrcmcm_mm_req_cmd)
里面参数
rrcmcm_cmd_store.rrcmcm_mm_req_cmd

保存的是服务请求的命令,所以进入default里面处理,此时rrc_csp_substate=RRCCSP_NO_CELL_SELECTED这个变量代表的是当然是否选择上小区了

rrc_csp_substate = rrccsp_no_cell_selected_hdlr (cmd_ptr);

rrc_curr_state = RRC_STATE_DISCONNECTED,这个变量代表的rrc连接状态,很显然现在没有建立rrc连接

next_substate = rrccsp_no_cell_sel_srvc_req( cmd_ptr );
这个函数在代码里面的描述是这样的:

This function processes a Service Request when in RRCCSP_NO_CELL_SELECTED substate. It verifies contents of Service Request and sends an Acq.Req to L1.

Note that the Stored Acquisition database will have to be searched for the requested PLMN.正式开始选网

首选进入rrccsp_cleanup_bplmn_state函数处理,因为rrc_csp_int_data.bplmn_guard_srch_tmr_expired初始化为1所以没做处理。

{

此时rrc_csp_int_data.curr_scan = RRC_CSP_CELL_SELECTION_SCAN  /* Scan triggered by one of MM commands (Service Req/Act Req etc)  */
}

  rrc_csp_init_data_from_service_req(&cmd_ptr->cmd.rrc_service_req)

{

This function stores the data passed in RRC_SERVICE_REQ and initializes RRC data and CSP local data with the passed  data.

实际上是初始化rrc_csp_int_data结构体里面的一些数据

}

由于此时rrc_csp_int_data.ue_in_deep_sleep=0,所以进入next_substate = rrc_csp_start_sel_on_mm_req();

rrc_csp_start_sel_on_mm_req

{

  /* Look for a frequency for this PLMN in RRC CSP Acquisition database now.
   * Store the Acq. entry and type returned by Stored and Initial Selection
   * Controller in the Internal Data.
   */

This function starts a cell selection in response to a newly received service request from MM。

The acquisition  type is initialized based on therequested PLMN type

The current scan is set to Cell selection scan.
Based on the returned frequency scan type, a CSP substate is returned.根据返回的频率扫描类型(RRC_CSP_ACQ_SCAN orRRC_CSP_FINE_SCAN or other)csp的子状态也不同

    rrc_csp_int_data.curr_scan = RRC_CSP_CELL_SELECTION_SCAN;

    /* Update GSM with UE's band preference */
    rr_rrc_set_band_pref(rrc_csp_int_data.band_pref);

    rrc_csp_curr_select_data.next_band_mask = rrc_csp_int_data.wcdma_band_mask;//下一个要扫描的频带

   rrc_csp_start_cell_selection(&rrc_csp_int_data.curr_req_plmn, 
                                  &rrc_csp_int_data.curr_type_acq,  // RRC_CSP_ANY_PLMN 想要获取的plmn的类型,这里是non-barred, non-forbidden reg area cell of any PLMN
                                  &rrc_csp_int_data.curr_acq_entry,
                                  &type_freq_scan

rrc_csp_continue_stored_initial_select_ctrl

接下来给L1发命令

rrc_csp_send_next_freq_to_l1(&rrc_csp_int_data.curr_acq_entry, type_freq_scan)

{

这个函数会根据type_freq_scan频率扫描类型给L1发CPHY_ACQ_REQ(如果type_freq_scan=RRC_CSP_ACQ_SCAN)或者CPHY_FREQ_SCAN_REQ

当发CPHY_ACQ_REQ请求时

    rrc_csp_int_data.acq_mode = L1_WCDMA_ACQ_DET_LIST;//可以获得一系列的扰码,一个扰码对应一个小区,就是说可以扫描出一个频率上的多个小区
    rrc_csp_int_data.acq_type = L1_WCDMA_FREQ_ONLY;//仅根据频率来获取小区

实际上这个请求在得到CNF时ms也是不知道小区的很多的信息的,只是知道了扰码组0,之后通过读取sib信息才能获取plmn以及cell_id等

}

 next_substate = RRCCSP_CELL_SEL_WT_FREQ_SCAN_CNF;  /* Start waiting for Frequency scan Confirmation */

}

rrc_csp_send_next_freq_to_l1(&rrc_csp_int_data.curr_acq_entry, type_freq_scan); //type_freq_scan = RRC_CSP_RAW_SCAN他会先给L1发一个RRC_RESET_L1_REQ,紧接着再发一个频率扫描请求:

 rrc_csp_send_l1_freq_scan_cmd(RRC_PROCEDURE_CSP,acq_entry_ptr->freq,type_freq_scan)


进入等待扫描结果后的处理函数rrccsp_cell_sel_wait_freq_scan_cnf_hdlr--->case :RRC_LLC_CMD_CNF--RRC_LL_CPHY_FREQ_SCAN_CNF.

next_substate = rrccsp_cell_sel_wait_freq_scan_cnf_recvd( cmd_ptr );rrc_csp_update_freq_scan_entry(&cmd_ptr->cmd.rrc_llc_cnf.cnf.freq_scan_cnf)首先保存扫描到的数据,本次扫描是      rrc_csp_curr_select_data.scan_info.type_freq_scan == RRC_CSP_RAW_SCAN      freq_scan_cnf->step == L1_FREQ_LIST_SCAN      rrc_csp_curr_select_data.scan_info.raw_scan.freq_result[i] = freq_scan_cnf->freq_result[i];next_substate = rrc_csp_continue_cell_selection(){rrc_csp_continue_stored_initial_select_ctrl      (        &rrc_csp_int_data.curr_type_acq, //RRC_CSP_ANY_PLMN        &rrc_csp_int_data.curr_acq_entry,//已经初始化些参数了,如搜索频率的起点        &type_freq_scan //RRC_CSP_NO_SCAN      ) 
</pre><pre name="code" class="cpp">由于此时的扫描类型是RRC_CSP_RAW_SCAN,rrc_csp_curr_select_data.acq_type=RRC_CSP_ANY_PLMN
rrc_csp_get_next_freq_scan_entry(&ret_freq)
</pre><pre name="code" class="cpp">/* This macro picks the first frequency from raw scan list in current * selection data and returns the frequency for <span style="color:#cc0000;"><strong>fine scan</strong></span>. It also * initializes the fine scan list and sets the <strong><span style="color:#cc0000;">type of scan to Fine Scan</span></strong>. */从raw 搜索里面挑选第一个频率来进行fine scan
RRC_CSP_PICK_FIRST_RAW_FREQ_FOR_FINE_SCAN();
      /* The next L1 cmd depends on the current frequency scan type */      *ret_type_freq_scan =  rrc_csp_curr_select_data.scan_info.type_freq_scan;
<span style="font-family: Arial, Helvetica, sans-serif;">    rrc_csp_curr_select_data.scan_info.fine_scan_completed = FALSE;   \    rrc_csp_curr_select_data.scan_info.fine_scan.curr_freq_index = 0; \    rrc_csp_curr_select_data.scan_info.fine_scan.num_freq = 0;        \    rrc_csp_curr_select_data.scan_info.type_freq_scan = RRC_CSP_FINE_SCAN;  \这里就转变了csp搜索类型为fine 搜索</span>
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>

这个函数返回后rrc_csp_send_next_freq_to_l1(&rrc_csp_int_data.curr_acq_entry, type_freq_scan)

由于返回的type_freq_scan == RRC_CSP_ACQ_SCAN,所以

    next_substate = RRCCSP_CELL_SEL_WT_FREQ_SCAN_CNF;

FINE扫描确认后的处理:

rrccsp_cell_sel_wait_freq_scan_cnf_recvd()

rrc_csp_update_freq_scan_entry(&cmd_ptr->cmd.rrc_llc_cnf.cnf.freq_scan_cnf)用扫描后获取到的数据来更新urrent selection data and list frequency scan

{

 1、 if((rrc_csp_curr_select_data.scan_info.type_freq_scan == RRC_CSP_RAW_SCAN) && 
     (freq_scan_cnf->step == L1_FREQ_RAW_SCAN))他会根据扫描类型以及这个cnf是哪个扫描的结果来进行相应的处理

 2、  if((rrc_csp_curr_select_data.scan_info.type_freq_scan == RRC_CSP_FINE_SCAN) && 
     /*lint -e506*/
     (freq_scan_cnf->step == L1_FREQ_FINE_SCAN))

    rrc_csp_curr_select_data.scan_info.fine_scan_completed = TRUE;

      rrc_csp_curr_select_data.scan_info.fine_scan.freq_result[i] = freq_scan_cnf->freq_result[i];//将获取到的频率保存起来

然后进入next_substate = rrc_csp_continue_cell_selection();//这个函数的处理如下

}

rrc_csp_continue_cell_selection

这个函数里有两个很重要,其中第一个是主要的:

1、rrc_csp_continue_stored_initial_select_ctrl
      (
        &rrc_csp_int_data.curr_type_acq, 
        &rrc_csp_int_data.curr_acq_entry,
        &type_freq_scan
      )  //其主要的作用是要获取一个和plmn相关的频率来扫描或者获取

2、rrc_csp_send_next_freq_to_l1(&rrc_csp_int_data.curr_acq_entry, type_freq_scan);根据扫描类型给L1发命令

rrc_csp_continue_stored_initial_select_ctrl函数的处理主要流程如下:

{

switch(rrc_csp_curr_select_data.acq_type)根据获取类型RRC_CSP_SPEC_PLMN or RRC_CSP_ANY_PLMN

case RRC_CSP_ANY_PLMN

rrc_csp_get_next_freq_scan_entry(&ret_freq) 

  {

  rrc_csp_curr_select_data.scan_info.type_freq_scan=RRC_CSP_FINE_SCAN

  }

}

CPHY_CELL_SELECTION_REQ : then  next_state=RRCCSP_SUIT_CELL_SEL_WT_SERV_S

RRC_LL_CPHY_CELL_SELECTION_CNF:     rrc_llc_cnf.cnf.cell_sel_cnf.evaluated=true表示L1层已经对小区参数进行了评估,通过下面两个参数:

rrc_llc_cnf.cnf.cell_sel_cnf.s_qual      /* Cell Selection quality Value */

rrc_llc_cnf.cnf.cell_sel_cnf.s_rxlev       /* Cell Selection RX Level Value */

如果这两个参数都大于零,表示evaluate 通过了,然后会选择去驻留在这个小区

RRC_CELL_CHANGE_REQ  :then next_substate = RRCCSP_SUIT_CELL_SEL_WT_CAMP 

RRC_CELL_CHANGE_CNF:里面会提示是否驻留在这个小区(Camped on a Cell )cell_change_cnf.cell_change_status=RRC_CELL_CHANGE_SUCCESS


rrccsp给MM发送RRC_SERVICE_CNF并且当rrc_service_cnf.service_status=MM_AS_NO_SERVICE时

            ** If the PLMN was not found then send the available list to REG
            ** in the MMR_REG_CNF

MSG          NAS MM/High                                                     00:00:18.522               mmplmnsel.c  00368  MM sent RR_PLMN_SELECT_REQ :进行GSM的选网

GSM选网

rr_control函数里面也有个大循环,while,跟下面的rr_selection_control函数是一样的

{

if: rr_state=RR_GOING_ACTIVE and

    rr_event == EV_GSM_MODE_ACTIVATED then

          if ( rr_process_panic_reset_saved_msg(&new_message_ptr) == EV_INPUT_MESSAGE )
          {
            rr_state = RR_NO_CHANNELS;
            new_rr_event = EV_INPUT_MESSAGE;
          }

    然后进入下一轮的处理,注意此时的rr_state = RR_NO_CHANNELS;

}

rr_selection_control函数里面有个大的循环while

循环最后的处理时这样的

while (cell_select_event != EV_NO_EVENT){   ...      ...   ...    if (new_cell_select_event != EV_NO_EVENT)    {      cell_select_event = new_cell_select_event;      new_cell_select_event = EV_NO_EVENT;    }    else    {      cell_select_event = EV_NO_EVENT;    }}rr_selection_control{if :cell_select_event=EV_INPUT_MESSAGE and     cell_select_state=RR_SELECTION_IDLE and     message_set == MS_MM_RR  and    message_id=RR_PLMN_SELECT_REQ then     rr_process_plmn_select_req -->return RR_EV_PROCESS_PLMN_SELECT_REQ;}rr_selection_control {case: cell_select_event:RR_EV_PROCESS_PLMN_SELECT_REQ and           cell_select_state =RR_SELECTION_IDLE  then       rr_perform_plmn_select_req_selection-->rr_selection_start_cell_selection  -->MPH_POWER_SCAN_REQ

TD-SCDMA :下行的同步

上行链路同步是UE发起一个业务呼叫前必须的过程,如果UE仅驻留在某小区而没有呼叫业务时,UE不用启动上行同步过程。

在下行链路上UE和系统取得同步后,由于UENODE-B的距离关系,系统还不能正确接受UE发送的消息。为了避免在不恰当的时间发送消息而对系统造成干扰,UE在上行方向首先要在UpPTS时隙上发送SYNC_UL(突发脉冲)UpPTS时隙专用于UE和系统的上行同步,没有用户的业务数据。

按照系统设置,每个DwPTS序列号对应8SYNC_UL码字,UE根据收到的DwPTS信息,随机决定将使用的上行SYNC_UL码字。UE决定SYNC_DL的方式类似,Node-B可以采用逐个做相关运算的办法,判断UE当前使用的是哪个上行同步码字。

  系统收到UE发送的SYNC_UL,就可得到SYNC_UL的定时和功率信息。并由此决定UE应该使用的发送功率和时间调整值,在接下来的4个子帧中的某一子帧通过F-PACH信道发送给UE。在F-PACH信道中还包含UE初选的SYNC-UL码字信息以及Node-B接收到SYNC_UL的相对时间,以区分在同一时间段内使用不同SYNC-ULUE,以及不同时间段内使用相同SYNC-ULUEUEF-PACH上接收到这些信息控制命令后,就可得知自己的上行同步请求是否已经被系统接受。