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