OAI项目GDB调试及代码分析

OAI项目GDB调试及代码分析

注:由于本人才研0,水平有限,另外代码分析也只进行了一部分,可能会有一些理解不到位,希望大家积极批评指正;另外如果有一起研究OAI项目代码的也可以联系我。

如果想使用GDB调试工具对项目进行调试,首先需要在编译时加入调试信息。

在完成之前的对eNB和UE的编译之后,使用作者写的编译脚本,同时加上-g选项加入调试信息

./cmake_targets/build_oai -g

完成之后即可使用gdb调试。

在这个项目中好像不用在编译时加上调试信息就可以调试了,当然,正常情况下还是需要加调试信息的。

1. 多线程调试

该项目中使用了多进程、多线程来实现,一些关于多线程的理论知识:

一般来说,多线程对共享资源的访问是通过锁和条件变量来实现

  • pthread_mutex_lock();线程调用该函数来获取锁

  • pthread_mutex_unlock();线程调用该函数来释放锁

  • pthread_cond_signal();发送一个信号给另一个处于阻塞(休眠)等待状态的线程,且根据优先级选择只给某个线程发送一次

  • pthread_cond_wait();用于阻塞当前线程,必须放在pthread_mutex_lock和pthread_mutex_unlock之间,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast()来唤醒

  • pthread_cond_broadcast();用于唤醒所有被阻塞的线程

2. 调试技巧

  1. start

    (gdb)start
    

    开始运行程序,并在程序入口(main函数第一行)设置断点,且运行到此处

  2. run

    (gdb)r
    

    运行程序

  3. breakpoint

    (gdb)b n
    

    在第n行设置断点

  4. clear

    (gdb)clear
    (gdb)delete n
    

    清除所有断点;

    清除第n行的断点

  5. continue

    (gdb)c
    

    继续运行直到下个断点

  6. step

    (gdb)s
    

    单步调试且进入函数

  7. next

    (gdb)n
    

    单步调试但不进入函数

  8. 输出多信息时不会暂停

    (gdb)set pagination off
    (gdb)set height 0
    

    有时候输出信息比较多,无法在一页显示,gdb会暂停并询问你,特别麻烦

  9. list

    (gdb)l
    

    列出10行源码

  10. skip

    (gdb)skip function fun1
    

    跳过名为fun1的函数,使用step也不会进入

  11. 图形化界面

    运行gdb过程中使用“Crtl+X+A”组合键,可以进入图形化界面

3. 插件

gdb调试工具有几种插件可以使用,有助于更好的观察调试结果。

一般来说有三个常用的:pade、gef、gdbinit

git clone https://github.com/gatieme/GdbPlugins.git ~/GdbPlugins

git clone可以使用代理,代理之后git clone会快很多

git config --global https.proxy http://127.0.0.1:1088
git config --global https.proxy https://127.0.0.1:1088

下载完插件之后,在打开gdb之前用以下三个命令可以分别使用不同的插件:

peda:

echo "source ~/GdbPlugins/peda/peda.py" > ~/.gdbinit 

gef:

echo "source ~/GdbPlugins/gef/gef.py" > ~/.gdbinit 

gdbinit:

echo "source ~/GdbPlugins/gdbinit/gdbinit" > ~/.gdbinit 

4. eNB部分

先设置环境变量:

export RFSIMULATOR=enb

进入调试界面,-q表示不打印gdb版本信息:

gdb -q lte-softmodem

设置参数:

(gdb)set args -O ~/opencells-mods/enb.10MHz.b200 --rfsim

设置完参数就可以进行调试了

  • 调试结果记录:

eNB一共有11个线程:

OAI项目GDB调试及代码分析_第1张图片

5. UE部分

首先同样要先生成虚拟SIM卡,创建网络名称空间

gdb -q lte-uesoftmodem

设置参数:

(gdb)set args -C 2685000000 -r 50 --rfsim --rfsimulator.serveraddr 10.200.1.1

在UE中,由于程序中fork了一个子进程,所以需要多进程调试,否则在调试过程中就会出现fork完子进程后,子进程就不受控制的运行起来导致无法调试。

在进入gdb调试工具之后,先查看此时指定调试的进程是父进程还是子进程

(gdb)show follow-fork-mode

看到目前选择调试的是子进程,我们将它改成父线程:

(gdb)set follow-fork-mode parent
(gdb)show follow-fork-mode
image-20200804204731997

接下来查看调用fork后相关进程的运行情况

~~(gdb)show detach-on-fork~~
image-20200804204754646

将detach-on-fork设置成off模式,原先follow-fork-mode指定的进程(即我们设定的父进程)将被调试,而未受控制的子进程会被阻塞住(阻塞在fork处),置于暂停状态。

~~(gdb)set detach-on-fork off~~
~~(gdb)show detach-on-fork~~
image-20200804204822772

但是在实际操作中发现,先设置为调试父进程+阻塞子进程的方式会有问题,在运行到fork函数之后:

同时,会显示:image-20200806002019568

但是当只设置成调试父进程,程序就可以正常运行和调试。

接下来就可以继续调试了。

5.1 线程概述

ue一共有8个线程:

  1. main函数主线程
  2. rrc_control_socket_thread线程:在main函数672行: rrc_control_socket_init();中创建
  3. TASK_NAS_UE线程:在main函数759行:create_tasks_ue(NB_UE_INST)中创建
  4. TASK_RRC_UE线程:在main函数759行:create_tasks_ue(NB_UE_INST)中创建
  5. UE_thread_rxn_txnp4线程1:在main函数780行:init_UE()函数的init_UE_threads()函数中创建
  6. UE_thread_slot1_dl_processing线程1:在main函数780行:init_UE()函数的init_UE_threads()函数中创建
  7. UE_thread_rxn_txnp4线程2:在main函数780行:init_UE()函数的init_UE_threads()函数中创建
  8. UE_thread_slot1_dl_processing线程2:在main函数780行:init_UE()函数的init_UE_threads()函数中创建
  9. UE_thread_synch线程:在main函数780行:init_UE()函数的init_UE_threads()函数中创建
  10. UE_thread线程:在main函数780行:init_UE()函数的375行中创建

注:该图是在gdb调试过程中的信息,只显示了8个线程,且大多数线程名字相同,但是程序中基本上给每一个线程都命了名,不知道为什么是这样显示的。

image-20200806230641141

其中最主要的线程为 UE_thread 线程,该线程控制了用于发射/接收的线程以及同步的线程

This is the main UE thread.
 * This thread controls the other three UE threads:
 * - UE_thread_rxn_txnp4 (even subframes)
 * - UE_thread_rxn_txnp4 (odd subframes)
 * - UE_thread_synch

(记录,暂时没用):

运行线程线程1、线程2和线程7的结果都是等待消息的接收:

image-20200806230943368

同时显示的跟踪信息也是一样:

image-20200806230538988

运行线程3、4无打印信息,显示的跟踪信息为:

image-20200806231555339

线程5、6的跟踪信息为:

image-20200806232034087

线程8的跟踪信息:

OAI项目GDB调试及代码分析_第2张图片

  • 第一个线程是主线程

  • 第二个线程:

在主函数中的第672行:

image-20200808223920251

在上述函数的5852中创建了线程:

OAI项目GDB调试及代码分析_第3张图片

接下来用到了signal函数,看不懂

image-20200808230329321

  • 第三个、第四个线程:

在主函数的759行:

image-20200808231042317

在上述函数的54、64行:

image-20200808231245460 image-20200808231259448

在itti_create_task()函数中创建了线程:

image-20200808231401796
  • 线程5/6/7/8:

在主函数的780:

image-20200808232144673

在init_UE()函数的361行: init_UE_threads(inst) 中:

OAI项目GDB调试及代码分析_第4张图片

创建了UE_thread_rxn_txnp4、UE_thread_slot1_dl_processing、UE_thread_synch线程,同时这个for循环执行了两次,所以一共创建了六个线程;

同时,init_UE()函数的373行:创建了线程UE_thread。

5.2 源码分析

OAI整体框图如下:

OAI项目GDB调试及代码分析_第5张图片

5.2.1 线程2

lte-uesoftmodem.c 文件 main函数中的rrc_control_socket_init(),在该函数的pthread_created()函数中运行了void *rrc_control_socket_thread_fct(void *arg)

首先是接收到一个消息(receive a message from ProSe App),ProSe是基于邻近的服务,应该是监听附近的eNB发出的信息

接下来在switch中判断接收到的信息类型,

switch (sl_ctrl_msg_recv->type) {
     
  case SESSION_INIT_REQ:
  case GROUP_COMMUNICATION_ESTABLISH_REQ:
  case GROUP_COMMUNICATION_RELEASE_REQ:
  case DIRECT_COMMUNICATION_ESTABLISH_REQ:
  case PC5S_ESTABLISH_REQ:
  case PC5_DISCOVERY_MESSAGE:
}

第一个case里,发送了一个**消息出去(存入send_buf中)

第二个case里,配置了底层 PDCP/MAC/PHY ,建立了SLRB直通链路无线承载(DRB3)

第三个case里,释放了承载

第四个case和第二个case差不多

第五个case里,配置了底层 PDCP/MAC/PHY ,建立了SLRB直通链路无线承载(DRB10)

第六个case…

5.2.2 线程3

lte-uesoftmodem.c 文件 main函数中的第759行:create_tasks_ue(NB_UE_INST)函数

在该函数的54行:itti_create_task (TASK_NAS_UE, nas_ue_task, users)中创建了线程3,伴随该线程运行的函数为: nas_ue_task()

在nas_ue_task()函数中,首先是从三个文件中分别获取了USIM、UE和EMM的数据;

接下来有个什么接口初始化?没看懂

/* Initialize user interface (to exchange AT commands with user process) */
nas_user_api_id_initialize(user);

接下来以ITTI的形式(?)发送了一个什么message?注释中说是 /* Set UE activation state */

然后又是一个while(1)循环

等待一个message或者event的发生,并在switch中判断接收到的message类型,

switch (ITTI_MSG_ID(msg_p)) {
     
  case INITIALIZE_MESSAGE:
  case TERMINATE_MESSAGE:
  case MESSAGE_TEST:
  case NAS_CELL_SELECTION_CNF:
  case NAS_CELL_SELECTION_IND:
  case NAS_PAGING_IND:
  case NAS_CONN_ESTABLI_CNF:
  case NAS_CONN_RELEASE_IND:
  case NAS_UPLINK_DATA_CNF:
  case NAS_DOWNLINK_DATA_IND:
  default:
}

总体来说,线程3应该是在做接收NAS层消息的事情,且NAS接收到的消息应该是UE发出的控制面信令消息

比如在第一个case INITIALIZE_MESSAGE中,进入到nas_user_receive_and_process (user, user_data)函数,在该函数中,读取了接收缓存中的数据:

image-20200815151558614

对应到打印信息应该是:

OAI项目GDB调试及代码分析_第6张图片

接收到用户应用层发送的数据之后,进行解码:

image-20200815152027260

对应到打印信息应该是image-20200815152314679

解码后进行消息处理:

image-20200815152634485

对应到打印信息应该是

image-20200815152724043

但是打印信息中ue和enb连接(注册?)时进行的后半部分流程(选中的该行开始)好像不在线程3中:

OAI项目GDB调试及代码分析_第7张图片

另外,在线程3的while循环中所监听的ITTI_msg中,除了刚刚所述的INITIALIZE_MESSAGE之外,还有其他几种类型,且在输出的打印信息中都是以 [UE 0] Received 开头的,可以找到又以下几类:

OAI项目GDB调试及代码分析_第8张图片

如上图,应该是用户给NAS层发送的小区选择的指令,在线程3中根据这个message的类型执行了相应的信令流程。

5.2.3 线程4

执行rrc_ue_task()函数,该函数也在while(1)循环中等待消息:

itti_receive_msg (TASK_RRC_UE, &msg_p);

并通过switch判断该接收消息的类型

switch (ITTI_MSG_ID(msg_p)){
     
    case TERMINATE_MESSAGE:
    case MESSAGE_TEST:
/* MAC messages */
    case RRC_MAC_IN_SYNC_IND:
    case RRC_MAC_OUT_OF_SYNC_IND:
    case RRC_MAC_BCCH_DATA_IND:
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
    case RRC_MAC_BCCH_MBMS_DATA_IND:
#endif
    case RRC_MAC_CCCH_DATA_CNF:
    case RRC_MAC_CCCH_DATA_IND:
#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
    case RRC_MAC_MCCH_DATA_IND:
# endif
/* PDCP messages */
    case RRC_DCCH_DATA_IND:
    case NAS_KENB_REFRESH_REQ:
/* NAS messages */
    case NAS_CELL_SELECTION_REQ:
        switch (rrc_get_state(ue_mod_id)){
     
        case RRC_STATE_INACTIVE:
        case RRC_STATE_IDLE:
        case RRC_STATE_CONNECTED:
        default:
        }
    case NAS_CONN_ESTABLI_REQ:
        switch (rrc_get_state(ue_mod_id)){
     
        case RRC_STATE_IDLE: 
        case RRC_STATE_INACTIVE:
        case RRC_STATE_CONNECTED:
        default:
        }
    case NAS_UPLINK_DATA_REQ:
# if ENABLE_RAL
	case RRC_RAL_SCAN_REQ:
        switch (rrc_get_state(ue_mod_id)){
     
            case RRC_STATE_INACTIVE:
        	case RRC_STATE_IDLE: 
        	case RRC_STATE_CONNECTED:
        	default:
        }
     case PHY_FIND_CELL_IND:
        switch (rrc_get_state(ue_mod_id)) {
     
                case RRC_STATE_IDLE:
                	switch (rrc_get_sub_state(ue_mod_id)){
     
                            case RRC_SUB_STATE_IDLE_SEARCHING:
                            default:
                    }
                case RRC_STATE_INACTIVE:
                case RRC_STATE_CONNECTED:
                default:
        }
        case PHY_MEAS_REPORT_IND: 
        case RRC_RAL_CONFIGURE_THRESHOLD_REQ:
        case RRC_RAL_CONNECTION_ESTABLISHMENT_REQ:
        	switch (rrc_get_state(ue_mod_id)){
     
                    case RRC_STATE_IDLE:
                    case RRC_STATE_INACTIVE:
                    case RRC_STATE_CONNECTED:
                    default:
            }
        case RRC_RAL_CONNECTION_RELEASE_REQ:
#endif
        default:
}

5.2.4 init_UE()函数

这个函数在lte-uesoftmodem.c 文件 main()函数的780行,目测是主函数中最重要的函数,其中创建了四种线程,分别为:UE_thread_rxn_txnp4、UE_thread_slot1_dl_processing、UE_thread_synch和UE_thread,UE_thread_rxn_txnp4、UE_thread_slot1_dl_processing线程重复创建了两次,所以一共有六个线程。

5.2.4.1 l2_init_ue()

