diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b252833c5a..95af74d9de 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -416,7 +416,7 @@ add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") -add_boolean_option(NEW_GTPU False "NEW_GTP") +add_boolean_option(NEW_GTPU True "NEW_GTP") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 474851480e..437b444e91 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -288,7 +288,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, } G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers); - LOG_D(PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,mod_order); + LOG_D(NR_PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,mod_order); if (A > 3824) { // Add 24-bit crc (polynomial A) to payload @@ -406,7 +406,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, E = nr_get_E(G, harq->C, mod_order, rel15->nrOfLayers, r); //#ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n", + LOG_D(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n", r, harq->C, G, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 5aa476bc13..129f7a9a71 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -490,8 +490,12 @@ typedef struct { int32_t **ul_ch_magb1[8][8]; /// measured RX power based on DRS int ulsch_power[8]; + /// total signal over antennas + int ulsch_power_tot; /// measured RX noise power int ulsch_noise_power[8]; + /// total noise over antennas + int ulsch_noise_power_tot; /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 1d7745a4e7..21b66d7576 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -382,10 +382,12 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, LOG_D(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update); - // estimate UL_CQI for MAC (from antenna port 0 only) - int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[0]); + // estimate UL_CQI for MAC - LOG_D(PHY, "Estimated SNR for PUSCH is = %f dB (ulsch_power %f, noise %f)\n", SNRtimes10/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0])/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[0])/10.0); + int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) - + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot); + + LOG_D(PHY, "Estimated SNR for PUSCH is = %f dB (ulsch_power %f, noise %f)\n", SNRtimes10/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot)/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot)/10.0); if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; @@ -657,22 +659,25 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); - start_meas(&gNB->rx_pusch_stats); - for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { - nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); - } - int ulsch_power=0,ulsch_noise_power=0; + start_meas(&gNB->rx_pusch_stats); + for (uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); + } + gNB->pusch_vars[ULSCH_id]->ulsch_power_tot=0; + gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot=0; for (int aarx=0;aarxframe_parms.nb_antennas_rx;aarx++) { gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx]/=num_dmrs; - ulsch_power += gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx]; + gNB->pusch_vars[ULSCH_id]->ulsch_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx]; gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx]/=num_dmrs; - ulsch_noise_power += gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx]; + gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx]; } - if (dB_fixed_x10(ulsch_power) < dB_fixed_x10(ulsch_noise_power) + gNB->pusch_thres) { + if (dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) < + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) { NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); - LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, - dB_fixed_x10(ulsch_power),dB_fixed_x10(ulsch_noise_power),gNB->pusch_thres); + LOG_I(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot), + dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres); nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1); gNB->pusch_vars[ULSCH_id]->DTX=1; stats->DTX++; diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index 88c99a90c3..dd971801e9 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -57,7 +57,8 @@ #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" #define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10" #define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10" - +#define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres" +#define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MacRLC configuration parameters */ @@ -83,6 +84,8 @@ {CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -103,5 +106,7 @@ #define MACRLC_REMOTE_S_PORTD_IDX 16 #define MACRLC_PUSCHTARGETSNRX10_IDX 17 #define MACRLC_PUCCHTARGETSNRX10_IDX 18 +#define MACRLC_PUCCHFAILURETHRES_IDX 19 +#define MACRLC_PUSCHFAILURETHRES_IDX 20 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 5eaf2942de..8eb9670934 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -675,7 +675,9 @@ void RCconfig_nr_macrlc() { RC.nb_nr_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr); RC.nrmac[j]->pusch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHTARGETSNRX10_IDX].iptr); RC.nrmac[j]->pucch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHTARGETSNRX10_IDX].iptr); - + RC.nrmac[j]->pucch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHFAILURETHRES_IDX].iptr); + RC.nrmac[j]->pusch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHFAILURETHRES_IDX].iptr); + if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { // check number of instances is same as RRC/PDCP diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index e234ef63fd..6adc65ad37 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -55,7 +55,7 @@ #define HALFWORD 16 #define WORD 32 //#define SIZE_OF_POINTER sizeof (void *) -static boolean_t loop_dcch_dtch = TRUE; +static int loop_dcch_dtch = DL_SCH_LCID_DTCH; void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) { @@ -390,8 +390,14 @@ void nr_store_dlsch_buffer(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; sched_ctrl->num_total_bytes = 0; - loop_dcch_dtch = BOOL_NOT(loop_dcch_dtch); - const int lcid = loop_dcch_dtch?DL_SCH_LCID_DTCH:DL_SCH_LCID_DCCH; + if (loop_dcch_dtch == DL_SCH_LCID_DCCH1) + loop_dcch_dtch = DL_SCH_LCID_DTCH; + else if (loop_dcch_dtch == DL_SCH_LCID_DTCH) + loop_dcch_dtch = DL_SCH_LCID_DCCH; + else if (loop_dcch_dtch == DL_SCH_LCID_DCCH) + loop_dcch_dtch = DL_SCH_LCID_DCCH1; + + const int lcid = loop_dcch_dtch; // const int lcid = DL_SCH_LCID_DTCH; const uint16_t rnti = UE_info->rnti[UE_id]; sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, @@ -1086,7 +1092,7 @@ void nr_schedule_ue_spec(module_id_t module_id, /* next, get RLC data */ // const int lcid = DL_SCH_LCID_DTCH; - const int lcid = loop_dcch_dtch?DL_SCH_LCID_DTCH:DL_SCH_LCID_DCCH; + const int lcid = loop_dcch_dtch; int dlsch_total_bytes = 0; if (sched_ctrl->num_total_bytes > 0) { tbs_size_t len = 0; @@ -1114,11 +1120,12 @@ void nr_schedule_ue_spec(module_id_t module_id, 0); LOG_D(NR_MAC, - "%4d.%2d RNTI %04x: %d bytes from DTCH %d (ndata %d, remaining size %d)\n", + "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n", frame, slot, rnti, len, + lcid < 4 ? "DCCH" : "DTCH", lcid, ndata, size); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 864373952b..51a71427c5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1840,6 +1840,10 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG sched_ctrl->ta_frame = 0; sched_ctrl->ta_update = 31; sched_ctrl->ta_apply = false; + sched_ctrl->ul_rssi = 0; + sched_ctrl->pucch_consecutive_dtx_cnt = 0; + sched_ctrl->pusch_consecutive_dtx_cnt = 0; + sched_ctrl->ul_failure = 0; /* set illegal time domain allocation to force recomputation of all fields */ sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; sched_ctrl->pusch_semi_static.time_domain_allocation = -1; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 120a2efae9..92b1c4ed99 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -359,6 +359,7 @@ void nr_process_mac_pdu(module_id_t module_idP, break; case UL_SCH_LCID_SRB1: + case UL_SCH_LCID_SRB2: if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; mac_subheader_len = 3; @@ -381,9 +382,6 @@ void nr_process_mac_pdu(module_id_t module_idP, 1, NULL); break; - case UL_SCH_LCID_SRB2: - // todo - break; case UL_SCH_LCID_SRB3: // todo break; @@ -448,7 +446,7 @@ void nr_process_mac_pdu(module_id_t module_idP, mac_sdu_len); UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); + log_dump(NR_MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); #endif mac_rlc_data_ind(module_idP, @@ -568,7 +566,6 @@ void handle_nr_ul_harq(module_id_t mod_id, add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); } } - /* * When data are received on PHY and transmitted to MAC */ @@ -588,6 +585,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const int current_rnti = rntiP; const int UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti); const int target_snrx10 = gNB_mac->pusch_target_snrx10; + const int pusch_failure_thres = gNB_mac->pusch_failure_thres; if (UE_id != -1) { NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id]; @@ -639,6 +637,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (sduP != NULL){ LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); + UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt = 0; const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) @@ -646,8 +645,24 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP); } + else { + NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; + /* reduce sched_ul_bytes when cur_harq->round == 3 */ + if (cur_harq->round == 3){ + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; + if (UE_scheduling_control->sched_ul_bytes < 0) + UE_scheduling_control->sched_ul_bytes = 0; + } + if (ul_cqi < 128) UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt++; + if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) { + LOG_I(NR_MAC,"Detected UL Failure on PUSCH, stopping scheduling\n"); + UE_info->UE_sched_ctrl[UE_id].ul_failure = 1; + } + } } else if(sduP) { + bool no_sig = true; for (int k = 0; k < sdu_lenP; k++) { if(sduP[k]!=0) { @@ -673,7 +688,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, continue; if(no_sig) { - LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + LOG_W(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } else { @@ -686,7 +701,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, current_rnti); if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) { - LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + LOG_W(NR_MAC, "Random Access %i failed at state %i (TC_RNTI %04x RNTI %04x\n", i, ra->state,ra->rnti,current_rnti); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } @@ -744,7 +759,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } return; - } } } else { @@ -753,7 +767,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (ra->state != WAIT_Msg3) continue; - LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state); + LOG_W(NR_MAC, "Random Access %i failed at state %i (state is not WAIT_Msg3)\n", i, ra->state); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } @@ -1520,8 +1534,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id]; int n_ubwp=1; if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) + CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && + CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) n_ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; config_uldci(sched_ctrl->active_ubwp, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 92a0a0a5cd..f22304aa85 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -563,7 +563,11 @@ typedef struct { int raw_rssi; int pusch_snrx10; int pucch_snrx10; - + uint16_t ul_rssi; + uint8_t current_harq_pid; + int pusch_consecutive_dtx_cnt; + int pucch_consecutive_dtx_cnt; + int ul_failure; struct CSI_Report CSI_report[MAX_CSI_REPORTS]; /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; @@ -651,6 +655,10 @@ typedef struct gNB_MAC_INST_s { int pusch_target_snrx10; /// Pucch target SNR int pucch_target_snrx10; + /// PUCCH Failure threshold (compared to consecutive PUCCH DTX) + int pucch_failure_thres; + /// PUSCH Failure threshold (compared to consecutive PUSCH DTX) + int pusch_failure_thres; /// Subcarrier Offset int ssb_SubcarrierOffset; /// Common cell resources diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 4c74c62dbd..6898d4ff71 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -333,7 +333,8 @@ void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) nr_pdcp_entity_t *new_nr_pdcp_entity( nr_pdcp_entity_type_t type, - int is_gnb, int rb_id, + int is_gnb, int rb_id, int pdusession_id,int has_sdap, + int has_sdapULheader, int has_sdapDLheader, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -372,6 +373,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ret->deliver_pdu_data = deliver_pdu_data; ret->rb_id = rb_id; + ret->pdusession_id = pdusession_id; + ret->has_sdap = has_sdap; + ret->has_sdapULheader = has_sdapULheader; + ret->has_sdapDLheader = has_sdapDLheader; ret->sn_size = sn_size; ret->t_reordering = t_reordering; ret->discard_timer = discard_timer; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index b7093c7182..5bdc6f7892 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -62,7 +62,10 @@ typedef struct nr_pdcp_entity_t { /* configuration variables */ int rb_id; - + int pdusession_id; + int has_sdap; + int has_sdapULheader; + int has_sdapDLheader; int sn_size; /* SN size, in bits */ int t_reordering; /* unit: ms */ int discard_timer; /* unit: ms */ @@ -113,7 +116,8 @@ typedef struct nr_pdcp_entity_t { nr_pdcp_entity_t *new_nr_pdcp_entity( nr_pdcp_entity_type_t type, - int is_gnb, int rb_id, + int is_gnb, int rb_id, int pdusession_id,int has_sdap, + int has_sdapULheader,int has_sdapDLheader, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index c534b6c57f..9cf06c9b7f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -478,22 +478,25 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, exit(1); rb_found: - gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, - size + GTPU_HEADER_OVERHEAD_MAX); - AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); - memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size); - message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ); - AssertFatal(message_p != NULL, "OUT OF MEMORY"); - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = size; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; - LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); - //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); - //printf("\n"); - itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); + { + int offset=0; + if (entity->has_sdap == 1 && entity->has_sdapULheader == 1) offset = 1; // this is the offset of the SDAP header in bytes + gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, + size + GTPU_HEADER_OVERHEAD_MAX - offset); + AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); + memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset); + message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ); + AssertFatal(message_p != NULL, "OUT OF MEMORY"); + GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; + GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length = size-offset; + GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; + GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; + GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id; + if (offset==1) LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]); + LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset); + itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); + } } } @@ -532,7 +535,7 @@ rb_found: memblock = get_free_mem_block(size, __FUNCTION__); memcpy(memblock->data, buf, size); - LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); + LOG_I(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); //printf("\n"); enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL); @@ -754,7 +757,8 @@ static void add_srb(int is_gnb, int rnti, struct NR_SRB_ToAddMod *s) LOG_D(PDCP, "%s:%d:%s: warning SRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); } else { - pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, + pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, + 0, 0, 0, 0, // sdap parameters deliver_sdu_srb, ue, deliver_pdu_srb, ue, 12, t_Reordering, -1, 0, 0, @@ -780,7 +784,31 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL); int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL); int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer); - + if ((!s->cnAssociation) || s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_NOTHING) { + LOG_E(PDCP,"%s:%d:%s: fatal, cnAssociation is missing or present is NR_DRB_ToAddMod__cnAssociation_PR_NOTHING\n",__FILE__,__LINE__,__FUNCTION__); + exit(-1); + } + + int pdusession_id; + int has_sdap = 0; + int has_sdapULheader=0; + int has_sdapDLheader=0; + if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) + pdusession_id = s->cnAssociation->choice.eps_BearerIdentity; + else { + if (!s->cnAssociation->choice.sdap_Config) { + LOG_E(PDCP,"%s:%d:%s: fatal, sdap_Config is null",__FILE__,__LINE__,__FUNCTION__); + exit(-1); + } + pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session; + has_sdap = 1; + has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0; + has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0; + if (has_sdapDLheader==1) { + LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__); + exit(-1); + } + } /* TODO(?): accept different UL and DL SN sizes? */ if (sn_size_ul != sn_size_dl) { LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", @@ -800,7 +828,8 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, drb_id, + pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id,pdusession_id,has_sdap, + has_sdapULheader,has_sdapDLheader, deliver_sdu_drb, ue, deliver_pdu_drb, ue, sn_size_dl, t_reordering, discard_timer, ciphering_algorithm, integrity_algorithm, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index caf9c32f87..105a2b2538 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -448,7 +448,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) exit(1); rb_found: - LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d", + LOG_I(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n", __FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size); memblock = get_free_mem_block(size, __func__); @@ -765,7 +765,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ /* TODO: accept other values? */ if (logical_channel_group != 1) { LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); + //exit(1); } switch (r->present) { diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index efbf950995..e3a12ff771 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -44,6 +44,8 @@ #include "NR_MIB.h" #include "NR_BCCH-BCH-Message.h" #include "rrc_gNB_UE_context.h" +#include + #include "RRC/NR/MESSAGES/asn1_msg.h" diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 46175e0b0b..47dadb9c23 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1034,7 +1034,7 @@ void fill_initial_SpCellConfig(rnti_t rnti, AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, "SCS != 30kHz\n"); AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5, - "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); + "TDD period != 5ms : %d\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 10*((rnti>>1)&3) + (rnti&2); schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); @@ -1081,7 +1081,7 @@ void fill_initial_SpCellConfig(rnti_t rnti, SpCellConfig->spCellConfigDedicated->tag_Id=0; } -void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig) { +void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup) { NR_RLC_BearerConfig_t *rlc_BearerConfig = NULL; NR_RLC_Config_t *rlc_Config = NULL; @@ -1116,7 +1116,24 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig) { rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8; //} rlc_BearerConfig->rlc_Config = rlc_Config; + + logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); + logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters)); + logicalChannelConfig->ul_SpecificParameters->priority = 3; + logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; + logicalChannelGroup = CALLOC(1, sizeof(long)); + *logicalChannelGroup = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup; + logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID)); + *logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0; + //} + rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig; + ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig); /*DRB Configuration*/ rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t)); @@ -1141,25 +1158,24 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig) { rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t4; //} rlc_BearerConfig->rlc_Config = rlc_Config; - ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); + logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters)); + logicalChannelConfig->ul_SpecificParameters->priority = 13; + logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100; + logicalChannelGroup = CALLOC(1, sizeof(long)); + *logicalChannelGroup = 1; + logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup; + logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID)); + *logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0; - - //if (0) { - logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); - logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters)); - logicalChannelConfig->ul_SpecificParameters->priority = 3; - logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; - logicalChannelGroup = CALLOC(1, sizeof(long)); - *logicalChannelGroup = 0; - logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup; - logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID)); - *logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0; - logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0; - logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0; - //} rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig; + ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig); + cellGroupConfig->rlc_BearerToReleaseList = NULL; } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 4601252cb0..4dd6fd939f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -97,7 +97,7 @@ void fill_initial_cellGroupConfig(rnti_t rnti, NR_CellGroupConfig_t *cellGroupConfig, NR_ServingCellConfigCommon_t *scc); -void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig); +void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup); uint8_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, uint8_t *const buffer, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d0fc32d3df..d636e1e5dd 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -688,6 +688,7 @@ rrc_gNB_process_RRCSetupComplete( LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); ue_context_pP->ue_context.Srb1.Active = 1; + ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1; ue_context_pP->ue_context.Status = NR_RRC_CONNECTED; if (AMF_MODE_ENABLED) { @@ -959,7 +960,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); sdap_config->pdu_Session = ue_context_pP->ue_context.pdusession[i].param.pdusession_id; - sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; + sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; sdap_config->defaultDRB = TRUE; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); @@ -1049,7 +1050,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( memset(buffer, 0, RRC_BUF_SIZE); cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig); + fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup); size = do_RRCReconfiguration(ctxt_pP, buffer, xid, *SRB_configList2, @@ -1294,6 +1295,7 @@ rrc_gNB_process_RRCReconfigurationComplete( for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { if (SRB_configList->list.array[i]->srb_Identity == 1) { ue_context_pP->ue_context.Srb1.Active = 1; + ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1; } else if (SRB_configList->list.array[i]->srb_Identity == 2) { ue_context_pP->ue_context.Srb2.Active = 1; ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index dd59711584..afd4af2ccc 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -808,7 +808,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( /* Transfer data to PDCP */ nr_rrc_data_req ( &ctxt, - DCCH, // ue_context_p->ue_context.Srb2.Srb_info.Srb_id, + ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, @@ -838,7 +838,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( /* Transfer data to PDCP */ nr_rrc_data_req ( &ctxt, - DCCH, + ue_context_p->ue_context.Srb2.Active == 1 ? ue_context_p->ue_context.Srb2.Srb_info.Srb_id : ue_context_p->ue_context.Srb1.Srb_info.Srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c index 4b729a9240..d3f26aeff1 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB.c +++ b/openair3/GTPV1-U/gtpv1u_gNB.c @@ -52,6 +52,9 @@ #undef GTP_DUMP_SOCKET +#undef GTPV1U_BEARER_OFFSET +#define GTPV1U_BEARER_OFFSET 1 + extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c index 0c7663921b..5479e176eb 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c +++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c @@ -59,6 +59,7 @@ extern "C" { #endif +#define LOG_GTPU 1 /*--------------------------------------------------------------------------* * P R I V A T E F U N C T I O N S * *--------------------------------------------------------------------------*/ diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index e4d3945469..2862a4d906 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -85,7 +85,7 @@ class gtpEndPoints { gtpEndPoints globGtp; - // note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions +// note TEid 0 is reserved for specific usage: echo req/resp, error and supported extensions static uint32_t gtpv1uNewTeid(void) { #ifdef GTPV1U_LINEAR_TEID_ALLOCATION g_gtpv1u_teid = g_gtpv1u_teid + 1; @@ -121,8 +121,10 @@ static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, te msgHdr->version=1; msgHdr->msgType=GTP_GPDU; msgHdr->msgLength=htons(msgLen); + if ( seqNumFlag || extHdrFlag || npduNumFlag) msgHdr->msgLength+=4; + msgHdr->teid=htonl(teid); if(seqNumFlag || extHdrFlag || npduNumFlag) { @@ -191,7 +193,48 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b tmp.teid_outgoing, buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; } - + +static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) { + uint8_t *buffer=req->buffer+req->offset; + size_t length=req->length; + uint64_t rnti=req->rnti; + int rab_id=req->pdusession_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + auto ptr=ptrRnti->second.bearers; + + if ( ptr.find(rab_id) == ptr.end() ) { + LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } else + LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %lx/%x/%x, len %lu, oldseq %d, oldnum %d\n", + rnti, rab_id,ptr[rab_id].teid_outgoing,length, ptr[rab_id].seqNum,ptr[rab_id].npduNum ); + + if(seqNumFlag) + ptr[rab_id].seqNum++; + + if(npduNumFlag) + ptr[rab_id].npduNum++; + + // We will release the lock, let's copy data before + ocp_gtpv1u_bearer_t tmp=ptr[rab_id]; + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1uCreateAndSendMsg(compatInst(instance), + tmp.outgoing_ip_addr, + tmp.outgoing_port, + tmp.teid_outgoing, + buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; +} + static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) { uint64_t rnti=req->rnti; int rab_id=req->rab_id; @@ -214,9 +257,9 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r } else LOG_D(GTPU,"sending a end packet packet to RNTI:RAB:teid %lx/%x/%x\n", rnti, rab_id,ptr[rab_id].teid_outgoing); + ocp_gtpv1u_bearer_t tmp=ptr[rab_id]; pthread_mutex_unlock(&globGtp.gtp_lock); - Gtpv1uMsgHeaderT msgHdr; // N should be 0 for us (it was used only in 2G and 3G) msgHdr.PN=0; @@ -229,7 +272,6 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r msgHdr.msgType=GTP_END_MARKER; msgHdr.msgLength=htons(0); msgHdr.teid=htonl(tmp.teid_outgoing); - // Fix me: add IPv6 support, using flag ipVersion static struct sockaddr_in to= {0}; to.sin_family = AF_INET; @@ -243,7 +285,7 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r compatInst(instance), IPV4_ADDR_FORMAT(tmp.outgoing_ip_addr), tmp.outgoing_port, sizeof(msgHdr)); } } - + static int udpServerSocket(openAddr_s addr) { LOG_I(GTPU, "Initializing UDP for local address %s with port %s\n", addr.originHost, addr.originService); int status; @@ -280,7 +322,7 @@ static int udpServerSocket(openAddr_s addr) { memcpy(globGtp.instances[sockfd].foundAddr, &ipv4->sin_addr.s_addr, sizeof(ipv4->sin_addr.s_addr)); globGtp.instances[sockfd].foundAddrLen=sizeof(ipv4->sin_addr.s_addr); - globGtp.instances[sockfd].ipVersion=4; + globGtp.instances[sockfd].ipVersion=4; break; } else if (p->ai_family == AF_INET6) { LOG_W(GTPU,"Local address is IP v6\n"); @@ -288,7 +330,7 @@ static int udpServerSocket(openAddr_s addr) { memcpy(globGtp.instances[sockfd].foundAddr, &ipv6->sin6_addr.s6_addr, sizeof(ipv6->sin6_addr.s6_addr)); globGtp.instances[sockfd].foundAddrLen=sizeof(ipv6->sin6_addr.s6_addr); - globGtp.instances[sockfd].ipVersion=6; + globGtp.instances[sockfd].ipVersion=6; } else AssertFatal(false,"Local address is not IPv4 or IPv6"); } @@ -344,7 +386,8 @@ instance_t ocp_gtpv1Init(openAddr_t context) { return id; } -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { +teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t outgoing_teid, + transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { pthread_mutex_lock(&globGtp.gtp_lock); auto inst=&globGtp.instances[instance]; auto it=inst->ue2te_mapping.find(rnti); @@ -354,18 +397,18 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid inst->ue2te_mapping.erase(it); } - uint32_t s1u_teid=gtpv1uNewTeid(); + uint32_t incoming_teid=gtpv1uNewTeid(); - while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { - LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid); - s1u_teid=gtpv1uNewTeid(); + while ( inst->te2ue_mapping.find(incoming_teid) != inst->te2ue_mapping.end() ) { + LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",incoming_teid); + incoming_teid=gtpv1uNewTeid(); }; - inst->te2ue_mapping[s1u_teid].rnti=rnti; + inst->te2ue_mapping[incoming_teid].rnti=rnti; - inst->te2ue_mapping[s1u_teid].rb_id= teid; + inst->te2ue_mapping[incoming_teid].rb_id= outgoing_teid; - inst->te2ue_mapping[s1u_teid].callBack=callBack; + inst->te2ue_mapping[incoming_teid].callBack=callBack; auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id]; @@ -390,12 +433,16 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid default: AssertFatal(false, "SGW Address size impossible"); } - - tmp->teid_incoming = s1u_teid; + + tmp->teid_incoming = incoming_teid; tmp->outgoing_port=port; - tmp->teid_outgoing= teid; + tmp->teid_outgoing= outgoing_teid; pthread_mutex_unlock(&globGtp.gtp_lock); - return s1u_teid; + LOG_I(GTPU, "Created tunnel for RNTI %x, teid for DL: %d, teid for UL %d\n", + rnti, + tmp->teid_incoming, + tmp->teid_outgoing); + return incoming_teid; } int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, @@ -459,20 +506,40 @@ int ocp_gtpv1u_update_s1u_tunnel( return 0; } - int gtpv1u_create_ngu_tunnel( const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP) { - return !GTPNOK; - } - - int gtpv1u_update_ngu_tunnel( - const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const rnti_t prior_rnti - ) { - return GTPNOK; +int gtpv1u_create_ngu_tunnel( const instance_t instance, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req, + gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp) { + LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n", + create_tunnel_req->rnti, + create_tunnel_req->num_tunnels, + create_tunnel_req->upf_NGu_teid[0]); + + for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { + teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, + create_tunnel_req->pdusession_id[i], + create_tunnel_req->upf_NGu_teid[i], + create_tunnel_req->upf_addr[i], 2152, + pdcp_data_req); + create_tunnel_resp->status=0; + create_tunnel_resp->rnti=create_tunnel_req->rnti; + create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; + create_tunnel_resp->gnb_NGu_teid[i]=teid; + memcpy(create_tunnel_resp->gnb_addr.buffer,globGtp.instances[compatInst(instance)].foundAddr, + globGtp.instances[compatInst(instance)].foundAddrLen); + create_tunnel_resp->gnb_addr.length= globGtp.instances[compatInst(instance)].foundAddrLen; } + return !GTPNOK; +} + +int gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +) { + return GTPNOK; +} + int ocp_gtpv1u_create_x2u_tunnel( const instance_t instanceP, const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP, @@ -510,10 +577,10 @@ int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, return newGtpuDeleteTunnel(instance, req_pP->rnti); } - int gtpv1u_delete_x2u_tunnel( const instance_t instanceP, - const gtpv1u_enb_delete_tunnel_req_t * const req_pP, - int enbflag) { - return 0; +int gtpv1u_delete_x2u_tunnel( const instance_t instanceP, + const gtpv1u_enb_delete_tunnel_req_t *const req_pP, + int enbflag) { + return 0; } static int Gtpv1uHandleEchoReq(int h, @@ -546,15 +613,16 @@ static int Gtpv1uHandleSupportedExt(int h, return rc; } - // When end marker arrives, we notify the client with buffer size = 0 - // The client will likely call "delete tunnel" - // nevertheless we don't take the initiative +// When end marker arrives, we notify the client with buffer size = 0 +// The client will likely call "delete tunnel" +// nevertheless we don't take the initiative static int Gtpv1uHandleEndMarker(int h, uint8_t *msgBuf, uint32_t msgBufLen, uint16_t peerPort, uint32_t peerIp) { Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *) msgBuf; + if ( msgHdr->version != 1 || msgHdr->PT != 1 ) { LOG_E(GTPU, "Received a packet that is not GTP header\n"); return GTPNOK; @@ -570,6 +638,7 @@ static int Gtpv1uHandleEndMarker(int h, pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; } + // This context is not good for gtp // frame, ... has no meaning // manyother attributes may come from create tunnel @@ -607,7 +676,7 @@ static int Gtpv1uHandleEndMarker(int h, LOG_D(GTPU,"Received END marker packet for: teid:%x\n", ntohl(msgHdr->teid)); return !GTPNOK; } - + static int Gtpv1uHandleGpdu(int h, uint8_t *msgBuf, uint32_t msgBufLen, @@ -732,8 +801,8 @@ void gtpv1uReceiver(int h) { void *ocp_gtpv1uTask(void *args) { while(1) { /* Trying to fetch a message from the message queue. - If the queue is empty, this function will block till a - message is sent to the task. + If the queue is empty, this function will block till a + message is sent to the task. */ MessageDef *message_p = NULL; itti_receive_msg(OCP_GTPV1_U, &message_p); @@ -750,20 +819,27 @@ void *ocp_gtpv1uTask(void *args) { } break; + case GTPV1U_GNB_TUNNEL_DATA_REQ: { + gtpv1uSend2(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_GNB_TUNNEL_DATA_REQ(message_p), false, false); + itti_free(OCP_GTPV1_U, GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer); + } + break; + case TERMINATE_MESSAGE: break; case TIMER_HAS_EXPIRED: LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p)); break; - - case GTPV1U_ENB_END_MARKER_REQ: - gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), - >PV1U_ENB_TUNNEL_DATA_REQ(message_p)); - itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); - break; - - case GTPV1U_ENB_DATA_FORWARDING_REQ: + + case GTPV1U_ENB_END_MARKER_REQ: + gtpv1uEndTunnel(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_ENB_TUNNEL_DATA_REQ(message_p)); + itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); + break; + + case GTPV1U_ENB_DATA_FORWARDING_REQ: case GTPV1U_ENB_DATA_FORWARDING_IND: case GTPV1U_ENB_END_MARKER_IND: LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); @@ -777,7 +853,7 @@ void *ocp_gtpv1uTask(void *args) { AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n"); break; - case GTPV1U_GNB_NG_REQ: + case GTPV1U_GNB_NG_REQ: // to be dev: should be removed, to use API strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr);