Merge remote-tracking branch 'origin/NR_SA_F1AP_5GRECORDS' into develop-NR_SA_F1AP_5GRECORDS
# Conflicts: # openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c # openair1/PHY/NR_TRANSPORT/nr_ulsch.c # openair1/SIMULATION/NR_PHY/dlsim.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c # openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;aarx<gNB->frame_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++;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "NR_MIB.h"
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "rrc_gNB_UE_context.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
|
||||
|
||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
+126
-50
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user