在init_UE()的259行,里面只有两个函数:rlcmac_init_global_param_ue();和mac_top_init_ue();

  • rlcmac_init_global_param_ue():

    该函数里也只有两个函数:rlc_module_init()和pdcp_layer_init();

    • rlc_module_init():看不出来做了什么 ,看起来是初始化了RLC层的什么东西,但是也没有写什么接口之类的
    RAZ the memory of the RLC layer, initialize the memory pool manager (mem_block_t structures mainly used in RLC module).
    
    • pdcp_layer_init():初始化了PDCP层的SDU列表,其中对于pdcp层来说,sdu是上层(也就是应用层)传入的数据。这样看来,pdcp层与上层的接口好像有两种?一种是通过sdu形式从上层传下来,一种是socket的形式传下来
  • mac_top_init_ue():

    该函数中有函数ue_init_mac() 和 openair_rrc_top_init_ue(),同时初始化了很多互斥锁(但是在本项目中没有进入这个if中)

      // mutex below are used for multiple UE's L2 FAPI simulation.
      if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
           
        pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL);
        pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL);
        pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL);
        pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL);
        pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL);
        pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL);
      }
    
    • ue_init_mac(): 初始化mac层主要配置信息,包括一些调度信息,逻辑信道的配置(default values as deined in 36.331 sec 9.2.2),156行初始化了一把UL_INFO_mutex互斥锁。

    • openair_rrc_top_init_ue(): 初始化UE capability?

          // fill UE capability
          UECap = fill_ue_capability (uecap_xer);
      
5.2.4.2 init_ue_vars()

在init_UE()的259行,里面有两个函数:init_lte_ue_signal() 和 init_lte_ue_transport() 函数

  • init_lte_ue_signal() :做了信号的初始化?其中有包括一些信道(有逻辑信道DLSCH,物理信道PDSCH和PBCH),以及下面的一部分:

      init_dfts();
      init_frame_parms(&ue->frame_parms,1);
      lte_sync_time_init(&ue->frame_parms);
      init_lte_top(&ue->frame_parms);
      init_7_5KHz();
      init_ul_hopping(&ue->frame_parms);
    
    
      // init TX buffers
    	……
      // init RX buffers
        ……
      // Channel estimates
        ……
    
    
  • init_lte_ue_transport() :看不太懂

5.2.4.3 init_UE_threads()

在init_UE()的361行,在该函数中创建的三种线程的优先级为(FIFO_PRIORITY-1):

先创建一个UE_thread_rxn_txnp4线程和UE_thread_slot1_dl_processing线程,再重复创建一次UE_thread_rxn_txnp4线程和UE_thread_slot1_dl_processing线程,最后创建一个UE_thread_synch线程。

在线程UE_thread_rxn_txnp4中,不是直接开始执行程序的,是被阻塞在一个while循环中。

    while (proc->instance_cnt_rxtx < 0) {
     
      // most of the time, the thread is waiting here
      pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
    }

不过,在该线程结束部分,有用于唤醒另一个被proc->cond_rxtx条件变量阻塞的线程:

    if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) {
     
      if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort();
    }

这应该是用来唤醒线程UE_thread中的(刚好也是有两处,对应两个UE_thread_rxn_txnp4线程):

          for (t = 0; t < 2; t++) {
     
            UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t];
            pthread_mutex_lock(&proc->mutex_rxtx);

            while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );

            pthread_mutex_unlock(&proc->mutex_rxtx);
          }
5.2.4.4 UE_thread线程

在init_UE()的375行,而该函数中创建的线程的优先级为(FIFO_PRIORITY)

按照注释的说法:

 * This is the main UE thread.
 * This thread controls the other three UE threads:
 * - UE_thread_rxn_txnp4 (even subframes)
 * - UE_thread_rxn_txnp4 (odd subframes)
 * - UE_thread_synch

分析完init_UE()函数内各个线程的执行顺序之后,可以发现UE_thread线程确实是控制了这三个线程的运行。

5.2.4.5 线程执行顺序分析

这部分线程执行流程:由于init_UE_threads()函数中一共创建了两个线程UE_thread_rxn_txnp4:第一个UE_thread_rxn_txnp4线程创建之后,由条件变量proc->cond_rxtx阻塞,主线程继续执行创建了第一个UE_thread_slot1_dl_processing线程,被条件变量proc->cond_slot1_dl_processing阻塞:

    while (proc->instance_cnt_slot1_dl_processing < 0) {
     
      // most of the time, the thread is waiting here
      pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
    }

主线程继续运行,同样的创建了第二个UE_thread_rxn_txnp4线程和第二个UE_thread_slot1_dl_processing线程,也被阻塞。

此时主线程继续运行,创建了新的线程UE_thread_synch,且该线程有两处地方被阻塞,第一处是通过wait_sync()函数,并在等待条件变量sync_cond的唤醒;另一处是通过条件变量UE->proc.cond_synch阻塞:

while (UE->proc.instance_cnt_synch < 0)
  // the thread waits here most of the time
  pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );

随后,主线程创建了线程UE_thread,该线程也被wait_sync()阻塞,等待条件变量sync_cond的唤醒。

至此,init_UE()函数中的六个线程已经全部创建完毕,主线程执行到823行的pthread_cond_broadcast(&sync_cond),唤醒被sync_cond变量阻塞的两个线程:UE_thread_synch和UE_thread。

其中UE_thread_synch被第二处阻塞,而线程UE_thread顺利执行。

线程UE_thread通过pthread_cond_signal(&UE->proc.cond_synch)函数唤醒线程UE_thread_synch的第二处阻塞,开启了同步线程UE_thread_synch的运行。

在UE_thread线程的结尾,通过pthread_cond_signal(&proc->cond_rxtx)函数唤醒先被阻塞的一个UE_thread_rxn_txnp4线程(不一定是第一个)。

在UE_thread_rxn_txnp4线程运行过程中,在phy_procedures_slot_parallelization_UE_RX()函数中的pthread_cond_signal(&proc->cond_slot1_dl_processing)唤醒了一个UE_thread_slot1_dl_processing线程。

然后在线程UE_thread的循环中,继续唤醒另一个UE_thread_rxn_txnp4线程,再唤醒另一个UE_thread_slot1_dl_processing线程。

5.2 结果分析

  1. lte-uesoftmodem :823 & 824

    pthread_cond_broadcast(&sync_cond);

    pthread_mutex_unlock(&sync_mutex);

    823行唤醒了所有被堵塞的线程,主要是用于同步的线程UE thread和UE_thread_sync;

    可以在整个UE项目中找调用了sync_cond的函数,发现该条件变量在仅一个函数中被调用:

    OAI项目GDB调试及代码分析_第9张图片

    函数wait_sync()的目的是,使线程进入堵塞状态,等待被唤醒。

    而调用该函数的有:

    OAI项目GDB调试及代码分析_第10张图片

    image-20200807103358946

    从运行结果来看,此处唤醒的线程为线程UE thread和UE_thread_sync

    执行完之后,UE连接到eNB

got sync (UE thread)
got sync (UE_thread_sync)
Started device, unlocked sync_mutex (UE_sync_thread)
[NAS] [UE 0] Received INITIALIZE_MESSAGE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USER/user_api.c:282 USR-API - 10 bytes write
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USER/user_api.c:380 USR-API - Decode user data: at+cfun=1
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USER/at_command.c:855 USR-API - Parsing of AT+CFUN= command succeed (fun:1)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USER/user_api.c:390 USR-API - 1 AT command has been successfully decoded
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/nas_user.c:311 USR-MAIN - Process set parameter AT command 6
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:295 EMM-FSM - Received event S1_ENABLED (1) in state NULL
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:458 EMM-PROC - Delete authentication data RAND and RES
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:237 EMM-FSM - Status changed: NULL ===> DEREGISTERED
[HW] rfsimulator: trying to connect to 10.200.1.1:4043
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/IdleMode.c:552 EMM-IDLE - 6 PLMNs available for network selection
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:295 EMM-FSM - Received event REGISTER_REQ (5) in state DEREGISTERED
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:458 EMM-PROC - Delete authentication data RAND and RES
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:237 EMM-FSM - Status changed: DEREGISTERED ===> DEREGISTERED.PLMN-SEARCH
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:295 EMM-FSM - Received event REGISTER_REQ (5) in state DEREGISTERED.PLMN-SEARCH
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/IdleMode.c:1154 EMM-IDLE - Trying to search a suitable cell of PLMN 0 in Automatic mode
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_CELL_INFO_REQ (214)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:1475 EMMAS-SAP - Send AS cell information request

