diff --git a/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG b/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG new file mode 100644 index 0000000000..5e40d6ac17 Binary files /dev/null and b/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG differ diff --git a/doc/episys/Proxy_Interface_Diagram.PNG b/doc/episys/Proxy_Interface_Diagram.PNG new file mode 100644 index 0000000000..a734f3d4b0 Binary files /dev/null and b/doc/episys/Proxy_Interface_Diagram.PNG differ diff --git a/doc/episys/functional_diagram_proxy_lte.png b/doc/episys/functional_diagram_proxy_lte.png new file mode 100644 index 0000000000..e2a3a2c868 Binary files /dev/null and b/doc/episys/functional_diagram_proxy_lte.png differ diff --git a/doc/episys/functional_diagram_proxy_nsa.png b/doc/episys/functional_diagram_proxy_nsa.png new file mode 100644 index 0000000000..4a555d12ea Binary files /dev/null and b/doc/episys/functional_diagram_proxy_nsa.png differ diff --git a/doc/episys/lte_mode_l2_emulator/README.txt b/doc/episys/lte_mode_l2_emulator/README.txt new file mode 100644 index 0000000000..2b35ce6f99 --- /dev/null +++ b/doc/episys/lte_mode_l2_emulator/README.txt @@ -0,0 +1,49 @@ +There are fundamental changes to the L2 emulation mechanism; these changes allow the +user to run multiple UEs in separate Linux processes/machines/VMs/etc. They use a separate +entity between the UE(s) and eNB; where the UEs use nFAPI to communicate with the eNB. The +nFAPI interface allows us to run in an emulated L2 mode, meaning that we are bypassing +the layer 1 (PHY) layer functionality. Becasue we are bypassing the PHY layer, special +channel modelling capabilty has been added in the LTE UE phy_stub_ue.c file. To understand +the interfaces between the different components associated with LTE mode, the image +functional_diagram_proxy_lte.png has been provided. + +This functionality allows the user to plug in their own channel model and emulator the packet dropping procedure +in real time. The channel modelling has not been provided by EpiSci, but the OAI code +base already has some BLER curves available for use. The channle modelling functionality +that is included in the phy_stub_ue.c file only includes the downlink channel modelling. +Any uplink channel modelling must be conducted in some sort of proxy, which would sit +between the UEs and eNB. (A description of the downlink channel modelling is shown in the +Channel_Abstraction_UE_Handling_LTE.PNG image). + +The updates to the OAI code base removed some latent bugs, added multi-UE scalability, +and were tested with a standard bypass proxy between the UE(s) and eNB. The bypass proxy is +publicly available on GitHub. With this package, +various multi-UE scenarios can be tested without the overhead of PHY-layer features +of underlying radios. + + - Ease of use of gprof and address sanitizer for debugging purposes + - Updated json files to allow for GDB, real-time debugging capabilities + - Updated logging features to minimally log only key connection milestones. This improves scalability of multiple UEs. +The logging mechanism described here is located in the log.c and log.h files. The LOG_MINIMAL +function allows us to remove all OAI logging and only include LOG_A(...) logs. The LOG_A +logs were chosen as analysis logs to meet EpiSci's internal testing procedure. The LOG_As +only include logs that are considered to be critical milestones in a particular procedure. (i.e. a +log indicating that the RACH procedure has been completed for LTE.) To revert to the original logging +mechanism, simply set LOG_MINIMAL = 0 in the log.h file. + - Updated logging to include time stamp for timing analysis + - Updated memory allocation procedures to correct size requirements + - Added debugging features to handle signal terminations + - nfapi.c pullarray8 fix invalid pointer math + - Overlapping destination and source memory in memcpy, so updated to memmove to check for this bug + - Advanced error checking mechanisms in critical pack and unpack functions + - Created option for CPU assignment to UE to improve scalability + - Added EPC integration to allow multiple individual UE entities to each have their USIM information parsed by the executables + - Updated random value seeds to minimize probability of error in generation of random values + - Enables capability round robin scheduler if desired + - Enables capability real time scheduler if desired + - Added new standalone functions to the UE phy-layer (phy_stub_ue.c) to incorporate individual UE entities + - Updated sending and packing functions in UE (lte_ue.c) to incorporate new standalone changes + - Incorporated semaphores to control timing of incoming downlink packets + - Implemented new queuing system to handle message exchange from UE to eNB and vice versa + - Updated global value in nFAPI for size of subframe + - Updated global value to increase scalability in system \ No newline at end of file diff --git a/doc/episys/nsa_mode_l2_emulator/README.txt b/doc/episys/nsa_mode_l2_emulator/README.txt new file mode 100644 index 0000000000..0fde5d0e3e --- /dev/null +++ b/doc/episys/nsa_mode_l2_emulator/README.txt @@ -0,0 +1,94 @@ +There are fundamental changes to the L2 emulation mechanism; these changes allow the +user to run multiple UEs in separate Linux processes/machines/VMs/etc. They use a separate +entity between the UE(s) and eNB; where the UEs use nFAPI to communicate with the eNB. The +nFAPI interface allows us to run in an emulated L2 mode, meaning that we are bypassing +the layer 1 (PHY) layer functionality. Becasue we are bypassing the PHY layer, special +channel modelling capabilty has been added in the LTE UE phy_stub_ue.c file. To understand +the interfaces between the different components associated with NSA mode, the image +functional_diagram_proxy_nsa.png has been provided. + +This functionality allows the user to plug in their own channel model and emulator the packet dropping procedure +in real time. The channel modelling has not been provided by EpiSci, but the OAI code +base already has some BLER curves available for use. The channle modelling functionality +that is included in the phy_stub_ue.c file only includes the downlink channel modelling. +Any uplink channel modelling must be conducted in some sort of proxy, which would sit +between the UEs and eNB. (A description of the downlink channel modelling is shown in the +Channel_Abstraction_UE_Handling_LTE.PNG image). + +The updates to the OAI code base removed some latent bugs, added multi-UE scalability, +and were tested with a standard bypass proxy between the UE(s) and eNB. The bypass proxy is +publicly available on GitHub. With this package, +various multi-UE scenarios can be tested without the overhead of PHY-layer features +of underlying radios. + + - Ease of use of gprof and address sanitizer for debugging purposes + - Updated json files to allow for GDB, real-time debugging capabilities + - Updated logging features to minimally log only key connection milestones. This improves scalability of multiple UEs. +The logging mechanism described here is located in the log.c and log.h files. The LOG_MINIMAL +function allows us to remove all OAI logging and only include LOG_A(...) logs. The LOG_A +logs were chosen as analysis logs to meet EpiSci's internal testing procedure. The LOG_As +only include logs that are considered to be critical milestones in a particular procedure. (i.e. a +log indicating that the RACH procedure has been completed for LTE.) To revert to the original logging +mechanism, simply set LOG_MINIMAL = 0 in the log.h file. + - Updated logging to include time stamp for timing analysis + - Updated memory allocation procedures to correct size requirements + - Added debugging features to handle signal terminations + - nfapi.c pullarray8 fix invalid pointer math + - Overlapping destination and source memory in memcpy, so updated to memmove to check for this bug + - Advanced error checking mechanisms in critical pack and unpack functions + - Created option for CPU assignment to UE to improve scalability + - Added EPC integration to allow multiple individual UE entities to each have their USIM information parsed by the executables + - Updated random value seeds to minimize probability of error in generation of random values + - Enables capability round robin scheduler if desired + - Enables capability real time scheduler if desired + - Added new standalone functions to the UE phy-layer (phy_stub_ue.c) to incorporate individual UE entities + - Updated sending and packing functions in UE (lte_ue.c) to incorporate new standalone changes + - Incorporated semaphores to control timing of incoming downlink packets + - Implemented new queuing system to handle message exchange from UE to eNB and vice versa + - Updated global value in nFAPI for size of subframe + - Updated global value to increase scalability in system + + +Additionally, NSA mode includes the establishment between an NR UE and the gNB via the LTE UE and eNB +connection. For NSA mode, the downlink channel abstraction has not been added to the feature set yet. +NSA mode has been tested and is fully functional with EpiSci's public version of the nFAPI proxy +located at https://github.com/EpiSci/oai-lte-multi-ue-proxy/blob/master/README.md +NSA mode establishment includes the following steps: + + - First UE capability enquiry is sent to NR UE + - NR UE updates and fills first capability enquiry + - eNB request for a measurement report + - Measurement request is sent to NR UE + - Measurement report is filled in NR UE + - Measurement report is received in eNB + - Request for second UE capability enquiry + - Send second enquiry to NR UE + - Second capability information is filled by NR UE + - Second capability information is sent to eNB + - NR UE capability information is received in gNB + - Periodic measurement report received in gNB + - RRCReconfigurationRequest is sent to NR UE + - RRCReconfigurationComplete is sent from NR UE + - RACH is received in the gNB + - RAR is received in NR UE + - Msg 3 is generated and sent to gNB + - CFRA procedure is complete + +Please note, the current status is: + - A single NSA UE is able to ping an external source + - Up to 4 NSA UEs can complete the CFRA procedure with a single gNB + - UE-to-UE traffic is still in work (incomplete due to gNB crashing) + - The gNB is crashing regularly and is still in work + +Test Setup: +For launching the multi-UE for NSA mode, there is a provided test script in the +public EpiSci GitHub multi-ue-proxy repository. However, a brief outline of the +test set up is included below. + + If running multiple NSA UEs in a single machine, you will need to launch + multiple LTE and NR UE processes. For example, to launch a 2 NSA UE scenario + there will be a total of 7 processes running for this particular scenario. + These processes are LTE UE #1, LTE UE #2, NR UE #1, NR UE #2, eNB, gNB and the + proxy. A detailed description of the launch processes can be found at + https://github.com/EpiSci/oai-lte-multi-ue-proxy/blob/master/README.md + diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 4d9e2dce35..a1d5292f11 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -603,11 +603,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t rx_ind; + fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); uint16_t number_pdus = 1; - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, NULL); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index bf12fe4f39..9d0f6fa7d5 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -487,7 +487,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; unsigned int dci_cnt=0; - fapi_nr_dci_indication_t dci_ind = {0}; + fapi_nr_dci_indication_t *dci_ind = calloc(1, sizeof(*dci_ind)); nr_downlink_indication_t dl_indication; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][gNB_id]; @@ -688,7 +688,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, n_ss); #endif - dci_cnt = nr_dci_decoding_procedure(ue, proc, &dci_ind, rel15); + dci_cnt = nr_dci_decoding_procedure(ue, proc, dci_ind, rel15); #ifdef NR_PDCCH_SCHED_DEBUG LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt); @@ -702,12 +702,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]], i + 1, dci_cnt, - dci_ind.dci_list[i].rnti, - dci_ind.dci_list[i].dci_format); + dci_ind->dci_list[i].rnti, + dci_ind->dci_list[i].dci_format); } ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt; - dci_ind.number_of_dcis = dci_cnt; + dci_ind->number_of_dcis = dci_cnt; /* for (int i=0; iif_inst->dl_indication(&dl_indication, NULL); @@ -893,7 +893,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UE_PDSCH *pdsch_vars; uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos); nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t rx_ind; + fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); uint16_t number_pdus = 1; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; @@ -1039,17 +1039,17 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, switch (pdsch) { case RA_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus); ue->UE_mode[gNB_id] = RA_RESPONSE; break; case PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus); break; case SI_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus); break; default: break; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 8a56d5cf4b..04adb34e9d 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -413,24 +413,18 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) nas_getparams(); if(UE_NAS_USE_TUN) { + char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue"; int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; - netlink_init_tun("nrue", num_if, id); + netlink_init_tun(ifsuffix_ue, num_if, id); //Add --nr-ip-over-lte option check for next line - if (IS_SOFTMODEM_NOS1 && get_softmodem_params()->nsa) - nas_config(1, 1, 3, "nrue"); - else if (IS_SOFTMODEM_NOS1) - nas_config(1, 1, 2, "ue"); + if (IS_SOFTMODEM_NOS1) + nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); LOG_I(PDCP, "UE pdcp will use tun interface\n"); start_pdcp_tun_ue(); } else if(ENB_NAS_USE_TUN) { - if (get_softmodem_params()->nsa) { - netlink_init_tun("gnb", 1, id); - nas_config(1, 1, 1, "gnb"); - } - else { - netlink_init_tun("enb", 1, id); - nas_config(1, 1, 1, "enb"); - } + char *ifsuffix_base_s = get_softmodem_params()->nsa ? "gnb" : "enb"; + netlink_init_tun(ifsuffix_base_s, 1, id); + nas_config(1, 1, 1, ifsuffix_base_s); LOG_I(PDCP, "ENB pdcp will use tun interface\n"); start_pdcp_tun_enb(); } else { diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index c64ae2e427..2e89229e90 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -958,14 +958,11 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ } //clean up nr_downlink_indication_t *dl_info - if(dl_info->dci_ind != NULL){ - free(dl_info->dci_ind); - dl_info->dci_ind = NULL; - } - if(dl_info->rx_ind != NULL){ - free(dl_info->rx_ind); - dl_info->rx_ind = NULL; - } + free(dl_info->dci_ind); + dl_info->dci_ind = NULL; + free(dl_info->rx_ind); + dl_info->rx_ind = NULL; + } return 0; }