preventing UE to schedule SR on PUCCH in the same slot when MSG4 ACK is sent
This commit is contained in:
@@ -303,6 +303,26 @@ typedef struct {
|
|||||||
uint32_t prach_mask;
|
uint32_t prach_mask;
|
||||||
} NR_pdcch_order_config_t;
|
} NR_pdcch_order_config_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NR_PUCCH_Resource_t *pucch_resource;
|
||||||
|
uint32_t ack_payload;
|
||||||
|
uint8_t sr_payload;
|
||||||
|
uint32_t csi_part1_payload;
|
||||||
|
uint32_t csi_part2_payload;
|
||||||
|
int n_sr;
|
||||||
|
int n_csi;
|
||||||
|
int n_harq;
|
||||||
|
int n_CCE;
|
||||||
|
int N_CCE;
|
||||||
|
int initial_pucch_id;
|
||||||
|
} PUCCH_sched_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sched_frame;
|
||||||
|
int sched_slot;
|
||||||
|
PUCCH_sched_t pucch_sched;
|
||||||
|
} RA_PUCCH_SCHED_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// pointer to RACH config dedicated
|
// pointer to RACH config dedicated
|
||||||
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated;
|
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated;
|
||||||
@@ -354,6 +374,8 @@ typedef struct {
|
|||||||
int preambleRxTargetPower;
|
int preambleRxTargetPower;
|
||||||
int msg3_deltaPreamble;
|
int msg3_deltaPreamble;
|
||||||
int preambleReceivedTargetPower_config;
|
int preambleReceivedTargetPower_config;
|
||||||
|
RA_PUCCH_SCHED_t *ra_pucch;
|
||||||
|
|
||||||
/// Random-access Contention Resolution Timer
|
/// Random-access Contention Resolution Timer
|
||||||
NR_timer_t contention_resolution_timer;
|
NR_timer_t contention_resolution_timer;
|
||||||
/// Transmitted UE Contention Resolution Identifier
|
/// Transmitted UE Contention Resolution Identifier
|
||||||
@@ -403,20 +425,6 @@ typedef struct {
|
|||||||
uint16_t Msg3_f_alloc;
|
uint16_t Msg3_f_alloc;
|
||||||
} RAR_grant_t;
|
} RAR_grant_t;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
NR_PUCCH_Resource_t *pucch_resource;
|
|
||||||
uint32_t ack_payload;
|
|
||||||
uint8_t sr_payload;
|
|
||||||
uint32_t csi_part1_payload;
|
|
||||||
uint32_t csi_part2_payload;
|
|
||||||
int n_sr;
|
|
||||||
int n_csi;
|
|
||||||
int n_harq;
|
|
||||||
int n_CCE;
|
|
||||||
int N_CCE;
|
|
||||||
int initial_pucch_id;
|
|
||||||
} PUCCH_sched_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ssb_index;
|
uint32_t ssb_index;
|
||||||
/// SSB RSRP in dBm
|
/// SSB RSRP in dBm
|
||||||
|
|||||||
@@ -1141,7 +1141,7 @@ void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS
|
|||||||
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_PADDING};
|
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_PADDING};
|
||||||
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
|
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||||
}
|
}
|
||||||
ra->Msg3_buffer = calloc(TBS_max, sizeof(uint8_t));
|
ra->Msg3_buffer = calloc_or_fail(TBS_max, sizeof(uint8_t));
|
||||||
memcpy(ra->Msg3_buffer, buf, sizeof(uint8_t) * TBS_max);
|
memcpy(ra->Msg3_buffer, buf, sizeof(uint8_t) * TBS_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1258,18 +1258,12 @@ void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
|
|||||||
.n_harq = 1};
|
.n_harq = 1};
|
||||||
current_harq->active = false;
|
current_harq->active = false;
|
||||||
current_harq->ack_received = false;
|
current_harq->ack_received = false;
|
||||||
if (get_softmodem_params()->emulate_l1) {
|
|
||||||
mac->nr_ue_emul_l1.harq[pid].active = true;
|
RA_config_t *ra = &mac->ra;
|
||||||
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_sfn = sched_frame;
|
ra->ra_pucch = calloc_or_fail(1, sizeof(*ra->ra_pucch));
|
||||||
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_slot = sched_slot;
|
ra->ra_pucch->pucch_sched = pucch;
|
||||||
}
|
ra->ra_pucch->sched_frame = sched_frame;
|
||||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
ra->ra_pucch->sched_slot = sched_slot;
|
||||||
if (!pdu)
|
|
||||||
return;
|
|
||||||
int ret = nr_ue_configure_pucch(mac, sched_slot, sched_frame, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
|
|
||||||
if (ret != 0)
|
|
||||||
remove_ul_config_last_item(pdu);
|
|
||||||
release_ul_config(pdu, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
|
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
|
||||||
|
|||||||
@@ -1713,7 +1713,7 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac,
|
|||||||
return mux_done;
|
return mux_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP)
|
static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frame, int slot)
|
||||||
{
|
{
|
||||||
PUCCH_sched_t pucch[3] = {0}; // TODO the size might change in the future in case of multiple SR or multiple CSI in a slot
|
PUCCH_sched_t pucch[3] = {0}; // TODO the size might change in the future in case of multiple SR or multiple CSI in a slot
|
||||||
|
|
||||||
@@ -1722,40 +1722,50 @@ static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slo
|
|||||||
mac->nr_ue_emul_l1.num_csi_reports = 0;
|
mac->nr_ue_emul_l1.num_csi_reports = 0;
|
||||||
int num_res = 0;
|
int num_res = 0;
|
||||||
|
|
||||||
// SR
|
if (mac->ra.ra_pucch) {
|
||||||
if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch[0], frameP, slotP)) {
|
// scheduling PUCCH prepared in advance for MSG4
|
||||||
num_res++;
|
RA_PUCCH_SCHED_t *ra_pucch = mac->ra.ra_pucch;
|
||||||
// TODO check if the PUCCH resource for the SR transmission occasion overlap with a UL-SCH resource
|
if (ra_pucch->sched_frame == frame && ra_pucch->sched_slot == slot) {
|
||||||
|
pucch[0] = ra_pucch->pucch_sched;
|
||||||
|
num_res++;
|
||||||
|
free_and_zero(mac->ra.ra_pucch);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// SR
|
||||||
|
if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch[0], frame, slot)) {
|
||||||
|
num_res++;
|
||||||
|
// TODO check if the PUCCH resource for the SR transmission occasion overlap with a UL-SCH resource
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSI
|
||||||
|
int csi_res = 0;
|
||||||
|
if (mac->state == UE_CONNECTED)
|
||||||
|
csi_res = nr_get_csi_measurements(mac, frame, slot, &pucch[num_res]);
|
||||||
|
if (csi_res > 0) {
|
||||||
|
num_res += csi_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACKNACK
|
||||||
|
bool any_harq = get_downlink_ack(mac, frame, slot, &pucch[num_res]);
|
||||||
|
if (any_harq)
|
||||||
|
num_res++;
|
||||||
|
|
||||||
|
if (num_res == 0)
|
||||||
|
return;
|
||||||
|
// do no transmit pucch if only SR scheduled and it is negative
|
||||||
|
if (num_res == 1 && pucch[0].n_sr > 0 && pucch[0].sr_payload == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (num_res > 1)
|
||||||
|
multiplex_pucch_resource(mac, pucch, num_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSI
|
|
||||||
int csi_res = 0;
|
|
||||||
if (mac->state == UE_CONNECTED)
|
|
||||||
csi_res = nr_get_csi_measurements(mac, frameP, slotP, &pucch[num_res]);
|
|
||||||
if (csi_res > 0) {
|
|
||||||
num_res += csi_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACKNACK
|
|
||||||
bool any_harq = get_downlink_ack(mac, frameP, slotP, &pucch[num_res]);
|
|
||||||
if (any_harq)
|
|
||||||
num_res++;
|
|
||||||
|
|
||||||
if (num_res == 0)
|
|
||||||
return;
|
|
||||||
// do no transmit pucch if only SR scheduled and it is negative
|
|
||||||
if (num_res == 1 && pucch[0].n_sr > 0 && pucch[0].sr_payload == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (num_res > 1)
|
|
||||||
multiplex_pucch_resource(mac, pucch, num_res);
|
|
||||||
|
|
||||||
for (int j = 0; j < num_res; j++) {
|
for (int j = 0; j < num_res; j++) {
|
||||||
if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) {
|
if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) {
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"%d.%d configure pucch, O_ACK %d, O_SR %d, O_CSI %d\n",
|
"%d.%d configure pucch, O_ACK %d, O_SR %d, O_CSI %d\n",
|
||||||
frameP,
|
frame,
|
||||||
slotP,
|
slot,
|
||||||
pucch[j].n_harq,
|
pucch[j].n_harq,
|
||||||
pucch[j].n_sr,
|
pucch[j].n_sr,
|
||||||
pucch[j].n_csi);
|
pucch[j].n_csi);
|
||||||
@@ -1764,20 +1774,20 @@ static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slo
|
|||||||
mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi;
|
mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi;
|
||||||
|
|
||||||
// checking if we need to schedule pucch[j] on PUSCH
|
// checking if we need to schedule pucch[j] on PUSCH
|
||||||
if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j], mac->current_UL_BWP))
|
if (schedule_uci_on_pusch(mac, frame, slot, &pucch[j], mac->current_UL_BWP))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame, slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
|
||||||
if (!pdu) {
|
if (!pdu) {
|
||||||
LOG_E(NR_MAC, "Error in pucch allocation\n");
|
LOG_E(NR_MAC, "Error in pucch allocation\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DevAssert(mac->current_DL_BWP != NULL);
|
DevAssert(mac->current_DL_BWP != NULL);
|
||||||
int mu = mac->current_DL_BWP->scs;
|
int mu = mac->current_DL_BWP->scs;
|
||||||
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2DEC(mu, frameP, slotP);
|
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2DEC(mu, frame, slot);
|
||||||
int ret = nr_ue_configure_pucch(mac,
|
int ret = nr_ue_configure_pucch(mac,
|
||||||
slotP,
|
slot,
|
||||||
frameP,
|
frame,
|
||||||
mac->crnti, // FIXME not sure this is valid for all pucch instances
|
mac->crnti, // FIXME not sure this is valid for all pucch instances
|
||||||
&pucch[j],
|
&pucch[j],
|
||||||
&pdu->pucch_config_pdu);
|
&pdu->pucch_config_pdu);
|
||||||
|
|||||||
Reference in New Issue
Block a user