diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 0ac77ffd7a..d9ac675493 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -42,6 +42,7 @@ #define NR_MAX_HARQ_PROCESSES 16 #define NR_NB_REG_PER_CCE 6 #define NR_NB_SC_PER_RB 12 +#define NR_MAX_NUM_LCID 32 typedef enum { nr_FR1 = 0, diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index cfc32354e6..fdfd8cc45e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -402,7 +402,6 @@ typedef struct { #define UL_SCH_LCID_L_BSR 0x3E #define UL_SCH_LCID_PADDING 0x3F -#define NR_MAX_NUM_LCID 32 #define NR_MAX_NUM_LCGID 8 #define MAX_RLC_SDU_SUBHEADER_SIZE 3 diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index d4515ac235..b1624126bb 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -511,19 +511,28 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac, mac->BWP_coresets[i] = NULL; } -// todo handle mac_LogicalChannelConfig -int nr_rrc_mac_config_req_ue_logicalChannelBearer( - module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - long logicalChannelIdentity, - bool status){ - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - mac->logicalChannelBearer_exist[logicalChannelIdentity] = status; - return 0; +void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list, + struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + if (rlc_toadd_list) { + for (int i = 0; i < rlc_toadd_list->list.count; i++) { + NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i]; + int id = rlc_bearer->logicalChannelIdentity - 1; + mac->active_RLC_bearer[id] = true; + } + } + if (rlc_torelease_list) { + for (int i = 0; i < rlc_torelease_list->list.count; i++) { + if (rlc_torelease_list->list.array[i]) { + int id = *rlc_torelease_list->list.array[i] - 1; + mac->active_RLC_bearer[id] = false; + } + } + } } - void configure_current_BWP(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommonSIB_t *scc, NR_CellGroupConfig_t *cell_group_config) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 96a968b33a..77a9484695 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -503,8 +503,8 @@ typedef struct { uint8_t BSR_reporting_active; /// LogicalChannelConfig has bearer. - bool logicalChannelBearer_exist[NR_MAX_NUM_LCID]; - NR_UE_SCHEDULING_INFO scheduling_info; + bool active_RLC_bearer[NR_MAX_NUM_LCID]; + NR_UE_SCHEDULING_INFO scheduling_info; /// PHR uint8_t PHR_reporting_active; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index adc9353ada..1817a67a0c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -63,17 +63,9 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint8_t *pduP, uint32_t pdu_len); -/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig - \param module_id module id - \param cc_id component carrier id - \param gNB_index gNB index - \param long logicalChannelIdentity - \param bool status*/ -int nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - long logicalChannelIdentity, - bool status); +void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list, + struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list); void nr_rrc_mac_config_req_scg(module_id_t module_id, int cc_idP, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 2b505bf6f4..40488d458a 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -51,7 +51,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { //LOG_I(MAC, "[MAIN] init UE MAC functions \n"); //init mac here - nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t), NB_NR_UE_MAC_INST); + nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(NB_NR_UE_MAC_INST, sizeof(NR_UE_MAC_INST_t)); for (int j = 0; j < NB_NR_UE_MAC_INST; j++) nr_ue_init_mac(j); @@ -73,15 +73,16 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { NR_RadioBearerConfig_t *rbconfig = NULL; NR_RLC_BearerConfig_t *rlc_rbconfig = NULL; fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); - struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_bearer_list = { - .list = { .array = &rlc_rbconfig, .count = 1, .size = 1, } - }; // set up PDCP, RLC, MAC nr_pdcp_layer_init(); - nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); - nr_ue_mac_inst->logicalChannelBearer_exist[4] = true; + struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_toadd_list; + rlc_toadd_list.list.count = 1; + rlc_toadd_list.list.array = calloc(1, sizeof(NR_RLC_BearerConfig_t)); + rlc_toadd_list.list.array[0] = rlc_rbconfig; + nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL); // free memory free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 0323dd90d3..6a8a4c213d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1119,8 +1119,6 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info) bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) { bool bsr_regular_triggered = false; - uint8_t lcid; - uint8_t lcgid; uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0}; int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID]; @@ -1137,37 +1135,38 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t // Reset All BSR Infos lcid_bytes_in_buffer[0] = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { + // TO BE NOTED LCID = 0 is excluded from buffers + // so they need to be addressed with lcid - 1 + for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { // Reset transmission status - lcid_bytes_in_buffer[lcid] = 0; - mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY; + lcid_bytes_in_buffer[lcid - 1] = 0; + mac->scheduling_info.LCID_status[lcid - 1] = LCID_EMPTY; } - for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { + for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { // Reset Buffer Info - mac->scheduling_info.BSR[lcgid]=0; - mac->scheduling_info.BSR_bytes[lcgid]=0; + mac->scheduling_info.BSR[lcgid] = 0; + mac->scheduling_info.BSR_bytes[lcgid] = 0; } //Get Buffer Occupancy and fill lcid_reordered_array - for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { - //if (mac->logicalChannelConfig[lcid]) { - if (mac->logicalChannelBearer_exist[lcid] ) { // todo - lcgid = mac->scheduling_info.LCGID[lcid]; + for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { + if (mac->active_RLC_bearer[lcid - 1]) { // todo + int lcgid = mac->scheduling_info.LCGID[lcid - 1]; // Store already available data to transmit per Group if (lcgid < NR_MAX_NUM_LCGID) { - lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid]; + lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid - 1]; } mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0); - lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; + lcid_bytes_in_buffer[lcid - 1] = rlc_status.bytes_in_buffer; if (rlc_status.bytes_in_buffer > 0) { LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n", module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP); - mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; + mac->scheduling_info.LCID_status[lcid - 1] = LCID_NOT_EMPTY; //Update BSR_bytes and position in lcid_reordered_array only if Group is defined if (lcgid < NR_MAX_NUM_LCGID) { @@ -1181,7 +1180,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t //if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) { if (1) { // todo //Insert if priority is higher or equal (lower or equal in value) - for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) { + for (pos_next = num_lcid_with_data - 1; pos_next > array_index; pos_next--) { lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; } @@ -1190,7 +1189,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t } array_index ++; - } while ((array_index < num_lcid_with_data) && (array_index < NR_MAX_NUM_LCID)); + } while ((array_index < num_lcid_with_data) && (array_index <= NR_MAX_NUM_LCID)); } } } @@ -1204,7 +1203,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t lcid_reordered_array[2]); for (array_index = 0; array_index < num_lcid_with_data; array_index++) { - lcid = lcid_reordered_array[array_index]; + int lcid = lcid_reordered_array[array_index]; /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity either the data belongs to a logical channel with higher priority than the priorities of the logical channels @@ -1212,10 +1211,13 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t */ { bsr_regular_triggered = true; - LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", - module_idP, lcid, - mac->scheduling_info.LCGID[lcid], - frameP, slotP); + LOG_D(NR_MAC, + "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", + module_idP, + lcid, + mac->scheduling_info.LCGID[lcid - 1], + frameP, + slotP); break; } } @@ -1232,8 +1234,8 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t } //Store Buffer Occupancy in remain buffers for next TTI - for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { - mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid]; + for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { + mac->scheduling_info.LCID_buffer_remain[lcid - 1] = lcid_bytes_in_buffer[lcid - 1]; } return bsr_regular_triggered; @@ -2688,27 +2690,27 @@ Update the following in mac_ce_p: bsr_t */ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t subframe, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - uint16_t buflen, - NR_UE_MAC_CE_INFO *mac_ce_p) { + int CC_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen, + NR_UE_MAC_CE_INFO *mac_ce_p) +{ NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); // Compute BSR Values and update Nb LCGID with data after multiplexing unsigned short padding_len = 0; - uint8_t lcid = 0; int lcg_id = 0; int num_lcg_id_with_data = 0; int lcg_id_bsr_trunc = 0; for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { - if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) { + if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) { mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); - } else { + } else { mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); - } + } if (mac->scheduling_info.BSR_bytes[lcg_id]) { num_lcg_id_with_data++; lcg_id_bsr_trunc = lcg_id; @@ -2742,8 +2744,8 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, if (num_lcg_id_with_data > 1) { // REPORT SHORT TRUNCATED BSR //Get LCGID of highest priority LCID with data (todo) - for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { - lcg_id = mac->scheduling_info.LCGID[lcid]; + for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { + lcg_id = mac->scheduling_info.LCGID[lcid - 1]; if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) { lcg_id_bsr_trunc = lcg_id; } @@ -2855,7 +2857,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, sub_frame_t subframe, uint8_t gNB_index, uint8_t *ulsch_buffer, - uint16_t buflen) { + uint16_t buflen) +{ NR_UE_MAC_CE_INFO mac_ce_info; NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info; int16_t buflen_remain = 0; @@ -2891,11 +2894,14 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization - for (int lcid = UL_SCH_LCID_SRB1; lcid < NR_MAX_NUM_LCID; lcid++) { + for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { + if (!mac->active_RLC_bearer[lcid - 1]) + continue; buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); - LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n", - __FUNCTION__, + LOG_D(NR_MAC, + "[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d " + "bytes, buflen_remain %d bytes)\n", module_idP, frameP, subframe, @@ -2905,8 +2911,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, mac_ce_p->tot_mac_ce_len, buflen_remain); - while (buflen_remain > 0){ - + while (buflen_remain > 0) { // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu; @@ -2924,23 +2929,23 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, 0, 0); - AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", - __FUNCTION__, + AssertFatal(buflen_remain >= sdu_length, + "LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", lcid, sdu_length, buflen_remain); if (sdu_length > 0) { - - LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", - __FUNCTION__, - module_idP, - frameP, - subframe, - num_sdus + 1, - sdu_length, - lcid, - buflen); + LOG_D(NR_MAC, + "[UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x " + "(buflen (TBS) %d bytes)\n", + module_idP, + frameP, + subframe, + num_sdus + 1, + sdu_length, + lcid, + buflen); header->R = 0; header->F = 1; @@ -2962,20 +2967,24 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } else { pdu -= sh_size; - LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); + LOG_D(NR_MAC, "no data to transmit for RB with LCID 0x%02x\n", lcid); break; } buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); //Update Buffer remain and BSR bytes after transmission - mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length; - mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length; - LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n", - module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid], - mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]); - if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0) - mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0; + mac->scheduling_info.LCID_buffer_remain[lcid - 1] -= sdu_length; + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] -= sdu_length; + LOG_D(NR_MAC, + "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n", + module_idP, + frameP, + subframe, + mac->scheduling_info.LCGID[lcid - 1], + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]]); + if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] < 0) + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] = 0; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index f38e70d66e..14c75deb26 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -282,10 +282,6 @@ void mac_top_init_gNB(ngran_node_t node_type, NR_RadioBearerConfig_t *rbconfig = NULL; NR_RLC_BearerConfig_t *rlc_rbconfig = NULL; fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig); - NR_RLC_BearerConfig_t *rlc_rbconfig_list[1] = {rlc_rbconfig}; - struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_bearer_list = { - .list = { .array = rlc_rbconfig_list, .count = 1, .size = 1, } - }; /* Note! previously, in nr_DRB_preconfiguration(), we passed ENB_FLAG_NO * if ENB_NAS_USE_TUN was *not* set. It seems to me that we could not set @@ -295,7 +291,7 @@ void mac_top_init_gNB(ngran_node_t node_type, * will output the packets at a local interface, which is in line with * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ // setup PDCP, RLC - nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); // free memory diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index 97370c5964..c7c91a38a0 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -32,8 +32,7 @@ void e1_add_drb(int is_gnb, unsigned char *ciphering_key, unsigned char *integrity_key) { - add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, - ciphering_key, integrity_key); + add_drb(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index b503fcc010..453422f278 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -369,6 +369,21 @@ void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) check_t_reordering(entity); } +void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) +{ + // deliver the PDCP SDUs stored in the receiving PDCP entity to upper layers + while (entity->rx_list != NULL) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + entity->stats.txsdu_pkts++; + entity->stats.txsdu_bytes += cur->size; + nr_pdcp_free_sdu(cur); + } +} + void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) { nr_pdcp_sdu_t *cur = entity->rx_list; @@ -428,6 +443,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ret->set_time = nr_pdcp_entity_set_time; ret->delete_entity = nr_pdcp_entity_delete; + ret->release_entity = nr_pdcp_entity_release; ret->get_stats = nr_pdcp_entity_get_stats; ret->deliver_sdu = deliver_sdu; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 965ea6a1ec..83d08ea259 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -76,6 +76,7 @@ typedef struct nr_pdcp_entity_t { int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, int sdu_id, char *pdu_buffer, int pdu_max_size); void (*delete_entity)(struct nr_pdcp_entity_t *entity); + void (*release_entity)(struct nr_pdcp_entity_t *entity); void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index be22753026..f19ae36819 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -757,21 +757,32 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock); } -static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) +void add_srb(int is_gnb, + ue_id_t rntiMaybeUEid, + struct NR_SRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_srb; nr_pdcp_ue_t *ue; - int t_Reordering=3000; int srb_id = s->srb_Identity; - if (s->pdcp_Config == NULL || - s->pdcp_Config->t_Reordering == NULL) t_Reordering = 3000; - else t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); + int t_Reordering = -1; // infinity as per default SRB configuration in 9.2.1 of 38.331 + if (s->pdcp_Config != NULL && s->pdcp_Config->t_Reordering != NULL) + t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid); if (ue->srb[srb_id-1] != NULL) { - LOG_D(PDCP, "%s:%d:%s: warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rntiMaybeUEid); + LOG_E(PDCP, + "%s:%d:%s: warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n", + __FILE__, + __LINE__, + __FUNCTION__, + srb_id, + rntiMaybeUEid); } else { pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, 0, false, false, // sdap parameters @@ -788,7 +799,13 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) +void add_drb(int is_gnb, + ue_id_t rntiMaybeUEid, + struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -882,32 +899,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, in nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static void add_drb(int is_gnb, - ue_id_t rntiMaybeUEid, - struct NR_DRB_ToAddMod *s, - NR_RLC_Config_t *rlc_Config, - int ciphering_algorithm, - int integrity_algorithm, - unsigned char *ciphering_key, - unsigned char *integrity_key) -{ - switch (rlc_Config->present) { - case NR_RLC_Config_PR_am: - add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); - break; - case NR_RLC_Config_PR_um_Bi_Directional: - // add_drb_um(rntiMaybeUEid, s); - /* hack */ - add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); - break; - default: - LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", - __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID/RNTI %ld\n", __FILE__, __FUNCTION__, __LINE__, rntiMaybeUEid); -} - void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddModList_t *const srb2add_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint) { if (srb2add_list != NULL) { @@ -923,12 +914,17 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, - uint8_t *const kUPint, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) + uint8_t *const kUPint) { if (drb2add_list != NULL) { for (int i = 0; i < drb2add_list->list.count; i++) { - add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); + add_drb(enb_flag, + rntiMaybeUEid, + drb2add_list->list.array[i], + security_modeP & 0x0f, + (security_modeP >> 4) & 0x0f, + kUPenc, + kUPint); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); @@ -1061,6 +1057,58 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, return 1; } +void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering) +{ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + nr_pdcp_entity_t *srb = ue->srb[srb_id - 1]; + int decoded_t_reordering = decode_t_reordering(t_Reordering); + srb->t_reordering = decoded_t_reordering; + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + +void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering) +{ + /* The enabling/disabling of ciphering or integrity protection + * can be changed only by releasing and adding the DRB + * (so not by reconfiguring). + */ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + nr_pdcp_entity_t *drb = ue->drb[drb_id - 1]; + int decoded_t_reordering = decode_t_reordering(t_Reordering); + drb->t_reordering = decoded_t_reordering; + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + +void nr_release_srb(ue_id_t ue_id, int srb_id) +{ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + if (ue->srb[srb_id - 1] != NULL) { + ue->srb[srb_id - 1]->delete_entity(ue->srb[srb_id - 1]); + ue->srb[srb_id - 1] = NULL; + } + else + LOG_E(PDCP, "Attempting to release SRB%d but it is not configured\n", srb_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + +void nr_release_drb(ue_id_t ue_id, int drb_id) +{ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + nr_pdcp_entity_t *drb = ue->drb[drb_id - 1]; + if (drb) { + drb->release_entity(drb); + drb->delete_entity(drb); + ue->drb[drb_id - 1] = NULL; + } + else + LOG_E(PDCP, "Attempting to release DRB%d but it is not configured\n", drb_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + void nr_pdcp_reestablishment(ue_id_t ue_id) { // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2 diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index f00ab98422..e6e7ca9273 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -51,14 +51,34 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, - uint8_t *const kUPint, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + uint8_t *const kUPint); + +void add_drb(int is_gnb, + ue_id_t rntiMaybeUEid, + struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid); bool nr_pdcp_remove_UE(ue_id_t ue_id); void nr_pdcp_reestablishment(ue_id_t ue_id); +void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering); +void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering); +void nr_release_srb(ue_id_t ue_id, int srb_id); +void nr_release_drb(ue_id_t ue_id, int drb_id); + +void add_srb(int is_gnb, + ue_id_t rntiMaybeUEid, + struct NR_SRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); + void nr_pdcp_config_set_security(ue_id_t ue_id, const rb_id_t rb_id, const uint8_t security_modeP, diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c index e23c755ba1..999cb79a52 100644 --- a/openair2/LAYER2/nr_rlc/asn1_utils.c +++ b/openair2/LAYER2/nr_rlc/asn1_utils.c @@ -66,8 +66,8 @@ int decode_t_poll_retransmit(int v) int decode_poll_pdu(int v) { static const int tab[24] = { - 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, - 8192, 12288, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536 - 1 /* -1 means infinity */ + 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, + 8192, 12288, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536, -1 /* -1 means infinity */ }; if (v < 0 || v > 23) { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index f0934ca599..0e07e14fc9 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -243,3 +243,31 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( return (nr_rlc_entity_t *)ret; } + +void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity, int t_reassembly, int *sn_field_length) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + entity->t_reassembly = t_reassembly; + if (sn_field_length) + entity->sn_field_length = *sn_field_length; +} + +void nr_rlc_entity_am_reconfigure(nr_rlc_entity_t *_entity, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int *sn_field_length) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + entity->t_poll_retransmit = t_poll_retransmit; + entity->t_reassembly = t_reassembly; + entity->t_status_prohibit = t_status_prohibit; + entity->poll_pdu = poll_pdu; + entity->poll_byte = poll_byte; + entity->max_retx_threshold = max_retx_threshold; + if (sn_field_length) + entity->sn_field_length = *sn_field_length; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index 7996d8c89e..dc0bf4907c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -176,4 +176,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( char *buf, int size), void *deliver_sdu_data); +void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity, int t_reassembly, int *sn_field_length); + +void nr_rlc_entity_am_reconfigure(nr_rlc_entity_t *_entity, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int *sn_field_length); + #endif /* _NR_RLC_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 17fa07da7b..04c1186f6e 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -54,6 +54,35 @@ static uint64_t nr_rlc_current_time; static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_subframe; +static void release_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) +{ + AssertFatal(channel_id != 0, "LCID = 0 shouldn't be handled here\n"); + nr_rlc_rb_t *rb = &ue->lcid2rb[channel_id - 1]; + if (rb->type == NR_RLC_NONE) + return; + if (rb->type == NR_RLC_SRB) { + int id = rb->choice.srb_id - 1; + AssertFatal(id > 0, "logic bug: impossible to have srb0 here\n"); + if (ue->srb[id]) { + ue->srb[id]->delete_entity(ue->srb[id]); + ue->srb[id] = NULL; + } + else + LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id); + } + else { + AssertFatal(rb->type == NR_RLC_DRB, + "Invalid RB type\n"); + int id = rb->choice.drb_id - 1; + if (ue->drb[id]) { + ue->drb[id]->delete_entity(ue->drb[id]); + ue->drb[id] = NULL; + } + else + LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id); + } +} + static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_id_t channel_id) { if (channel_id == 0) @@ -71,6 +100,23 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i } } +void nr_release_rlc_entity(int rnti, logical_chan_id_t channel_id) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (channel_id == 0) { + if (ue->srb0 != NULL) { + free(ue->srb0->deliver_sdu_data); + ue->srb0->delete_entity(ue->srb0); + ue->srb0 = NULL; + } else + LOG_E(RLC, "Trying to release a non-established enity with LCID %d\n", channel_id); + } else { + release_rlc_entity_from_lcid(ue, channel_id); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + void mac_rlc_data_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, @@ -582,6 +628,93 @@ rb_found: #endif } +void nr_rlc_reestablish_entity(int rnti, int lc_id) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + + if (ue == NULL) + LOG_E(RLC, "RLC instance for the given UE was not found \n"); + + nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id); + + if (rb != NULL) { + LOG_D(RLC, "RB found! (channel ID %d) \n", lc_id); + rb->reestablishment(rb); + } else { + LOG_E(RLC, "no RLC entity found (channel ID %d) for reestablishment\n", lc_id); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +void nr_rlc_reconfigure_entity(int rnti, int lc_id, struct NR_RLC_Config *rlc_Config, struct NR_LogicalChannelConfig *lc_Config) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + + if (ue == NULL) + LOG_E(RLC, "RLC instance for the given UE was not found \n"); + + nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id); + if (lc_Config) { + if (lc_Config->ul_SpecificParameters && lc_Config->ul_SpecificParameters->logicalChannelGroup) + AssertFatal(*lc_Config->ul_SpecificParameters->logicalChannelGroup < 2, + "LCG %ld not supported as per limitation when creating RBs\n", + *lc_Config->ul_SpecificParameters->logicalChannelGroup); + } + if (rlc_Config) { + AssertFatal(rb->stats.mode != NR_RLC_TM, "Cannot reconfigure TM mode\n"); + if (rb->stats.mode == NR_RLC_AM) { + AssertFatal(rlc_Config->present == NR_RLC_Config_PR_am, "Invalid RLC Config type\n"); + struct NR_RLC_Config__am *am = rlc_Config->choice.am; + int t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly); + int t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + int t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + int poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + int poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + int max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); + int _sn_field_length; + int *sn_field_length = NULL; + if (am->dl_AM_RLC.sn_FieldLength) { + AssertFatal(am->ul_AM_RLC.sn_FieldLength != NULL, "Cannot handle different sn_FieldLength for DL and UL\n"); + if (am->ul_AM_RLC.sn_FieldLength) { + AssertFatal(*am->dl_AM_RLC.sn_FieldLength == *am->ul_AM_RLC.sn_FieldLength, + "Cannot handle different sn_FieldLength for DL and UL\n"); + _sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength); + sn_field_length = &_sn_field_length; + } + } else + AssertFatal(am->ul_AM_RLC.sn_FieldLength == NULL, "Cannot handle different sn_FieldLength for DL and UL\n"); + nr_rlc_entity_am_reconfigure(rb, + t_poll_retransmit, + t_reassembly, + t_status_prohibit, + poll_pdu, + poll_byte, + max_retx_threshold, + sn_field_length); + } else { // UM + AssertFatal(rlc_Config->present == NR_RLC_Config_PR_um_Bi_Directional, "Invalid RLC Config type\n"); + struct NR_RLC_Config__um_Bi_Directional *um = rlc_Config->choice.um_Bi_Directional; + int t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly); + int _sn_field_length; + int *sn_field_length = NULL; + if (um->dl_UM_RLC.sn_FieldLength) { + AssertFatal(um->ul_UM_RLC.sn_FieldLength != NULL, "Cannot handle different sn_FieldLength for DL and UL\n"); + if (um->ul_UM_RLC.sn_FieldLength) { + AssertFatal(*um->dl_UM_RLC.sn_FieldLength == *um->ul_UM_RLC.sn_FieldLength, + "Cannot handle different sn_FieldLength for DL and UL\n"); + _sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength); + sn_field_length = &_sn_field_length; + } + } else + AssertFatal(um->ul_UM_RLC.sn_FieldLength == NULL, "Cannot handle different sn_FieldLength for DL and UL\n"); + nr_rlc_entity_um_reconfigure(rb, t_reassembly, sn_field_length); + } + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; @@ -600,7 +733,10 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare AssertFatal(srb_id > 0 && srb_id < 4, "Invalid srb id %d\n", srb_id); - logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + if (l && l->ul_SpecificParameters && l->ul_SpecificParameters->logicalChannelGroup) + logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + else + logical_channel_group = 0; // default value as in 9.2.1 of 38.331 /* TODO: accept other values? */ if (logical_channel_group != 0) { @@ -608,26 +744,29 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare exit(1); } - switch (r->present) { - case NR_RLC_Config_PR_am: { + if (r && r->present == NR_RLC_Config_PR_am) { struct NR_RLC_Config__am *am; am = r->choice.am; - t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly); - t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); - t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); - poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); - poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + t_reassembly = decode_t_reassembly(am->dl_AM_RLC.t_Reassembly); + t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); if (*am->dl_AM_RLC.sn_FieldLength != *am->ul_AM_RLC.sn_FieldLength) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength); - break; - } - default: - LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); + sn_field_length = decode_sn_field_length_am(*am->dl_AM_RLC.sn_FieldLength); + } else { + // default values as in 9.2.1 of 38.331 + t_reassembly = 35; + t_status_prohibit = 0; + t_poll_retransmit = 45; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 8; + sn_field_length = 12; } nr_rlc_manager_lock(nr_rlc_ue_manager); @@ -642,14 +781,6 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare if (ue->srb[srb_id-1] != NULL) { LOG_E(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); } else { - /* hack: hardcode values for NR */ - t_poll_retransmit = 45; - t_reassembly = 35; - t_status_prohibit = 0; - poll_pdu = -1; - poll_byte = -1; - max_retx_threshold = 8; - sn_field_length = 12; nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE, RLC_TX_MAXSIZE, deliver_sdu, ue, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index feeb371244..c40e5c923a 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -44,12 +44,17 @@ struct NR_LogicalChannelConfig; void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); +void nr_rlc_reestablish_entity(int rnti, int lc_id); void nr_rlc_remove_ue(int rnti); bool nr_rlc_update_rnti(int from_rnti, int to_rnti); /* test function for CI to trigger reestablishments */ void nr_rlc_test_trigger_reestablishment(int rnti); +void nr_release_rlc_entity(int rnti, logical_chan_id_t channel_id); + +void nr_rlc_reconfigure_entity(int rnti, int lc_id, struct NR_RLC_Config *rlc_Config, struct NR_LogicalChannelConfig *lc_Config); + int nr_rlc_get_available_tx_space( const rnti_t rntiP, const logical_chan_id_t channel_idP); diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 1d51f67ec6..485edc08a4 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -154,8 +154,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, DRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, - kUPint, - get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL); + kUPint); return ret; } diff --git a/openair2/RRC/NR/nr_rrc_common.h b/openair2/RRC/NR/nr_rrc_common.h index ca0fd29850..1505e71924 100644 --- a/openair2/RRC/NR/nr_rrc_common.h +++ b/openair2/RRC/NR/nr_rrc_common.h @@ -28,11 +28,12 @@ #define NR_RRC_HEADER_SIZE_MAX 64 #define NR_RRC_BUFFER_SIZE_MAX 1024 +#define NR_NUM_SRB 4 typedef struct { - char Payload[NR_RRC_BUFFER_SIZE_MAX]; - char Header[NR_RRC_HEADER_SIZE_MAX]; - uint16_t payload_size; + char Payload[NR_RRC_BUFFER_SIZE_MAX]; + char Header[NR_RRC_HEADER_SIZE_MAX]; + uint16_t payload_size; } NR_RRC_BUFFER; typedef enum UE_STATE_NR_e { @@ -45,17 +46,17 @@ typedef enum UE_STATE_NR_e { } NR_UE_STATE_t; typedef struct { - unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ - unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */ - unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/ - unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/ - uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/ - uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/ - uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/ + unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ + unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */ + unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/ + unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/ + uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/ + uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/ + uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/ } __attribute__ ((__packed__)) NR_LCHAN_DESC; typedef struct RB_INFO_NR_s { - uint16_t Rb_id; //=Lchan_id + uint16_t Rb_id; //=Lchan_id NR_LCHAN_DESC Lchan_desc[2]; //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT } NR_RB_INFO; @@ -66,8 +67,8 @@ typedef struct NR_SRB_INFO_s { } NR_SRB_INFO; typedef struct SRB_INFO_TABLE_ENTRY_NR_s { - NR_SRB_INFO Srb_info; - uint8_t Active; + NR_SRB_INFO Srb_info; + uint8_t Active; uint8_t status; } NR_SRB_INFO_TABLE_ENTRY; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index d132b8291d..510e058495 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -155,8 +155,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, - uint8_t *const kUPint, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + uint8_t *const kUPint); int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 228056ce37..9160d7213e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -938,8 +938,7 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co DRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kUPenc, - kUPint, - get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL); + kUPint); /* Loop through DRBs and establish if necessary */ if (DRB_configList != NULL) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 0b22621c0e..aa39239f88 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -389,8 +389,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, kUPenc, - kUPint, - ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + kUPint); ctxt.rntiMaybeUEid = du_ue_id; // assume only a single bearer diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index d0fb36c475..1cfb8068d3 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -133,14 +133,16 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, switch(Srb_id) { case CCCH: - - LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); - memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); - for(int i = 0; isrb_buffers.Tx_buffer.Payload, Srb0->srb_buffers.Tx_buffer.payload_size); + for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++) { LOG_D(NR_RRC,"(%i): %i\n", i, buffer_pP[i]); } - return NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size; + return Srb0->srb_buffers.Tx_buffer.payload_size; case DCCH: AssertFatal(1==0, "SRB1 not implemented yet!\n"); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 48700e564c..17bfc108ea 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -97,13 +97,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( uint8_t gNB_index ); -void -nr_rrc_ue_process_RadioBearerConfig( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - NR_RadioBearerConfig_t *const radioBearerConfig -); - uint8_t do_NR_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, @@ -120,70 +113,9 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( mui_t nr_rrc_mui=0; -static void nr_rrc_addmod_srbs(int rnti, - const NR_SRB_ToAddModList_t *srb_list, - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) -{ - if (srb_list == NULL || bearer_list == NULL) - return; - - for (int i = 0; i < srb_list->list.count; i++) { - const NR_SRB_ToAddMod_t *srb = srb_list->list.array[i]; - for (int j = 0; j < bearer_list->list.count; j++) { - const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j]; - if (bearer->servedRadioBearer != NULL - && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity - && srb->srb_Identity == bearer->servedRadioBearer->choice.srb_Identity) { - nr_rlc_add_srb(rnti, srb->srb_Identity, bearer); - } - } - } -} - -static void nr_rrc_addmod_drbs(int rnti, - const NR_DRB_ToAddModList_t *drb_list, - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) -{ - if (drb_list == NULL || bearer_list == NULL) - return; - - for (int i = 0; i < drb_list->list.count; i++) { - const NR_DRB_ToAddMod_t *drb = drb_list->list.array[i]; - for (int j = 0; j < bearer_list->list.count; j++) { - const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j]; - if (bearer->servedRadioBearer != NULL - && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity - && drb->drb_Identity == bearer->servedRadioBearer->choice.drb_Identity) { - nr_rlc_add_drb(rnti, drb->drb_Identity, bearer); - } - } - } -} - // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded) -int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, - const uint8_t *buffer, - const uint32_t size){ - - NR_CellGroupConfig_t *cell_group_config = NULL; - uint32_t i; - - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&cell_group_config, - (uint8_t *)buffer, - size, 0, 0); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n"); - for (i=0; icriticalExtensions.present){ case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ @@ -212,16 +144,31 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR } } if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ + NR_CellGroupConfig_t *cellGroupConfig = NULL; + int size = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size; + uint8_t *buffer = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf; + asn_dec_rval_t dec_rval = + uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, // might be added prefix later + (void **)&cellGroupConfig, + (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, + size, + 0, + 0); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n"); + for (int i = 0; i < size; i++) + LOG_E(NR_RRC, "%02x ", buffer[i]); + LOG_E(NR_RRC, "\n"); + // free the memory + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1); + return -1; + } - if(get_softmodem_params()->sa || get_softmodem_params()->nsa) { - - NR_CellGroupConfig_t *cellGroupConfig = NULL; - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, - rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); + if (get_softmodem_params()->sa || get_softmodem_params()->nsa) + nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, module_id, NR_UE_rrc_inst[module_id].rnti); + if (get_softmodem_params()->sa || get_softmodem_params()->nsa) { if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } @@ -241,11 +188,8 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR if (get_softmodem_params()->nsa) { nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig); } - } - else - nr_rrc_ue_decode_secondary_cellgroup_config(module_id, - rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, - rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size); + } else + nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig); } if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ if(NR_UE_rrc_inst[module_id].meas_config == NULL){ @@ -272,15 +216,13 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR return 0; } - - int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){ return 0; } - -void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len) { +void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len) +{ module_id_t module_id=0; // TODO switch (nsa_message_type) { case nr_SecondaryCellGroupConfig_r15: @@ -322,7 +264,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, protocol_ctxt_t ctxt; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0); - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)RadioBearerConfig); LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig() at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n", __LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity, RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity, @@ -341,7 +282,6 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, AssertFatal(1==0,"Unknown message %d\n",nsa_message_type); break; } - } NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file) @@ -357,15 +297,21 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi rrc->ubwpd = NULL; rrc->as_security_activated = false; - for (int i = 0; i < NB_SIG_CNX_UE; i++) + for (int i = 0; i < NB_CNX_UE; i++) { memset((void *)&rrc->SInfo[i], 0, sizeof(rrc->SInfo[i])); - + for (int j = 0; j < NR_NUM_SRB; j++) + memset((void *)&rrc->Srb[i][j], 0, sizeof(rrc->Srb[i][j])); + for (int j = 0; j < MAX_DRBS_PER_UE; j++) + rrc->active_DRBs[i][j] = false; + // SRB0 activated by default + rrc->Srb[i][0].status = RB_ESTABLISHED; + } rrc->ra_trigger = RA_NOT_RUNNING; } NR_UE_rrc_inst->uecap_file = uecap_file; - if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { + if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) { // read in files for RRCReconfiguration and RBconfig LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file); @@ -389,10 +335,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi strerror(errno)); msg_len=fread(buffer,1,1024,fd); fclose(fd); - process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); - } - else if (get_softmodem_params()->nsa) - { + process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); + } else if (get_softmodem_params()->nsa) { LOG_D(NR_RRC, "In NSA mode \n"); } @@ -407,11 +351,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi return NR_UE_rrc_inst; } -int8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){ - - return 0; -} - int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){ return 0; @@ -810,6 +749,47 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, return 0; } +void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, + NR_UE_RRC_INST_t *rrc, + int gNB_index, + module_id_t module_id, + int rnti) +{ + if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { + NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i]; + AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n"); + nr_release_rlc_entity(rnti, *lcid); + } + } + + if (cellGroupConfig->rlc_BearerToAddModList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { + NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; + NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; + if (rrc->active_RLC_entity[gNB_index][lcid]) { + if (rlc_bearer->reestablishRLC) + nr_rlc_reestablish_entity(rnti, lcid); + nr_rlc_reconfigure_entity(rnti, lcid, rlc_bearer->rlc_Config, rlc_bearer->mac_LogicalChannelConfig); + } else { + rrc->active_RLC_entity[gNB_index][lcid] = true; + AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); + AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, + "Invalid RB for RLC configuration\n"); + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { + NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; + nr_rlc_add_srb(rnti, srb_id, rlc_bearer); + } else { // DRB + NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; + nr_rlc_add_drb(rnti, drb_id, rlc_bearer); + } + } + } + } + nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id, + cellGroupConfig->rlc_BearerToAddModList, + cellGroupConfig->rlc_BearerToReleaseList); +} void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, uint8_t gNB_index, @@ -833,20 +813,7 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t)); } - if(cellGroupConfig->rlc_BearerToReleaseList != NULL){ - //TODO (perform RLC bearer release as specified in 5.3.5.5.3) - } - - if(cellGroupConfig->rlc_BearerToAddModList != NULL){ - //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) - if(rrc->cell_group_config->rlc_BearerToAddModList != NULL){ - // Laurent: there are cases where the not NULL value is also not coming from a previous malloc - // so it is better to let the potential memory leak than corrupting the heap //free(rrc->cell_group_config->rlc_BearerToAddModList); - } - rrc->cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); - memcpy(rrc->cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList, - sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); - } + nr_rrc_manage_rlc_bearers(cellGroupConfig, rrc, gNB_index, ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid); if(cellGroupConfig->mac_CellGroupConfig != NULL){ //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) @@ -955,13 +922,11 @@ void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config) } } -/*--------------------------------------------------*/ -static void rrc_ue_generate_RRCSetupComplete( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - const uint8_t Transaction_id, - uint8_t sel_plmn_id){ - +static void rrc_ue_generate_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id) +{ uint8_t buffer[100]; uint8_t size; const char *nas_msg; @@ -980,47 +945,59 @@ static void rrc_ue_generate_RRCSetupComplete( size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer), Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); - LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); + LOG_I(NR_RRC, + "[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + size, + gNB_index); + int srb_id = 1; // RRC setup complete on SRB1 LOG_D(NR_RRC, - "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB " + "%02d]\n", ctxt_pP->frame, ctxt_pP->module_id, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id + NB_eNB_INST, - DCCH); + srb_id); - //for (int i=0;irntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); } -int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ) +int8_t nr_rrc_ue_decode_ccch(const protocol_ctxt_t *const ctxt_pP, const NR_UE_RRC_SRB_INFO_t *Srb_info, const uint8_t gNB_index) { NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; int rval=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); - LOG_D(RRC,"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",ctxt_pP->module_id,Srb_info->Rx_buffer.payload_size, + LOG_D(RRC, + "[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n", + ctxt_pP->module_id, + Srb_info->srb_buffers.Rx_buffer.payload_size, rrc->nrRrcState); - dec_rval = uper_decode(NULL, - &asn_DEF_NR_DL_CCCH_Message, - (void **)&dl_ccch_msg, - (uint8_t *)Srb_info->Rx_buffer.Payload, - Srb_info->Rx_buffer.payload_size,0,0); + dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **)&dl_ccch_msg, + (uint8_t *)Srb_info->srb_buffers.Rx_buffer.Payload, + Srb_info->srb_buffers.Rx_buffer.payload_size, + 0, + 0); -// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); -// } + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)dl_ccch_msg); + // } - if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { - LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); - return -1; + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, + "[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + dec_rval.consumed); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return -1; } if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { @@ -1159,7 +1136,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, asn_enc_rval_t enc_rval; NR_UL_DCCH_Message_t ul_dcch_msg; uint8_t buffer[200]; - int i, securityMode; + int securityMode; LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index); @@ -1263,7 +1240,11 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, if (securityMode != 0xff) { uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4); - nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc); + // configure lower layers to apply SRB integrity protection and ciphering + for (int i = 1; i < NR_NUM_SRB; i++) { + if (ue_rrc->Srb[gNB_index][i].status == RB_ESTABLISHED) + nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, i, security_mode, kRRCenc, kRRCint, kUPenc); + } } else { LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); } @@ -1290,7 +1271,7 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: "); LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); - for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { + for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(NR_RRC, "%02x.", buffer[i]); } LOG_T(NR_RRC, "\n"); @@ -1298,122 +1279,52 @@ void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP, //TODO the SecurityModeCommand message needs to pass the integrity protection check // for the UE to declare AS security to be activated ue_rrc->as_security_activated = true; - - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); + int srb_id = 1; // SecurityModeComplete in SRB1 + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, + srb_id, + nr_rrc_mui++, + (enc_rval.encoded + 7) / 8, + buffer, + deliver_pdu_srb_rlc, + NULL); } else LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", securityModeCommand->criticalExtensions.present); } - //----------------------------------------------------------------------------- - void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) { - uint8_t i=0,rv[6]; - - if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { - // Get RRCConnectionRequest, fill random for now - // Generate random byte stream for contention resolution - for (i=0; i<6; i++) { - #ifdef SMBV - // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed - rv[i]=i; - #else - rv[i]=taus()&0xff; - #endif - LOG_T(NR_RRC,"%x.",rv[i]); - } - - LOG_T(NR_RRC,"\n"); - NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size = - do_RRCSetupRequest( - module_id, - (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, - sizeof(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload), - rv); - LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", - module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); - - for (i=0; idrb_Identity); - - if(!get_softmodem_params()->sa) { - ip_addr_offset3 = 0; - ip_addr_offset4 = 1; - LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1); - oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id - UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet - ip_addr_offset4+ue_mod_idP+1, // fourth_octet - "oip"); // interface suffix (when using kernel module) - - if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB - LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ue_mod_idP, - ip_addr_offset3+ue_mod_idP, - (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity)); - rb_conf_ipv4(0,//add - ue_mod_idP,//cx align with the UE index - ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index - (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb - 0,//dscp - ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr - ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr - LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index); + uint8_t rv[6]; + NR_UE_RRC_SRB_INFO_t *Srb0 = &NR_UE_rrc_inst[module_id].Srb[gNB_index][0]; + if (Srb0->srb_buffers.Tx_buffer.payload_size == 0) { + // Get RRCConnectionRequest, fill random for now + // Generate random byte stream for contention resolution + for (int i = 0; i < 6; i++) { +#ifdef SMBV + // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed + rv[i] = i; +#else + rv[i] = taus() & 0xff; +#endif + LOG_T(NR_RRC, "%x.", rv[i]); } + + LOG_T(NR_RRC, "\n"); + Srb0->srb_buffers.Tx_buffer.payload_size = do_RRCSetupRequest(module_id, + (uint8_t *)Srb0->srb_buffers.Tx_buffer.Payload, + sizeof(Srb0->srb_buffers.Tx_buffer.Payload), + rv); + LOG_I(NR_RRC, + "[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", + module_id, + Srb0->srb_buffers.Tx_buffer.payload_size, + gNB_index); + + for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++) + LOG_T(NR_RRC, "%x.", Srb0->srb_buffers.Tx_buffer.Payload[i]); + + LOG_T(NR_RRC, "\n"); } - return(0); } //----------------------------------------------------------------------------- @@ -1540,35 +1451,33 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, } } - //----------------------------------------------------------------------------- - void - nr_rrc_ue_process_RadioBearerConfig( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - NR_RadioBearerConfig_t *const radioBearerConfig - ) - //----------------------------------------------------------------------------- + void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + NR_RadioBearerConfig_t *const radioBearerConfig) { - long SRB_id, DRB_id; - int i, cnt; - - if( radioBearerConfig->srb3_ToRelease != NULL){ - if( *radioBearerConfig->srb3_ToRelease == true){ - //TODO (release the PDCP entity and the srb-Identity of the SRB3.) - } - } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig); NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - if (radioBearerConfig->srb_ToAddModList != NULL) { + if (radioBearerConfig->srb3_ToRelease) + nr_release_srb(ctxt_pP->rntiMaybeUEid, 3); + + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + if (ue_rrc->as_security_activated) { if (radioBearerConfig->securityConfig != NULL) { - if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) { - ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; - ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; + // When the field is not included, continue to use the currently configured keyToUse + if (radioBearerConfig->securityConfig->keyToUse) { + AssertFatal(*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master, + "Secondary key usage seems not to be implemented\n"); + ue_rrc->keyToUse = *radioBearerConfig->securityConfig->keyToUse; + } + // When the field is not included, continue to use the currently configured security algorithm + if (radioBearerConfig->securityConfig->securityAlgorithmConfig) { + ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; + ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; } } - - uint8_t kRRCenc[16] = {0}; - uint8_t kRRCint[16] = {0}; nr_derive_key(RRC_ENC_ALG, NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, @@ -1577,137 +1486,65 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, kRRCint); + } - // Refresh SRBs - nr_pdcp_add_srbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - radioBearerConfig->srb_ToAddModList, - ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), - kRRCenc, - kRRCint); - // Refresh SRBs - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, - radioBearerConfig->srb_ToAddModList, - ue_rrc->cell_group_config->rlc_BearerToAddModList); - - for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { - SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity; - LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id); - if (SRB_id == 1) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index], - radioBearerConfig->srb_ToAddModList->list.array[cnt], - sizeof(NR_SRB_ToAddMod_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; - nr_rrc_ue_establish_srb1(ctxt_pP->module_id, - ctxt_pP->frame, - gNB_index, - radioBearerConfig->srb_ToAddModList->list.array[cnt]); - - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); - nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig - // rrc_mac_config_req_ue - } - } else { - if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index], - radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; - nr_rrc_ue_establish_srb2(ctxt_pP->module_id, - ctxt_pP->frame, - gNB_index, - radioBearerConfig->srb_ToAddModList->list.array[cnt]); - - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); - nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig - // rrc_mac_config_req_ue - } - } // srb2 + if (radioBearerConfig->srb_ToAddModList != NULL) { + for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { + struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + NR_UE_RRC_SRB_INFO_t *Srb_info = &ue_rrc->Srb[gNB_index][srb->srb_Identity]; + if (Srb_info->status == RB_NOT_PRESENT) + add_srb(ctxt_pP->enb_flag, + ctxt_pP->rntiMaybeUEid, + radioBearerConfig->srb_ToAddModList->list.array[cnt], + ue_rrc->cipheringAlgorithm, + ue_rrc->integrityProtAlgorithm, + kRRCenc, + kRRCint); + else { + AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n"); + AssertFatal(srb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); + if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering) + nr_pdcp_reconfigure_srb(ctxt_pP->rntiMaybeUEid, srb->srb_Identity, *srb->pdcp_Config->t_Reordering); + } + Srb_info->status = RB_ESTABLISHED; } - } // srb_ToAddModList + } + + if (radioBearerConfig->drb_ToReleaseList) { + for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) { + NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt]; + if (DRB_id) + nr_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id); + } + } // Establish DRBs if present if (radioBearerConfig->drb_ToAddModList != NULL) { - if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && - (radioBearerConfig->drb_ToAddModList->list.count >= 1)) { - NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); - *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity; - } - - for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { - DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity; - if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], - radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); + for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { + struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt]; + int DRB_id = drb->drb_Identity; + if (ue_rrc->active_DRBs[gNB_index][DRB_id]) { + AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n"); + AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n"); + if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering) + nr_pdcp_reconfigure_drb(ctxt_pP->rntiMaybeUEid, DRB_id, *drb->pdcp_Config->t_Reordering); + if (drb->cnAssociation) + AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n"); } else { - //LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); - NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; - int j; - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList; - if (rlc_bearer2add_list != NULL) { - for(j = 0; j < rlc_bearer2add_list->list.count; j++){ - if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){ - if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){ - if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){ - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id); - nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig - } - } - } - } - } + ue_rrc->active_DRBs[gNB_index][DRB_id] = true; + add_drb(ctxt_pP->enb_flag, + ctxt_pP->rntiMaybeUEid, + radioBearerConfig->drb_ToAddModList->list.array[cnt], + ue_rrc->cipheringAlgorithm, + ue_rrc->integrityProtAlgorithm, + kRRCenc, + kRRCint); } } - - uint8_t kUPenc[16] = {0}; - uint8_t kUPint[16] = {0}; - nr_derive_key(UP_ENC_ALG, - NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - kUPenc); - nr_derive_key(UP_INT_ALG, - NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - kUPint); - - // Refresh DRBs - nr_pdcp_add_drbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - radioBearerConfig->drb_ToAddModList, - ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), - kUPenc, - kUPint, - ue_rrc->cell_group_config->rlc_BearerToAddModList); - // Refresh DRBs - nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, - radioBearerConfig->drb_ToAddModList, - ue_rrc->cell_group_config->rlc_BearerToAddModList); - } // drb_ToAddModList // - if (radioBearerConfig->drb_ToReleaseList != NULL) { - for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) { - DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]); - } - } - - if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) { - for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) { - NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i]; - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id); - nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig - } - } - NR_UE_rrc_inst[ctxt_pP->module_id].nrRrcState = RRC_STATE_CONNECTED_NR; - LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); + LOG_I(NR_RRC, "[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); } //----------------------------------------------------------------------------- @@ -1763,53 +1600,54 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, } } - //----------------------------------------------------------------------------- - void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) { + void nr_rrc_ue_generate_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + const int srb_id, + const uint8_t Transaction_id) + { uint8_t buffer[32], size; size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id); - LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index); + LOG_I(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT + " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + gNB_index); + AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id); LOG_D(RLC, - "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", - ctxt_pP->frame, - UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), - size, - gNB_index, - nr_rrc_mui, - UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), - DCCH); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); + "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) " + "--->][PDCP][INST %02d][RB %02d]\n", + ctxt_pP->frame, + UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), + size, + gNB_index, + nr_rrc_mui, + UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), + srb_id); + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL); } - // from NR SRB1 - //----------------------------------------------------------------------------- - int - nr_rrc_ue_decode_dcch( - const protocol_ctxt_t *const ctxt_pP, - const srb_id_t Srb_id, - const uint8_t *const Buffer, - size_t Buffer_size, - const uint8_t gNB_indexP - ) - //----------------------------------------------------------------------------- + int nr_rrc_ue_decode_dcch(const protocol_ctxt_t *const ctxt_pP, + const srb_id_t Srb_id, + const uint8_t *const Buffer, + size_t Buffer_size, + const uint8_t gNB_indexP) + { - asn_dec_rval_t dec_rval; - NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; + asn_dec_rval_t dec_rval; + NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; MessageDef *msg_p; if (Srb_id != 1 && Srb_id != 2) { - LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", - ctxt_pP->module_id, ctxt_pP->frame, Srb_id); + LOG_E(NR_RRC, + "[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", + ctxt_pP->module_id, + ctxt_pP->frame, + Srb_id); } LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); - dec_rval = uper_decode( NULL, - &asn_DEF_NR_DL_DCCH_Message, - (void **)&dl_dcch_msg, - Buffer, - Buffer_size, - 0, - 0); + dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); @@ -1817,8 +1655,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, return -1; } - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg); } if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { @@ -1827,58 +1665,51 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); break; - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: - { - rrc_ue_process_rrcReconfiguration(ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, - gNB_indexP); - nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, - gNB_indexP, - dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: { + rrc_ue_process_rrcReconfiguration(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, gNB_indexP); + nr_rrc_ue_generate_RRCReconfigurationComplete( + ctxt_pP, + gNB_indexP, + Srb_id, + dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); break; } case NR_DL_DCCH_MessageType__c1_PR_rrcResume: case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", - ctxt_pP->module_id, gNB_indexP); + LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); - if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == - NR_RRCRelease__criticalExtensions_PR_rrcRelease) && - (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) { - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + if ((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present + == NR_RRCRelease__criticalExtensions_PR_rrcRelease) + && (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) { + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq + ->deprioritisationTimer = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq + ->deprioritisationType = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; } itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); break; case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id,gNB_indexP); - nr_rrc_ue_process_ueCapabilityEnquiry( - ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, - gNB_indexP); + LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); + nr_rrc_ue_process_ueCapabilityEnquiry(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, gNB_indexP); break; case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: LOG_I(NR_RRC, - "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n", - ctxt_pP->module_id, - ctxt_pP->frame); - nr_rrc_ue_generate_rrcReestablishmentComplete( - ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.rrcReestablishment, - gNB_indexP); + "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n", + ctxt_pP->module_id, + ctxt_pP->frame); + nr_rrc_ue_generate_rrcReestablishmentComplete(ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.rrcReestablishment, + gNB_indexP); break; - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - { + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer; if (dlInformationTransfer->criticalExtensions.present - == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { + == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { /* This message hold a dedicated info NAS payload, forward it to NAS */ NR_DedicatedNAS_Message_t *dedicatedNAS_Message = dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; @@ -1890,8 +1721,7 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf; itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p); } - } - break; + } break; case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: @@ -1903,11 +1733,8 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, case NR_DL_DCCH_MessageType__c1_PR_counterCheck: break; case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", - ctxt_pP->module_id, gNB_indexP); - nr_rrc_ue_process_securityModeCommand(ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.securityModeCommand, - gNB_indexP); + LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", ctxt_pP->module_id, gNB_indexP); + nr_rrc_ue_process_securityModeCommand(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.securityModeCommand, gNB_indexP); break; } } @@ -1932,7 +1759,6 @@ void *rrc_nrue_task(void *args_p) instance_t instance; unsigned int ue_mod_id; int result; - NR_SRB_INFO *srb_info_p; protocol_ctxt_t ctxt; itti_mark_task_ready(TASK_RRC_NRUE); @@ -2008,15 +1834,12 @@ void *rrc_nrue_task(void *args_p) ITTI_MSG_NAME (msg_p), NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); - srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index]; - memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); - srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size; + NR_UE_RRC_SRB_INFO_t *srb0 = &NR_UE_rrc_inst[ue_mod_id].Srb[NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index][0]; + memcpy(srb0->srb_buffers.Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); + srb0->srb_buffers.Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0); // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); - nr_rrc_ue_decode_ccch (&ctxt, - srb_info_p, - NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + nr_rrc_ue_decode_ccch(&ctxt, srb0, NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index); break; /* PDCP messages */ @@ -2077,8 +1900,8 @@ void *rrc_nrue_task(void *args_p) length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); /* Transfer data to PDCP */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0); - // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) - rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL ? DCCH : DCCH1; + // check if SRB2 is created, if yes request data_req on SRB2 + rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1; nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL); break; } @@ -2115,14 +1938,9 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig( } } -//----------------------------------------------------------------------------- -void -nr_rrc_ue_process_ueCapabilityEnquiry( - const protocol_ctxt_t *const ctxt_pP, - NR_UECapabilityEnquiry_t *UECapabilityEnquiry, - uint8_t gNB_index -) -//----------------------------------------------------------------------------- +void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, + NR_UECapabilityEnquiry_t *UECapabilityEnquiry, + uint8_t gNB_index) { asn_enc_rval_t enc_rval; asn_dec_rval_t dec_rval; @@ -2131,7 +1949,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( char UE_NR_Capability_xer[65536]; size_t size; uint8_t buffer[500]; - int i; LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n", ctxt_pP->module_id, ctxt_pP->frame, @@ -2139,10 +1956,10 @@ nr_rrc_ue_process_ueCapabilityEnquiry( memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t)); - ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation)); + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation)); ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; NR_UE_NR_Capability_t* UE_Capability_nr = NULL; @@ -2193,8 +2010,9 @@ nr_rrc_ue_process_ueCapabilityEnquiry( (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); + NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry; if (get_softmodem_params()->nsa == 1) { - OCTET_STRING_t * requestedFreqBandsNR = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityEnquiryExt; + OCTET_STRING_t *requestedFreqBandsNR = ueCapabilityEnquiry_ie->ue_CapabilityEnquiryExt; nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO); } // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; @@ -2203,27 +2021,34 @@ nr_rrc_ue_process_ueCapabilityEnquiry( "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry); - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation; - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs)); - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList = CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList)); - ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0; + NR_UECapabilityInformation_t *ueCapabilityInformation = ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation; + ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation; + ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation = + CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs)); + ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList = + CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList)); + ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0; - for (i=0; icriticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.count; i++) { - if (UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type - == NR_RAT_Type_nr) { - asn1cSeqAdd( - &ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list, - &ue_CapabilityRAT_Container); + for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) { + if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) { + asn1cSeqAdd(&ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list, + &ue_CapabilityRAT_Container); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } - LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); + int srb_id = 1; // UECapabilityInformation on SRB1 + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, + srb_id, + nr_rrc_mui++, + (enc_rval.encoded + 7) / 8, + buffer, + deliver_pdu_srb_rlc, + NULL); } } } diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 89dac531a5..03b983d7ed 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -39,6 +39,7 @@ #include "platform_types.h" #include "commonDef.h" +#include "common/platform_constants.h" #include "NR_asn_constant.h" #include "NR_MeasConfig.h" @@ -56,11 +57,10 @@ #include "RRC/NR/nr_rrc_common.h" #include "as_message.h" +#include "common/utils/nr/nr_common.h" #define NB_NR_UE_INST 1 #define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE -#define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE - #define MAX_MEAS_OBJ 7 #define MAX_MEAS_CONFIG 7 #define MAX_MEAS_ID 7 @@ -178,6 +178,13 @@ typedef enum { IN_SYNC = 1 } nr_sync_msg_t; +typedef enum { RB_NOT_PRESENT, RB_ESTABLISHED, RB_SUSPENDED } NR_RB_status_t; + +typedef struct NR_UE_RRC_SRB_INFO_s { + NR_RB_status_t status; + NR_SRB_INFO srb_buffers; +} NR_UE_RRC_SRB_INFO_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; NR_CellGroupConfig_t *cell_group_config; @@ -191,17 +198,13 @@ typedef struct NR_UE_RRC_INST_s { NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID]; NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE]; NR_RSRP_Range_t s_measure; - NR_SRB_ToAddMod_t *SRB1_config[NB_CNX_UE]; - NR_SRB_ToAddMod_t *SRB2_config[NB_CNX_UE]; - NR_DRB_ToAddMod_t *DRB_config[NB_CNX_UE][8]; - rb_id_t *defaultDRB; // remember the ID of the default DRB char *uecap_file; rnti_t rnti; - NR_SRB_INFO Srb0[NB_SIG_CNX_UE]; - NR_SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE]; - NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; + NR_UE_RRC_SRB_INFO_t Srb[NB_CNX_UE][NR_NUM_SRB]; + bool active_DRBs[NB_CNX_UE][MAX_DRBS_PER_UE]; + bool active_RLC_entity[NB_CNX_UE][NR_MAX_NUM_LCID]; OAI_NR_UECapability_t *UECap; uint8_t *UECapability; @@ -213,7 +216,7 @@ typedef struct NR_UE_RRC_INST_s { plmn_t plmnID; - NR_UE_RRC_SI_INFO SInfo[NB_SIG_CNX_UE]; + NR_UE_RRC_SI_INFO SInfo[NB_CNX_UE]; NR_MIB_t *mib; @@ -227,6 +230,7 @@ typedef struct NR_UE_RRC_INST_s { //RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list; NR_CipheringAlgorithm_t cipheringAlgorithm; e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; + long keyToUse; bool as_security_activated; long selected_plmn_identity; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index df2d44a996..d04830192c 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -65,14 +65,6 @@ NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *); /**\brief Initial the top level RRC structure instance*/ NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *); -/**\brief Decode RRC Connection Reconfiguration, sent from E-UTRA RRC Connection Reconfiguration v1510 carring EN-DC config - \param buffer encoded NR-RRC-Connection-Reconfiguration/Secondary-Cell-Group-Config message. - \param size length of buffer*/ -//TODO check to use which one -//int8_t nr_rrc_ue_decode_rrcReconfiguration(const uint8_t *buffer, const uint32_t size); -int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, const uint8_t *buffer, const uint32_t size); - - /**\brief Process NR RRC connection reconfiguration via SRB3 \param rrcReconfiguration decoded rrc connection reconfiguration*/ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration); @@ -81,9 +73,9 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR \param meas_config measurement configuration*/ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config); -/**\prief Process radio bearer config from NR RRC connection reconfiguration message - \param radio_bearer_config radio bearer configuration*/ -int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_bearer_config); +void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + NR_RadioBearerConfig_t *const radioBearerConfig); /**\brief decode NR BCCH-BCH (MIB) message \param module_idP module id @@ -171,6 +163,12 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants); +void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig, + NR_UE_RRC_INST_t *rrc, + int gNB_index, + module_id_t module_id, + int rnti); + int configure_NR_SL_Preconfig(int sync_source); /** @}*/ #endif