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:
Laurent THOMAS
2024-11-13 14:15:30 +01:00
parent f54ca5714e
commit d641a76196
7 changed files with 429 additions and 642 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 lc_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
+101 -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 (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && 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,99 @@ 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.lc_bsr[0] && mac_ce < mac_ce_end) {
ceLong->LcgID0 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[0];
}
if (bsr->bsr.lc_bsr[1] && mac_ce < mac_ce_end) {
ceLong->LcgID1 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[1];
}
if (bsr->bsr.lc_bsr[2] && mac_ce < mac_ce_end) {
ceLong->LcgID2 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[2];
}
if (bsr->bsr.lc_bsr[3] && mac_ce < mac_ce_end) {
ceLong->LcgID3 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[3];
}
if (bsr->bsr.lc_bsr[4] && mac_ce < mac_ce_end) {
ceLong->LcgID4 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[4];
}
if (bsr->bsr.lc_bsr[5] && mac_ce < mac_ce_end) {
ceLong->LcgID5 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[5];
}
if (bsr->bsr.lc_bsr[6] && mac_ce < mac_ce_end) {
ceLong->LcgID6 = 1;
*mac_ce++ = bsr->bsr.lc_bsr[6];
}
if (bsr->bsr.lc_bsr[7] && mac_ce < mac_ce_end) {
ceLong->LcgID7 = 1;
*mac_ce++ = bsr->bsr.lc_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.lc_bsr[0],
bsr->bsr.lc_bsr[1],
bsr->bsr.lc_bsr[2],
bsr->bsr.lc_bsr[3],
bsr->bsr.lc_bsr[4],
bsr->bsr.lc_bsr[5],
bsr->bsr.lc_bsr[6],
bsr->bsr.lc_bsr[7]);
} break;
case b_none:
break;
default:
DevAssert(false);
>>>>>>> 4a6be6c8ce (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)
}
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