Commit de801af6 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/nr_ue_mac_pdu_fixes_sr_bsr' into integration_2021_wk44

parents 604e6e06 f0c98e2b
......@@ -254,7 +254,6 @@ MACRLCs = (
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 150;
ulsch_max_slots_inactivity=20;
}
);
......
......@@ -251,7 +251,6 @@ MACRLCs = (
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 150;
ulsch_max_slots_inactivity=20;
}
);
......
......@@ -228,7 +228,6 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_slots_inactivity = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
}
......
......@@ -232,7 +232,6 @@ MACRLCs = (
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 150;
ulsch_max_slots_inactivity = 10;
}
);
......
......@@ -211,7 +211,6 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_slots_inactivity = 1;
}
);
......
......@@ -55,7 +55,7 @@
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity"
#define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity"
#define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10"
#define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10"
#define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres"
......@@ -83,7 +83,7 @@
{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
......@@ -106,7 +106,7 @@
#define MACRLC_REMOTE_S_PORTC_IDX 14
#define MACRLC_LOCAL_S_PORTD_IDX 15
#define MACRLC_REMOTE_S_PORTD_IDX 16
#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17
#define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17
#define MACRLC_PUSCHTARGETSNRX10_IDX 18
#define MACRLC_PUCCHTARGETSNRX10_IDX 19
#define MACRLC_PUCCHFAILURETHRES_IDX 20
......
......@@ -754,7 +754,7 @@ void RCconfig_nr_macrlc() {
}else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
}
RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr);
RC.nrmac[j]->num_ulprbbl = num_prbbl;
LOG_I(NR_MAC,"Blacklisted PRBS %d\n",num_prbbl);
memcpy(RC.nrmac[j]->ulprbbl,prbbl,275*sizeof(prbbl[0]));
......
......@@ -40,6 +40,9 @@
#include "NR_SubcarrierSpacing.h"
#define NR_SHORT_BSR_TABLE_SIZE 32
#define NR_LONG_BSR_TABLE_SIZE 256
#define TABLE_38213_13_1_NUM_INDEXES 15
#define TABLE_38213_13_2_NUM_INDEXES 14
#define TABLE_38213_13_3_NUM_INDEXES 9
......@@ -65,6 +68,11 @@ typedef enum frequency_range_e {
FR2
} frequency_range_t;
#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */
#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
......
......@@ -48,6 +48,33 @@ void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
}
}
//38.321 Table 6.1.3.1-1
const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE] = {
0, 10, 14, 20, 28, 38, 53, 74,
102, 142, 198, 276, 384, 535, 745, 1038,
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
};
//38.321 Table 6.1.3.1-2
const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE] ={
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
};
// start symbols for SSB types A,B,C,D,E
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
......
......@@ -76,6 +76,9 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#endif*/
extern const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE];
extern const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE];
// Type0-PDCCH search space
extern const int32_t table_38213_13_1_c1[16];
extern const int32_t table_38213_13_1_c2[16];
......
......@@ -615,6 +615,18 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){
}
}
// todo handle mac_LogicalChannelConfig
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
module_id_t module_id,
int cc_idP,
uint8_t gNB_index,
long logicalChannelIdentity,
boolean_t status){
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
mac->logicalChannelBearer_exist[logicalChannelIdentity] = status;
return 0;
}
int nr_rrc_mac_config_req_ue(
module_id_t module_id,
int cc_idP,
......@@ -678,6 +690,17 @@ int nr_rrc_mac_config_req_ue(
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
mac->cg = cell_group_config;
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
mac->scheduling_info.periodicBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->scheduling_info.retxBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
module_id,
mac->scheduling_info.periodicBSR_SF,
mac->scheduling_info.retxBSR_SF);
config_control_ue(mac);
//config_common_ue(mac,module_id,cc_idP);
/*
......
......@@ -182,9 +182,9 @@ typedef struct {
uint16_t All_lcid_buffer_size_lastTTI;
/// buffer status for each lcid
uint8_t LCID_status[NR_MAX_NUM_LCID];
/// SR pending as defined in 36.321
/// SR pending as defined in 38.321
uint8_t SR_pending;
/// SR_COUNTER as defined in 36.321
/// SR_COUNTER as defined in 38.321
uint16_t SR_COUNTER;
/// logical channel group ide for each LCID
uint8_t LCGID[NR_MAX_NUM_LCID];
......@@ -328,15 +328,6 @@ typedef struct {
} RAR_grant_t;
typedef struct {
uint8_t phr_reporting;
uint16_t truncated_bsr;
uint16_t short_bsr;
uint16_t long_bsr;
} NR_UE_MAC_CE_t;
typedef struct {
int n_HARQ_ACK;
uint32_t ack_payload;
......@@ -353,6 +344,7 @@ typedef struct {
int8_t delta_pucch;
} PUCCH_sched_t;
/*!\brief Top level UE MAC structure */
typedef struct {
......@@ -419,8 +411,15 @@ typedef struct {
nr_ue_if_module_t *if_module;
nr_phy_config_t phy_config;
/// BSR report flag management
uint8_t BSR_reporting_active;
/// LogicalChannelConfig has bearer.
boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID];
NR_UE_SCHEDULING_INFO scheduling_info;
NR_UE_MAC_CE_t nr_ue_mac_ce;
/// PHR
uint8_t PHR_reporting_active;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
NR_SearchSpace_t *search_space_zero;
......
......@@ -40,6 +40,10 @@
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
/**\brief initialize the field in nr_mac instance
\param module_id module id */
void nr_ue_init_mac(module_id_t module_idP);
/**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message
\param module_id module id
\param cc_id component carrier id
......@@ -74,6 +78,20 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
uint8_t *pduP,
uint32_t pdu_len);
/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig
\param module_id module id
\param cc_id component carrier id
\param gNB_index gNB index
\param long logicalChannelIdentity
\param boolean_t status*/
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
module_id_t module_id,
int cc_idP,
uint8_t gNB_index,
long logicalChannelIdentity,
boolean_t status
);
/**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config)
\param module_id module id
\param cc_id component carrier id
......@@ -125,7 +143,53 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
int slot,
int thread_id);
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP);
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
\param[in] Mod_id Instance id of UE in machine
\param[in] frameP subframe number
\param[in] slotP slot number
*/
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index)
\brief get the rlc stats and update the bsr level for each lcid
\param[in] Mod_id instance of the UE
\param[in] frameP Frame index
\param[in] slot slotP number
\param[in] uint8_t gNB_index
*/
boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index);
/*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value)
\brief locate the BSR level in the table as defined in 38.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] size Size of the table
\param[in] value Value of the buffer
\return the index in the BSR_LEVEL table
*/
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
int value);
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
\param[in] periodicBSR_Timer timer for periodic BSR
\return the number of subframe
*/
int nr_get_sf_periodicBSRTimer(uint8_t bucketSize);
/*! \fn int nr_get_ms_bucketsizeduration(uint8_t bucketSize)
\brief get the time in ms form the bucket size duration configured by the higher layer
\param[in] bucketSize the bucket size duration
\return the time in ms
*/
int nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration);
/*! \fn int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer)
\brief get the number of subframe form the bucket size duration configured by the higher layer
\param[in] retxBSR_Timer timer for regular BSR
\return the time in sf
*/
int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer);
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
......@@ -170,7 +234,13 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
int pdu_id);
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac);
NR_UE_MAC_INST_t *mac,
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
uint16_t *crnti,
NR_BSR_SHORT *truncated_bsr,
NR_BSR_SHORT *short_bsr,
NR_BSR_LONG *long_bsr
);
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
......@@ -330,7 +400,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 38.321)
@param mod_id Index of UE instance
@param CC_id Component Carrier Index
@param frame
......
......@@ -52,8 +52,9 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
//init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
for (int j=0;j<NB_NR_UE_MAC_INST;j++)
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) nr_ue_mac_inst[j].first_ul_tx[i]=1;
for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
nr_ue_init_mac(j);
}
if (rrc_inst && rrc_inst->scell_group_config) {
......
......@@ -740,7 +740,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
} else {
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac);
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
pdu += size_sdu;
ra->Msg3_size = size_sdu;
......
......@@ -134,6 +134,55 @@ const initial_pucch_resource_t initial_pucch_resource[16] = {
};
void nr_ue_init_mac(module_id_t module_idP) {
int i;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
// default values as deined in 38.331 sec 9.2.2
LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP);
//mac->scheduling_info.macConfig=NULL;
mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240;
mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity;
// mac->scheduling_info.periodicPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
// mac->scheduling_info.prohibitPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
// mac->scheduling_info.PathlossChange_db = NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
// mac->PHR_state = NR_MAC_MainConfig__phr_Config_PR_setup;
mac->scheduling_info.SR_COUNTER = 0;
mac->scheduling_info.sr_ProhibitTimer = 0;
mac->scheduling_info.sr_ProhibitTimer_Running = 0;
// mac->scheduling_info.maxHARQ_Tx = NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
// mac->scheduling_info.ttiBundling = 0;
// mac->scheduling_info.extendedBSR_Sizes_r10 = 0;
// mac->scheduling_info.extendedPHR_r10 = 0;
// mac->scheduling_info.drx_config = NULL;
// mac->scheduling_info.phr_config = NULL;
// 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.
mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
// mac->scheduling_info.periodicPHR_SF = nr_get_sf_perioidicPHR_Timer(mac->scheduling_info.periodicPHR_Timer);
// mac->scheduling_info.prohibitPHR_SF = nr_get_sf_prohibitPHR_Timer(mac->scheduling_info.prohibitPHR_Timer);
// mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange);
// mac->PHR_reporting_active = 0;
for (i = 0; i < NR_MAX_NUM_LCID; i++) {
LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n",
module_idP, i);
mac->scheduling_info.Bj[i] = -1;
mac->scheduling_info.bucket_size[i] = -1;
if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0
mac->scheduling_info.LCGID[i] = 0;
} else { // initialize all the data channels lcgid to 1
mac->scheduling_info.LCGID[i] = 1;
}
mac->scheduling_info.LCID_status[i] = LCID_EMPTY;
mac->scheduling_info.LCID_buffer_remain[i] = 0;
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) mac->first_ul_tx[i]=1;
}
}
void get_bwp_info(NR_UE_MAC_INST_t *mac,
int dl_bwp_id,
int ul_bwp_id,
......@@ -2202,9 +2251,54 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
return false;
}
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){
return 0;
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){
// no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_NR_UE_MAC_INST, 0);
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
DSR_TRANSMAX_t dsr_TransMax = sr_n64; // todo
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
module_idP, frameP, slot,
mac->scheduling_info.SR_COUNTER,
(1 << (2 + dsr_TransMax)),
mac->scheduling_info.SR_pending); // todo
if ((mac->scheduling_info.SR_pending == 1) &&
(mac->scheduling_info.SR_COUNTER < (1 << (2 + dsr_TransMax)))) {
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n",
module_idP, frameP, slot,
mac->scheduling_info.SR_COUNTER,
(1 << (2 + dsr_TransMax)),
mac->scheduling_info.SR_pending); // todo
mac->scheduling_info.SR_COUNTER++;
// start the sr-prohibittimer : rel 9 and above
if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured
mac->scheduling_info.sr_ProhibitTimer--;
mac->scheduling_info.
sr_ProhibitTimer_Running = 1;
} else {
mac->scheduling_info.
sr_ProhibitTimer_Running = 0;
}
//mac->ul_active =1;
return (1); //instruct phy to signal SR
} else {
// notify RRC to relase PUCCH/SRS
// clear any configured dl/ul
// initiate RA
if (mac->scheduling_info.SR_pending) {
// release all pucch resource
//mac->physicalConfigDedicated = NULL; // todo
//mac->ul_active = 0; // todo
mac->BSR_reporting_active =
NR_BSR_TRIGGER_NONE;
LOG_I(NR_MAC, "[UE %d] Release all SRs \n", module_idP);
}
mac->scheduling_info.SR_pending = 0;
mac->scheduling_info.SR_COUNTER = 0;
return (0);
}
}
......@@ -3466,13 +3560,17 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
* Return: number of written bytes
*/
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac) {
NR_UE_MAC_INST_t *mac,
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
uint16_t *crnti,
NR_BSR_SHORT *truncated_bsr,
NR_BSR_SHORT *short_bsr,
NR_BSR_LONG *long_bsr) {
int mac_ce_len = 0;
uint8_t mac_ce_size = 0;
NR_UE_MAC_CE_t *nr_ue_mac_ce = &mac->nr_ue_mac_ce;
if (nr_ue_mac_ce->phr_reporting && mac->phr_Config != NULL) {
uint8_t *pdu = mac_ce;
if (power_headroom) {
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
......@@ -3480,21 +3578,22 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
mac_ce++;
// PHR MAC CE (1 octet)
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0;
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
// update pointer and length
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n",
pdu, mac_ce);
}
if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED) {
if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) {
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti);
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti));
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
......@@ -3502,7 +3601,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
mac_ce++;
// C-RNTI MAC CE (2 octets)
*(uint16_t *) mac_ce = mac->crnti;
*(uint16_t *) mac_ce = (*crnti);
// update pointer and length
mac_ce_size = sizeof(uint16_t);
......@@ -3511,9 +3610,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
}
if (nr_ue_mac_ce->truncated_bsr) {
LOG_D(NR_MAC, "In %s: generating short truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr);
if (truncated_bsr) {
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
......@@ -3521,17 +3618,17 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
mac_ce++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = 0;
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0;
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size;
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;;
// update pointer and length
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce);
} else if (nr_ue_mac_ce->short_bsr) {
LOG_D(NR_MAC, "In %s: generating short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr);
} else if (short_bsr) {
// MAC CE fixed subheader
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
......@@ -3539,27 +3636,84 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
mac_ce++;
// Short truncated BSR MAC CE (1 octet)
((NR_BSR_SHORT *) mac_ce)->Buffer_size = nr_ue_mac_ce->short_bsr;
((NR_BSR_SHORT *) mac_ce)->LcgID = 0;
((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size;
((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID;
// update pointer and length
mac_ce_size = sizeof(NR_BSR_SHORT);
mac_ce += mac_ce_size;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce);
} else if (long_bsr) {
} else if (nr_ue_mac_ce->long_bsr) {
// MAC CE variable subheader
// todo ch 6.1.3.1. TS 38.321
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
// sh_size = 2;
// Short truncated BSR MAC CE (1 octet)
// ((NR_BSR_LONG *) mac_ce)->Buffer_size0 = short_bsr;
// ((NR_BSR_LONG *) mac_ce)->LCGID0 = 0;
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
// ch 6.1.3.1. TS 38.321
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0;
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR;
NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce;
mac_ce += 2;
// Could move to nr_get_sdu()
uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1;
//int NR_BSR_LONG_SIZE = 1;
if (long_bsr->Buffer_size0 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID0 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID0 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size0;
}
if (long_bsr->Buffer_size1 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID1 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID1 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size1;
}
if (long_bsr->Buffer_size2 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID2 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID2 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size2;
}
if (long_bsr->Buffer_size3 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID3 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID3 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size3;
}
if (long_bsr->Buffer_size4 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID4 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID4 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size4;
}
if (long_bsr->Buffer_size5 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID5 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID5 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size5;
}
if (long_bsr->Buffer_size6 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID6 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID6 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size6;
}
if (long_bsr->Buffer_size7 == 0) {
((NR_BSR_LONG *) mac_ce)->LcgID7 = 0;
} else {
((NR_BSR_LONG *) mac_ce)->LcgID7 = 1;
*Buffer_size_ptr++ = long_bsr->Buffer_size7;
}
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce),
((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3,
((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7);
// update pointer and length
mac_ce = Buffer_size_ptr;
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT);
}
return mac_ce_len;
......
......@@ -53,6 +53,8 @@
#include <executables/softmodem-common.h>
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
static prach_association_pattern_t prach_assoc_pattern;
static ssb_list_info_t ssb_list;
......@@ -1004,10 +1006,324 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
}
}
if (dl_info) {
return (CONNECTION_OK);
}
module_id_t mod_id = ul_info->module_id;
frame_t txFrameP = ul_info->frame_tx;
slot_t txSlotP = ul_info->slot_tx;
// Handle the SR/BSR procedures per subframe
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint8_t gNB_indexP=0;
// Call BSR procedure as described in Section 5.4.5 in 38.321
// First check ReTxBSR Timer because it is always configured
// Decrement ReTxBSR Timer if it is running and not null
if ((mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) {
mac->scheduling_info.retxBSR_SF--;
}
// Decrement Periodic Timer if it is running and not null
if ((mac->scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) {
mac->scheduling_info.periodicBSR_SF--;
}
//Check whether Regular BSR is triggered
if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_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 38.321
mac->scheduling_info.SR_pending = 1;
// Regular BSR trigger
mac->BSR_reporting_active |= NR_BSR_TRIGGER_REGULAR;
LOG_D(NR_MAC, "[UE %d][BSR] Regular BSR Triggered Frame %d slot %d SR for PUSCH is pending\n",
mod_id, txFrameP, txSlotP);
}
return UE_CONNECTION_OK;
}
boolean_t
nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) {
mac_rlc_status_resp_t rlc_status;
boolean_t bsr_regular_triggered = FALSE;
uint8_t lcid;
uint8_t lcgid;
uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0};
int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID];
/* Array for ordering LCID with data per decreasing priority order */
uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]=
{NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
};
uint8_t pos_next = 0;
//uint8_t highest_priority = 16;
uint8_t array_index = 0;
// Reset All BSR Infos
lcid_bytes_in_buffer[0] = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
// Reset transmission status
lcid_bytes_in_buffer[lcid] = 0;
mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY;
}
for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
// Reset Buffer Info
mac->scheduling_info.BSR[lcgid]=0;
mac->scheduling_info.BSR_bytes[lcgid]=0;
}
//Get Buffer Occupancy and fill lcid_reordered_array
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
//if (mac->logicalChannelConfig[lcid]) {
if (mac->logicalChannelBearer_exist[lcid] ) { // todo
lcgid = mac->scheduling_info.LCGID[lcid];
// Store already available data to transmit per Group
if (lcgid < NR_MAX_NUM_LCGID) {
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid];
}
rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
if (lcgid < NR_MAX_NUM_LCGID) {
num_lcid_with_data ++;
// sum lcid buffer which has same lcgid
mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
//Fill in the array
array_index = 0;
do {
//if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) {
if (1) { // todo
//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 < NR_MAX_NUM_LCID));
}
}
}
}
// Check whether a regular BSR can be triggered according to the first cases in 38.321
if (num_lcid_with_data) {
LOG_D(NR_MAC, "[UE %d] PDCCH Tick at frame %d slot %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n",
module_idP, frameP, slotP, 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
*/
{
bsr_regular_triggered = TRUE;
LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
module_idP, lcid,
mac->scheduling_info.LCGID[lcid],
frameP, slotP);
break;
}
}
// Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission
if (mac->scheduling_info.retxBSR_SF == 0) {
bsr_regular_triggered = TRUE;
if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) {
LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n",
module_idP, frameP, slotP);
}
}
}
//Store Buffer Occupancy in remain buffers for next TTI
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid];
}
return bsr_regular_triggered;
}
uint8_t
nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) {
uint8_t ju, jm, jl;
int ascend;
//DevAssert(size > 0);
//DevAssert(size <= 256);
if (value == 0) {
return 0; //elseif (value > 150000) return 63;
}
jl = 0; // lower bound
ju = size - 1; // upper bound
ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise
while (ju - jl > 1) { //If we are not yet done,
jm = (ju + jl) >> 1; //compute a midpoint,
if ((value >= table[jm]) == ascend) {
jl = jm; // replace the lower limit
} else {
ju = jm; //replace the upper limit
}
LOG_T(NR_MAC, "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n",
jm, table[jm], value);
}
if (value == table[jl]) {
return jl;
} else {
return jl + 1; //equally ju
}
}
int nr_get_sf_periodicBSRTimer(uint8_t sf_offset) {
switch (sf_offset) {
case NR_BSR_Config__periodicBSR_Timer_sf1:
return 1;
break;
case NR_BSR_Config__periodicBSR_Timer_sf5:
return 5;
break;
case NR_BSR_Config__periodicBSR_Timer_sf10:
return 10;
break;
case NR_BSR_Config__periodicBSR_Timer_sf16:
return 16;
break;
case NR_BSR_Config__periodicBSR_Timer_sf20:
return 20;
break;
case NR_BSR_Config__periodicBSR_Timer_sf32:
return 32;
break;
case NR_BSR_Config__periodicBSR_Timer_sf40:
return 40;
break;
case NR_BSR_Config__periodicBSR_Timer_sf64:
return 64;
break;
case NR_BSR_Config__periodicBSR_Timer_sf80:
return 80;
break;
case NR_BSR_Config__periodicBSR_Timer_sf128:
return 128;
break;
case NR_BSR_Config__periodicBSR_Timer_sf160:
return 160;
break;
case NR_BSR_Config__periodicBSR_Timer_sf320:
return 320;
break;
case NR_BSR_Config__periodicBSR_Timer_sf640:
return 640;
break;
case NR_BSR_Config__periodicBSR_Timer_sf1280:
return 1280;
break;
case NR_BSR_Config__periodicBSR_Timer_sf2560:
return 2560;
break;
case NR_BSR_Config__periodicBSR_Timer_infinity:
default:
return 0xFFFF;
break;
}
}
int nr_get_sf_retxBSRTimer(uint8_t sf_offset) {
switch (sf_offset) {
case NR_BSR_Config__retxBSR_Timer_sf10:
return 10;
break;
case NR_BSR_Config__retxBSR_Timer_sf20:
return 20;
break;
case NR_BSR_Config__retxBSR_Timer_sf40:
return 40;
break;
case NR_BSR_Config__retxBSR_Timer_sf80:
return 80;
break;
case NR_BSR_Config__retxBSR_Timer_sf160:
return 160;
break;
case NR_BSR_Config__retxBSR_Timer_sf320:
return 320;
break;
case NR_BSR_Config__retxBSR_Timer_sf640:
return 640;
break;
case NR_BSR_Config__retxBSR_Timer_sf1280:
return 1280;
break;
case NR_BSR_Config__retxBSR_Timer_sf2560:
return 2560;
break;
case NR_BSR_Config__retxBSR_Timer_sf5120:
return 5120;
break;
case NR_BSR_Config__retxBSR_Timer_sf10240:
return 10240;
break;
default:
return -1;
break;
}
}
// PUSCH scheduler:
// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
// - where K2 is the offset between the slot in which UL DCI is received and the slot
......@@ -2041,6 +2357,261 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
#define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID
typedef struct {
uint8_t bsr_len;
uint8_t bsr_ce_len;
uint8_t bsr_header_len;
uint8_t phr_len;
uint8_t phr_ce_len;
uint8_t phr_header_len;
uint16_t sdu_length_total;
NR_BSR_SHORT *bsr_s;
NR_BSR_LONG *bsr_l;
NR_BSR_SHORT *bsr_t;
//NR_POWER_HEADROOM_CMD *phr_pr;
int tot_mac_ce_len;
uint8_t total_mac_pdu_header_len;
} NR_UE_MAC_CE_INFO;
/*
nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field
Need nothing from mac_ce_p:
Update the following in mac_ce_p:
bsr_len;
bsr_ce_len;
bsr_header_len;
phr_len; TBD
phr_ce_len; TBD
phr_header_len; TBD
*/
int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint16_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
int num_lcg_id_with_data = 0;
// Preparing the MAC CEs sub-PDUs and get the total size
mac_ce_p->bsr_header_len = 0;
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
int lcg_id = 0;
while (lcg_id < NR_MAX_NUM_LCGID) {
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
num_lcg_id_with_data++;
}
lcg_id++;
}
//Restart ReTxBSR Timer at new grant indication (38.321)
if (mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) {
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
}
// periodicBSR-Timer expires, trigger BSR
if ((mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)
&& (mac->scheduling_info.periodicBSR_SF == 0)) {
// Trigger BSR Periodic
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PERIODIC;
LOG_D(NR_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 (mac->BSR_reporting_active) {
AssertFatal((mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING) == 0,
"Inconsistent BSR Trigger=%d !\n",
mac->BSR_reporting_active);
//A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit
if (num_lcg_id_with_data <= 1) {
if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) {
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
}
} else {
if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) {
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
}
}
}
mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len;
return (mac_ce_p->bsr_len + mac_ce_p->phr_len);
}
/*
nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field
Need the following from mac_ce_p:
bsr_ce_len
bsr_len
sdu_length_total
total_mac_pdu_header_len
Update the following in mac_ce_p:
bsr_ce_len
bsr_header_len
bsr_len
tot_mac_ce_len
total_mac_pdu_header_len
bsr_s
bsr_l
bsr_t
*/
void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t subframe,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint16_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
// Compute BSR Values and update Nb LCGID with data after multiplexing
unsigned short padding_len = 0;
uint8_t lcid = 0;
int lcg_id = 0;
int num_lcg_id_with_data = 0;
int lcg_id_bsr_trunc = 0;
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
} else {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
}
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
num_lcg_id_with_data++;
lcg_id_bsr_trunc = lcg_id;
}
}
// TS 38.321 Section 5.4.5
// Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
/* For Padding BSR:
- 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:
- 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 (mac_ce_p->sdu_length_total) {
padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
}
if ((padding_len) && (mac_ce_p->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 >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT))) {
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
// Trigger BSR Padding
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
} else if (padding_len >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED))) {
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
if (num_lcg_id_with_data > 1) {
// REPORT SHORT TRUNCATED BSR
//Get LCGID of highest priority LCID with data (todo)
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
lcg_id = mac->scheduling_info.LCGID[lcid];
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
lcg_id_bsr_trunc = lcg_id;
}
}
} else {
//Report SHORT BSR, clear bsr_t
mac_ce_p->bsr_t = NULL;
}
// Trigger BSR Padding
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
}
mac_ce_p->bsr_len = mac_ce_p->bsr_header_len + mac_ce_p->bsr_ce_len;
mac_ce_p->tot_mac_ce_len += mac_ce_p->bsr_len;
mac_ce_p->total_mac_pdu_header_len += mac_ce_p->bsr_len;
}
//Fill BSR Infos
if (mac_ce_p->bsr_ce_len == 0) {
mac_ce_p->bsr_s = NULL;
mac_ce_p->bsr_l = NULL;
mac_ce_p->bsr_t = NULL;
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
mac_ce_p->bsr_s = NULL;
mac_ce_p->bsr_t = NULL;
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0];
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1];
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2];
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3];
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4];
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5];
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6];
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7];
LOG_D(NR_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 level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
module_idP, frameP, subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[0],
mac->scheduling_info.BSR[1],
mac->scheduling_info.BSR[2],
mac->scheduling_info.BSR[3],
mac->scheduling_info.BSR[4],
mac->scheduling_info.BSR[5],
mac->scheduling_info.BSR[6],
mac->scheduling_info.BSR[7]);
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
mac_ce_p->bsr_l = NULL;
if ((mac_ce_p->bsr_t != NULL) && (mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING)) {
//Truncated BSR
mac_ce_p->bsr_s = NULL;
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
} else {
mac_ce_p->bsr_t = NULL;
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
}
}
LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP);
mac->scheduling_info.SR_pending = 0;
mac->scheduling_info.SR_COUNTER = 0;
/* Actions when a BSR is sent */
if (mac_ce_p->bsr_ce_len) {
LOG_D(NR_MAC, "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
module_idP, mac_ce_p->bsr_ce_len, mac_ce_p->bsr_header_len, buflen);
// Reset ReTx BSR Timer
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF);
// Reset Periodic Timer except when BSR is truncated
if ((mac_ce_p->bsr_t == NULL) && (mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) {
mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info.periodicBSR_Timer);
LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n",
module_idP,
mac->scheduling_info.periodicBSR_SF);
}
// Reset BSR Trigger flags
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
}
}
/**
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
......@@ -2061,31 +2632,45 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint16_t buflen) {
NR_UE_MAC_CE_INFO mac_ce_info;
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
int16_t buflen_remain = 0;
mac_ce_p->bsr_len = 0;
mac_ce_p->bsr_ce_len = 0;
mac_ce_p->bsr_header_len = 0;
mac_ce_p->phr_len = 0;
//mac_ce_p->phr_ce_len = 0;
//mac_ce_p->phr_header_len = 0;
uint8_t lcid = 0;
uint16_t sdu_length = 0;
uint16_t num_sdus = 0;
uint16_t sdu_length_total = 0;
mac_ce_p->sdu_length_total = 0;
NR_BSR_SHORT bsr_short, bsr_truncated;
NR_BSR_LONG bsr_long;
mac_ce_p->bsr_s = &bsr_short;
mac_ce_p->bsr_l = &bsr_long;
mac_ce_p->bsr_t = &bsr_truncated;
//NR_POWER_HEADROOM_CMD phr;
//mac_ce_p->phr_p = &phr;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
//int highest_priority = 16;
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
uint8_t *pdu = ulsch_buffer;
// Preparing the MAC CEs sub-PDUs and get the total size
unsigned char mac_header_control_elements[16] = {0};
int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], mac);
uint8_t total_mac_pdu_header_len = tot_mac_ce_len;
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
// Check for DCCH first
// TO DO: Multiplex in the order defined by the logical channel prioritization
for (lcid = UL_SCH_LCID_SRB1;
lcid < MAX_LCID; lcid++) {
for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) {
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n",
__FUNCTION__,
......@@ -2094,8 +2679,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
subframe,
lcid,
buflen,
sdu_length_total,
tot_mac_ce_len,
mac_ce_p->sdu_length_total,
mac_ce_p->tot_mac_ce_len,
buflen_remain);
while (buflen_remain > 0){
......@@ -2125,7 +2710,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
if (sdu_length > 0) {
LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
num_sdus + 1,
sdu_length,
lcid,
......@@ -2145,40 +2730,53 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
#endif
pdu += sdu_length;
sdu_length_total += sdu_length;
total_mac_pdu_header_len += sh_size;
mac_ce_p->sdu_length_total += sdu_length;
mac_ce_p->total_mac_pdu_header_len += sh_size;
num_sdus++;
} else {
pdu -= sh_size;
LOG_D(MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
break;
}
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
//Update Buffer remain and BSR bytes after transmission
mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length;
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length;
LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid],
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]);
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0)
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0;
}
}
if (tot_mac_ce_len > 0) {
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
nr_ue_get_sdu_mac_ce_post(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
if (mac_ce_p->tot_mac_ce_len > 0) {
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len);
memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len);
pdu += (unsigned char) tot_mac_ce_len;
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l);
pdu += (unsigned char) mac_ce_p->tot_mac_ce_len;
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len);
log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
#endif
}
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total);
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
// Compute final offset for padding and fill remainder of ULSCH with 0
if (buflen_remain > 0) {
LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
......
......@@ -34,34 +34,7 @@
#include "common/utils/nr/nr_common.h"
#include <openair2/UTIL/OPT/opt.h>
//38.321 Table 6.1.3.1-1
const uint32_t NR_SHORT_BSR_TABLE[32] = {
0, 10, 14, 20, 28, 38, 53, 74,
102, 142, 198, 276, 384, 535, 745, 1038,
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
};
//38.321 Table 6.1.3.1-2
const uint32_t NR_LONG_BSR_TABLE[256] ={
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
};
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
......@@ -896,7 +869,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
* (2) there is a scheduling request
* (3) or we did not schedule it in more than 10 frames */
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
const bool high_inactivity = diff >= nrmac->ulsch_max_frame_inactivity * n;
LOG_D(NR_MAC,
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
frame,
......
......@@ -750,7 +750,7 @@ typedef struct gNB_MAC_INST_s {
int *preferred_ul_tda[MAX_NUM_BWP];
/// maximum number of slots before a UE will be scheduled ULSCH automatically
uint32_t ulsch_max_slots_inactivity;
uint32_t ulsch_max_frame_inactivity;
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
......
......@@ -270,7 +270,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
+ buf_stat.retx_size
+ buf_stat.tx_size;
} else {
if (!(frameP%128)) //to supress this warning message
if (!(frameP%128)) //to suppress this warning message
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
ret.bytes_in_buffer = 0;
}
......@@ -334,6 +334,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
+ buf_stat.retx_size
+ buf_stat.tx_size;
} else {
if (!(frameP%128)) //to suppress this warning message
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
ret = 0;
}
......
......@@ -1184,7 +1184,7 @@ void fill_initial_SpCellConfig(rnti_t rnti,
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8+(10*((rnti>>1)&3)) + (rnti&1);
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1);
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
*schedulingRequestResourceConfig->resource = 0;
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
......
......@@ -2100,6 +2100,7 @@ nr_rrc_ue_establish_srb2(
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig
// rrc_mac_config_req_ue
}
} else {
......@@ -2115,6 +2116,7 @@ nr_rrc_ue_establish_srb2(
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig
// rrc_mac_config_req_ue
}
} // srb2
......@@ -2135,8 +2137,23 @@ nr_rrc_ue_establish_srb2(
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
} else {
LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
//LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
int j;
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList;
if (rlc_bearer2add_list != NULL) {
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig
}
}
}
}
}
}
}
......@@ -2199,6 +2216,15 @@ nr_rrc_ue_establish_srb2(
}
}
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) {
for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) {
NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i];
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id);
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig
}
}
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
}
......
......@@ -230,7 +230,6 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_slots_inactivity = 10;
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
......
......@@ -230,7 +230,6 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
ulsch_max_slots_inactivity = 10;
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
}
......
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