BSR and MAC UL encoding fixes
This commit is contained in:
@@ -959,9 +959,9 @@ typedef struct {
|
||||
/// buffer status for each lcgid
|
||||
uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology
|
||||
/// keep the number of bytes in rlc buffer for each lcgid
|
||||
uint16_t BSR_bytes[MAX_NUM_LCGID];
|
||||
int32_t BSR_bytes[MAX_NUM_LCGID];
|
||||
/// after multiplexing buffer remain for each lcid
|
||||
uint16_t LCID_buffer_remain[MAX_NUM_LCID];
|
||||
int32_t LCID_buffer_remain[MAX_NUM_LCID];
|
||||
/// sum of all lcid buffer size
|
||||
uint16_t All_lcid_buffer_size_lastTTI;
|
||||
/// buffer status for each lcid
|
||||
|
||||
@@ -1162,50 +1162,67 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
|
||||
LOG_T(MAC,"[UE] sdu subheader %d (lcid %d, %d bytes)\n",i,sdu_lcids[i],sdu_lengths[i]);
|
||||
#endif
|
||||
|
||||
if ((first_element>0)) {
|
||||
mac_header_ptr->E = 1;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
|
||||
#endif
|
||||
mac_header_ptr+=last_size;
|
||||
// printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
|
||||
} else {
|
||||
first_element=1;
|
||||
|
||||
if ((i == (num_sdus - 1)) && ((short_padding) || (post_padding == 0))) {
|
||||
if (first_element>0) {
|
||||
mac_header_ptr->E = 1;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
|
||||
#endif
|
||||
mac_header_ptr+=last_size;
|
||||
}
|
||||
mac_header_ptr->R = 0;
|
||||
mac_header_ptr->E = 0;
|
||||
mac_header_ptr->LCID = sdu_lcids[i];
|
||||
}
|
||||
else {
|
||||
if ((first_element>0)) {
|
||||
mac_header_ptr->E = 1;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
|
||||
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
|
||||
#endif
|
||||
mac_header_ptr+=last_size;
|
||||
// printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
|
||||
} else {
|
||||
first_element=1;
|
||||
|
||||
if (sdu_lengths[i] < 128) {
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; // 3
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0;
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0;
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i];
|
||||
last_size=2;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] short sdu\n");
|
||||
LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
|
||||
((uint16_t*)mac_header_ptr)[0],
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
|
||||
#endif
|
||||
} else {
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00;
|
||||
last_size=3;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] long sdu\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sdu_lengths[i] < 128) {
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; // 3
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0;
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0;
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i];
|
||||
last_size=2;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] short sdu\n");
|
||||
LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
|
||||
((uint16_t*)mac_header_ptr)[0],
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
|
||||
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
|
||||
#endif
|
||||
} else {
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff;
|
||||
((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00;
|
||||
last_size=3;
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
LOG_D(MAC,"[UE] long sdu\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,6 +1240,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
|
||||
//mac_header_ptr=last_size; // FIXME: should be ++
|
||||
}
|
||||
|
||||
|
||||
if ((ce_ptr-mac_header_control_elements) > 0) {
|
||||
memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
|
||||
mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
|
||||
@@ -1249,7 +1267,7 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
|
||||
uint16_t buflen_remain = 0;
|
||||
uint8_t bsr_len=0,bsr_ce_len=0,bsr_header_len=0;
|
||||
uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0;
|
||||
uint8_t lcid=0;
|
||||
uint8_t lcid=0,lcid_rlc_pdu_count=0;
|
||||
boolean_t is_lcid_processed = FALSE;
|
||||
uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
@@ -1384,12 +1402,13 @@ for (lcid=DCCH; lcid < DTCH ; lcid++) {
|
||||
if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
|
||||
|
||||
is_lcid_processed = FALSE;
|
||||
lcid_rlc_pdu_count = 0;
|
||||
|
||||
//Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
|
||||
//Adjust at the end of the loop
|
||||
while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
|
||||
while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
|
||||
|
||||
buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total + 1);
|
||||
buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
|
||||
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
UE_mac_inst[module_idP].crnti,
|
||||
@@ -1400,8 +1419,8 @@ for (lcid=DCCH; lcid < DTCH ; lcid++) {
|
||||
lcid,
|
||||
buflen_remain);
|
||||
|
||||
AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d\n",
|
||||
lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer);
|
||||
AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n",
|
||||
lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe);
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
@@ -1458,9 +1477,6 @@ for (lcid=DCCH; lcid < DTCH ; lcid++) {
|
||||
|
||||
}
|
||||
|
||||
//Update total MAC Header size for RLC PDUs and save last one
|
||||
total_rlc_pdu_header_len += rlc_pdu_header_len_last;
|
||||
|
||||
if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) {
|
||||
//No more remaining TBS after this PDU
|
||||
//exit the function
|
||||
@@ -1475,17 +1491,20 @@ for (lcid=DCCH; lcid < DTCH ; lcid++) {
|
||||
rlc_pdu_header_len_last = 1;
|
||||
is_lcid_processed = TRUE;
|
||||
}
|
||||
|
||||
//Update number of SDU
|
||||
num_sdus ++;
|
||||
}
|
||||
|
||||
//Update number of SDU
|
||||
num_sdus ++;
|
||||
|
||||
//Update total MAC Header size for RLC PDUs and save last one
|
||||
total_rlc_pdu_header_len += rlc_pdu_header_len_last;
|
||||
|
||||
} //end if (rlc_status.bytes_in_buffer > 0)
|
||||
else {
|
||||
// Switch to next LCID or exit the whole loop
|
||||
is_lcid_processed = TRUE;
|
||||
}
|
||||
lcid_rlc_pdu_count ++;
|
||||
}
|
||||
|
||||
UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY;
|
||||
@@ -1499,12 +1518,13 @@ for (lcid=DTCH; lcid < MAX_NUM_LCID ; lcid++) {
|
||||
if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
|
||||
|
||||
is_lcid_processed = FALSE;
|
||||
lcid_rlc_pdu_count = 0;
|
||||
|
||||
//Multiplex all available DTCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
|
||||
//Adjust at the end of the loop
|
||||
while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
|
||||
while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
|
||||
|
||||
buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total + 1);
|
||||
buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
|
||||
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
UE_mac_inst[module_idP].crnti,
|
||||
@@ -1515,8 +1535,8 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
lcid,
|
||||
buflen_remain);
|
||||
|
||||
AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d\n",
|
||||
lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer);
|
||||
AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n",
|
||||
lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe);
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
@@ -1535,6 +1555,9 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
lcid,
|
||||
(char *)&ulsch_buff[sdu_length_total]);
|
||||
|
||||
AssertFatal (sdu_lengths[num_sdus] < MAX_ULSCH_PAYLOAD_BYTES, "LCID=%d RLC PDU size = %d is too big\n",
|
||||
lcid,sdu_lengths[num_sdus]);
|
||||
|
||||
|
||||
AssertFatal (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
|
||||
lcid,sdu_lengths[num_sdus],UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]);
|
||||
@@ -1573,9 +1596,6 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
|
||||
}
|
||||
|
||||
//Update total MAC Header size for RLC PDUs and save last one
|
||||
total_rlc_pdu_header_len += rlc_pdu_header_len_last;
|
||||
|
||||
if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) {
|
||||
//No more remaining TBS after this PDU
|
||||
//exit the function
|
||||
@@ -1590,17 +1610,20 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
rlc_pdu_header_len_last = 1;
|
||||
is_lcid_processed = TRUE;
|
||||
}
|
||||
|
||||
//Update number of SDU
|
||||
num_sdus ++;
|
||||
}
|
||||
|
||||
//Update number of SDU
|
||||
num_sdus ++;
|
||||
|
||||
//Update total MAC Header size for RLC PDUs and save last one
|
||||
total_rlc_pdu_header_len += rlc_pdu_header_len_last;
|
||||
|
||||
} //end if (rlc_status.bytes_in_buffer > 0)
|
||||
else {
|
||||
// Switch to next LCID or exit the whole loop
|
||||
is_lcid_processed = TRUE;
|
||||
}
|
||||
lcid_rlc_pdu_count ++;
|
||||
}
|
||||
|
||||
UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY;
|
||||
@@ -1666,7 +1689,7 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
- else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR.
|
||||
*/
|
||||
if (sdu_length_total) {
|
||||
padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
|
||||
padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
|
||||
}
|
||||
else {
|
||||
padding_len = buflen - (bsr_len + phr_len);
|
||||
@@ -1762,7 +1785,7 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
// 1-bit padding or 2-bit padding special padding subheader
|
||||
// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
|
||||
if (sdu_length_total) {
|
||||
padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
|
||||
padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
|
||||
}
|
||||
else {
|
||||
padding_len = buflen - (bsr_len + phr_len);
|
||||
@@ -1774,12 +1797,11 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
post_padding = 0;
|
||||
//update total MAC Hdr size for RLC data
|
||||
if (sdu_length_total) {
|
||||
total_rlc_pdu_header_len = total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1;
|
||||
rlc_pdu_header_len_last = 1;
|
||||
total_rlc_pdu_header_len ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sdu_length_total) {
|
||||
total_rlc_pdu_header_len += rlc_pdu_header_len_last;
|
||||
post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
|
||||
// If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding
|
||||
if (post_padding == 0) {
|
||||
@@ -1824,8 +1846,10 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY)
|
||||
}
|
||||
|
||||
// fill remainder of DLSCH with random data
|
||||
for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) {
|
||||
ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff);
|
||||
if (post_padding) {
|
||||
for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) {
|
||||
ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff);
|
||||
}
|
||||
}
|
||||
LOG_D(MAC,"[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n",
|
||||
module_idP,payload_offset, sdu_length_total);
|
||||
@@ -2295,7 +2319,7 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subfra
|
||||
uint8_t lcgid;
|
||||
uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
|
||||
uint16_t lcgid_buffer_remain[MAX_NUM_LCGID] = {0,0,0,0};
|
||||
uint16_t lcid_bytes_in_buffer[MAX_NUM_LCID];
|
||||
int32_t lcid_bytes_in_buffer[MAX_NUM_LCID];
|
||||
/* Array for ordering LCID with data per decreasing priority order */
|
||||
uint8_t lcid_reordered_array[MAX_NUM_LCID]=
|
||||
{MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID};
|
||||
|
||||
Reference in New Issue
Block a user