同时,在eNB端:

[HW] A ue connected

  1. lte-uesoftmodem :836 itti_wait_tasks_end();

该函数是一个while无限循环睡眠,同时,由于其他线程已经被pthread_cond_broadcast()函数唤醒,其他线程开始执行接下来的功能

836 itti_wait_tasks_end();
gef➤ n
[HW] gap of: 114293760 in reception
[HW] Tx/Rx shift too large Tx:0, Rx:114293760
[PHY] [UE thread Synch] Running Initial Synch (mode 0)
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] [UE] lte_sync_time: Sync source = 0, Peak found at pos 6656, val = 1215157 (30 dB)
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 1, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 1, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Not yet implemented: noise power calculation when prefix length == EXTENDED
[PHY] Not yet implemented: noise power calculation when prefix length == EXTENDED
[PHY] FeMBMS CAS Extended prefix: CellId 375 metric 15, phase 0, flip 0, pbch -1
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 1, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 1, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Not yet implemented: noise power calculation when prefix length == EXTENDED
[PHY] [UE0] Initial sync : Estimated power: 0 dB
[PHY] [initial_sync] trying carrier off 0 Hz, rxgain 135 (DL 2685000000, UL 2565000000)
[PHY] [UE thread Synch] Running Initial Synch (mode 0)
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] [UE] lte_sync_time: Sync source = 0, Peak found at pos 6656, val = 2430314 (32 dB)
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] [UE0] In synch, rx_offset 0 samples
pcfich_reg : 0,25,50,75
[PHY] [UE 0] Frame 756 RRC Measurements => rssi -83.2 dBm (dig 51.8 dB, gain 135), N0 -165 dBm, rsrp -110.9 dBm/RE, rsrq 9.0 dB
[PHY] [UE 0] Frame 756 MIB Information => FDD, NORMAL, NidCell 0, N_RB_DL 50, PHICH DURATION 0, PHICH RESOURCE 1/6, TX_ANT 1
[PHY] [UE 0] Frame 756 Measured Carrier Frequency 2685000029 Hz (offset -29 Hz)
[HW] Got synch: hw_slot_offset 0, carrier off 0 Hz, rxgain 135 (DL 2685000000, UL 2565000000), UE_scan_carrier 0
[PHY] Initializing frame parms for N_RB_DL 50, Ncp 0, osf 1
[PHY] lte_parms.c: Setting N_RB_DL to 50, ofdm_symbol_size 1024
[PHY] Resynchronizing RX by 0 samples (mode = 0)
[UE 0] frame 101, subframe 0: Adjusting frame counter (PBCH ant_tx=1, frame_tx=101, phase 1, rx_offset 0) => new frame 101
[UE 0] frame 101, subframe 0: Adjusting frame counter (PBCH ant_tx=1, frame_tx=101, phase 1, rx_offset 0) => new frame 101
[RRC] [UE 0] : Dumping SIB 1
[RRC] PLMN MCC 208, MNC 92, TAC 0x0001
[RRC] cellReservedForOperatorUse : raw:1 decoded:notReserved
[RRC] Found Unknown operator (no entry in internal table)
[RRC] cellAccessRelatedInfo.cellIdentity : raw:3584 decoded:00.00.e0.00
[RRC] cellAccessRelatedInfo.cellBarred : raw:1 decoded:notBarred
[RRC] cellAccessRelatedInfo.intraFreqReselection : raw:1 decoded:notAllowed
[RRC] cellAccessRelatedInfo.csg_Indication : 0
[RRC] cellAccessRelatedInfo.csg_Identity : not defined
[RRC] cellSelectionInfo.q_RxLevMin : -65
[RRC] cellSelectionInfo.q_RxLevMinOffset : not defined
[RRC] p_Max : not defined
[RRC] freqBandIndicator : 7
[RRC] si_Periodicity[0] : rf8
[RRC] siSchedulingInfoSIBType[0] : SIB3
[RRC] siWindowLength : 20ms
[RRC] systemInfoValueTag : 0
[RRC] [FRAME unknown][RRC_UE][MOD 00][][— MAC_CONFIG_REQ (SIB1 params eNB 0) —>][MAC_UE][MOD 00][]

[MAC] [CONFIG][UE 0] Configuring MAC/PHY from eNB 0
[RRC] Setting SIStatus bit 0 to 1
[NAS] [UE] Received 1 events
[NAS] [UE 0] Received NAS_CELL_SELECTION_CNF: errCode 1, cellID 3584, tac 1
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_CELL_INFO_RES (215)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:671 EMMAS-SAP - Received AS cell information response
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/IdleMode.c:694 EMM-IDLE - One cell found for PLMN 0 in Automatic mode
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/IdleMode.c:778 EMM-IDLE - UE may camp on this suitable cell for normal services
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:295 EMM-FSM - Received event REGISTER_CNF (6) in state DEREGISTERED.PLMN-SEARCH
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:237 EMM-FSM - Status changed: DEREGISTERED.PLMN-SEARCH ===> DEREGISTERED.NORMAL-SERVICE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_fsm.c:295 EMM-FSM - Received event ATTACH_INIT (8) in state DEREGISTERED.NORMAL-SERVICE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Attach.c:145 EMM-PROC - Initiate EPS attach type = EPS (0)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Attach.c:181 EMM-PROC - Initiate EPS attach with IMSI
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:465 EMM_AS_NO_KEY_AVAILABLE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Attach.c:222 EMM-PROC - eps_encryption 0x0
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Attach.c:223 EMM-PROC - eps_integrity 0x2
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/SAP/esm_sap.c:158 ESM-SAP - Received primitive ESM_PDN_CONNECTIVITY_REQ (12)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/PdnConnectivity.c:184 ESM-PROC - Define new IPv4 PDN connection to APN (null) (cid=1)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/PdnConnectivity.c:697 ESM-PROC - Create new PDN connection (pid=0)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/PdnConnectivity.c:161 ESM-PROC - Assign new procedure transaction identity (cid=1)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/esm_pt.c:151 ESM-FSM - Procedure transaction identity 1 assigned
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/SAP/esm_send.c:208 ESM-SAP - Send PDN Connectivity Request message (pti=1, ebi=0)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/ESM/MSG/esm_msg.c:269 ESM-MSG - Encoded ESM message header (3)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/PdnConnectivity.c:290 ESM-PROC - Initiate PDN connectivity (pti=1)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/ESM/esm_pt.c:386 ESM-FSM - Status of procedure transaction 1 changed: PROCEDURE TRANSACTION INACTIVE ===> PROCEDURE TRANSACTION PENDING
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Attach.c:257 EMM-PROC - Timer T3410 (-1) expires in 15 seconds
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_ESTABLISH_REQ (205)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:1382 EMMAS-SAP - Send AS connection establish request
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_send.c:166 EMMAS-SAP - Send Attach Request message
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_send.c:216 EMMAS-SAP - Send Attach Request message with IMSI
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/IES/UeNetworkCapability.c:115 uenetworkcapability encoded EPS 3

