From 98480e7102d60c36eb2ede8f6df6b5857f8b0250 Mon Sep 17 00:00:00 2001 From: cig <guido.casati@iis.fraunhofer.de> Date: Mon, 10 Feb 2020 16:02:55 +0100 Subject: [PATCH] RA, Updated nr_ue_get_rach: - using LTE function mac_rrc_nr_data_req_ue in noS1 mode - cleanup code, comments - fixes RA procedure - Processing UL MAC PDU according to TS 38.321 ch 6.1: - introduced function for gNB side UL PDU processing - fixed bug in nr_ue_process_mac_pdu --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 106 ++++++++------ openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 3 - openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 19 +-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 134 ++++++++++++++++++ 4 files changed, 203 insertions(+), 59 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index e2eb4edf502..812ef8fd26d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -78,7 +78,7 @@ void nr_get_prach_resources(module_id_t mod_id, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3; @@ -90,15 +90,15 @@ void nr_get_prach_resources(module_id_t mod_id, //////////* UE Random Access Resource Selection *////////// /////////////////////////////////////////////////////////// - // todo: switch initialisation cases - // - RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) - // -- SSB selection, set prach_resources->ra_PreambleIndex - // - RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 - // -- TBR coming from dci_pdu_rel15[0].ra_preamble_index - // -- set PREAMBLE_INDEX to ra_preamble_index - // -- select the SSB signalled by PDCCH - // - RA initiated for SI request: - // -- SSB selection, set prach_resources->ra_PreambleIndex + // todo: + // - switch initialisation cases + // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) + // --- SSB selection, set prach_resources->ra_PreambleIndex + // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 + // --- set PREAMBLE_INDEX to ra_preamble_index + // --- select the SSB signalled by PDCCH + // -- RA initiated for SI request: + // --- SSB selection, set prach_resources->ra_PreambleIndex // if (rach_ConfigDedicated) { // This is for network controlled Mobility // // operation for contention-free RA resources when: @@ -109,12 +109,16 @@ void nr_get_prach_resources(module_id_t mod_id, // } //////////* Contention-based RA preamble selection *////////// - // todo + // todo: // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB // - todo determine next available PRACH occasion // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; + AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + + nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; + Msg3_size = mac->RA_Msg3_size; numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles; @@ -162,7 +166,6 @@ void nr_get_prach_resources(module_id_t mod_id, } /* Power offset for preamble selection in dB */ - /* TBR: what value to use as default? Shall it be converted ? */ messagePowerOffsetGroupB = -9999; switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){ case 0: @@ -237,16 +240,16 @@ void nr_get_prach_resources(module_id_t mod_id, // todo: // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission + // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded) if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); - /* RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) + // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) // 1) this does not apply to contention-free RA Preamble for beam failure recovery request // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) - // 3) TBR extend this (e.g. f_id selection, ul_carrier_id are hardcoded) */ switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used case 0: @@ -287,6 +290,7 @@ void nr_get_prach_resources(module_id_t mod_id, } } prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; + mac->ra_rnti = prach_resources->ra_RNTI; LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); } @@ -317,6 +321,18 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint /// the RA procedure on a SCell shall only be initiated by PDCCH order // WIP +// todo TS 38.321: +// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX +// - BWP operation (subclause 5.15 TS 38.321) +// - handle initialization by beam failure recovery +// - handle initialization by handover +// - handle 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 ... +// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, int CC_id, @@ -326,15 +342,15 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, int nr_tti_tx){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - uint8_t lcid = CCCH, dcch_header_len = 0, mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES], * payload, ra_ResponseWindow; + uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, dcch_header_len = 0, *mac_sdus, *payload, ra_ResponseWindow; uint16_t size_sdu = 0; unsigned short post_padding; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL; int32_t frame_diff = 0; - uint8_t sdu_lcids[NB_RB_MAX] = {0}; // TBR - uint16_t sdu_lengths[NB_RB_MAX] = {0}; // TBR - int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax; // TBR + uint8_t sdu_lcids[NB_RB_MAX] = {0}; + uint16_t sdu_lengths[NB_RB_MAX] = {0}; + int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax, mac_ce_len; AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); @@ -344,7 +360,7 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); - if (mac->nr_rach_ConfigCommon) { // TBR check the condition + if (mac->nr_rach_ConfigCommon != NULL) { nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; } else prach_resources = NULL; @@ -375,38 +391,36 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, prach_resources->RA_SCALING_FACTOR_BI = 1; prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 - // todo: - // - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX - // - BWP operation (subclause 5.15 TS 38.321) - // - handle initialization by beam failure recovery - // - handle initialization by handover + payload = &mac->CCCH_pdu.payload; - if (!IS_SOFTMODEM_NOS1){ - // todo mac_rrc_nr_data_req_ue - payload = &mac->CCCH_pdu.payload; - size_sdu = (uint16_t) mac_rrc_nr_data_req_ue(mod_id, - CC_id, - frame, - CCCH, - payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); + mac_ce_len = 0; + num_sdus = 1; + post_padding = 1; + if (!IS_SOFTMODEM_NOS1){ + // initialisation by RRC + // CCCH PDU + mac_sdus = payload[sizeof(NR_MAC_SUBHEADER_SHORT)]; + size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id, + CC_id, + frame, + CCCH, + 1, + mac_sdus, + gNB_id, + 0); LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id,frame, size_sdu); - - // todo: else triggers a transmission on DCCH using PRACH (during handover, or sending SR for example) - } else { // fill ulsch_buffer with random data - payload = (uint8_t *)mac->ulsch_pdu.payload[0]; for (int i = 0; i < TBS_bytes; i++){ mac_sdus[i] = (unsigned char) (lrand48()&0xff); } //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = UL_SCH_LCID_DTCH; - sdu_lengths[0] = TBS_bytes - 3; + sdu_lcids[0] = lcid; + sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; header_length_total += 2 + (sdu_lengths[0] >= 128); size_sdu += sdu_lengths[0]; - num_sdus +=1; } mac->RA_tx_frame = frame; @@ -414,17 +428,15 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, mac->RA_backoff_frame = frame; mac->RA_backoff_subframe = nr_tti_tx; - if (size_sdu > 0) { // TBR size_sdu + MAC_Header_len + mac_ce_len - /* TBR initialisation by RRC - // PDU from CCCH */ + if (size_sdu > 0) { LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // TBR size_sdu + MAC_Header_len + mac_ce_len + mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); mac->RA_prachMaskIndex = 0; - // TBR todo: add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + // todo: add the backoff condition here mac->RA_backoff_cnt = 0; mac->RA_active = 1; prach_resources->Msg3 = payload; @@ -461,7 +473,7 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, nr_get_prach_resources(prach_resources, mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL); offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer - (uint8_t *) payload, // logical channel payload + (uint8_t *) payload, // UL MAC pdu pointer num_sdus, // num sdus sdu_lengths, // sdu length sdu_lcids, // sdu lcid @@ -470,9 +482,9 @@ void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, 0, // truncated bsr 0, // short bsr 0, // long_bsr - 1); // post_padding + post_padding); // post_padding - // Padding: fill remainder of DLSCH with 0 + // Padding: fill remainder with 0 if (post_padding > 0){ for (int j = 0; j < (TBS_bytes - offset); j++) payload[offset + j] = 0; // mac_pdu[offset + j] = 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 472b4108904..4c05ea3c700 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3290,9 +3290,6 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, mac->t_crnti = 0; mac->ra_state = RA_SUCCEEDED; } - break; - - break; case DL_SCH_LCID_PADDING: done = 1; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 074eda8ea80..208d45762f9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -46,11 +46,12 @@ void nr_add_subframe(uint16_t *frameP, uint16_t *slotP, int offset){ *slotP = ((*slotP + offset) % 10); } -// TBR +// WIP // handles the event of msg1 reception // todo: // - offset computation // - fix nr_add_subframe +// - msg2 time location void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, @@ -96,17 +97,15 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->Msg2_frame = msg2_frame; ra->Msg2_slot = msg2_slot; + // ra->Msg2_slot = (slotP + offset) % 10; LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP, offset); - ra->Msg2_slot = (slotP + offset) % 10; // TBR this is done twice ? - do { - ra->rnti = taus(); // todo 5.1.3 TS 38.321 + ra->rnti = (taus() % 65518) + 1; loop++; } - // Range coming from 5.1.3 TS 38.321 - while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 17920)); + while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519)); if (loop == 100) { LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); abort(); @@ -137,7 +136,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -// WIP void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ //uint8_t i = 0; @@ -166,6 +164,7 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ } // WIP +// todo: fix void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, @@ -367,6 +366,7 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ ra->msg3_round = 0; } +// WIP // todo: // - handle MAC RAR BI subheader // - sending only 1 RAR subPDU @@ -403,6 +403,7 @@ void nr_fill_rar(NR_RA_t * ra, } // WIP +// todo: fix void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ gNB_MAC_INST *mac = RC.nrmac[module_idP]; @@ -439,7 +440,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); - ul_req->SFN = ra->Msg3_frame << 4 | ra->Msg3_slot; // TBR + ul_req->SFN = ra->Msg3_frame << 4 | ra->Msg3_slot; ul_req->Slot = slotP; ul_req->n_pdus = 1; ul_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; @@ -485,7 +486,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->nrOfLayers = 1; pusch_pdu->ul_dmrs_symb_pos = 1; pusch_pdu->dmrs_config_type = 0; - pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. // TBR + pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. pusch_pdu->resource_alloc = 1; //type 1 //pusch_pdu->rb_bitmap;// for ressource alloc type 0 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 604664f3efd..cf8aafc3452 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -70,3 +70,137 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_scheduling_control->ta_update = timing_advance; } } + +// WIP +// todo: complete +// TS 38.321 ch 6.1 Protocol Data Units - UL-SCH +void nr_process_mac_pdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + uint8_t *pduP, + uint16_t mac_pdu_len, + uint8_t UE_id){ + + 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; + + // 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. + + while (!done && pdu_len > 0){ + mac_ce_len = 0x0000; + mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct + mac_sdu_len = 0x0000; + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + + switch(rx_lcid){ + // MAC CEs + case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: + // 38.321 Ch6.1.3.20 + mac_ce_len = 2; + break; + case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT: + // 38.321 Ch6.1.3.9 + // variable length + // todo + break; + case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION: + // 38.321 Ch6.1.3.7 + break; + case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT: + // 38.321 Ch6.1.3.9 + // variable length + // todo + break; + case UL_SCH_LCID_SINGLE_ENTRY_PHR: + // 38.321 Ch6.1.3.8 + mac_ce_len = 2; + break; + case UL_SCH_LCID_C_RNTI: + // 38.321 Ch6.1.3.2 + mac_ce_len = 2; + break; + case UL_SCH_LCID_S_TRUNCATED_BSR: + // 38.321 Ch6.1.3.1 + // fixed length + mac_ce_len = 1; + break; + case UL_SCH_LCID_L_TRUNCATED_BSR: + // 38.321 Ch6.1.3.1 + // variable length + // todo + break; + case UL_SCH_LCID_S_BSR: + // 38.321 Ch6.1.3.1 + // fixed length + mac_ce_len = 1; + break; + case UL_SCH_LCID_L_BSR: + // 38.321 Ch6.1.3.1 + // variable length + // todo + break; + case UL_SCH_LCID_PADDING: + done = 1; + // end of MAC PDU, can ignore the rest. + break; + + // MAC SDUs + case UL_SCH_LCID_SRB1: + // todo + break; + case UL_SCH_LCID_SRB2: + // todo + break; + case UL_SCH_LCID_SRB3: + // todo + break; + case UL_SCH_LCID_CCCH_MSG3: + case UL_SCH_LCID_CCCH: + // todo + mac_subheader_len = 2; + break; + case UL_SCH_LCID_DTCH: + // todo + default: + if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + mac_subheader_len = 3; + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + + } else { + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_subheader_len = 2; + } + // todo + break; + } + pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + + AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n"); + } +} \ No newline at end of file -- GitLab