Commit 2ba79f3f authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/NR_UE_MAC_SR_improvements' into integration_2024_w15

parents 87242ca9 2f9fe364
...@@ -755,6 +755,7 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, ...@@ -755,6 +755,7 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
AssertFatal(mac_lc_config->ul_SpecificParameters, "UL parameters shouldn't be NULL for DRBs\n"); AssertFatal(mac_lc_config->ul_SpecificParameters, "UL parameters shouldn't be NULL for DRBs\n");
struct NR_LogicalChannelConfig__ul_SpecificParameters *ul_parm = mac_lc_config->ul_SpecificParameters; struct NR_LogicalChannelConfig__ul_SpecificParameters *ul_parm = mac_lc_config->ul_SpecificParameters;
lc_info->priority = ul_parm->priority; lc_info->priority = ul_parm->priority;
lc_info->sr_id = ul_parm->schedulingRequestID ? *ul_parm->schedulingRequestID : -1;
lc_info->sr_DelayTimerApplied = ul_parm->logicalChannelSR_DelayTimerApplied; lc_info->sr_DelayTimerApplied = ul_parm->logicalChannelSR_DelayTimerApplied;
lc_info->lc_SRMask = ul_parm->logicalChannelSR_Mask; lc_info->lc_SRMask = ul_parm->logicalChannelSR_Mask;
lc_info->pbr = nr_get_pbr(ul_parm->prioritisedBitRate); lc_info->pbr = nr_get_pbr(ul_parm->prioritisedBitRate);
...@@ -1691,37 +1692,35 @@ static uint32_t nr_get_sf_periodicBSRTimer(long periodicBSR) ...@@ -1691,37 +1692,35 @@ static uint32_t nr_get_sf_periodicBSRTimer(long periodicBSR)
static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_t *mcg) static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_t *mcg)
{ {
NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info; NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info;
int scs = mac->current_UL_BWP->scs;
if (mcg->drx_Config) if (mcg->drx_Config)
LOG_E(NR_MAC, "DRX not implemented! Configuration not handled!\n"); LOG_E(NR_MAC, "DRX not implemented! Configuration not handled!\n");
if (mcg->schedulingRequestConfig) { if (mcg->schedulingRequestConfig) {
const NR_SchedulingRequestConfig_t *src = mcg->schedulingRequestConfig; const NR_SchedulingRequestConfig_t *src = mcg->schedulingRequestConfig;
if (src->schedulingRequestToReleaseList) { if (src->schedulingRequestToReleaseList) {
for (int i = 0; i < src->schedulingRequestToReleaseList->list.count; i++) { for (int i = 0; i < src->schedulingRequestToReleaseList->list.count; i++) {
if (*src->schedulingRequestToReleaseList->list.array[i] == si->sr_id) { NR_SchedulingRequestId_t id = *src->schedulingRequestToReleaseList->list.array[i];
si->SR_COUNTER = 0; memset(&si->sr_info[id], 0, sizeof(si->sr_info[id]));
si->sr_ProhibitTimer = 0;
si->sr_ProhibitTimer_Running = 0;
si->sr_id = -1; // invalid init value
}
else
LOG_E(NR_MAC, "Cannot release SchedulingRequestConfig. Not configured.\n");
} }
} }
if (src->schedulingRequestToAddModList) { if (src->schedulingRequestToAddModList) {
for (int i = 0; i < src->schedulingRequestToAddModList->list.count; i++) { for (int i = 0; i < src->schedulingRequestToAddModList->list.count; i++) {
NR_SchedulingRequestToAddMod_t *sr = src->schedulingRequestToAddModList->list.array[i]; NR_SchedulingRequestToAddMod_t *sr = src->schedulingRequestToAddModList->list.array[i];
AssertFatal(si->sr_id == -1 || nr_sr_info_t *sr_info = &si->sr_info[sr->schedulingRequestId];
si->sr_id == sr->schedulingRequestId, sr_info->active_SR_ID = true;
"Current implementation cannot handle more than 1 SR configuration\n"); // NR_SchedulingRequestToAddMod__sr_TransMax_n4 = 0 and so on
si->sr_id = sr->schedulingRequestId; // to obtain the value to configure we need to right shift 4 by the RRC parameter
si->sr_TransMax = sr->sr_TransMax; sr_info->maxTransmissions = 4 << sr->sr_TransMax;
int target_ms = 0;
if (sr->sr_ProhibitTimer) if (sr->sr_ProhibitTimer)
LOG_E(NR_MAC, "SR prohibit timer not properly implemented\n"); target_ms = 1 << *sr->sr_ProhibitTimer;
// length of slot is (1/2^scs)ms
nr_timer_setup(&sr_info->prohibitTimer, target_ms << scs, 1); // 1 slot update rate
} }
} }
} }
if (mcg->bsr_Config) { if (mcg->bsr_Config) {
int subframes_per_slot = nr_slots_per_frame[mac->current_UL_BWP->scs] / 10; int subframes_per_slot = nr_slots_per_frame[scs] / 10;
uint32_t periodic_sf = nr_get_sf_periodicBSRTimer(mcg->bsr_Config->periodicBSR_Timer); uint32_t periodic_sf = nr_get_sf_periodicBSRTimer(mcg->bsr_Config->periodicBSR_Timer);
uint32_t target = periodic_sf < UINT_MAX ? periodic_sf * subframes_per_slot : periodic_sf; uint32_t target = periodic_sf < UINT_MAX ? periodic_sf * subframes_per_slot : periodic_sf;
nr_timer_setup(&si->periodicBSR_Timer, target, 1); // 1 slot update rate nr_timer_setup(&si->periodicBSR_Timer, target, 1); // 1 slot update rate
......
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#define MAX_NUM_BWP_UE 5 #define MAX_NUM_BWP_UE 5
#define NUM_SLOT_FRAME 10 #define NUM_SLOT_FRAME 10
#define NR_MAX_SR_ID 8 // SchedulingRequestId ::= INTEGER (0..7)
/*!\brief value for indicating BSR Timer is not running */ /*!\brief value for indicating BSR Timer is not running */
#define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) #define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
...@@ -202,33 +203,36 @@ typedef struct { ...@@ -202,33 +203,36 @@ typedef struct {
int32_t BSR_bytes; int32_t BSR_bytes;
} NR_LCG_SCHEDULING_INFO; } NR_LCG_SCHEDULING_INFO;
typedef struct {
bool active_SR_ID;
/// SR pending as defined in 38.321
bool pending;
/// SR_COUNTER as defined in 38.321
uint32_t counter;
/// sr ProhibitTimer
NR_timer_t prohibitTimer;
// Maximum number of SR transmissions
uint32_t maxTransmissions;
} nr_sr_info_t;
// LTE structure, might need to be adapted for NR // LTE structure, might need to be adapted for NR
typedef struct { typedef struct {
// lcs scheduling info // lcs scheduling info
NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID]; NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID];
// lcg scheduling info // lcg scheduling info
NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID]; NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID];
// SR INFO
nr_sr_info_t sr_info[NR_MAX_SR_ID];
/// BSR report flag management /// BSR report flag management
uint8_t BSR_reporting_active; uint8_t BSR_reporting_active;
// LCID triggering BSR // LCID triggering BSR
NR_LogicalChannelIdentity_t regularBSR_trigger_lcid; NR_LogicalChannelIdentity_t regularBSR_trigger_lcid;
/// SR pending as defined in 38.321
uint8_t SR_pending;
/// SR_COUNTER as defined in 38.321
uint16_t SR_COUNTER;
// logicalChannelSR-DelayTimer // logicalChannelSR-DelayTimer
NR_timer_t sr_DelayTimer; NR_timer_t sr_DelayTimer;
/// retxBSR-Timer /// retxBSR-Timer
NR_timer_t retxBSR_Timer; NR_timer_t retxBSR_Timer;
/// periodicBSR-Timer /// periodicBSR-Timer
NR_timer_t periodicBSR_Timer; NR_timer_t periodicBSR_Timer;
/// default value is 0: not configured
uint16_t sr_ProhibitTimer;
/// sr ProhibitTime running
uint8_t sr_ProhibitTimer_Running;
// Maximum number of SR transmissions
uint32_t sr_TransMax;
int sr_id;
///timer before triggering a periodic PHR ///timer before triggering a periodic PHR
uint16_t periodicPHR_Timer; uint16_t periodicPHR_Timer;
///timer before triggering a prohibit PHR ///timer before triggering a prohibit PHR
...@@ -446,6 +450,7 @@ typedef struct ssb_list_info { ...@@ -446,6 +450,7 @@ typedef struct ssb_list_info {
typedef struct nr_lcordered_info_s { typedef struct nr_lcordered_info_s {
// logical channels ids ordered as per priority // logical channels ids ordered as per priority
NR_LogicalChannelIdentity_t lcid; NR_LogicalChannelIdentity_t lcid;
int sr_id;
long priority; long priority;
uint32_t pbr; // in B/s (UINT_MAX = infinite) uint32_t pbr; // in B/s (UINT_MAX = infinite)
// Bucket size per lcid // Bucket size per lcid
......
...@@ -111,14 +111,11 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, ...@@ -111,14 +111,11 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac,
void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info); void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info);
void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info); void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info);
/*! \fn int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP); /*! \fn int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id);
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and \brief This function schedules a positive or negative SR for schedulingRequestID sr_id
DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and depending on the presence of any active SR and the prohibit timer.
DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 If the max number of retransmissions is reached, it triggers a new RA */
SDUs and generates header and forms the complete MAC SDU. \param[in] mac pointer to MAC instance \param[in] frameP int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id);
subframe number \param[in] slotP slot number
*/
int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP);
nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
......
...@@ -79,6 +79,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) ...@@ -79,6 +79,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
memset(mac->ssb_list, 0, sizeof(mac->ssb_list)); memset(mac->ssb_list, 0, sizeof(mac->ssb_list));
memset(mac->prach_assoc_pattern, 0, sizeof(mac->prach_assoc_pattern)); memset(mac->prach_assoc_pattern, 0, sizeof(mac->prach_assoc_pattern));
for (int i = 0; i < NR_MAX_SR_ID; i++)
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
} }
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
...@@ -166,6 +169,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) ...@@ -166,6 +169,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
nr_timer_stop(&nr_mac->ra.contention_resolution_timer); nr_timer_stop(&nr_mac->ra.contention_resolution_timer);
nr_timer_stop(&nr_mac->scheduling_info.sr_DelayTimer); nr_timer_stop(&nr_mac->scheduling_info.sr_DelayTimer);
nr_timer_stop(&nr_mac->scheduling_info.retxBSR_Timer); nr_timer_stop(&nr_mac->scheduling_info.retxBSR_Timer);
for (int i = 0; i < NR_MAX_SR_ID; i++)
nr_timer_stop(&nr_mac->scheduling_info.sr_info[i].prohibitTimer);
// consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2 // consider all timeAlignmentTimers as expired and perform the corresponding actions in clause 5.2
// TODO // TODO
...@@ -185,11 +190,10 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) ...@@ -185,11 +190,10 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
free_and_zero(nr_mac->ra.Msg3_buffer); free_and_zero(nr_mac->ra.Msg3_buffer);
// cancel any triggered Scheduling Request procedure // cancel any triggered Scheduling Request procedure
nr_mac->scheduling_info.SR_COUNTER = 0; for (int i = 0; i < NR_MAX_SR_ID; i++) {
nr_mac->scheduling_info.SR_pending = 0; nr_mac->scheduling_info.sr_info[i].pending = false;
nr_mac->scheduling_info.sr_ProhibitTimer = 0; nr_mac->scheduling_info.sr_info[i].counter = 0;
nr_mac->scheduling_info.sr_ProhibitTimer_Running = 0; }
nr_mac->scheduling_info.sr_id = -1; // invalid init value
// cancel any triggered Buffer Status Reporting procedure // cancel any triggered Buffer Status Reporting procedure
nr_mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE; nr_mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE;
......
...@@ -2436,80 +2436,80 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p ...@@ -2436,80 +2436,80 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
return false; // SR not configured return false; // SR not configured
int sr_count = 0; int sr_count = 0;
for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { for (int id = 0; id < pucch_Config->schedulingRequestResourceToAddModList->list.count; id++) {
NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; NR_SchedulingRequestResourceConfig_t *sr_Config = pucch_Config->schedulingRequestResourceToAddModList->list.array[id];
int SR_period; int SR_offset; int SR_period; int SR_offset;
find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); find_period_offset_SR(sr_Config, &SR_period, &SR_offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
int sfn_sf = frame * n_slots_frame + slot; int sfn_sf = frame * n_slots_frame + slot;
if ((sfn_sf - SR_offset) % SR_period == 0) { if ((sfn_sf - SR_offset) % SR_period == 0) {
LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot); LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot);
if (!SchedulingRequestResourceConfig->resource) { if (!sr_Config->resource) {
LOG_E(MAC, "No resource associated with SR. SR not scheduled\n"); LOG_E(MAC, "No resource associated with SR. SR not scheduled\n");
break; break;
} }
NR_PUCCH_Resource_t *sr_pucch = NR_PUCCH_Resource_t *sr_pucch =
find_pucch_resource_from_list(pucch_Config->resourceToAddModList, *SchedulingRequestResourceConfig->resource); find_pucch_resource_from_list(pucch_Config->resourceToAddModList, *sr_Config->resource);
AssertFatal(sr_pucch != NULL, "Couldn't find PUCCH Resource ID for SR in PUCCH resource list\n"); AssertFatal(sr_pucch != NULL, "Couldn't find PUCCH Resource ID for SR in PUCCH resource list\n");
pucch->pucch_resource = sr_pucch; pucch->pucch_resource = sr_pucch;
pucch->n_sr = 1; pucch->n_sr = 1;
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
pucch->sr_payload = nr_ue_get_SR(mac, frame, slot, sr_Config->schedulingRequestID);
sr_count++; sr_count++;
AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n");
} }
} }
AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n");
return sr_count > 0 ? true : false; return sr_count > 0 ? true : false;
} }
int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slot) int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id)
{ {
// no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info; NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info;
int max_sr_transmissions = (1 << (2 + si->sr_TransMax)); nr_sr_info_t *sr_info = &si->sr_info[sr_id];
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/sr_TransMax %d/%d), SR_pending %d\n", if (!sr_info->active_SR_ID) {
LOG_E(NR_MAC, "SR triggered for an inactive SR with ID %ld\n", sr_id);
return 0;
}
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d SR %s for ID %ld\n",
mac->ue_id, mac->ue_id,
frameP, frame,
slot, slot,
si->SR_COUNTER, sr_info->pending ? "pending" : "not pending",
max_sr_transmissions, sr_id); // todo
si->SR_pending); // todo
// TODO check if the PUCCH resource for the SR transmission occasion does not overlap with a UL-SCH resource
if (!sr_info->pending || is_nr_timer_active(sr_info->prohibitTimer))
return 0;
if ((si->SR_pending == 1) && if (sr_info->counter < sr_info->maxTransmissions) {
(si->SR_COUNTER < max_sr_transmissions)) { sr_info->counter++;
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/sr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n", // start the sr-prohibittimer
nr_timer_start(&sr_info->prohibitTimer);
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d instruct the physical layer to signal the SR (counter/sr_TransMax %d/%d)\n",
mac->ue_id, mac->ue_id,
frameP, frame,
slot, slot,
si->SR_COUNTER, sr_info->counter,
max_sr_transmissions, sr_info->maxTransmissions);
si->SR_pending); // todo return 1;
si->SR_COUNTER++;
// start the sr-prohibittimer : rel 9 and above
if (si->sr_ProhibitTimer > 0) { // timer configured
si->sr_ProhibitTimer--;
si->sr_ProhibitTimer_Running = 1;
} else {
si->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 (si->SR_pending) {
// release all pucch resource
//mac->physicalConfigDedicated = NULL; // todo
//mac->ul_active = 0; // todo
si->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
LOG_I(NR_MAC, "[UE %d] Release all SRs \n", mac->ue_id);
}
si->SR_pending = 0;
si->SR_COUNTER = 0;
return (0);
} }
// TODO
// notify RRC to release PUCCH for all Serving Cells;
// notify RRC to release SRS for all Serving Cells;
// clear any configured downlink assignments and uplink grants;
// clear any PUSCH resources for semi-persistent CSI reporting;
// initiate a Random Access procedure (see clause 5.1) on the SpCell and cancel all pending SRs.
LOG_E(NR_MAC, "[UE %d] SR not served. Triggering of new RA procedure not implemented yet.\n", mac->ue_id);
sr_info->pending = false;
sr_info->counter = 0;
nr_timer_stop(&sr_info->prohibitTimer);
return 0;
} }
// section 5.2.5 of 38.214 // section 5.2.5 of 38.214
......
...@@ -133,6 +133,8 @@ static void trigger_regular_bsr(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity ...@@ -133,6 +133,8 @@ static void trigger_regular_bsr(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity
void update_mac_timers(NR_UE_MAC_INST_t *mac) void update_mac_timers(NR_UE_MAC_INST_t *mac)
{ {
nr_timer_tick(&mac->ra.contention_resolution_timer); nr_timer_tick(&mac->ra.contention_resolution_timer);
for (int j = 0; j < NR_MAX_SR_ID; j++)
nr_timer_tick(&mac->scheduling_info.sr_info[j].prohibitTimer);
nr_timer_tick(&mac->scheduling_info.sr_DelayTimer); nr_timer_tick(&mac->scheduling_info.sr_DelayTimer);
bool retxBSR_expired = nr_timer_tick(&mac->scheduling_info.retxBSR_Timer); bool retxBSR_expired = nr_timer_tick(&mac->scheduling_info.retxBSR_Timer);
if (retxBSR_expired) { if (retxBSR_expired) {
...@@ -1107,9 +1109,31 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info ...@@ -1107,9 +1109,31 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info
LOG_E(NR_MAC, "Internal error, no scheduled_response function\n"); LOG_E(NR_MAC, "Internal error, no scheduled_response function\n");
} }
static void nr_trigger_sr(NR_UE_MAC_INST_t *mac) static void nr_update_sr(NR_UE_MAC_INST_t *mac)
{ {
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info; NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
// if no pending data available for transmission
// All pending SR(s) shall be cancelled and each respective sr-ProhibitTimer shall be stopped
bool data_avail = false;
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
if (sched_info->lc_sched_info[i].LCID_buffer_remain > 0) {
data_avail = true;
break;
}
}
if (!data_avail) {
for (int i = 0; i < NR_MAX_SR_ID; i++) {
nr_sr_info_t *sr = &sched_info->sr_info[i];
if (sr->active_SR_ID) {
LOG_D(NR_MAC, "No pending data available -> Canceling pending SRs\n");
sr->pending = false;
sr->counter = 0;
nr_timer_stop(&sr->prohibitTimer);
}
}
}
// if a Regular BSR has been triggered and logicalChannelSR-DelayTimer is not running // if a Regular BSR has been triggered and logicalChannelSR-DelayTimer is not running
if (((sched_info->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) if (((sched_info->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0)
|| is_nr_timer_active(sched_info->sr_DelayTimer)) || is_nr_timer_active(sched_info->sr_DelayTimer))
...@@ -1128,7 +1152,18 @@ static void nr_trigger_sr(NR_UE_MAC_INST_t *mac) ...@@ -1128,7 +1152,18 @@ static void nr_trigger_sr(NR_UE_MAC_INST_t *mac)
// TODO not implemented // TODO not implemented
// trigger SR // trigger SR
sched_info->SR_pending = 1; if (lc_info->sr_id < 0 || lc_info->sr_id >= NR_MAX_SR_ID)
LOG_E(NR_MAC, "No SR corresponding to this LCID\n"); // TODO not sure what to do here
else {
nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id];
if (!sr->pending) {
LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id);
sr->pending = true;
sr->counter = 0;
// TODO initiate a Random Access procedure on the SpCell and cancel the pending SR
// if the MAC entity has no valid PUCCH resource configured for the pending SR
}
}
} }
static void nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index) static void nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index)
...@@ -1287,7 +1322,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) ...@@ -1287,7 +1322,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
} }
if(mac->state == UE_CONNECTED) if(mac->state == UE_CONNECTED)
nr_trigger_sr(mac); nr_update_sr(mac);
// update Bj for all active lcids before LCP procedure // update Bj for all active lcids before LCP procedure
LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx); LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx);
...@@ -1946,8 +1981,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi ...@@ -1946,8 +1981,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi
// SR // SR
if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch[0], frameP, slotP)) { if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch[0], frameP, slotP)) {
num_res++; num_res++;
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */ // TODO check if the PUCCH resource for the SR transmission occasion overlap with a UL-SCH resource
pucch[0].sr_payload = nr_ue_get_SR(mac, frameP, slotP);
} }
// CSI // CSI
...@@ -2533,10 +2567,8 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, ...@@ -2533,10 +2567,8 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
bsr_t bsr_t
*/ */
static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
int CC_id,
frame_t frame, frame_t frame,
slot_t slot, slot_t slot,
uint8_t gNB_index,
uint8_t *ulsch_buffer, uint8_t *ulsch_buffer,
uint16_t buflen, uint16_t buflen,
NR_UE_MAC_CE_INFO *mac_ce_p) NR_UE_MAC_CE_INFO *mac_ce_p)
...@@ -2675,18 +2707,15 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, ...@@ -2675,18 +2707,15 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
} }
} }
LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", mac->ue_id);
sched_info->SR_pending = 0;
sched_info->SR_COUNTER = 0;
/* Actions when a BSR is sent */ /* Actions when a BSR is sent */
if (mac_ce_p->bsr_ce_len) { if (mac_ce_p->bsr_ce_len) {
LOG_D(NR_MAC, LOG_D(NR_MAC,
"[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", "[UE %d] MAC BSR Sent! ce %d, hdr %d buff_len %d triggering LCID %ld\n",
mac->ue_id, mac->ue_id,
mac_ce_p->bsr_ce_len, mac_ce_p->bsr_ce_len,
mac_ce_p->bsr_header_len, mac_ce_p->bsr_header_len,
buflen); buflen,
sched_info->regularBSR_trigger_lcid);
// Reset ReTx BSR Timer // Reset ReTx BSR Timer
nr_timer_start(&sched_info->retxBSR_Timer); nr_timer_start(&sched_info->retxBSR_Timer);
// Reset Periodic Timer except when BSR is truncated // Reset Periodic Timer except when BSR is truncated
...@@ -2695,8 +2724,20 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, ...@@ -2695,8 +2724,20 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset\n", mac->ue_id); LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset\n", mac->ue_id);
} }
if (sched_info->regularBSR_trigger_lcid > 0) {
nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, sched_info->regularBSR_trigger_lcid);
AssertFatal(lc_info, "Couldn't find logical channel with LCID %ld\n", sched_info->regularBSR_trigger_lcid);
if (lc_info->sr_id >= 0 && lc_info->sr_id < NR_MAX_SR_ID) {
LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing scheduling request with ID %d\n", mac->ue_id, lc_info->sr_id);
nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id];
sr->pending = false;
sr->counter = 0;
nr_timer_stop(&sr->prohibitTimer);
}
}
// Reset BSR Trigger flags // Reset BSR Trigger flags
sched_info->BSR_reporting_active = NR_BSR_TRIGGER_NONE; sched_info->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
sched_info->regularBSR_trigger_lcid = 0;
} }
} }
...@@ -3079,7 +3120,7 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, ...@@ -3079,7 +3120,7 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req. //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. //Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
nr_ue_get_sdu_mac_ce_post(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, mac_ce_p); nr_ue_get_sdu_mac_ce_post(mac, frame, slot, ulsch_buffer, buflen, mac_ce_p);
if (mac_ce_p->tot_mac_ce_len > 0) { if (mac_ce_p->tot_mac_ce_len > 0) {
......
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