[RRC] [UE 0] Decoding SI for frameP 105
[RRC] [UE 0] Frame 105 Found SIB2 from eNB 0
[RRC] ac_BarringInfo : not defined
[RRC] radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : raw:15 decoded:n64
[RRC] radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig : not defined
[RRC] radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : raw:2 decoded:dB4
[RRC] radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower : raw:6 decoded:dBm-108
[RRC] radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax : raw:6 decoded:n10
[RRC] radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize : raw:7 decoded:sf10
[RRC] radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer : raw:5 decoded:sf48
[RRC] radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx : 4
[RRC] radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff : raw:0 decoded:n2
[RRC] radioResourceConfigCommon.pcch_Config.defaultPagingCycle : raw:2 decoded:rf64
[RRC] radioResourceConfigCommon.pcch_Config.nB : raw:2 decoded:oneT
[RRC] radioResourceConfigCommon.prach_Config.rootSequenceIndex : 0
[RRC] radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex : 0
[RRC] radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag : 0
[RRC] radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig : 1
[RRC] radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset : 2
[RRC] radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower : -27
[RRC] radioResourceConfigCommon.pdsch_ConfigCommon.p_b : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB : 1
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled : 1
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled : 0
[RRC] radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift : 1
[RRC] radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift : 0
[RRC] radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI : 0
[RRC] radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN : 0
[RRC] radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN : 0
[RRC] radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present : raw:1 decoded:release
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH : -96
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.alpha : 7
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH : -104
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1 : 2
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b : 1
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2 : 1
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a : 1
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b : 1
[RRC] radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 : 6
[RRC] radioResourceConfigCommon.ul_CyclicPrefixLength : 0
[RRC] ue_TimersAndConstants.t300 : 5
[RRC] ue_TimersAndConstants.t301 : 5
[RRC] ue_TimersAndConstants.t310 : 5
[RRC] ue_TimersAndConstants.n310 : 7
[RRC] ue_TimersAndConstants.t311 : 3
[RRC] ue_TimersAndConstants.n311 : 0
[RRC] freqInfo.ul_CarrierFreq : not defined
[RRC] freqInfo.ul_Bandwidth : not defined
[RRC] freqInfo.additionalSpectrumEmission : 1
[RRC] mbsfn_SubframeConfigList : not defined
[RRC] timeAlignmentTimerCommon : 7
[RRC] lateNonCriticalExtension : not defined
[RRC] ssac_BarringForMMTEL_Voice_r9 : not defined
[RRC] ssac_BarringForMMTEL_Video_r9 : not defined
[RRC] ac_BarringForCSFB_r10 : not defined
[RRC] [FRAME 00105][RRC_UE][MOD 00][][— MAC_CONFIG_REQ (SIB2 params eNB 0) —>][MAC_UE][MOD 00][]
[MAC] [CONFIG][UE 0] Configuring MAC/PHY from eNB 0
[PHY] [UE0] Applying radioResourceConfigCommon from eNB0
[RRC] [UE 0] : Frame 105, Logical Channel UL-CCCH (SRB0), Generating RRCConnectionRequest (bytes 6, eNB 0)
[RRC] [UE 0] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED
[RRC] [UE 0] Frame 105 Found SIB3 from eNB 0
[RRC] Dumping SIB3 (see TS36.331 V8.21.0)
[RRC] cellReselectionInfoCommon.q_Hyst : raw:4 decoded:4 dB
[RRC] cellReselectionInfoCommon.speedStateReselectionPars : not defined
[RRC] cellReselectionServingFreqInfo.s_NonIntraSearch : not defined
[RRC] cellReselectionServingFreqInfo.threshServingLow : 31
[RRC] cellReselectionServingFreqInfo.cellReselectionPriority : 7
[RRC] intraFreqCellReselectionInfo.q_RxLevMin : -70
[RRC] intraFreqCellReselectionInfo.p_Max : not defined
[RRC] intraFreqCellReselectionInfo.s_IntraSearch : 31
[RRC] intraFreqCellReselectionInfo.allowedMeasBandwidth : 0
[RRC] intraFreqCellReselectionInfo.presenceAntennaPort1 : 0
[RRC] intraFreqCellReselectionInfo.neighCellConfig : 1
[RRC] intraFreqCellReselectionInfo.t_ReselectionEUTRA : 1
[RRC] intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF : not defined
[RRC] SIStatus 7, SIcnt 1/1
[PHY] [UE0] Sending synch status to higher layers
[MAC] RA not active
[RRC] [MSC_MSG][FRAME 00118][RRC_UE][MOD 00][][— MAC_DATA_REQ (RRCConnectionRequest eNB 0) —>][MAC_UE][MOD 00][]
[MAC] [UE 0] Frame 118: Requested RRCConnectionRequest, got 6 bytes
[PHY] mode 0
[PHY] [UE 0] prach_start 15360, rx_offset 0, hw_timing_advance 0, N_TA_offset 0
[PHY] [UE 0][RAPROC] PRACH PL 84 dB, power -24 dBm (max 23 dBm), digital power 0 dB (amp 6)
[PHY] [UE 0][RAPROC] Frame 118, subframe 1: Generating PRACH (eNB 0) preamble index 7 for UL, TX power -24 dBm (PL 84 dB), l3msg
[MAC] Received RRC_MAC_CCCH_DATA_REQ from TASK_RRC_UE: instance 0, frameP 118, eNB_index 0
[MAC] [UE 0][RAPROC] Frame 118 Received RAR (47|00.00.05.4c.90.91) for preamble 7/7
[PHY] [UE 0][PUSCH PC] Initializing f_pusch to 2 dB, TPC 3 (delta_PUSCH_msg2 0 dB), deltaP_rampup 2 dB
[PHY] [UE 0][RAPROC] Frame 119, Subframe 2 Generating (RRCConnectionRequest) Msg3 (nb_rb 1, first_rb 2, round 0, rvidx 0) Msg3: 20.6.1f|51.df.c8.65.59.c6
[PHY] Done Msg3 encoding
[PHY] [UE 0][RAPROC] frame 119, subframe 2: Msg3 Po_PUSCH -22 dBm (-10800,0,100*PL=8400,0,200)
[MAC] Frame 119: Contention resolution timer 0/48
[MAC] Frame 119: Contention resolution timer 1/48
[MAC] Frame 119: Contention resolution timer 2/48
[MAC] Frame 119: Contention resolution timer 3/48
[MAC] Frame 119: Contention resolution timer 4/48
[MAC] Frame 119: Contention resolution timer 5/48
[MAC] Frame 119: Contention resolution timer 6/48
[MAC] [UE 0][RAPROC] Frame 119 : received contention resolution msg: 51.df.c8.65.59.c6, Terminating RA procedure
[MAC] [UE 0][RAPROC] Frame 119 : Clearing RA_active flag
[MAC] [UE 0][RAPROC] Frame 119 : Clearing contention resolution timer
[PHY] [UE 0][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI
[RRC] [UE0][RAPROC] Frame 119 : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI 9091
[RRC] Save physicalConfigDedicated if present
[RRC] Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated
[PDCP] [FRAME 00119][ UE][MOD 00][RNTI 9091][SRB 01] Action ADD LCID 1 (SRB id 1) configured with SN size 5 bits and RLC AM
[RLC] [FRAME 00119][ UE][MOD 00][RNTI 9091] [SRB 1] rrc_rlc_add_rlc SRB
[RLC] [FRAME 00119][ UE][MOD 00][RNTI 9091][SRB AM 01][CONFIGURE] max_retx_threshold 4 poll_pdu 4 poll_byte 65535 t_poll_retransmit 80 t_reordering 35 t_status_prohibit 0
[RRC] [UE 0], CONFIG_SRB1 1 corresponding to eNB_index 0
[RRC] [FRAME 00119][RRC_UE][MOD 00][][— MAC_CONFIG_REQ (SRB1 eNB 0) —>][MAC_UE][MOD 00][]
[MAC] [CONFIG][UE 0] Configuring MAC/PHY from eNB 0
[MAC] [CONFIG][UE 0] Applying RRC logicalChannelConfig from eNB0
[MAC] [CONFIG][UE0] Applying RRC macMainConfig from eNB0
[PHY] Transmission Mode 1
[PHY] C-RNTI 9091 9091
[RRC] [UE 0] State = RRC_CONNECTED (eNB 0)
[RRC] [UE 0][RAPROC] Frame 119 : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes53, eNB 0)
[RLC] [FRAME 00119][ UE][MOD 00][RNTI 9091][SRB AM 01] RLC_AM_DATA_REQ size 58 Bytes, NB SDU 1 current_sdu_index=0 next_sdu_index=1 conf 0 mui 0 vtA 0 vtS 0
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 58 bytes for LcId1
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 4 bytes for LcId1
[RRC] [UE 0] Frame 123: received a DCCH 1 message on SRB 1 with Size 39 from eNB 0
[NAS] [UE] Received 1 events
[NAS] [UE 0] Received NAS_DOWNLINK_DATA_IND: UEid 0, length 36
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_DATA_IND (211)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:415 EMMAS-SAP - Received AS data transfer indication (ueid=0, delivered=TRUE, length=36)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:315 EMMAS-SAP - Received EMM message (length=36)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/EMM/MSG/emm_msg.c:108 EMM-MSG - Message Type 0x52
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_recv.c:387 EMMAS-SAP - Received Authentication Request message
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:153 EMM-PROC - Authentication requested ksi type = native, ksi = 0
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:356 USIM-API - res(f2) :0x73 0x87 0x28 0x1a 0xb5 0x39 0xb3 0xdb
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:357 USIM-API - ck(f3) :0xc4 0xb1 0x1 0xb6 0x7b 0xb 0x30 0x88 0xae 0xab 0x4d 0x7d 0xf 0x6c 0xc 0xc3
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:358 USIM-API - ik(f4) :0x7c 0x15 0xb 0x28 0xc5 0xc2 0x8f 0xf9 0x1 0x9a 0x73 0x17 0x8b 0xbb 0xf3 0xb6
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:360 USIM-API - ak(f5) : EE6393A77461
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:371 USIM-API - Retrieved SQN 00000000055F
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/API/USIM/usim_api.c:393 USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:269 EMM-PROC - Timer T3416 (-1) expires in 30 seconds
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:465 EMM_AS_NO_KEY_AVAILABLE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_SECURITY_RES (203)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:1288 EMMAS-SAP - Send AS security response
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_send.c:772 EMMAS-SAP - Send Authentication Response message
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:923 EMM-PROC _authentication_kasme INPUT CK 0xc4 0xb1 0x1 0xb6 0x7b 0xb 0x30 0x88 0xae 0xab 0x4d 0x7d 0xf 0x6c 0xc 0xc3
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:925 EMM-PROC _authentication_kasme INPUT IK 0x7c 0x15 0xb 0x28 0xc5 0xc2 0x8f 0xf9 0x1 0x9a 0x73 0x17 0x8b 0xbb 0xf3 0xb6
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:927 EMM-PROC _authentication_kasme INPUT AUTN 0xee 0x63 0x93 0xa7 0x71 0x3e 0x80 0x0 0xf0 0xf2 0x45 0x48 0x8c 0x7c 0xf4 0xa
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:929 EMM-PROC _authentication_kasme INPUT KASME LENGTH 32
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:959 EMM-PROC _authentication_kasme P0 MCC,MNC 02 F8 29
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:981 EMM-PROC _authentication_kasme input S to KFD (length 14)10 02 F8 29 00 03 EE 63 93 A7 71 3E 00 06
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:993 EMM-PROC KASME (l=32)0x88 0x85 0x24 0x78 0x9c 0xba 0xab 0xdb 0xd 0x13 0x6c 0xb3 0xd7 0x52 0x6a 0x40 0xf1 0xd3 0x65 0x16 0x81 0x13 0xf7 0xa6 0xac 0x4 0x12 0x12 0x79 0xc4 0x18 0x74
[RLC] [FRAME 00000][ UE][MOD 00][RNTI 9091][SRB AM 01] RLC_AM_DATA_REQ size 19 Bytes, NB SDU 2 current_sdu_index=1 next_sdu_index=2 conf 0 mui 1 vtA 2 vtS 2
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 2 bytes for LcId1
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 21 bytes for LcId1
[RRC] [UE 0] Frame 125: received a DCCH 1 message on SRB 1 with Size 16 from eNB 0
[NAS] [UE] Received 1 events
[NAS] [UE 0] Received NAS_DOWNLINK_DATA_IND: UEid 0, length 13
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_DATA_IND (211)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:415 EMMAS-SAP - Received AS data transfer indication (ueid=0, delivered=TRUE, length=13)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/API/NETWORK/nas_message.c:329 MAC failure but continue due to EIA0 selected
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:315 EMMAS-SAP - Received EMM message (length=7)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/EMM/MSG/emm_msg.c:108 EMM-MSG - Message Type 0x5d
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_recv.c:469 EMMAS-SAP - Received Security Mode Command message
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_recv.c:475 Execute the security mode control procedure initiated by the network: imeisvrequest 0

