diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index cb1b2e491769bccc414d85a49559cc590e13c3ee..86fc367f51b0c3b572a5d28b500f6a2c98e5a63d 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -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 diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 1ba0fa092d5bd7e7ccd4f34e5b1143d4ad20ca04..0413cfe524af442798b23e4b97e3d08b2925510f 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -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};