:::warning # <center><i class="fa fa-edit"></i> Begining of Main function </center> ::: [TOC] ### E2 Agent headers ```c= #include "agent_if/read/sm_ag_if_rd.h" #include "agent_if/sm_io.h" #include "agent_if/e2_agent_api.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include <time.h> ``` ### Main function ```c= int main( int argc, char **argv ) { int ru_id, CC_id = 0; start_background_system(); ///static configuration for NR at the moment if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } set_softmodem_sighandler(); #ifdef DEBUG_CONSOLE setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); #endif mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); logInit(); configure_linux(); printf("Reading in command-line options\n"); get_options (); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); } openair0_cfg[0].threequarter_fs = threequarter_fs; AMF_MODE_ENABLED = get_softmodem_params()->sa; NGAP_CONF_MODE = get_softmodem_params()->sa; if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); if (get_softmodem_params()->sa) AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n"); #if T_TRACER T_Config_Init(); #endif //randominit (0); set_taus_seed (0); printf("configuring for RAU/RRU\n"); if (opp_enabled ==1) { reset_opp_meas(); } cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, tasks_info); // initialize mscgen log after ITTI MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); if(PDCP_USE_NETLINK) if(!IS_SOFTMODEM_NOS1) netlink_init(); #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); if (RC.nb_nr_L1_inst > 0) RCconfig_NR_L1(); // don't create if node doesn't connect to RRC/S1/GTP AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); /* Start the agent. If it is turned off in the configuration, it won't start */ /* RCconfig_nr_flexran(); for (i = 0; i < RC.nb_nr_L1_inst; i++) { flexran_agent_start(i); } */ // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); mlockall(MCL_CURRENT | MCL_FUTURE); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); usleep(1000); if (NFAPI_MODE) { printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); } const char *nfapi_mode_str = "<UNKNOWN>"; switch(NFAPI_MODE) { case 0: nfapi_mode_str = "MONOLITHIC"; break; case 1: nfapi_mode_str = "PNF"; break; case 2: nfapi_mode_str = "VNF"; break; default: nfapi_mode_str = "<UNKNOWN NFAPI MODE>"; break; } printf("NFAPI MODE:%s\n", nfapi_mode_str); if (NFAPI_MODE==NFAPI_MODE_VNF) wait_nfapi_init("main?"); printf("START MAIN THREADS\n"); // start the main threads number_of_cards = 1; printf("RC.nb_nr_L1_inst:%d\n", RC.nb_nr_L1_inst); if (RC.nb_nr_L1_inst > 0) { printf("Initializing gNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); init_gNB(single_thread_flag,wait_for_sync); } printf("wait_gNBs()\n"); wait_gNBs(); printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); if (RC.nb_RU >0) { printf("Initializing RU threads\n"); init_NR_RU(get_softmodem_params()->rf_config_file); for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { RC.ru[ru_id]->rf_map.card=0; RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset; } } config_sync_var=0; ////////////////////////////////// ////////////////////////////////// //// Init the E2 Agent sleep(2); const gNB_RRC_INST* rrc = RC.nrrrc[mod_id]; assert(rrc != NULL && "rrc cannot be NULL"); const int mcc = rrc->configuration.mcc[0]; // 208; const int mnc = rrc->configuration.mnc[0]; // 94; const int mnc_digit_len = rrc->configuration.mnc_digit_length[0]; // 2; const int nb_id = rrc->configuration.cell_identity; //42; sm_io_ag_t io = {.read = read_RAN, .write = write_RAN}; printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id); init_agent_api( mcc, mnc, mnc_digit_len, nb_id, io); ////////////////////////////////// ////////////////////////////////// if (NFAPI_MODE==NFAPI_MODE_PNF) { wait_nfapi_init("main?"); } if (RC.nb_nr_L1_inst > 0) { printf("wait RUs\n"); wait_RUs(); printf("ALL RUs READY!\n"); printf("RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init gNBs\n"); if(IS_SOFTMODEM_DOSCOPE) { sleep(1); scopeParms_t p; p.argc=&argc; p.argv=argv; p.gNB=RC.gNB[0]; p.ru=RC.ru[0]; load_softscope("nr",&p); } if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) { printf("Not NFAPI mode - call init_eNB_afterRU()\n"); init_eNB_afterRU(); } else { printf("NFAPI mode - DO NOT call init_gNB_afterRU()\n"); } printf("ALL RUs ready - ALL gNBs ready\n"); // connect the TX/RX buffers printf("Sending sync to all threads\n"); pthread_mutex_lock(&sync_mutex); sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); } printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); // We have to set PARAMFLAG_NOFREE on right paramters before re-enabling end_configmodule() //end_configmodule(); printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); // wait for end of program printf("TYPE <CTRL-C> TO TERMINATE\n"); //getchar(); printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); printf("Returned from ITTI signal handler\n"); oai_exit=1; printf("oai_exit=%d\n",oai_exit); // stop threads printf("stopping MODEM threads\n"); // cleanup stop_gNB(NB_gNB_INST); if (RC.nb_nr_L1_inst > 0) { stop_RU(NB_RU); } /* release memory used by the RU/gNB threads (incomplete), after all * threads have been stopped (they partially use the same memory) */ for (int inst = 0; inst < NB_gNB_INST; inst++) { //free_transport(RC.gNB[inst]); phy_free_nr_gNB(RC.gNB[inst]); } for (int inst = 0; inst < NB_RU; inst++) { nr_phy_free_RU(RC.ru[inst]); } free_lte_top(); pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); pthread_cond_destroy(&nfapi_sync_cond); pthread_mutex_destroy(&nfapi_sync_mutex); pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 for(ru_id=0; ru_id<NB_RU; ru_id++) { if (RC.ru[ru_id]->rfdevice.trx_end_func) RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); if (RC.ru[ru_id]->ifdevice.trx_end_func) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } logClean(); printf("Bye.\n"); return 0; } ``` #### Lets describe this part of code ```c= ///static configuration for NR at the moment if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } set_softmodem_sighandler(); #ifdef DEBUG_CONSOLE setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); #endif mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); logInit(); configure_linux(); printf("Reading in command-line options\n"); get_options (); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); } ``` | exit_fun | Exit function | | ----------------- | ----------------------------- | | configure_linux() | Block CPU C-states deep sleep | | CONFIG_ABORT | config failed,abort execution | | logInit() | initialize message | | openair0_cfg |RF frontend parameters set by application | | load_configmodule | Loading of config module | #### Code of exit_fun ```c= #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) ``` #### Code of load_configmodule ```c= configmodule_interface_t *load_configmodule(int argc, char **argv, <error-type> initflags) ```