[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:153 EMM-PROC - Security mode control requested (ksi=0)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/Authentication.c:458 EMM-PROC - Delete authentication data RAND and RES
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:187 EMM-PROC - Update the non-current EPS security context seea=0 seia=2
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:203 EMM-PROC - Update the non-current EPS security context knas_enc
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:418 _security_knas_enc with algo dist 1 algo id 0
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:217 EMM-PROC - Update the non-current EPS security context knas_int
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:444 _security_knas_int with algo dist 2 algo id 2
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:231 EMM-PROC - Update the non-current EPS security context kenb
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:476 _security_kenb with count= 0[NAS]/home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:243 EMM-PROC - NAS security mode command accepted by the UE
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SecurityModeControl.c:259 EMM-PROC - Update Current security context
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:434 EPS security context exists is new 1 KSI 0 SQN 0 count 0
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:436 knas_int 0xc8 0x98 0xfc 0x54 0x21 0xf 0xd2 0x57 0xc5 0xf9 0x2a 0xa7 0x30 0xe8 0xeb 0xa
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:438 knas_enc 0x38 0x5a 0x21 0x57 0x2e 0x42 0xb5 0x15 0x57 0xb1 0x66 0x65 0x2b 0xd0 0x5d 0x3e
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:440 kasme 0x88 0x85 0x24 0x78 0x9c 0xba 0xab 0xdb 0xd 0x13 0x6c 0xb3 0xd7 0x52 0x6a 0x40 0xf1 0xd3 0x65 0x16 0x81 0x13 0xf7 0xa6 0xac 0x4 0x12 0x12 0x79 0xc4 0x18 0x74
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/LowerLayer.c:461 EPS security context exists knas_encfont size=“1”>[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:201 EMMAS-SAP - Received primitive EMMAS_SECURITY_RES (203)
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_as.c:1288 EMMAS-SAP - Send AS security response
[NAS] /home/hyl/openairinterface5g/openair3/NAS/UE/EMM/SAP/emm_send.c:853 EMMAS-SAP - Send Security Mode Complete message
[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c:79 SECURITY MODE COMMAND COMPLETE: presencemask: 0

[NAS] /home/hyl/openairinterface5g/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c:93 SECURITY MODE COMMAND COMPLETE done !!!

Byte length: 11, Zero bits: 0
m: 000000000000000000075e
Key:c898fc54210fd257c5f92aa730e8eb0a
Message:00075e
out: cbbffc919c34614ada0f9ea16b60f33c
[RLC] [FRAME 00000][ UE][MOD 00][RNTI 9091][SRB AM 01] RLC_AM_DATA_REQ size 16 Bytes, NB SDU 3 current_sdu_index=2 next_sdu_index=3 conf 0 mui 2 vtA 3 vtS 3
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 2 bytes for LcId1
[MAC] [UE 0] TX Multiplex RLC PDU TX Got 18 bytes for LcId1
[PHY] Delay to wake up UE_Thread_Rx (case 2) avg=36 iterations=10000 max=357:367:375:390:397:424:435:436:1418:4772
[PHY] Delay to process sub-frame (case 3) avg=137 iterations=10000 max=747:774:779:790:1023:1032:1137:1316:1860:2405
[PHY] Delay to wake up UE_Thread_Rx (case 2) avg=32 iterations=10000max=328:336:341:351:358:359:395:540:599:667
[PHY] Delay to process sub-frame (case 3) avg=173 iterations=10000max=1318:1333:1465:1488:1564:1928:2285:2289:5985:7987
[PHY] Delay between two IQ acquisitions (case 1) avg=365 iterations=20000 max=2763:4415:4599:4961:5139:5589:6231:7393:8227:8633
[PHY] Delay to wake up UE_Thread_Rx (case 2) avg=33 iterations=20000 max=367:375:390:397:424:435:436:529:1418:4772

5.3 额外补充

  1. 以下两处注释中解释了在项目中出现多次的简称req和ind的含义:

Req:是对于该层来说的,用于请求上层,使用信息传输服务的过程传输上层PDU给该层;

Ind:是对于当前层来说,指示在一个传输时间间隔内通过信息传输服务接收到的上层PDU的到达。

/*! \brief MAC-DATA-Req primitive is used to request that an upper layer PDU be sent using the procedures for the information transfer service;*/
/*! \brief  MAC-DATA-Ind primitive indicates the arrival of upper layer PDUs received within one transmission time interval by means of the information transfer service.*/
  1. 用于区分接口的实现方式?ITTI or OTG

由于OTG是一组用于不同设备之间的接口,所以ITTI应该也是有类似功能;

根据之前项目中出现的ITTI_TASK来推测,也确实合情合理。

ITTI可能是类似一组队列的形式,在底层(PHY\MAC\RLC\PDCP)接收并处理完数据后,以ITTI_TASK的方式来向上层发送,上层根据接收到的ITTI_TASK的类别来进行相应的处理,ITTI的详细内容可以参考 5.2.2 & 5.2.3

但是这样理解就会出现一个问题,OTG是用于不同设备的接口,应该是UE和eNB之间用的;但是ITTI就不像是用于UE和eNB之间的,而是UE中底层和高层之间的一个接口???

  instance_t  instance;      /*!< \brief  ITTI or OTG module identifier      */
5.3.1 多线程调试
5.3.1.1 线程2的调试

main函数中的rrc_control_socket_init(); 该函数中创建了第二个线程:

if (pthread_create(&rrc_control_socket_thread, &attr, rrc_control_socket_thread_fct, NULL) != 0) 

在该行之前是一个线程,该行之后就变成两个线程了,但新创建的线程名字和主函数线程名一样。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zigs1aQW-1598970126962)(https://typora-hyl.oss-cn-beijing.aliyuncs.com/img/(J@4F(E)]UE42KM6OT`[email protected])

切换到线程2,此时若直接调试(不管是next还是step),程序都会一直往下跑(因为主线程一直在运行)。所以首先需要开启锁定线程的模式(注意要先切换到线程2):

set scheduler-locking on

但是不知道为什么切换到线程2后,进行step或者next,程序都会卡死(可能也正因为这样,所以之前没锁定线程的时候执行的step或者next,线程2卡死,主线程可以顺势一直运行到底):

img

5.5.1.2 线程3的调试

线程3名字为TASK_NAS_UE,运行的函数为nas_ue_task,在函数itti_create_task (TASK_NAS_UE, nas_ue_task, users)中创建完线程3之后,就切换到线程3,并开启了锁定其他线程的模式。

调试结果:

  1. 一切换到线程3,它就已经运行到127行函数:nas_user_api_id_initialize(user)中的某些函数:

    image-20200828114725752猜测:由于线程一旦创建,就开始运行,所以可能这上面的一些函数已经执行完毕了。

  2. 接下来执行该线程运行的函数:nas_ue_task,但是到执行到142行之后就开始乱跳了。。直接先跳到while循环中的后面一个地方,又跳回来,最后才由于没有接收到消息而卡死在itti_receive_msg (TASK_NAS_UE, &msg_p)OAI项目GDB调试及代码分析_第11张图片

  3. 尝试在主线程运行过程中就开启线程锁定模式,试图使线程3在创建后不能直接运行,但实际操作发现切换到线程3后仍然不会从想要的第一行开始执行,直接就跳到了133行:nas_user_initialize函数中的某些函数

5.5.1.3 线程4的调试

线程4名字为TASK_RRC_UE,和线程3很相似,在创建线程之后,都会等待在itti_receive_msg函数中一直等待消息的到来

注:除线程3、4有自己的名字之外,其他线程的名字都和主线程名字一样的,叫lte-uesoftmodem。看代码的时候发现作者应该是给每个(或大部分)线程都起了单独的名字,只不过不知道为什么调试时候名字全都是lte-uesoftmodem。

另外,这些名为lte-uesoftmodem的线程确实是后来创建的和主函数不一样的线程,在每一处pthread_create创建的前后我都有观察线程信息,且切换到这些线程,确实可以发现他们在执行各自的函数。

5.5.1.4 线程5、6的调试

线程5和线程6运行的函数都为:UE_thread_rxn_txnp4。

在该函数中单步调试的结果(顺序)为:

首先是卡在while (!oai_exit)循环中的pthread_cond_wait,被我通过 set scheduler-locking off 关闭了其他线程的锁定,从而通过其他线程唤醒了该线程(各线程逻辑可以参考5.2.4.5 线程执行顺序分析章节)。

接下来,执行顺序为:

791 -> 792 -> 793 -> 794 -> 796 -> 798 -> 801 -> 809 -> 821 -> 829

#ifdef UE_SLOT_PARALLELISATION
      phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
      phy_procedures_UE_RX(UE, proc, 0, 0, 1, UE->mode);
#endif

可以看到没有进入上述代码中的第一个判断中,这也和之前未创建UE_thread_slot1_dl_processing线程是前后呼应的,该处进入的phy_procedures_UE_RX()中,该函数非常复杂,负责物理层的接收?还没仔细看。

829 -> 830 -> 839 -> 851 -> 853 -> 854 -> 856 -> 861 -> 862 -> 864 -> 865 -> 868

接下来又继续一直在while (!oai_exit)中循环:

868 -> 779 -> 780 -> 785 -> 793 -> 794 -> 796 -> 798 -> 801 -> 809 -> 821 -> 829…

5.5.1.5 线程7的调试

切换到线程7后,首先也是处于被条件变量阻塞的状态,关闭了锁定其他线程的模式后,成功将该线程运行的函数唤醒。

执行顺序为:

530 -> 531 -> 533 -> 535

由于535行被另一个条件变量阻塞:

pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );

且此时未开启锁定其他线程的模式,所以主函数就跑到底了。。

重新开始,执行到535行之前,先关闭其他线程,只允许当前线程的运行,然后再进入535处的阻塞。

被阻塞后,开启其他线程(等待其他线程的唤醒),等跳出这里的阻塞后,关闭其他线程的运行。

执行顺序:

537 -> 570 -> 572 -> 573 -> 582 -> 583 -> 585 -> 599 -> 615 -> 616 -> 617 -> 619 -> 629 -> 632 -> 633 -> 640 -> 643 -> 644 -> 645 -> 647 -> 723 -> 725 -> 726 -> 727 -> 537

5.3.2 UE_thread_rxn_txnp4线程分析

该线程中有一个比较重要的接收的函数:phy_procedures_UE_RX()

该函数中首先判断了是否扫描到pdcch信号:

  if (do_pdcch_flag) {
     
    // deactivate reception until we scan pdcch

然后做了一部分和帧、符号等物理层相关的事情。

其中有一个函数应该比较关键,做的是物理层的事情,也包括信道估计,好像还有物理层的接收。

  slot_fep(ue,
           0,
           1+(subframe_rx<<1),
           0,
           0,
           0);

然后有一个测量的程序:ue_measurement_procedures()

接下来在第一个时隙中,根据注释以及程序推测,应该做了判断,判断当前接收到的PDCCH有哪类RNTI标识

// first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)  
...
  // do procedures for C-RNTI
  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
     
    ue_pdsch_procedures(ue,
                        proc,
                        eNB_id,
                        PDSCH,
                        ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
                        NULL,
                        ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
                        ue->frame_parms.symbols_per_tti>>1,
                        abstraction_flag);
  }
  // do procedures for SI-RNTI
...
  // do procedures for P-RNTI
...
  // do procedures for RA-RNTI
...

接下来是第二个时隙的处理

// do front-end processing for second slot, and first symbol of next subframe

ue_measurement_procedures()
    
// do first symbol of next downlink subframe for channel estimation
    
  if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) {
     
    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
  }
    
  // do procedures for C-RNTI
    ue_pdsch_procedures(ue,
                        proc,
                        eNB_id,
                        PDSCH,
                        ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
                        NULL,
                        1+(ue->frame_parms.symbols_per_tti>>1),
                        ue->frame_parms.symbols_per_tti-1,
                        abstraction_flag);
    ue_dlsch_procedures(ue,
                        proc,
                        eNB_id,
                        PDSCH,
                        ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
                        ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
                        &ue->dlsch_errors[eNB_id],
                        mode,
                        abstraction_flag);
  // do procedures for SI-RNTI
  // do procedures for P-RNTI
  // do procedures for RA-RNTI

其中,ue_dlsch_procedures()函数中有:

ue_send_sdu(ue->Mod_id,
                        CC_id,
                        frame_rx,
                        subframe_rx,
                        dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
                        dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
                        eNB_id);

最后有一部分没看懂在做什么,注释如下:

  // duplicate harq structure

在接收和发射中间,还有一个函数ue_scheduler()做了非常多的事情(比较复杂),虽然写了注释也看不太懂。。

//------------------------------------------------------------------------------
// called at each subframe
// Performs :
// 1. Trigger PDCP every 5ms
// 2. Call RRC for link status return to PHY
// 3. Perform SR/BSR procedures for scheduling feedback
// 4. Perform PHR procedures

该线程中还有一个发送的函数:phy_procedures_UE_TX()

首先得到了一个SRS信息,接下来根据UE的不同模式进行不同的处理:

    if (ue->UE_mode[eNB_id] == PUSCH) {
     
      // check if we need to use PUCCH 1a/1b
      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
      // check if we need to use SRS
      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
    } // UE_mode==PUSCH
    
    ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
      
      if ((ue->UE_mode[eNB_id] == PRACH) &&
      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
     
    // check if we have PRACH opportunity
    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
     
      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
    }
  } // mode is PRACH

