Merge remote-tracking branch 'origin/fix-ulsch-bsr' into integration_2024_w46 (!2991)

fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR)...

fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR)
simplify the code and make the code more explicit, but the may structure
remain (nr_write_ce_ulsch_pdu interface is complex, merging it into the
called would make simpler and more interstandable code), fix some asserts
related to this part of code
This commit is contained in:
Jaroslava Fiedlerova
2024-11-15 18:43:26 +01:00
7 changed files with 461 additions and 677 deletions
+6 -13
View File
@@ -122,6 +122,11 @@ static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_l
*mac_subheader_len = sizeof(*s);
*mac_ce_len = s->L;
}
if (*mac_ce_len > pdu_len) {
LOG_E(NR_MAC, "MAC sdu len impossible (%d)\n", *mac_ce_len);
return false;
}
return true;
}
@@ -133,8 +138,6 @@ typedef struct {
uint8_t LcgID: 3; // octet 1 MSB
} __attribute__ ((__packed__)) NR_BSR_SHORT;
typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
// Long BSR for all logical channel group ID
typedef struct {
uint8_t LcgID0: 1; // octet 1 [0]
@@ -144,19 +147,9 @@ typedef struct {
uint8_t LcgID4: 1; // octet 1 [4]
uint8_t LcgID5: 1; // octet 1 [5]
uint8_t LcgID6: 1; // octet 1 [6]
uint8_t LcgID7: 1; // octet 1 [7]
uint8_t Buffer_size0: 8; // octet 2 [7:0]
uint8_t Buffer_size1: 8; // octet 3 [7:0]
uint8_t Buffer_size2: 8; // octet 4 [7:0]
uint8_t Buffer_size3: 8; // octet 5 [7:0]
uint8_t Buffer_size4: 8; // octet 6 [7:0]
uint8_t Buffer_size5: 8; // octet 7 [7:0]
uint8_t Buffer_size6: 8; // octet 8 [7:0]
uint8_t Buffer_size7: 8; // octet 9 [7:0]
uint8_t LcgID7: 1; // octet 1 [7]
} __attribute__ ((__packed__)) NR_BSR_LONG;
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
// 38.321 ch. 6.1.3.4
typedef struct {
uint8_t TA_COMMAND: 6; // octet 1 [5:0]
+1 -13
View File
@@ -70,8 +70,7 @@
#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */
#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define NR_INVALID_LCGID (NR_MAX_NUM_LCGID)
@@ -194,8 +193,6 @@ typedef enum {
typedef struct {
// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain;
// buffer status for each lcid
bool LCID_buffer_with_data;
// logical channel group id of this LCID
long LCGID;
// Bj bucket usage per lcid
@@ -203,13 +200,6 @@ typedef struct {
NR_timer_t Bj_timer;
} NR_LC_SCHEDULING_INFO;
typedef struct {
// buffer status for each lcgid
uint8_t BSR; // should be more for mesh topology
// keep the number of bytes in rlc buffer for each lcgid
int32_t BSR_bytes;
} NR_LCG_SCHEDULING_INFO;
typedef struct {
bool active_SR_ID;
/// SR pending as defined in 38.321
@@ -244,8 +234,6 @@ typedef struct {
typedef struct {
// lcs scheduling info
NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID];
// lcg scheduling info
NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID];
// SR INFO
nr_sr_info_t sr_info[NR_MAX_SR_ID];
/// BSR report flag management
+13 -14
View File
@@ -172,13 +172,22 @@ void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, in
void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac,nr_downlink_indication_t *dl_info, int pdu_id);
typedef struct {
union {
NR_BSR_SHORT s;
NR_BSR_LONG l;
uint8_t lcg_bsr[8];
} bsr;
enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr;
} type_bsr_t;
int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end);
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac,
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
uint16_t *crnti,
NR_BSR_SHORT *truncated_bsr,
NR_BSR_SHORT *short_bsr,
NR_BSR_LONG *long_bsr);
const type_bsr_t *bsr,
uint8_t *mac_ce_end);
void config_dci_pdu(NR_UE_MAC_INST_t *mac,
fapi_nr_dl_config_request_t *dl_config,
@@ -188,16 +197,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot);
uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
int cc_id,
frame_t frameP,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint32_t buflen,
int16_t tx_power,
int16_t P_CMAX);
void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
-1
View File
@@ -192,7 +192,6 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
LOG_D(NR_MAC, "Applying default logical channel config for LCID %d\n", i);
nr_mac->scheduling_info.lc_sched_info[i].Bj = 0;
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false;
nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
}
+1 -1
View File
@@ -785,7 +785,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
} else if (!IS_SA_MODE(get_softmodem_params())) {
uint8_t temp_pdu[16] = {0};
size_sdu = nr_write_ce_ulsch_pdu(temp_pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
size_sdu = nr_write_ce_msg3_pdu(temp_pdu, mac, mac->crnti, temp_pdu + sizeof(temp_pdu));
ra->Msg3_size = size_sdu;
}
} else if (ra->RA_window_cnt != -1) { // RACH is active
+100 -144
View File
@@ -2524,7 +2524,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n");
}
}
return sr_count > 0 ? true : false;
return sr_count > 0;
}
int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id)
@@ -2537,12 +2537,14 @@ int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_Schedu
return 0;
}
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d SR %s for ID %ld\n",
LOG_D(NR_MAC,
"[UE %d] Frame %d slot %d SR %s for ID %ld, timer %d\n",
mac->ue_id,
frame,
slot,
sr_info->pending ? "pending" : "not pending",
sr_id); // todo
sr_id, // todo
nr_timer_is_active(&sr_info->prohibitTimer));
// TODO check if the PUCCH resource for the SR transmission occasion does not overlap with a UL-SCH resource
if (!sr_info->pending || nr_timer_is_active(&sr_info->prohibitTimer))
@@ -3772,9 +3774,23 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
}
}
int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end)
{
uint8_t *pdu = mac_ce;
if (IS_SA_MODE(get_softmodem_params()) && mac->ra.ra_state != nrRA_SUCCEEDED) {
LOG_D(NR_MAC, "Generating C-RNTI MAC CE with C-RNTI %x\n", crnti);
*(NR_MAC_SUBHEADER_FIXED *)mac_ce = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_C_RNTI};
mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED);
// C-RNTI MAC CE (2 octets)
memcpy(mac_ce, &crnti, sizeof(crnti));
// update pointer and length
mac_ce += sizeof(crnti);
}
return mac_ce - pdu;
}
/**
* 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
* @mac pointer to the MAC instance
@@ -3783,158 +3799,98 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac,
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
uint16_t *crnti,
NR_BSR_SHORT *truncated_bsr,
NR_BSR_SHORT *short_bsr,
NR_BSR_LONG *long_bsr)
const type_bsr_t *bsr,
uint8_t *mac_ce_end)
{
int mac_ce_len = 0;
uint8_t *pdu = mac_ce;
if (power_headroom) {
// 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++;
// PHR MAC CE (1 octet)
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom->PH;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = power_headroom->PCMAX;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
// update pointer and length
int 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);
*(NR_MAC_SUBHEADER_FIXED *)mac_ce = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR};
mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED);
*(NR_SINGLE_ENTRY_PHR_MAC_CE *)mac_ce = *power_headroom;
mac_ce += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n",
pdu, mac_ce);
}
if (crnti && (!IS_SA_MODE(get_softmodem_params()) && get_softmodem_params()->do_ra && mac->ra.ra_state != nrRA_SUCCEEDED)) {
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti));
// 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++;
// C-RNTI MAC CE (2 octets)
memcpy(mac_ce, crnti, sizeof(*crnti));
// update pointer and length
int mac_ce_size = sizeof(uint16_t);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
switch (bsr->type_bsr) {
case b_short:
case b_short_trunc: {
*(NR_MAC_SUBHEADER_FIXED *)mac_ce =
(NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = bsr->type_bsr == b_short ? UL_SCH_LCID_S_BSR : UL_SCH_LCID_S_TRUNCATED_BSR};
mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED);
*(NR_BSR_SHORT *)mac_ce = bsr->bsr.s;
mac_ce += sizeof(NR_BSR_SHORT);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : bsr Buffer_size %d LcgID %d \n", bsr->bsr.s.Buffer_size, bsr->bsr.s.LcgID);
} break;
case b_long:
case b_long_trunc: {
// ch 6.1.3.1. TS 38.321
NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *)mac_ce;
mac_ce += sizeof(NR_MAC_SUBHEADER_SHORT);
uint8_t *mark = mac_ce;
// Could move to nr_get_sdu()
NR_BSR_LONG *ceLong = (NR_BSR_LONG *)mac_ce;
*ceLong = (NR_BSR_LONG){0};
mac_ce += sizeof(NR_BSR_LONG);
// int NR_BSR_LONG_SIZE = 1;
if (bsr->bsr.lcg_bsr[0] && mac_ce < mac_ce_end) {
ceLong->LcgID0 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[0];
}
if (bsr->bsr.lcg_bsr[1] && mac_ce < mac_ce_end) {
ceLong->LcgID1 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[1];
}
if (bsr->bsr.lcg_bsr[2] && mac_ce < mac_ce_end) {
ceLong->LcgID2 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[2];
}
if (bsr->bsr.lcg_bsr[3] && mac_ce < mac_ce_end) {
ceLong->LcgID3 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[3];
}
if (bsr->bsr.lcg_bsr[4] && mac_ce < mac_ce_end) {
ceLong->LcgID4 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[4];
}
if (bsr->bsr.lcg_bsr[5] && mac_ce < mac_ce_end) {
ceLong->LcgID5 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[5];
}
if (bsr->bsr.lcg_bsr[6] && mac_ce < mac_ce_end) {
ceLong->LcgID6 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[6];
}
if (bsr->bsr.lcg_bsr[7] && mac_ce < mac_ce_end) {
ceLong->LcgID7 = 1;
*mac_ce++ = bsr->bsr.lcg_bsr[7];
}
*mac_pdu_subheader_ptr =
(NR_MAC_SUBHEADER_SHORT){.LCID = bsr->type_bsr == b_long ? UL_SCH_LCID_L_BSR : UL_SCH_LCID_L_TRUNCATED_BSR,
.L = mac_ce - mark};
LOG_D(NR_MAC,
"[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n",
((NR_MAC_SUBHEADER_SHORT *)mac_pdu_subheader_ptr)->L,
*mac_ce,
bsr->bsr.lcg_bsr[0],
bsr->bsr.lcg_bsr[1],
bsr->bsr.lcg_bsr[2],
bsr->bsr.lcg_bsr[3],
bsr->bsr.lcg_bsr[4],
bsr->bsr.lcg_bsr[5],
bsr->bsr.lcg_bsr[6],
bsr->bsr.lcg_bsr[7]);
} break;
case b_none:
break;
default:
DevAssert(false);
}
if (truncated_bsr) {
// MAC CE fixed subheader
((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_ce)-> Buffer_size = truncated_bsr->Buffer_size;
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;;
// update pointer and length
int mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce);
} else if (short_bsr) {
// MAC CE fixed subheader
((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_ce)->Buffer_size = short_bsr->Buffer_size;
((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID;
// update pointer and length
int mac_ce_size = sizeof(NR_BSR_SHORT);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce);
} else if (long_bsr) {
// MAC CE variable subheader
// ch 6.1.3.1. TS 38.321
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR;
NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce;
mac_ce += 2;
// Could move to nr_get_sdu()
uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1;
//int NR_BSR_LONG_SIZE = 1;
if (long_bsr->Buffer_size0 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID0 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID0 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size0;
}
if (long_bsr->Buffer_size1 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID1 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID1 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size1;
}
if (long_bsr->Buffer_size2 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID2 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID2 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size2;
}
if (long_bsr->Buffer_size3 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID3 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID3 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size3;
}
if (long_bsr->Buffer_size4 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID4 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID4 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size4;
}
if (long_bsr->Buffer_size5 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID5 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID5 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size5;
}
if (long_bsr->Buffer_size6 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID6 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID6 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size6;
}
if (long_bsr->Buffer_size7 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID7 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID7 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size7;
}
int mac_ce_size = ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce),
((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3,
((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7);
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT);
}
return mac_ce_len;
return mac_ce - pdu;
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
File diff suppressed because it is too large Load Diff