Merge branch 'integration_2024_w05' into 'develop'

Integration: 2024.w05

See merge request oai/openairinterface5g!2549

* !2537 Fix for UE PUSCH scheduler DURATION_RX_TO_TX assertion
* !2538 Fix for UE MAC PDU LCID handling
* !2542 Fix L1_SSB_CSI_RSRP table mapping and check validity
* !2544 NR UE RRC timers improvement
* !2546 Correcting the location of packages
* !2493 Fix for computing SSB subcarrier offset
* !2496 MCS for retransmission fix in case of dci failed detection at NR UE
* !2503 Handle PDU Sessions in NG Initial UE context Setup and forward 5G-S-TMSI to core
* enable caching in the docker build of the CI build steps
* !2541 Fix RA bug, improve overall logging
This commit is contained in:
Robert Schmidt
2024-02-06 10:14:17 +00:00
51 changed files with 1073 additions and 1085 deletions
+1 -1
View File
@@ -132,7 +132,7 @@ class Cluster:
def _start_build(self, name):
# will return "immediately" but build runs in background
# if multiple builds are started at the same time, this can take some time, however
ret = self.cmd.run(f'oc start-build {name} --from-file={self.eNBSourceCodePath}')
ret = self.cmd.run(f'oc start-build {name} --from-dir={self.eNBSourceCodePath} --exclude=""')
regres = re.search(r'build.build.openshift.io/(?P<jobname>[a-zA-Z0-9\-]+) started', ret.stdout)
if ret.returncode != 0 or ret.stdout.count('Uploading finished') != 1 or regres is None:
logging.error(f"error during oc start-build: {ret.stdout}")
+4 -4
View File
@@ -357,11 +357,11 @@ class Containerize():
if self.host == 'Ubuntu':
self.cli = 'docker'
self.dockerfileprefix = '.ubuntu20'
self.cliBuildOptions = '--no-cache'
self.cliBuildOptions = ''
elif self.host == 'Red Hat':
self.cli = 'sudo podman'
self.dockerfileprefix = '.rhel9'
self.cliBuildOptions = '--no-cache --disable-compression'
self.cliBuildOptions = '--disable-compression'
# we always build the ran-build image with all targets
# Creating a tupple with the imageName, the DockerFile prefix pattern, targetName and sanitized option
@@ -509,7 +509,7 @@ class Containerize():
cmd.run(f"{self.cli} volume prune --force")
# Remove any cached artifacts: we don't use the cache for now, prevent
# out of diskspace problem
cmd.run(f"{self.cli} buildx prune --force")
cmd.run(f"{self.cli} buildx prune --filter=until=6h --force")
# create a zip with all logs
build_log_name = f'build_log_{self.testCase_id}'
@@ -570,7 +570,7 @@ class Containerize():
sys.exit(1)
self.cli = 'docker'
self.cliBuildOptions = '--no-cache'
self.cliBuildOptions = ''
# Workaround for some servers, we need to erase completely the workspace
if self.forcedWorkspaceCleanup:
+2 -2
View File
@@ -992,7 +992,7 @@ class RANManagement():
NSA_RAPROC_PUSCH_check = 1
# Collect information on UE DLSCH and ULSCH statistics
keys = {'dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
keys = {'dlsch_rounds','ulsch_rounds'}
for k in keys:
result = re.search(k, line)
if result is None:
@@ -1161,7 +1161,7 @@ class RANManagement():
dlcheckers = [] if 'd_retx_th' not in checkers else checkers['d_retx_th']
retx_status[ue]['dl'] = self._analyzeUeRetx(dlulstat['dlsch_rounds'], dlcheckers, r'^.*dlsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+dlsch_errors\s+(\d+)')
ulcheckers = [] if 'u_retx_th' not in checkers else checkers['u_retx_th']
retx_status[ue]['ul'] = self._analyzeUeRetx(dlulstat['ulsch_rounds'], ulcheckers, r'^.*ulsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+.*,\s+ulsch_errors\s+(\d+)')
retx_status[ue]['ul'] = self._analyzeUeRetx(dlulstat['ulsch_rounds'], ulcheckers, r'^.*ulsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+ulsch_errors\s+(\d+)')
#real time statistics
+26 -12
View File
@@ -755,11 +755,25 @@ void SLIV2SL(int SLIV,int *S,int *L) {
}
}
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA)
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs)
{
uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA);
const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1;
return ((absolute_diff / scaling_5khz) % 24);
// for FR1 k_SSB expressed in terms of 15kHz SCS
// for FR2 k_SSB expressed in terms of the subcarrier spacing provided by the higher-layer parameter subCarrierSpacingCommon
// absoluteFrequencySSB and absoluteFrequencyPointA are ARFCN
// NR-ARFCN delta frequency is 5kHz if f < 3 GHz, 15kHz for other FR1 freq and 60kHz for FR2
const uint32_t absolute_diff = absoluteFrequencySSB - absoluteFrequencyPointA;
int scaling = 1;
if (absoluteFrequencyPointA < 600000) // correspond to 3GHz
scaling = 3;
if (scs > 2) // FR2
scaling <<= (scs - 2);
int sco_limit = scs == 1 ? 24 : 12;
int subcarrier_offset = (absolute_diff / scaling) % sco_limit;
// 30kHz is the only case where k_SSB is expressed in terms of a different SCS (15kHz)
// the assertion is to avoid having an offset of half a subcarrier
if (scs == 1)
AssertFatal(subcarrier_offset % 2 == 0, "ssb offset %d invalid for scs %d\n", subcarrier_offset, scs);
return subcarrier_offset;
}
uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
@@ -767,16 +781,16 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
int ssbSubcarrierSpacing,
int frequency_range)
{
// offset to pointA is expressed in terms of 15kHz SCS for FR1 and 60kHz for FR2
// only difference wrt NR-ARFCN is delta frequency 5kHz if f < 3 GHz for ARFCN
uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA);
const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1;
int sco = get_ssb_subcarrier_offset(absoluteFrequencySSB, absoluteFrequencyPointA);
const int scs_scaling = frequency_range == FR2 ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
const int scaled_abs_diff = absolute_diff / scaling_5khz;
const int ssb_offset_point_a =
(scaled_abs_diff - sco) / 12
- 10 * scs_scaling; // absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total
AssertFatal(ssb_offset_point_a % scs_scaling == 0, "PRB offset %d can create frequency offset\n", ssb_offset_point_a);
AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco);
const int scaling = frequency_range == FR2 ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
const int scaled_abs_diff = absolute_diff / (scaling_5khz * scaling);
// absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total
const int ssb_offset_point_a = ((scaled_abs_diff / 12) - 10) * scaling;
// Offset to point A needs to be divisible by scaling
AssertFatal(ssb_offset_point_a % scaling == 0, "PRB offset %d not valid for scs %d\n", ssb_offset_point_a, ssbSubcarrierSpacing);
return ssb_offset_point_a;
}
+1 -1
View File
@@ -202,7 +202,7 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
uint32_t absoluteFrequencyPointA,
int ssbSubcarrierSpacing,
int frequency_range);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs);
int get_delay_idx(int delay, int max_delay_comp);
void freq2time(uint16_t ofdm_symbol_size,
+4 -4
View File
@@ -32,7 +32,7 @@
*\param[in] pointer to the BIT_STRING_t object.
*\return the extracted value.
*/
static inline uint8_t BIT_STRING_to_uint8(BIT_STRING_t *asn) {
static inline uint8_t BIT_STRING_to_uint8(const BIT_STRING_t *asn) {
DevCheck ((asn->size == 1), asn->size, 0, 0);
return asn->buf[0] >> asn->bits_unused;
@@ -43,7 +43,7 @@ static inline uint8_t BIT_STRING_to_uint8(BIT_STRING_t *asn) {
*\param[in] pointer to the BIT_STRING_t object.
*\return the extracted value.
*/
static inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
static inline uint16_t BIT_STRING_to_uint16(const BIT_STRING_t *asn) {
uint16_t result = 0;
int index = 0;
@@ -69,7 +69,7 @@ static inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
*\param[in] pointer to the BIT_STRING_t object.
*\return the extracted value.
*/
static inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
static inline uint32_t BIT_STRING_to_uint32(const BIT_STRING_t *asn) {
uint32_t result = 0;
size_t index;
@@ -91,7 +91,7 @@ static inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
*\param[in] pointer to the BIT_STRING_t object.
*\return the extracted value.
*/
static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) {
static inline uint64_t BIT_STRING_to_uint64(const BIT_STRING_t *asn) {
uint64_t result = 0;
size_t index;
int shift;
+6 -4
View File
@@ -56,7 +56,7 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
return 0;
}
void rrc_gNB_trigger_new_bearer(int rnti);
//void rrc_gNB_trigger_new_bearer(int rnti);
int add_bearer(char *buf, int debug, telnet_printfunc_t prnt)
{
int rnti = -1;
@@ -75,12 +75,13 @@ int add_bearer(char *buf, int debug, telnet_printfunc_t prnt)
if (!rrcue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
rrc_gNB_trigger_new_bearer(rnti);
AssertFatal(false, "not implemented\n");
//rrc_gNB_trigger_new_bearer(rnti);
prnt("called rrc_gNB_trigger_new_bearer(%04x)\n", rnti);
return 0;
}
void rrc_gNB_trigger_release_bearer(int rnti);
//void rrc_gNB_trigger_release_bearer(int rnti);
int release_bearer(char *buf, int debug, telnet_printfunc_t prnt)
{
int rnti = -1;
@@ -99,7 +100,8 @@ int release_bearer(char *buf, int debug, telnet_printfunc_t prnt)
if (!rrcue)
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
rrc_gNB_trigger_release_bearer(rnti);
AssertFatal(false, "not implemented\n");
//rrc_gNB_trigger_release_bearer(rnti);
prnt("called rrc_gNB_trigger_release_bearer(%04x)\n", rnti);
return 0;
}
+2 -2
View File
@@ -92,10 +92,10 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n");
}
prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n",
prnt("UE RNTI %04x reestab %d reconfig %d\n",
ue->ue_context.rnti,
ue->ue_context.ue_reestablishment_counter,
ue->ue_context.ue_reconfiguration_after_reestablishment_counter);
ue->ue_context.ue_reconfiguration_counter);
return 0;
}
+2 -2
View File
@@ -40,12 +40,12 @@ RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libsctp1 \
libconfig9 \
iproute2 \
net-tools \
openssl && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libasan5 \
iproute2 \
net-tools \
libubsan1 \
liblapacke; fi' && \
rm -rf /var/lib/apt/lists/*
-4
View File
@@ -1812,10 +1812,6 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
LOG_E(PHY,"%s() DJP - ru->gNB_list ru->num_gNB are not initialized - so do it manually\n", __FUNCTION__);
ru->gNB_list[0] = RC.gNB[0];
ru->num_gNB=1;
//
//
} else {
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
}
}
@@ -239,9 +239,9 @@ typedef struct {
typedef struct
{
uint8_t rv_index;
uint8_t harq_process_id;
uint8_t new_data_indicator;
uint8_t rv_index;
uint8_t harq_process_id;
bool new_data_indicator;
uint32_t tb_size;
uint16_t num_cb;
uint8_t cb_present_and_position[(NFAPI_UE_MAX_NUM_CB+7) / 8];
@@ -455,13 +455,13 @@ typedef struct {
uint8_t rate_matching_ind;
uint8_t zp_csi_rs_trigger;
uint8_t mcs;
uint8_t ndi;
bool new_data_indicator;
uint8_t rv;
uint16_t targetCodeRate;
uint8_t qamModOrder;
uint32_t TBS;
uint8_t tb2_mcs;
uint8_t tb2_ndi;
bool tb2_new_data_indicator;
uint8_t tb2_rv;
uint8_t harq_process_nbr;
vrb_to_prb_mapping_t vrb_to_prb_mapping;
+4 -2
View File
@@ -347,10 +347,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
uint8_t sco = 0;
if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset<24)) ||
((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset<12)) ) {
if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||
((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) {
if (fp->freq_range == nr_FR1)
sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common;
else
sco = config->ssb_table.ssb_subcarrier_offset;
}
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
@@ -104,8 +104,6 @@ typedef struct {
typedef struct {
/// Indicator of first reception
uint8_t first_rx;
/// Last Ndi received for this process on DCI (used for C-RNTI only)
uint8_t Ndi;
/// DLSCH status flag indicating
SCH_status_t status;
/// Transport block size
+8 -1
View File
@@ -304,7 +304,14 @@ static void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
if ((dlsch_config_pdu->dmrs_ports>>i)&0x01) Nl += 1;
}
dlsch0->Nl = Nl;
downlink_harq_process(dlsch0_harq, current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
if (dlsch_config_pdu->new_data_indicator) {
dlsch0_harq->first_rx = true;
dlsch0_harq->DLround = 0;
} else {
dlsch0_harq->first_rx = false;
dlsch0_harq->DLround++;
}
downlink_harq_process(dlsch0_harq, current_harq_pid, dlsch_config_pdu->new_data_indicator, dlsch_config_pdu->rv, dlsch0->rnti_type);
if (dlsch0_harq->status != ACTIVE) {
// dlsch0_harq->status not ACTIVE due to false retransmission
// Reset the following flag to skip PDSCH procedures in that case and retrasmit harq status
+2 -26
View File
@@ -115,7 +115,6 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
dl_harq->status = SCH_IDLE;
dl_harq->first_rx = 1;
dl_harq->DLround = 0;
dl_harq->Ndi = 2; // set to an invalid value
dl_harq->ack = DL_ACKNACK_NO_SET;
}
@@ -152,32 +151,9 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dci_ndi,
rv,
dci_ndi,
rnti_type,
dl_harq->Ndi != dci_ndi ? "yes" : "no");
dci_ndi ? "yes" : "no");
AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
if (dci_ndi!=dl_harq->Ndi) {
if (dl_harq->ack == DL_NACK)
LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
else
LOG_D(PHY,"Starting new transmission on a harq pid (%d)\n", harq_pid);
} else {
if (dl_harq->ack != DL_NACK)
LOG_D(PHY,"gNB asked for retransmission even if we sent ACK\n");
else
LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
}
if (dci_ndi!=dl_harq->Ndi) {
dl_harq->first_rx = true;
dl_harq->DLround = 0;
} else {
dl_harq->first_rx = false;
dl_harq->DLround++;
}
dl_harq->status = ACTIVE;
dl_harq->Ndi = dci_ndi;
//dl_harq->status = SCH_IDLE;
}
}
}
+2 -2
View File
@@ -665,7 +665,7 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1);
ieC6_1_1->dRB_ID = j->id;
ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB;
ieC6_1_1->sDAP_Configuration.defaultDRB = j->defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false;
ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL;
ieC6_1_1->sDAP_Configuration.sDAP_Header_DL = j->sDAP_Header_DL;
@@ -971,7 +971,7 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
drb->id = drb2Setup->dRB_ID;
drb->defaultDRB = drb2Setup->sDAP_Configuration.defaultDRB;
drb->defaultDRB = drb2Setup->sDAP_Configuration.defaultDRB == E1AP_DefaultDRB_true;
drb->sDAP_Header_UL = drb2Setup->sDAP_Configuration.sDAP_Header_UL;
drb->sDAP_Header_DL = drb2Setup->sDAP_Configuration.sDAP_Header_DL;
+1 -1
View File
@@ -480,7 +480,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t search_space_frame_period; // in slots
uint32_t ssb_length;
uint32_t ssb_index;
uint32_t cset_start_rb;
int32_t cset_start_rb;
NR_SubcarrierSpacing_t scs_pdcch;
bool active;
} NR_Type0_PDCCH_CSS_config_t;
@@ -4443,6 +4443,8 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
AssertFatal(type0_PDCCH_CSS_config->cset_start_rb >= 0, "Invalid CSET0 start PRB %d SSB offset point A %d RB offset %d\n",
type0_PDCCH_CSS_config->cset_start_rb, ssb_offset_point_a, type0_PDCCH_CSS_config->rb_offset);
}
void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
+2 -2
View File
@@ -348,11 +348,13 @@ typedef struct {
int8_t delta_pucch;
uint32_t R;
uint32_t TBS;
int last_ndi;
} NR_UE_HARQ_STATUS_t;
typedef struct {
uint32_t R;
uint32_t TBS;
int last_ndi;
} NR_UL_HARQ_INFO_t;
typedef struct {
@@ -499,8 +501,6 @@ typedef struct NR_UE_MAC_INST_s {
/// measurements from CSI-RS
fapi_nr_csirs_measurements_t csirs_measurements;
/// Last NDI of UL HARQ processes
int UL_ndi[NR_MAX_HARQ_PROCESSES];
//// FAPI-like interface message
fapi_nr_ul_config_request_t *ul_config_request;
fapi_nr_dl_config_request_t *dl_config_request;
+8 -4
View File
@@ -74,6 +74,10 @@ void nr_ue_init_mac(module_id_t module_idP)
memset(&mac->ssb_list[i], 0, sizeof(mac->ssb_list[i]));
memset(&mac->prach_assoc_pattern[i], 0, sizeof(mac->prach_assoc_pattern[i]));
}
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
}
}
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
@@ -100,8 +104,6 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
mac->scheduling_info.lc_sched_info[i].LCGID = 0; // defaults to 0 irrespective of SRB or DRB
mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY;
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
mac->UL_ndi[k] = -1; // initialize to invalid value
}
}
@@ -142,6 +144,7 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
// MAC reset according to 38.321 Section 5.12
nr_ue_mac_default_configs(nr_mac);
// initialize Bj for each logical channel to zero
// Done in default config but to -1 (is that correct?)
@@ -153,7 +156,7 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
// set the NDIs for all uplink HARQ processes to the value 0
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
nr_mac->UL_ndi[k] = -1; // initialize to invalid value
nr_mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
// stop any ongoing RACH procedure
if (nr_mac->ra.ra_state < RA_SUCCEEDED)
@@ -179,7 +182,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
memset(&nr_mac->dl_harq_info[k], 0, sizeof(NR_UE_HARQ_STATUS_t));
// for each DL HARQ process, consider the next received transmission for a TB as the very first transmission
// TODO there is nothing in the MAC indicating first transmission
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
nr_mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
// release, if any, Temporary C-RNTI
nr_mac->ra.t_crnti = 0;
+53 -12
View File
@@ -681,13 +681,30 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id,
/* MCS */
dlsch_pdu->mcs = dci->mcs;
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid];
/* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
if (dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH ||
dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH ||
dci->ndi != current_harq->last_ndi) {
// new data
dlsch_pdu->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
}
else
dlsch_pdu->new_data_indicator = false;
if (dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH &&
dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH) {
current_harq->last_ndi = dci->ndi;
}
dlsch_pdu->qamModOrder = nr_get_Qm_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (dlsch_pdu->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid];
int R = nr_get_code_rate_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (R > 0) {
dlsch_pdu->targetCodeRate = R;
@@ -707,6 +724,11 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id,
1);
// storing for possible retransmissions
current_harq->R = dlsch_pdu->targetCodeRate;
if (!dlsch_pdu->new_data_indicator && current_harq->TBS != dlsch_pdu->TBS) {
LOG_W(NR_MAC, "NDI indicates re-transmission but computed TBS %d doesn't match with what previously stored %d\n",
dlsch_pdu->TBS, current_harq->TBS);
dlsch_pdu->new_data_indicator = true; // treated as new data
}
current_harq->TBS = dlsch_pdu->TBS;
}
else {
@@ -716,11 +738,14 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id,
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
if (dlsch_pdu->TBS == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
return -1;
}
int bw_tbslbrm = current_DL_BWP ? mac->sc_info.dl_bw_tbslbrm : dlsch_pdu->BWPSize;
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, bw_tbslbrm, 1);
/* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
dlsch_pdu->ndi = dci->ndi;
/* RV (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
dlsch_pdu->rv = dci->rv;
/* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
@@ -801,7 +826,7 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id,
"scaling_factor_S=%f\n>>> tpc_pucch=%d\n>>> pucch_res_ind=%d\n>>> pdsch_to_harq_feedback_time_ind=%d\n",
dlsch_pdu->vrb_to_prb_mapping,
dlsch_pdu->mcs,
dlsch_pdu->ndi,
dlsch_pdu->new_data_indicator,
dlsch_pdu->rv,
dlsch_pdu->harq_process_nbr,
dci->dai[0].val,
@@ -961,13 +986,23 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
/* MCS (for transport block 1)*/
dlsch_pdu->mcs = dci->mcs;
/* NDI (for transport block 1)*/
dlsch_pdu->ndi = dci->ndi;
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid];
if (dci->ndi != current_harq->last_ndi) {
// new data
dlsch_pdu->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
}
else {
dlsch_pdu->new_data_indicator = false;
}
current_harq->last_ndi = dci->ndi;
/* RV (for transport block 1)*/
dlsch_pdu->rv = dci->rv;
/* MCS (for transport block 2)*/
dlsch_pdu->tb2_mcs = dci->mcs2.val;
/* NDI (for transport block 2)*/
dlsch_pdu->tb2_ndi = dci->ndi2.val;
dlsch_pdu->tb2_new_data_indicator = dci->ndi2.val;
/* RV (for transport block 2)*/
dlsch_pdu->tb2_rv = dci->rv2.val;
/* HARQ_PROCESS_NUMBER */
@@ -1124,7 +1159,6 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
nb_rb_oh = 0;
int nb_re_dmrs = ((dmrs_type == NULL) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups;
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid];
int R = nr_get_code_rate_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (R > 0) {
dlsch_pdu->targetCodeRate = R;
@@ -1137,6 +1171,11 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
0,
Nl);
// storing for possible retransmissions
if (!dlsch_pdu->new_data_indicator && current_harq->TBS != dlsch_pdu->TBS) {
LOG_W(NR_MAC, "NDI indicates re-transmission but computed TBS %d doesn't match with what previously stored %d\n",
dlsch_pdu->TBS, current_harq->TBS);
dlsch_pdu->new_data_indicator = true; // treated as new data
}
current_harq->R = dlsch_pdu->targetCodeRate;
current_harq->TBS = dlsch_pdu->TBS;
}
@@ -1147,6 +1186,11 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
if (dlsch_pdu->TBS == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
return -1;
}
// TBS_LBRM according to section 5.4.2.1 of 38.212
AssertFatal(sc_info->maxMIMO_Layers_PDSCH != NULL, "Option with max MIMO layers not configured is not supported\n");
int nl_tbslbrm = *sc_info->maxMIMO_Layers_PDSCH < 4 ? *sc_info->maxMIMO_Layers_PDSCH : 4;
@@ -3733,11 +3777,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
// end of MAC PDU, can ignore the rest.
break;
// MAC SDU
case DL_SCH_LCID_DCCH:
// check if LCID is valid at current time.
case DL_SCH_LCID_DCCH1:
// check if LCID is valid at current time.
case DL_SCH_LCID_DTCH ... (DL_SCH_LCID_DTCH + 28):
// From values 1 to 32 it equals to the identity of the logical channel
case 1 ... 32:
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
return;
LOG_D(NR_MAC, "%4d.%2d : DLSCH -> LCID %d %d bytes\n", frameP, slot, rx_lcid, mac_len);
+22 -9
View File
@@ -656,8 +656,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
}
/* NDI */
pusch_config_pdu->pusch_data.new_data_indicator = dci->ndi != mac->UL_ndi[dci->harq_pid] ? 1 : 0;
mac->UL_ndi[dci->harq_pid] = dci->ndi;
NR_UL_HARQ_INFO_t *harq = &mac->ul_harq_info[dci->harq_pid];
pusch_config_pdu->pusch_data.new_data_indicator = false;
if (dci->ndi != harq->last_ndi) {
pusch_config_pdu->pusch_data.new_data_indicator = true;
// if new data reset harq structure
memset(harq, 0, sizeof(*harq));
}
harq->last_ndi = dci->ndi;
/* RV */
pusch_config_pdu->pusch_data.rv_index = dci->rv;
/* HARQ_PROCESS_NUMBER */
@@ -768,7 +774,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->target_code_rate = mac->ul_harq_info[pid].R;
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
}
pusch_config_pdu->ldpcBaseGraph = get_BG(pusch_config_pdu->pusch_data.tb_size << 3, pusch_config_pdu->target_code_rate);
if (pusch_config_pdu->pusch_data.tb_size == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
return -1;
}
return 0;
}
@@ -1454,13 +1467,6 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
int *slot_tx,
const long k2)
{
AssertFatal(k2 > DURATION_RX_TO_TX,
"Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n",
k2,
DURATION_RX_TO_TX,
DURATION_RX_TO_TX,
DURATION_RX_TO_TX);
int delta = 0;
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
@@ -1505,6 +1511,13 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
} else {
AssertFatal(k2 > DURATION_RX_TO_TX,
"Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n",
k2,
DURATION_RX_TO_TX,
DURATION_RX_TO_TX,
DURATION_RX_TO_TX);
if (k2 < 0) { // This can happen when a false DCI is received
LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2);
return -1;
+2 -1
View File
@@ -639,7 +639,8 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
cfg->num_tlv++;
cfg->ssb_table.ssb_subcarrier_offset.value =
get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->ssbSubcarrierSpacing);
AssertFatal(cfg->ssb_table.ssb_subcarrier_offset.value < 16,
"cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA "
+12 -6
View File
@@ -688,7 +688,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
}
NR_SCHED_UNLOCK(&nr_mac->sched_lock);
LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d %4d.%2d initiating RA procedure for preamble index %d: no free RA process\n", module_idP, CC_id, frameP, slotP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
@@ -768,8 +768,14 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
return;
}
LOG_I(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n",
module_idP, frame, slot, CC_id, sched_frame, sched_slot);
LOG_I(NR_MAC,
"%4d%2d: RA RNTI %04x CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n",
frame,
slot,
ra->rnti,
CC_id,
sched_frame,
sched_slot);
buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[CC_id][buffer_index];
@@ -1253,7 +1259,8 @@ static void nr_generate_Msg2(module_id_t module_idP,
true);
if (CCEIndex < 0) {
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti);
LOG_E(NR_MAC, "cannot find free CCE for Msg2 of RA RNTI 0x%04x!\n", ra->rnti);
nr_clear_ra_proc(module_idP, CC_id, frameP, ra);
return;
}
@@ -1455,7 +1462,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
}
ra->state = WAIT_Msg3;
LOG_W(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %d\n", module_idP, frameP, slotP, ra->rnti, ra->state);
LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %d\n", module_idP, frameP, slotP, ra->rnti, ra->state);
}
}
@@ -1698,7 +1705,6 @@ static void nr_generate_Msg4(module_id_t module_idP,
// Need to wait until data for Msg4 is ready
if (srb_status.bytes_in_buffer == 0)
return;
LOG_I(NR_MAC, "(%4d.%2d) SRB%d has %d bytes\n", frameP, slotP, lcid, srb_status.bytes_in_buffer);
mac_sdu_length = srb_status.bytes_in_buffer;
}
@@ -2376,8 +2376,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
{
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
NR_UEs_t *UE_info = &nr_mac->UE_info;
LOG_I(NR_MAC, "Adding UE with rnti 0x%04x\n",
rntiP);
LOG_I(NR_MAC, "Adding new UE context with RNTI 0x%04x\n", rntiP);
dump_nr_list(UE_info->list);
// We will attach at the end, to mitigate race conditions
@@ -2851,11 +2850,11 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo
static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t frame, sub_frame_t slot)
{
LOG_I(NR_MAC, "%4d.%2d RNTI %04x: RRC processing timer expired\n", frame, slot, UE->rnti);
LOG_D(NR_MAC, "%4d.%2d RNTI %04x: RRC processing timer expired\n", frame, slot, UE->rnti);
/* check if there is a new CellGroupConfig to be applied */
if (UE->apply_cellgroup && UE->reconfigCellGroup != NULL) {
LOG_I(NR_MAC, "%4d.%2d RNTI %04x: Apply CellGroupConfig after RRC processing timer expiry\n", frame, slot, UE->rnti);
LOG_D(NR_MAC, "%4d.%2d RNTI %04x: Apply CellGroupConfig after RRC processing timer expiry\n", frame, slot, UE->rnti);
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
UE->CellGroup = UE->reconfigCellGroup;
UE->reconfigCellGroup = NULL;
@@ -2911,7 +2910,7 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b
// frames, after RRC processing timer.
UE->UE_sched_ctrl.ta_frame = (mac->frame - 1 + 1024) % 1024;
LOG_I(NR_MAC, "%4d.%2d UE %04x: Activate RRC processing timer (%d ms)\n", mac->frame, mac->slot, UE->rnti, delay);
LOG_D(NR_MAC, "%4d.%2d UE %04x: Activate RRC processing timer (%d ms)\n", mac->frame, mac->slot, UE->rnti, delay);
return 0;
}
@@ -3092,7 +3091,7 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct
/* to trigger only once: trigger when ul_failure_timer == 1, but timer will
* stop at 0 and we wait for a UE release command from upper layers */
if (sched_ctrl->ul_failure_timer == 1) {
LOG_W(MAC, "request release after UL failure timer expiry\n");
LOG_W(MAC, "UE %04x: request release after UL failure timer expiry\n", rnti);
f1_ue_data_t ue_data = du_get_f1_ue_data(rnti);
f1ap_ue_context_release_req_t request = {
.gNB_CU_ue_id = ue_data.secondary_ue,
+24 -9
View File
@@ -96,6 +96,7 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
}
#define MIN_RSRP_VALUE -141
#define MAX_RSRP_VALUE -43
#define MAX_NUM_SSB 128
#define MAX_SSB_SCHED 8
#define L1_RSRP_HYSTERIS 10 //considering 10 dBm as hysterisis for avoiding frequent SSB Beam Switching. !Fixme provide exact value if any
@@ -109,7 +110,7 @@ int ssb_rsrp_sorted[MAX_NUM_SSB] = {0};
//stored -1 for invalid values
static const int L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 9
-1, -1, -1, -1, -1, -1, INT_MIN, -140, -139, -138, // 10 - 19
-1, -1, -1, -1, -1, -1, MIN_RSRP_VALUE, -140, -139, -138, // 10 - 19
-137, -136, -135, -134, -133, -132, -131, -130, -129, -128, // 20 - 29
-127, -126, -125, -124, -123, -122, -121, -120, -119, -118, // 30 - 39
-117, -116, -115, -114, -113, -112, -111, -110, -109, -108, // 40 - 49
@@ -119,7 +120,7 @@ static const int L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[128] = {
-77, -76, -75, -74, -73, -72, -71, -70, -69, -68, // 80 - 89
-67, -66, -65, -64, -63, -62, -61, -60, -59, -58, // 90 - 99
-57, -56, -55, -54, -53, -52, -51, -50, -49, -48, // 100 - 109
-47, -46, -45, -44, INT_MAX, -1, -1, -1, -1, -1, // 110 - 119
-47, -46, -45, -44, MAX_RSRP_VALUE, -1, -1, -1, -1, -1, // 110 - 119
-1, -1, -1, -1, -1, -1, -1, -1 // 120 - 127
};
@@ -455,13 +456,16 @@ static int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *
}
//returns the measured RSRP value (upper limit)
static int get_measured_rsrp(uint8_t index)
static bool get_measured_rsrp(uint8_t index, int *rsrp)
{
//if index is invalid returning minimum rsrp -140
if(index <= 15 || index >= 114)
return MIN_RSRP_VALUE;
if (index <= 15)
return false;
if (index >= 114)
return false;
return L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index];
*rsrp = L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index];
return true;
}
//returns the differential RSRP value (upper limit)
@@ -477,7 +481,6 @@ static int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
//handles triggering of PDCCH and PDSCH MAC CEs
static void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot)
{
int strongest_ssb_rsrp = 0;
int cqi_idx = 0;
int curr_ssb_beam_index = 0; //ToDo: yet to know how to identify the serving ssb beam index
uint8_t target_ssb_beam_index = curr_ssb_beam_index;
@@ -520,7 +523,13 @@ static void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot)
}
//if strongest measured RSRP is configured
strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
int strongest_ssb_rsrp;
int rsrp_index = sched_ctrl->CSI_report.ssb_cri_report.RSRP;
bool valid = get_measured_rsrp(rsrp_index, &strongest_ssb_rsrp);
if (!valid) {
LOG_E(NR_MAC, "UE %04x: reported RSRP index %d invalid\n", UE->rnti, rsrp_index);
return;
}
ssb_rsrp[idx * nb_of_csi_ssb_report] = strongest_ssb_rsrp;
LOG_D(NR_MAC,"ssb_rsrp = %d\n",strongest_ssb_rsrp);
@@ -717,7 +726,13 @@ static void evaluate_rsrp_report(NR_UE_info_t *UE,
*cumul_bits += 4;
}
csi_report->nb_of_csi_ssb_report++;
int strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
int strongest_ssb_rsrp;
int rsrp_index = sched_ctrl->CSI_report.ssb_cri_report.RSRP;
bool valid = get_measured_rsrp(rsrp_index, &strongest_ssb_rsrp);
if (!valid) {
LOG_E(NR_MAC, "UE %04x: reported RSRP index %d invalid\n", UE->rnti, rsrp_index);
return;
}
NR_mac_stats_t *stats = &UE->mac_stats;
// including ssb rsrp in mac stats
stats->cumul_rsrp += strongest_ssb_rsrp;
@@ -377,7 +377,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
mac_len = 6;
}
LOG_W(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti);
LOG_D(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti);
prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE);
mac_rlc_data_ind(module_idP,
@@ -509,7 +509,7 @@ void handle_nr_ul_harq(const int CC_idP,
bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(nrmac, CC_idP, frame, slot);
if (!UE || UE_waiting_CFRA_msg3 == true) {
LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
LOG_D(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i];
if (ra->state >= WAIT_Msg3 && ra->rnti == crc_pdu->rnti) {
@@ -518,7 +518,7 @@ void handle_nr_ul_harq(const int CC_idP,
}
}
NR_SCHED_UNLOCK(&nrmac->sched_lock);
LOG_E(NR_MAC, "%s(): unknown RNTI 0x%04x in PUSCH\n", __func__, crc_pdu->rnti);
LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/PUSCH\n", crc_pdu->rnti);
return;
}
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -676,9 +676,11 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
}
if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt);
nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
LOG_W(NR_MAC,
"UE %04x: Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
UE->rnti,
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt);
nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
}
}
} else if(sduP) {
@@ -792,7 +794,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented
mac_remove_nr_ue(gNB_mac, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg.3 to have UE come back with new RA attempt\n", ra->rnti);
LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti);
return;
} else {
// Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration
@@ -260,7 +260,7 @@ static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ct
f1ap_drb_to_be_setup_t *drb_p = &req->drbs_to_be_setup[i];
uint8_t nb_qos_flows = drb_p->drb_info.flows_to_be_setup_length;
long drb_id = drb_p->drb_id;
LOG_I(NR_MAC, "In %s: number of QOS flows mapped to DRB_id %d: %ld \n", __func__, drb_count, drb_id);
LOG_I(NR_MAC, "number of QOS flows mapped to DRB_id %ld: %d\n", drb_id, nb_qos_flows);
for (int q = 0; q < nb_qos_flows; q++) {
f1ap_flows_mapped_to_drb_t *qos_flow = &drb_p->drb_info.flows_mapped_to_drb[q];
@@ -338,9 +338,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
UE->capability = ue_cap;
if (ue_cap != NULL) {
// store the new UE capabilities, and update the cellGroupConfig
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
UE->capability = ue_cap;
LOG_I(NR_MAC, "UE %04x: received capabilities, updating CellGroupConfig\n", UE->rnti);
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc);
}
@@ -69,7 +69,6 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
{
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
AssertFatal(req->drbs_to_be_setup_length == 0, "not implemented\n");
(void) req; /* we don't need the request -- it is to set up GTP in F1 case */
MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
@@ -85,6 +84,13 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req,
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
}
if (resp->drbs_to_be_setup_length > 0) {
DevAssert(resp->drbs_to_be_setup != NULL);
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
}
f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
+7 -1
View File
@@ -103,7 +103,6 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
{
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
AssertFatal(req->drbs_to_be_setup_length == 0, "not implmented\n");
DevAssert(req->srbs_to_be_setup_length == resp->srbs_to_be_setup_length);
MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
@@ -118,6 +117,13 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
}
if (resp->drbs_to_be_setup_length > 0) {
DevAssert(resp->drbs_to_be_setup != NULL);
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
}
f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
+19 -14
View File
@@ -85,7 +85,6 @@ void clear_mac_stats(gNB_MAC_INST *gNB) {
size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp)
{
int num = 1;
const char *begin = output;
const char *end = output + strlen;
@@ -99,11 +98,19 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
NR_mac_stats_t *stats = &UE->mac_stats;
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
output += snprintf(output, end - output, "UE RNTI %04x CU-UE-ID ", UE->rnti);
if (du_exists_f1_ue_data(UE->rnti)) {
f1_ue_data_t ued = du_get_f1_ue_data(UE->rnti);
output += snprintf(output, end - output, "%d", ued.secondary_ue);
} else {
output += snprintf(output, end-output, "(none)");
}
bool in_sync = !sched_ctrl->ul_failure;
output += snprintf(output,
end - output,
"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
UE->rnti,
num++,
" %s PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
in_sync ? "in-sync" : "out-of-sync",
sched_ctrl->ph,
sched_ctrl->pcmax,
avg_rsrp,
@@ -132,19 +139,16 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
output += snprintf(output,
end - output,
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS (%d) %d\n",
stats->dl.errors,
stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler,
UE->current_DL_BWP.mcsTableIdx,
sched_ctrl->dl_bler_stats.mcs);
if (reset_rsrp) {
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0;
}
output += snprintf(output,
end - output,
"UE %04x: dlsch_total_bytes %"PRIu64"\n",
UE->rnti, stats->dl.total_bytes);
output += snprintf(output,
end - output,
"UE %04x: ulsch_rounds ", UE->rnti);
@@ -154,16 +158,17 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
output += snprintf(output,
end - output,
", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
stats->ulsch_DTX,
", ulsch_errors %"PRIu64", ulsch_DTX %d, BLER %.5f MCS (%d) %d\n",
stats->ul.errors,
stats->ulsch_DTX,
sched_ctrl->ul_bler_stats.bler,
UE->current_UL_BWP.mcs_table,
sched_ctrl->ul_bler_stats.mcs);
output += snprintf(output,
end - output,
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
UE->rnti,
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
"UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes);
for (int i = 0; i < sched_ctrl->dl_lc_num; i++) {
int lc_id = sched_ctrl->dl_lc_ids[i];
+4 -2
View File
@@ -184,8 +184,8 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
sdap_data_req,
&resp_n3);
AssertFatal(ret >= 0, "Unable to create GTP Tunnel for NG-U\n");
AssertFatal(resp_n3.num_tunnels == req->numPDUSessions, "could not create all tunnels\n");
resp_pdu->teId = resp_n3.gnb_NGu_teid[i];
AssertFatal(resp_n3.num_tunnels == req_pdu->numDRB2Setup, "could not create all tunnels\n");
resp_pdu->teId = resp_n3.gnb_NGu_teid[0];
memcpy(&resp_pdu->tlAddress, &resp_n3.gnb_addr.buffer, 4);
// create PDCP bearers. This will also create SDAP bearers
@@ -240,6 +240,7 @@ void e1_bearer_context_modif(const e1ap_bearer_setup_req_t *req)
instance_t f1inst = get_f1_gtp_instance();
for (int i=0; i < req->numPDUSessionsMod; i++) {
DevAssert(req->pduSessionMod[i].sessionId > 0);
LOG_I(E1AP,
"UE %d: updating PDU session ID %ld (%ld bearers)\n",
req->gNB_cu_up_ue_id,
@@ -278,6 +279,7 @@ void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd)
if (f1inst >= 0) // is there F1-U?
newGtpuDeleteAllTunnels(f1inst, cmd->gNB_cu_up_ue_id);
nr_pdcp_remove_UE(cmd->gNB_cu_up_ue_id);
nr_sdap_delete_ue_entities(cmd->gNB_cu_up_ue_id);
if (need_ue_id_mgmt) {
cu_remove_f1_ue_data(cmd->gNB_cu_up_ue_id);
}
+2 -1
View File
@@ -925,7 +925,7 @@ void add_drb(int is_gnb,
has_integrity ? integrity_key : NULL);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid);
new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, UEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount);
}
@@ -1193,6 +1193,7 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
drb->release_entity(drb);
drb->delete_entity(drb);
ue->drb[drb_id - 1] = NULL;
LOG_I(PDCP, "release DRB %d of UE %ld\n", drb_id, ue_id);
}
else
LOG_E(PDCP, "Attempting to release DRB%d but it is not configured\n", drb_id);
+1 -1
View File
@@ -77,7 +77,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info)
bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7);
if (UL_info->rach_ind.number_of_pdus > 0 && in_timewindow) {
LOG_A(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",
UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot);
for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) {
UL_info->rach_ind.number_of_pdus--;
+14 -2
View File
@@ -51,8 +51,20 @@ static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_c
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
*f1ap_msg = *req;
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
AssertFatal(req->drbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n");
AssertFatal(req->srbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n");
if (req->drbs_to_be_setup_length > 0) {
int n = req->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup_length = n;
f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup));
AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n");
memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup));
}
if (req->srbs_to_be_setup_length > 0) {
int n = req->srbs_to_be_setup_length;
f1ap_msg->srbs_to_be_setup_length = n;
f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup));
AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n");
memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup));
}
if (req->rrc_container_length > 0) {
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
+2 -1
View File
@@ -1768,7 +1768,8 @@ NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc)
int ssb_subcarrier_offset = 31; // default value for NSA
if (get_softmodem_params()->sa) {
ssb_subcarrier_offset = get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->ssbSubcarrierSpacing);
}
mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset & 15;
+9 -14
View File
@@ -224,6 +224,7 @@ typedef struct drb_s {
} drb_t;
typedef enum {
RRC_ACTION_NONE, /* no transaction ongoing */
RRC_SETUP,
RRC_SETUP_FOR_REESTABLISHMENT,
RRC_REESTABLISH,
@@ -232,12 +233,12 @@ typedef enum {
RRC_DEDICATED_RECONF,
RRC_PDUSESSION_ESTABLISH,
RRC_PDUSESSION_MODIFY,
RRC_PDUSESSION_RELEASE
RRC_PDUSESSION_RELEASE,
RRC_UECAPABILITY_ENQUIRY,
} rrc_action_t;
typedef struct gNB_RRC_UE_s {
drb_t established_drbs[MAX_DRBS_PER_UE];
uint8_t DRB_active[MAX_DRBS_PER_UE];
NR_DRB_ToReleaseList_t *DRB_ReleaseList;
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
@@ -245,6 +246,8 @@ typedef struct gNB_RRC_UE_s {
NR_HANDOVER_INFO *handover_info;
NR_MeasResults_t *measResults;
bool as_security_active;
byte_array_t ue_cap_buffer;
NR_UE_NR_Capability_t* UE_Capability_nr;
int UE_Capability_size;
@@ -275,12 +278,8 @@ typedef struct gNB_RRC_UE_s {
/* Information from UE RRC Setup Request */
NR_UE_S_TMSI Initialue_identity_5g_s_TMSI;
uint64_t ng_5G_S_TMSI_Part1;
uint16_t ng_5G_S_TMSI_Part2;
NR_EstablishmentCause_t establishment_cause;
/* Information from UE RRCReestablishmentRequest */
NR_ReestablishmentCause_t reestablishment_cause;
uint32_t rrc_ue_id;
uint64_t amf_ue_ngap_id;
nr_rrc_guami_t ue_guami;
@@ -303,19 +302,15 @@ typedef struct gNB_RRC_UE_s {
uint8_t e_rab_release_command_flag;
uint32_t ue_rrc_inactivity_timer;
uint32_t ue_reestablishment_counter;
uint32_t ue_reconfiguration_after_reestablishment_counter;
NR_CellGroupId_t cellGroupId;
uint32_t ue_reconfiguration_counter;
struct NR_SpCellConfig *spCellConfig;
struct NR_CellGroupConfig__sCellToAddModList *sCellconfig;
struct NR_CellGroupConfig__sCellToReleaseList *sCellconfigRelease;
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_BearerBonfig;
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_BearerRelease;
struct NR_MAC_CellGroupConfig *mac_CellGroupConfig;
struct NR_PhysicalCellGroupConfig *physicalCellGroupConfig;
/* Nas Pdu */
ngap_pdu_t nas_pdu;
/* hack, see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() for more info */
int max_delays_pdu_session;
} gNB_RRC_UE_t;
typedef struct rrc_gNB_ue_context_s {
+4 -1
View File
@@ -81,7 +81,9 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2
void
rrc_gNB_generate_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs
);
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
@@ -125,6 +127,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP);
bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd);
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req);
+450 -647
View File
File diff suppressed because it is too large Load Diff
+178 -151
View File
@@ -145,11 +145,6 @@ nr_rrc_pdcp_config_security(
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc);
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint);
if (!IS_SOFTMODEM_IQPLAYER) {
SET_LOG_DUMP(DEBUG_SECURITY) ;
}
if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) {
if (print_keys == 1 ) {
print_keys =0;
@@ -201,10 +196,13 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
/* Fill UE identities with available information */
req->ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE;
/* Fill s-TMSI */
req->ue_identity.s_tmsi.amf_set_id = UE->Initialue_identity_5g_s_TMSI.amf_set_id;
req->ue_identity.s_tmsi.amf_pointer = UE->Initialue_identity_5g_s_TMSI.amf_pointer;
req->ue_identity.s_tmsi.m_tmsi = UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi;
if (UE->Initialue_identity_5g_s_TMSI.presence) {
/* Fill s-TMSI */
req->ue_identity.presenceMask = NGAP_UE_IDENTITIES_FiveG_s_tmsi;
req->ue_identity.s_tmsi.amf_set_id = UE->Initialue_identity_5g_s_TMSI.amf_set_id;
req->ue_identity.s_tmsi.amf_pointer = UE->Initialue_identity_5g_s_TMSI.amf_pointer;
req->ue_identity.s_tmsi.m_tmsi = UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi;
}
/* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */
int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1;
@@ -359,6 +357,109 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
return 0;
}
static void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink)
{
e1ap_bearer_setup_req_t bearer_req = {0};
e1ap_nssai_t cuup_nssai = {0};
for (int i = 0; i < n; i++) {
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, sessions[i].pdusession_id, true);
pdusession_t *session = &pduSession->param;
session->pdusession_id = sessions[i].pdusession_id;
LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions);
session->pdu_session_type = sessions[i].pdu_session_type;
session->nas_pdu = sessions[i].nas_pdu;
session->pdusessionTransfer = sessions[i].pdusessionTransfer;
session->nssai = sessions[i].nssai;
decodePDUSessionResourceSetup(session);
bearer_req.gNB_cu_cp_ue_id = UE->rrc_ue_id;
bearer_req.cipheringAlgorithm = UE->ciphering_algorithm;
bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey);
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, (uint8_t *)bearer_req.integrityProtectionKey);
bearer_req.ueDlAggMaxBitRate = ueAggMaxBitRateDownlink;
pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions;
bearer_req.numPDUSessions++;
pdu->sessionId = session->pdusession_id;
pdu->nssai = sessions[i].nssai;
if (cuup_nssai.sst == 0)
cuup_nssai = pdu->nssai; /* for CU-UP selection below */
pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
pdu->teId = session->gtp_teid;
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
/* we assume for the moment one DRB per PDU session. Activate the bearer,
* and configure in RRC. */
int drb_id = get_next_available_drb_id(UE);
drb_t *rrc_drb = generateDRB(UE,
drb_id,
pduSession,
rrc->configuration.enable_sdap,
rrc->security.do_drb_integrity,
rrc->security.do_drb_ciphering);
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
for (int j=0; j < pdu->numDRB2Setup; j++) {
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
drb->id = rrc_drb->drb_id;
struct sdap_config_s *sdap_config = &rrc_drb->cnAssociation.sdap_config;
drb->defaultDRB = sdap_config->defaultDRB;
drb->sDAP_Header_UL = sdap_config->sdap_HeaderUL;
drb->sDAP_Header_DL = sdap_config->sdap_HeaderDL;
struct pdcp_config_s *pdcp_config = &rrc_drb->pdcp_config;
drb->pDCP_SN_Size_UL = pdcp_config->pdcp_SN_SizeUL;
drb->pDCP_SN_Size_DL = pdcp_config->pdcp_SN_SizeDL;
drb->discardTimer = pdcp_config->discardTimer;
drb->reorderingTimer = pdcp_config->t_Reordering;
drb->rLC_Mode = rrc->configuration.um_on_default_drb ? E1AP_RLC_Mode_rlc_um_bidirectional : E1AP_RLC_Mode_rlc_am;
drb->numCellGroups = 1; // assume one cell group associated with a DRB
for (int k=0; k < drb->numCellGroups; k++) {
cell_group_t *cellGroup = drb->cellGroupList + k;
cellGroup->id = 0; // MCG
}
drb->numQosFlow2Setup = session->nb_qos;
for (int k=0; k < drb->numQosFlow2Setup; k++) {
qos_flow_to_setup_t *qos_flow = drb->qosFlows + k;
pdusession_level_qos_parameter_t *qos_session = session->qos + k;
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
qos_flow->qfi = qos_session->qfi;
qos_char->qos_type = qos_session->fiveQI_type;
if (qos_char->qos_type == dynamic) {
qos_char->dynamic.fiveqi = qos_session->fiveQI;
qos_char->dynamic.qos_priority_level = qos_session->qos_priority;
} else {
qos_char->non_dynamic.fiveqi = qos_session->fiveQI;
qos_char->non_dynamic.qos_priority_level = qos_session->qos_priority;
}
ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority;
ngap_allocation_retention_priority_t *rent_priority_in = &qos_session->allocation_retention_priority;
rent_priority->priority_level = rent_priority_in->priority_level;
rent_priority->preemption_capability = rent_priority_in->pre_emp_capability;
rent_priority->preemption_vulnerability = rent_priority_in->pre_emp_vulnerability;
}
}
}
/* Limitation: we assume one fixed CU-UP per UE. We base the selection on
* NSSAI, but the UE might have multiple PDU sessions with differing slices,
* in which we might need to select different CU-UPs. In this case, we would
* actually need to group the E1 bearer context setup for the different
* CU-UPs, and send them to the different CU-UPs. */
sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE, cuup_nssai.sst, cuup_nssai.sd);
rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req);
}
//------------------------------------------------------------------------------
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
@@ -381,40 +482,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
}
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
UE->amf_ue_ngap_id = req->amf_ue_ngap_id;
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
if (nb_pdusessions_tosetup) {
AssertFatal(false, "PDU sessions in Initial context setup request not handled by E1 yet\n");
/* this code should pass by E1: commenting here for future reference, but
* already handled in E1 for the "normal case" of a separate request for
* PDU session setup.
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
for (int i = 0; i < nb_pdusessions_tosetup; i++) {
UE->nb_of_pdusessions++;
if(UE->pduSession[i].status >= PDU_SESSION_STATUS_DONE)
continue;
UE->pduSession[i].status = PDU_SESSION_STATUS_NEW;
UE->pduSession[i].param = req->pdusession_param[i];
create_tunnel_req.num_tunnels++;
create_tunnel_req.pdusession_id[i] = req->pdusession_param[i].pdusession_id;
create_tunnel_req.outgoing_teid[i] = req->pdusession_param[i].gtp_teid;
// To be developped: hardcoded first flow
create_tunnel_req.outgoing_qfi[i] = req->pdusession_param[i].qos[0].qfi;
create_tunnel_req.dst_addr[i].length = req->pdusession_param[i].upf_addr.length;
memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer));
LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]);
}
create_tunnel_req.ue_id = UE->rrc_ue_id;
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0};
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req);
if (ret != 0) {
LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti);
AssertFatal(false, "release timer not implemented\n");
return (0);
}
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0);
*/
}
/* NAS PDU */
// this is malloced pointers, we pass it for later free()
@@ -427,12 +494,18 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0);
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
// in case, send the S1SP initial context response if it is not sent with the attach complete message
if (UE->StatusRrc == NR_RRC_RECONFIGURED) {
LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", UE->reestablishment_cause);
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt, ue_context_p);
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
/* if there are PDU sessions to setup, first send them to the CU-UP, then
* send the UE Context setup with Security commend. Else go to the security
* command directly. */
if (nb_pdusessions_tosetup > 0) {
trigger_bearer_setup(RC.nrrrc[instance],
UE,
req->nb_of_pdusessions,
req->pdusession_param,
/*req->ueAggMaxBitRateDownlink*/ 0);
} else {
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, 0, NULL);
}
return 0;
@@ -466,12 +539,13 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi;
resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
}
} else {
} else if (session->status != PDU_SESSION_STATUS_ESTABLISHED) {
session->status = PDU_SESSION_STATUS_FAILED;
pdusession_failed_t *fail = &resp->pdusessions_failed[pdu_sessions_failed];
fail->pdusession_id = session->param.pdusession_id;
fail->cause = NGAP_CAUSE_RADIO_NETWORK;
fail->cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
pdu_sessions_failed++;
resp->pdusessions_failed[pdusession].pdusession_id = session->param.pdusession_id;
// TODO add cause when it will be integrated
resp->pdusessions_failed[pdusession].cause = NGAP_CAUSE_RADIO_NETWORK;
resp->pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
}
}
@@ -511,7 +585,7 @@ static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(
}
}
LOG_I(RRC, "selecting ciphering algorithm %d\n", ret);
LOG_D(RRC, "selecting ciphering algorithm %d\n", ret);
return ret;
}
@@ -547,7 +621,7 @@ static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(
}
}
LOG_I(RRC, "selecting integrity algorithm %d\n", ret);
LOG_D(RRC, "selecting integrity algorithm %d\n", ret);
return ret;
}
@@ -585,13 +659,13 @@ static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gN
}
LOG_I(NR_RRC,
"[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n",
"[gNB %d][UE %d] Selected security algorithms (%p): ciphering %lx, integrity %x (algorithms %s)\n",
ctxt_pP->module_id,
UE->rnti,
UE->rrc_ue_id,
security_capabilities_pP,
(unsigned long)cipheringAlgorithm,
cipheringAlgorithm,
integrityProtAlgorithm,
changed ? "changed" : "same");
changed ? "changed" : "are the same");
return changed;
}
@@ -715,9 +789,11 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
pdu_sessions_done++;
} else if (session->status != PDU_SESSION_STATUS_ESTABLISHED) {
session->status = PDU_SESSION_STATUS_FAILED;
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = session->param.pdusession_id;
pdusession_failed_t *fail = &resp->pdusessions_failed[pdu_sessions_failed];
fail->pdusession_id = session->param.pdusession_id;
fail->cause = NGAP_CAUSE_RADIO_NETWORK;
fail->cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
pdu_sessions_failed++;
// TODO add cause when it will be integrated
}
resp->nb_of_pdusessions = pdu_sessions_done;
resp->nb_of_pdusessions_failed = pdu_sessions_failed;
@@ -739,6 +815,28 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
return;
}
/* \brief checks if any transaction is ongoing for any xid of this UE */
static bool transaction_ongoing(const gNB_RRC_UE_t *UE)
{
for (int xid = 0; xid < 4; ++xid)
if (UE->xids[xid] != RRC_ACTION_NONE)
return true;
return false;
}
/* \brief delays the ongoing transaction (in msg_p) by setting a timer to wait
* 10ms; upon expiry, delivers to RRC, which sends the message to itself */
static void delay_transaction(MessageDef *msg_p, int wait_us)
{
MessageDef *new = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQ);
ngap_pdusession_setup_req_t *n = &NGAP_PDUSESSION_SETUP_REQ(new);
*n = NGAP_PDUSESSION_SETUP_REQ(msg_p);
int instance = msg_p->ittiMsgHeader.originInstance;
long timer_id;
timer_setup(0, wait_us, TASK_RRC_GNB, instance, TIMER_ONE_SHOT, new, &timer_id);
}
//------------------------------------------------------------------------------
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
@@ -762,98 +860,27 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
return ;
}
UE->rrc_ue_id = msg->gNB_ue_ngap_id;
AssertFatal(UE->rrc_ue_id == msg->gNB_ue_ngap_id, "logic bug\n");
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
e1ap_bearer_setup_req_t bearer_req = {0};
e1ap_nssai_t cuup_nssai = {0};
for (int i = 0; i < msg->nb_pdusessions_tosetup; i++) {
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, msg->pdusession_setup_params[i].pdusession_id, true);
pdusession_t *session = &pduSession->param;
session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id;
LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions);
session->pdu_session_type = msg->pdusession_setup_params[i].pdu_session_type;
session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu;
session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer;
session->nssai = msg->pdusession_setup_params[i].nssai;
decodePDUSessionResourceSetup(session);
bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id;
bearer_req.cipheringAlgorithm = UE->ciphering_algorithm;
bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm;
nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey);
nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, (uint8_t *)bearer_req.integrityProtectionKey);
bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink;
pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions;
bearer_req.numPDUSessions++;
pdu->sessionId = session->pdusession_id;
pdu->nssai = msg->pdusession_setup_params[i].nssai;
if (cuup_nssai.sst == 0)
cuup_nssai = pdu->nssai; /* for CU-UP selection below */
pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
pdu->teId = session->gtp_teid;
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
for (int j=0; j < pdu->numDRB2Setup; j++) {
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
drb->id = i + j + UE->nb_of_pdusessions;
drb->defaultDRB = true;
drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
drb->discardTimer = E1AP_DiscardTimer_infinity;
drb->reorderingTimer = E1AP_T_Reordering_ms100;
drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
drb->numCellGroups = 1; // assume one cell group associated with a DRB
for (int k=0; k < drb->numCellGroups; k++) {
cell_group_t *cellGroup = drb->cellGroupList + k;
cellGroup->id = 0; // MCG
}
drb->numQosFlow2Setup = session->nb_qos;
for (int k=0; k < drb->numQosFlow2Setup; k++) {
qos_flow_to_setup_t *qos_flow = drb->qosFlows + k;
pdusession_level_qos_parameter_t *qos_session = session->qos + k;
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
qos_flow->qfi = qos_session->qfi;
qos_char->qos_type = qos_session->fiveQI_type;
if (qos_char->qos_type == dynamic) {
qos_char->dynamic.fiveqi = qos_session->fiveQI;
qos_char->dynamic.qos_priority_level = qos_session->qos_priority;
} else {
qos_char->non_dynamic.fiveqi = qos_session->fiveQI;
qos_char->non_dynamic.qos_priority_level = qos_session->qos_priority;
}
ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority;
ngap_allocation_retention_priority_t *rent_priority_in = &qos_session->allocation_retention_priority;
rent_priority->priority_level = rent_priority_in->priority_level;
rent_priority->preemption_capability = rent_priority_in->pre_emp_capability;
rent_priority->preemption_vulnerability = rent_priority_in->pre_emp_vulnerability;
}
}
/* This is a hack. We observed that with some UEs, PDU session requests might
* come in quick succession, faster than the RRC reconfiguration for the PDU
* session requests can be carried out (UE is doing reconfig, and second PDU
* session request arrives). We don't have currently the means to "queue up"
* these transactions, which would probably involve some rework of the RRC.
* To still allow these requests to come in and succeed, we below check and delay transactions
* for 10ms. However, to not accidentally end up in infinite loops, the
* maximum number is capped on a per-UE basis as indicated in variable
* max_delays_pdu_session. */
if (UE->max_delays_pdu_session > 0 && transaction_ongoing(UE)) {
int wait_us = 10000;
LOG_D(RRC, "UE %d: delay PDU session setup by %d us, pending %d retries\n", UE->rrc_ue_id, wait_us, UE->max_delays_pdu_session);
delay_transaction(msg_p, wait_us);
UE->max_delays_pdu_session--;
return;
}
int xid = rrc_gNB_get_next_transaction_identifier(instance);
UE->xids[xid] = RRC_PDUSESSION_ESTABLISH;
/* Limitation: we assume one fixed CU-UP per UE. We base the selection on
* NSSAI, but the UE might have multiple PDU sessions with differing slices,
* in which we might need to select different CU-UPs. In this case, we would
* actually need to group the E1 bearer context setup for the different
* CU-UPs, and send them to the different CU-UPs. */
sctp_assoc_t assoc_id = get_new_cuup_for_ue(rrc, UE, cuup_nssai.sst, cuup_nssai.sd);
rrc->cucp_cuup.bearer_context_setup(assoc_id, &bearer_req);
trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink);
return;
}
+2 -1
View File
@@ -72,7 +72,7 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance
for(int i = 0; i < NB_RB_MAX; i++)
new_p->ue_context.pduSession[i].xid = -1;
LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.rrc_ue_id);
LOG_D(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.rrc_ue_id);
return(new_p);
}
@@ -188,6 +188,7 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
"UE F1 Context for ID %d already exists, logic bug\n",
ue->rrc_ue_id);
cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data);
ue->max_delays_pdu_session = 20; /* see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() */
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
LOG_I(NR_RRC,
+7 -5
View File
@@ -75,14 +75,16 @@ static const nr_rrc_cuup_container_t *select_cuup_round_robin(size_t n_t, const
return NULL;
}
bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue)
{
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id);
return ue_data.e1_assoc_id != 0;
}
sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue)
{
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id);
if (ue_data.e1_assoc_id == 0) {
LOG_W(RRC, "UE %d should be associated to CU-UP, but is not\n", ue->rrc_ue_id);
/* we could possibly check the SST/SD from the PDU session */
return get_new_cuup_for_ue(rrc, ue, 0, 0);
}
AssertFatal(ue_data.e1_assoc_id != 0, "UE %d should be associated to CU-UP, but is not\n", ue->rrc_ue_id);
LOG_D(RRC, "UE %d using CU-UP assoc_id %d\n", ue->rrc_ue_id, ue_data.e1_assoc_id);
return ue_data.e1_assoc_id;
}
+83 -70
View File
@@ -37,62 +37,82 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
return ue->pduSession + j;
}
void generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering)
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id)
{
int i;
int qos_flow_index;
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
if (est_drb->status == DRB_INACTIVE) {
/* DRB Management */
est_drb->drb_id = drb_id;
est_drb->reestablishPDCP = -1;
est_drb->recoverPDCP = -1;
for (i = 0; i < MAX_DRBS_PER_UE; i++) {
if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
|| est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
&& est_drb->defaultDRBid == 0) {
est_drb->cnAssociation.sdap_config.defaultDRB = true;
est_drb->defaultDRBid = drb_id;
}
}
/* SDAP Configuration */
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
if (enable_sdap) {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
} else {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
}
for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
est_drb->status = DRB_ACTIVE_NONGBR;
else
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
est_drb->pdcp_config.headerCompression.NotUsed = 0;
if (do_drb_integrity)
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
else
est_drb->pdcp_config.integrityProtection = 1;
if (do_drb_ciphering)
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
else
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
const drb_t *drb = &ue->established_drbs[drb_id - 1];
if (drb->status == DRB_INACTIVE) {
LOG_E(NR_RRC, "UE %d: DRB %d inactive\n", ue->rrc_ue_id, drb_id);
return NULL;
}
int id = drb->cnAssociation.sdap_config.pdusession_id;
return find_pduSession(ue, id, false);
}
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
{
DevAssert(drb_id > 0 && drb_id < 32);
DevAssert(ue != NULL);
return &ue->established_drbs[drb_id - 1];
}
drb_t *generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
const rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering)
{
DevAssert(ue != NULL);
LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, drb_id, pduSession->param.pdusession_id);
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
DevAssert(est_drb->status == DRB_INACTIVE);
est_drb->status = DRB_ACTIVE;
est_drb->drb_id = drb_id;
est_drb->reestablishPDCP = -1;
est_drb->recoverPDCP = -1;
est_drb->cnAssociation.sdap_config.defaultDRB = true;
est_drb->defaultDRBid = drb_id;
/* SDAP Configuration */
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
if (enable_sdap) {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
} else {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
}
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
est_drb->status = DRB_ACTIVE_NONGBR;
else
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
est_drb->pdcp_config.headerCompression.NotUsed = 0;
if (do_drb_integrity)
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
else
est_drb->pdcp_config.integrityProtection = 1;
if (do_drb_ciphering)
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
else
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
drb_t *rrc_drb = get_drb(ue, drb_id);
DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */
return rrc_drb;
}
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
@@ -143,27 +163,20 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
return DRB_config;
}
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr)
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue)
{
uint8_t drb_id;
if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR)
return drb_id + 1;
}
/* GBR Flow or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (ue->DRB_active[drb_id] == DRB_INACTIVE)
for (uint8_t drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (ue->established_drbs[drb_id].status == DRB_INACTIVE)
return drb_id + 1;
/* From this point, we need to handle the case that all DRBs are already used by the UE. */
LOG_E(RRC, "Error - All the DRBs are used - Handle this\n");
return DRB_INACTIVE;
}
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id) {
DevAssert(drb_id > 0);
if(ue->DRB_active[drb_id-1] == DRB_ACTIVE)
return true;
return false;
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id)
{
drb_t *drb = get_drb(ue, drb_id);
if (drb == NULL)
return DRB_INACTIVE;
return drb->status != DRB_INACTIVE;
}
+22 -9
View File
@@ -39,23 +39,36 @@
/// @param drb_t drb_asn1
/// @return Returns the ASN1 DRB-ToAddMod structs.
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity,
/// to create the actual entity use the generateDRB_ASN1.
/// @brief retrieve the data structure representing DRB with ID drb_id of UE ue
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id);
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
/// @param pduSession The PDU Session that the DRB is created for.
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
/// @param do_drb_integrity
/// @param do_drb_ciphering
void generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering);
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
/// @return returns a pointer to the generated DRB structure
drb_t *generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
const rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering);
/// @brief return the next available (inactive) DRB ID of UE ue
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue);
/// @brief check if DRB with ID drb_id of UE ue is active
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
/// @brief retrieve PDU session of UE ue with ID id, optionally creating it if
/// create is true
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
/// @brief get PDU session of UE ue through the DRB drb_id
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id);
#endif
+1
View File
@@ -311,6 +311,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
rrc->uecap_file = uecap_file;
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
set_default_timers_and_constants(&rrc->timers_and_constants);
for (int i = 0; i < NB_CNX_UE; i++) {
rrcPerNB_t *ptr = &rrc->perNB[i];
@@ -120,11 +120,14 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
bool t300_expired = nr_timer_tick(&timers->T300);
if(t300_expired)
if(t300_expired) {
LOG_W(NR_RRC, "Timer T300 expired\n");
handle_t300_expiry(rrc);
}
bool t304_expired = nr_timer_tick(&timers->T304);
if(t304_expired) {
LOG_W(NR_RRC, "Timer T304 expired\n");
// TODO
// For T304 of MCG, in case of the handover from NR or intra-NR
// handover, initiate the RRC re-establishment procedure;
@@ -134,6 +137,7 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
bool t310_expired = nr_timer_tick(&timers->T310);
if(t310_expired) {
LOG_W(NR_RRC, "Timer T310 expired\n");
// TODO
// handle detection of radio link failure
// as described in 5.3.10.3 of 38.331
@@ -142,6 +146,7 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
bool t311_expired = nr_timer_tick(&timers->T311);
if(t311_expired) {
LOG_W(NR_RRC, "Timer T311 expired\n");
// Upon T311 expiry, the UE shall perform the actions upon going to RRC_IDLE
// with release cause 'RRC connection failure'
nr_rrc_going_to_IDLE(rrc, RRC_CONNECTION_FAILURE, NULL);
@@ -577,7 +582,7 @@ void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac)
{
// 38.331 9.2.3 Default values timers and constants
nr_timer_setup(&tac->T310, 1000, 10); // 10ms step
nr_timer_setup(&tac->T310, 30000, 10); // 10ms step
nr_timer_setup(&tac->T311, 30000, 10); // 10ms step
tac->N310_k = 1;
tac->N311_k = 1;
}
+1 -1
View File
@@ -556,7 +556,7 @@ bool nr_sdap_delete_ue_entities(ue_id_t ue_id)
entityPrev->next_entity = entityPtr->next_entity;
free(entityPtr);
entityPtr = entityPrev->next_entity;
LOG_D(SDAP, "Successfully deleted Entity.\n");
LOG_I(SDAP, "Successfully deleted SDAP entity for UE %ld\n", ue_id);
ret = true;
}
}
+2 -2
View File
@@ -102,7 +102,7 @@ extern int asn1_xer_print;
# define NGAP_WARN(x, args...) LOG_W(NGAP, x, ##args)
# define NGAP_TRAF(x, args...) LOG_I(NGAP, x, ##args)
# define NGAP_INFO(x, args...) LOG_I(NGAP, x, ##args)
# define NGAP_DEBUG(x, args...) LOG_I(NGAP, x, ##args)
# define NGAP_DEBUG(x, args...) LOG_D(NGAP, x, ##args)
#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
do { \
@@ -118,7 +118,7 @@ extern int asn1_xer_print;
if (mandatory) { \
AssertFatal(NGAP, "NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \
} else { \
NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \
NGAP_DEBUG("NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \
} \
} \
} while (0); \
+12 -2
View File
@@ -732,7 +732,7 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32
asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL),
&(msg->ue_ambr.br_dl));
} else {
NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate\n");
NGAP_WARN("could not find NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate\n");
}
@@ -755,6 +755,16 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32
NGAP_PDUSessionResourceSetupItemCxtReq_t *item_p = ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i];
msg->pdusession_param[i].pdusession_id = item_p->pDUSessionID;
OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->pdusession_param[i].nssai.sst);
if (item_p->s_NSSAI.sD != NULL) {
uint8_t *sd_p = (uint8_t *)&msg->pdusession_param[i].nssai.sd;
sd_p[0] = item_p->s_NSSAI.sD->buf[0];
sd_p[1] = item_p->s_NSSAI.sD->buf[1];
sd_p[2] = item_p->s_NSSAI.sD->buf[2];
} else {
msg->pdusession_param[i].nssai.sd = 0xffffff;
}
if (item_p->nAS_PDU) {
allocCopy(&msg->pdusession_param[i].nas_pdu, *item_p->nAS_PDU);
}
@@ -775,7 +785,7 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32
AssertFatal(ie, "AllowedNSSAI not present, forging 2 NSSAI\n");
NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
msg->nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) {
+25 -18
View File
@@ -95,8 +95,8 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami(instance_p, UEfirstReq->establishment_cause, UEfirstReq->ue_identity.guami);
if (amf_desc_p) {
NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n",
instance,
NGAP_INFO("UE %d: Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n",
UEfirstReq->gNB_ue_ngap_id,
amf_desc_p->amf_name,
amf_desc_p->assoc_id,
UEfirstReq->ue_identity.guami.mcc,
@@ -115,8 +115,8 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
if (amf_desc_p) {
NGAP_INFO(
"[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n",
instance,
"UE %d: Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n",
UEfirstReq->gNB_ue_ngap_id,
amf_desc_p->amf_name,
amf_desc_p->assoc_id,
UEfirstReq->ue_identity.s_tmsi.amf_set_id,
@@ -134,8 +134,8 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id(instance_p, UEfirstReq->establishment_cause, UEfirstReq->selected_plmn_identity);
if (amf_desc_p) {
NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n",
instance,
NGAP_INFO("UE %d: Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n",
UEfirstReq->gNB_ue_ngap_id,
amf_desc_p->amf_name,
amf_desc_p->assoc_id,
UEfirstReq->selected_plmn_identity,
@@ -153,7 +153,7 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
amf_desc_p = ngap_gNB_nnsf_select_amf(instance_p, UEfirstReq->establishment_cause);
if (amf_desc_p) {
NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", instance, amf_desc_p->amf_name, amf_desc_p->assoc_id);
NGAP_INFO("UE %d: Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", UEfirstReq->gNB_ue_ngap_id, amf_desc_p->amf_name, amf_desc_p->assoc_id);
}
}
@@ -246,7 +246,7 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_FiveG_S_TMSI;
AMF_SETID_TO_BIT_STRING(UEfirstReq->ue_identity.s_tmsi.amf_set_id, &ie->value.choice.FiveG_S_TMSI.aMFSetID);
AMF_SETID_TO_BIT_STRING(UEfirstReq->ue_identity.s_tmsi.amf_pointer, &ie->value.choice.FiveG_S_TMSI.aMFPointer);
AMF_POINTER_TO_BIT_STRING(UEfirstReq->ue_identity.s_tmsi.amf_pointer, &ie->value.choice.FiveG_S_TMSI.aMFPointer);
M_TMSI_TO_OCTET_STRING(UEfirstReq->ue_identity.s_tmsi.m_tmsi, &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI);
}
@@ -631,7 +631,14 @@ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_r
GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &tmp->gTP_TEID);
allocAddrCopy(&tmp->transportLayerAddress, initial_ctxt_resp_p->pdusessions[i].gNB_addr);
NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld\n", item->pDUSessionID);
NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld, TEID %u\n",
item->pDUSessionID,
tmp->transportLayerAddress.buf[0],
tmp->transportLayerAddress.buf[1],
tmp->transportLayerAddress.buf[2],
tmp->transportLayerAddress.buf[3],
tmp->transportLayerAddress.size,
initial_ctxt_resp_p->pdusessions[i].gtp_teid);
/* associatedQosFlowList. number of 1? */
for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) {
@@ -692,11 +699,11 @@ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_r
case NGAP_CAUSE_NOTHING:
default:
LOG_E(NR_RRC, "Unknown PDU session failure cause %d\n", initial_ctxt_resp_p->pdusessions_failed[i].cause);
AssertFatal(false, "Unknown PDU session failure cause %d\n", initial_ctxt_resp_p->pdusessions_failed[i].cause);
break;
}
NGAP_DEBUG("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID);
NGAP_INFO("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID);
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer);
AssertFatal(res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded);
item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer;
@@ -885,13 +892,14 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_re
asn1cCalloc(pdusessionTransfer.dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel, tmp);
GTP_TEID_TO_ASN1(pdusession->gtp_teid, &tmp->gTP_TEID);
allocAddrCopy(&tmp->transportLayerAddress, pdusession->gNB_addr);
NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n",
NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld, TEID %u\n",
item->pDUSessionID,
tmp->transportLayerAddress.buf[0],
tmp->transportLayerAddress.buf[1],
tmp->transportLayerAddress.buf[2],
tmp->transportLayerAddress.buf[3],
tmp->transportLayerAddress.size);
tmp->transportLayerAddress.size,
pdusession->gtp_teid);
/* associatedQosFlowList. number of 1? */
for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) {
asn1cSequenceAdd(pdusessionTransfer.dLQosFlowPerTNLInformation.associatedQosFlowList.list, NGAP_AssociatedQosFlowItem_t, ass_qos_item_p);
@@ -923,7 +931,6 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_re
ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes;
for (int i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) {
LOG_W(NGAP,"add a failed session\n");
pdusession_failed_t *pdusession_failed = pdusession_setup_resp_p->pdusessions_failed + i;
asn1cSequenceAdd(ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, NGAP_PDUSessionResourceFailedToSetupItemSURes_t, item);
NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t pdusessionUnTransfer_p = {0};
@@ -960,10 +967,10 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_re
case NGAP_CAUSE_NOTHING:
default:
LOG_E(NR_RRC, "Unknown PDU session failure cause %d\n", pdusession_failed->cause);
AssertFatal(false, "Unknown PDU session failure cause %d\n", pdusession_failed->cause);
break;
}
NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID);
NGAP_INFO("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID);
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &pdusessionUnTransfer_p);
item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer;
@@ -1124,7 +1131,7 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, ngap_pdusession_modify_
case NGAP_CAUSE_NOTHING:
default:
LOG_E(NR_RRC, "Unknown PDU session failure cause %d\n", pdusession_modify_resp_p->pdusessions_failed[i].cause);
AssertFatal(false, "Unknown PDU session failure cause %d\n", pdusession_modify_resp_p->pdusessions_failed[i].cause);
break;
}
@@ -1136,7 +1143,7 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, ngap_pdusession_modify_
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p);
NGAP_DEBUG("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID);
NGAP_INFO("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID);
}
}
+4 -4
View File
@@ -735,10 +735,10 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
}
if ( t->lastWroteTS != 0 && fabs((double)t->lastWroteTS-timestamp) > (double)CirSize)
LOG_E(HW, "Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp);
LOG_W(HW, "Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp);
if (t->lastWroteTS > timestamp+nsamps)
LOG_E(HW, "Not supported to send Tx out of order (same in USRP) %lu, %lu\n", t->lastWroteTS, timestamp);
LOG_W(HW, "Not supported to send Tx out of order %lu, %lu\n", t->lastWroteTS, timestamp);
t->lastWroteTS=timestamp+nsamps;
@@ -872,14 +872,14 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
} else if (b->lastReceivedTS == b->th.timestamp) {
// normal case
} else {
LOG_E(HW, "Received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
LOG_W(HW, "Received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
b->trashingPacket=true;
}
pthread_mutex_lock(&Sockmutex);
if (t->lastWroteTS != 0 && (fabs((double)t->lastWroteTS-b->lastReceivedTS) > (double)CirSize))
LOG_E(HW, "UEsock(%d) Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, t->lastWroteTS, b->lastReceivedTS);
LOG_W(HW, "UEsock(%d) Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, t->lastWroteTS, b->lastReceivedTS);
pthread_mutex_unlock(&Sockmutex);
b->transferPtr=(char *)&b->circularBuf[(b->lastReceivedTS*b->th.nbAnt)%CirSize];