然后进行了下行ACK/NACK的设置

  // reset DL ACK/NACK status
5.3.3 UE_thread_synch线程分析

在该线程函数上就有注释,说明这是一个用于同步的线程:

/*!
 * \brief This is the UE synchronize thread.
 * It performs band scanning and synchonization.
 * \param arg is a pointer to a \ref PHY_VARS_UE structure.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */

线程刚开始就进行了扫频,扫频完后设置了:sync_mode = pbch;

接下来被阻塞在 wait_sync(“UE_thread_sync”) 处等待主线程的唤醒

唤醒后进入while (oai_exit==0) 循环,while循环中的阻塞略(详情见5.2.4.4 UE_thread线程&5.2.4.5 线程执行顺序分析

接下来在一个大switch语句中进行判断sync_mode:

switch (sync_mode) {
     
	case pss:	//物理层(频率频移等)
	case pbch:
        if (initial_sync( UE, UE->mode ) == 0) {
      //同步初始化成功,物理层
			switch(UE->frame_parms.N_RB_DL) {
     // reconfigure for potentially different bandwidth
				case 6:
					openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
					openair0_cfg[UE->rf_map.card].rx_bw          =.96e6;
					openair0_cfg[UE->rf_map.card].tx_bw          =.96e6;
				case 25:
            	case 50:
            	case 100:
         }
	case si:  //空白
	default:  //空白
}
5.3.4 UE_thread线程分析

首先,阻塞wait_sync(),跳过

接下来有NAS层的初始化

#ifdef NAS_UE
  MessageDef *message_p;
  message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
  itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif

然后就进入了while循环中:

while (!oai_exit) {
     
	if (is_synchronized == 0) {
     
	
	}
	else {
     
	
	}
	

该循环按照UE是否完成同步,将整个while循环分成了两段,其中也多是物理层的处理。

个人认为:该线程还是和他的注释的差不多,做了同步、接收这两个线程的辅助控制。

5.3.5 搜网流程分析

手机开机的搜网,先要接收pbch完成同步,再接收pdsch上的bcch来获取SIB消息

同步流程为:

  1. UE开机后,先扫频(若存有之前信息,可以利用原有信息快速搜索小区),然后再接收PSS信号,对应于 UE_thread_synch 线程 switch 中case pss。接收到pss后进行一系列时隙等的同步?在代码中接收到pss后好像进行一系列时隙等?频率?带宽?等的偏移、同步。
  2. 接下来应该是接收SSS信号,没找到。接收到上述两个信号之后,才开始读取pbch并解码?
  3. 不过代码中是把接收SSS信号和PBCH写在了一起,都在 UE_thread_synch 线程 switch 中case pbch 中。在该case中的initial_sync()函数中,进行了SSS信号的接收以及pbch信道的检测,随后也做了物理层的相关配置:帧、带宽、天线等等。
  4. 至此同步过程结束,相应的,线程UE_thread_synch也完成了它的使命。

接收SIB消息:

  1. 首先得接收PCFICF,解码得到PDCCH相关的信息;在代码中没找到相关函数,只找到一行相关的注释:
    • // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH);
    • 猜测是在该行注释上方的函数slot_fep()中,该函数确实有做信道估计等。
  2. 在PDCCH信道域的公共搜索空间里查找发送到SI-RNTI的候选PDCCH,如果找到一个并通过了相关的CRC校验,那就意味着有相应的SIB消息,于是接收PDSCH,译码后将SIB上报给高层协议栈;
  3. 上述第二条应该是在代码中phy_procedures_UE_RX()函数中实现的:
    • 该函数首先确认了有PDCCH被扫描到
    • 接下来是分时隙(共两个时隙)的进行判断接收到的RNTI是哪种,再进行相应的处理,其中当然包括了SI-RNTI的处理,处理函数为:ue_pdsch_procedures()和ue_dlsch_procedures()
    • 在第二点中的两个处理函数ue_pdsch_procedures()和ue_dlsch_procedures()中,也有:case SI_PDSCH的判断。

搜网流程差不多结束了。

你可能感兴趣的:(OAI项目GDB调试及代码分析)