Commit 3a3a699b authored by Fabrice Nabet's avatar Fabrice Nabet

Merge branch 'BSR_fixes_fabrice' into 'develop1B'

Bsr fixes fabrice

Merge feature BSR stabilization to develop1B

See merge request !15
parents 9bea08ab bc032392
...@@ -70,6 +70,9 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) ...@@ -70,6 +70,9 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index)
UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
//Set BSR Trigger Bmp and remove timer flags
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
// stop ongoing RACH procedure // stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
...@@ -178,8 +181,14 @@ rrc_mac_config_req( ...@@ -178,8 +181,14 @@ rrc_mac_config_req(
if (logicalChannelConfig->ul_SpecificParameters) { if (logicalChannelConfig->ul_SpecificParameters) {
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate *
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; if (logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup != NULL) {
LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_idP,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup); UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_idP,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup);
}
else {
UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity] = MAX_NUM_LCGID;
}
UE_mac_inst[Mod_idP].scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
} else { } else {
LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_idP,logicalChannelIdentity); LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_idP,logicalChannelIdentity);
mac_xface->macphy_exit("NULL ul_SpecificParameters"); mac_xface->macphy_exit("NULL ul_SpecificParameters");
...@@ -225,12 +234,34 @@ rrc_mac_config_req( ...@@ -225,12 +234,34 @@ rrc_mac_config_req(
if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9; UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = (uint16_t) 0; UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0;
} }
if (mac_MainConfig->ext2 && mac_MainConfig->ext2->mac_MainConfig_v1020) {
if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0;
}
if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0;
}
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0;
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0;
}
#endif #endif
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer); UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer); UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
LOG_D(MAC,"[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
UE_mac_inst[Mod_idP].scheduling_info.drx_config = mac_MainConfig->drx_Config; UE_mac_inst[Mod_idP].scheduling_info.drx_config = mac_MainConfig->drx_Config;
UE_mac_inst[Mod_idP].scheduling_info.phr_config = mac_MainConfig->phr_Config; UE_mac_inst[Mod_idP].scheduling_info.phr_config = mac_MainConfig->phr_Config;
...@@ -252,6 +283,7 @@ rrc_mac_config_req( ...@@ -252,6 +283,7 @@ rrc_mac_config_req(
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer); UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer); UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].scheduling_info.PathlossChange); UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].scheduling_info.PathlossChange);
UE_mac_inst[Mod_idP].PHR_reporting_active = 0;
LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP, Mod_idP,
(mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1, (mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1,
......
...@@ -133,10 +133,18 @@ ...@@ -133,10 +133,18 @@
/*!\brief maximum value for channel quality indicator */ /*!\brief maximum value for channel quality indicator */
#define MAX_CQI_VALUE 15 #define MAX_CQI_VALUE 15
/*!\brief value for indicating BSR Timer is not running */
#define MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
#define LCID_EMPTY 0 #define LCID_EMPTY 0
#define LCID_NOT_EMPTY 1 #define LCID_NOT_EMPTY 1
/*!\brief minimum RLC PDU size to be transmitted = min RLC Status PDU or RLC UM PDU SN 5 bits */
#define MIN_RLC_PDU_SIZE (2)
/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
#define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE)
/* /*
* eNB part * eNB part
*/ */
...@@ -222,11 +230,10 @@ typedef struct { ...@@ -222,11 +230,10 @@ typedef struct {
typedef BSR_SHORT BSR_TRUNCATED; typedef BSR_SHORT BSR_TRUNCATED;
/*!\brief mac control element: long buffer status report for all logical channel group ID*/ /*!\brief mac control element: long buffer status report for all logical channel group ID*/
typedef struct { typedef struct {
uint32_t Buffer_size3:6; uint8_t Buffer_size3:6;
uint32_t Buffer_size2:6; uint8_t Buffer_size2:6;
uint32_t Buffer_size1:6; uint8_t Buffer_size1:6;
uint32_t Buffer_size0:6; uint8_t Buffer_size0:6;
uint32_t padding:8;
} __attribute__((__packed__))BSR_LONG; } __attribute__((__packed__))BSR_LONG;
#define BSR_LONG_SIZE (sizeof(BSR_LONG)) #define BSR_LONG_SIZE (sizeof(BSR_LONG))
...@@ -336,6 +343,12 @@ typedef struct { ...@@ -336,6 +343,12 @@ typedef struct {
#define SHORT_BSR 29 #define SHORT_BSR 29
/*!\brief LCID of long BSR for ULSCH */ /*!\brief LCID of long BSR for ULSCH */
#define LONG_BSR 30 #define LONG_BSR 30
/*!\bitmaps for BSR Triggers */
#define BSR_TRIGGER_NONE (0) /* No BSR Trigger */
#define BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
#define BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
/*! \brief Downlink SCH PDU Structure */ /*! \brief Downlink SCH PDU Structure */
typedef struct { typedef struct {
...@@ -945,8 +958,12 @@ typedef enum { ...@@ -945,8 +958,12 @@ typedef enum {
typedef struct { typedef struct {
/// buffer status for each lcgid /// buffer status for each lcgid
uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology
/// keep the number of bytes in rlc buffer for each lcid /// 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
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 /// buffer status for each lcid
uint8_t LCID_status[MAX_NUM_LCID]; uint8_t LCID_status[MAX_NUM_LCID];
/// SR pending as defined in 36.321 /// SR pending as defined in 36.321
...@@ -958,11 +975,11 @@ typedef struct { ...@@ -958,11 +975,11 @@ typedef struct {
/// retxBSR-Timer, default value is sf2560 /// retxBSR-Timer, default value is sf2560
uint16_t retxBSR_Timer; uint16_t retxBSR_Timer;
/// retxBSR_SF, number of subframe before triggering a regular BSR /// retxBSR_SF, number of subframe before triggering a regular BSR
int16_t retxBSR_SF; uint16_t retxBSR_SF;
/// periodicBSR-Timer, default to infinity /// periodicBSR-Timer, default to infinity
uint16_t periodicBSR_Timer; uint16_t periodicBSR_Timer;
/// periodicBSR_SF, number of subframe before triggering a periodic BSR /// periodicBSR_SF, number of subframe before triggering a periodic BSR
int16_t periodicBSR_SF; uint16_t periodicBSR_SF;
/// default value is 0: not configured /// default value is 0: not configured
uint16_t sr_ProhibitTimer; uint16_t sr_ProhibitTimer;
/// sr ProhibitTime running /// sr ProhibitTime running
...@@ -987,6 +1004,12 @@ typedef struct { ...@@ -987,6 +1004,12 @@ typedef struct {
int16_t prohibitPHR_SF; int16_t prohibitPHR_SF;
///DL Pathloss Change in db ///DL Pathloss Change in db
uint16_t PathlossChange_db; uint16_t PathlossChange_db;
/// default value is false
uint16_t extendedBSR_Sizes_r10;
/// default value is false
uint16_t extendedPHR_r10;
//Bj bucket usage per lcid //Bj bucket usage per lcid
int16_t Bj[MAX_NUM_LCID]; int16_t Bj[MAX_NUM_LCID];
// Bucket size per lcid // Bucket size per lcid
...@@ -1074,6 +1097,13 @@ typedef struct { ...@@ -1074,6 +1097,13 @@ typedef struct {
uint8_t PHR_reporting_active; uint8_t PHR_reporting_active;
/// power backoff due to power management (as allowed by P-MPRc) for this cell /// power backoff due to power management (as allowed by P-MPRc) for this cell
uint8_t power_backoff_db[NUMBER_OF_eNB_MAX]; uint8_t power_backoff_db[NUMBER_OF_eNB_MAX];
/// BSR report falg management
uint8_t BSR_reporting_active;
/// retxBSR-Timer expires flag
uint8_t retxBSRTimer_expires_flag;
/// periodBSR-Timer expires flag
uint8_t periodBSRTimer_expires_flag;
/// MBSFN_Subframe Configuration /// MBSFN_Subframe Configuration
struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
/// number of subframe allocation pattern available for MBSFN sync area /// number of subframe allocation pattern available for MBSFN sync area
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
//extern uint32_t EBSR_Level[63]; //extern uint32_t EBSR_Level[63];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
//extern uint32_t Extended_BSR_TABLE[63]; ----currently not used
extern UE_MAC_INST *UE_mac_inst; extern UE_MAC_INST *UE_mac_inst;
extern eNB_MAC_INST *eNB_mac_inst; extern eNB_MAC_INST *eNB_mac_inst;
......
...@@ -538,21 +538,6 @@ UE_L2_STATE_t ue_scheduler( ...@@ -538,21 +538,6 @@ UE_L2_STATE_t ue_scheduler(
*/ */
int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen); int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen);
/*! \fn int get_bsr_lcgid (module_id_t module_idP);
\brief determine the lcgid for the bsr
\param[in] Mod_id instance of the UE
\param[out] lcgid
*/
int get_bsr_lcgid (module_id_t module_idP);
/*! \fn uint8_t get_bsr_len (module_id_t module_idP,uint16_t bufflen);
\brief determine whether the bsr is short or long assuming that the MAC pdu is built
\param[in] Mod_id instance of the UE
\param[in] bufflen size of phy transport block
\param[out] bsr_len size of bsr control element
*/
uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen);
/*! \fn BSR_SHORT * get_bsr_short(module_id_t module_idP, uint8_t bsr_len) /*! \fn BSR_SHORT * get_bsr_short(module_id_t module_idP, uint8_t bsr_len)
\brief get short bsr level \brief get short bsr level
\param[in] Mod_id instance of the UE \param[in] Mod_id instance of the UE
...@@ -569,22 +554,21 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len); ...@@ -569,22 +554,21 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len);
*/ */
BSR_LONG * get_bsr_long(module_id_t module_idP, uint8_t bsr_len); BSR_LONG * get_bsr_long(module_id_t module_idP, uint8_t bsr_len);
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid) /*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP)
\brief get the rlc stats and update the bsr level for each lcid \brief get the rlc stats and update the bsr level for each lcid
\param[in] Mod_id instance of the UE \param[in] Mod_id instance of the UE
\param[in] frame Frame index \param[in] frame Frame index
\param[in] lcid logical channel identifier
*/ */
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, eNB_index_t eNB_index, uint8_t lcid, uint8_t lcgid); boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP,eNB_index_t eNB_index);
/*! \fn locate (int *table, int size, int value) /*! \fn locate_BsrIndexByBufferSize (int *table, int size, int value)
\brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. \brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
\param[in] *table Pointer to BSR table \param[in] *table Pointer to BSR table
\param[in] size Size of the table \param[in] size Size of the table
\param[in] value Value of the buffer \param[in] value Value of the buffer
\return the index in the BSR_LEVEL table \return the index in the BSR_LEVEL table
*/ */
uint8_t locate (const uint32_t *table, int size, int value); uint8_t locate_BsrIndexByBufferSize (const uint32_t *table, int size, int value);
/*! \fn int get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer) /*! \fn int get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
......
...@@ -391,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -391,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
1); //post_padding 1); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources); return(&UE_mac_inst[module_idP].RA_prach_resources);
} else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DCCH] > 0) { } else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
...@@ -412,7 +412,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -412,7 +412,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
(char *)&ulsch_buff[0]); (char *)&ulsch_buff[0]);
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]); LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
update_bsr(module_idP, frameP, eNB_indexP,DCCH,UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]); update_bsr(module_idP, frameP, subframeP,eNB_indexP);
UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] =
locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]]);
//TO DO: fill BSR infos in UL TBS
//header_len +=2; //header_len +=2;
UE_mac_inst[module_idP].RA_active = 1; UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1; UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
......
...@@ -70,6 +70,8 @@ ...@@ -70,6 +70,8 @@
#define DEBUG_HEADER_PARSING 1 #define DEBUG_HEADER_PARSING 1
#define ENABLE_MAC_PAYLOAD_DEBUG 1 #define ENABLE_MAC_PAYLOAD_DEBUG 1
extern uint8_t usim_test;
/* /*
#ifndef USER_MODE #ifndef USER_MODE
#define msg debug_msg #define msg debug_msg
...@@ -91,7 +93,7 @@ void ue_init_mac(module_id_t module_idP) ...@@ -91,7 +93,7 @@ void ue_init_mac(module_id_t module_idP)
// default values as deined in 36.331 sec 9.2.2 // default values as deined in 36.331 sec 9.2.2
LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
//UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240;
UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
...@@ -102,13 +104,19 @@ void ue_init_mac(module_id_t module_idP) ...@@ -102,13 +104,19 @@ void ue_init_mac(module_id_t module_idP)
UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0; UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
UE_mac_inst[module_idP].scheduling_info.ttiBundling=0; UE_mac_inst[module_idP].scheduling_info.ttiBundling=0;
UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10=0;
UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10=0;
UE_mac_inst[module_idP].scheduling_info.drx_config=NULL; UE_mac_inst[module_idP].scheduling_info.drx_config=NULL;
UE_mac_inst[module_idP].scheduling_info.phr_config=NULL; UE_mac_inst[module_idP].scheduling_info.phr_config=NULL;
UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer); // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW.
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer); UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer); UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer);
UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer); UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer);
UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[module_idP].scheduling_info.PathlossChange); UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[module_idP].scheduling_info.PathlossChange);
UE_mac_inst[module_idP].PHR_reporting_active = 0;
for (i=0; i < MAX_NUM_LCID; i++) { for (i=0; i < MAX_NUM_LCID; i++) {
LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i); LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i);
...@@ -121,7 +129,8 @@ void ue_init_mac(module_id_t module_idP) ...@@ -121,7 +129,8 @@ void ue_init_mac(module_id_t module_idP)
UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1; UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1;
} }
UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=0; UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=LCID_EMPTY;
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
} }
#ifdef CBA #ifdef CBA
...@@ -304,6 +313,14 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i ...@@ -304,6 +313,14 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i
// notify RRC to relase PUCCH/SRS // notify RRC to relase PUCCH/SRS
// clear any configured dl/ul // clear any configured dl/ul
// initiate RA // initiate RA
if (UE_mac_inst[module_idP].scheduling_info.SR_pending){
// release all pucch resource
UE_mac_inst[module_idP].physicalConfigDedicated = NULL;
UE_mac_inst[module_idP].ul_active=0;
UE_mac_inst[module_idP].BSR_reporting_active=BSR_TRIGGER_NONE;
LOG_I(MAC,"[UE %d] Release all SRs \n", module_idP);
}
UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
return(0); return(0);
...@@ -312,12 +329,16 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i ...@@ -312,12 +329,16 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
ue_send_sdu(module_id_t module_idP, ue_send_sdu(
module_id_t module_idP,
uint8_t CC_id, uint8_t CC_id,
frame_t frameP, frame_t frameP,
uint8_t* sdu, uint8_t* sdu,
uint16_t sdu_len, uint16_t sdu_len,
uint8_t eNB_index) { uint8_t eNB_index
)
//------------------------------------------------------------------------------
{
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX]; unsigned char rx_lcids[NB_RB_MAX];
...@@ -1131,8 +1152,6 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, ...@@ -1131,8 +1152,6 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
*(ce_ptr) = (long_bsr->Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4); *(ce_ptr) = (long_bsr->Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4);
*(ce_ptr + 1) = ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr->Buffer_size2 & 0x3C) >> 2); *(ce_ptr + 1) = ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr->Buffer_size2 & 0x3C) >> 2);
*(ce_ptr + 2) = ((long_bsr->Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F); *(ce_ptr + 2) = ((long_bsr->Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F);
/* Padding */
*(ce_ptr + 3) = 0;
ce_ptr += BSR_LONG_SIZE; ce_ptr += BSR_LONG_SIZE;
// printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
...@@ -1145,50 +1164,67 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, ...@@ -1145,50 +1164,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]); LOG_T(MAC,"[UE] sdu subheader %d (lcid %d, %d bytes)\n",i,sdu_lcids[i],sdu_lengths[i]);
#endif #endif
if ((first_element>0)) { if ((i == (num_sdus - 1)) && ((short_padding) || (post_padding == 0))) {
mac_header_ptr->E = 1; if (first_element>0) {
#ifdef DEBUG_HEADER_PARSING mac_header_ptr->E = 1;
LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, #ifdef DEBUG_HEADER_PARSING
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, 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)->E, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
#endif ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
mac_header_ptr+=last_size; #endif
// printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); mac_header_ptr+=last_size;
} else { }
first_element=1; 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; if (sdu_lengths[i] < 128) {
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; // 3
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0;
last_size=2; ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
#ifdef DEBUG_HEADER_PARSING ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i];
LOG_D(MAC,"[UE] short sdu\n"); last_size=2;
LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n", #ifdef DEBUG_HEADER_PARSING
((uint16_t*)mac_header_ptr)[0], LOG_D(MAC,"[UE] short sdu\n");
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R, LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E, ((uint16_t*)mac_header_ptr)[0],
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID, ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F, ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L); ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
#endif ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
} else { ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; #endif
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; } else {
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
last_size=3; ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff;
#ifdef DEBUG_HEADER_PARSING ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00;
LOG_D(MAC,"[UE] long sdu\n"); last_size=3;
#endif #ifdef DEBUG_HEADER_PARSING
LOG_D(MAC,"[UE] long sdu\n");
#endif
}
} }
} }
...@@ -1206,6 +1242,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, ...@@ -1206,6 +1242,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
//mac_header_ptr=last_size; // FIXME: should be ++ //mac_header_ptr=last_size; // FIXME: should be ++
} }
if ((ce_ptr-mac_header_control_elements) > 0) { if ((ce_ptr-mac_header_control_elements) > 0) {
memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); 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); mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
...@@ -1228,27 +1265,36 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf ...@@ -1228,27 +1265,36 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
{ {
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0,dtch_header_len_last=0; uint8_t total_rlc_pdu_header_len=0, rlc_pdu_header_len_last=0 ;
uint8_t dcch_header_len_tmp=0, dtch_header_len_tmp=0; uint16_t buflen_remain = 0;
uint8_t bsr_header_len=0, bsr_ce_len=0, bsr_len=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 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 }; 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 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t payload_offset=0,num_sdus=0; uint8_t payload_offset=0,num_sdus=0;
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
uint16_t sdu_length_total=0; uint16_t sdu_length_total=0;
BSR_SHORT bsr_short; BSR_SHORT bsr_short,bsr_truncated;
BSR_LONG bsr_long; BSR_LONG bsr_long;
BSR_SHORT *bsr_s=&bsr_short; BSR_SHORT *bsr_s=&bsr_short;
BSR_LONG *bsr_l=&bsr_long; BSR_LONG *bsr_l=&bsr_long;
BSR_SHORT *bsr_t=&bsr_truncated;
POWER_HEADROOM_CMD phr; POWER_HEADROOM_CMD phr;
POWER_HEADROOM_CMD *phr_p=&phr; POWER_HEADROOM_CMD *phr_p=&phr;
unsigned short short_padding=0, post_padding=0; unsigned short short_padding=0, post_padding=0, padding_len=0;
int lcgid;
int j; // used for padding int j; // used for padding
// Compute header length // Compute header length
int lcg_id = 0;
int lcg_id_bsr_trunc = 0;
int highest_priority = 16;
int num_lcg_id_with_data = 0;
LOG_D(MAC,"[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n",
module_idP, frameP, subframe, buflen);
if (CC_id>0) { if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0"); mac_xface->macphy_exit("MAC FATAL CC_id>0");
...@@ -1276,33 +1322,76 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf ...@@ -1276,33 +1322,76 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
} }
#endif #endif
dcch_header_len=2;//sizeof(SCH_SUBHEADER_SHORT); bsr_header_len = 0;
dcch1_header_len=2;//sizeof(SCH_SUBHEADER_SHORT);
// hypo length,in case of long header skip the padding byte
dtch_header_len=(buflen > 128 ) ? 3 : 2 ; //sizeof(SCH_SUBHEADER_LONG)-1 : sizeof(SCH_SUBHEADER_SHORT);
bsr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
phr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED); phr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
if (phr_ce_len > 0) { while (lcg_id < MAX_NUM_LCGID) {
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
num_lcg_id_with_data ++;
}
lcg_id ++;
}
if (num_lcg_id_with_data){
LOG_D(MAC,"[UE %d] MAC Tx data pending at frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
module_idP,
frameP,
subframe,
num_lcg_id_with_data,
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
UE_mac_inst[module_idP].BSR_reporting_active, buflen);
}
//Restart ReTxBSR Timer at new grant indication (36.321)
if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING){
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
}
// periodicBSR-Timer expires, trigger BSR
if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity)
&& (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)){
// Trigger BSR Periodic
UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PERIODIC;
LOG_I(MAC,"[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n",
module_idP, frameP, subframe, buflen);
}
//Compute BSR Length if Regular or Periodic BSR is triggered
//WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx
if (UE_mac_inst[module_idP].BSR_reporting_active){
AssertFatal ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING) == 0 , "Inconsistent BSR Trigger=%d !\n",
UE_mac_inst[module_idP].BSR_reporting_active);
if (buflen >= 4){
//A Regular or Periodic BSR can only be sent if TBS >= 4 as transmitting only a BSR is not allowed if UE has data to transmit
bsr_header_len = 1;
if (num_lcg_id_with_data <= 1){
bsr_ce_len = sizeof(BSR_SHORT); //1 byte
}
else{
bsr_ce_len = BSR_LONG_SIZE; //3 bytes
}
}
}
bsr_len = bsr_ce_len + bsr_header_len;
phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
if ((phr_ce_len > 0) && ((phr_ce_len + phr_header_len + bsr_len) <= buflen)){
phr_len = phr_ce_len + phr_header_len; phr_len = phr_ce_len + phr_header_len;
LOG_D(MAC,"[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n", LOG_D(MAC,"[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n",
module_idP, phr_len, phr_ce_len, phr_header_len, buflen); module_idP, phr_len, phr_ce_len, phr_header_len, buflen);
} else { } else {
phr_len=0; phr_len=0;
} phr_header_len = 0;
phr_ce_len = 0;
bsr_ce_len = get_bsr_len (module_idP, buflen-phr_len);
if (bsr_ce_len > 0 ) {
bsr_len = bsr_ce_len + bsr_header_len;
LOG_D(MAC,"[UE %d] header size info: dcch %d, dcch1 %d, dtch %d, bsr (ce%d,hdr%d) buff_len %d\n",
module_idP, dcch_header_len,dcch1_header_len,dtch_header_len, bsr_ce_len, bsr_header_len, buflen);
} else {
bsr_len=0;
//LOG_D(MAC,"[UE %d] Empty buffers, send a long BSR to reset the bsr at eNB \n ",Mod_id);
// bsr_ce_len = sizeof(BSR_LONG);
//bsr_len = bsr_ce_len + bsr_header_len;
} }
// check for UL bandwidth requests and add SR control element // check for UL bandwidth requests and add SR control element
...@@ -1310,164 +1399,308 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf ...@@ -1310,164 +1399,308 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
// check for UL bandwidth requests and add SR control element // check for UL bandwidth requests and add SR control element
// Check for DCCH first // Check for DCCH first
// TO DO: Unrool the loop to do it at least once to avoid the if num_sdu
for (lcid=DCCH; lcid < DTCH ; lcid++) {
if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH] == LCID_NOT_EMPTY) { is_lcid_processed = FALSE;
lcid_rlc_pdu_count = 0;
rlc_status = mac_rlc_status_ind(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO, // eNB_index
DCCH,
(buflen-dcch_header_len-bsr_len-phr_len));
LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to "
"send (Transport Block size %d, mac header len %d)\n",
module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch_header_len);
sdu_lengths[0] += mac_rlc_data_req(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
DCCH,
(char *)&ulsch_buff[sdu_lengths[0]]);
sdu_length_total += sdu_lengths[0];
sdu_lcids[0] = DCCH;
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
num_sdus = 1;
update_bsr(module_idP, frameP, eNB_index, DCCH, UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
//header_len +=2;
} else {
dcch_header_len=0;
num_sdus = 0;
}
// if the RLC AM is used, then RLC will only provide 2 bytes for ACK
// in this case, we sould add bsr
// DCCH1
if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH1] == LCID_NOT_EMPTY) {
rlc_status = mac_rlc_status_ind(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO, // eNB_index
DCCH1,
(buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-sdu_length_total));
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH1 -> ULSCH, RRC message has %d bytes to"
" send (Transport Block size %d, mac header len %d)\n",
module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch1_header_len);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
DCCH1,
(char *)&ulsch_buff[sdu_lengths[num_sdus]]);
sdu_length_total += sdu_lengths[num_sdus];
sdu_lcids[num_sdus] = DCCH1;
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH1\n",module_idP,sdu_lengths[num_sdus]);
num_sdus++;
//update_bsr(module_idP, frameP, DCCH1);
//dcch_header_len +=2; // include dcch1
} else {
dcch1_header_len =0;
}
dtch_header_len=0; //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
dtch_header_len_last=0; //Adjust at the end of the loop
for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){ while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
dtch_header_len+=3;
dtch_header_len_last=3; // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU
if ((usim_test == 0) && (lcid == DCCH1) && (lcid_rlc_pdu_count == 0) && (num_sdus)) {
if ((UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) &&
((bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len+sdu_length_total) <= buflen)) { // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed
break;
// optimize the dtch header lenght }
//if ((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] > 128) &&
/* if (((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] >= 128) && buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH]+bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len) > buflen)&&
buflen >=128 )) rlc_status = mac_rlc_status_ind(module_idP,
dtch_header_len = 3;//sizeof(SCH_SUBHEADER_LONG); UE_mac_inst[module_idP].crnti,
else eNB_index,
dtch_header_len = 2;//sizeof(SCH_SUBHEADER_SHORT); frameP,
*/ ENB_FLAG_NO,
rlc_status = mac_rlc_status_ind(module_idP, MBMS_FLAG_NO, // eNB_index
UE_mac_inst[module_idP].crnti, lcid,
eNB_index, buflen_remain);
frameP,
ENB_FLAG_NO, // Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO
MBMS_FLAG_NO, // eNB_index if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] < rlc_status.bytes_in_buffer) {
lcid,
buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total); LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n",
module_idP,frameP,subframe,
LOG_D(MAC,"[UE %d] Frame %d : UL-DTCH -> ULSCH%d, %d bytes to send (Transport Block size %d, mac header len %d, BSR byte[%d] %d)\n", lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count);
module_idP,frameP, lcid, rlc_status.bytes_in_buffer,buflen,dtch_header_len,
lcid, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcid]); // Skip multiplexing for the LCID
break;
if (rlc_status.bytes_in_buffer > 0) { }
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
UE_mac_inst[module_idP].crnti, /*
eNB_index, 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",
frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe);
ENB_FLAG_NO, */
MBMS_FLAG_NO, // eNB_index
lcid, if (rlc_status.bytes_in_buffer > 0) {
(char *)&ulsch_buff[sdu_length_total]);
//adjust dtch header LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RLC SRB%d has %d bytes to "
LOG_D(MAC,"[UE %d] TX Got %d bytes for DTCH\n",module_idP,sdu_lengths[num_sdus]); "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n",
sdu_lcids[num_sdus] = lcid; module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
sdu_length_total += sdu_lengths[num_sdus];
if (sdu_lengths[num_sdus] < 128) {
dtch_header_len --; sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
dtch_header_len_last --; UE_mac_inst[module_idP].crnti,
} eNB_index,
num_sdus++; frameP,
UE_mac_inst[module_idP].ul_active = update_bsr(module_idP, frameP, eNB_index,lcid, UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]); ENB_FLAG_NO,
} else { MBMS_FLAG_NO,
dtch_header_len -= 3; lcid,
} (char *)&ulsch_buff[sdu_length_total]);
} else { // no rlc pdu : generate the dummy header
dtch_header_len -= 3;
} 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]);
sdu_length_total += sdu_lengths[num_sdus];
sdu_lcids[num_sdus] = lcid;
LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for SRB%d\n",module_idP,sdu_lengths[num_sdus],lcid);
//header_len +=2;
// update LCID remain buffer
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus];
/* Update BSR : substract transmitted data */
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ;
}
else {
LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n",
module_idP,frameP,subframe,
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],
sdu_lengths[num_sdus],lcid);
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
}
//Update the number of LCGID with data as BSR shall reflect status after BSR transmission
if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0))
{
num_lcg_id_with_data --;
// Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1
if ((bsr_len) && (num_lcg_id_with_data == 1))
{
bsr_ce_len = sizeof(BSR_SHORT);
bsr_len = bsr_ce_len + bsr_header_len;
}
}
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
rlc_pdu_header_len_last = 1;
is_lcid_processed = TRUE;
}
else {
rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ;
//Change to 1 byte if it does not fit in the TBS, ie last PDU
if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) {
rlc_pdu_header_len_last = 1;
is_lcid_processed = TRUE;
}
}
//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;
}
}
// Now Check for DTCH first
// TO DO: do it according to Logical Channel Prioritization if at least 2 DTCH
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 + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
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,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO, // eNB_index
lcid,
buflen_remain);
// Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO
if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] < rlc_status.bytes_in_buffer) {
LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n",
module_idP,frameP,subframe,
lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count);
// Skip multiplexing for the LCID
break;
}
/*
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) {
LOG_D(MAC, "[UE %d] Frame %d : UL-DTCH -> ULSCH, RLC LCID%d has %d bytes to "
"send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n",
module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
UE_mac_inst[module_idP].crnti,
eNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
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]);
sdu_length_total += sdu_lengths[num_sdus];
sdu_lcids[num_sdus] = lcid;
LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LCID%d\n",module_idP,sdu_lengths[num_sdus],lcid);
//header_len +=2;
// update LCID remain buffer
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus];
/* Update BSR : substract transmitted data */
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ;
}
else {
LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n",
module_idP,frameP,subframe,
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],
sdu_lengths[num_sdus],lcid);
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
}
//Update the number of LCGID with data as BSR shall reflect status after BSR transmission
if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0))
{
num_lcg_id_with_data --;
// Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1
if ((bsr_len) && (num_lcg_id_with_data == 1))
{
bsr_ce_len = sizeof(BSR_SHORT);
bsr_len = bsr_ce_len + bsr_header_len;
}
}
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
rlc_pdu_header_len_last = 1;
is_lcid_processed = TRUE;
}
else {
rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ;
//Change to 1 byte if it does not fit in the TBS, ie last PDU
if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) {
rlc_pdu_header_len_last = 1;
is_lcid_processed = TRUE;
}
}
//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;
}
}
//lcgid= get_bsr_lcgid(module_idP);
// Compute BSR Values and update Nb LCGID with data after multiplexing
num_lcg_id_with_data = 0;
lcg_id_bsr_trunc = 0;
for (lcg_id=0;lcg_id<MAX_NUM_LCGID;lcg_id++){
UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]);
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
num_lcg_id_with_data ++;
lcg_id_bsr_trunc = lcg_id;
}
} }
lcgid= get_bsr_lcgid(module_idP);
if (bsr_ce_len) {
if (lcgid < 0 ) { //Print updated BSR when sent
bsr_s = NULL; LOG_D(MAC,"[UE %d] Remaining Buffer after Tx frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
bsr_l = NULL ; module_idP,
} else if ((lcgid ==MAX_NUM_LCGID) && (bsr_ce_len == sizeof(BSR_LONG))) { frameP,
bsr_s = NULL; subframe,
bsr_l->Buffer_size0 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0]; num_lcg_id_with_data,
bsr_l->Buffer_size1 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]; UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
bsr_l->Buffer_size2 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]; UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
bsr_l->Buffer_size3 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]; UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
LOG_D(MAC, "[UE %d] Frame %d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0], UE_mac_inst[module_idP].BSR_reporting_active, buflen);
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1],
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2], LOG_D(MAC,"[UE %d] Frame %d Subframe %d TX BSR Regular or Periodic size=%d BSR0=%d BSR1=%d BSR2=%d BSR3=%d\n",module_idP,frameP,subframe,bsr_ce_len,
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]); UE_mac_inst[module_idP].scheduling_info.BSR[0],
} else if (bsr_ce_len == sizeof(BSR_SHORT)) { UE_mac_inst[module_idP].scheduling_info.BSR[1],
bsr_l = NULL; UE_mac_inst[module_idP].scheduling_info.BSR[2],
bsr_s->LCGID = lcgid; UE_mac_inst[module_idP].scheduling_info.BSR[3]);
bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcgid];
LOG_D(MAC,"[UE %d] Frame %d report SHORT BSR with level %d for LCGID %d\n",
module_idP, frameP, UE_mac_inst[module_idP].scheduling_info.BSR[lcgid],lcgid);
} else {
bsr_s = NULL;
bsr_l = NULL;
} }
// build PHR and update the timers // build PHR and update the timers
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index); phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
...@@ -1481,37 +1714,146 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf ...@@ -1481,37 +1714,146 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", module_idP,frameP,bsr_s, bsr_l, phr_p); LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", module_idP,frameP,bsr_s, bsr_l, phr_p);
if (dtch_header_len == 0 )
dtch_header_len_last =0;
// adjust the header length
dcch_header_len_tmp = dcch_header_len;
dtch_header_len_tmp = dtch_header_len;
if (dtch_header_len==0) { // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
dcch_header_len = (dcch_header_len>0)? 1: dcch_header_len; // Check for max padding size, ie MAC Hdr for last RLC PDU = 1
} else { /* For Padding BSR:
dtch_header_len_last-=1; - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader:
dtch_header_len= (dtch_header_len >0)? dtch_header_len - dtch_header_len_last : dtch_header_len; - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission;
} - else report Short BSR.
- 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 ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) <= 2) { */
short_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total; if (sdu_length_total) {
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);
}
if ((padding_len) && (bsr_len == 0))
{
/* 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 (padding_len >= (1+BSR_LONG_SIZE))
{
bsr_ce_len = BSR_LONG_SIZE;
bsr_header_len = 1;
// Trigger BSR Padding
UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;
} else if (padding_len >= (1+sizeof(BSR_SHORT))) {
bsr_ce_len = sizeof(BSR_SHORT);
bsr_header_len = 1;
if (num_lcg_id_with_data > 1)
{
// REPORT TRUNCATED BSR
//Get LCGID of highest priority LCID with data
for (lcid=DCCH; lcid < MAX_NUM_LCID ; lcid++) {
if (UE_mac_inst[module_idP].logicalChannelConfig[lcid] != NULL) {
lcg_id = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid];
if ((lcg_id < MAX_NUM_LCGID) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id])
&& (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority)) {
highest_priority = UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority;
lcg_id_bsr_trunc = lcg_id;
}
}
}
}
else
{
//Report SHORT BSR, clear bsr_t
bsr_t = NULL;
}
// Trigger BSR Padding
UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;
}
bsr_len = bsr_header_len + bsr_ce_len;
}
//Fill BSR Infos
if (bsr_ce_len == 0 ) {
bsr_s = NULL;
bsr_l = NULL;
bsr_t = NULL;
} else if (bsr_ce_len == BSR_LONG_SIZE) {
bsr_s = NULL;
bsr_t = NULL;
bsr_l->Buffer_size0 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0];
bsr_l->Buffer_size1 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1];
bsr_l->Buffer_size2 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2];
bsr_l->Buffer_size3 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3];
LOG_D(MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP,subframe,
UE_mac_inst[module_idP].BSR_reporting_active,
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0],
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1],
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2],
UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]);
} else if (bsr_ce_len == sizeof(BSR_SHORT)) {
bsr_l = NULL;
if ((bsr_t != NULL) && (UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING)) {
//Truncated BSR
bsr_s = NULL;
bsr_t->LCGID = lcg_id_bsr_trunc;
bsr_t->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);
}
else
{
bsr_t = NULL;
bsr_s->LCGID = lcg_id_bsr_trunc;
bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);
}
}
// 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 - rlc_pdu_header_len_last + sdu_length_total + 1);
}
else {
padding_len = buflen - (bsr_len + phr_len);
}
if (padding_len <= 2) {
short_padding = padding_len;
// only add padding header
post_padding = 0; post_padding = 0;
} else { //update total MAC Hdr size for RLC data
if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) == buflen) { 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;
}
}
else if (sdu_length_total) {
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) {
total_rlc_pdu_header_len -= rlc_pdu_header_len_last;
padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
short_padding = padding_len;
total_rlc_pdu_header_len ++;
}
}
else {
if (padding_len == buflen) {// nona mac pdu
*access_mode=CANCELED_ACCESS; *access_mode=CANCELED_ACCESS;
} }
short_padding = 0; short_padding = 0;
if (dtch_header_len==0) { post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
dcch_header_len = dcch_header_len_tmp;
} else {
dtch_header_len= dtch_header_len_tmp;
}
post_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total -1 ;
} }
// Generate header // Generate header
...@@ -1524,26 +1866,57 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf ...@@ -1524,26 +1866,57 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
sdu_lcids, // sdu lcid sdu_lcids, // sdu lcid
phr_p, // power headroom phr_p, // power headroom
NULL, // crnti NULL, // crnti
NULL, // truncated bsr bsr_t, // truncated bsr
bsr_s, // short bsr bsr_s, // short bsr
bsr_l, bsr_l,
post_padding); // long_bsr post_padding); // long_bsr
LOG_D(MAC, LOG_D(MAC,
"[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, dcch_header_len %d, dtch_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n", "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n",
module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, dcch_header_len, dtch_header_len, module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, total_rlc_pdu_header_len,
short_padding,post_padding, bsr_len, phr_len,buflen-sdu_length_total-payload_offset); short_padding,post_padding, bsr_len, phr_len,buflen-sdu_length_total-payload_offset);
// cycle through SDUs and place in ulsch_buffer // cycle through SDUs and place in ulsch_buffer
memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total); if (sdu_length_total) {
memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total);
}
// fill remainder of DLSCH with random data // fill remainder of DLSCH with random data
for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) { if (post_padding) {
ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff); 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", LOG_D(MAC,"[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n",
module_idP,payload_offset, sdu_length_total); module_idP,payload_offset, sdu_length_total);
UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
/* Actions when a BSR is sent */
if (bsr_ce_len)
{
LOG_D(MAC,"[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
module_idP, bsr_ce_len, bsr_header_len, buflen);
// Reset ReTx BSR Timer
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
LOG_D(MAC,"[UE %d] MAC ReTx BSR Timer Reset =%d\n",
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF);
// Reset Periodic Timer except when BSR is truncated
if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity))
{
UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer);
LOG_D(MAC,"[UE %d] MAC Periodic BSR Timer Reset =%d\n",
UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF);
}
// Reset BSR Trigger flags
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
...@@ -1572,7 +1945,6 @@ ue_scheduler( ...@@ -1572,7 +1945,6 @@ ue_scheduler(
const int CC_id) const int CC_id)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int lcid; // lcid index int lcid; // lcid index
int TTI= 1; int TTI= 1;
int bucketsizeduration = -1; int bucketsizeduration = -1;
...@@ -1581,6 +1953,7 @@ ue_scheduler( ...@@ -1581,6 +1953,7 @@ ue_scheduler(
// int8_t lcg_id; // int8_t lcg_id;
struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL; struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL;
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
MessageDef *msg_p; MessageDef *msg_p;
const char *msg_name; const char *msg_name;
...@@ -1703,13 +2076,9 @@ ue_scheduler( ...@@ -1703,13 +2076,9 @@ ue_scheduler(
} }
// call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures
// outlined in Sections 5.4.4 an 5.4.5 of 36.321
// Put this in another function
// Get RLC status info and update Bj for all lcids that are active // Get RLC status info and update Bj for all lcids that are active
for (lcid=DCCH; lcid <= DTCH; lcid++ ) { for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++ ) {
if ((lcid == 0) ||(UE_mac_inst[module_idP].logicalChannelConfig[lcid])) { if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) {
// meausre the Bj // meausre the Bj
if ((directionP == SF_UL)&& (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] >= 0)) { if ((directionP == SF_UL)&& (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] >= 0)) {
if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters) { if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters) {
...@@ -1727,16 +2096,42 @@ ue_scheduler( ...@@ -1727,16 +2096,42 @@ ue_scheduler(
} }
} }
if (update_bsr(module_idP,frameP, eNB_indexP, lcid, UE_mac_inst[module_idP].scheduling_info.LCGID[lcid])) { /*
UE_mac_inst[module_idP].scheduling_info.SR_pending= 1; if (lcid == DCCH) {
LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d SR for PUSCH is pending for LCGID %d with BSR level %d (%d bytes in RLC)\n", LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d Pending data for SRB1=%d for LCGID %d \n",
module_idP, frameP,subframeP,UE_mac_inst[module_idP].scheduling_info.LCGID[lcid], module_idP, frameP,subframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]);
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
} }
*/
} }
} }
// Call BSR procedure as described in Section 5.4.5 in 36.321
// First check ReTxBSR Timer because it is always configured
// Decrement ReTxBSR Timer if it is running and not null
if ((UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING)
&& (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != 0)){
UE_mac_inst[module_idP].scheduling_info.retxBSR_SF --;
}
// Decrement Periodic Timer if it is running and not null
if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING)
&& (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != 0)){
UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF--;
}
//Check whether Regular BSR is triggered
if (update_bsr(module_idP,frameP, subframeP,eNB_indexP) == TRUE) {
// call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures
// outlined in Sections 5.4.4 an 5.4.5 of 36.321
UE_mac_inst[module_idP].scheduling_info.SR_pending= 1;
// Regular BSR trigger
UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_REGULAR;
LOG_D(MAC,"[UE %d][BSR] Regular BSR Triggered Frame %d subframe %d SR for PUSCH is pending\n",
module_idP, frameP,subframeP);
}
// UE has no valid phy config dedicated || no valid/released SR // UE has no valid phy config dedicated || no valid/released SR
if ((UE_mac_inst[module_idP].physicalConfigDedicated == NULL)) { if ((UE_mac_inst[module_idP].physicalConfigDedicated == NULL)) {
// cancel all pending SRs // cancel all pending SRs
...@@ -1949,103 +2344,147 @@ int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8 ...@@ -1949,103 +2344,147 @@ int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8
} }
#endif #endif
int get_bsr_lcgid (module_id_t module_idP)
{
int lcgid, lcgid_tmp=-1;
int num_active_lcgid = 0;
for (lcgid = 0 ; lcgid < MAX_NUM_LCGID; lcgid++) {
if (UE_mac_inst[module_idP].scheduling_info.BSR[lcgid] > 0 ) {
lcgid_tmp = lcgid;
num_active_lcgid+=1;
}
}
if (num_active_lcgid == 0) {
return -1;
} else if (num_active_lcgid == 1) {
return lcgid_tmp;
} else {
return MAX_NUM_LCGID;
}
}
uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen)
{
int lcgid=0;
uint8_t bsr_len=0, num_lcgid=0;
int pdu = 0;
for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) {
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) {
pdu += (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] + bsr_len + 2); //2 = sizeof(SCH_SUBHEADER_SHORT)
}
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 128 ) { // long header size: adjust the header size
pdu += 1;
}
// current phy buff can not transport all sdu for this lcgid -> transmit a bsr for this lcgid
if ( (pdu > buflen) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) ) {
num_lcgid +=1;
bsr_len = (num_lcgid >= 2 ) ? sizeof(BSR_LONG) : sizeof(BSR_SHORT) ;
}
LOG_D(MAC,"BSR Bytes %d for lcgid %d bsr len %d num lcgid %d\n", UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid], lcgid, bsr_len, num_lcgid);
}
if ( bsr_len > 0 )
LOG_D(MAC,"[UE %d] Prepare a %s (Transport Block Size %d, MAC pdu Size %d) \n",
module_idP, map_int_to_str(BSR_names, bsr_len), buflen, pdu);
return bsr_len;
}
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP,eNB_index_t eNB_index)
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, eNB_index_t eNB_index, uint8_t lcid, uint8_t lcg_id)
{ {
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
boolean_t sr_pending = FALSE; boolean_t bsr_regular_triggered = FALSE;
uint8_t lcid;
uint8_t lcgid;
if ((lcg_id < 0) || (lcg_id >= MAX_NUM_LCGID) ) { uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
return sr_pending; uint16_t lcgid_buffer_remain[MAX_NUM_LCGID] = {0,0,0,0};
} int32_t lcid_bytes_in_buffer[MAX_NUM_LCID];
/* Array for ordering LCID with data per decreasing priority order */
// fixme: need a better way to reset uint8_t lcid_reordered_array[MAX_NUM_LCID]=
if ((lcid == DCCH) || (lcid == DTCH)) { {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};
UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id]=0; uint8_t pos_next = 0;
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]=0; uint8_t highest_priority = 16;
} uint8_t array_index = 0;
// for (lcid =0 ; lcid < MAX_NUM_LCID; lcid++) { // Reset All BSR Infos
if (UE_mac_inst[module_idP].scheduling_info.LCGID[lcid] == lcg_id) { lcid_bytes_in_buffer[0] = 0;
rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
lcid, {
0); // Reset transmission status
lcid_bytes_in_buffer[lcid] = 0;
if (rlc_status.bytes_in_buffer > 0 ) { UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY;
sr_pending = TRUE; }
UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] += locate (BSR_TABLE,BSR_TABLE_SIZE, rlc_status.bytes_in_buffer); for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++)
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id] += rlc_status.bytes_in_buffer; {
// UE_mac_inst[module_idP].scheduling_info.BSR_short_lcid = lcid; // only applicable to short bsr // Reset Buffer Info
LOG_D(MAC,"[UE %d] BSR level %d (LCGID %d, rlc buffer %d byte)\n", UE_mac_inst[module_idP].scheduling_info.BSR[lcgid]=0;
module_idP, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id],lcg_id, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]); UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid]=0;
} else { }
UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY;
} //Get Buffer Occupancy and fill lcid_reordered_array
} for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
{
//} if (UE_mac_inst[module_idP].logicalChannelConfig[lcid])
return sr_pending; {
lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid];
// Store already available data to transmit per Group
if (lcgid < MAX_NUM_LCGID)
{
lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid];
}
rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
lcid,
0);
lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
if (rlc_status.bytes_in_buffer > 0)
{
LOG_D(MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n",
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,subframeP);
UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
if (lcgid < MAX_NUM_LCGID)
{
num_lcid_with_data ++;
// sum lcid buffer which has same lcgid
UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
//Fill in the array
array_index = 0;
do
{
if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority)
{
//Insert if priority is higher or equal (lower or equal in value)
for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--)
{
lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1];
}
lcid_reordered_array[array_index] = lcid;
break;
}
array_index ++;
}
while ((array_index < num_lcid_with_data) && (array_index < MAX_NUM_LCID));
}
}
}
}
// Check whether a regular BSR can be triggered according to the first cases in 36.321
if (num_lcid_with_data)
{
LOG_D(MAC,"[UE %d] PDCCH Tick at frame %d subframe %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n",
module_idP, frameP, subframeP,num_lcid_with_data,lcid_reordered_array[0],lcid_reordered_array[1],lcid_reordered_array[2]);
for (array_index=0; array_index < num_lcid_with_data; array_index++)
{
lcid = lcid_reordered_array[array_index];
/* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
either the data belongs to a logical channel with higher priority than the priorities of the logical channels
which belong to any LCG and for which data is already available for transmission
*/
if ((UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] == 0)
/* or there is no data available for any of the logical channels which belong to a LCG */
||(lcgid_buffer_remain[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)
)
{
bsr_regular_triggered = TRUE;
LOG_D(MAC,"[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n",
module_idP, lcid,UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],frameP, subframeP);
break;
}
}
// Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission
if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0)
{
bsr_regular_triggered = TRUE;
if ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_REGULAR) == 0) {
LOG_I(MAC,"[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d subframe %d\n",
module_idP, frameP, subframeP);
}
}
}
//Store Buffer Occupancy in remain buffers for next TTI
for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
{
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid];
}
return bsr_regular_triggered;
} }
uint8_t locate (const uint32_t *table, int size, int value) uint8_t locate_BsrIndexByBufferSize (const uint32_t *table, int size, int value)
{ {
uint8_t ju, jm, jl; uint8_t ju, jm, jl;
...@@ -2144,7 +2583,7 @@ int get_sf_periodicBSRTimer(uint8_t sf_offset) ...@@ -2144,7 +2583,7 @@ int get_sf_periodicBSRTimer(uint8_t sf_offset)
case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity: case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity:
default: default:
return -1; return 0xFFFF;
break; break;
} }
} }
......
...@@ -45,6 +45,15 @@ const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57 ...@@ -45,6 +45,15 @@ const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099, 1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000 16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000
}; };
// extended bsr table--currently not used
const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,
181,223,274,337,414,509,625,769,945,1162,1429,
1757,2161,2657,3267,4017,4940,6074,7469,9185,
11294,13888,17077,20999,25822,31752,39045,48012,
59039,72598,89272,109774,134986,165989,204111,
250990,308634,379519,466683,573866,705666,867737,
1067031,1312097,1613447,1984009,2439678,3000000,
6000000};
//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181}; //uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
......
...@@ -341,6 +341,7 @@ rlc_am_get_pdus ( ...@@ -341,6 +341,7 @@ rlc_am_get_pdus (
if (pdu) { if (pdu) {
list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer); list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer);
rlc_pP->status_requested = 0; rlc_pP->status_requested = 0;
rlc_pP->status_buffer_occupancy = 0;
rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP); rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP);
return; return;
} }
......
...@@ -122,6 +122,8 @@ char smbv_ip[16]; ...@@ -122,6 +122,8 @@ char smbv_ip[16];
//#define K 2 /* averaging coefficient */ //#define K 2 /* averaging coefficient */
//#define TARGET_SF_TIME_NS 1000000 /* 1ms = 1000000 ns */ //#define TARGET_SF_TIME_NS 1000000 /* 1ms = 1000000 ns */
uint8_t usim_test = 0;
frame_t frame = 0; frame_t frame = 0;
char stats_buffer[16384]; char stats_buffer[16384];
channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs]; channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
......
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