From 4277d4e1bb5a82aa0eda2e6d08eb39ccc83e071f Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 26 Jul 2021 14:08:16 +0200 Subject: [PATCH 01/11] Fixes to UE ULSCH PDU generation - included MAC CE sub-PDUs size in the computation of RLC data to transmit this fixes the error with residual mac pdu appearing at gNB side when transmitting higher amount of data - got rid of the nr_generate_ulsch_pdu and moved the relevant UL-SCH MAC PDU generation procedure within the nr_ue_get_sdu and nr_ue_get_rach - reduced memcpy calls and unnecessary memory allocations - fetching RLC data and SDU size from the mac_rlc_data_req, removed the call to mac_rlc_get_buffer_occupancy_ind - introduced a new function to generate the MAC CEs sub-PDUs - removed unnecessary function input parameters - minor fixes and cleanup - enhanced logging --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 10 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 24 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 117 +++++---- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 189 ++++++--------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 237 ++++++++++++------- 5 files changed, 297 insertions(+), 280 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index fc02662a63..d3917b345c 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -390,6 +390,16 @@ typedef struct { } NR_UE_MAC_INST_t; +typedef struct { + + uint8_t power_headroom; + uint16_t crnti; + uint16_t truncated_bsr; + uint16_t short_bsr; + uint16_t long_bsr; + +} NR_UE_MAC_CE_t; + typedef enum seach_space_mask_e { type0_pdcch = 0x1, type0a_pdcch = 0x2, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 2d00aa0003..e546fb9fc0 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -156,18 +156,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); -uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, - uint8_t *pdu, - uint8_t num_sdus, - uint16_t *sdu_lengths, - uint8_t *sdu_lcids, - uint8_t power_headroom, - uint16_t crnti, - uint16_t truncated_bsr, - uint16_t short_bsr, - uint16_t long_bsr, - unsigned short post_padding, - uint16_t buflen); +int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, + NR_UE_MAC_CE_t *nr_ue_mac_ce); void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); @@ -188,10 +178,12 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind, bool use_default); -uint8_t -nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, - uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) ; +uint8_t nr_ue_get_sdu(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen); int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu, int nrofDownlinkSlots, int nrofDownlinkSymbols, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 5d9126ad69..ae361591d2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -474,23 +474,19 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint } -///////////////////////////////////////////////////////////////////////// -// This function handles: -// - Random Access Preamble Initialization (5.1.1 TS 38.321) -// - Random Access Response reception (5.1.4 TS 38.321) -/// In the current implementation, RA is 4-step contention free only -///////////////////////////////////////////////////////////////////////// -// todo TS 38.321: -// - BWP operation (subclause 5.15 TS 38.321) -// - beam failure recovery -// - handle initialization by handover -// - handle DL assignment on PDCCH for RA-RNTI -// - transmission on DCCH using PRACH (during handover, or sending SR for example) -// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader) -// - fix rrc data req logic -// - retrieve TBS -// - add mac_rrc_nr_data_req_ue, etc ... -// - Msg3 Retransmissions to be scheduled by DCI 0_0 +/** + * Function: handles Random Access Preamble Initialization (5.1.1 TS 38.321) + * handles Random Access Response reception (5.1.4 TS 38.321) + * Note: In the current implementation, RA is 4-step contention free only + * + * @prach_resources pointer to PRACH resources + * @prach_pdu pointer to FAPI UL PRACH PDU + * @mod_id module ID + * @CC_id CC ID + * @frame current UL TX frame + * @gNB_id gNB ID + * @nr_slot_tx current UL TX slot + */ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, @@ -501,11 +497,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; uint8_t lcid = UL_SCH_LCID_CCCH; - uint8_t *payload; - uint16_t size_sdu = 0; - unsigned short post_padding; + uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_SHORT); + int8_t size_sdu = 0; + NR_RACH_ConfigCommon_t *setup; if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; else setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; @@ -513,11 +508,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; - uint8_t sdu_lcids[NB_RB_MAX] = {0}; - uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int num_sdus = 0; - int offset = 0; - // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){ @@ -528,22 +518,26 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } } - LOG_D(NR_MAC,"frame %d prach_resources->init_msg1 %d, ra->ra_state %d, ra->RA_active %d\n", - frame,prach_resources->init_msg1,ra->ra_state,ra->RA_active); + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: init_msg1 %d, ra_state %d, RA_active %d\n", + __FUNCTION__, + mod_id, + frame, + nr_slot_tx, + prach_resources->init_msg1, + ra->ra_state, + ra->RA_active); if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) { if (ra->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ - LOG_D(NR_MAC, "RA not active. Checking for data to transmit from upper layers...\n"); + LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__); - uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); - payload = (uint8_t*) mac->CCCH_pdu.payload; - - num_sdus = 1; - post_padding = 1; - sdu_lcids[0] = lcid; + uint8_t TBS_max = 8 + 2 * sh_size; + uint8_t *pdu = (uint8_t*) mac->CCCH_pdu.payload; + NR_MAC_SUBHEADER_SHORT *header = (NR_MAC_SUBHEADER_SHORT *) pdu; + pdu += sh_size; // initialisation by RRC @@ -553,57 +547,56 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } // CCCH PDU - size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus); + size_sdu = nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, pdu); - sdu_lengths[0] = size_sdu; - - LOG_D(NR_MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: Requested RRCConnectionRequest, got %d bytes for LCID 0x%02x \n", __FUNCTION__, mod_id, frame, nr_slot_tx, size_sdu, lcid); if (size_sdu > 0) { // UE Contention Resolution Identity // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the // Random Access Procedure has been successful after reception of Msg4 - memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6); + memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6); - LOG_D(NR_MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx); + pdu += size_sdu; - ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); + + ra->Msg3_size = size_sdu + sh_size; + + AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); - prach_resources->Msg3 = payload; + prach_resources->Msg3 = (uint8_t*) mac->CCCH_pdu.payload; nr_get_RA_window(mac); // Fill in preamble and PRACH resources if (ra->generate_nr_prach == GENERATE_PREAMBLE) { nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); } - offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer - (uint8_t *) payload, // UL MAC pdu pointer - num_sdus, // num sdus - sdu_lengths, // sdu length - sdu_lcids, // sdu lcid - 0, // power headroom - 0, // crnti - 0, // truncated bsr - 0, // short bsr - 0, // long_bsr - post_padding, - 0); - AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n"); + header->R = 0; + header->F = 0; + header->LCID = lcid; + header->L = (unsigned char) size_sdu; // Padding: fill remainder with 0 - if (post_padding > 0){ - for (int j = 0; j < (TBS_max - offset); j++) - payload[offset + j] = 0; + if (TBS_max - ra->Msg3_size > 0) { + LOG_D(NR_MAC, "In %s: remaining %d bytes, filling with padding\n", __FUNCTION__, TBS_max - ra->Msg3_size); + ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; + pdu += sizeof(NR_MAC_SUBHEADER_FIXED); + for (int j = 0; j < TBS_max - ra->Msg3_size - sizeof(NR_MAC_SUBHEADER_FIXED); j++) { + pdu[j] = 0; + } } + } else { + pdu -= sh_size; } - LOG_D(MAC,"size_sdu = %i\n", size_sdu); - LOG_D(MAC,"offset = %i\n", offset); + LOG_D(NR_MAC, "In %s: dumping UL Msg3 MAC PDU with length %d: \n", __FUNCTION__, TBS_max); for(int k = 0; k < TBS_max; k++) { - LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); + LOG_D(NR_MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); } // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index a72d7dc23d..5d42ac7ea2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1137,14 +1137,6 @@ void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - for (i = 0; i < 32; i++) { - LOG_T(MAC, "%x.", sdu[i]); - } - LOG_T(MAC, "\n"); - #endif - LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot); // Processing MAC PDU @@ -2149,145 +2141,116 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, } } -//////////////////////////////////////////////////////// -/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) *///// -//////////////////////////////////////////////////////// +// about: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU +// returns: number of written bytes +/** + * Function: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU + * @mac_ce pointer to the MAC sub-PDUs including the MAC CEs + * @nr_ue_mac_ce pointer to the MAC CEs to be transmitted + */ +int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, + NR_UE_MAC_CE_t *nr_ue_mac_ce) { -uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, - uint8_t *pdu, - uint8_t num_sdus, - uint16_t *sdu_lengths, - uint8_t *sdu_lcids, - uint8_t power_headroom, - uint16_t crnti, - uint16_t truncated_bsr, - uint16_t short_bsr, - uint16_t long_bsr, - unsigned short post_padding, - uint16_t buflen) { + int mac_ce_len = 0; + uint8_t mac_ce_size = 0; - NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu; + if (nr_ue_mac_ce->power_headroom) { - LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus); + LOG_D(NR_MAC, "In %s: generating PHR MAC CE with command %d\n", __FUNCTION__, nr_ue_mac_ce->power_headroom); - #ifdef DEBUG_HEADER_PARSING - - for (int i = 0; i < num_sdus; i++) - LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]); - - #endif - - // Generating UL MAC subPDUs including MAC SDU and subheader - - for (int i = 0; i < num_sdus; i++) { - LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus); - - if (sdu_lcids[i] != UL_SCH_LCID_CCCH){ - if (sdu_lengths[i] < 128) { - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; - mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_SHORT); - } else { - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; - mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_LONG); - } - } else { // UL CCCH SDU - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = sdu_lcids[i]; - mac_pdu_ptr ++; - } - - // cycle through SDUs, compute each relevant and place ulsch_buffer in - memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]); - sdus_payload += sdu_lengths[i]; - mac_pdu_ptr += sdu_lengths[i]; - } - - // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader) - - if (power_headroom) { // MAC CE fixed subheader - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR; - mac_pdu_ptr++; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR; + mac_ce++; // PHR MAC CE (1 octet) - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PH = power_headroom; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R1 = 0; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PCMAX = 0; // todo - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R2 = 0; - mac_pdu_ptr += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = nr_ue_mac_ce->power_headroom; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0; + + // update pointer and length + mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); + mac_ce += mac_ce_size; + mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + } - if (crnti) { + if (nr_ue_mac_ce->crnti) { + + LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, nr_ue_mac_ce->crnti); + // MAC CE fixed subheader - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = UL_SCH_LCID_C_RNTI; - mac_pdu_ptr++; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_C_RNTI; + mac_ce++; // C-RNTI MAC CE (2 octets) - * (uint16_t *) mac_pdu_ptr = crnti; - mac_pdu_ptr += sizeof(uint16_t); + *(uint16_t *) mac_ce = nr_ue_mac_ce->crnti; + + // update pointer and length + mac_ce_size = sizeof(uint16_t); + mac_ce += mac_ce_size; + mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + } - if (truncated_bsr) { + if (nr_ue_mac_ce->truncated_bsr) { + + LOG_D(NR_MAC, "In %s: generating Truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr); + // MAC CE fixed subheader - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; - mac_pdu_ptr++; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; + mac_ce++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> Buffer_size = truncated_bsr; - ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> LcgID = 0; // todo - mac_pdu_ptr+= sizeof(NR_BSR_SHORT_TRUNCATED); - } else if (short_bsr) { + ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = nr_ue_mac_ce->truncated_bsr; + ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0; + + // update pointer and length + mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); + mac_ce += mac_ce_size; + mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + + } else if (nr_ue_mac_ce->short_bsr) { + + LOG_D(NR_MAC, "In %s: generating Truncated short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr); + // MAC CE fixed subheader - mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = UL_SCH_LCID_S_BSR; - mac_pdu_ptr++; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR; + mac_ce++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT *) mac_pdu_ptr)->Buffer_size = short_bsr; - ((NR_BSR_SHORT *) mac_pdu_ptr)->LcgID = 0; // todo - mac_pdu_ptr+= sizeof(NR_BSR_SHORT); - } else if (long_bsr) { + ((NR_BSR_SHORT *) mac_ce)->Buffer_size = nr_ue_mac_ce->short_bsr; + ((NR_BSR_SHORT *) mac_ce)->LcgID = 0; + + // update pointer and length + mac_ce_size = sizeof(NR_BSR_SHORT); + mac_ce += mac_ce_size; + mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + + } else if (nr_ue_mac_ce->long_bsr) { // MAC CE variable subheader // todo ch 6.1.3.1. TS 38.321 // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR; // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0; - // last_size = 2; - // mac_pdu_ptr += last_size; + // sh_size = 2; // Short truncated BSR MAC CE (1 octet) - // ((NR_BSR_LONG *) ce_ptr)->Buffer_size0 = short_bsr; - // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0; + // ((NR_BSR_LONG *) mac_ce)->Buffer_size0 = short_bsr; + // ((NR_BSR_LONG *) mac_ce)->LCGID0 = 0; // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable } -// compute offset before adding padding (if necessary) - int padding_bytes = 0; - if(buflen > 0) // If the buflen is provided - padding_bytes = buflen + pdu - (unsigned char *) mac_pdu_ptr; + return mac_ce_len; - AssertFatal(padding_bytes>=0,""); - - // Compute final offset for padding - if (post_padding || padding_bytes>0) { - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; - mac_pdu_ptr++; - } - return (uint8_t *)mac_pdu_ptr-pdu; } + ///////////////////////////////////// // Random Access Response PDU // // TS 38.213 ch 8.2 // diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 8916555f18..4a174057ef 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -989,7 +989,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in frame_t frame_tx = ul_info->frame_tx; slot_t slot_tx = ul_info->slot_tx; module_id_t mod_id = ul_info->module_id; - uint8_t access_mode = SCHEDULED_ACCESS; + uint32_t gNB_index = ul_info->gNB_index; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; @@ -1036,19 +1036,18 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // Getting IP traffic to be transmitted data_existing = nr_ue_get_sdu(mod_id, - cc_id, frame_tx, slot_tx, - 0, + gNB_index, ulsch_input_buffer, - TBS_bytes, - &access_mode); + TBS_bytes); } LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; + // TBR use the proper function ! //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity if (!data_existing) { //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid @@ -1965,114 +1964,174 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s } // if is_nr_UL_slot } -#define MAX_LCID 8 //Fixme: also defined in LCID table -uint8_t -nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, - uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { - uint8_t total_rlc_pdu_header_len = 0; +#define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID + +/** + * Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer + to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321) + the selected sub-header for the payload sub-PDUs is NR_MAC_SUBHEADER_LONG + * @module_idP Module ID + * @frameP current UL frame + * @subframe current UL slot + * @gNB_index gNB index + * @ulsch_buffer Pointer to ULSCH PDU + * @buflen TBS + */ +uint8_t nr_ue_get_sdu(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen) { + int16_t buflen_remain = 0; uint8_t lcid = 0; uint16_t sdu_lengths[MAX_LCID] = { 0 }; - uint8_t sdu_lcids[MAX_LCID] = { 0 }; - uint16_t payload_offset = 0, num_sdus = 0; - uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; + uint16_t num_sdus = 0; uint16_t sdu_length_total = 0; - //unsigned short post_padding = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); - rlc_buffer_occupancy_t lcid_buffer_occupancy_new = 0; - LOG_D(NR_MAC, - "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", - module_idP, frameP, subframe, buflen); - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); + // Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer + uint8_t *pdu = ulsch_buffer; + + // Preparing the MAC CEs sub-PDUs and get the total size + unsigned char mac_header_control_elements[16] = {0}; + NR_UE_MAC_CE_t nr_ue_mac_ce = {.crnti = mac->crnti}; + int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], &nr_ue_mac_ce); + uint8_t total_mac_pdu_header_len = tot_mac_ce_len; + + LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen); // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) { - lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP, mac->crnti, eNB_index, frameP, subframe, ENB_FLAG_NO, lcid); - if(lcid_buffer_occupancy_new) { - buflen_remain = - buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); - LOG_D(NR_MAC, - "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " - "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d - module_idP, frameP, lcid, lcid_buffer_occupancy_new, - buflen, sdu_length_total, - total_rlc_pdu_header_len, buflen_remain); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); - while(buflen_remain > 0 && lcid_buffer_occupancy_new){ + 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__, + module_idP, + frameP, + subframe, + lcid, + buflen, + sdu_length_total, + tot_mac_ce_len, + buflen_remain); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - mac->crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - buflen_remain-MAX_RLC_SDU_SUBHEADER_SIZE, - //Fixme: Laurent I removed MAX_RLC_SDU_SUBHEADER_SIZE because else we get out the buffer silently - // the interface with nr_generate_ulsch_pdu() looks over complex and not CPU optimized - (char *)&ulsch_sdus[sdu_length_total],0, - 0); + while (buflen_remain > 0){ - AssertFatal(buflen_remain >= sdu_lengths[num_sdus], - "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", - lcid, sdu_lengths[num_sdus], buflen_remain); + // 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; - if (sdu_lengths[num_sdus]) { - sdu_length_total += sdu_lengths[num_sdus]; - sdu_lcids[num_sdus] = lcid; + pdu += sh_size; - total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last; + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + mac->crnti, + gNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)pdu, + 0, + 0); - //Update number of SDU - num_sdus++; - } + AssertFatal(buflen_remain >= sdu_lengths[num_sdus], "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", + __FUNCTION__, + lcid, + sdu_lengths[num_sdus], + buflen_remain); - /* Get updated BO after multiplexing this PDU */ - lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,mac->crnti,eNB_index,frameP, subframe, ENB_FLAG_NO, lcid); - buflen_remain = buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + if (sdu_lengths[num_sdus]) { + + LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, + num_sdus + 1, + sdu_lengths[num_sdus], + lcid, + buflen); + + header->R = 0; + header->F = 1; + header->LCID = lcid; + header->L1 = ((unsigned short) sdu_lengths[num_sdus] >> 8) & 0x7f; + header->L2 = (unsigned short) sdu_lengths[num_sdus] & 0xff; + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size); + log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_lengths[num_sdus]); + log_dump(NR_MAC, pdu, sdu_lengths[num_sdus], LOG_DUMP_CHAR, "\n"); + #endif + + pdu += sdu_lengths[num_sdus]; + sdu_length_total += sdu_lengths[num_sdus]; + total_mac_pdu_header_len += sh_size; + + num_sdus++; + + } else { + pdu -= sh_size; + LOG_D(MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); + break; } + + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + } } - // Generate ULSCH PDU - if (num_sdus>0) { - payload_offset = nr_generate_ulsch_pdu(ulsch_sdus, - ulsch_buffer, // mac header - num_sdus, // num sdus - sdu_lengths, // sdu length - sdu_lcids, // sdu lcid - 0, // power_headroom - mac->crnti, // crnti - 0, // truncated_bsr - 0, // short_bsr - 0, // long_bsr - 0, // post_padding - buflen); // TBS in bytes - } else { - return 0; + if (num_sdus > 0) { + + if (tot_mac_ce_len > 0) { + + LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); + memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len); + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); + pdu += (unsigned char) tot_mac_ce_len; + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len); + log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); + #endif + + } + + // Compute final offset for padding and fill remainder of ULSCH with 0 + if (buflen_remain > 0) { + + ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED)); + log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); + #endif + + pdu++; + buflen_remain--; + + for (int j = 0; j < buflen_remain; j++) { + pdu[j] = 0; + } + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain); + log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); + #endif + + } + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen); + log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); + #endif + } - // Padding: fill remainder of ULSCH with 0 - if (buflen - payload_offset > 0){ - for (int j = payload_offset; j < buflen; j++) - ulsch_buffer[j] = 0; - } + return num_sdus > 0 ? 1 : 0; -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(NR_MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset); - for (int i = 0; i < buflen ; i++) { - //harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - printf("%02x ",(unsigned char)ulsch_buffer[i]); - } - printf("\n"); -#endif - - return 1; } From 5cfa2cd2f49581652b7c6b2c45ede7850f78061e Mon Sep 17 00:00:00 2001 From: cig Date: Wed, 28 Jul 2021 07:55:36 +0200 Subject: [PATCH 02/11] Removed OAI exit in mac_rlc_data_req when no RB is present - this prevents crashes when the function is called for LCIDs that have no RB - and simply print error message and return 0 when no RB is found --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index fb657bf5a8..92d7b213db 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -208,7 +208,10 @@ tbs_size_t mac_rlc_data_req( switch (channel_idP) { case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; case 4 ... 8: rb = ue->drb[channel_idP - 4]; break; - default: rb = NULL; break; + default: + rb = NULL; + LOG_E(RLC, "In %s:%d:%s: data request for unknown RB with LCID 0x%02x !\n", __FILE__, __LINE__, __FUNCTION__, channel_idP); + break; } if (rb != NULL) { @@ -216,8 +219,6 @@ tbs_size_t mac_rlc_data_req( maxsize = tb_sizeP; ret = rb->generate_pdu(rb, buffer_pP, maxsize); } else { - LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB, channel_idP: %d\n", __FILE__, __LINE__, __FUNCTION__, channel_idP); - exit(1); ret = 0; } From 021788c7a76c1b64888ce623f246d5ef02d42f7a Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 29 Jul 2021 14:25:14 +0200 Subject: [PATCH 03/11] Improved logging in the MAC PDU processing function at gNB - improved debug logging - minor fixes and cleanup --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 163 ++++++++++-------- 1 file changed, 89 insertions(+), 74 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fbd8a4b5ca..11d2090094 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -174,60 +174,63 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub tdd->nrofUplinkSlots); } +// For both UL-SCH except: +// - UL-SCH: fixed-size MAC CE(known by LCID) +// - UL-SCH: padding +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// | L | +// +// For: +// - UL-SCH: fixed-size MAC CE(known by LCID) +// - UL-SCH: padding, for single/multiple 1-oct padding CE(s) +// - UL-SCH: MSG3 48-bits +// |0|1|2|3|4|5|6|7| bit-wise +// |R|R| LCID | +// +// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; +// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; +// F: length of L is 0:8 or 1:16 bits wide +// R: Reserved bit, set to zero. + void nr_process_mac_pdu(module_id_t module_idP, int UE_id, uint8_t CC_id, frame_t frameP, sub_frame_t slot, uint8_t *pduP, - uint16_t mac_pdu_len) + int pdu_len) { - // This function is adapting code from the old - // parse_header(...) and ue_send_sdu(...) functions of OAI LTE - - uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; - int pdu_len = mac_pdu_len; - uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; + uint8_t rx_lcid; + uint8_t done = 0; + uint16_t mac_ce_len; + uint16_t mac_subheader_len; + uint16_t mac_sdu_len; NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; if ( pduP[0] != UL_SCH_LCID_PADDING ) - trace_NRpdu(DIRECTION_UPLINK, pduP, mac_pdu_len ,UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0); + trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0); - // For both DL/UL-SCH - // Except: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // | L | - - // For both DL/UL-SCH - // For: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|R| LCID | - // LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; - // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; - // F: lenght of L is 0:8 or 1:16 bits wide - // R: Reserved bit, set to zero. + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot); + log_dump(NR_MAC, pduP, pdu_len, LOG_DUMP_CHAR, "\n"); + #endif while (!done && pdu_len > 0){ mac_ce_len = 0; - mac_subheader_len = 1; // default to fixed-length subheader = 1-oct + mac_subheader_len = sizeof(NR_MAC_SUBHEADER_FIXED); mac_sdu_len = 0; - rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID; - LOG_D(NR_MAC, "LCID received at gNB side: %d \n", rx_lcid); + LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len); unsigned char *ce_ptr; int n_Lcg = 0; @@ -236,7 +239,7 @@ void nr_process_mac_pdu(module_id_t module_idP, // MAC CE /*#ifdef DEBUG_HEADER_PARSING - LOG_D(NR_MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + LOG_D(NR_MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID, pdu_len); #endif*/ case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: // 38.321 Ch6.1.3.20 @@ -252,7 +255,7 @@ void nr_process_mac_pdu(module_id_t module_idP, //fixed length mac_ce_len =1; /* Extract short BSR value */ - ce_ptr = &pdu_ptr[mac_subheader_len]; + ce_ptr = &pduP[mac_subheader_len]; NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr; sched_ctrl->estimated_ul_buffer = 0; sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size]; @@ -270,14 +273,14 @@ void nr_process_mac_pdu(module_id_t module_idP, case UL_SCH_LCID_L_TRUNCATED_BSR: //38.321 section 6.1.3.1 //variable length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } /* Extract long BSR value */ - ce_ptr = &pdu_ptr[mac_subheader_len]; + ce_ptr = &pduP[mac_subheader_len]; NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr; sched_ctrl->estimated_ul_buffer = 0; @@ -290,18 +293,18 @@ void nr_process_mac_pdu(module_id_t module_idP, for (int n = 0; n < n_Lcg; n++){ LOG_D(NR_MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d", - n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n], - NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]); + n, n_Lcg, pduP[mac_subheader_len + 1 + n], + NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]]); sched_ctrl->estimated_ul_buffer += - NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]; + NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]]; LOG_D(NR_MAC, "LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n", frameP, slot, n, n_Lcg, - pdu_ptr[mac_subheader_len + 1 + n], - NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]], + pduP[mac_subheader_len + 1 + n], + NR_LONG_BSR_TABLE[pduP[mac_subheader_len + 1 + n]], sched_ctrl->estimated_ul_buffer); } @@ -319,7 +322,7 @@ void nr_process_mac_pdu(module_id_t module_idP, //fixed length mac_ce_len = 2; /* Extract SINGLE ENTRY PHR elements for PHR calculation */ - ce_ptr = &pdu_ptr[mac_subheader_len]; + ce_ptr = &pduP[mac_subheader_len]; NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr; /* Save the phr info */ const int PH = phr->PH; @@ -338,10 +341,10 @@ void nr_process_mac_pdu(module_id_t module_idP, case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: //38.321 section 6.1.3.9 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } /* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */ @@ -350,10 +353,10 @@ void nr_process_mac_pdu(module_id_t module_idP, case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: //38.321 section 6.1.3.9 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } /* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */ @@ -366,13 +369,13 @@ void nr_process_mac_pdu(module_id_t module_idP, case UL_SCH_LCID_SRB1: case UL_SCH_LCID_SRB2: - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; } LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, UE_info->rnti[UE_id]); @@ -383,7 +386,7 @@ void nr_process_mac_pdu(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), + (char *) (pduP + mac_subheader_len), mac_sdu_len, 1, NULL); @@ -404,7 +407,7 @@ void nr_process_mac_pdu(module_id_t module_idP, // Check if it is a valid CCCH1 message, we get all 00's messages very often int i = 0; for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) { - if(pdu_ptr[i] != 0) { + if(pduP[i] != 0) { break; } } @@ -425,35 +428,34 @@ void nr_process_mac_pdu(module_id_t module_idP, 0, UE_info->rnti[UE_id], CCCH, - pdu_ptr+mac_subheader_len, + pduP + mac_subheader_len, mac_sdu_len, 0); break; case UL_SCH_LCID_DTCH: // check if LCID is valid at current time. - if (((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F) { - // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if (((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2 & 0xff); + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pduP)->L2 & 0xff); } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; } - LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n", + LOG_D(NR_MAC, "In %s: [UE %d] %d.%d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n", + __func__, module_idP, frameP, + slot, rx_lcid<4?"DCCH":"DTCH", rx_lcid, module_idP, mac_sdu_len); UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - log_dump(NR_MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); -#endif mac_rlc_data_ind(module_idP, UE_info->rnti[UE_id], @@ -462,7 +464,7 @@ void nr_process_mac_pdu(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcid, - (char *)(pdu_ptr + mac_subheader_len), + (char *)(pduP + mac_subheader_len), mac_sdu_len, 1, NULL); @@ -479,14 +481,27 @@ void nr_process_mac_pdu(module_id_t module_idP, return; break; } - pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) { + LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid); + log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_sdu_len, rx_lcid); + log_dump(NR_MAC, pduP + mac_subheader_len, mac_sdu_len, LOG_DUMP_CHAR, "\n"); + } else { + LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_ce_len, rx_lcid); + log_dump(NR_MAC, pduP + mac_subheader_len + mac_sdu_len, mac_ce_len, LOG_DUMP_CHAR, "\n"); + } + #endif + + pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); if (pdu_len < 0) { - LOG_E(NR_MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len); + LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len); LOG_E(NR_MAC, "MAC PDU "); for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes - printf("%02x ", pdu_ptr[i]); + printf("%02x ", pduP[i]); printf("\n"); return; } From 02012e77eeb82fda9ae8713a445db7c5ee5cc142 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 29 Jul 2021 15:26:12 +0200 Subject: [PATCH 04/11] Minor MAC UE fixes - set constant variables to const --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 6 +++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index ae361591d2..8ee1e90077 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -497,8 +497,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - uint8_t lcid = UL_SCH_LCID_CCCH; - uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_SHORT); int8_t size_sdu = 0; NR_RACH_ConfigCommon_t *setup; @@ -534,7 +532,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__); - uint8_t TBS_max = 8 + 2 * sh_size; + const uint8_t lcid = UL_SCH_LCID_CCCH; + const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_SHORT); + const uint8_t TBS_max = 8 + 2 * sh_size; uint8_t *pdu = (uint8_t*) mac->CCCH_pdu.payload; NR_MAC_SUBHEADER_SHORT *header = (NR_MAC_SUBHEADER_SHORT *) pdu; pdu += sh_size; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 4a174057ef..4719e8f277 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1990,7 +1990,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, uint16_t num_sdus = 0; uint16_t sdu_length_total = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); + const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); // Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer uint8_t *pdu = ulsch_buffer; From 07a80bc84e0a2bbff0ee6fcbd5bcb4a9d684dd21 Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 2 Aug 2021 15:38:17 +0200 Subject: [PATCH 05/11] Do generation of UL padding in nr_ue_get_sdu only - removed code from outside this function - generate random padding in RFSIM mode - generate 0 padding in real-time - padding is generated either to complete the PDU or to transmit a new one when no data from RLC was fetched --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 115 +++++++------------- 1 file changed, 42 insertions(+), 73 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 4719e8f277..03d07080d1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1003,7 +1003,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; - uint8_t data_existing = 0; nr_scheduled_response_t scheduled_response; fapi_nr_tx_request_t tx_req; @@ -1035,45 +1034,15 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1)){ // Getting IP traffic to be transmitted - data_existing = nr_ue_get_sdu(mod_id, - frame_tx, - slot_tx, - gNB_index, - ulsch_input_buffer, - TBS_bytes); + nr_ue_get_sdu(mod_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); } LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; - // TBR use the proper function ! - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - if (!data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes); - - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = UL_SCH_LCID_PADDING; - - for (int i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - } - } } - #ifdef DEBUG_MAC_PDU - LOG_D(PHY, "Is data existing ?: %d \n", data_existing); - LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); - for (i = 0; i < TBS_bytes; i++) { - printf("%02x", ulsch_input_buffer[i]); - } - printf("\n"); - #endif - // Config UL TX PDU tx_req.slot = slot_tx; tx_req.sfn = frame_tx; @@ -2084,54 +2053,54 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } } - if (num_sdus > 0) { + if (tot_mac_ce_len > 0) { - if (tot_mac_ce_len > 0) { - - LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); - memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len); - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); - pdu += (unsigned char) tot_mac_ce_len; - - #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len); - log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); - #endif - - } - - // Compute final offset for padding and fill remainder of ULSCH with 0 - if (buflen_remain > 0) { - - ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; - - #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED)); - log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); - #endif - - pdu++; - buflen_remain--; - - for (int j = 0; j < buflen_remain; j++) { - pdu[j] = 0; - } - - #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain); - log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); - #endif - - } + LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); + memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len); + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); + pdu += (unsigned char) tot_mac_ce_len; #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen); - log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len); + log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); #endif } + // Compute final offset for padding and fill remainder of ULSCH with 0 + if (buflen_remain > 0) { + + ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED)); + log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); + #endif + + pdu++; + buflen_remain--; + + if (IS_SOFTMODEM_RFSIM) { + for (int j = 0; j < buflen_remain; j++) { + pdu[j] = (unsigned char) rand(); + } + } else { + memset(pdu, 0, buflen_remain); + } + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain); + log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); + #endif + + } + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG + LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen); + log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); + #endif + return num_sdus > 0 ? 1 : 0; } From b6e3718d70664aac1b33d2e1a1ce510f03f284c0 Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 2 Aug 2021 16:11:11 +0200 Subject: [PATCH 06/11] Changes to nr_write_ce_ulsch_pdu - takes in input MAC instance - uses a mac ce struct - minor fixes --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 25 ++++++--------- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 32 ++++++++++---------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 3 +- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index d3917b345c..35b932ad01 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -311,6 +311,15 @@ typedef struct { } RAR_grant_t; +typedef struct { + + uint8_t phr_reporting; + uint16_t truncated_bsr; + uint16_t short_bsr; + uint16_t long_bsr; + +} NR_UE_MAC_CE_t; + /*!\brief Top level UE MAC structure */ typedef struct { @@ -374,12 +383,8 @@ typedef struct { nr_ue_if_module_t *if_module; nr_phy_config_t phy_config; - /// BSR report flag management - uint8_t BSR_reporting_active; NR_UE_SCHEDULING_INFO scheduling_info; - - /// PHR - uint8_t PHR_reporting_active; + NR_UE_MAC_CE_t nr_ue_mac_ce; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; NR_SearchSpace_t *search_space_zero; @@ -390,16 +395,6 @@ typedef struct { } NR_UE_MAC_INST_t; -typedef struct { - - uint8_t power_headroom; - uint16_t crnti; - uint16_t truncated_bsr; - uint16_t short_bsr; - uint16_t long_bsr; - -} NR_UE_MAC_CE_t; - typedef enum seach_space_mask_e { type0_pdcch = 0x1, type0a_pdcch = 0x2, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index e546fb9fc0..b0905928a3 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -156,8 +156,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); -int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, - NR_UE_MAC_CE_t *nr_ue_mac_ce); +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, + NR_UE_MAC_INST_t *mac); void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5d42ac7ea2..cc019a4398 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2141,22 +2141,22 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, } } -// about: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU -// returns: number of written bytes /** * Function: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU + * Notes: TODO: PHR and BSR reporting + * Parameters: * @mac_ce pointer to the MAC sub-PDUs including the MAC CEs - * @nr_ue_mac_ce pointer to the MAC CEs to be transmitted + * @mac pointer to the MAC instance + * Return: number of written bytes */ -int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, - NR_UE_MAC_CE_t *nr_ue_mac_ce) { +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, + NR_UE_MAC_INST_t *mac) { int mac_ce_len = 0; uint8_t mac_ce_size = 0; + NR_UE_MAC_CE_t *nr_ue_mac_ce = &mac->nr_ue_mac_ce; - if (nr_ue_mac_ce->power_headroom) { - - LOG_D(NR_MAC, "In %s: generating PHR MAC CE with command %d\n", __FUNCTION__, nr_ue_mac_ce->power_headroom); + if (nr_ue_mac_ce->phr_reporting && mac->phr_Config != NULL) { // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; @@ -2164,9 +2164,9 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, mac_ce++; // PHR MAC CE (1 octet) - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = nr_ue_mac_ce->power_headroom; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = 0; ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0; // update pointer and length @@ -2176,9 +2176,9 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, } - if (nr_ue_mac_ce->crnti) { + if (!get_softmodem_params()->sa && mac->ra.ra_state == WAIT_RAR) { - LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, nr_ue_mac_ce->crnti); + LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti); // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; @@ -2186,7 +2186,7 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, mac_ce++; // C-RNTI MAC CE (2 octets) - *(uint16_t *) mac_ce = nr_ue_mac_ce->crnti; + *(uint16_t *) mac_ce = mac->crnti; // update pointer and length mac_ce_size = sizeof(uint16_t); @@ -2197,7 +2197,7 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, if (nr_ue_mac_ce->truncated_bsr) { - LOG_D(NR_MAC, "In %s: generating Truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr); + LOG_D(NR_MAC, "In %s: generating short truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr); // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; @@ -2205,7 +2205,7 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, mac_ce++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = nr_ue_mac_ce->truncated_bsr; + ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = 0; ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0; // update pointer and length @@ -2215,7 +2215,7 @@ int nr_write_ce_ulsch_pdu(unsigned char *mac_ce, } else if (nr_ue_mac_ce->short_bsr) { - LOG_D(NR_MAC, "In %s: generating Truncated short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr); + LOG_D(NR_MAC, "In %s: generating short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr); // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 03d07080d1..488d5d4ded 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1966,8 +1966,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // Preparing the MAC CEs sub-PDUs and get the total size unsigned char mac_header_control_elements[16] = {0}; - NR_UE_MAC_CE_t nr_ue_mac_ce = {.crnti = mac->crnti}; - int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], &nr_ue_mac_ce); + int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], mac); uint8_t total_mac_pdu_header_len = tot_mac_ce_len; LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen); From 9af71a7a4634aa79f474fc5ce2683fec1287edbb Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 2 Aug 2021 16:27:39 +0200 Subject: [PATCH 07/11] Set the tc-rnti only in CBRA - TC-RNTI is set and used after RAR reception according to the specs - C-RNTI is used in CFRA --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 1 - openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 17 +++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 8ee1e90077..92c9aa001d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -760,7 +760,6 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); ra->RA_window_cnt = -1; - mac->crnti = ra->t_crnti; } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index cc019a4398..7b5734f640 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2299,7 +2299,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t uint8_t is_Msg3 = 1; frame_t frame_tx = 0; int slot_tx = 0; - uint16_t rnti = 0; int ret = 0; NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer @@ -2351,9 +2350,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t unsigned char csi_req; #endif - // TC-RNTI - ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); - // TA command ul_time_alignment->apply_ta = 1; ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5); @@ -2399,12 +2395,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t rar_grant.Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); // frequency hopping rar_grant.freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); - // TC-RNTI - if (ra->t_crnti) { - rnti = ra->t_crnti; - } else { - rnti = mac->crnti; - } #ifdef DEBUG_RAR LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); @@ -2444,12 +2434,19 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t if (ret != -1){ fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + uint16_t rnti = mac->crnti; if (!ul_config) { LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } + // Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles + if (!ra->cfra) { + ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); + rnti = ra->t_crnti; + } + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); From 6e0737d9e4aa470b4d38dae761dded4f142d8b0f Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 3 Aug 2021 09:36:45 +0200 Subject: [PATCH 08/11] Send Msg3 CCCH SDU in SA mode only - send C-RNTI MAC CE otherwise - init RA if there are bytes to send and is a PRACH occasion - minor cleanups --- openair1/PHY/defs_nr_common.h | 2 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 3 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 110 ++++++++++--------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index d333732d1f..5dca6932ca 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -234,8 +234,6 @@ typedef struct { int RA_PCMAX; /// Corresponding RA-RNTI for UL-grant uint16_t ra_RNTI; - /// Pointer to Msg3 payload for UL-grant - uint8_t *Msg3; /// Frame of last completed synch uint16_t sync_frame; /// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index c0020cc689..66cbc04c54 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2117,7 +2117,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); - LOG_D(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", + LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", + __FUNCTION__, mod_id, frame_tx, nr_slot_tx, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 92c9aa001d..c9a907cce7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -477,7 +477,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint /** * Function: handles Random Access Preamble Initialization (5.1.1 TS 38.321) * handles Random Access Response reception (5.1.4 TS 38.321) - * Note: In the current implementation, RA is 4-step contention free only + * Note: In SA mode the Msg3 contains a CCCH SDU, therefore no C-RNTI MAC CE is transmitted. * * @prach_resources pointer to PRACH resources * @prach_pdu pointer to FAPI UL PRACH PDU @@ -497,8 +497,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - int8_t size_sdu = 0; - NR_RACH_ConfigCommon_t *setup; if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; else setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; @@ -535,50 +533,63 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, const uint8_t lcid = UL_SCH_LCID_CCCH; const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_SHORT); const uint8_t TBS_max = 8 + 2 * sh_size; - uint8_t *pdu = (uint8_t*) mac->CCCH_pdu.payload; - NR_MAC_SUBHEADER_SHORT *header = (NR_MAC_SUBHEADER_SHORT *) pdu; - pdu += sh_size; + int8_t size_sdu = 0; + uint8_t mac_ce[16] = {0}; + uint8_t *pdu = get_softmodem_params()->sa ? mac->CCCH_pdu.payload : mac_ce; + uint8_t *payload = pdu; - // initialisation by RRC + // Concerning the C-RNTI MAC CE, it has to be included if the UL transmission (Msg3) is not being made for the CCCH logical channel. + // Therefore it has been assumed that this event only occurs only when RA is done and it is not SA mode. + if (get_softmodem_params()->sa) { - // TODO: To be removed after RA procedures fully implemented - if(get_softmodem_params()->do_ra) { + NR_MAC_SUBHEADER_SHORT *header = (NR_MAC_SUBHEADER_SHORT *) pdu; + pdu += sh_size; + + // initialisation by RRC nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id); - } - // CCCH PDU - size_sdu = nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, pdu); + // CCCH PDU + size_sdu = nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, pdu); + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: Requested RRCConnectionRequest, got %d bytes for LCID 0x%02x \n", __FUNCTION__, mod_id, frame, nr_slot_tx, size_sdu, lcid); - LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: Requested RRCConnectionRequest, got %d bytes for LCID 0x%02x \n", __FUNCTION__, mod_id, frame, nr_slot_tx, size_sdu, lcid); + if (size_sdu > 0) { - if (size_sdu > 0) { + // UE Contention Resolution Identity + // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the + // Random Access Procedure has been successful after reception of Msg4 + memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6); - // UE Contention Resolution Identity - // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the - // Random Access Procedure has been successful after reception of Msg4 - memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6); + pdu += size_sdu; + ra->Msg3_size = size_sdu + sh_size; - pdu += size_sdu; + // Build header + header->R = 0; + header->F = 0; + header->LCID = lcid; + header->L = (unsigned char) size_sdu; - LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); - - ra->Msg3_size = size_sdu + sh_size; - - AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); - - init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); - prach_resources->Msg3 = (uint8_t*) mac->CCCH_pdu.payload; - nr_get_RA_window(mac); - - // Fill in preamble and PRACH resources - if (ra->generate_nr_prach == GENERATE_PREAMBLE) { - nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + } else { + pdu -= sh_size; } - header->R = 0; - header->F = 0; - header->LCID = lcid; - header->L = (unsigned char) size_sdu; + } else { + + size_sdu = nr_write_ce_ulsch_pdu(pdu, mac); + pdu += size_sdu; + ra->Msg3_size = size_sdu; + + } + + if (size_sdu > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) { + + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); + AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); + + // Init RA procedure + init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); + nr_get_RA_window(mac); + // Fill in preamble and PRACH resources + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); // Padding: fill remainder with 0 if (TBS_max - ra->Msg3_size > 0) { @@ -590,21 +601,22 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, pdu[j] = 0; } } + + // Dumping ULSCH payload + LOG_D(NR_MAC, "In %s: dumping UL Msg3 MAC PDU with length %d: \n", __FUNCTION__, TBS_max); + for(int k = 0; k < TBS_max; k++) { + LOG_D(NR_MAC,"(%i): %i\n", k, payload[k]); + } + + // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after + // receiving Msg2 (which contains the Msg3 resource reserve). + // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, payload, TBS_max); + } else { - pdu -= sh_size; + return 0; } - - LOG_D(NR_MAC, "In %s: dumping UL Msg3 MAC PDU with length %d: \n", __FUNCTION__, TBS_max); - for(int k = 0; k < TBS_max; k++) { - LOG_D(NR_MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); - } - - // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after - // receiving Msg2 (which contains the Msg3 resource reserve). - // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. - mac->ulsch_pdu.Pdu_size = TBS_max; - memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max); - } else if (ra->RA_window_cnt != -1) { // RACH is active LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 7b5734f640..7086f760c6 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2176,7 +2176,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, } - if (!get_softmodem_params()->sa && mac->ra.ra_state == WAIT_RAR) { + if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED) { LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti); From 05a4c48d96cc7fa3b20578ee05a1942bd4fbdb14 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 3 Aug 2021 17:41:01 +0200 Subject: [PATCH 09/11] Bugfix in the generation of UL MAC PDU in Msg3 - restored FIXED subheader length - restored SHORT subheader in MAX TBS (still unclear the reason behind the selection of SHORT subheader here by developer) --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index c9a907cce7..3320e4356b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -531,8 +531,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__); const uint8_t lcid = UL_SCH_LCID_CCCH; - const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_SHORT); - const uint8_t TBS_max = 8 + 2 * sh_size; + const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_FIXED); + const uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // Note: unclear the reason behind the selection of such TBS_max int8_t size_sdu = 0; uint8_t mac_ce[16] = {0}; uint8_t *pdu = get_softmodem_params()->sa ? mac->CCCH_pdu.payload : mac_ce; @@ -542,7 +542,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // Therefore it has been assumed that this event only occurs only when RA is done and it is not SA mode. if (get_softmodem_params()->sa) { - NR_MAC_SUBHEADER_SHORT *header = (NR_MAC_SUBHEADER_SHORT *) pdu; + NR_MAC_SUBHEADER_FIXED *header = (NR_MAC_SUBHEADER_FIXED *) pdu; pdu += sh_size; // initialisation by RRC @@ -564,9 +564,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // Build header header->R = 0; - header->F = 0; header->LCID = lcid; - header->L = (unsigned char) size_sdu; } else { pdu -= sh_size; From 92fb370258b162ecd0d2a28f7d7c6048cd62f358 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 3 Aug 2021 17:41:50 +0200 Subject: [PATCH 10/11] Removed unnecessary sdu_lengths array in nr_ue_get_sdu --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 44 ++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 488d5d4ded..21cb0805f7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1955,7 +1955,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, int16_t buflen_remain = 0; uint8_t lcid = 0; - uint16_t sdu_lengths[MAX_LCID] = { 0 }; + uint16_t sdu_length = 0; uint16_t num_sdus = 0; uint16_t sdu_length_total = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); @@ -1996,47 +1996,47 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, pdu += sh_size; - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - mac->crnti, - gNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - buflen_remain, - (char *)pdu, - 0, - 0); + sdu_length = mac_rlc_data_req(module_idP, + mac->crnti, + gNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)pdu, + 0, + 0); - AssertFatal(buflen_remain >= sdu_lengths[num_sdus], "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", + AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", __FUNCTION__, lcid, - sdu_lengths[num_sdus], + sdu_length, buflen_remain); - if (sdu_lengths[num_sdus]) { + if (sdu_length > 0) { LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, num_sdus + 1, - sdu_lengths[num_sdus], + sdu_length, lcid, buflen); header->R = 0; header->F = 1; header->LCID = lcid; - header->L1 = ((unsigned short) sdu_lengths[num_sdus] >> 8) & 0x7f; - header->L2 = (unsigned short) sdu_lengths[num_sdus] & 0xff; + header->L1 = ((unsigned short) sdu_length >> 8) & 0x7f; + header->L2 = (unsigned short) sdu_length & 0xff; #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size); log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n"); - LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_lengths[num_sdus]); - log_dump(NR_MAC, pdu, sdu_lengths[num_sdus], LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length); + log_dump(NR_MAC, pdu, sdu_length, LOG_DUMP_CHAR, "\n"); #endif - pdu += sdu_lengths[num_sdus]; - sdu_length_total += sdu_lengths[num_sdus]; + pdu += sdu_length; + sdu_length_total += sdu_length; total_mac_pdu_header_len += sh_size; num_sdus++; From 6c227f4d6b262caac2d3d17277a1939597694e24 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 5 Aug 2021 12:15:09 +0200 Subject: [PATCH 11/11] NR_UE: Assure correct padding in nr_ue_get_sdu() In case no MAC CE needs to be transmitted and we filled the buffer with SDUs from RLC, we missed to add padding for the last 3 bytes. --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 21cb0805f7..2357ebae9a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1976,7 +1976,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) { - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + buflen_remain = buflen - (total_mac_pdu_header_len + 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__, @@ -2047,7 +2047,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, break; } - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size); } } @@ -2056,7 +2056,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len); - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); pdu += (unsigned char) tot_mac_ce_len; #ifdef ENABLE_MAC_PAYLOAD_DEBUG @@ -2066,6 +2065,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); + // Compute final offset for padding and fill remainder of ULSCH with 0 if (buflen_remain > 0) {