Commit 4277d4e1 authored by cig's avatar cig Committed by Thomas Schlichter

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
parent efc696cc
......@@ -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,
......
......@@ -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,
......
......@@ -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");
uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
payload = (uint8_t*) mac->CCCH_pdu.payload;
LOG_D(NR_MAC, "In %s: RA not active. Checking for data to transmit from upper layers...\n", __FUNCTION__);
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);
pdu += 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);
LOG_D(NR_MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
ra->Msg3_size = size_sdu + sh_size;
ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
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
......
......@@ -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
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR;
mac_ce++;
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]);
// 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)->R1 = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
#endif
// 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);
// 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 (nr_ue_mac_ce->crnti) {
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 ++;
}
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, nr_ue_mac_ce->crnti);
// 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];
}
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_C_RNTI;
mac_ce++;
// Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
// C-RNTI MAC CE (2 octets)
*(uint16_t *) mac_ce = nr_ue_mac_ce->crnti;
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++;
// 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);
// 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);
}
if (crnti) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = UL_SCH_LCID_C_RNTI;
mac_pdu_ptr++;
if (nr_ue_mac_ce->truncated_bsr) {
// C-RNTI MAC CE (2 octets)
* (uint16_t *) mac_pdu_ptr = crnti;
mac_pdu_ptr += sizeof(uint16_t);
}
LOG_D(NR_MAC, "In %s: generating Truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr);
if (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;
AssertFatal(padding_bytes>=0,"");
return mac_ce_len;
// 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 //
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment