|
|
|
@@ -19,7 +19,7 @@
|
|
|
|
|
* contact@openairinterface.org
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
#define _GNU_SOURCE // For pthread_setname_np
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <openair1/PHY/impl_defs_top.h>
|
|
|
|
|
#include "executables/nr-uesoftmodem.h"
|
|
|
|
@@ -239,84 +239,21 @@ static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_p
|
|
|
|
|
LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool sfn_slot_matcher(void *wanted, void *candidate)
|
|
|
|
|
{
|
|
|
|
|
nfapi_p7_message_header_t *msg = candidate;
|
|
|
|
|
int sfn_sf = *(int*)wanted;
|
|
|
|
|
|
|
|
|
|
switch (msg->message_id)
|
|
|
|
|
{
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_rach_indication_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_rx_data_indication_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_crc_indication_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_uci_indication_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_dl_tti_request_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_tx_data_request_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_ul_dci_request_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_ul_tti_request_t *ind = candidate;
|
|
|
|
|
return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
|
|
|
|
|
{
|
|
|
|
|
nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
|
|
|
|
nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
|
|
|
|
nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
|
|
|
|
nfapi_nr_dl_tti_request_t *dl_tti_request = get_queue(&nr_dl_tti_req_queue);
|
|
|
|
|
nfapi_nr_ul_dci_request_t *ul_dci_request = get_queue(&nr_ul_dci_req_queue);
|
|
|
|
|
|
|
|
|
|
LOG_D(NR_MAC, "Try to get a ul_tti_req for sfn/slot %d %d from queue with %lu items\n",
|
|
|
|
|
NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot),NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot), nr_ul_tti_req_queue.num_items);
|
|
|
|
|
nfapi_nr_ul_tti_request_t *ul_tti_request = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot);
|
|
|
|
|
if (!ul_tti_request)
|
|
|
|
|
{
|
|
|
|
|
LOG_D(NR_MAC, "Try to get a ul_tti_req from seprate queue because dl_tti_req was late\n");
|
|
|
|
|
ul_tti_request = unqueue_matching(&nr_wait_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot);
|
|
|
|
|
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
|
|
|
|
LOG_D(NR_MAC, "Try to get a ul_tti_req by matching CRC active SFN %d/SLOT %d from queue with %lu items\n",
|
|
|
|
|
NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot),
|
|
|
|
|
NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot), nr_ul_tti_req_queue.num_items);
|
|
|
|
|
nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot);
|
|
|
|
|
if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0)
|
|
|
|
|
{
|
|
|
|
|
check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rach_ind && rach_ind->number_of_pdus > 0)
|
|
|
|
@@ -333,24 +270,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
|
|
|
|
|
free(rach_ind);
|
|
|
|
|
nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0);
|
|
|
|
|
}
|
|
|
|
|
if (crc_ind && crc_ind->number_crcs > 0)
|
|
|
|
|
{
|
|
|
|
|
NR_UL_IND_t UL_INFO = {
|
|
|
|
|
.crc_ind = *crc_ind,
|
|
|
|
|
};
|
|
|
|
|
send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id);
|
|
|
|
|
free(crc_ind->crc_list);
|
|
|
|
|
free(crc_ind);
|
|
|
|
|
}
|
|
|
|
|
if (rx_ind && rx_ind->number_of_pdus > 0)
|
|
|
|
|
{
|
|
|
|
|
NR_UL_IND_t UL_INFO = {
|
|
|
|
|
.rx_ind = *rx_ind,
|
|
|
|
|
};
|
|
|
|
|
send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id);
|
|
|
|
|
free(rx_ind->pdu_list);
|
|
|
|
|
free(rx_ind);
|
|
|
|
|
}
|
|
|
|
|
if (dl_tti_request)
|
|
|
|
|
{
|
|
|
|
|
int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot);
|
|
|
|
@@ -380,10 +299,6 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
|
|
|
|
|
{
|
|
|
|
|
check_and_process_dci(NULL, NULL, ul_dci_request, NULL);
|
|
|
|
|
}
|
|
|
|
|
if (ul_tti_request && ul_tti_request->n_pdus > 0)
|
|
|
|
|
{
|
|
|
|
|
check_and_process_dci(NULL, NULL, NULL, ul_tti_request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources)
|
|
|
|
@@ -434,7 +349,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
reset_queue(&nr_tx_req_queue);
|
|
|
|
|
reset_queue(&nr_ul_dci_req_queue);
|
|
|
|
|
reset_queue(&nr_ul_tti_req_queue);
|
|
|
|
|
reset_queue(&nr_wait_ul_tti_req_queue);
|
|
|
|
|
|
|
|
|
|
NR_PRACH_RESOURCES_t prach_resources;
|
|
|
|
|
memset(&prach_resources, 0, sizeof(prach_resources));
|
|
|
|
@@ -443,6 +357,13 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
int last_sfn_slot = -1;
|
|
|
|
|
uint16_t sfn_slot = 0;
|
|
|
|
|
|
|
|
|
|
module_id_t mod_id = 0;
|
|
|
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
|
|
|
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
|
|
|
|
mac->nr_ue_emul_l1.harq[i].active = false;
|
|
|
|
|
mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!oai_exit)
|
|
|
|
|
{
|
|
|
|
|
if (sem_wait(&sfn_slot_semaphore) != 0)
|
|
|
|
@@ -459,9 +380,11 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
}
|
|
|
|
|
if (slot_ind) {
|
|
|
|
|
sfn_slot = *slot_ind;
|
|
|
|
|
free_and_zero(slot_ind);
|
|
|
|
|
}
|
|
|
|
|
else if (ch_info) {
|
|
|
|
|
sfn_slot = ch_info->sfn_slot;
|
|
|
|
|
free_and_zero(ch_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot);
|
|
|
|
@@ -477,8 +400,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n",
|
|
|
|
|
frame, slot);
|
|
|
|
|
|
|
|
|
|
module_id_t mod_id = 0;
|
|
|
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
|
|
|
if (get_softmodem_params()->sa && mac->mib == NULL)
|
|
|
|
|
{
|
|
|
|
|
LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n");
|
|
|
|
@@ -533,8 +454,10 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
|
|
|
|
|
ul_info.slot_tx, mac->frame_type))
|
|
|
|
|
{
|
|
|
|
|
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() from %s\n", ul_info.slot_tx, __FUNCTION__);
|
|
|
|
|
nr_ue_ul_indication(&ul_info);
|
|
|
|
|
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() and nr_ue_pucch_scheduler() from %s\n", ul_info.slot_tx, __FUNCTION__);
|
|
|
|
|
nr_ue_scheduler(NULL, &ul_info);
|
|
|
|
|
nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, ul_info.thread_id);
|
|
|
|
|
nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, ul_info.thread_id);
|
|
|
|
|
check_nr_prach(mac, &ul_info, &prach_resources);
|
|
|
|
|
}
|
|
|
|
|
if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) {
|
|
|
|
@@ -544,10 +467,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
|
|
|
|
pdcp_run(&ctxt);
|
|
|
|
|
}
|
|
|
|
|
process_queued_nr_nfapi_msgs(mac, sfn_slot);
|
|
|
|
|
free(slot_ind);
|
|
|
|
|
slot_ind = NULL;
|
|
|
|
|
free(ch_info);
|
|
|
|
|
ch_info = NULL;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
@@ -654,17 +573,7 @@ static void UE_synch(void *arg) {
|
|
|
|
|
openair0_cfg[UE->rf_map.card].rx_freq[0],
|
|
|
|
|
openair0_cfg[UE->rf_map.card].tx_freq[0]);
|
|
|
|
|
|
|
|
|
|
if (UE->mode != loop_through_memory) {
|
|
|
|
|
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
|
|
|
|
|
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
|
|
|
|
|
//UE->rfdevice.trx_stop_func(&UE->rfdevice);
|
|
|
|
|
// sleep(1);
|
|
|
|
|
/*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
|
|
|
|
|
LOG_E(HW,"Could not start the device\n");
|
|
|
|
|
oai_exit=1;
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
|
|
|
|
|
if (UE->UE_scan_carrier == 1) {
|
|
|
|
|
UE->UE_scan_carrier = 0;
|
|
|
|
|
} else {
|
|
|
|
@@ -683,8 +592,7 @@ static void UE_synch(void *arg) {
|
|
|
|
|
|
|
|
|
|
LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
|
|
|
|
|
|
|
|
|
|
if (UE->mode != loop_through_memory)
|
|
|
|
|
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
|
|
|
|
|
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
@@ -729,7 +637,7 @@ void processSlotTX(void *arg) {
|
|
|
|
|
stop_meas(&UE->ue_ul_indication_stats);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((UE->mode != loop_through_memory) && (rxtxD->ue_sched_mode != NOT_PUSCH)) {
|
|
|
|
|
if (rxtxD->ue_sched_mode != NOT_PUSCH) {
|
|
|
|
|
phy_procedures_nrUE_TX(UE,proc,0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -744,6 +652,7 @@ void processSlotRX(void *arg) {
|
|
|
|
|
int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
|
|
|
|
|
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
|
|
|
|
|
uint8_t gNB_id = 0;
|
|
|
|
|
NR_UE_PDCCH_CONFIG phy_pdcch_config={0};
|
|
|
|
|
|
|
|
|
|
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
|
|
|
|
|
/* send tick to RLC and PDCP every ms */
|
|
|
|
@@ -759,7 +668,7 @@ void processSlotRX(void *arg) {
|
|
|
|
|
|
|
|
|
|
if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
|
|
|
|
|
nr_downlink_indication_t dl_indication;
|
|
|
|
|
nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id);
|
|
|
|
|
nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_pdcch_config);
|
|
|
|
|
UE->if_inst->dl_indication(&dl_indication, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -768,7 +677,7 @@ void processSlotRX(void *arg) {
|
|
|
|
|
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
|
|
|
|
|
#else
|
|
|
|
|
uint64_t a=rdtsc_oai();
|
|
|
|
|
phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
|
|
|
|
|
phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &phy_pdcch_config, &rxtxD->txFifo);
|
|
|
|
|
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@@ -818,9 +727,10 @@ void processSlotRX(void *arg) {
|
|
|
|
|
|
|
|
|
|
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
|
|
|
|
|
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
|
|
|
|
|
|
|
|
|
|
int16_t dummy_tx_data[UE->frame_parms.nb_antennas_tx][2*writeBlockSize]; // 2 because the function we call use pairs of int16_t implicitly as complex numbers
|
|
|
|
|
memset(dummy_tx_data, 0, sizeof(dummy_tx_data));
|
|
|
|
|
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
|
|
|
|
|
dummy_tx[i]=malloc16_clear(writeBlockSize*4);
|
|
|
|
|
dummy_tx[i]=dummy_tx_data[i];
|
|
|
|
|
|
|
|
|
|
AssertFatal( writeBlockSize ==
|
|
|
|
|
UE->rfdevice.trx_write_func(&UE->rfdevice,
|
|
|
|
@@ -830,8 +740,6 @@ void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockS
|
|
|
|
|
UE->frame_parms.nb_antennas_tx,
|
|
|
|
|
4),"");
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
|
|
|
|
|
free(dummy_tx[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) {
|
|
|
|
@@ -873,7 +781,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
|
|
|
|
|
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
|
|
|
|
|
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
|
|
|
|
|
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
|
|
|
|
|
// we write before read becasue gNB waits for UE to write and both executions halt
|
|
|
|
|
// we write before read because gNB waits for UE to write and both executions halt
|
|
|
|
|
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
|
|
|
|
|
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
|
|
|
|
|
AssertFatal(unitTransfer ==
|
|
|
|
|